pax_global_header00006660000000000000000000000064121504735020014511gustar00rootroot0000000000000052 comment=f21bb4beeac4365fcc85e2e3e6339a81313bd991 ruby-oauth2-0.9.1/000077500000000000000000000000001215047350200137015ustar00rootroot00000000000000ruby-oauth2-0.9.1/.document000066400000000000000000000000741215047350200155210ustar00rootroot00000000000000README.rdoc lib/**/*.rb bin/* features/**/*.feature LICENSE ruby-oauth2-0.9.1/CONTRIBUTING.md000066400000000000000000000012251215047350200161320ustar00rootroot00000000000000## Submitting a Pull Request 1. [Fork the repository.][fork] 2. [Create a topic branch.][branch] 3. Add specs for your unimplemented feature or bug fix. 4. Run `bundle exec rake spec`. If your specs pass, return to step 3. 5. Implement your feature or bug fix. 6. Run `bundle exec rake spec`. If your specs fail, return to step 5. 7. Run `open coverage/index.html`. If your changes are not completely covered by your tests, return to step 3. 8. Add, commit, and push your changes. 9. [Submit a pull request.][pr] [fork]: http://help.github.com/fork-a-repo/ [branch]: http://learn.github.com/p/branching.html [pr]: http://help.github.com/send-pull-requests/ ruby-oauth2-0.9.1/LICENSE.md000066400000000000000000000020721215047350200153060ustar00rootroot00000000000000Copyright (c) 2011-2013 Michael Bleigh and Intridea, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ruby-oauth2-0.9.1/README.md000066400000000000000000000136221215047350200151640ustar00rootroot00000000000000# OAuth2 [![Gem Version](https://badge.fury.io/rb/oauth2.png)][gem] [![Build Status](https://secure.travis-ci.org/intridea/oauth2.png?branch=master)][travis] [![Dependency Status](https://gemnasium.com/intridea/oauth2.png?travis)][gemnasium] [![Code Climate](https://codeclimate.com/github/intridea/oauth2.png)][codeclimate] [gem]: https://rubygems.org/gems/oauth2 [travis]: http://travis-ci.org/intridea/oauth2 [gemnasium]: https://gemnasium.com/intridea/oauth2 [codeclimate]: https://codeclimate.com/github/intridea/oauth2 A Ruby wrapper for the OAuth 2.0 specification. This is a work in progress, being built first to solve the pragmatic process of connecting to existing OAuth 2.0 endpoints (a.k.a. Facebook) with the goal of building it up to meet the entire specification over time. ## Installation gem install oauth2 To ensure the code you're installing hasn't been tampered with, it's recommended that you verify the signature. To do this, you need to add my public key as a trusted certificate (you only need to do this once): gem cert --add <(curl -Ls https://gist.github.com/sferik/4701180/raw/public_cert.pem) Then, install the gem with the high security trust policy: gem install oauth2 -P HighSecurity ## Resources * [View Source on GitHub][code] * [Report Issues on GitHub][issues] * [Read More at the Wiki][wiki] [code]: https://github.com/intridea/oauth2 [issues]: https://github.com/intridea/oauth2/issues [wiki]: https://wiki.github.com/intridea/oauth2 ## Usage Examples require 'oauth2' client = OAuth2::Client.new('client_id', 'client_secret', :site => 'https://example.org') client.auth_code.authorize_url(:redirect_uri => 'http://localhost:8080/oauth2/callback') # => "https://example.org/oauth/authorization?response_type=code&client_id=client_id&redirect_uri=http://localhost:8080/oauth2/callback" token = client.auth_code.get_token('authorization_code_value', :redirect_uri => 'http://localhost:8080/oauth2/callback', :headers => {'Authorization' => 'Basic some_password'}) response = token.get('/api/resource', :params => { 'query_foo' => 'bar' }) response.class.name # => OAuth2::Response ## OAuth2::Response The AccessToken methods #get, #post, #put and #delete and the generic #request will return an instance of the #OAuth2::Response class. This instance contains a #parsed method that will parse the response body and return a Hash if the Content-Type is application/x-www-form-urlencoded or if the body is a JSON object. It will return an Array if the body is a JSON array. Otherwise, it will return the original body string. The original response body, headers, and status can be accessed via their respective methods. ## OAuth2::AccessToken If you have an existing Access Token for a user, you can initialize an instance using various class methods including the standard new, from_hash (if you have a hash of the values), or from_kvform (if you have an application/x-www-form-urlencoded encoded string of the values). ## OAuth2::Error On 400+ status code responses, an OAuth2::Error will be raised. If it is a standard OAuth2 error response, the body will be parsed and #code and #description will contain the values provided from the error and error_description parameters. The #response property of OAuth2::Error will always contain the OAuth2::Response instance. If you do not want an error to be raised, you may use :raise_errors => false option on initialization of the client. In this case the OAuth2::Response instance will be returned as usual and on 400+ status code responses, the Response instance will contain the OAuth2::Error instance. ## Authorization Grants Currently the Authorization Code, Implicit, Resource Owner Password Credentials, Client Credentials, and Assertion authentication grant types have helper strategy classes that simplify client use. They are available via the #auth_code, #implicit, #password, #client_credentials, and #assertion methods respectively. auth_url = client.auth_code.authorize_url(:redirect_uri => 'http://localhost:8080/oauth/callback') token = client.auth_code.get_token('code_value', :redirect_uri => 'http://localhost:8080/oauth/callback') auth_url = client.implicit.authorize_url(:redirect_uri => 'http://localhost:8080/oauth/callback') # get the token params in the callback and token = OAuth2::AccessToken.from_kvform(client, query_string) token = client.password.get_token('username', 'password') token = client.client_credentials.get_token token = client.assertion.get_token(assertion_params) If you want to specify additional headers to be sent out with the request, add a 'headers' hash under 'params': token = client.auth_code.get_token('code_value', :redirect_uri => 'http://localhost:8080/oauth/callback', :headers => {'Some' => 'Header'}) You can always use the #request method on the OAuth2::Client instance to make requests for tokens for any Authentication grant type. ## Supported Ruby Versions This library aims to support and is [tested against][travis] the following Ruby implementations: * Ruby 1.8.7 * Ruby 1.9.2 * Ruby 1.9.3 * Ruby 2.0.0 * [JRuby][] * [Rubinius][] [jruby]: http://jruby.org/ [rubinius]: http://rubini.us/ If something doesn't work on one of these interpreters, it's a bug. This library may inadvertently work (or seem to work) on other Ruby implementations, however support will only be provided for the versions listed above. If you would like this library to support another Ruby version, you may volunteer to be a maintainer. Being a maintainer entails making sure all tests run and pass on that implementation. When something breaks on your implementation, you will be responsible for providing patches in a timely fashion. If critical issues for a particular implementation exist at the time of a major release, support for that Ruby version may be dropped. ## License Copyright (c) 2011-2013 Michael Bleigh and Intridea, Inc. See [LICENSE][] for details. [license]: LICENSE.md ruby-oauth2-0.9.1/Rakefile000066400000000000000000000007261215047350200153530ustar00rootroot00000000000000require 'bundler' Bundler::GemHelper.install_tasks require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) task :default => :spec task :test => :spec namespace :doc do require 'rdoc/task' require File.expand_path('../lib/oauth2/version', __FILE__) RDoc::Task.new do |rdoc| rdoc.rdoc_dir = 'rdoc' rdoc.title = "oauth2 #{OAuth2::Version}" rdoc.main = 'README.md' rdoc.rdoc_files.include('README.md', 'LICENSE.md', 'lib/**/*.rb') end end ruby-oauth2-0.9.1/data.tar.gz.sig000066400000000000000000000004001215047350200165140ustar00rootroot00000000000000Q D!dI"NO9Meg8>Rn@ hOb:He̤qWZp#b7 ;rPJEBxc"d"%ZB*ʔ)7&GH_B˻g opts.delete(:mode) || :header, :header_format => opts.delete(:header_format) || 'Bearer %s', :param_name => opts.delete(:param_name) || 'access_token'} @params = opts end # Indexer to additional params present in token response # # @param [String] key entry key to Hash def [](key) @params[key] end # Whether or not the token expires # # @return [Boolean] def expires? !!@expires_at end # Whether or not the token is expired # # @return [Boolean] def expired? expires? && (expires_at < Time.now.to_i) end # Refreshes the current Access Token # # @return [AccessToken] a new AccessToken # @note options should be carried over to the new AccessToken def refresh!(params={}) raise "A refresh_token is not available" unless refresh_token params.merge!(:client_id => @client.id, :client_secret => @client.secret, :grant_type => 'refresh_token', :refresh_token => refresh_token) new_token = @client.get_token(params) new_token.options = options new_token.refresh_token = refresh_token unless new_token.refresh_token new_token end # Make a request with the Access Token # # @param [Symbol] verb the HTTP request method # @param [String] path the HTTP URL path of the request # @param [Hash] opts the options to make the request with # @see Client#request def request(verb, path, opts={}, &block) set_token(opts) @client.request(verb, path, opts, &block) end # Make a GET request with the Access Token # # @see AccessToken#request def get(path, opts={}, &block) request(:get, path, opts, &block) end # Make a POST request with the Access Token # # @see AccessToken#request def post(path, opts={}, &block) request(:post, path, opts, &block) end # Make a PUT request with the Access Token # # @see AccessToken#request def put(path, opts={}, &block) request(:put, path, opts, &block) end # Make a PATCH request with the Access Token # # @see AccessToken#request def patch(path, opts={}, &block) request(:patch, path, opts, &block) end # Make a DELETE request with the Access Token # # @see AccessToken#request def delete(path, opts={}, &block) request(:delete, path, opts, &block) end # Get the headers hash (includes Authorization token) def headers { 'Authorization' => options[:header_format] % token } end private def set_token(opts) case options[:mode] when :header opts[:headers] ||= {} opts[:headers].merge!(headers) when :query opts[:params] ||= {} opts[:params][options[:param_name]] = token when :body opts[:body] ||= {} if opts[:body].is_a?(Hash) opts[:body][options[:param_name]] = token else opts[:body] << "&#{options[:param_name]}=#{token}" end # @todo support for multi-part (file uploads) else raise "invalid :mode option of #{options[:mode]}" end end end end ruby-oauth2-0.9.1/lib/oauth2/client.rb000066400000000000000000000144071215047350200174620ustar00rootroot00000000000000require 'faraday' module OAuth2 # The OAuth2::Client class class Client attr_reader :id, :secret, :site attr_accessor :options attr_writer :connection # Instantiate a new OAuth 2.0 client using the # Client ID and Client Secret registered to your # application. # # @param [String] client_id the client_id value # @param [String] client_secret the client_secret value # @param [Hash] opts the options to create the client with # @option opts [String] :site the OAuth2 provider site host # @option opts [String] :authorize_url ('/oauth/authorize') absolute or relative URL path to the Authorization endpoint # @option opts [String] :token_url ('/oauth/token') absolute or relative URL path to the Token endpoint # @option opts [Symbol] :token_method (:post) HTTP method to use to request token (:get or :post) # @option opts [Hash] :connection_opts ({}) Hash of connection options to pass to initialize Faraday with # @option opts [FixNum] :max_redirects (5) maximum number of redirects to follow # @option opts [Boolean] :raise_errors (true) whether or not to raise an OAuth2::Error # on responses with 400+ status codes # @yield [builder] The Faraday connection builder def initialize(client_id, client_secret, opts={}, &block) @id = client_id @secret = client_secret @site = opts.delete(:site) ssl = opts.delete(:ssl) @options = {:authorize_url => '/oauth/authorize', :token_url => '/oauth/token', :token_method => :post, :connection_opts => {}, :connection_build => block, :max_redirects => 5, :raise_errors => true}.merge(opts) @options[:connection_opts][:ssl] = ssl if ssl end # Set the site host # # @param [String] the OAuth2 provider site host def site=(value) @connection = nil @site = value end # The Faraday connection object def connection @connection ||= begin conn = Faraday.new(site, options[:connection_opts]) conn.build do |b| options[:connection_build].call(b) end if options[:connection_build] conn end end # The authorize endpoint URL of the OAuth2 provider # # @param [Hash] params additional query parameters def authorize_url(params=nil) connection.build_url(options[:authorize_url], params).to_s end # The token endpoint URL of the OAuth2 provider # # @param [Hash] params additional query parameters def token_url(params=nil) connection.build_url(options[:token_url], params).to_s end # Makes a request relative to the specified site root. # # @param [Symbol] verb one of :get, :post, :put, :delete # @param [String] url URL path of request # @param [Hash] opts the options to make the request with # @option opts [Hash] :params additional query parameters for the URL of the request # @option opts [Hash, String] :body the body of the request # @option opts [Hash] :headers http request headers # @option opts [Boolean] :raise_errors whether or not to raise an OAuth2::Error on 400+ status # code response for this request. Will default to client option # @option opts [Symbol] :parse @see Response::initialize # @yield [req] The Faraday request def request(verb, url, opts={}) url = self.connection.build_url(url, opts[:params]).to_s response = connection.run_request(verb, url, opts[:body], opts[:headers]) do |req| yield(req) if block_given? end response = Response.new(response, :parse => opts[:parse]) case response.status when 301, 302, 303, 307 opts[:redirect_count] ||= 0 opts[:redirect_count] += 1 return response if opts[:redirect_count] > options[:max_redirects] if response.status == 303 verb = :get opts.delete(:body) end request(verb, response.headers['location'], opts) when 200..299, 300..399 # on non-redirecting 3xx statuses, just return the response response when 400..599 e = Error.new(response) raise e if opts[:raise_errors] || options[:raise_errors] response.error = e response else raise Error.new(response), "Unhandled status code value of #{response.status}" end end # Initializes an AccessToken by making a request to the token endpoint # # @param [Hash] params a Hash of params for the token endpoint # @param [Hash] access token options, to pass to the AccessToken object # @return [AccessToken] the initalized AccessToken def get_token(params, access_token_opts={}) opts = {:raise_errors => options[:raise_errors], :parse => params.delete(:parse)} if options[:token_method] == :post headers = params.delete(:headers) opts[:body] = params opts[:headers] = {'Content-Type' => 'application/x-www-form-urlencoded'} opts[:headers].merge!(headers) if headers else opts[:params] = params end response = request(options[:token_method], token_url, opts) raise Error.new(response) if options[:raise_errors] && !(response.parsed.is_a?(Hash) && response.parsed['access_token']) AccessToken.from_hash(self, response.parsed.merge(access_token_opts)) end # The Authorization Code strategy # # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.1 def auth_code @auth_code ||= OAuth2::Strategy::AuthCode.new(self) end # The Implicit strategy # # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-26#section-4.2 def implicit @implicit ||= OAuth2::Strategy::Implicit.new(self) end # The Resource Owner Password Credentials strategy # # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.3 def password @password ||= OAuth2::Strategy::Password.new(self) end # The Client Credentials strategy # # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.4 def client_credentials @client_credentials ||= OAuth2::Strategy::ClientCredentials.new(self) end def assertion @assertion ||= OAuth2::Strategy::Assertion.new(self) end end end ruby-oauth2-0.9.1/lib/oauth2/error.rb000066400000000000000000000011611215047350200173260ustar00rootroot00000000000000module OAuth2 class Error < StandardError attr_reader :response, :code, :description # standard error values include: # :invalid_request, :invalid_client, :invalid_token, :invalid_grant, :unsupported_grant_type, :invalid_scope def initialize(response) response.error = self @response = response message = [] if response.parsed.is_a?(Hash) @code = response.parsed['error'] @description = response.parsed['error_description'] message << "#{@code}: #{@description}" end message << response.body super(message.join("\n")) end end end ruby-oauth2-0.9.1/lib/oauth2/response.rb000066400000000000000000000057241215047350200200440ustar00rootroot00000000000000require 'multi_json' require 'rack' module OAuth2 # OAuth2::Response class class Response attr_reader :response attr_accessor :error, :options # Adds a new content type parser. # # @param [Symbol] key A descriptive symbol key such as :json or :query. # @param [Array] One or more mime types to which this parser applies. # @yield [String] A block returning parsed content. def self.register_parser(key, mime_types, &block) key = key.to_sym PARSERS[key] = block Array(mime_types).each do |mime_type| CONTENT_TYPES[mime_type] = key end end # Initializes a Response instance # # @param [Faraday::Response] response The Faraday response instance # @param [Hash] opts options in which to initialize the instance # @option opts [Symbol] :parse (:automatic) how to parse the response body. one of :query (for x-www-form-urlencoded), # :json, or :automatic (determined by Content-Type response header) def initialize(response, opts={}) @response = response @options = {:parse => :automatic}.merge(opts) end # The HTTP response headers def headers response.headers end # The HTTP response status code def status response.status end # The HTTP response body def body response.body || '' end # Procs that, when called, will parse a response body according # to the specified format. PARSERS = { # Can't reliably detect whether MultiJson responds to load, since it's # a reserved word. Use adapter as a proxy for new features. :json => lambda{ |body| MultiJson.respond_to?(:adapter) ? MultiJson.load(body) : MultiJson.decode(body) rescue body }, :query => lambda{ |body| Rack::Utils.parse_query(body) }, :text => lambda{ |body| body } } # Content type assignments for various potential HTTP content types. CONTENT_TYPES = { 'application/json' => :json, 'text/javascript' => :json, 'application/x-www-form-urlencoded' => :query, 'text/plain' => :text } # The parsed response body. # Will attempt to parse application/x-www-form-urlencoded and # application/json Content-Type response bodies def parsed return nil unless PARSERS.key?(parser) @parsed ||= PARSERS[parser].call(body) end # Attempts to determine the content type of the response. def content_type ((response.headers.values_at('content-type', 'Content-Type').compact.first || '').split(';').first || '').strip end # Determines the parser that will be used to supply the content of #parsed def parser return options[:parse].to_sym if PARSERS.key?(options[:parse]) CONTENT_TYPES[content_type] end end end begin require 'multi_xml' OAuth2::Response.register_parser(:xml, ['text/xml', 'application/rss+xml', 'application/rdf+xml', 'application/atom+xml']) do |body| MultiXml.parse(body) rescue body end rescue LoadError; end ruby-oauth2-0.9.1/lib/oauth2/strategy/000077500000000000000000000000001215047350200175135ustar00rootroot00000000000000ruby-oauth2-0.9.1/lib/oauth2/strategy/assertion.rb000066400000000000000000000047361215047350200220610ustar00rootroot00000000000000require 'httpauth' require 'jwt' module OAuth2 module Strategy # The Client Assertion Strategy # # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-10#section-4.1.3 # # Sample usage: # client = OAuth2::Client.new(client_id, client_secret, # :site => 'http://localhost:8080') # # params = {:hmac_secret => "some secret", # # or :private_key => "private key string", # :iss => "http://localhost:3001", # :prn => "me@here.com", # :exp => Time.now.utc.to_i + 3600} # # access = client.assertion.get_token(params) # access.token # actual access_token string # access.get("/api/stuff") # making api calls with access token in header # class Assertion < Base # Not used for this strategy # # @raise [NotImplementedError] def authorize_url raise NotImplementedError, "The authorization endpoint is not used in this strategy" end # Retrieve an access token given the specified client. # # @param [Hash] params assertion params # pass either :hmac_secret or :private_key, but not both. # # params :hmac_secret, secret string. # params :private_key, private key string. # # params :iss, issuer # params :aud, audience, optional # params :prn, principal, current user # params :exp, expired at, in seconds, like Time.now.utc.to_i + 3600 # # @param [Hash] opts options def get_token(params={}, opts={}) hash = build_request(params) @client.get_token(hash, opts.merge('refresh_token' => nil)) end def build_request(params) assertion = build_assertion(params) {:grant_type => "assertion", :assertion_type => "urn:ietf:params:oauth:grant-type:jwt-bearer", :assertion => assertion, :scope => params[:scope] }.merge(client_params) end def build_assertion(params) claims = {:iss => params[:iss], :aud => params[:aud], :prn => params[:prn], :exp => params[:exp] } if params[:hmac_secret] jwt_assertion = JWT.encode(claims, params[:hmac_secret], "HS256") elsif params[:private_key] jwt_assertion = JWT.encode(claims, params[:private_key], "RS256") end end end end end ruby-oauth2-0.9.1/lib/oauth2/strategy/auth_code.rb000066400000000000000000000022461215047350200217770ustar00rootroot00000000000000module OAuth2 module Strategy # The Authorization Code Strategy # # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.1 class AuthCode < Base # The required query parameters for the authorize URL # # @param [Hash] params additional query parameters def authorize_params(params={}) params.merge('response_type' => 'code', 'client_id' => @client.id) end # The authorization URL endpoint of the provider # # @param [Hash] params additional query parameters for the URL def authorize_url(params={}) @client.authorize_url(authorize_params.merge(params)) end # Retrieve an access token given the specified validation code. # # @param [String] code The Authorization Code value # @param [Hash] params additional params # @param [Hash] opts options # @note that you must also provide a :redirect_uri with most OAuth 2.0 providers def get_token(code, params={}, opts={}) params = {'grant_type' => 'authorization_code', 'code' => code}.merge(client_params).merge(params) @client.get_token(params, opts) end end end end ruby-oauth2-0.9.1/lib/oauth2/strategy/base.rb000066400000000000000000000004701215047350200207530ustar00rootroot00000000000000module OAuth2 module Strategy class Base def initialize(client) @client = client end # The OAuth client_id and client_secret # # @return [Hash] def client_params {'client_id' => @client.id, 'client_secret' => @client.secret} end end end end ruby-oauth2-0.9.1/lib/oauth2/strategy/client_credentials.rb000066400000000000000000000017651215047350200237040ustar00rootroot00000000000000require 'httpauth' module OAuth2 module Strategy # The Client Credentials Strategy # # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.4 class ClientCredentials < Base # Not used for this strategy # # @raise [NotImplementedError] def authorize_url raise NotImplementedError, "The authorization endpoint is not used in this strategy" end # Retrieve an access token given the specified client. # # @param [Hash] params additional params # @param [Hash] opts options def get_token(params={}, opts={}) request_body = opts.delete('auth_scheme') == 'request_body' params.merge!('grant_type' => 'client_credentials') params.merge!(request_body ? client_params : {:headers => {'Authorization' => HTTPAuth::Basic.pack_authorization(client_params['client_id'], client_params['client_secret'])}}) @client.get_token(params, opts.merge('refresh_token' => nil)) end end end end ruby-oauth2-0.9.1/lib/oauth2/strategy/implicit.rb000066400000000000000000000015521215047350200216550ustar00rootroot00000000000000module OAuth2 module Strategy # The Implicit Strategy # # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-26#section-4.2 class Implicit < Base # The required query parameters for the authorize URL # # @param [Hash] params additional query parameters def authorize_params(params={}) params.merge('response_type' => 'token', 'client_id' => @client.id) end # The authorization URL endpoint of the provider # # @param [Hash] params additional query parameters for the URL def authorize_url(params={}) @client.authorize_url(authorize_params.merge(params)) end # Not used for this strategy # # @raise [NotImplementedError] def get_token(*) raise NotImplementedError, "The token is accessed differently in this strategy" end end end end ruby-oauth2-0.9.1/lib/oauth2/strategy/password.rb000066400000000000000000000017011215047350200217010ustar00rootroot00000000000000module OAuth2 module Strategy # The Resource Owner Password Credentials Authorization Strategy # # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.3 class Password < Base # Not used for this strategy # # @raise [NotImplementedError] def authorize_url raise NotImplementedError, "The authorization endpoint is not used in this strategy" end # Retrieve an access token given the specified End User username and password. # # @param [String] username the End User username # @param [String] password the End User password # @param [Hash] params additional params def get_token(username, password, params={}, opts={}) params = {'grant_type' => 'password', 'username' => username, 'password' => password}.merge(client_params).merge(params) @client.get_token(params, opts) end end end end ruby-oauth2-0.9.1/lib/oauth2/version.rb000066400000000000000000000004731215047350200176670ustar00rootroot00000000000000module OAuth2 class Version MAJOR = 0 unless defined? MAJOR MINOR = 9 unless defined? MINOR PATCH = 1 unless defined? PATCH PRE = nil unless defined? PRE class << self # @return [String] def to_s [MAJOR, MINOR, PATCH, PRE].compact.join('.') end end end end ruby-oauth2-0.9.1/metadata.gz.sig000066400000000000000000000004001215047350200165760ustar00rootroot00000000000000&30wQ0{Ce1>A#I9u_c>5n+łCV~&$#2wabOKiUyzy#};*5w*Q=۴ZGcZl - !ruby/object:Gem::Version version: '1.0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '1.0' - !ruby/object:Gem::Dependency name: faraday requirement: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '0.8' type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '0.8' - !ruby/object:Gem::Dependency name: httpauth requirement: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '0.1' type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '0.1' - !ruby/object:Gem::Dependency name: multi_json requirement: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '1.0' type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '1.0' - !ruby/object:Gem::Dependency name: multi_xml requirement: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '0.5' type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '0.5' - !ruby/object:Gem::Dependency name: rack requirement: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '1.2' type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '1.2' - !ruby/object:Gem::Dependency name: jwt requirement: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: 0.1.4 type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: 0.1.4 description: A Ruby wrapper for the OAuth 2.0 protocol built with a similar style to the original OAuth spec. email: - michael@intridea.com - sferik@gmail.com executables: [] extensions: [] extra_rdoc_files: [] files: - .document - CONTRIBUTING.md - LICENSE.md - README.md - Rakefile - oauth2.gemspec - lib/oauth2/access_token.rb - lib/oauth2/client.rb - lib/oauth2/error.rb - lib/oauth2/response.rb - lib/oauth2/strategy/assertion.rb - lib/oauth2/strategy/auth_code.rb - lib/oauth2/strategy/base.rb - lib/oauth2/strategy/client_credentials.rb - lib/oauth2/strategy/implicit.rb - lib/oauth2/strategy/password.rb - lib/oauth2/version.rb - lib/oauth2.rb - spec/helper.rb - spec/oauth2/access_token_spec.rb - spec/oauth2/client_spec.rb - spec/oauth2/response_spec.rb - spec/oauth2/strategy/assertion_spec.rb - spec/oauth2/strategy/auth_code_spec.rb - spec/oauth2/strategy/base_spec.rb - spec/oauth2/strategy/client_credentials_spec.rb - spec/oauth2/strategy/implicit_spec.rb - spec/oauth2/strategy/password_spec.rb homepage: http://github.com/intridea/oauth2 licenses: - MIT post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: 1.3.6 requirements: [] rubyforge_project: rubygems_version: 1.8.23 signing_key: specification_version: 3 summary: A Ruby wrapper for the OAuth 2.0 protocol. test_files: - spec/helper.rb - spec/oauth2/access_token_spec.rb - spec/oauth2/client_spec.rb - spec/oauth2/response_spec.rb - spec/oauth2/strategy/assertion_spec.rb - spec/oauth2/strategy/auth_code_spec.rb - spec/oauth2/strategy/base_spec.rb - spec/oauth2/strategy/client_credentials_spec.rb - spec/oauth2/strategy/implicit_spec.rb - spec/oauth2/strategy/password_spec.rb has_rdoc: ruby-oauth2-0.9.1/oauth2.gemspec000066400000000000000000000026031215047350200164510ustar00rootroot00000000000000# coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'oauth2/version' Gem::Specification.new do |spec| spec.add_development_dependency 'bundler', '~> 1.0' spec.add_dependency 'faraday', '~> 0.8' spec.add_dependency 'httpauth', '~> 0.1' spec.add_dependency 'multi_json', '~> 1.0' spec.add_dependency 'multi_xml', '~> 0.5' spec.add_dependency 'rack', '~> 1.2' spec.add_dependency 'jwt', '~> 0.1.4' spec.authors = ["Michael Bleigh", "Erik Michaels-Ober"] spec.cert_chain = %w(certs/sferik.pem) spec.description = %q{A Ruby wrapper for the OAuth 2.0 protocol built with a similar style to the original OAuth spec.} spec.email = ['michael@intridea.com', 'sferik@gmail.com'] spec.files = %w(.document CONTRIBUTING.md LICENSE.md README.md Rakefile oauth2.gemspec) spec.files += Dir.glob("lib/**/*.rb") spec.files += Dir.glob("spec/**/*") spec.homepage = 'http://github.com/intridea/oauth2' spec.licenses = ['MIT'] spec.name = 'oauth2' spec.require_paths = ['lib'] spec.required_rubygems_version = '>= 1.3.6' spec.signing_key = File.expand_path("~/.gem/private_key.pem") if $0 =~ /gem\z/ spec.summary = %q{A Ruby wrapper for the OAuth 2.0 protocol.} spec.test_files = Dir.glob("spec/**/*") spec.version = OAuth2::Version end ruby-oauth2-0.9.1/spec/000077500000000000000000000000001215047350200146335ustar00rootroot00000000000000ruby-oauth2-0.9.1/spec/helper.rb000066400000000000000000000005421215047350200164400ustar00rootroot00000000000000unless ENV['CI'] require 'simplecov' SimpleCov.start do add_filter 'spec' end end require 'oauth2' require 'addressable/uri' require 'rspec' require 'rspec/autorun' RSpec.configure do |config| config.expect_with :rspec do |c| c.syntax = :expect end end Faraday.default_adapter = :test RSpec.configure do |conf| include OAuth2 end ruby-oauth2-0.9.1/spec/oauth2/000077500000000000000000000000001215047350200160355ustar00rootroot00000000000000ruby-oauth2-0.9.1/spec/oauth2/access_token_spec.rb000066400000000000000000000130501215047350200220340ustar00rootroot00000000000000require 'helper' VERBS = [:get, :post, :put, :delete] describe AccessToken do let(:token) {'monkey'} let(:token_body) {MultiJson.encode(:access_token => 'foo', :expires_in => 600, :refresh_token => 'bar')} let(:refresh_body) {MultiJson.encode(:access_token => 'refreshed_foo', :expires_in => 600, :refresh_token => 'refresh_bar')} let(:client) do Client.new('abc', 'def', :site => 'https://api.example.com') do |builder| builder.request :url_encoded builder.adapter :test do |stub| VERBS.each do |verb| stub.send(verb, '/token/header') {|env| [200, {}, env[:request_headers]['Authorization']]} stub.send(verb, "/token/query?access_token=#{token}") {|env| [200, {}, Addressable::URI.parse(env[:url]).query_values['access_token']]} stub.send(verb, '/token/body') {|env| [200, {}, env[:body]]} end stub.post('/oauth/token') {|env| [200, {'Content-Type' => 'application/json'}, refresh_body]} end end end subject {AccessToken.new(client, token)} describe "#initialize" do it "assigns client and token" do expect(subject.client).to eq(client) expect(subject.token).to eq(token) end it "assigns extra params" do target = AccessToken.new(client, token, 'foo' => 'bar') expect(target.params).to include('foo') expect(target.params['foo']).to eq('bar') end def assert_initialized_token(target) expect(target.token).to eq(token) expect(target).to be_expires expect(target.params.keys).to include('foo') expect(target.params['foo']).to eq('bar') end it "initializes with a Hash" do hash = {:access_token => token, :expires_at => Time.now.to_i + 200, 'foo' => 'bar'} target = AccessToken.from_hash(client, hash) assert_initialized_token(target) end it "initalizes with a form-urlencoded key/value string" do kvform = "access_token=#{token}&expires_at=#{Time.now.to_i+200}&foo=bar" target = AccessToken.from_kvform(client, kvform) assert_initialized_token(target) end it "sets options" do target = AccessToken.new(client, token, :param_name => 'foo', :header_format => 'Bearer %', :mode => :body) expect(target.options[:param_name]).to eq('foo') expect(target.options[:header_format]).to eq('Bearer %') expect(target.options[:mode]).to eq(:body) end it "initializes with a string expires_at" do hash = {:access_token => token, :expires_at => '1361396829', 'foo' => 'bar'} target = AccessToken.from_hash(client, hash) assert_initialized_token(target) expect(target.expires_at).to be_a(Integer) end end describe "#request" do context ":mode => :header" do before :all do subject.options[:mode] = :header end VERBS.each do |verb| it "sends the token in the Authorization header for a #{verb.to_s.upcase} request" do expect(subject.post('/token/header').body).to include(token) end end end context ":mode => :query" do before :all do subject.options[:mode] = :query end VERBS.each do |verb| it "sends the token in the Authorization header for a #{verb.to_s.upcase} request" do expect(subject.post('/token/query').body).to eq(token) end end end context ":mode => :body" do before :all do subject.options[:mode] = :body end VERBS.each do |verb| it "sends the token in the Authorization header for a #{verb.to_s.upcase} request" do expect(subject.post('/token/body').body.split('=').last).to eq(token) end end end end describe "#expires?" do it "is false if there is no expires_at" do expect(AccessToken.new(client, token)).not_to be_expires end it "is true if there is an expires_in" do expect(AccessToken.new(client, token, :refresh_token => 'abaca', :expires_in => 600)).to be_expires end it "is true if there is an expires_at" do expect(AccessToken.new(client, token, :refresh_token => 'abaca', :expires_in => Time.now.getutc.to_i+600)).to be_expires end end describe "#expired?" do it "is false if there is no expires_in or expires_at" do expect(AccessToken.new(client, token)).not_to be_expired end it "is false if expires_in is in the future" do expect(AccessToken.new(client, token, :refresh_token => 'abaca', :expires_in => 10800)).not_to be_expired end it "is true if expires_at is in the past" do access = AccessToken.new(client, token, :refresh_token => 'abaca', :expires_in => 600) @now = Time.now + 10800 Time.stub!(:now).and_return(@now) expect(access).to be_expired end end describe "#refresh!" do let(:access) { AccessToken.new(client, token, :refresh_token => 'abaca', :expires_in => 600, :param_name => 'o_param') } it "returns a refresh token with appropriate values carried over" do refreshed = access.refresh! expect(access.client).to eq(refreshed.client) expect(access.options[:param_name]).to eq(refreshed.options[:param_name]) end context "with a nil refresh_token in the response" do let(:refresh_body) { MultiJson.encode(:access_token => 'refreshed_foo', :expires_in => 600, :refresh_token => nil) } it "copies the refresh_token from the original token" do refreshed = access.refresh! expect(refreshed.refresh_token).to eq(access.refresh_token) end end end end ruby-oauth2-0.9.1/spec/oauth2/client_spec.rb000066400000000000000000000154031215047350200206550ustar00rootroot00000000000000require 'helper' describe OAuth2::Client do let!(:error_value) {'invalid_token'} let!(:error_description_value) {'bad bad token'} subject do OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com') do |builder| builder.adapter :test do |stub| stub.get('/success') {|env| [200, {'Content-Type' => 'text/awesome'}, 'yay']} stub.get('/reflect') {|env| [200, {}, env[:body]]} stub.post('/reflect') {|env| [200, {}, env[:body]]} stub.get('/unauthorized') {|env| [401, {'Content-Type' => 'application/json'}, MultiJson.encode(:error => error_value, :error_description => error_description_value)]} stub.get('/conflict') {|env| [409, {'Content-Type' => 'text/plain'}, 'not authorized']} stub.get('/redirect') {|env| [302, {'Content-Type' => 'text/plain', 'location' => '/success' }, '']} stub.post('/redirect') {|env| [303, {'Content-Type' => 'text/plain', 'location' => '/reflect' }, '']} stub.get('/error') {|env| [500, {'Content-Type' => 'text/plain'}, 'unknown error']} stub.get('/empty_get') {|env| [204, {}, nil]} end end end describe "#initialize" do it "assigns id and secret" do expect(subject.id).to eq('abc') expect(subject.secret).to eq('def') end it "assigns site from the options hash" do expect(subject.site).to eq('https://api.example.com') end it "assigns Faraday::Connection#host" do expect(subject.connection.host).to eq('api.example.com') end it "leaves Faraday::Connection#ssl unset" do expect(subject.connection.ssl).to eq({}) end it "is able to pass a block to configure the connection" do connection = stub('connection') session = stub('session', :to_ary => nil) builder = stub('builder') connection.stub(:build).and_yield(builder) Faraday::Connection.stub(:new => connection) builder.should_receive(:adapter).with(:test) OAuth2::Client.new('abc', 'def') do |builder| builder.adapter :test end.connection end it "defaults raise_errors to true" do expect(subject.options[:raise_errors]).to be_true end it "allows true/false for raise_errors option" do client = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :raise_errors => false) expect(client.options[:raise_errors]).to be_false client = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :raise_errors => true) expect(client.options[:raise_errors]).to be_true end it "allows get/post for access_token_method option" do client = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :access_token_method => :get) expect(client.options[:access_token_method]).to eq(:get) client = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :access_token_method => :post) expect(client.options[:access_token_method]).to eq(:post) end end %w(authorize token).each do |url_type| describe ":#{url_type}_url option" do it "defaults to a path of /oauth/#{url_type}" do expect(subject.send("#{url_type}_url")).to eq("https://api.example.com/oauth/#{url_type}") end it "is settable via the :#{url_type}_url option" do subject.options[:"#{url_type}_url"] = '/oauth/custom' expect(subject.send("#{url_type}_url")).to eq('https://api.example.com/oauth/custom') end it "allows a different host than the site" do subject.options[:"#{url_type}_url"] = 'https://api.foo.com/oauth/custom' expect(subject.send("#{url_type}_url")).to eq('https://api.foo.com/oauth/custom') end end end describe "#request" do it "works with a null response body" do expect(subject.request(:get, 'empty_get').body).to eq('') end it "returns on a successful response" do response = subject.request(:get, '/success') expect(response.body).to eq('yay') expect(response.status).to eq(200) expect(response.headers).to eq({'Content-Type' => 'text/awesome'}) end it "posts a body" do response = subject.request(:post, '/reflect', :body => 'foo=bar') expect(response.body).to eq('foo=bar') end it "follows redirects properly" do response = subject.request(:get, '/redirect') expect(response.body).to eq('yay') expect(response.status).to eq(200) expect(response.headers).to eq({'Content-Type' => 'text/awesome'}) end it "redirects using GET on a 303" do response = subject.request(:post, '/redirect', :body => 'foo=bar') expect(response.body).to be_empty expect(response.status).to eq(200) end it "obeys the :max_redirects option" do max_redirects = subject.options[:max_redirects] subject.options[:max_redirects] = 0 response = subject.request(:get, '/redirect') expect(response.status).to eq(302) subject.options[:max_redirects] = max_redirects end it "returns if raise_errors is false" do subject.options[:raise_errors] = false response = subject.request(:get, '/unauthorized') expect(response.status).to eq(401) expect(response.headers).to eq({'Content-Type' => 'application/json'}) expect(response.error).not_to be_nil end %w(/unauthorized /conflict /error).each do |error_path| it "raises OAuth2::Error on error response to path #{error_path}" do expect{subject.request(:get, error_path)}.to raise_error(OAuth2::Error) end end it "parses OAuth2 standard error response" do begin subject.request(:get, '/unauthorized') rescue Exception => e expect(e.code).to eq(error_value) expect(e.description).to eq(error_description_value) expect(e.to_s).to match(/#{error_value}/) expect(e.to_s).to match(/#{error_description_value}/) end end it "provides the response in the Exception" do begin subject.request(:get, '/error') rescue Exception => e expect(e.response).not_to be_nil expect(e.to_s).to match(/unknown error/) end end end it "instantiates an AuthCode strategy with this client" do expect(subject.auth_code).to be_kind_of(OAuth2::Strategy::AuthCode) end it "instantiates an Implicit strategy with this client" do expect(subject.implicit).to be_kind_of(OAuth2::Strategy::Implicit) end context "with SSL options" do subject do cli = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com', :ssl => {:ca_file => 'foo.pem'}) cli.connection.build do |b| b.adapter :test end cli end it "passes the SSL options along to Faraday::Connection#ssl" do expect(subject.connection.ssl).to eq({:ca_file => 'foo.pem'}) end end end ruby-oauth2-0.9.1/spec/oauth2/response_spec.rb000066400000000000000000000060601215047350200212340ustar00rootroot00000000000000require 'helper' describe OAuth2::Response do describe "#initialize" do let(:status) {200} let(:headers) {{'foo' => 'bar'}} let(:body) {'foo'} it "returns the status, headers and body" do response = double('response', :headers => headers, :status => status, :body => body) subject = Response.new(response) expect(subject.headers).to eq(headers) expect(subject.status).to eq(status) expect(subject.body).to eq(body) end end describe ".register_parser" do let(:response) { double('response', :headers => {'Content-Type' => 'application/foo-bar'}, :status => 200, :body => 'baz') } before do OAuth2::Response.register_parser(:foobar, 'application/foo-bar') do |body| "foobar #{body}" end end it "adds to the content types and parsers" do expect(OAuth2::Response::PARSERS.keys).to include(:foobar) expect(OAuth2::Response::CONTENT_TYPES.keys).to include('application/foo-bar') end it "is able to parse that content type automatically" do expect(OAuth2::Response.new(response).parsed).to eq('foobar baz') end end describe "#parsed" do it "parses application/x-www-form-urlencoded body" do headers = {'Content-Type' => 'application/x-www-form-urlencoded'} body = 'foo=bar&answer=42' response = double('response', :headers => headers, :body => body) subject = Response.new(response) expect(subject.parsed.keys.size).to eq(2) expect(subject.parsed['foo']).to eq('bar') expect(subject.parsed['answer']).to eq('42') end it "parses application/json body" do headers = {'Content-Type' => 'application/json'} body = MultiJson.encode(:foo => 'bar', :answer => 42) response = double('response', :headers => headers, :body => body) subject = Response.new(response) expect(subject.parsed.keys.size).to eq(2) expect(subject.parsed['foo']).to eq('bar') expect(subject.parsed['answer']).to eq(42) end it "doesn't try to parse other content-types" do headers = {'Content-Type' => 'text/html'} body = '' response = double('response', :headers => headers, :body => body) MultiJson.should_not_receive(:decode) MultiJson.should_not_receive(:load) Rack::Utils.should_not_receive(:parse_query) subject = Response.new(response) expect(subject.parsed).to be_nil end end context "xml parser registration" do it "tries to load multi_xml and use it" do expect(OAuth2::Response::PARSERS[:xml]).not_to be_nil end it "is able to parse xml" do headers = {'Content-Type' => 'text/xml'} body = 'baz' response = double('response', :headers => headers, :body => body) expect(OAuth2::Response.new(response).parsed).to eq({"foo" => {"bar" => "baz"}}) end end end ruby-oauth2-0.9.1/spec/oauth2/strategy/000077500000000000000000000000001215047350200176775ustar00rootroot00000000000000ruby-oauth2-0.9.1/spec/oauth2/strategy/assertion_spec.rb000066400000000000000000000027441215047350200232540ustar00rootroot00000000000000require 'helper' describe OAuth2::Strategy::Assertion do let(:client) do cli = OAuth2::Client.new('abc', 'def', :site => 'http://api.example.com') cli.connection.build do |b| b.adapter :test do |stub| stub.post('/oauth/token') do |env| case @mode when "formencoded" [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, 'expires_in=600&access_token=salmon&refresh_token=trout'] when "json" [200, {'Content-Type' => 'application/json'}, '{"expires_in":600,"access_token":"salmon","refresh_token":"trout"}'] end end end end cli end let(:params) { {:hmac_secret => 'foo'}} subject {client.assertion} describe "#authorize_url" do it "raises NotImplementedError" do expect{subject.authorize_url}.to raise_error(NotImplementedError) end end %w(json formencoded).each do |mode| describe "#get_token (#{mode})" do before do @mode = mode @access = subject.get_token(params) end it "returns AccessToken with same Client" do expect(@access.client).to eq(client) end it "returns AccessToken with #token" do expect(@access.token).to eq('salmon') end it "returns AccessToken with #expires_in" do expect(@access.expires_in).to eq(600) end it "returns AccessToken with #expires_at" do expect(@access.expires_at).not_to be_nil end end end end ruby-oauth2-0.9.1/spec/oauth2/strategy/auth_code_spec.rb000066400000000000000000000060411215047350200231720ustar00rootroot00000000000000require 'helper' describe OAuth2::Strategy::AuthCode do let(:code) {'sushi'} let(:kvform_token) {'expires_in=600&access_token=salmon&refresh_token=trout&extra_param=steve'} let(:facebook_token) {kvform_token.gsub('_in', '')} let(:json_token) {MultiJson.encode(:expires_in => 600, :access_token => 'salmon', :refresh_token => 'trout', :extra_param => 'steve')} let(:client) do OAuth2::Client.new('abc', 'def', :site => 'http://api.example.com') do |builder| builder.adapter :test do |stub| stub.get("/oauth/token?client_id=abc&client_secret=def&code=#{code}&grant_type=authorization_code") do |env| case @mode when "formencoded" [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, kvform_token] when "json" [200, {'Content-Type' => 'application/json'}, json_token] when "from_facebook" [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, facebook_token] end end stub.post('/oauth/token', {'client_id' => 'abc', 'client_secret' => 'def', 'code' => 'sushi', 'grant_type' => 'authorization_code'}) do |env| case @mode when "formencoded" [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, kvform_token] when "json" [200, {'Content-Type' => 'application/json'}, json_token] when "from_facebook" [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, facebook_token] end end end end end subject {client.auth_code} describe "#authorize_url" do it "includes the client_id" do expect(subject.authorize_url).to include('client_id=abc') end it "includes the type" do expect(subject.authorize_url).to include('response_type=code') end it "includes passed in options" do cb = 'http://myserver.local/oauth/callback' expect(subject.authorize_url(:redirect_uri => cb)).to include("redirect_uri=#{Rack::Utils.escape(cb)}") end end %w(json formencoded from_facebook).each do |mode| [:get, :post].each do |verb| describe "#get_token (#{mode}, access_token_method=#{verb}" do before :each do @mode = mode client.options[:token_method] = verb @access = subject.get_token(code) end it "returns AccessToken with same Client" do expect(@access.client).to eq(client) end it "returns AccessToken with #token" do expect(@access.token).to eq('salmon') end it "returns AccessToken with #refresh_token" do expect(@access.refresh_token).to eq('trout') end it "returns AccessToken with #expires_in" do expect(@access.expires_in).to eq(600) end it "returns AccessToken with #expires_at" do expect(@access.expires_at).to be_kind_of(Integer) end it "returns AccessToken with params accessible via []" do expect(@access['extra_param']).to eq('steve') end end end end end ruby-oauth2-0.9.1/spec/oauth2/strategy/base_spec.rb000066400000000000000000000002771215047350200221560ustar00rootroot00000000000000require 'helper' describe OAuth2::Strategy::Base do it "initializes with a Client" do expect{OAuth2::Strategy::Base.new(OAuth2::Client.new('abc', 'def'))}.not_to raise_error end end ruby-oauth2-0.9.1/spec/oauth2/strategy/client_credentials_spec.rb000066400000000000000000000046511215047350200250770ustar00rootroot00000000000000require 'helper' describe OAuth2::Strategy::ClientCredentials do let(:kvform_token) { 'expires_in=600&access_token=salmon&refresh_token=trout' } let(:json_token) { '{"expires_in":600,"access_token":"salmon","refresh_token":"trout"}' } let(:client) do OAuth2::Client.new('abc', 'def', :site => 'http://api.example.com') do |builder| builder.adapter :test do |stub| stub.post('/oauth/token', {'grant_type' => 'client_credentials'}) do |env| client_id, client_secret = HTTPAuth::Basic.unpack_authorization(env[:request_headers]['Authorization']) client_id == 'abc' && client_secret == 'def' or raise Faraday::Adapter::Test::Stubs::NotFound.new case @mode when "formencoded" [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, kvform_token] when "json" [200, {'Content-Type' => 'application/json'}, json_token] end end stub.post('/oauth/token', {'client_id' => 'abc', 'client_secret' => 'def', 'grant_type' => 'client_credentials'}) do |env| case @mode when "formencoded" [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, kvform_token] when "json" [200, {'Content-Type' => 'application/json'}, json_token] end end end end end subject {client.client_credentials} describe "#authorize_url" do it "raises NotImplementedError" do expect{subject.authorize_url}.to raise_error(NotImplementedError) end end %w(json formencoded).each do |mode| %w(default basic_auth request_body).each do |auth_scheme| describe "#get_token (#{mode}) (#{auth_scheme})" do before do @mode = mode @access = subject.get_token({}, auth_scheme == 'default' ? {} : {'auth_scheme' => auth_scheme}) end it "returns AccessToken with same Client" do expect(@access.client).to eq(client) end it "returns AccessToken with #token" do expect(@access.token).to eq('salmon') end it "returns AccessToken without #refresh_token" do expect(@access.refresh_token).to be_nil end it "returns AccessToken with #expires_in" do expect(@access.expires_in).to eq(600) end it "returns AccessToken with #expires_at" do expect(@access.expires_at).not_to be_nil end end end end end ruby-oauth2-0.9.1/spec/oauth2/strategy/implicit_spec.rb000066400000000000000000000014241215047350200230510ustar00rootroot00000000000000require 'helper' describe OAuth2::Strategy::Implicit do let(:client) { OAuth2::Client.new('abc', 'def', :site => 'http://api.example.com') } subject {client.implicit} describe "#authorize_url" do it "includes the client_id" do expect(subject.authorize_url).to include('client_id=abc') end it "includes the type" do expect(subject.authorize_url).to include('response_type=token') end it "includes passed in options" do cb = 'http://myserver.local/oauth/callback' expect(subject.authorize_url(:redirect_uri => cb)).to include("redirect_uri=#{Rack::Utils.escape(cb)}") end end describe "#get_token" do it "raises NotImplementedError" do expect{subject.get_token}.to raise_error(NotImplementedError) end end end ruby-oauth2-0.9.1/spec/oauth2/strategy/password_spec.rb000066400000000000000000000030731215047350200231030ustar00rootroot00000000000000require 'helper' describe OAuth2::Strategy::Password do let(:client) do cli = OAuth2::Client.new('abc', 'def', :site => 'http://api.example.com') cli.connection.build do |b| b.adapter :test do |stub| stub.post('/oauth/token') do |env| case @mode when "formencoded" [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, 'expires_in=600&access_token=salmon&refresh_token=trout'] when "json" [200, {'Content-Type' => 'application/json'}, '{"expires_in":600,"access_token":"salmon","refresh_token":"trout"}'] end end end end cli end subject {client.password} describe "#authorize_url" do it "raises NotImplementedError" do expect{subject.authorize_url}.to raise_error(NotImplementedError) end end %w(json formencoded).each do |mode| describe "#get_token (#{mode})" do before do @mode = mode @access = subject.get_token('username', 'password') end it "returns AccessToken with same Client" do expect(@access.client).to eq(client) end it "returns AccessToken with #token" do expect(@access.token).to eq('salmon') end it "returns AccessToken with #refresh_token" do expect(@access.refresh_token).to eq('trout') end it "returns AccessToken with #expires_in" do expect(@access.expires_in).to eq(600) end it "returns AccessToken with #expires_at" do expect(@access.expires_at).not_to be_nil end end end end