linkedin-v2 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +10 -0
- data/CONTRIBUTING.md +1 -0
- data/Gemfile +8 -0
- data/LICENSE +22 -0
- data/README.md +224 -0
- data/Rakefile +19 -0
- data/lib/linked_in/access_token.rb +24 -0
- data/lib/linked_in/api.rb +108 -0
- data/lib/linked_in/api_resource.rb +180 -0
- data/lib/linked_in/communications.rb +40 -0
- data/lib/linked_in/configuration.rb +41 -0
- data/lib/linked_in/connection.rb +35 -0
- data/lib/linked_in/errors.rb +73 -0
- data/lib/linked_in/jobs.rb +11 -0
- data/lib/linked_in/mash.rb +68 -0
- data/lib/linked_in/media.rb +13 -0
- data/lib/linked_in/oauth2.rb +223 -0
- data/lib/linked_in/organizations.rb +217 -0
- data/lib/linked_in/people.rb +151 -0
- data/lib/linked_in/raise_error.rb +28 -0
- data/lib/linked_in/search.rb +70 -0
- data/lib/linked_in/share_and_social_stream.rb +143 -0
- data/lib/linked_in/version.rb +3 -0
- data/lib/linkedin-v2.rb +52 -0
- data/linkedin-v2.gemspec +39 -0
- data/pkg/linkedin-oauth2-2.0.0.gem +0 -0
- data/spec/linked_in/api/api_spec.rb +41 -0
- data/spec/linked_in/api/communications_spec.rb +13 -0
- data/spec/linked_in/api/jobs_spec.rb +33 -0
- data/spec/linked_in/api/organizations_spec.rb +54 -0
- data/spec/linked_in/api/people_spec.rb +191 -0
- data/spec/linked_in/api/search_spec.rb +71 -0
- data/spec/linked_in/api/share_and_social_stream_spec.rb +87 -0
- data/spec/linked_in/configuration_spec.rb +46 -0
- data/spec/linked_in/connection_spec.rb +10 -0
- data/spec/linked_in/module_loading_spec.rb +23 -0
- data/spec/linked_in/oauth/access_token_spec.rb +27 -0
- data/spec/linked_in/oauth/auth_code_spec.rb +86 -0
- data/spec/linked_in/oauth/credentials_spec.rb +96 -0
- data/spec/linked_in/oauth/get_access_token_spec.rb +108 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/vcr_cassettes/access_token_success.yml +99 -0
- data/spec/vcr_cassettes/bad_code.yml +99 -0
- data/spec/vcr_cassettes/organization_data.yml +51 -0
- data/spec/vcr_cassettes/people_picture_urls.yml +52 -0
- data/spec/vcr_cassettes/people_profile_connections_fields.yml +52 -0
- data/spec/vcr_cassettes/people_profile_connections_other.yml +52 -0
- data/spec/vcr_cassettes/people_profile_connections_self.yml +52 -0
- data/spec/vcr_cassettes/people_profile_fields_complex.yml +52 -0
- data/spec/vcr_cassettes/people_profile_fields_simple.yml +52 -0
- data/spec/vcr_cassettes/people_profile_lang_spanish.yml +53 -0
- data/spec/vcr_cassettes/people_profile_multiple_fields.yml +52 -0
- data/spec/vcr_cassettes/people_profile_multiple_uids.yml +52 -0
- data/spec/vcr_cassettes/people_profile_multiple_uids_and_urls.yml +52 -0
- data/spec/vcr_cassettes/people_profile_multiple_urls.yml +52 -0
- data/spec/vcr_cassettes/people_profile_new_connections_fields.yml +52 -0
- data/spec/vcr_cassettes/people_profile_new_connections_other.yml +52 -0
- data/spec/vcr_cassettes/people_profile_new_connections_self.yml +52 -0
- data/spec/vcr_cassettes/people_profile_other_uid.yml +57 -0
- data/spec/vcr_cassettes/people_profile_other_url.yml +54 -0
- data/spec/vcr_cassettes/people_profile_own.yml +57 -0
- data/spec/vcr_cassettes/people_profile_own_secure.yml +53 -0
- data/spec/vcr_cassettes/people_profile_skills.yml +52 -0
- data/spec/vcr_cassettes/unavailable.yml +99 -0
- metadata +285 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
# Communications APIs
|
3
|
+
#
|
4
|
+
# @see http://developer.linkedin.com/documents/communications
|
5
|
+
class Communications < APIResource
|
6
|
+
|
7
|
+
# (Create) send a message from the authenticated user to a
|
8
|
+
# connection
|
9
|
+
#
|
10
|
+
# Permissions: w_messages
|
11
|
+
#
|
12
|
+
# @see http://developer.linkedin.com/documents/messaging-between-connections-api
|
13
|
+
# @see http://developer.linkedin.com/documents/invitation-api Invitation API
|
14
|
+
#
|
15
|
+
# @example
|
16
|
+
# api.send_message("subject", "body", ["person_1_id", "person_2_id"])
|
17
|
+
#
|
18
|
+
# @param [String] subject Subject of the message
|
19
|
+
# @param [String] body Body of the message, plain text only
|
20
|
+
# @param [Array<String>] recipient_paths a collection of
|
21
|
+
# profile paths that identify the users who will receive the
|
22
|
+
# message
|
23
|
+
# @return [void]
|
24
|
+
def send_message(subject, body, recipient_paths)
|
25
|
+
path = "/people/~/mailbox"
|
26
|
+
|
27
|
+
message = {
|
28
|
+
subject: subject,
|
29
|
+
body: body,
|
30
|
+
recipients: {
|
31
|
+
values: recipient_paths.map do |profile_path|
|
32
|
+
{person: {_path: "/people/#{profile_path}"} }
|
33
|
+
end
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
post(path, MultiJson.dump(message), "Content-Type" => "application/json")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
# Configuration for the LinkedIn gem.
|
3
|
+
#
|
4
|
+
# LinkedIn.configure do |config|
|
5
|
+
# config.client_id = ENV["LINKEDIN_CLIENT_ID"]
|
6
|
+
# config.client_secret = ENV["LINKEDIN_CLIENT_SECRET"]
|
7
|
+
# end
|
8
|
+
#
|
9
|
+
# The default endpoints for LinkedIn are also stored here.
|
10
|
+
#
|
11
|
+
# LinkedIn uses the term "API key" to refer to "client id". They also
|
12
|
+
# use the term "Secret Key" to refer to "client_secret". We alias those
|
13
|
+
# terms in the config.
|
14
|
+
#
|
15
|
+
# * LinkedIn.config.site = "https://www.linkedin.com"
|
16
|
+
# * LinkedIn.config.token_url = "/uas/oauth2/accessToken"
|
17
|
+
# * LinkedIn.config.authorize_url = "/uas/oauth2/authorization"
|
18
|
+
class Configuration
|
19
|
+
attr_accessor :api,
|
20
|
+
:site,
|
21
|
+
:scope,
|
22
|
+
:client_id,
|
23
|
+
:token_url,
|
24
|
+
:api_version,
|
25
|
+
:redirect_uri,
|
26
|
+
:authorize_url,
|
27
|
+
:client_secret,
|
28
|
+
:default_profile_fields
|
29
|
+
|
30
|
+
alias_method :api_key, :client_id
|
31
|
+
alias_method :secret_key, :client_secret
|
32
|
+
|
33
|
+
def initialize
|
34
|
+
@api = "https://api.linkedin.com"
|
35
|
+
@api_version = "/v2"
|
36
|
+
@site = "https://www.linkedin.com"
|
37
|
+
@token_url = "/uas/oauth2/accessToken"
|
38
|
+
@authorize_url = "/uas/oauth2/authorization"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
# Used to perform requests against LinkedIn's API.
|
3
|
+
class Connection < ::Faraday::Connection
|
4
|
+
|
5
|
+
def initialize(url=nil, options=nil, &block)
|
6
|
+
|
7
|
+
if url.is_a? Hash
|
8
|
+
options = url
|
9
|
+
url = options[:url]
|
10
|
+
end
|
11
|
+
|
12
|
+
url = default_url if url.nil?
|
13
|
+
|
14
|
+
super url, options, &block
|
15
|
+
|
16
|
+
# We need to use the FlatParamsEncoder so we can pass multiple of
|
17
|
+
# the same param to certain endpoints (like the search API).
|
18
|
+
self.options.params_encoder = ::Faraday::FlatParamsEncoder
|
19
|
+
|
20
|
+
logger = Logger.new $stderr
|
21
|
+
logger.level = Logger::DEBUG
|
22
|
+
self.response :logger, logger
|
23
|
+
|
24
|
+
self.response :linkedin_raise_error
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
private ##############################################################
|
29
|
+
|
30
|
+
|
31
|
+
def default_url
|
32
|
+
LinkedIn.config.api + LinkedIn.config.api_version
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
# Thanks https://github.com/ResultadosDigitais/linkedin-oauth2 !
|
3
|
+
|
4
|
+
class Error < StandardError
|
5
|
+
attr_reader :data
|
6
|
+
|
7
|
+
def initialize(data)
|
8
|
+
@data = data
|
9
|
+
super
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Raised when users call a deprecated function
|
14
|
+
class Deprecated < LinkedIn::Error; end
|
15
|
+
|
16
|
+
# Raised when we know requests will be malformed and LinkedIn returns
|
17
|
+
# a 400 status code
|
18
|
+
class InvalidRequest < LinkedIn::Error; end
|
19
|
+
|
20
|
+
# Raised when LinkedIn returns a 401 status code during an API
|
21
|
+
# request.
|
22
|
+
class UnauthorizedError < LinkedIn::Error; end
|
23
|
+
|
24
|
+
# Raised when LinkedIn returns a 403 status code during an API
|
25
|
+
# request.
|
26
|
+
class AccessDeniedError < LinkedIn::Error; end
|
27
|
+
|
28
|
+
# Raised when LinkedIn returns a 404 status code during an API
|
29
|
+
# request.
|
30
|
+
class NotFoundError < LinkedIn::Error; end
|
31
|
+
|
32
|
+
# Raised when LinkedIn returns a 500 status code during an API
|
33
|
+
# request.
|
34
|
+
class InformLinkedInError < LinkedIn::Error; end
|
35
|
+
|
36
|
+
# Raised when LinkedIn returns a 502+ status code during an API
|
37
|
+
# request.
|
38
|
+
class UnavailableError < LinkedIn::Error; end
|
39
|
+
|
40
|
+
# Raised when LinkedIn returns a non 400+ status code during an OAuth
|
41
|
+
# request.
|
42
|
+
class OAuthError < OAuth2::Error; end
|
43
|
+
|
44
|
+
module ErrorMessages
|
45
|
+
class << self
|
46
|
+
attr_reader :deprecated,
|
47
|
+
:redirect_uri,
|
48
|
+
:no_auth_code,
|
49
|
+
:no_access_token,
|
50
|
+
:credentials_missing,
|
51
|
+
:redirect_uri_mismatch,
|
52
|
+
:throttled
|
53
|
+
end
|
54
|
+
|
55
|
+
@deprecated = "This has been deprecated by LinkedIn. Check https://developer.linkedin.com to see the latest available API calls"
|
56
|
+
|
57
|
+
@redirect_uri = "You must provide a redirect_uri. Set it in LinkedIn.configure or pass it in as the redirect_uri option. It must exactly match the redirect_uri you set on your application's settings page on LinkedIn's website."
|
58
|
+
|
59
|
+
@no_auth_code = "You must provide the authorization code passed to your redirect uri in the url params"
|
60
|
+
|
61
|
+
@no_access_token = "You must have an access token to use LinkedIn's API. Use the LinkedIn::OAuth2 module to obtain an access token"
|
62
|
+
|
63
|
+
@credentials_missing = "Client credentials do not exist. Please either pass your client_id and client_secret to the LinkedIn::Oauth.new constructor or set them via LinkedIn.configure"
|
64
|
+
|
65
|
+
@redirect_uri_mismatch = "Throttle limit for calls to this resource is reached"
|
66
|
+
|
67
|
+
def klass
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
# Jobs API
|
3
|
+
#
|
4
|
+
# @see http://developer.linkedin.com/documents/job-lookup-api-and-fields Job Lookup API and Fields
|
5
|
+
# @see http://developer.linkedin.com/documents/job-bookmarks-and-suggestions Job Bookmarks and Suggestions
|
6
|
+
#
|
7
|
+
# I do not have access to the Jobs-related endpoints.
|
8
|
+
# [(contribute here)](https://github.com/mdesjardins/linkedin-v2)
|
9
|
+
class Jobs < APIResource
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
# Coerces LinkedIn JSON to a nice Ruby hash
|
3
|
+
# LinkedIn::Mash inherits from Hashie::Mash
|
4
|
+
class Mash < ::Hashie::Mash
|
5
|
+
|
6
|
+
# a simple helper to convert a json string to a Mash
|
7
|
+
def self.from_json(json_string)
|
8
|
+
result_hash = JSON.load(json_string)
|
9
|
+
new(result_hash)
|
10
|
+
end
|
11
|
+
|
12
|
+
# returns a Date if we have year, month and day, and no conflicting key
|
13
|
+
def to_date
|
14
|
+
if !self.has_key?('to_date') && contains_date_fields?
|
15
|
+
Date.civil(self.year, self.month, self.day)
|
16
|
+
else
|
17
|
+
super
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def timestamp
|
22
|
+
value = self['timestamp']
|
23
|
+
if value.kind_of? Integer
|
24
|
+
value = value / 1000 if value > 9999999999
|
25
|
+
Time.at(value)
|
26
|
+
else
|
27
|
+
value
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
protected ############################################################
|
33
|
+
|
34
|
+
|
35
|
+
def contains_date_fields?
|
36
|
+
self.year? && self.month? && self.day?
|
37
|
+
end
|
38
|
+
|
39
|
+
# overload the convert_key mash method so that the LinkedIn
|
40
|
+
# keys are made a little more ruby-ish
|
41
|
+
def convert_key(key)
|
42
|
+
case key.to_s
|
43
|
+
when '_key'
|
44
|
+
'id'
|
45
|
+
when '_total'
|
46
|
+
'total'
|
47
|
+
when 'values'
|
48
|
+
'all'
|
49
|
+
when 'numResults'
|
50
|
+
'total_results'
|
51
|
+
else
|
52
|
+
underscore(key)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# borrowed from ActiveSupport
|
57
|
+
# no need require an entire lib when we only need one method
|
58
|
+
def underscore(camel_cased_word)
|
59
|
+
word = camel_cased_word.to_s.dup
|
60
|
+
word.gsub!(/::/, '/')
|
61
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
62
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
63
|
+
word.tr!("-", "_")
|
64
|
+
word.downcase!
|
65
|
+
word
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
# Rich Media APIs
|
3
|
+
#
|
4
|
+
# @see https://developer.linkedin.com/docs/guide/v2/shares/rich-media-shares
|
5
|
+
#
|
6
|
+
# [(contribute here)](https://github.com/mdesjardins/linkedin-v2)
|
7
|
+
class Media < APIResource
|
8
|
+
def summary(options = {})
|
9
|
+
path = "/richMediaSummariesV2/#{options.delete(:id)}"
|
10
|
+
get(path, options)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,223 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
# The LinkedIn::OAuth2::Client class. Inherits directly from [intreda/oauth2](https://github.com/intridea/oauth2)'s `OAuth2::Client`
|
3
|
+
#
|
4
|
+
# LinkedIn::OAuth2 sets the following default options:
|
5
|
+
#
|
6
|
+
# * site = "https://www.linkedin.com"
|
7
|
+
# * token_url = "/uas/oauth2/accessToken"
|
8
|
+
# * authorize_url = "/uas/oauth2/authorization"
|
9
|
+
#
|
10
|
+
# More details on LinkedIn's Authorization process can be found here: https://developer.linkedin.com/documents/authentication
|
11
|
+
class OAuth2 < ::OAuth2::Client
|
12
|
+
|
13
|
+
attr_accessor :access_token
|
14
|
+
|
15
|
+
# Instantiate a new OAuth 2.0 client using your client ID (aka API
|
16
|
+
# Key) and client secret (aka Secret Key).
|
17
|
+
#
|
18
|
+
# You should set the client_id and client_secret in the config.
|
19
|
+
#
|
20
|
+
# LinkedIn.configure do |config|
|
21
|
+
# config.client_id = ENV["LINKEDIN_CLIENT_ID"]
|
22
|
+
# config.client_secret = ENV["LINKEDIN_CLIENT_SECRET"]
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# This will let you initialize with zero arguments.
|
26
|
+
#
|
27
|
+
# If you have already set the `client_id` and `client_secret` in your
|
28
|
+
# config, the first and only argument can be the `options` hash.
|
29
|
+
#
|
30
|
+
# @param [String] client_id the client_id value
|
31
|
+
# @param [String] client_secret the client_secret value
|
32
|
+
# @param [Hash] options the options to create the client with
|
33
|
+
# @option options [Symbol] :token_method (:post) HTTP method to use to
|
34
|
+
# request token (:get or :post)
|
35
|
+
# @option options [Hash] :connection_opts ({}) Hash of connection options
|
36
|
+
# to pass to initialize Faraday with
|
37
|
+
# @option options [FixNum] :max_redirects (5) maximum number of redirects
|
38
|
+
# to follow
|
39
|
+
# @option options [Boolean] :raise_errors (true) whether or not to
|
40
|
+
# raise an error on malformed responses
|
41
|
+
# @yield [builder] The Faraday connection builder
|
42
|
+
def initialize(client_id=LinkedIn.config.client_id,
|
43
|
+
client_secret=LinkedIn.config.client_secret,
|
44
|
+
options = {}, &block)
|
45
|
+
|
46
|
+
if client_id.is_a? Hash
|
47
|
+
options = client_id
|
48
|
+
client_id = LinkedIn.config.client_id
|
49
|
+
end
|
50
|
+
|
51
|
+
options = default_oauth_options(options)
|
52
|
+
|
53
|
+
super client_id, client_secret, options, &block
|
54
|
+
|
55
|
+
@redirect_uri = options[:redirect_uri]
|
56
|
+
|
57
|
+
if self.options[:raise_errors]
|
58
|
+
check_credentials!(client_id, client_secret)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Generates the URL users use to sign into your application.
|
63
|
+
#
|
64
|
+
# Once a user enters their LinkedIn credentials, they will be
|
65
|
+
# redirected to your `redirect_uri` with the `code` parameter attached
|
66
|
+
# to it. The value of the `code` parameter can be used to get an
|
67
|
+
# access token.
|
68
|
+
#
|
69
|
+
# We recommend you set your `client_id, `client_secret`, and
|
70
|
+
# `redirect_uri` in the `LinkedIn.configure` block. They can also be
|
71
|
+
# passed in as options.
|
72
|
+
#
|
73
|
+
# @param [Hash] options the options to generate the url with
|
74
|
+
# @option options [String] :redirect_uri The url that gets redirected
|
75
|
+
# to after a successful authentication. This must exactly match the
|
76
|
+
# redirect urls setup on your LinkedIn Application Settings page.
|
77
|
+
# This option is not required if you already set the redirect_uri in
|
78
|
+
# the config.
|
79
|
+
# @option options [String] :scope A string of requested permissions
|
80
|
+
# you want from users when they authenticate with your app. If these
|
81
|
+
# are set on yoru LinkedIn Application settings page, you do not
|
82
|
+
# need to pass them in. The string must be a space-sparated,
|
83
|
+
# case-sensitive list of available scopes. See available scopes on
|
84
|
+
# LinkedIn's API documentation page.
|
85
|
+
# @option options [String] :state A long string used for CSRF
|
86
|
+
# protection. It is added as the `state` GET param in the
|
87
|
+
# redirect_uri
|
88
|
+
# @option options [Boolean] :raise_errors (true) whether or not to
|
89
|
+
# raise an error on malformed responses
|
90
|
+
def auth_code_url(options={})
|
91
|
+
options = default_auth_code_url_options(options)
|
92
|
+
|
93
|
+
if self.options[:raise_errors]
|
94
|
+
check_redirect_uri!(options)
|
95
|
+
end
|
96
|
+
|
97
|
+
@redirect_uri = options[:redirect_uri]
|
98
|
+
|
99
|
+
self.auth_code.authorize_url(options)
|
100
|
+
end
|
101
|
+
|
102
|
+
# Returns the access token string for the newly authenticated user.
|
103
|
+
#
|
104
|
+
# It also sets the `access_token` field on this LinkedIn::OAuth2
|
105
|
+
# instance.
|
106
|
+
#
|
107
|
+
# The required `code`
|
108
|
+
#
|
109
|
+
# @param [String] code the auth code which is passed in as a GET
|
110
|
+
# parameter to your `redirect_uri` after users authenticate your app
|
111
|
+
# @param [Hash] options
|
112
|
+
# @option options [String] :redirect_uri You normally should not have
|
113
|
+
# to pass in the redirect_uri again. If `auth_code_url` was called
|
114
|
+
# on this LinkedIn::OAuth2 instance, then the `redirect_uri` will
|
115
|
+
# already be set. This is because the `redirect_uri` in the access
|
116
|
+
# token request must exactly match the `redirect_uri` in the auth
|
117
|
+
# code url.
|
118
|
+
# @option options [Boolean] :raise_errors (true) whether or not to
|
119
|
+
# raise an error on malformed responses
|
120
|
+
def get_access_token(code=nil, options={})
|
121
|
+
check_for_code!(code)
|
122
|
+
options = default_access_code_options(options)
|
123
|
+
|
124
|
+
if self.options[:raise_errors]
|
125
|
+
check_access_code_url!(options)
|
126
|
+
end
|
127
|
+
|
128
|
+
tok = self.auth_code.get_token(code, options)
|
129
|
+
self.access_token = LinkedIn::AccessToken.new(tok.token,
|
130
|
+
tok.expires_in,
|
131
|
+
tok.expires_at)
|
132
|
+
return self.access_token
|
133
|
+
rescue ::OAuth2::Error => e
|
134
|
+
raise OAuthError.new(e.response)
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
private ##############################################################
|
139
|
+
|
140
|
+
|
141
|
+
def default_access_code_options(custom_options={})
|
142
|
+
custom_options ||= {}
|
143
|
+
options = {raise_errors: true}
|
144
|
+
|
145
|
+
@redirect_uri = LinkedIn.config.redirect_uri if @redirect_uri.nil?
|
146
|
+
options[:redirect_uri] = @redirect_uri
|
147
|
+
|
148
|
+
options = options.merge custom_options
|
149
|
+
return options
|
150
|
+
end
|
151
|
+
|
152
|
+
def default_auth_code_url_options(custom_options={})
|
153
|
+
custom_options ||= {}
|
154
|
+
options = {raise_errors: true}
|
155
|
+
|
156
|
+
if not LinkedIn.config.redirect_uri.nil?
|
157
|
+
options[:redirect_uri] = LinkedIn.config.redirect_uri
|
158
|
+
end
|
159
|
+
if not LinkedIn.config.scope.nil?
|
160
|
+
options[:scope] = LinkedIn.config.scope
|
161
|
+
end
|
162
|
+
|
163
|
+
options = options.merge custom_options
|
164
|
+
|
165
|
+
if options[:state].nil?
|
166
|
+
options[:state] = generate_csrf_token
|
167
|
+
end
|
168
|
+
|
169
|
+
return options
|
170
|
+
end
|
171
|
+
|
172
|
+
def generate_csrf_token
|
173
|
+
SecureRandom.base64(32)
|
174
|
+
end
|
175
|
+
|
176
|
+
def check_access_code_url!(options={})
|
177
|
+
check_redirect_uri!(options)
|
178
|
+
if options[:redirect_uri] != @redirect_uri
|
179
|
+
raise redirect_uri_mismatch
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def check_for_code!(code)
|
184
|
+
if code.nil?
|
185
|
+
msg = ErrorMessages.no_auth_code
|
186
|
+
raise InvalidRequest.new(msg)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def check_redirect_uri!(options={})
|
191
|
+
if options[:redirect_uri].nil?
|
192
|
+
raise redirect_uri_error
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def default_oauth_options(custom_options={})
|
197
|
+
custom_options ||= {}
|
198
|
+
options = {}
|
199
|
+
options[:site] = LinkedIn.config.site
|
200
|
+
options[:token_url] = LinkedIn.config.token_url
|
201
|
+
options[:authorize_url] = LinkedIn.config.authorize_url
|
202
|
+
return options.merge custom_options
|
203
|
+
end
|
204
|
+
|
205
|
+
def check_credentials!(client_id, client_secret)
|
206
|
+
if client_id.nil? or client_secret.nil?
|
207
|
+
raise credential_error
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def redirect_uri_error
|
212
|
+
InvalidRequest.new ErrorMessages.redirect_uri
|
213
|
+
end
|
214
|
+
|
215
|
+
def credential_error
|
216
|
+
InvalidRequest.new ErrorMessages.credentials_missing
|
217
|
+
end
|
218
|
+
|
219
|
+
def redirect_uri_mismatch
|
220
|
+
InvalidRequest.new ErrorMessages.redirect_uri_mismatch
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|