Class: OmniAuth::Strategies::LinkedIn

Inherits:
Object
  • Object
show all
Includes:
OmniAuth::Strategy
Defined in:
lib/omniauth/strategies/linkedin.rb

Overview

Authentication strategy for connecting by [exchanging LinkedIn JSAPI for REST API OAuth Tokens](developer.linkedin.com/documents/exchange-jsapi-tokens-rest-api-oauth-tokens).

Defined Under Namespace

Classes: InvalidSecureCookieError, NoSecureCookieError

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#access_tokenObject

Returns the value of attribute access_token.



66
67
68
# File 'lib/omniauth/strategies/linkedin.rb', line 66

def access_token
  @access_token
end

Instance Method Details

#callback_phaseObject



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/omniauth/strategies/linkedin.rb', line 80

def callback_phase 
  if request_contains_secure_cookie?
    # We should already have an oauth2 token from secure cookie. 
    # Need to exchange it for an oauth token for REST API
    self.access_token = client.get_access_token(nil, {}, {:xoauth_oauth2_access_token => secure_cookie['access_token']})
    super
  else
    raise NoSecureCookieError, 'must pass a `linkedin_oauth_XXX` cookie'
  end
rescue ::Timeout::Error => e
  fail!(:timeout, e)
rescue ::Net::HTTPFatalError, ::OpenSSL::SSL::SSLError => e
  fail!(:service_unavailable, e)
rescue ::OAuth::Unauthorized => e
  fail!(:invalid_credentials, e)
rescue ::MultiJson::DecodeError => e
  fail!(:invalid_response, e)
rescue ::OmniAuth::NoSessionError => e
  fail!(:session_expired, e)
end

#clientObject



101
102
103
# File 'lib/omniauth/strategies/linkedin.rb', line 101

def client
  @client ||= OAuth::Consumer.new(options.api_key, options.secret_key, options.client_options)
end


117
118
119
120
121
122
123
124
# File 'lib/omniauth/strategies/linkedin.rb', line 117

def parse_secure_cookie(cookie)
  payload = MultiJson.decode cookie
  if validate_signature(payload)
    payload
  else
    raise InvalidSecureCookieError, 'secure cookie signature validation fails'
  end
end

#raw_infoObject



62
63
64
# File 'lib/omniauth/strategies/linkedin.rb', line 62

def raw_info
  @raw_info ||= MultiJson.decode(access_token.get("/v1/people/~:(#{options.fields.join(',')})?format=json").body)
end


113
114
115
# File 'lib/omniauth/strategies/linkedin.rb', line 113

def raw_secure_cookie
  request.cookies["linkedin_oauth_#{options.api_key}"]
end

#request_contains_secure_cookie?Boolean

Returns:

  • (Boolean)


105
106
107
# File 'lib/omniauth/strategies/linkedin.rb', line 105

def request_contains_secure_cookie?
  secure_cookie && secure_cookie['access_token']
end

#request_phaseObject



68
69
70
71
72
73
74
75
76
77
78
# File 'lib/omniauth/strategies/linkedin.rb', line 68

def request_phase
  url = callback_url
  url << "?" unless url.match(/\?/)
  url << "&" unless url.match(/[\&\?]$/)
  url << Rack::Utils.build_query(request.params)
  redirect url
rescue ::Timeout::Error => e
  fail!(:timeout, e)
rescue ::Net::HTTPFatalError, ::OpenSSL::SSL::SSLError => e
  fail!(:service_unavailable, e)
end


109
110
111
# File 'lib/omniauth/strategies/linkedin.rb', line 109

def secure_cookie
  @secure_cookie ||= raw_secure_cookie && parse_secure_cookie(raw_secure_cookie)
end

#user_nameObject



142
143
144
145
# File 'lib/omniauth/strategies/linkedin.rb', line 142

def user_name
  name = "#{raw_info['firstName']} #{raw_info['lastName']}".strip
  name.empty? ? nil : name
end

#validate_signature(payload) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/omniauth/strategies/linkedin.rb', line 126

def validate_signature(payload)
  valid = false
  if payload['signature_version'] == '1' or payload['signature_version'] == 1
    if !payload['signature_order'].nil? and payload['signature_order'].is_a?(Array)
      plain_msg = payload['signature_order'].map {|key| payload[key]}.join('')
      if payload['signature_method'] == 'HMAC-SHA1'
        signature = Base64.encode64(OpenSSL::HMAC.digest('sha1', options.secret_key, plain_msg)).chomp
        if signature == payload['signature']
          valid = true
        end
      end
    end
  end
  valid
end