Codebase list ruby-oauth2 / 7665479
Imported Upstream version 0.9.3 Cédric Boutillier 10 years ago
28 changed file(s) with 460 addition(s) and 415 deletion(s). Raw diff Collapse all Expand all
33 3. Add specs for your unimplemented feature or bug fix.
44 4. Run `bundle exec rake spec`. If your specs pass, return to step 3.
55 5. Implement your feature or bug fix.
6 6. Run `bundle exec rake spec`. If your specs fail, return to step 5.
6 6. Run `bundle exec rake`. If your specs fail, return to step 5.
77 7. Run `open coverage/index.html`. If your changes are not completely covered
88 by your tests, return to step 3.
9 8. Add, commit, and push your changes.
10 9. [Submit a pull request.][pr]
9 8. Add documentation for your feature or bug fix.
10 9. Run `bundle exec rake verify_measurements`. If your changes are not 100%
11 documented, go back to step 8.
12 10. Commit and push your changes.
13 11. [Submit a pull request.][pr]
1114
1215 [fork]: http://help.github.com/fork-a-repo/
1316 [branch]: http://learn.github.com/p/branching.html
00 # OAuth2
1
12 [![Gem Version](https://badge.fury.io/rb/oauth2.png)][gem]
23 [![Build Status](https://secure.travis-ci.org/intridea/oauth2.png?branch=master)][travis]
34 [![Dependency Status](https://gemnasium.com/intridea/oauth2.png?travis)][gemnasium]
45 [![Code Climate](https://codeclimate.com/github/intridea/oauth2.png)][codeclimate]
6 [![Coverage Status](https://coveralls.io/repos/intridea/oauth2/badge.png?branch=master)][coveralls]
57
68 [gem]: https://rubygems.org/gems/oauth2
79 [travis]: http://travis-ci.org/intridea/oauth2
810 [gemnasium]: https://gemnasium.com/intridea/oauth2
911 [codeclimate]: https://codeclimate.com/github/intridea/oauth2
12 [coveralls]: https://coveralls.io/r/intridea/oauth2
1013
1114 A Ruby wrapper for the OAuth 2.0 specification. This is a work in progress,
1215 being built first to solve the pragmatic process of connecting to existing
13 OAuth 2.0 endpoints (a.k.a. Facebook) with the goal of building it up to meet
16 OAuth 2.0 endpoints (e.g. Facebook) with the goal of building it up to meet
1417 the entire specification over time.
1518
1619 ## Installation
1720 gem install oauth2
18
19 To ensure the code you're installing hasn't been tampered with, it's
20 recommended that you verify the signature. To do this, you need to add my
21 public key as a trusted certificate (you only need to do this once):
22
23 gem cert --add <(curl -Ls https://gist.github.com/sferik/4701180/raw/public_cert.pem)
24
25 Then, install the gem with the high security trust policy:
26
27 gem install oauth2 -P HighSecurity
2821
2922 ## Resources
3023 * [View Source on GitHub][code]
3629 [wiki]: https://wiki.github.com/intridea/oauth2
3730
3831 ## Usage Examples
39 require 'oauth2'
40 client = OAuth2::Client.new('client_id', 'client_secret', :site => 'https://example.org')
4132
42 client.auth_code.authorize_url(:redirect_uri => 'http://localhost:8080/oauth2/callback')
43 # => "https://example.org/oauth/authorization?response_type=code&client_id=client_id&redirect_uri=http://localhost:8080/oauth2/callback"
33 ```ruby
34 require 'oauth2'
35 client = OAuth2::Client.new('client_id', 'client_secret', :site => 'https://example.org')
4436
45 token = client.auth_code.get_token('authorization_code_value', :redirect_uri => 'http://localhost:8080/oauth2/callback', :headers => {'Authorization' => 'Basic some_password'})
46 response = token.get('/api/resource', :params => { 'query_foo' => 'bar' })
47 response.class.name
48 # => OAuth2::Response
37 client.auth_code.authorize_url(:redirect_uri => 'http://localhost:8080/oauth2/callback')
38 # => "https://example.org/oauth/authorization?response_type=code&client_id=client_id&redirect_uri=http://localhost:8080/oauth2/callback"
4939
40 token = client.auth_code.get_token('authorization_code_value', :redirect_uri => 'http://localhost:8080/oauth2/callback', :headers => {'Authorization' => 'Basic some_password'})
41 response = token.get('/api/resource', :params => { 'query_foo' => 'bar' })
42 response.class.name
43 # => OAuth2::Response
44 ```
5045 ## OAuth2::Response
5146 The AccessToken methods #get, #post, #put and #delete and the generic #request
5247 will return an instance of the #OAuth2::Response class.
8176 authentication grant types have helper strategy classes that simplify client
8277 use. They are available via the #auth_code, #implicit, #password, #client_credentials, and #assertion methods respectively.
8378
84 auth_url = client.auth_code.authorize_url(:redirect_uri => 'http://localhost:8080/oauth/callback')
85 token = client.auth_code.get_token('code_value', :redirect_uri => 'http://localhost:8080/oauth/callback')
79 ```ruby
80 auth_url = client.auth_code.authorize_url(:redirect_uri => 'http://localhost:8080/oauth/callback')
81 token = client.auth_code.get_token('code_value', :redirect_uri => 'http://localhost:8080/oauth/callback')
8682
87 auth_url = client.implicit.authorize_url(:redirect_uri => 'http://localhost:8080/oauth/callback')
88 # get the token params in the callback and
89 token = OAuth2::AccessToken.from_kvform(client, query_string)
83 auth_url = client.implicit.authorize_url(:redirect_uri => 'http://localhost:8080/oauth/callback')
84 # get the token params in the callback and
85 token = OAuth2::AccessToken.from_kvform(client, query_string)
9086
91 token = client.password.get_token('username', 'password')
87 token = client.password.get_token('username', 'password')
9288
93 token = client.client_credentials.get_token
89 token = client.client_credentials.get_token
9490
95 token = client.assertion.get_token(assertion_params)
91 token = client.assertion.get_token(assertion_params)
92 ```
9693
9794 If you want to specify additional headers to be sent out with the
9895 request, add a 'headers' hash under 'params':
9996
100 token = client.auth_code.get_token('code_value', :redirect_uri => 'http://localhost:8080/oauth/callback', :headers => {'Some' => 'Header'})
97 ```ruby
98 token = client.auth_code.get_token('code_value', :redirect_uri => 'http://localhost:8080/oauth/callback', :headers => {'Some' => 'Header'})
99 ```
101100
102101 You can always use the #request method on the OAuth2::Client instance to make
103102 requests for tokens for any Authentication grant type.
110109 * Ruby 1.9.2
111110 * Ruby 1.9.3
112111 * Ruby 2.0.0
112 * Ruby 2.1.0
113113 * [JRuby][]
114114 * [Rubinius][]
115115
33 require 'rspec/core/rake_task'
44 RSpec::Core::RakeTask.new(:spec)
55
6 task :default => :spec
76 task :test => :spec
87
98 namespace :doc do
1615 rdoc.rdoc_files.include('README.md', 'LICENSE.md', 'lib/**/*.rb')
1716 end
1817 end
18
19 begin
20 require 'rubocop/rake_task'
21 Rubocop::RakeTask.new
22 rescue LoadError
23 task :rubocop do
24 $stderr.puts 'Rubocop is disabled'
25 end
26 end
27
28 require 'yardstick/rake/measurement'
29 Yardstick::Rake::Measurement.new do |measurement|
30 measurement.output = 'measurement/report.txt'
31 end
32
33 require 'yardstick/rake/verify'
34 Yardstick::Rake::Verify.new do |verify|
35 verify.threshold = 58.9
36 end
37
38 task :default => [:spec, :rubocop, :verify_measurements]
Binary diff not shown
Binary diff not shown
Binary diff not shown
99 # @param [Hash] a hash of AccessToken property values
1010 # @return [AccessToken] the initalized AccessToken
1111 def from_hash(client, hash)
12 self.new(client, hash.delete('access_token') || hash.delete(:access_token), hash)
12 new(client, hash.delete('access_token') || hash.delete(:access_token), hash)
1313 end
1414
1515 # Initializes an AccessToken from a key/value application/x-www-form-urlencoded string
3535 # @option opts [String] :header_format ('Bearer %s') the string format to use for the Authorization header
3636 # @option opts [String] :param_name ('access_token') the parameter name to use for transmission of the
3737 # Access Token value in :body or :query transmission mode
38 def initialize(client, token, opts={})
38 def initialize(client, token, opts = {})
3939 @client = client
4040 @token = token.to_s
4141 [:refresh_token, :expires_in, :expires_at].each do |arg|
7676 #
7777 # @return [AccessToken] a new AccessToken
7878 # @note options should be carried over to the new AccessToken
79 def refresh!(params={})
80 raise "A refresh_token is not available" unless refresh_token
79 def refresh!(params = {})
80 fail('A refresh_token is not available') unless refresh_token
8181 params.merge!(:client_id => @client.id,
8282 :client_secret => @client.secret,
8383 :grant_type => 'refresh_token',
8888 new_token
8989 end
9090
91 # Convert AccessToken to a hash which can be used to rebuild itself with AccessToken.from_hash
92 #
93 # @return [Hash] a hash of AccessToken property values
94 def to_hash
95 params.merge(:access_token => token, :refresh_token => refresh_token, :expires_at => expires_at)
96 end
97
9198 # Make a request with the Access Token
9299 #
93100 # @param [Symbol] verb the HTTP request method
94101 # @param [String] path the HTTP URL path of the request
95102 # @param [Hash] opts the options to make the request with
96103 # @see Client#request
97 def request(verb, path, opts={}, &block)
98 set_token(opts)
104 def request(verb, path, opts = {}, &block)
105 self.token = opts
99106 @client.request(verb, path, opts, &block)
100107 end
101108
102109 # Make a GET request with the Access Token
103110 #
104111 # @see AccessToken#request
105 def get(path, opts={}, &block)
112 def get(path, opts = {}, &block)
106113 request(:get, path, opts, &block)
107114 end
108115
109116 # Make a POST request with the Access Token
110117 #
111118 # @see AccessToken#request
112 def post(path, opts={}, &block)
119 def post(path, opts = {}, &block)
113120 request(:post, path, opts, &block)
114121 end
115122
116123 # Make a PUT request with the Access Token
117124 #
118125 # @see AccessToken#request
119 def put(path, opts={}, &block)
126 def put(path, opts = {}, &block)
120127 request(:put, path, opts, &block)
121128 end
122129
123130 # Make a PATCH request with the Access Token
124131 #
125132 # @see AccessToken#request
126 def patch(path, opts={}, &block)
133 def patch(path, opts = {}, &block)
127134 request(:patch, path, opts, &block)
128135 end
129136
130137 # Make a DELETE request with the Access Token
131138 #
132139 # @see AccessToken#request
133 def delete(path, opts={}, &block)
140 def delete(path, opts = {}, &block)
134141 request(:delete, path, opts, &block)
135142 end
136143
137144 # Get the headers hash (includes Authorization token)
138145 def headers
139 { 'Authorization' => options[:header_format] % token }
146 {'Authorization' => options[:header_format] % token}
140147 end
141148
142149 private
143 def set_token(opts)
150
151 def token=(opts) # rubocop:disable MethodLength
144152 case options[:mode]
145153 when :header
146154 opts[:headers] ||= {}
157165 end
158166 # @todo support for multi-part (file uploads)
159167 else
160 raise "invalid :mode option of #{options[:mode]}"
168 fail("invalid :mode option of #{options[:mode]}")
161169 end
162170 end
163171 end
2222 # @option opts [Boolean] :raise_errors (true) whether or not to raise an OAuth2::Error
2323 # on responses with 400+ status codes
2424 # @yield [builder] The Faraday connection builder
25 def initialize(client_id, client_secret, opts={}, &block)
25 def initialize(client_id, client_secret, opts = {}, &block)
26 _opts = opts.dup
2627 @id = client_id
2728 @secret = client_secret
28 @site = opts.delete(:site)
29 ssl = opts.delete(:ssl)
29 @site = _opts.delete(:site)
30 ssl = _opts.delete(:ssl)
3031 @options = {:authorize_url => '/oauth/authorize',
3132 :token_url => '/oauth/token',
3233 :token_method => :post,
3334 :connection_opts => {},
3435 :connection_build => block,
3536 :max_redirects => 5,
36 :raise_errors => true}.merge(opts)
37 :raise_errors => true}.merge(_opts)
3738 @options[:connection_opts][:ssl] = ssl if ssl
3839 end
3940
5960 # The authorize endpoint URL of the OAuth2 provider
6061 #
6162 # @param [Hash] params additional query parameters
62 def authorize_url(params=nil)
63 def authorize_url(params = nil)
6364 connection.build_url(options[:authorize_url], params).to_s
6465 end
6566
6667 # The token endpoint URL of the OAuth2 provider
6768 #
6869 # @param [Hash] params additional query parameters
69 def token_url(params=nil)
70 def token_url(params = nil)
7071 connection.build_url(options[:token_url], params).to_s
7172 end
7273
8283 # code response for this request. Will default to client option
8384 # @option opts [Symbol] :parse @see Response::initialize
8485 # @yield [req] The Faraday request
85 def request(verb, url, opts={})
86 url = self.connection.build_url(url, opts[:params]).to_s
86 def request(verb, url, opts = {}) # rubocop:disable CyclomaticComplexity, MethodLength
87 url = connection.build_url(url, opts[:params]).to_s
8788
8889 response = connection.run_request(verb, url, opts[:body], opts[:headers]) do |req|
8990 yield(req) if block_given?
104105 # on non-redirecting 3xx statuses, just return the response
105106 response
106107 when 400..599
107 e = Error.new(response)
108 raise e if opts[:raise_errors] || options[:raise_errors]
109 response.error = e
108 error = Error.new(response)
109 fail(error) if opts.fetch(:raise_errors, options[:raise_errors])
110 response.error = error
110111 response
111112 else
112 raise Error.new(response), "Unhandled status code value of #{response.status}"
113 error = Error.new(response)
114 fail(error, "Unhandled status code value of #{response.status}")
113115 end
114116 end
115117
117119 #
118120 # @param [Hash] params a Hash of params for the token endpoint
119121 # @param [Hash] access token options, to pass to the AccessToken object
122 # @param [Class] class of access token for easier subclassing OAuth2::AccessToken
120123 # @return [AccessToken] the initalized AccessToken
121 def get_token(params, access_token_opts={})
124 def get_token(params, access_token_opts = {}, access_token_class = AccessToken)
122125 opts = {:raise_errors => options[:raise_errors], :parse => params.delete(:parse)}
123126 if options[:token_method] == :post
124127 headers = params.delete(:headers)
129132 opts[:params] = params
130133 end
131134 response = request(options[:token_method], token_url, opts)
132 raise Error.new(response) if options[:raise_errors] && !(response.parsed.is_a?(Hash) && response.parsed['access_token'])
133 AccessToken.from_hash(self, response.parsed.merge(access_token_opts))
135 error = Error.new(response)
136 fail(error) if options[:raise_errors] && !(response.parsed.is_a?(Hash) && response.parsed['access_token'])
137 access_token_class.from_hash(self, response.parsed.merge(access_token_opts))
134138 end
135139
136140 # The Authorization Code strategy
00 require 'multi_json'
1 require 'multi_xml'
12 require 'rack'
23
34 module OAuth2
2526 # @param [Hash] opts options in which to initialize the instance
2627 # @option opts [Symbol] :parse (:automatic) how to parse the response body. one of :query (for x-www-form-urlencoded),
2728 # :json, or :automatic (determined by Content-Type response header)
28 def initialize(response, opts={})
29 def initialize(response, opts = {})
2930 @response = response
3031 @options = {:parse => :automatic}.merge(opts)
3132 end
4849 # Procs that, when called, will parse a response body according
4950 # to the specified format.
5051 PARSERS = {
51 # Can't reliably detect whether MultiJson responds to load, since it's
52 # a reserved word. Use adapter as a proxy for new features.
53 :json => lambda{ |body| MultiJson.respond_to?(:adapter) ? MultiJson.load(body) : MultiJson.decode(body) rescue body },
54 :query => lambda{ |body| Rack::Utils.parse_query(body) },
55 :text => lambda{ |body| body }
52 :json => lambda { |body| MultiJson.load(body) rescue body }, # rubocop:disable RescueModifier
53 :query => lambda { |body| Rack::Utils.parse_query(body) },
54 :text => lambda { |body| body }
5655 }
5756
5857 # Content type assignments for various potential HTTP content types.
8483 end
8584 end
8685
87 begin
88 require 'multi_xml'
89 OAuth2::Response.register_parser(:xml, ['text/xml', 'application/rss+xml', 'application/rdf+xml', 'application/atom+xml']) do |body|
90 MultiXml.parse(body) rescue body
91 end
92 rescue LoadError; end
86 OAuth2::Response.register_parser(:xml, ['text/xml', 'application/rss+xml', 'application/rdf+xml', 'application/atom+xml']) do |body|
87 MultiXml.parse(body) rescue body # rubocop:disable RescueModifier
88 end
0 require 'httpauth'
10 require 'jwt'
21
32 module OAuth2
2524 #
2625 # @raise [NotImplementedError]
2726 def authorize_url
28 raise NotImplementedError, "The authorization endpoint is not used in this strategy"
27 fail(NotImplementedError, 'The authorization endpoint is not used in this strategy')
2928 end
3029
3130 # Retrieve an access token given the specified client.
4241 # params :exp, expired at, in seconds, like Time.now.utc.to_i + 3600
4342 #
4443 # @param [Hash] opts options
45 def get_token(params={}, opts={})
44 def get_token(params = {}, opts = {})
4645 hash = build_request(params)
4746 @client.get_token(hash, opts.merge('refresh_token' => nil))
4847 end
4948
5049 def build_request(params)
5150 assertion = build_assertion(params)
52 {:grant_type => "assertion",
53 :assertion_type => "urn:ietf:params:oauth:grant-type:jwt-bearer",
51 {:grant_type => 'assertion',
52 :assertion_type => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
5453 :assertion => assertion,
5554 :scope => params[:scope]
5655 }.merge(client_params)
6362 :exp => params[:exp]
6463 }
6564 if params[:hmac_secret]
66 jwt_assertion = JWT.encode(claims, params[:hmac_secret], "HS256")
65 JWT.encode(claims, params[:hmac_secret], 'HS256')
6766 elsif params[:private_key]
68 jwt_assertion = JWT.encode(claims, params[:private_key], "RS256")
67 JWT.encode(claims, params[:private_key], 'RS256')
6968 end
7069 end
7170 end
7271 end
7372 end
74
66 # The required query parameters for the authorize URL
77 #
88 # @param [Hash] params additional query parameters
9 def authorize_params(params={})
9 def authorize_params(params = {})
1010 params.merge('response_type' => 'code', 'client_id' => @client.id)
1111 end
1212
1313 # The authorization URL endpoint of the provider
1414 #
1515 # @param [Hash] params additional query parameters for the URL
16 def authorize_url(params={})
16 def authorize_url(params = {})
1717 @client.authorize_url(authorize_params.merge(params))
1818 end
1919
2323 # @param [Hash] params additional params
2424 # @param [Hash] opts options
2525 # @note that you must also provide a :redirect_uri with most OAuth 2.0 providers
26 def get_token(code, params={}, opts={})
26 def get_token(code, params = {}, opts = {})
2727 params = {'grant_type' => 'authorization_code', 'code' => code}.merge(client_params).merge(params)
2828 @client.get_token(params, opts)
2929 end
0 require 'httpauth'
0 require 'base64'
11
22 module OAuth2
33 module Strategy
99 #
1010 # @raise [NotImplementedError]
1111 def authorize_url
12 raise NotImplementedError, "The authorization endpoint is not used in this strategy"
12 fail(NotImplementedError, 'The authorization endpoint is not used in this strategy')
1313 end
1414
1515 # Retrieve an access token given the specified client.
1616 #
1717 # @param [Hash] params additional params
1818 # @param [Hash] opts options
19 def get_token(params={}, opts={})
19 def get_token(params = {}, opts = {})
2020 request_body = opts.delete('auth_scheme') == 'request_body'
2121 params.merge!('grant_type' => 'client_credentials')
22 params.merge!(request_body ? client_params : {:headers => {'Authorization' => HTTPAuth::Basic.pack_authorization(client_params['client_id'], client_params['client_secret'])}})
22 params.merge!(request_body ? client_params : {:headers => {'Authorization' => authorization(client_params['client_id'], client_params['client_secret'])}})
2323 @client.get_token(params, opts.merge('refresh_token' => nil))
24 end
25
26 # Returns the Authorization header value for Basic Authentication
27 #
28 # @param [String] The client ID
29 # @param [String] the client secret
30 def authorization(client_id, client_secret)
31 'Basic ' + Base64.encode64(client_id + ':' + client_secret).gsub("\n", '')
2432 end
2533 end
2634 end
66 # The required query parameters for the authorize URL
77 #
88 # @param [Hash] params additional query parameters
9 def authorize_params(params={})
9 def authorize_params(params = {})
1010 params.merge('response_type' => 'token', 'client_id' => @client.id)
1111 end
1212
1313 # The authorization URL endpoint of the provider
1414 #
1515 # @param [Hash] params additional query parameters for the URL
16 def authorize_url(params={})
16 def authorize_url(params = {})
1717 @client.authorize_url(authorize_params.merge(params))
1818 end
1919
2121 #
2222 # @raise [NotImplementedError]
2323 def get_token(*)
24 raise NotImplementedError, "The token is accessed differently in this strategy"
24 fail(NotImplementedError, 'The token is accessed differently in this strategy')
2525 end
2626 end
2727 end
77 #
88 # @raise [NotImplementedError]
99 def authorize_url
10 raise NotImplementedError, "The authorization endpoint is not used in this strategy"
10 fail(NotImplementedError, 'The authorization endpoint is not used in this strategy')
1111 end
1212
1313 # Retrieve an access token given the specified End User username and password.
1515 # @param [String] username the End User username
1616 # @param [String] password the End User password
1717 # @param [Hash] params additional params
18 def get_token(username, password, params={}, opts={})
18 def get_token(username, password, params = {}, opts = {})
1919 params = {'grant_type' => 'password',
2020 'username' => username,
2121 'password' => password}.merge(client_params).merge(params)
00 module OAuth2
11 class Version
2 MAJOR = 0 unless defined? MAJOR
3 MINOR = 9 unless defined? MINOR
4 PATCH = 1 unless defined? PATCH
5 PRE = nil unless defined? PRE
2 MAJOR = 0
3 MINOR = 9
4 PATCH = 3
5 PRE = nil
66
77 class << self
8
98 # @return [String]
109 def to_s
1110 [MAJOR, MINOR, PATCH, PRE].compact.join('.')
1211 end
13
1412 end
15
1613 end
1714 end
0 &3¤ß0wQ0{Ce1>ª†ð¤ÆA#˜Ò÷”Iøõ„²Î9ušþ ü_ÔåØÜÔc>í5n‚+ÊïłÝCVò®æ~þ‘ë&$#ž2wab£Š¡‚‡Oõ¹KiUy£zy#};½*¶5¥w‰*QÓ=±Û´ZG…cÆZl¸<!kÀ¹Eݨê6¾(Ø[ª‚:F_iMÑïúÍ
1 ˜]ÉSËI¼¬dìÀQН¶‹Ü1ð0’SŒ9W§|ò1H`^ÀÀ('¹Æ T/uÁˆ#1Q52Å;àêsâʦaLúì2@ˆ–¤¶jfgòÁ·ëŠÿN»Û¯
2 sเว
0 uHFï3,ìÕ"߅vÏŸ2{>‰têAé–jäOâB'ú•Ù=G)º/š‰I ­5/!¼v˜uÖ$Úþå2Rà¥Ð[B<z¼…›~苮ïˆNüCj¤måj‘ehÍÇèÈvK‰È0hlÆ#ć:DH-¢#LmÍzZX!ERÅ 1¡IøÇb8iWàË m´QaúÈ
1 0ºyŒ3CTMþ™›M€P‚0}KØûy¯»µÔ¬ÌÊ ¹—þ®ïT‰ 7³"ç§åWLˆI%¿/™M
2 ┐щa_ўнс?Ф┐░ЮhIэF¤ИsС╦┐Y=іlЪ#kAД.8╣▀њMB░E┴~┴S
00 --- !ruby/object:Gem::Specification
11 name: oauth2
22 version: !ruby/object:Gem::Version
3 version: 0.9.1
4 prerelease:
3 version: 0.9.3
54 platform: ruby
65 authors:
76 - Michael Bleigh
98 autorequire:
109 bindir: bin
1110 cert_chain:
12 - !binary |-
13 LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURMakNDQWhhZ0F3SUJB
14 Z0lCQURBTkJna3Foa2lHOXcwQkFRVUZBREE5TVE4d0RRWURWUVFEREFaelpt
15 VnkKYVdzeEZUQVRCZ29Ka2lhSmsvSXNaQUVaRmdWbmJXRnBiREVUTUJFR0Nn
16 bVNKb21UOGl4a0FSa1dBMk52YlRBZQpGdzB4TXpBeU1ETXhNREF5TWpkYUZ3
17 MHhOREF5TURNeE1EQXlNamRhTUQweER6QU5CZ05WQkFNTUJuTm1aWEpwCmF6
18 RVZNQk1HQ2dtU0pvbVQ4aXhrQVJrV0JXZHRZV2xzTVJNd0VRWUtDWkltaVpQ
19 eUxHUUJHUllEWTI5dE1JSUIKSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4
20 QU1JSUJDZ0tDQVFFQWwweDVkeDh1S3hpN1Rrckl1eUJVVEpWQgp2MW85M25V
21 QjlqL3k0TTk2Z1Yycll3QWNpMUpQQnNlTmQ2RnliempvM1lHdUhsN0VRSHVT
22 SE5hZjFwMmx4ZXcvCnk2MEpYSUpCQmdQY0RLL0tDUDROVUhvZm0wamZvWUQr
23 SDV1TkpmSENOcTcvWnNUeE90RTNSYTkyczBCQ01UcG0Kd0JNTWxXUjVNdGRF
24 aElZdUJPNFhobmVqWWdIMEwvN0JMMmx5bW50Vm5zci9hZ2RRb29qUUNOMUlR
25 bXNSSnZyUgpkdVpSTzN0WnZvSW8xcEJjNEpFZWhEdXFDZXlCZ1BMT3FNb0t0
26 UWxvbGQxVFFzMWtXVUJLN0tXTUZFaEtDL0tnCnp5ektSSFFvOXlEWXdPdllu
27 Z29CTFkrVC9sd0NUNGR5c3NkaHpSYmZueEFoYUt1NFNBc3NJd2FDMDF5Vm93
28 SUQKQVFBQm96a3dOekFKQmdOVkhSTUVBakFBTUIwR0ExVWREZ1FXQkJTMHJ1
29 RGZSYWs1Y2kxT3BETlgvWmRERWtJcwppVEFMQmdOVkhROEVCQU1DQkxBd0RR
30 WUpLb1pJaHZjTkFRRUZCUUFEZ2dFQkFISFNNcy9NUDBzT2FMa0V2NEpvCnp2
31 a20zcW41QTZ0MHZhSHg3NzRjbWVqeU1VKzV3eVN4UmV6c3BMN1VMaDlOZXVL
32 Mk9oVStPZTNUcHFyQWc1VEsKUjhHUUlMblZ1MkZlbUdBNnNBa1BEbGNQdGdB
33 NmllSTE5UFpPRjZIVkxtYy9JRC9kUC9OZ1pXV3pFZXFRS21jSwoyK0hNK1NF
34 RURoWmtTY1lla3c0Wk9lMTY0WnRaRzgxNm9BdjV4MHBHaXRTSWt1bVVwN1Y4
35 aUVaLzZlaHI3WTllClhPZzRlZXVuNUwvSmptakFSb1cya05kdmtSRDNjMkVl
36 U0xxV3ZRUnNCbHlwSGZoczZKSnVMbHlaUEdoVTNSL3YKU2YzbFZLcEJDV2dS
37 cEdUdnk0NVhWcEIrNTl5MzNQSm1FdVExUFRFT1l2UXlhbzlVS01BQWFBTi83
38 cVdRdGpsMApobHc9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
39 date: 2013-02-20 00:00:00.000000000 Z
11 - |
12 -----BEGIN CERTIFICATE-----
13 MIIDLjCCAhagAwIBAgIBADANBgkqhkiG9w0BAQUFADA9MQ8wDQYDVQQDDAZzZmVy
14 aWsxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2NvbTAe
15 Fw0xMzAyMDMxMDAyMjdaFw0xNDAyMDMxMDAyMjdaMD0xDzANBgNVBAMMBnNmZXJp
16 azEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYDY29tMIIB
17 IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl0x5dx8uKxi7TkrIuyBUTJVB
18 v1o93nUB9j/y4M96gV2rYwAci1JPBseNd6Fybzjo3YGuHl7EQHuSHNaf1p2lxew/
19 y60JXIJBBgPcDK/KCP4NUHofm0jfoYD+H5uNJfHCNq7/ZsTxOtE3Ra92s0BCMTpm
20 wBMMlWR5MtdEhIYuBO4XhnejYgH0L/7BL2lymntVnsr/agdQoojQCN1IQmsRJvrR
21 duZRO3tZvoIo1pBc4JEehDuqCeyBgPLOqMoKtQlold1TQs1kWUBK7KWMFEhKC/Kg
22 zyzKRHQo9yDYwOvYngoBLY+T/lwCT4dyssdhzRbfnxAhaKu4SAssIwaC01yVowID
23 AQABozkwNzAJBgNVHRMEAjAAMB0GA1UdDgQWBBS0ruDfRak5ci1OpDNX/ZdDEkIs
24 iTALBgNVHQ8EBAMCBLAwDQYJKoZIhvcNAQEFBQADggEBAHHSMs/MP0sOaLkEv4Jo
25 zvkm3qn5A6t0vaHx774cmejyMU+5wySxRezspL7ULh9NeuK2OhU+Oe3TpqrAg5TK
26 R8GQILnVu2FemGA6sAkPDlcPtgA6ieI19PZOF6HVLmc/ID/dP/NgZWWzEeqQKmcK
27 2+HM+SEEDhZkScYekw4ZOe164ZtZG816oAv5x0pGitSIkumUp7V8iEZ/6ehr7Y9e
28 XOg4eeun5L/JjmjARoW2kNdvkRD3c2EeSLqWvQRsBlypHfhs6JJuLlyZPGhU3R/v
29 Sf3lVKpBCWgRpGTvy45XVpB+59y33PJmEuQ1PTEOYvQyao9UKMAAaAN/7qWQtjl0
30 hlw=
31 -----END CERTIFICATE-----
32 date: 2014-01-16 00:00:00.000000000 Z
4033 dependencies:
4134 - !ruby/object:Gem::Dependency
4235 name: bundler
4336 requirement: !ruby/object:Gem::Requirement
44 none: false
4537 requirements:
46 - - ~>
38 - - "~>"
4739 - !ruby/object:Gem::Version
4840 version: '1.0'
4941 type: :development
5042 prerelease: false
5143 version_requirements: !ruby/object:Gem::Requirement
52 none: false
5344 requirements:
54 - - ~>
45 - - "~>"
5546 - !ruby/object:Gem::Version
5647 version: '1.0'
5748 - !ruby/object:Gem::Dependency
5849 name: faraday
5950 requirement: !ruby/object:Gem::Requirement
60 none: false
6151 requirements:
62 - - ~>
52 - - ">="
6353 - !ruby/object:Gem::Version
6454 version: '0.8'
55 - - "<"
56 - !ruby/object:Gem::Version
57 version: '0.10'
6558 type: :runtime
6659 prerelease: false
6760 version_requirements: !ruby/object:Gem::Requirement
68 none: false
6961 requirements:
70 - - ~>
62 - - ">="
7163 - !ruby/object:Gem::Version
7264 version: '0.8'
65 - - "<"
66 - !ruby/object:Gem::Version
67 version: '0.10'
7368 - !ruby/object:Gem::Dependency
74 name: httpauth
69 name: multi_json
7570 requirement: !ruby/object:Gem::Requirement
76 none: false
7771 requirements:
78 - - ~>
72 - - "~>"
7973 - !ruby/object:Gem::Version
80 version: '0.1'
74 version: '1.3'
8175 type: :runtime
8276 prerelease: false
8377 version_requirements: !ruby/object:Gem::Requirement
84 none: false
8578 requirements:
86 - - ~>
79 - - "~>"
8780 - !ruby/object:Gem::Version
88 version: '0.1'
89 - !ruby/object:Gem::Dependency
90 name: multi_json
91 requirement: !ruby/object:Gem::Requirement
92 none: false
93 requirements:
94 - - ~>
95 - !ruby/object:Gem::Version
96 version: '1.0'
97 type: :runtime
98 prerelease: false
99 version_requirements: !ruby/object:Gem::Requirement
100 none: false
101 requirements:
102 - - ~>
103 - !ruby/object:Gem::Version
104 version: '1.0'
81 version: '1.3'
10582 - !ruby/object:Gem::Dependency
10683 name: multi_xml
10784 requirement: !ruby/object:Gem::Requirement
108 none: false
10985 requirements:
110 - - ~>
86 - - "~>"
11187 - !ruby/object:Gem::Version
11288 version: '0.5'
11389 type: :runtime
11490 prerelease: false
11591 version_requirements: !ruby/object:Gem::Requirement
116 none: false
11792 requirements:
118 - - ~>
93 - - "~>"
11994 - !ruby/object:Gem::Version
12095 version: '0.5'
12196 - !ruby/object:Gem::Dependency
12297 name: rack
12398 requirement: !ruby/object:Gem::Requirement
124 none: false
12599 requirements:
126 - - ~>
100 - - "~>"
127101 - !ruby/object:Gem::Version
128102 version: '1.2'
129103 type: :runtime
130104 prerelease: false
131105 version_requirements: !ruby/object:Gem::Requirement
132 none: false
133106 requirements:
134 - - ~>
107 - - "~>"
135108 - !ruby/object:Gem::Version
136109 version: '1.2'
137110 - !ruby/object:Gem::Dependency
138111 name: jwt
139112 requirement: !ruby/object:Gem::Requirement
140 none: false
141113 requirements:
142 - - ~>
114 - - "~>"
143115 - !ruby/object:Gem::Version
144 version: 0.1.4
116 version: 0.1.8
145117 type: :runtime
146118 prerelease: false
147119 version_requirements: !ruby/object:Gem::Requirement
148 none: false
149120 requirements:
150 - - ~>
121 - - "~>"
151122 - !ruby/object:Gem::Version
152 version: 0.1.4
123 version: 0.1.8
153124 description: A Ruby wrapper for the OAuth 2.0 protocol built with a similar style
154125 to the original OAuth spec.
155126 email:
159130 extensions: []
160131 extra_rdoc_files: []
161132 files:
162 - .document
133 - ".document"
163134 - CONTRIBUTING.md
164135 - LICENSE.md
165136 - README.md
166137 - Rakefile
167 - oauth2.gemspec
138 - lib/oauth2.rb
168139 - lib/oauth2/access_token.rb
169140 - lib/oauth2/client.rb
170141 - lib/oauth2/error.rb
176147 - lib/oauth2/strategy/implicit.rb
177148 - lib/oauth2/strategy/password.rb
178149 - lib/oauth2/version.rb
179 - lib/oauth2.rb
150 - oauth2.gemspec
180151 - spec/helper.rb
181152 - spec/oauth2/access_token_spec.rb
182153 - spec/oauth2/client_spec.rb
190161 homepage: http://github.com/intridea/oauth2
191162 licenses:
192163 - MIT
164 metadata: {}
193165 post_install_message:
194166 rdoc_options: []
195167 require_paths:
196168 - lib
197169 required_ruby_version: !ruby/object:Gem::Requirement
198 none: false
199170 requirements:
200 - - ! '>='
171 - - ">="
201172 - !ruby/object:Gem::Version
202173 version: '0'
203174 required_rubygems_version: !ruby/object:Gem::Requirement
204 none: false
205175 requirements:
206 - - ! '>='
176 - - ">="
207177 - !ruby/object:Gem::Version
208 version: 1.3.6
178 version: 1.3.5
209179 requirements: []
210180 rubyforge_project:
211 rubygems_version: 1.8.23
181 rubygems_version: 2.2.0
212182 signing_key:
213 specification_version: 3
183 specification_version: 4
214184 summary: A Ruby wrapper for the OAuth 2.0 protocol.
215185 test_files:
216186 - spec/helper.rb
44
55 Gem::Specification.new do |spec|
66 spec.add_development_dependency 'bundler', '~> 1.0'
7 spec.add_dependency 'faraday', '~> 0.8'
8 spec.add_dependency 'httpauth', '~> 0.1'
9 spec.add_dependency 'multi_json', '~> 1.0'
7 spec.add_dependency 'faraday', ['>= 0.8', '< 0.10']
8 spec.add_dependency 'multi_json', '~> 1.3'
109 spec.add_dependency 'multi_xml', '~> 0.5'
1110 spec.add_dependency 'rack', '~> 1.2'
12 spec.add_dependency 'jwt', '~> 0.1.4'
13 spec.authors = ["Michael Bleigh", "Erik Michaels-Ober"]
11 spec.add_dependency 'jwt', '~> 0.1.8'
12 spec.authors = ['Michael Bleigh', 'Erik Michaels-Ober']
1413 spec.cert_chain = %w(certs/sferik.pem)
1514 spec.description = %q{A Ruby wrapper for the OAuth 2.0 protocol built with a similar style to the original OAuth spec.}
1615 spec.email = ['michael@intridea.com', 'sferik@gmail.com']
1716 spec.files = %w(.document CONTRIBUTING.md LICENSE.md README.md Rakefile oauth2.gemspec)
18 spec.files += Dir.glob("lib/**/*.rb")
19 spec.files += Dir.glob("spec/**/*")
17 spec.files += Dir.glob('lib/**/*.rb')
18 spec.files += Dir.glob('spec/**/*')
2019 spec.homepage = 'http://github.com/intridea/oauth2'
2120 spec.licenses = ['MIT']
2221 spec.name = 'oauth2'
2322 spec.require_paths = ['lib']
24 spec.required_rubygems_version = '>= 1.3.6'
25 spec.signing_key = File.expand_path("~/.gem/private_key.pem") if $0 =~ /gem\z/
23 spec.required_rubygems_version = '>= 1.3.5'
24 spec.signing_key = File.expand_path('~/.gem/private_key.pem') if $PROGRAM_NAME =~ /gem\z/
2625 spec.summary = %q{A Ruby wrapper for the OAuth 2.0 protocol.}
27 spec.test_files = Dir.glob("spec/**/*")
26 spec.test_files = Dir.glob('spec/**/*')
2827 spec.version = OAuth2::Version
2928 end
0 unless ENV['CI']
1 require 'simplecov'
2 SimpleCov.start do
3 add_filter 'spec'
4 end
0 require 'simplecov'
1 require 'coveralls'
2
3 SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
4 SimpleCov::Formatter::HTMLFormatter,
5 Coveralls::SimpleCov::Formatter
6 ]
7
8 SimpleCov.start do
9 add_filter '/spec/'
10 minimum_coverage(95.29)
511 end
612
713 require 'oauth2'
22 VERBS = [:get, :post, :put, :delete]
33
44 describe AccessToken do
5 let(:token) {'monkey'}
6 let(:token_body) {MultiJson.encode(:access_token => 'foo', :expires_in => 600, :refresh_token => 'bar')}
7 let(:refresh_body) {MultiJson.encode(:access_token => 'refreshed_foo', :expires_in => 600, :refresh_token => 'refresh_bar')}
5 let(:token) { 'monkey' }
6 let(:token_body) { MultiJson.encode(:access_token => 'foo', :expires_in => 600, :refresh_token => 'bar') }
7 let(:refresh_body) { MultiJson.encode(:access_token => 'refreshed_foo', :expires_in => 600, :refresh_token => 'refresh_bar') }
88 let(:client) do
99 Client.new('abc', 'def', :site => 'https://api.example.com') do |builder|
1010 builder.request :url_encoded
1111 builder.adapter :test do |stub|
1212 VERBS.each do |verb|
13 stub.send(verb, '/token/header') {|env| [200, {}, env[:request_headers]['Authorization']]}
14 stub.send(verb, "/token/query?access_token=#{token}") {|env| [200, {}, Addressable::URI.parse(env[:url]).query_values['access_token']]}
15 stub.send(verb, '/token/body') {|env| [200, {}, env[:body]]}
13 stub.send(verb, '/token/header') { |env| [200, {}, env[:request_headers]['Authorization']] }
14 stub.send(verb, "/token/query?access_token=#{token}") { |env| [200, {}, Addressable::URI.parse(env[:url]).query_values['access_token']] }
15 stub.send(verb, '/token/body') { |env| [200, {}, env[:body]] }
1616 end
17 stub.post('/oauth/token') {|env| [200, {'Content-Type' => 'application/json'}, refresh_body]}
17 stub.post('/oauth/token') { |env| [200, {'Content-Type' => 'application/json'}, refresh_body] }
1818 end
1919 end
2020 end
2121
22 subject {AccessToken.new(client, token)}
22 subject { AccessToken.new(client, token) }
2323
24 describe "#initialize" do
25 it "assigns client and token" do
24 describe '#initialize' do
25 it 'assigns client and token' do
2626 expect(subject.client).to eq(client)
2727 expect(subject.token).to eq(token)
2828 end
2929
30 it "assigns extra params" do
30 it 'assigns extra params' do
3131 target = AccessToken.new(client, token, 'foo' => 'bar')
3232 expect(target.params).to include('foo')
3333 expect(target.params['foo']).to eq('bar')
4040 expect(target.params['foo']).to eq('bar')
4141 end
4242
43 it "initializes with a Hash" do
43 it 'initializes with a Hash' do
4444 hash = {:access_token => token, :expires_at => Time.now.to_i + 200, 'foo' => 'bar'}
4545 target = AccessToken.from_hash(client, hash)
4646 assert_initialized_token(target)
4747 end
4848
49 it "initalizes with a form-urlencoded key/value string" do
50 kvform = "access_token=#{token}&expires_at=#{Time.now.to_i+200}&foo=bar"
49 it 'initalizes with a form-urlencoded key/value string' do
50 kvform = "access_token=#{token}&expires_at=#{Time.now.to_i + 200}&foo=bar"
5151 target = AccessToken.from_kvform(client, kvform)
5252 assert_initialized_token(target)
5353 end
5454
55 it "sets options" do
55 it 'sets options' do
5656 target = AccessToken.new(client, token, :param_name => 'foo', :header_format => 'Bearer %', :mode => :body)
5757 expect(target.options[:param_name]).to eq('foo')
5858 expect(target.options[:header_format]).to eq('Bearer %')
5959 expect(target.options[:mode]).to eq(:body)
6060 end
61
62 it "initializes with a string expires_at" do
61
62 it 'initializes with a string expires_at' do
6363 hash = {:access_token => token, :expires_at => '1361396829', 'foo' => 'bar'}
6464 target = AccessToken.from_hash(client, hash)
6565 assert_initialized_token(target)
6767 end
6868 end
6969
70 describe "#request" do
71 context ":mode => :header" do
72 before :all do
70 describe '#request' do
71 context ':mode => :header' do
72 before do
7373 subject.options[:mode] = :header
7474 end
7575
8080 end
8181 end
8282
83 context ":mode => :query" do
84 before :all do
83 context ':mode => :query' do
84 before do
8585 subject.options[:mode] = :query
8686 end
8787
9292 end
9393 end
9494
95 context ":mode => :body" do
96 before :all do
95 context ':mode => :body' do
96 before do
9797 subject.options[:mode] = :body
9898 end
9999
105105 end
106106 end
107107
108 describe "#expires?" do
109 it "is false if there is no expires_at" do
108 describe '#expires?' do
109 it 'is false if there is no expires_at' do
110110 expect(AccessToken.new(client, token)).not_to be_expires
111111 end
112112
113 it "is true if there is an expires_in" do
113 it 'is true if there is an expires_in' do
114114 expect(AccessToken.new(client, token, :refresh_token => 'abaca', :expires_in => 600)).to be_expires
115115 end
116116
117 it "is true if there is an expires_at" do
118 expect(AccessToken.new(client, token, :refresh_token => 'abaca', :expires_in => Time.now.getutc.to_i+600)).to be_expires
117 it 'is true if there is an expires_at' do
118 expect(AccessToken.new(client, token, :refresh_token => 'abaca', :expires_in => Time.now.getutc.to_i + 600)).to be_expires
119119 end
120120 end
121121
122 describe "#expired?" do
123 it "is false if there is no expires_in or expires_at" do
122 describe '#expired?' do
123 it 'is false if there is no expires_in or expires_at' do
124124 expect(AccessToken.new(client, token)).not_to be_expired
125125 end
126126
127 it "is false if expires_in is in the future" do
128 expect(AccessToken.new(client, token, :refresh_token => 'abaca', :expires_in => 10800)).not_to be_expired
127 it 'is false if expires_in is in the future' do
128 expect(AccessToken.new(client, token, :refresh_token => 'abaca', :expires_in => 10_800)).not_to be_expired
129129 end
130130
131 it "is true if expires_at is in the past" do
131 it 'is true if expires_at is in the past' do
132132 access = AccessToken.new(client, token, :refresh_token => 'abaca', :expires_in => 600)
133 @now = Time.now + 10800
134 Time.stub!(:now).and_return(@now)
133 @now = Time.now + 10_800
134 allow(Time).to receive(:now).and_return(@now)
135135 expect(access).to be_expired
136136 end
137137
138138 end
139139
140 describe "#refresh!" do
141 let(:access) {
140 describe '#refresh!' do
141 let(:access) do
142142 AccessToken.new(client, token, :refresh_token => 'abaca',
143143 :expires_in => 600,
144144 :param_name => 'o_param')
145 }
145 end
146146
147 it "returns a refresh token with appropriate values carried over" do
147 it 'returns a refresh token with appropriate values carried over' do
148148 refreshed = access.refresh!
149149 expect(access.client).to eq(refreshed.client)
150150 expect(access.options[:param_name]).to eq(refreshed.options[:param_name])
151151 end
152152
153 context "with a nil refresh_token in the response" do
153 context 'with a nil refresh_token in the response' do
154154 let(:refresh_body) { MultiJson.encode(:access_token => 'refreshed_foo', :expires_in => 600, :refresh_token => nil) }
155155
156 it "copies the refresh_token from the original token" do
156 it 'copies the refresh_token from the original token' do
157157 refreshed = access.refresh!
158158
159159 expect(refreshed.refresh_token).to eq(access.refresh_token)
160160 end
161161 end
162162 end
163
164 describe '#to_hash' do
165 it 'return a hash equals to the hash used to initialize access token' do
166 hash = {:access_token => token, :refresh_token => 'foobar', :expires_at => Time.now.to_i + 200, 'foo' => 'bar'}
167 access_token = AccessToken.from_hash(client, hash.clone)
168 expect(access_token.to_hash).to eq(hash)
169 end
170 end
163171 end
00 require 'helper'
11
22 describe OAuth2::Client do
3 let!(:error_value) {'invalid_token'}
4 let!(:error_description_value) {'bad bad token'}
3 let!(:error_value) { 'invalid_token' }
4 let!(:error_description_value) { 'bad bad token' }
55
66 subject do
77 OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com') do |builder|
88 builder.adapter :test do |stub|
9 stub.get('/success') {|env| [200, {'Content-Type' => 'text/awesome'}, 'yay']}
10 stub.get('/reflect') {|env| [200, {}, env[:body]]}
11 stub.post('/reflect') {|env| [200, {}, env[:body]]}
12 stub.get('/unauthorized') {|env| [401, {'Content-Type' => 'application/json'}, MultiJson.encode(:error => error_value, :error_description => error_description_value)]}
13 stub.get('/conflict') {|env| [409, {'Content-Type' => 'text/plain'}, 'not authorized']}
14 stub.get('/redirect') {|env| [302, {'Content-Type' => 'text/plain', 'location' => '/success' }, '']}
15 stub.post('/redirect') {|env| [303, {'Content-Type' => 'text/plain', 'location' => '/reflect' }, '']}
16 stub.get('/error') {|env| [500, {'Content-Type' => 'text/plain'}, 'unknown error']}
17 stub.get('/empty_get') {|env| [204, {}, nil]}
18 end
19 end
20 end
21
22 describe "#initialize" do
23 it "assigns id and secret" do
9 stub.get('/success') { |env| [200, {'Content-Type' => 'text/awesome'}, 'yay'] }
10 stub.get('/reflect') { |env| [200, {}, env[:body]] }
11 stub.post('/reflect') { |env| [200, {}, env[:body]] }
12 stub.get('/unauthorized') { |env| [401, {'Content-Type' => 'application/json'}, MultiJson.encode(:error => error_value, :error_description => error_description_value)] }
13 stub.get('/conflict') { |env| [409, {'Content-Type' => 'text/plain'}, 'not authorized'] }
14 stub.get('/redirect') { |env| [302, {'Content-Type' => 'text/plain', 'location' => '/success'}, ''] }
15 stub.post('/redirect') { |env| [303, {'Content-Type' => 'text/plain', 'location' => '/reflect'}, ''] }
16 stub.get('/error') { |env| [500, {'Content-Type' => 'text/plain'}, 'unknown error'] }
17 stub.get('/empty_get') { |env| [204, {}, nil] }
18 end
19 end
20 end
21
22 describe '#initialize' do
23 it 'assigns id and secret' do
2424 expect(subject.id).to eq('abc')
2525 expect(subject.secret).to eq('def')
2626 end
2727
28 it "assigns site from the options hash" do
28 it 'assigns site from the options hash' do
2929 expect(subject.site).to eq('https://api.example.com')
3030 end
3131
32 it "assigns Faraday::Connection#host" do
32 it 'assigns Faraday::Connection#host' do
3333 expect(subject.connection.host).to eq('api.example.com')
3434 end
3535
36 it "leaves Faraday::Connection#ssl unset" do
37 expect(subject.connection.ssl).to eq({})
38 end
39
40 it "is able to pass a block to configure the connection" do
41 connection = stub('connection')
42 session = stub('session', :to_ary => nil)
43 builder = stub('builder')
44 connection.stub(:build).and_yield(builder)
45 Faraday::Connection.stub(:new => connection)
46
47 builder.should_receive(:adapter).with(:test)
48
49 OAuth2::Client.new('abc', 'def') do |builder|
50 builder.adapter :test
36 it 'leaves Faraday::Connection#ssl unset' do
37 expect(subject.connection.ssl).to be_empty
38 end
39
40 it 'is able to pass a block to configure the connection' do
41 connection = double('connection')
42 builder = double('builder')
43 allow(connection).to receive(:build).and_yield(builder)
44 allow(Faraday::Connection).to receive(:new).and_return(connection)
45
46 expect(builder).to receive(:adapter).with(:test)
47
48 OAuth2::Client.new('abc', 'def') do |client|
49 client.adapter :test
5150 end.connection
5251 end
5352
54 it "defaults raise_errors to true" do
55 expect(subject.options[:raise_errors]).to be_true
56 end
57
58 it "allows true/false for raise_errors option" do
53 it 'defaults raise_errors to true' do
54 expect(subject.options[:raise_errors]).to be true
55 end
56
57 it 'allows true/false for raise_errors option' do
5958 client = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :raise_errors => false)
60 expect(client.options[:raise_errors]).to be_false
59 expect(client.options[:raise_errors]).to be false
6160 client = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :raise_errors => true)
62 expect(client.options[:raise_errors]).to be_true
63 end
64
65 it "allows get/post for access_token_method option" do
61 expect(client.options[:raise_errors]).to be true
62 end
63
64 it 'allows override of raise_errors option' do
65 client = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :raise_errors => true) do |builder|
66 builder.adapter :test do |stub|
67 stub.get('/notfound') { |env| [404, {}, nil] }
68 end
69 end
70 expect(client.options[:raise_errors]).to be true
71 expect { client.request(:get, '/notfound') }.to raise_error(OAuth2::Error)
72 response = client.request(:get, '/notfound', :raise_errors => false)
73 expect(response.status).to eq(404)
74 end
75
76 it 'allows get/post for access_token_method option' do
6677 client = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :access_token_method => :get)
6778 expect(client.options[:access_token_method]).to eq(:get)
6879 client = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :access_token_method => :post)
6980 expect(client.options[:access_token_method]).to eq(:post)
7081 end
82
83 it 'does not mutate the opts hash argument' do
84 opts = {:site => 'http://example.com/'}
85 opts2 = opts.dup
86 OAuth2::Client.new 'abc', 'def', opts
87 expect(opts).to eq(opts2)
88 end
7189 end
7290
7391 %w(authorize token).each do |url_type|
8199 expect(subject.send("#{url_type}_url")).to eq('https://api.example.com/oauth/custom')
82100 end
83101
84 it "allows a different host than the site" do
102 it 'allows a different host than the site' do
85103 subject.options[:"#{url_type}_url"] = 'https://api.foo.com/oauth/custom'
86104 expect(subject.send("#{url_type}_url")).to eq('https://api.foo.com/oauth/custom')
87105 end
88106 end
89107 end
90108
91 describe "#request" do
92 it "works with a null response body" do
109 describe '#request' do
110 it 'works with a null response body' do
93111 expect(subject.request(:get, 'empty_get').body).to eq('')
94112 end
95113
96 it "returns on a successful response" do
114 it 'returns on a successful response' do
97115 response = subject.request(:get, '/success')
98116 expect(response.body).to eq('yay')
99117 expect(response.status).to eq(200)
100 expect(response.headers).to eq({'Content-Type' => 'text/awesome'})
101 end
102
103 it "posts a body" do
118 expect(response.headers).to eq('Content-Type' => 'text/awesome')
119 end
120
121 it 'posts a body' do
104122 response = subject.request(:post, '/reflect', :body => 'foo=bar')
105123 expect(response.body).to eq('foo=bar')
106124 end
107125
108 it "follows redirects properly" do
126 it 'follows redirects properly' do
109127 response = subject.request(:get, '/redirect')
110128 expect(response.body).to eq('yay')
111129 expect(response.status).to eq(200)
112 expect(response.headers).to eq({'Content-Type' => 'text/awesome'})
113 end
114
115 it "redirects using GET on a 303" do
130 expect(response.headers).to eq('Content-Type' => 'text/awesome')
131 end
132
133 it 'redirects using GET on a 303' do
116134 response = subject.request(:post, '/redirect', :body => 'foo=bar')
117135 expect(response.body).to be_empty
118136 expect(response.status).to eq(200)
119137 end
120138
121 it "obeys the :max_redirects option" do
139 it 'obeys the :max_redirects option' do
122140 max_redirects = subject.options[:max_redirects]
123141 subject.options[:max_redirects] = 0
124142 response = subject.request(:get, '/redirect')
126144 subject.options[:max_redirects] = max_redirects
127145 end
128146
129 it "returns if raise_errors is false" do
147 it 'returns if raise_errors is false' do
130148 subject.options[:raise_errors] = false
131149 response = subject.request(:get, '/unauthorized')
132150
133151 expect(response.status).to eq(401)
134 expect(response.headers).to eq({'Content-Type' => 'application/json'})
152 expect(response.headers).to eq('Content-Type' => 'application/json')
135153 expect(response.error).not_to be_nil
136154 end
137155
138156 %w(/unauthorized /conflict /error).each do |error_path|
139157 it "raises OAuth2::Error on error response to path #{error_path}" do
140 expect{subject.request(:get, error_path)}.to raise_error(OAuth2::Error)
141 end
142 end
143
144 it "parses OAuth2 standard error response" do
158 expect { subject.request(:get, error_path) }.to raise_error(OAuth2::Error)
159 end
160 end
161
162 it 'parses OAuth2 standard error response' do
145163 begin
146164 subject.request(:get, '/unauthorized')
147 rescue Exception => e
165 rescue StandardError => e
148166 expect(e.code).to eq(error_value)
149167 expect(e.description).to eq(error_description_value)
150168 expect(e.to_s).to match(/#{error_value}/)
152170 end
153171 end
154172
155 it "provides the response in the Exception" do
173 it 'provides the response in the Exception' do
156174 begin
157175 subject.request(:get, '/error')
158 rescue Exception => e
176 rescue StandardError => e
159177 expect(e.response).not_to be_nil
160178 expect(e.to_s).to match(/unknown error/)
161179 end
162180 end
163181 end
164182
165 it "instantiates an AuthCode strategy with this client" do
183 it 'instantiates an AuthCode strategy with this client' do
166184 expect(subject.auth_code).to be_kind_of(OAuth2::Strategy::AuthCode)
167185 end
168186
169 it "instantiates an Implicit strategy with this client" do
187 it 'instantiates an Implicit strategy with this client' do
170188 expect(subject.implicit).to be_kind_of(OAuth2::Strategy::Implicit)
171189 end
172190
173 context "with SSL options" do
191 context 'with SSL options' do
174192 subject do
175193 cli = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :ssl => {:ca_file => 'foo.pem'})
176194 cli.connection.build do |b|
179197 cli
180198 end
181199
182 it "passes the SSL options along to Faraday::Connection#ssl" do
183 expect(subject.connection.ssl).to eq({:ca_file => 'foo.pem'})
200 it 'passes the SSL options along to Faraday::Connection#ssl' do
201 expect(subject.connection.ssl.fetch(:ca_file)).to eq('foo.pem')
184202 end
185203 end
186204 end
00 require 'helper'
11
22 describe OAuth2::Response do
3 describe "#initialize" do
4 let(:status) {200}
5 let(:headers) {{'foo' => 'bar'}}
6 let(:body) {'foo'}
3 describe '#initialize' do
4 let(:status) { 200 }
5 let(:headers) { {'foo' => 'bar'} }
6 let(:body) { 'foo' }
77
8 it "returns the status, headers and body" do
8 it 'returns the status, headers and body' do
99 response = double('response', :headers => headers,
1010 :status => status,
1111 :body => body)
1616 end
1717 end
1818
19 describe ".register_parser" do
20 let(:response) {
19 describe '.register_parser' do
20 let(:response) do
2121 double('response', :headers => {'Content-Type' => 'application/foo-bar'},
2222 :status => 200,
2323 :body => 'baz')
24 }
24 end
2525 before do
2626 OAuth2::Response.register_parser(:foobar, 'application/foo-bar') do |body|
2727 "foobar #{body}"
2828 end
2929 end
3030
31 it "adds to the content types and parsers" do
31 it 'adds to the content types and parsers' do
3232 expect(OAuth2::Response::PARSERS.keys).to include(:foobar)
3333 expect(OAuth2::Response::CONTENT_TYPES.keys).to include('application/foo-bar')
3434 end
3535
36 it "is able to parse that content type automatically" do
36 it 'is able to parse that content type automatically' do
3737 expect(OAuth2::Response.new(response).parsed).to eq('foobar baz')
3838 end
3939 end
4040
41 describe "#parsed" do
42 it "parses application/x-www-form-urlencoded body" do
41 describe '#parsed' do
42 it 'parses application/x-www-form-urlencoded body' do
4343 headers = {'Content-Type' => 'application/x-www-form-urlencoded'}
4444 body = 'foo=bar&answer=42'
4545 response = double('response', :headers => headers, :body => body)
4949 expect(subject.parsed['answer']).to eq('42')
5050 end
5151
52 it "parses application/json body" do
52 it 'parses application/json body' do
5353 headers = {'Content-Type' => 'application/json'}
5454 body = MultiJson.encode(:foo => 'bar', :answer => 42)
5555 response = double('response', :headers => headers, :body => body)
6565
6666 response = double('response', :headers => headers, :body => body)
6767
68 MultiJson.should_not_receive(:decode)
69 MultiJson.should_not_receive(:load)
70 Rack::Utils.should_not_receive(:parse_query)
68 expect(MultiJson).not_to receive(:decode)
69 expect(MultiJson).not_to receive(:load)
70 expect(Rack::Utils).not_to receive(:parse_query)
7171
7272 subject = Response.new(response)
7373 expect(subject.parsed).to be_nil
7474 end
7575 end
7676
77 context "xml parser registration" do
78 it "tries to load multi_xml and use it" do
77 context 'xml parser registration' do
78 it 'tries to load multi_xml and use it' do
7979 expect(OAuth2::Response::PARSERS[:xml]).not_to be_nil
8080 end
8181
82 it "is able to parse xml" do
82 it 'is able to parse xml' do
8383 headers = {'Content-Type' => 'text/xml'}
8484 body = '<?xml version="1.0" standalone="yes" ?><foo><bar>baz</bar></foo>'
8585
8686 response = double('response', :headers => headers, :body => body)
87 expect(OAuth2::Response.new(response).parsed).to eq({"foo" => {"bar" => "baz"}})
87 expect(OAuth2::Response.new(response).parsed).to eq('foo' => {'bar' => 'baz'})
8888 end
8989 end
9090 end
66 b.adapter :test do |stub|
77 stub.post('/oauth/token') do |env|
88 case @mode
9 when "formencoded"
10 [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, 'expires_in=600&access_token=salmon&refresh_token=trout']
11 when "json"
12 [200, {'Content-Type' => 'application/json'}, '{"expires_in":600,"access_token":"salmon","refresh_token":"trout"}']
9 when 'formencoded'
10 [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, 'expires_in=600&access_token=salmon&refresh_token=trout']
11 when 'json'
12 [200, {'Content-Type' => 'application/json'}, '{"expires_in":600,"access_token":"salmon","refresh_token":"trout"}']
1313 end
1414 end
1515 end
1717 cli
1818 end
1919
20 let(:params) { {:hmac_secret => 'foo'}}
20 let(:params) { {:hmac_secret => 'foo'} }
2121
22 subject {client.assertion}
22 subject { client.assertion }
2323
24 describe "#authorize_url" do
25 it "raises NotImplementedError" do
26 expect{subject.authorize_url}.to raise_error(NotImplementedError)
24 describe '#authorize_url' do
25 it 'raises NotImplementedError' do
26 expect { subject.authorize_url }.to raise_error(NotImplementedError)
2727 end
2828 end
2929
3434 @access = subject.get_token(params)
3535 end
3636
37 it "returns AccessToken with same Client" do
37 it 'returns AccessToken with same Client' do
3838 expect(@access.client).to eq(client)
3939 end
4040
41 it "returns AccessToken with #token" do
41 it 'returns AccessToken with #token' do
4242 expect(@access.token).to eq('salmon')
4343 end
4444
45 it "returns AccessToken with #expires_in" do
45 it 'returns AccessToken with #expires_in' do
4646 expect(@access.expires_in).to eq(600)
4747 end
4848
49 it "returns AccessToken with #expires_at" do
49 it 'returns AccessToken with #expires_at' do
5050 expect(@access.expires_at).not_to be_nil
5151 end
5252 end
5353 end
5454
5555 end
56
00 require 'helper'
11
22 describe OAuth2::Strategy::AuthCode do
3 let(:code) {'sushi'}
4 let(:kvform_token) {'expires_in=600&access_token=salmon&refresh_token=trout&extra_param=steve'}
5 let(:facebook_token) {kvform_token.gsub('_in', '')}
6 let(:json_token) {MultiJson.encode(:expires_in => 600, :access_token => 'salmon', :refresh_token => 'trout', :extra_param => 'steve')}
3 let(:code) { 'sushi' }
4 let(:kvform_token) { 'expires_in=600&access_token=salmon&refresh_token=trout&extra_param=steve' }
5 let(:facebook_token) { kvform_token.gsub('_in', '') }
6 let(:json_token) { MultiJson.encode(:expires_in => 600, :access_token => 'salmon', :refresh_token => 'trout', :extra_param => 'steve') }
77
88 let(:client) do
99 OAuth2::Client.new('abc', 'def', :site => 'http://api.example.com') do |builder|
1010 builder.adapter :test do |stub|
1111 stub.get("/oauth/token?client_id=abc&client_secret=def&code=#{code}&grant_type=authorization_code") do |env|
1212 case @mode
13 when "formencoded"
13 when 'formencoded'
1414 [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, kvform_token]
15 when "json"
15 when 'json'
1616 [200, {'Content-Type' => 'application/json'}, json_token]
17 when "from_facebook"
17 when 'from_facebook'
1818 [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, facebook_token]
1919 end
2020 end
21 stub.post('/oauth/token', {'client_id' => 'abc', 'client_secret' => 'def', 'code' => 'sushi', 'grant_type' => 'authorization_code'}) do |env|
21 stub.post('/oauth/token', 'client_id' => 'abc', 'client_secret' => 'def', 'code' => 'sushi', 'grant_type' => 'authorization_code') do |env|
2222 case @mode
23 when "formencoded"
23 when 'formencoded'
2424 [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, kvform_token]
25 when "json"
25 when 'json'
2626 [200, {'Content-Type' => 'application/json'}, json_token]
27 when "from_facebook"
27 when 'from_facebook'
2828 [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, facebook_token]
2929 end
3030 end
3232 end
3333 end
3434
35 subject {client.auth_code}
35 subject { client.auth_code }
3636
37 describe "#authorize_url" do
38 it "includes the client_id" do
37 describe '#authorize_url' do
38 it 'includes the client_id' do
3939 expect(subject.authorize_url).to include('client_id=abc')
4040 end
4141
42 it "includes the type" do
42 it 'includes the type' do
4343 expect(subject.authorize_url).to include('response_type=code')
4444 end
4545
46 it "includes passed in options" do
46 it 'includes passed in options' do
4747 cb = 'http://myserver.local/oauth/callback'
4848 expect(subject.authorize_url(:redirect_uri => cb)).to include("redirect_uri=#{Rack::Utils.escape(cb)}")
4949 end
5252 %w(json formencoded from_facebook).each do |mode|
5353 [:get, :post].each do |verb|
5454 describe "#get_token (#{mode}, access_token_method=#{verb}" do
55 before :each do
55 before do
5656 @mode = mode
5757 client.options[:token_method] = verb
5858 @access = subject.get_token(code)
5959 end
6060
61 it "returns AccessToken with same Client" do
61 it 'returns AccessToken with same Client' do
6262 expect(@access.client).to eq(client)
6363 end
6464
65 it "returns AccessToken with #token" do
65 it 'returns AccessToken with #token' do
6666 expect(@access.token).to eq('salmon')
6767 end
6868
69 it "returns AccessToken with #refresh_token" do
69 it 'returns AccessToken with #refresh_token' do
7070 expect(@access.refresh_token).to eq('trout')
7171 end
7272
73 it "returns AccessToken with #expires_in" do
73 it 'returns AccessToken with #expires_in' do
7474 expect(@access.expires_in).to eq(600)
7575 end
7676
77 it "returns AccessToken with #expires_at" do
77 it 'returns AccessToken with #expires_at' do
7878 expect(@access.expires_at).to be_kind_of(Integer)
7979 end
8080
81 it "returns AccessToken with params accessible via []" do
81 it 'returns AccessToken with params accessible via []' do
8282 expect(@access['extra_param']).to eq('steve')
8383 end
8484 end
00 require 'helper'
11
22 describe OAuth2::Strategy::Base do
3 it "initializes with a Client" do
4 expect{OAuth2::Strategy::Base.new(OAuth2::Client.new('abc', 'def'))}.not_to raise_error
3 it 'initializes with a Client' do
4 expect { OAuth2::Strategy::Base.new(OAuth2::Client.new('abc', 'def')) }.not_to raise_error
55 end
66 end
66 let(:client) do
77 OAuth2::Client.new('abc', 'def', :site => 'http://api.example.com') do |builder|
88 builder.adapter :test do |stub|
9 stub.post('/oauth/token', {'grant_type' => 'client_credentials'}) do |env|
10 client_id, client_secret = HTTPAuth::Basic.unpack_authorization(env[:request_headers]['Authorization'])
11 client_id == 'abc' && client_secret == 'def' or raise Faraday::Adapter::Test::Stubs::NotFound.new
9 stub.post('/oauth/token', 'grant_type' => 'client_credentials') do |env|
10 client_id, client_secret = Base64.decode64(env[:request_headers]['Authorization'].split(' ', 2)[1]).split(':', 2)
11 client_id == 'abc' && client_secret == 'def' || fail(Faraday::Adapter::Test::Stubs::NotFound)
1212 case @mode
13 when "formencoded"
13 when 'formencoded'
1414 [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, kvform_token]
15 when "json"
15 when 'json'
1616 [200, {'Content-Type' => 'application/json'}, json_token]
1717 end
1818 end
19 stub.post('/oauth/token', {'client_id' => 'abc', 'client_secret' => 'def', 'grant_type' => 'client_credentials'}) do |env|
19 stub.post('/oauth/token', 'client_id' => 'abc', 'client_secret' => 'def', 'grant_type' => 'client_credentials') do |env|
2020 case @mode
21 when "formencoded"
21 when 'formencoded'
2222 [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, kvform_token]
23 when "json"
23 when 'json'
2424 [200, {'Content-Type' => 'application/json'}, json_token]
2525 end
2626 end
2828 end
2929 end
3030
31 subject {client.client_credentials}
31 subject { client.client_credentials }
3232
33 describe "#authorize_url" do
34 it "raises NotImplementedError" do
35 expect{subject.authorize_url}.to raise_error(NotImplementedError)
33 describe '#authorize_url' do
34 it 'raises NotImplementedError' do
35 expect { subject.authorize_url }.to raise_error(NotImplementedError)
36 end
37 end
38
39 describe '#authorization' do
40 it 'generates an Authorization header value for HTTP Basic Authentication' do
41 [
42 ['abc', 'def', 'Basic YWJjOmRlZg=='],
43 ['xxx', 'secret', 'Basic eHh4OnNlY3JldA==']
44 ].each do |client_id, client_secret, expected|
45 expect(subject.authorization(client_id, client_secret)).to eq(expected)
46 end
3647 end
3748 end
3849
4455 @access = subject.get_token({}, auth_scheme == 'default' ? {} : {'auth_scheme' => auth_scheme})
4556 end
4657
47 it "returns AccessToken with same Client" do
58 it 'returns AccessToken with same Client' do
4859 expect(@access.client).to eq(client)
4960 end
5061
51 it "returns AccessToken with #token" do
62 it 'returns AccessToken with #token' do
5263 expect(@access.token).to eq('salmon')
5364 end
5465
55 it "returns AccessToken without #refresh_token" do
66 it 'returns AccessToken without #refresh_token' do
5667 expect(@access.refresh_token).to be_nil
5768 end
5869
59 it "returns AccessToken with #expires_in" do
70 it 'returns AccessToken with #expires_in' do
6071 expect(@access.expires_in).to eq(600)
6172 end
6273
63 it "returns AccessToken with #expires_at" do
74 it 'returns AccessToken with #expires_at' do
6475 expect(@access.expires_at).not_to be_nil
6576 end
6677 end
22 describe OAuth2::Strategy::Implicit do
33 let(:client) { OAuth2::Client.new('abc', 'def', :site => 'http://api.example.com') }
44
5 subject {client.implicit}
5 subject { client.implicit }
66
7 describe "#authorize_url" do
8 it "includes the client_id" do
7 describe '#authorize_url' do
8 it 'includes the client_id' do
99 expect(subject.authorize_url).to include('client_id=abc')
1010 end
1111
12 it "includes the type" do
12 it 'includes the type' do
1313 expect(subject.authorize_url).to include('response_type=token')
1414 end
1515
16 it "includes passed in options" do
16 it 'includes passed in options' do
1717 cb = 'http://myserver.local/oauth/callback'
1818 expect(subject.authorize_url(:redirect_uri => cb)).to include("redirect_uri=#{Rack::Utils.escape(cb)}")
1919 end
2020 end
2121
22 describe "#get_token" do
23 it "raises NotImplementedError" do
24 expect{subject.get_token}.to raise_error(NotImplementedError)
22 describe '#get_token' do
23 it 'raises NotImplementedError' do
24 expect { subject.get_token }.to raise_error(NotImplementedError)
2525 end
2626 end
2727 end
66 b.adapter :test do |stub|
77 stub.post('/oauth/token') do |env|
88 case @mode
9 when "formencoded"
10 [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, 'expires_in=600&access_token=salmon&refresh_token=trout']
11 when "json"
12 [200, {'Content-Type' => 'application/json'}, '{"expires_in":600,"access_token":"salmon","refresh_token":"trout"}']
9 when 'formencoded'
10 [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, 'expires_in=600&access_token=salmon&refresh_token=trout']
11 when 'json'
12 [200, {'Content-Type' => 'application/json'}, '{"expires_in":600,"access_token":"salmon","refresh_token":"trout"}']
1313 end
1414 end
1515 end
1616 end
1717 cli
1818 end
19 subject {client.password}
19 subject { client.password }
2020
21 describe "#authorize_url" do
22 it "raises NotImplementedError" do
23 expect{subject.authorize_url}.to raise_error(NotImplementedError)
21 describe '#authorize_url' do
22 it 'raises NotImplementedError' do
23 expect { subject.authorize_url }.to raise_error(NotImplementedError)
2424 end
2525 end
2626
3131 @access = subject.get_token('username', 'password')
3232 end
3333
34 it "returns AccessToken with same Client" do
34 it 'returns AccessToken with same Client' do
3535 expect(@access.client).to eq(client)
3636 end
3737
38 it "returns AccessToken with #token" do
38 it 'returns AccessToken with #token' do
3939 expect(@access.token).to eq('salmon')
4040 end
4141
42 it "returns AccessToken with #refresh_token" do
42 it 'returns AccessToken with #refresh_token' do
4343 expect(@access.refresh_token).to eq('trout')
4444 end
4545
46 it "returns AccessToken with #expires_in" do
46 it 'returns AccessToken with #expires_in' do
4747 expect(@access.expires_in).to eq(600)
4848 end
4949
50 it "returns AccessToken with #expires_at" do
50 it 'returns AccessToken with #expires_at' do
5151 expect(@access.expires_at).not_to be_nil
5252 end
5353 end