linkedin-v2 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|