class Motion::Firebase::TwitterAuthHelper

Public Class Methods

new(ref, api_key) click to toggle source
# File lib/firebase/firebase_twitter_helper.rb, line 30
def initialize(ref, api_key)
  @store = ACAccountStore.new
  @ref = ref
  @api_key = api_key
  @account = nil
  @acounts = nil
  @firebase_callback = nil
end

Public Instance Methods

authenticate_account(account, &firebase_handler) click to toggle source

Last public facing method

# File lib/firebase/firebase_twitter_helper.rb, line 73
def authenticate_account(account, &firebase_handler)
  if !account
    error = NSError.alloc.initWithDomain('TwitterAuthHelper',
                 code: AuthHelperErrorAccountAccessDenied,
                 userInfo: { NSLocalizedDescriptionKey => 'No Twitter account to authenticate.' })
    Dispatch::Queue.main.async do
      firebase_handler.call(error, nil)
    end if firebase_handler
  else
    @account = account
    @firebase_callback = firebase_handler
    make_reverse_request # kick off step 1b
  end
end
authenticate_with_twitter_credentials(response_data) click to toggle source

Step 3 – authenticate with Firebase using Twitter credentials

# File lib/firebase/firebase_twitter_helper.rb, line 135
def authenticate_with_twitter_credentials(response_data)
  params = parse_twitter_credentials(response_data)
  if params['error']
    error = NSError.alloc.initWithDomain('TwitterAuthHelper',
                 code: AuthHelperErrorOAuthTokenRequestDenied,
                 userInfo: { NSLocalizedDescriptionKey => 'OAuth token request was denied.',
                             'details' => params['error']})
    callback_if_exists_with_error(error)
  else
    @ref.authWithOAuthProvider('twitter', parameters: params, withCompletionBlock: @firebase_callback)
  end
end
callback_if_exists_with_error(error) click to toggle source
# File lib/firebase/firebase_twitter_helper.rb, line 88
def callback_if_exists_with_error(error)
  if @firebase_callback
    Dispatch::Queue.main.async do
      @firebase_callback.call(error, nil)
    end
  end
end
create_credential_request_with_reverse_auth_payload(json) click to toggle source

Step 1b Helper – creates request to Twitter

# File lib/firebase/firebase_twitter_helper.rb, line 109
def create_credential_request_with_reverse_auth_payload(json)
  params = {}

  request_token = json['oauth']
  params['x_reverse_auth_parameters'] = request_token
  params['x_reverse_auth_target'] = @api_key

  url = NSURL.URLWithString('https://api.twitter.com/oauth/access_token')
  req = SLRequest.requestForServiceType(SLServiceTypeTwitter, requestMethod: SLRequestMethodPOST, URL: url, parameters: params)
  req.setAccount(@account)

  req
end
make_reverse_request() click to toggle source

Step 1b – get request token from Twitter

# File lib/firebase/firebase_twitter_helper.rb, line 97
def make_reverse_request
  @ref.makeReverseOAuthRequestTo('twitter', withCompletionBlock: -> (error, json) do
    if error
      callback_if_exists_with_error(error)
    else
      request = create_credential_request_with_reverse_auth_payload(json)
      request_twitter_credentials(request)
    end
  end)
end
parse_twitter_credentials(response_data) click to toggle source

Step 3 Helper – parsers credentials into dictionary

# File lib/firebase/firebase_twitter_helper.rb, line 149
def parse_twitter_credentials(response_data)
  account_data = NSString.alloc.initWithData(response_data, encoding:NSUTF8StringEncoding)
  params = {}

  account_data.split('&').each do |param|
    key, value = param.split('=')
    params[key] = value
  end

  # This is super fragile error handling, but basically check that the token and token secret are there.
  # If not, return the result that Twitter returned.
  if params['oauth_token_secret'] && params['oauth_token']
    params
  else
    { 'error' => account_data }
  end
end
request_twitter_credentials(request) click to toggle source

Step 2 – request credentials from Twitter

# File lib/firebase/firebase_twitter_helper.rb, line 124
def request_twitter_credentials(request)
  request.performRequestWithHandler(-> (response_data, url_response, error) do
    if error
      callback_if_exists_with_error(error)
    else
      authenticate_with_twitter_credentials(response_data)
    end
  end)
end
select_twitter_account(&callback) click to toggle source

Step 1a – get account

# File lib/firebase/firebase_twitter_helper.rb, line 40
def select_twitter_account(&callback)
  account_type = @store.accountTypeWithAccountTypeIdentifier(ACAccountTypeIdentifierTwitter)

  @store.requestAccessToAccountsWithType(account_type, options: nil, completion: -> (granted, error) do
    if granted
      @accounts = @store.accountsWithAccountType(account_type)
      if @accounts.length > 0
        Dispatch::Queue.main.async do
          next_step = -> (account, &firebase_handler) do
            self.authenticate_account(account, &firebase_handler)
          end
          callback.call(nil, @accounts, next_step)
        end if callback
      else
        error = NSError.alloc.initWithDomain('TwitterAuthHelper',
                       code: AuthHelperErrorAccountAccessDenied,
                   userInfo: { NSLocalizedDescriptionKey => 'No Twitter accounts detected on phone. Please add one in the settings first.' })
        Dispatch::Queue.main.async do
          callback.call(error, nil, nil)
        end if callback
      end
    else
      error = NSError.alloc.initWithDomain('TwitterAuthHelper',
                     code: AuthHelperErrorAccountAccessDenied,
                 userInfo: { NSLocalizedDescriptionKey => 'Access to twitter accounts denied.' })
      Dispatch::Queue.main.async do
        callback.call(error, nil, nil)
      end if callback
    end
  end)
end