Class: DropboxOAuth2Flow

Inherits:
DropboxOAuth2FlowBase show all
Defined in:
lib/dropbox_sdk.rb

Overview

The standard OAuth 2 authorization helper. Use this if you’re writing a web app.

Defined Under Namespace

Classes: BadRequestError, BadStateError, CsrfError, NotApprovedError, ProviderError

Instance Method Summary collapse

Methods inherited from DropboxOAuth2FlowBase

#_finish, #_get_authorize_url

Constructor Details

#initialize(consumer_key, consumer_secret, redirect_uri, session, csrf_token_session_key, locale = nil) ⇒ DropboxOAuth2Flow

  • consumer_key: Your Dropbox API app’s “app key”

  • consumer_secret: Your Dropbox API app’s “app secret”

  • redirect_uri: The URI that the Dropbox server will redirect the user to after the user finishes authorizing your app. This URI must be HTTPs-based and pre-registered with the Dropbox servers, though localhost URIs are allowed without pre-registration and can be either HTTP or HTTPS.

  • session: A hash that represents the current web app session (will be used to save the CSRF token)

  • csrf_token_key: The key to use when storing the CSRF token in the session (for example, :dropbox_auth_csrf_token)

  • locale: The locale of the user currently using your app (ex: “en” or “en_US”).



483
484
485
486
487
488
489
490
491
# File 'lib/dropbox_sdk.rb', line 483

def initialize(consumer_key, consumer_secret, redirect_uri, session, csrf_token_session_key, locale=nil)
    super(consumer_key, consumer_secret, locale)
    if not redirect_uri.is_a?(String)
        raise ArgumentError, "redirect_uri must be a String, got #{consumer_secret.inspect}"
    end
    @redirect_uri = redirect_uri
    @session = session
    @csrf_token_session_key = csrf_token_session_key
end

Instance Method Details

#finish(query_params) ⇒ Object

Call this after the user has visited the authorize URL (see: start()), approved your app, and was redirected to your redirect URI.

  • query_params: The query params on the GET request to your redirect URI.

Returns a tuple of (access_token, user_id, url_state). access_token can be used to construct a DropboxClient. user_id is the Dropbox user ID of the user that jsut approved your app. url_state is the value you originally passed in to start().

Can throw BadRequestError, BadStateError, CsrfError, NotApprovedError, ProviderError, and the standard DropboxError.



533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
# File 'lib/dropbox_sdk.rb', line 533

def finish(query_params)
    csrf_token_from_session = @session[@csrf_token_session_key]

    # Check well-formedness of request.

    state = query_params['state']
    if state.nil?
        raise BadRequestError.new("Missing query parameter 'state'.")
    end

    error = query_params['error']
    error_description = query_params['error_description']
    code = query_params['code']

    if not error.nil? and not code.nil?
        raise BadRequestError.new("Query parameters 'code' and 'error' are both set;" +
                                  " only one must be set.")
    end
    if error.nil? and code.nil?
        raise BadRequestError.new("Neither query parameter 'code' or 'error' is set.")
    end

    # Check CSRF token
    
    if csrf_token_from_session.nil?
        raise BadStateError.new("Missing CSRF token in session.");
    end
    unless csrf_token_from_session.length > 20
        raise RuntimeError.new("CSRF token unexpectedly short: #{csrf_token_from_session.inspect}")
    end

    split_pos = state.index('|')
    if split_pos.nil?
        given_csrf_token = state
        url_state = nil
    else
        given_csrf_token, url_state = state.split('|', 2)
    end
    if not Dropbox::safe_string_equals(csrf_token_from_session, given_csrf_token)
        raise CsrfError.new("Expected #{csrf_token_from_session.inspect}, " +
                                "got #{given_csrf_token.inspect}.")
    end
    @session.delete(@csrf_token_session_key)

    # Check for error identifier
    
    if not error.nil?
        if error == 'access_denied'
            # The user clicked "Deny"
            if error_description.nil?
                raise NotApprovedError.new("No additional description from Dropbox.")
            else
                raise NotApprovedError.new("Additional description from Dropbox: #{error_description}")
            end
        else
            # All other errors.
            full_message = error
            if not error_description.nil?
                full_message += ": " + error_description
            end
            raise ProviderError.new(full_message)
        end
    end

    # If everything went ok, make the network call to get an access token.

    access_token, user_id = _finish(code, @redirect_uri)
    return access_token, user_id, url_state
end

#start(url_state = nil) ⇒ Object

Starts the OAuth 2 authorizaton process, which involves redirecting the user to the returned “authorization URL” (a URL on the Dropbox website). When the user then either approves or denies your app access, Dropbox will redirect them to the redirect_uri you provided to the constructor, at which point you should call finish() to complete the process.

This function will also save a CSRF token to the session and csrf_token_session_key you provided to the constructor. This CSRF token will be checked on finish() to prevent request forgery.

  • url_state: Any data you would like to keep in the URL through the authorization process. This exact value will be returned to you by finish().

Returns the URL to redirect the user to.



507
508
509
510
511
512
513
514
515
516
517
518
519
520
# File 'lib/dropbox_sdk.rb', line 507

def start(url_state=nil)
    unless url_state.nil? or url_state.is_a?(String)
        raise ArgumentError, "url_state must be a String"
    end

    csrf_token = SecureRandom.base64(16)
    state = csrf_token
    unless url_state.nil?
        state += "|" + url_state
    end
    @session[@csrf_token_session_key] = csrf_token

    return _get_authorize_url(@redirect_uri, state)
end