nov-oauth2 0.1.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,33 @@
1
+ .rvmrc
2
+ /live
3
+
4
+ ## MAC OS
5
+ .DS_Store
6
+
7
+ ## TEXTMATE
8
+ *.tmproj
9
+ tmtags
10
+
11
+ ## EMACS
12
+ *~
13
+ \#*
14
+ .\#*
15
+
16
+ ## VIM
17
+ *.swp
18
+
19
+ ## PROJECT::GENERAL
20
+ coverage
21
+ doc
22
+ rdoc
23
+ log
24
+
25
+ ## BUNDLER
26
+ *.gem
27
+ .bundle
28
+ pkg
29
+
30
+ ## RCOV
31
+ coverage.data
32
+
33
+ ## PROJECT::SPECIFIC
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --backtrace
3
+ --format=nested
@@ -0,0 +1,22 @@
1
+ == 0.0.10 (June 19)
2
+
3
+ * Handle ActiveSupport JSON case where incompatible string does not raise an error. (via Flameeyes)
4
+ * Depend on latest version of MultiJSON.
5
+
6
+ == 0.0.9 (June 18)
7
+
8
+ * Support a JSON token response with swappable JSON parser via MultiJSON.
9
+ * Add support for "expires_in" parameter and relevant methods on AccessToken.
10
+
11
+ == 0.0.8 (April 27)
12
+
13
+ * Change get_request_token to use POST to conform to OAuth 2.0 spec. (via jeremy)
14
+
15
+ == 0.0.7 (April 27)
16
+
17
+ * Updating Faraday dependency for improved SSL support (via technoweenie)
18
+
19
+ == 0.0.6 (April 25)
20
+
21
+ * Added ResponseString so as not to throw away response information when making requests.
22
+ * Deprecated #access_token on WebServer strategy in favor of #get_access_token
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,42 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ oauth2 (0.1.1)
5
+ faraday (~> 0.5.0)
6
+ multi_json (~> 0.0.4)
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ addressable (2.1.2)
12
+ diff-lcs (1.1.2)
13
+ faraday (0.5.0)
14
+ addressable (~> 2.1.1)
15
+ multipart-post (~> 1.0.1)
16
+ rack (~> 1.2.1)
17
+ json_pure (1.4.6)
18
+ multi_json (0.0.4)
19
+ multipart-post (1.0.1)
20
+ rack (1.2.1)
21
+ rake (0.8.7)
22
+ rcov (0.9.9)
23
+ rspec (2.4.0)
24
+ rspec-core (~> 2.4.0)
25
+ rspec-expectations (~> 2.4.0)
26
+ rspec-mocks (~> 2.4.0)
27
+ rspec-core (2.4.0)
28
+ rspec-expectations (2.4.0)
29
+ diff-lcs (~> 1.1.2)
30
+ rspec-mocks (2.4.0)
31
+
32
+ PLATFORMS
33
+ ruby
34
+
35
+ DEPENDENCIES
36
+ faraday (~> 0.5.0)
37
+ json_pure (~> 1.4.6)
38
+ multi_json (~> 0.0.4)
39
+ oauth2!
40
+ rake (~> 0.8)
41
+ rcov (~> 0.9)
42
+ rspec (~> 2.4.0)
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Intridea, Inc. and Michael Bleigh
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,80 @@
1
+ = OAuth2
2
+
3
+ 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.
4
+
5
+ == Installation
6
+
7
+ gem install oauth2
8
+
9
+ == Resources
10
+
11
+ * View Source on GitHub (http://github.com/intridea/oauth2)
12
+ * Report Issues on GitHub (http://github.com/intridea/oauth2/issues)
13
+ * Read More at the Wiki (http://wiki.github.com/intridea/oauth2/)
14
+
15
+ == Web Server Example (Sinatra)
16
+
17
+ Below is a fully functional example of a Sinatra application that would authenticate to Facebook utilizing the OAuth 2.0 web server flow.
18
+
19
+ require 'rubygems'
20
+ require 'sinatra'
21
+ require 'oauth2'
22
+ require 'json'
23
+
24
+ def client
25
+ OAuth2::Client.new('app_id', 'app_secret', :site => 'https://graph.facebook.com')
26
+ end
27
+
28
+ get '/auth/facebook' do
29
+ redirect client.web_server.authorize_url(
30
+ :redirect_uri => redirect_uri,
31
+ :scope => 'email,offline_access'
32
+ )
33
+ end
34
+
35
+ get '/auth/facebook/callback' do
36
+ access_token = client.web_server.get_access_token(params[:code], :redirect_uri => redirect_uri)
37
+ user = JSON.parse(access_token.get('/me'))
38
+
39
+ user.inspect
40
+ end
41
+
42
+ def redirect_uri
43
+ uri = URI.parse(request.url)
44
+ uri.path = '/auth/facebook/callback'
45
+ uri.query = nil
46
+ uri.to_s
47
+ end
48
+
49
+ That's all there is to it! You can use the access token like you would with the
50
+ OAuth gem, calling HTTP verbs on it etc. You can view more examples on the OAuth2
51
+ Wiki (http://wiki.github.com/intridea/oauth2/examples)
52
+
53
+ == JSON Parsing
54
+
55
+ Because JSON has become the standard format of the OAuth 2.0 specification,
56
+ the <tt>oauth2</tt> gem contains a mode that will perform automatic parsing
57
+ of JSON response bodies, returning a hash instead of a string. To enable this
58
+ mode, simply add the <tt>:parse_json</tt> option to your client initialization:
59
+
60
+ client = OAuth2::Client.new('app_id', 'app_secret',
61
+ :site => 'https://example.com',
62
+ :parse_json => true
63
+ )
64
+
65
+ # Obtain an access token using the client
66
+ token.get('/some/url.json') # {"some" => "hash"}
67
+
68
+ == Note on Patches/Pull Requests
69
+
70
+ * Fork the project.
71
+ * Make your feature addition or bug fix.
72
+ * Add tests for it. This is important so I don't break it in a
73
+ future version unintentionally.
74
+ * Commit, do not mess with rakefile, version, or history.
75
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
76
+ * Send me a pull request. Bonus points for topic branches.
77
+
78
+ == Copyright
79
+
80
+ Copyright (c) 2010 Intridea, Inc. and Michael Bleigh. See LICENSE for details.
@@ -0,0 +1,31 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ desc "Run all examples"
6
+ RSpec::Core::RakeTask.new(:spec) do |t|
7
+ t.rspec_opts = %w[--color]
8
+ end
9
+
10
+ task :cleanup_rcov_files do
11
+ rm_rf 'coverage.data'
12
+ end
13
+
14
+ namespace :spec do
15
+ desc "Run all examples using rcov"
16
+ RSpec::Core::RakeTask.new :rcov => :cleanup_rcov_files do |t|
17
+ t.rcov = true
18
+ t.rcov_opts = %[-Ilib -Ispec --exclude "gems/*,features"]
19
+ t.rcov_opts << %[--text-report --sort coverage --no-html --aggregate coverage.data]
20
+ end
21
+ end
22
+
23
+ task :default => :spec
24
+
25
+ require 'rake/rdoctask'
26
+ Rake::RDocTask.new do |rdoc|
27
+ rdoc.rdoc_dir = 'rdoc'
28
+ rdoc.title = "oauth2 #{OAuth2::VERSION}"
29
+ rdoc.rdoc_files.include('README*')
30
+ rdoc.rdoc_files.include('lib/**/*.rb')
31
+ end
@@ -0,0 +1,11 @@
1
+ module OAuth2
2
+ class ErrorWithResponse < StandardError; attr_accessor :response end
3
+ class AccessDenied < ErrorWithResponse; end
4
+ class HTTPError < ErrorWithResponse; end
5
+ end
6
+
7
+ require 'oauth2/client'
8
+ require 'oauth2/strategy/base'
9
+ require 'oauth2/strategy/web_server'
10
+ require 'oauth2/access_token'
11
+ require 'oauth2/response_object'
@@ -0,0 +1,47 @@
1
+ module OAuth2
2
+ class AccessToken
3
+ attr_reader :client, :token, :refresh_token, :expires_in, :expires_at
4
+ attr_accessor :token_param
5
+
6
+ def initialize(client, token, refresh_token = nil, expires_in = nil, params = {})
7
+ @client = client
8
+ @token = token.to_s
9
+ @refresh_token = refresh_token.to_s
10
+ @expires_in = (expires_in.nil? || expires_in == '') ? nil : expires_in.to_i
11
+ @expires_at = Time.now + @expires_in if @expires_in
12
+ @params = params
13
+ @token_param = 'oauth_token'
14
+ end
15
+
16
+ def [](key)
17
+ @params[key]
18
+ end
19
+
20
+ # True if the token in question has an expiration time.
21
+ def expires?
22
+ !!@expires_in
23
+ end
24
+
25
+ def request(verb, path, params = {}, headers = {})
26
+ params = params.merge token_param => @token
27
+ headers = headers.merge 'Authorization' => "OAuth #{@token}"
28
+ @client.request(verb, path, params, headers)
29
+ end
30
+
31
+ def get(path, params = {}, headers = {})
32
+ request(:get, path, params, headers)
33
+ end
34
+
35
+ def post(path, params = {}, headers = {})
36
+ request(:post, path, params, headers)
37
+ end
38
+
39
+ def put(path, params = {}, headers = {})
40
+ request(:put, path, params, headers)
41
+ end
42
+
43
+ def delete(path, params = {}, headers = {})
44
+ request(:delete, path, params, headers)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,88 @@
1
+ require 'faraday'
2
+
3
+ module OAuth2
4
+ class Client
5
+ class << self
6
+ def default_connection_adapter
7
+ warn '[DEPRECATED] OAuth2::Client#default_connection_adapter is deprecated, use Faraday.default_adapter instead. Will be removed in 0.1.0'
8
+ Faraday.default_adapter
9
+ end
10
+
11
+ def default_connection_adapter=(adapter)
12
+ warn '[DEPRECATED] OAuth2::Client#default_connection_adapter is deprecated, use Faraday.default_adapter instead. Will be removed in 0.1.0'
13
+ Faraday.default_adapter = adapter
14
+ end
15
+ end
16
+
17
+ attr_accessor :id, :secret, :site, :connection, :options
18
+ attr_writer :json
19
+
20
+ # Instantiate a new OAuth 2.0 client using the
21
+ # client ID and client secret registered to your
22
+ # application.
23
+ #
24
+ # Options:
25
+ #
26
+ # <tt>:site</tt> :: Specify a base URL for your OAuth 2.0 client.
27
+ # <tt>:authorize_path</tt> :: Specify the path to the authorization endpoint.
28
+ # <tt>:authorize_url</tt> :: Specify a full URL of the authorization endpoint.
29
+ # <tt>:access_token_path</tt> :: Specify the path to the access token endpoint.
30
+ # <tt>:access_token_url</tt> :: Specify the full URL of the access token endpoint.
31
+ # <tt>:parse_json</tt> :: If true, <tt>application/json</tt> responses will be automatically parsed.
32
+ def initialize(client_id, client_secret, opts = {})
33
+ adapter = opts.delete(:adapter)
34
+ self.id = client_id
35
+ self.secret = client_secret
36
+ self.site = opts.delete(:site) if opts[:site]
37
+ self.options = opts
38
+ self.connection = Faraday::Connection.new(site)
39
+ self.json = opts.delete(:parse_json)
40
+
41
+ if adapter && adapter != :test
42
+ connection.build { |b| b.adapter(adapter) }
43
+ end
44
+ end
45
+
46
+ def authorize_url(params = nil)
47
+ path = options[:authorize_url] || options[:authorize_path] || "/oauth/authorize"
48
+ connection.build_url(path, params).to_s
49
+ end
50
+
51
+ def access_token_url(params = nil)
52
+ path = options[:access_token_url] || options[:access_token_path] || "/oauth/access_token"
53
+ connection.build_url(path, params).to_s
54
+ end
55
+
56
+ # Makes a request relative to the specified site root.
57
+ def request(verb, url, params = {}, headers = {})
58
+ if verb == :get
59
+ resp = connection.run_request(verb, url, nil, headers) do |req|
60
+ req.params.update(params)
61
+ end
62
+ else
63
+ resp = connection.run_request(verb, url, params, headers)
64
+ end
65
+
66
+ case resp.status
67
+ when 200..299
68
+ if json?
69
+ return ResponseObject.from(resp)
70
+ else
71
+ return ResponseString.new(resp)
72
+ end
73
+ when 401
74
+ e = OAuth2::AccessDenied.new("Received HTTP 401 during request.")
75
+ e.response = resp
76
+ raise e
77
+ else
78
+ e = OAuth2::HTTPError.new("Received HTTP #{resp.status} during request.")
79
+ e.response = resp
80
+ raise e
81
+ end
82
+ end
83
+
84
+ def json?; !!@json end
85
+
86
+ def web_server; OAuth2::Strategy::WebServer.new(self) end
87
+ end
88
+ end
@@ -0,0 +1,58 @@
1
+ module OAuth2
2
+ module ResponseObject
3
+ def self.from(response)
4
+ object = MultiJson.decode(response.body)
5
+
6
+ case object
7
+ when Array
8
+ ResponseArray.new(response, object)
9
+ when Hash
10
+ ResponseHash.new(response, object)
11
+ else
12
+ ResponseString.new(response)
13
+ end
14
+ rescue
15
+ ResponseString.new(response)
16
+ end
17
+
18
+ def self.included(base)
19
+ base.class_eval do
20
+ attr_accessor :response
21
+ end
22
+ end
23
+
24
+ def headers; response.headers end
25
+ def status; response.status end
26
+ end
27
+
28
+ class ResponseHash < Hash
29
+ include ResponseObject
30
+
31
+ def initialize(response, hash)
32
+ self.response = response
33
+ hash.keys.each{|k| self[k] = hash[k]}
34
+ end
35
+ end
36
+
37
+ class ResponseArray < Array
38
+ include ResponseObject
39
+
40
+ def initialize(response, array)
41
+ self.response = response
42
+ super(array)
43
+ end
44
+ end
45
+
46
+ # This special String class is returned from HTTP requests
47
+ # and contains the original full response along with convenience
48
+ # methods for accessing the HTTP status code and headers. It
49
+ # is returned from all access token requests.
50
+ class ResponseString < String
51
+ include ResponseObject
52
+
53
+ def initialize(response)
54
+ super(response.body)
55
+ self.response = response
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,29 @@
1
+ module OAuth2
2
+ module Strategy
3
+ class Base #:nodoc:
4
+ def initialize(client)#:nodoc:
5
+ @client = client
6
+ end
7
+
8
+ def authorize_url(options = {}) #:nodoc:
9
+ @client.authorize_url(authorize_params(options))
10
+ end
11
+
12
+ def authorize_params(options = {}) #:nodoc:
13
+ options = options.inject({}){|h, (k, v)| h[k.to_s] = v; h}
14
+ {'client_id' => @client.id}.merge(options)
15
+ end
16
+
17
+ def access_token_url(options = {})
18
+ @client.access_token_url(access_token_params(options))
19
+ end
20
+
21
+ def access_token_params(options = {})
22
+ {
23
+ 'client_id' => @client.id,
24
+ 'client_secret' => @client.secret
25
+ }.merge(options)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,44 @@
1
+ require 'multi_json'
2
+
3
+ module OAuth2
4
+ module Strategy
5
+ class WebServer < Base
6
+ def authorize_params(options = {}) #:nodoc:
7
+ super(options).merge('response_type' => 'code')
8
+ end
9
+
10
+ # Retrieve an access token given the specified validation code.
11
+ # Note that you must also provide a <tt>:redirect_uri</tt> option
12
+ # in order to successfully verify your request for most OAuth 2.0
13
+ # endpoints.
14
+ def get_access_token(code, options = {})
15
+ response = @client.request(:post, @client.access_token_url, access_token_params(code, options))
16
+
17
+ params = MultiJson.decode(response) rescue nil
18
+ # the ActiveSupport JSON parser won't cause an exception when
19
+ # given a formencoded string, so make sure that it was
20
+ # actually parsed in an Hash. This covers even the case where
21
+ # it caused an exception since it'll still be nil.
22
+ params = Rack::Utils.parse_query(response) unless params.is_a? Hash
23
+
24
+ access = params['access_token']
25
+ refresh = params['refresh_token']
26
+ expires_in = params['expires_in'] || params['expires'] # params['expires'] is only for facebook
27
+ OAuth2::AccessToken.new(@client, access, refresh, expires_in, params)
28
+ end
29
+
30
+ # <b>DEPRECATED:</b> Use #get_access_token instead.
31
+ def access_token(*args)
32
+ warn '[DEPRECATED] OAuth2::Strategy::WebServer#access_token is deprecated, use #get_access_token instead. Will be removed in 0.1.0'
33
+ get_access_token(*args)
34
+ end
35
+
36
+ def access_token_params(code, options = {}) #:nodoc:
37
+ super(options).merge({
38
+ 'grant_type' => 'authorization_code',
39
+ 'code' => code
40
+ })
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,3 @@
1
+ module OAuth2
2
+ VERSION = "0.1.1.1"
3
+ end
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path("../lib/oauth2/version", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "nov-oauth2"
6
+ s.version = OAuth2::VERSION
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.3.6") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Nov Matake", "Michael Bleigh"]
9
+ s.description = %q{A Ruby wrapper for the OAuth 2.0 protocol built with a similar style to the original OAuth gem.}
10
+ s.summary = %q{Michael Bleigh's OAuth Gem with OAuth 2.0 Draft v.10 support.}
11
+ s.email = "nov@matake.com"
12
+ s.extra_rdoc_files = ["LICENSE", "README.rdoc"]
13
+ s.rdoc_options = ["--charset=UTF-8"]
14
+ s.homepage = "http://github.com/nov/oauth2"
15
+ s.require_paths = ["lib"]
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.add_runtime_dependency("faraday", "~> 0.5.0")
20
+ s.add_runtime_dependency("multi_json", "~> 0.0.4")
21
+ s.add_development_dependency("json_pure", "~> 1.4.6")
22
+ s.add_development_dependency("rake", "~> 0.8")
23
+ s.add_development_dependency("rcov", "~> 0.9")
24
+ s.add_development_dependency("rspec", "~> 2.4.0")
25
+ end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ describe OAuth2::AccessToken do
4
+ let(:client) do
5
+ cli = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com')
6
+ cli.connection.build do |b|
7
+ b.adapter :test do |stub|
8
+ stub.get('/client?oauth_token=monkey') { |env| [200, {}, 'get'] }
9
+ stub.post('/client') { |env| [200, {}, 'oauth_token=' << env[:body]['oauth_token']] }
10
+ stub.put('/client') { |env| [200, {}, 'oauth_token=' << env[:body]['oauth_token']] }
11
+ stub.delete('/client') { |env| [200, {}, 'oauth_token=' << env[:body]['oauth_token']] }
12
+ end
13
+ end
14
+ cli
15
+ end
16
+
17
+ let(:token) { 'monkey' }
18
+
19
+ subject { OAuth2::AccessToken.new(client, token) }
20
+
21
+ describe '#initialize' do
22
+ it 'should assign client and token' do
23
+ subject.client.should == client
24
+ subject.token.should == token
25
+ end
26
+
27
+ it "makes GET requests with access token" do
28
+ subject.send(:get, 'client').should == 'get'
29
+ end
30
+
31
+ %w(post put delete).each do |http_method|
32
+ it "makes #{http_method.upcase} requests with access token" do
33
+ subject.send(http_method.to_sym, 'client').should == 'oauth_token=monkey'
34
+ end
35
+ end
36
+ end
37
+
38
+ describe '#expires?' do
39
+ it 'should be false if there is no expires_at' do
40
+ OAuth2::AccessToken.new(client, token).should_not be_expires
41
+ end
42
+
43
+ it 'should be true if there is an expires_at' do
44
+ OAuth2::AccessToken.new(client, token, 'abaca', 600).should be_expires
45
+ end
46
+ end
47
+
48
+ describe '#expires_at' do
49
+ before do
50
+ @now = Time.now
51
+ Time.stub!(:now).and_return(@now)
52
+ end
53
+
54
+ subject{ OAuth2::AccessToken.new(client, token, 'abaca', 600)}
55
+
56
+ it 'should be a time representation of #expires_in' do
57
+ subject.expires_at.should == (@now + 600)
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,98 @@
1
+ require 'spec_helper'
2
+
3
+ describe OAuth2::Client do
4
+ subject do
5
+ cli = OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com')
6
+ cli.connection.build do |b|
7
+ b.adapter :test do |stub|
8
+ stub.get('/success') { |env| [200, {'Content-Type' => 'text/awesome'}, 'yay'] }
9
+ stub.get('/unauthorized') { |env| [401, {}, ''] }
10
+ stub.get('/error') { |env| [500, {}, ''] }
11
+ stub.get('/json') { |env| [200, {'Content-Type' => 'application/json; charset=utf8'}, '{"abc":"def"}']}
12
+ end
13
+ end
14
+ cli
15
+ end
16
+
17
+ describe '#initialize' do
18
+ it 'should assign id and secret' do
19
+ subject.id.should == 'abc'
20
+ subject.secret.should == 'def'
21
+ end
22
+
23
+ it 'should assign site from the options hash' do
24
+ subject.site.should == 'https://api.example.com'
25
+ end
26
+
27
+ it 'should assign Faraday::Connection#host' do
28
+ subject.connection.host.should == 'api.example.com'
29
+ end
30
+ end
31
+
32
+ %w(authorize access_token).each do |path_type|
33
+ describe "##{path_type}_url" do
34
+ it "should default to a path of /oauth/#{path_type}" do
35
+ subject.send("#{path_type}_url").should == "https://api.example.com/oauth/#{path_type}"
36
+ end
37
+
38
+ it "should be settable via the :#{path_type}_path option" do
39
+ subject.options[:"#{path_type}_path"] = '/oauth/custom'
40
+ subject.send("#{path_type}_url").should == 'https://api.example.com/oauth/custom'
41
+ end
42
+
43
+ it "should be settable via the :#{path_type}_url option" do
44
+ subject.options[:"#{path_type}_url"] = 'https://abc.com/authorize'
45
+ subject.send("#{path_type}_url").should == 'https://abc.com/authorize'
46
+ end
47
+ end
48
+ end
49
+
50
+ describe "#request" do
51
+ it "returns ResponseString on successful response" do
52
+ response = subject.request(:get, '/success', {}, {})
53
+ response.should == 'yay'
54
+ response.status.should == 200
55
+ response.headers.should == {'Content-Type' => 'text/awesome'}
56
+ end
57
+
58
+ it "raises OAuth2::AccessDenied on 401 response" do
59
+ lambda { subject.request(:get, '/unauthorized', {}, {}) }.should raise_error(OAuth2::AccessDenied)
60
+ end
61
+
62
+ it "raises OAuth2::HTTPError on error response" do
63
+ lambda { subject.request(:get, '/error', {}, {}) }.should raise_error(OAuth2::HTTPError)
64
+ end
65
+ end
66
+
67
+ it '#web_server should instantiate a WebServer strategy with this client' do
68
+ subject.web_server.should be_kind_of(OAuth2::Strategy::WebServer)
69
+ end
70
+
71
+ context 'with JSON parsing' do
72
+ before do
73
+ subject.json = true
74
+ end
75
+
76
+ describe '#request' do
77
+ it 'should return a response hash' do
78
+ response = subject.request(:get, '/json')
79
+ puts response.inspect
80
+ response.should be_kind_of(OAuth2::ResponseHash)
81
+ response['abc'].should == 'def'
82
+ end
83
+
84
+ it 'should only try to decode application/json' do
85
+ subject.request(:get, '/success').should == 'yay'
86
+ end
87
+ end
88
+
89
+ it 'should set json? based on the :parse_json option' do
90
+ OAuth2::Client.new('abc', 'def', :site => 'http://example.com', :parse_json => true).should be_json
91
+ OAuth2::Client.new('abc', 'def', :site => 'http://example.com', :parse_json => false).should_not be_json
92
+ end
93
+
94
+ after do
95
+ subject.json = false
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe OAuth2::Strategy::Base do
4
+ it 'should initialize with a Client' do
5
+ lambda{ OAuth2::Strategy::Base.new(OAuth2::Client.new('abc', 'def')) }.should_not raise_error
6
+ end
7
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe OAuth2::Strategy::WebServer do
4
+ let(:client) do
5
+ cli = OAuth2::Client.new('abc', 'def', :site => 'http://api.example.com')
6
+ cli.connection.build do |b|
7
+ b.adapter :test do |stub|
8
+ stub.post('/oauth/access_token') do |env|
9
+ case @mode
10
+ when "formencoded"
11
+ [200, {}, 'expires_in=600&access_token=salmon&refresh_token=trout&extra_param=steve']
12
+ when "json"
13
+ [200, {}, '{"expires_in":600,"access_token":"salmon","refresh_token":"trout","extra_param":"steve"}']
14
+ end
15
+ end
16
+ end
17
+ end
18
+ cli
19
+ end
20
+ subject { client.web_server }
21
+
22
+ describe '#authorize_url' do
23
+ it 'should include the client_id' do
24
+ subject.authorize_url.should be_include('client_id=abc')
25
+ end
26
+
27
+ it 'should include the type' do
28
+ subject.authorize_url.should be_include('response_type=code')
29
+ end
30
+
31
+ it 'should include passed in options' do
32
+ cb = 'http://myserver.local/oauth/callback'
33
+ subject.authorize_url(:redirect_uri => cb).should be_include("redirect_uri=#{Rack::Utils.escape(cb)}")
34
+ end
35
+ end
36
+
37
+ %w(json formencoded).each do |mode|
38
+ describe "#get_access_token (#{mode})" do
39
+ before do
40
+ @mode = mode
41
+ @access = subject.get_access_token('sushi')
42
+ end
43
+
44
+ it 'returns AccessToken with same Client' do
45
+ @access.client.should == client
46
+ end
47
+
48
+ it 'returns AccessToken with #token' do
49
+ @access.token.should == 'salmon'
50
+ end
51
+
52
+ it 'returns AccessToken with #refresh_token' do
53
+ @access.refresh_token.should == 'trout'
54
+ end
55
+
56
+ it 'returns AccessToken with #expires_in' do
57
+ @access.expires_in.should == 600
58
+ end
59
+
60
+ it 'returns AccessToken with #expires_at' do
61
+ @access.expires_at.should be_kind_of(Time)
62
+ end
63
+
64
+ it 'returns AccessToken with params accessible via []' do
65
+ @access['extra_param'].should == 'steve'
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,8 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'rubygems'
4
+ require 'oauth2'
5
+ require 'rspec'
6
+ require 'rspec/autorun'
7
+
8
+ Faraday.default_adapter = :test
@@ -0,0 +1,61 @@
1
+ # Run me with:
2
+ #
3
+ # $ watchr specs.watchr
4
+
5
+ # --------------------------------------------------
6
+ # Convenience Methods
7
+ # --------------------------------------------------
8
+ def all_test_files
9
+ Dir['spec/**/*_spec.rb']
10
+ end
11
+
12
+ def run_test_matching(thing_to_match)
13
+ matches = all_test_files.grep(/#{thing_to_match}/i)
14
+ if matches.empty?
15
+ puts "Sorry, thanks for playing, but there were no matches for #{thing_to_match}"
16
+ else
17
+ run matches.join(' ')
18
+ end
19
+ end
20
+
21
+ def run(files_to_run)
22
+ puts("Running: #{files_to_run}")
23
+ system("clear;spec -cfs --backtrace #{files_to_run}")
24
+ no_int_for_you
25
+ end
26
+
27
+ def run_all_tests
28
+ # system("clear;rake spec")
29
+ run(all_test_files.join(' '))
30
+ end
31
+
32
+ # --------------------------------------------------
33
+ # Watchr Rules
34
+ # --------------------------------------------------
35
+ watch('^spec/(.*)_spec\.rb') { |m| run_test_matching(m[1]) }
36
+ watch('^lib/(.*)\.rb') { |m| run_test_matching(m[1]) }
37
+ watch('^sites/(.*)\.rb') { |m| run_test_matching(m[1]) }
38
+ watch('^spec/spec_helper\.rb') { run_all_tests }
39
+ watch('^spec/support/.*\.rb') { run_all_tests }
40
+
41
+ # --------------------------------------------------
42
+ # Signal Handling
43
+ # --------------------------------------------------
44
+
45
+ def no_int_for_you
46
+ @sent_an_int = nil
47
+ end
48
+
49
+ Signal.trap 'INT' do
50
+ if @sent_an_int then
51
+ puts " A second INT? Ok, I get the message. Shutting down now."
52
+ exit
53
+ else
54
+ puts " Did you just send me an INT? Ugh. I'll quit for real if you do it again."
55
+ @sent_an_int = true
56
+ Kernel.sleep 1.5
57
+ run_all_tests
58
+ end
59
+ end
60
+
61
+ # vim:ft=ruby
metadata ADDED
@@ -0,0 +1,191 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nov-oauth2
3
+ version: !ruby/object:Gem::Version
4
+ hash: 65
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 1
10
+ - 1
11
+ version: 0.1.1.1
12
+ platform: ruby
13
+ authors:
14
+ - Nov Matake
15
+ - Michael Bleigh
16
+ autorequire:
17
+ bindir: bin
18
+ cert_chain: []
19
+
20
+ date: 2011-03-09 00:00:00 +09:00
21
+ default_executable:
22
+ dependencies:
23
+ - !ruby/object:Gem::Dependency
24
+ name: faraday
25
+ prerelease: false
26
+ requirement: &id001 !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - ~>
30
+ - !ruby/object:Gem::Version
31
+ hash: 11
32
+ segments:
33
+ - 0
34
+ - 5
35
+ - 0
36
+ version: 0.5.0
37
+ type: :runtime
38
+ version_requirements: *id001
39
+ - !ruby/object:Gem::Dependency
40
+ name: multi_json
41
+ prerelease: false
42
+ requirement: &id002 !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ hash: 23
48
+ segments:
49
+ - 0
50
+ - 0
51
+ - 4
52
+ version: 0.0.4
53
+ type: :runtime
54
+ version_requirements: *id002
55
+ - !ruby/object:Gem::Dependency
56
+ name: json_pure
57
+ prerelease: false
58
+ requirement: &id003 !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ~>
62
+ - !ruby/object:Gem::Version
63
+ hash: 11
64
+ segments:
65
+ - 1
66
+ - 4
67
+ - 6
68
+ version: 1.4.6
69
+ type: :development
70
+ version_requirements: *id003
71
+ - !ruby/object:Gem::Dependency
72
+ name: rake
73
+ prerelease: false
74
+ requirement: &id004 !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ~>
78
+ - !ruby/object:Gem::Version
79
+ hash: 27
80
+ segments:
81
+ - 0
82
+ - 8
83
+ version: "0.8"
84
+ type: :development
85
+ version_requirements: *id004
86
+ - !ruby/object:Gem::Dependency
87
+ name: rcov
88
+ prerelease: false
89
+ requirement: &id005 !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ~>
93
+ - !ruby/object:Gem::Version
94
+ hash: 25
95
+ segments:
96
+ - 0
97
+ - 9
98
+ version: "0.9"
99
+ type: :development
100
+ version_requirements: *id005
101
+ - !ruby/object:Gem::Dependency
102
+ name: rspec
103
+ prerelease: false
104
+ requirement: &id006 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ hash: 31
110
+ segments:
111
+ - 2
112
+ - 4
113
+ - 0
114
+ version: 2.4.0
115
+ type: :development
116
+ version_requirements: *id006
117
+ description: A Ruby wrapper for the OAuth 2.0 protocol built with a similar style to the original OAuth gem.
118
+ email: nov@matake.com
119
+ executables: []
120
+
121
+ extensions: []
122
+
123
+ extra_rdoc_files:
124
+ - LICENSE
125
+ - README.rdoc
126
+ files:
127
+ - .document
128
+ - .gitignore
129
+ - .rspec
130
+ - CHANGELOG.rdoc
131
+ - Gemfile
132
+ - Gemfile.lock
133
+ - LICENSE
134
+ - README.rdoc
135
+ - Rakefile
136
+ - lib/oauth2.rb
137
+ - lib/oauth2/access_token.rb
138
+ - lib/oauth2/client.rb
139
+ - lib/oauth2/response_object.rb
140
+ - lib/oauth2/strategy/base.rb
141
+ - lib/oauth2/strategy/web_server.rb
142
+ - lib/oauth2/version.rb
143
+ - oauth2.gemspec
144
+ - spec/oauth2/access_token_spec.rb
145
+ - spec/oauth2/client_spec.rb
146
+ - spec/oauth2/strategy/base_spec.rb
147
+ - spec/oauth2/strategy/web_server_spec.rb
148
+ - spec/spec_helper.rb
149
+ - specs.watchr
150
+ has_rdoc: true
151
+ homepage: http://github.com/nov/oauth2
152
+ licenses: []
153
+
154
+ post_install_message:
155
+ rdoc_options:
156
+ - --charset=UTF-8
157
+ require_paths:
158
+ - lib
159
+ required_ruby_version: !ruby/object:Gem::Requirement
160
+ none: false
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ hash: 3
165
+ segments:
166
+ - 0
167
+ version: "0"
168
+ required_rubygems_version: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ hash: 23
174
+ segments:
175
+ - 1
176
+ - 3
177
+ - 6
178
+ version: 1.3.6
179
+ requirements: []
180
+
181
+ rubyforge_project:
182
+ rubygems_version: 1.5.3
183
+ signing_key:
184
+ specification_version: 3
185
+ summary: Michael Bleigh's OAuth Gem with OAuth 2.0 Draft v.10 support.
186
+ test_files:
187
+ - spec/oauth2/access_token_spec.rb
188
+ - spec/oauth2/client_spec.rb
189
+ - spec/oauth2/strategy/base_spec.rb
190
+ - spec/oauth2/strategy/web_server_spec.rb
191
+ - spec/spec_helper.rb