oauth2-rails2 0.0.13a

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,24 @@
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
+ rdoc
22
+ pkg
23
+
24
+ ## PROJECT::SPECIFIC
data/CHANGELOG.rdoc ADDED
@@ -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/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.
data/README.rdoc ADDED
@@ -0,0 +1,85 @@
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
+ == Foursquare Example
69
+
70
+ ==
71
+
72
+
73
+ == Note on Patches/Pull Requests
74
+
75
+ * Fork the project.
76
+ * Make your feature addition or bug fix.
77
+ * Add tests for it. This is important so I don't break it in a
78
+ future version unintentionally.
79
+ * Commit, do not mess with rakefile, version, or history.
80
+ (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)
81
+ * Send me a pull request. Bonus points for topic branches.
82
+
83
+ == Copyright
84
+
85
+ Copyright (c) 2010 Intridea, Inc. and Michael Bleigh. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,51 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "oauth2"
8
+ gem.summary = %Q{A Ruby wrapper for the OAuth 2.0 protocol.}
9
+ gem.description = %Q{A Ruby wrapper for the OAuth 2.0 protocol built with a similar style to the original OAuth gem.}
10
+ gem.email = "michael@intridea.com"
11
+ gem.homepage = "http://github.com/intridea/oauth2"
12
+ gem.authors = ["Michael Bleigh"]
13
+ gem.add_dependency 'faraday', '~> 0.4.1'
14
+ gem.add_dependency 'multi_json', '>= 0.0.4'
15
+ gem.add_development_dependency "rspec", ">= 1.2.9"
16
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
17
+ end
18
+ Jeweler::GemcutterTasks.new
19
+
20
+ task :spec => :check_dependencies
21
+ rescue LoadError
22
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
23
+ end
24
+
25
+ begin
26
+ require 'spec/rake/spectask'
27
+ Spec::Rake::SpecTask.new(:spec) do |spec|
28
+ spec.libs << 'lib' << 'spec'
29
+ spec.spec_files = FileList['spec/**/*_spec.rb']
30
+ end
31
+
32
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
33
+ spec.libs << 'lib' << 'spec'
34
+ spec.pattern = 'spec/**/*_spec.rb'
35
+ spec.rcov = true
36
+ end
37
+
38
+ task :default => :spec
39
+ rescue LoadError
40
+ puts "RSpec (or a dependency) not available. Install it with: gem install rspec"
41
+ end
42
+
43
+ require 'rake/rdoctask'
44
+ Rake::RDocTask.new do |rdoc|
45
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
46
+
47
+ rdoc.rdoc_dir = 'rdoc'
48
+ rdoc.title = "oauth2 #{version}"
49
+ rdoc.rdoc_files.include('README*')
50
+ rdoc.rdoc_files.include('lib/**/*.rb')
51
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.13
@@ -0,0 +1,38 @@
1
+ module OAuth2
2
+ class AccessToken
3
+ attr_reader :client, :token, :refresh_token, :expires_in, :expires_at
4
+
5
+ def initialize(client, token, refresh_token = nil, expires_in = nil)
6
+ @client = client
7
+ @token = token
8
+ @refresh_token = refresh_token
9
+ @expires_in = (expires_in.nil? || expires_in == '') ? nil : expires_in.to_i
10
+ @expires_at = Time.now + @expires_in if @expires_in
11
+ end
12
+
13
+ # True if the token in question has an expiration time.
14
+ def expires?
15
+ !!@expires_in
16
+ end
17
+
18
+ def request(verb, path, params = {}, headers = {})
19
+ @client.request(verb, path, params.merge('access_token' => @token), headers.merge('Authorization' => "Token token=\"#{@token}\""))
20
+ end
21
+
22
+ def get(path, params = {}, headers = {})
23
+ request(:get, path, params, headers)
24
+ end
25
+
26
+ def post(path, params = {}, headers = {})
27
+ request(:post, path, params, headers)
28
+ end
29
+
30
+ def put(path, params = {}, headers = {})
31
+ request(:put, path, params, headers)
32
+ end
33
+
34
+ def delete(path, params = {}, headers = {})
35
+ request(:delete, path, params, headers)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,101 @@
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
+ case resp.status
66
+ when 200...201
67
+ if json?
68
+ begin
69
+ ResponseHash.new(resp)
70
+ rescue StandardError => e
71
+ ResponseString.new(resp)
72
+ end
73
+ else
74
+ ResponseString.new(resp)
75
+ end
76
+ when 301
77
+ if json?
78
+ begin
79
+ ResponseHash.new(resp)
80
+ rescue StandardError => e
81
+ ResponseString.new(resp)
82
+ end
83
+ else
84
+ ResponseString.new(resp)
85
+ end
86
+ when 401
87
+ e = OAuth2::AccessDenied.new("Received HTTP 401 during request.")
88
+ e.response = resp
89
+ raise e
90
+ else
91
+ e = OAuth2::HTTPError.new("Received HTTP #{resp.status} during request.")
92
+ e.response = resp
93
+ raise e
94
+ end
95
+ end
96
+
97
+ def json?; !!@json end
98
+
99
+ def web_server; OAuth2::Strategy::WebServer.new(self) end
100
+ end
101
+ end
@@ -0,0 +1,13 @@
1
+ class ResponseHash < Hash
2
+ def initialize(response)
3
+ self.response = response
4
+
5
+ body = MultiJson.decode(response.body)
6
+ body.keys.each{|k| self[k] = body[k]}
7
+ end
8
+
9
+ attr_accessor :response
10
+
11
+ def status; response.status end
12
+ def headers; response.headers end
13
+ end
@@ -0,0 +1,15 @@
1
+ # This special String class is returned from HTTP requests
2
+ # and contains the original full response along with convenience
3
+ # methods for accessing the HTTP status code and headers. It
4
+ # is returned from all access token requests.
5
+ class ResponseString < String
6
+ def initialize(response)
7
+ super(response.body)
8
+ self.response = response
9
+ end
10
+
11
+ attr_accessor :response
12
+
13
+ def status; response.status end
14
+ def headers; response.headers end
15
+ 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('type' => 'web_server')
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']
27
+ OAuth2::AccessToken.new(@client, access, refresh, expires_in)
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
+ 'type' => 'web_server',
39
+ 'code' => code
40
+ })
41
+ end
42
+ end
43
+ end
44
+ end
data/lib/oauth2.rb ADDED
@@ -0,0 +1,12 @@
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_string'
12
+ require 'oauth2/response_hash'
@@ -0,0 +1,75 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{oauth2-rails2}
8
+ s.version = "0.0.13a"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Michael Bleigh"]
12
+ s.date = %q{2010-08-17}
13
+ s.description = %q{A Ruby wrapper for the OAuth 2.0 protocol built with a similar style to the original OAuth gem.}
14
+ s.email = %q{michael@intridea.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "CHANGELOG.rdoc",
23
+ "LICENSE",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "lib/oauth2.rb",
28
+ "lib/oauth2/access_token.rb",
29
+ "lib/oauth2/client.rb",
30
+ "lib/oauth2/response_hash.rb",
31
+ "lib/oauth2/response_string.rb",
32
+ "lib/oauth2/strategy/base.rb",
33
+ "lib/oauth2/strategy/web_server.rb",
34
+ "oauth2-rails2.gemspec",
35
+ "spec/oauth2/access_token_spec.rb",
36
+ "spec/oauth2/client_spec.rb",
37
+ "spec/oauth2/strategy/base_spec.rb",
38
+ "spec/oauth2/strategy/web_server_spec.rb",
39
+ "spec/spec.opts",
40
+ "spec/spec_helper.rb",
41
+ "specs.watchr"
42
+ ]
43
+ s.homepage = %q{http://github.com/intridea/oauth2}
44
+ s.rdoc_options = ["--charset=UTF-8"]
45
+ s.require_paths = ["lib"]
46
+ s.rubygems_version = %q{1.3.7}
47
+ s.summary = %q{A Ruby wrapper for the OAuth 2.0 protocol.}
48
+ s.test_files = [
49
+ "spec/oauth2/access_token_spec.rb",
50
+ "spec/oauth2/client_spec.rb",
51
+ "spec/oauth2/strategy/base_spec.rb",
52
+ "spec/oauth2/strategy/web_server_spec.rb",
53
+ "spec/spec_helper.rb"
54
+ ]
55
+
56
+ if s.respond_to? :specification_version then
57
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
58
+ s.specification_version = 3
59
+
60
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
61
+ s.add_runtime_dependency(%q<faraday>, ["~> 0.4.1"])
62
+ s.add_runtime_dependency(%q<multi_json>, [">= 0.0.4"])
63
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
64
+ else
65
+ s.add_dependency(%q<faraday>, ["~> 0.4.1"])
66
+ s.add_dependency(%q<multi_json>, [">= 0.0.4"])
67
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
68
+ end
69
+ else
70
+ s.add_dependency(%q<faraday>, ["~> 0.4.1"])
71
+ s.add_dependency(%q<multi_json>, [">= 0.0.4"])
72
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
73
+ end
74
+ end
75
+
@@ -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?access_token=monkey') { |env| [200, {}, 'get'] }
9
+ stub.post('/client') { |env| [200, {}, 'access_token=' << env[:body]['access_token']] }
10
+ stub.put('/client') { |env| [200, {}, 'access_token=' << env[:body]['access_token']] }
11
+ stub.delete('/client') { |env| [200, {}, 'access_token=' << env[:body]['access_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 == 'access_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,97 @@
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
+ response.should be_kind_of(ResponseHash)
80
+ response['abc'].should == 'def'
81
+ end
82
+
83
+ it 'should only try to decode application/json' do
84
+ subject.request(:get, '/success').should == 'yay'
85
+ end
86
+ end
87
+
88
+ it 'should set json? based on the :parse_json option' do
89
+ OAuth2::Client.new('abc','def', :site => 'http://example.com', :parse_json => true).should be_json
90
+ OAuth2::Client.new('abc','def', :site => 'http://example.com', :parse_json => false).should_not be_json
91
+ end
92
+
93
+ after do
94
+ subject.json = false
95
+ end
96
+ end
97
+ 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,65 @@
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']
12
+ when "json"
13
+ [200, {}, '{"expires_in":600,"access_token":"salmon","refresh_token":"trout"}']
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('type=web_server')
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
+ end
64
+ end
65
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --backtrace
@@ -0,0 +1,12 @@
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 'spec'
6
+ require 'spec/autorun'
7
+
8
+ Faraday.default_adapter = :test
9
+
10
+ Spec::Runner.configure do |config|
11
+
12
+ end
data/specs.watchr ADDED
@@ -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,140 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: oauth2-rails2
3
+ version: !ruby/object:Gem::Version
4
+ hash: 420914397
5
+ prerelease: true
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 13a
10
+ version: 0.0.13a
11
+ platform: ruby
12
+ authors:
13
+ - Michael Bleigh
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-08-17 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: faraday
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 13
30
+ segments:
31
+ - 0
32
+ - 4
33
+ - 1
34
+ version: 0.4.1
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: multi_json
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 23
46
+ segments:
47
+ - 0
48
+ - 0
49
+ - 4
50
+ version: 0.0.4
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: rspec
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 13
62
+ segments:
63
+ - 1
64
+ - 2
65
+ - 9
66
+ version: 1.2.9
67
+ type: :development
68
+ version_requirements: *id003
69
+ description: A Ruby wrapper for the OAuth 2.0 protocol built with a similar style to the original OAuth gem.
70
+ email: michael@intridea.com
71
+ executables: []
72
+
73
+ extensions: []
74
+
75
+ extra_rdoc_files:
76
+ - LICENSE
77
+ - README.rdoc
78
+ files:
79
+ - .document
80
+ - .gitignore
81
+ - CHANGELOG.rdoc
82
+ - LICENSE
83
+ - README.rdoc
84
+ - Rakefile
85
+ - VERSION
86
+ - lib/oauth2.rb
87
+ - lib/oauth2/access_token.rb
88
+ - lib/oauth2/client.rb
89
+ - lib/oauth2/response_hash.rb
90
+ - lib/oauth2/response_string.rb
91
+ - lib/oauth2/strategy/base.rb
92
+ - lib/oauth2/strategy/web_server.rb
93
+ - oauth2-rails2.gemspec
94
+ - spec/oauth2/access_token_spec.rb
95
+ - spec/oauth2/client_spec.rb
96
+ - spec/oauth2/strategy/base_spec.rb
97
+ - spec/oauth2/strategy/web_server_spec.rb
98
+ - spec/spec.opts
99
+ - spec/spec_helper.rb
100
+ - specs.watchr
101
+ has_rdoc: true
102
+ homepage: http://github.com/intridea/oauth2
103
+ licenses: []
104
+
105
+ post_install_message:
106
+ rdoc_options:
107
+ - --charset=UTF-8
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ hash: 3
116
+ segments:
117
+ - 0
118
+ version: "0"
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ none: false
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ hash: 3
125
+ segments:
126
+ - 0
127
+ version: "0"
128
+ requirements: []
129
+
130
+ rubyforge_project:
131
+ rubygems_version: 1.3.7
132
+ signing_key:
133
+ specification_version: 3
134
+ summary: A Ruby wrapper for the OAuth 2.0 protocol.
135
+ test_files:
136
+ - spec/oauth2/access_token_spec.rb
137
+ - spec/oauth2/client_spec.rb
138
+ - spec/oauth2/strategy/base_spec.rb
139
+ - spec/oauth2/strategy/web_server_spec.rb
140
+ - spec/spec_helper.rb