oauth2-provider 0.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. data/.gitignore +8 -0
  2. data/Gemfile +3 -0
  3. data/README.md +49 -0
  4. data/Rakefile +24 -0
  5. data/examples/client/Gemfile +6 -0
  6. data/examples/client/Gemfile.lock +20 -0
  7. data/examples/client/README +8 -0
  8. data/examples/client/app.rb +59 -0
  9. data/examples/client/config.ru +3 -0
  10. data/examples/client/views/home.haml +3 -0
  11. data/examples/client/views/response.haml +11 -0
  12. data/examples/rails3-example/.gitignore +4 -0
  13. data/examples/rails3-example/Gemfile +10 -0
  14. data/examples/rails3-example/Gemfile.lock +82 -0
  15. data/examples/rails3-example/README +9 -0
  16. data/examples/rails3-example/Rakefile +7 -0
  17. data/examples/rails3-example/app/controllers/account_controller.rb +14 -0
  18. data/examples/rails3-example/app/controllers/application_controller.rb +18 -0
  19. data/examples/rails3-example/app/controllers/authorization_controller.rb +18 -0
  20. data/examples/rails3-example/app/controllers/home_controller.rb +4 -0
  21. data/examples/rails3-example/app/controllers/session_controller.rb +24 -0
  22. data/examples/rails3-example/app/helpers/application_helper.rb +2 -0
  23. data/examples/rails3-example/app/models/account.rb +6 -0
  24. data/examples/rails3-example/app/views/authorization/new.html.erb +5 -0
  25. data/examples/rails3-example/app/views/home/show.html.erb +1 -0
  26. data/examples/rails3-example/app/views/layouts/application.html.erb +16 -0
  27. data/examples/rails3-example/app/views/session/new.html.erb +7 -0
  28. data/examples/rails3-example/config.ru +4 -0
  29. data/examples/rails3-example/config/application.rb +42 -0
  30. data/examples/rails3-example/config/boot.rb +6 -0
  31. data/examples/rails3-example/config/database.yml +22 -0
  32. data/examples/rails3-example/config/environment.rb +5 -0
  33. data/examples/rails3-example/config/environments/development.rb +26 -0
  34. data/examples/rails3-example/config/environments/production.rb +49 -0
  35. data/examples/rails3-example/config/environments/test.rb +35 -0
  36. data/examples/rails3-example/config/initializers/backtrace_silencers.rb +7 -0
  37. data/examples/rails3-example/config/initializers/inflections.rb +10 -0
  38. data/examples/rails3-example/config/initializers/mime_types.rb +5 -0
  39. data/examples/rails3-example/config/initializers/secret_token.rb +7 -0
  40. data/examples/rails3-example/config/initializers/session_store.rb +8 -0
  41. data/examples/rails3-example/config/locales/en.yml +5 -0
  42. data/examples/rails3-example/config/routes.rb +9 -0
  43. data/examples/rails3-example/db/migrate/20110508151935_add_account_table.rb +12 -0
  44. data/examples/rails3-example/db/migrate/20110508151948_add_oauth2_tables.rb +43 -0
  45. data/examples/rails3-example/db/schema.rb +52 -0
  46. data/examples/rails3-example/db/seeds.rb +11 -0
  47. data/examples/rails3-example/doc/README_FOR_APP +2 -0
  48. data/examples/rails3-example/lib/tasks/.gitkeep +0 -0
  49. data/examples/rails3-example/public/404.html +26 -0
  50. data/examples/rails3-example/public/422.html +26 -0
  51. data/examples/rails3-example/public/500.html +26 -0
  52. data/examples/rails3-example/public/favicon.ico +0 -0
  53. data/examples/rails3-example/public/images/rails.png +0 -0
  54. data/examples/rails3-example/public/robots.txt +5 -0
  55. data/examples/rails3-example/public/stylesheets/.gitkeep +0 -0
  56. data/examples/rails3-example/script/rails +6 -0
  57. data/lib/oauth2-provider.rb +3 -0
  58. data/lib/oauth2/provider.rb +39 -0
  59. data/lib/oauth2/provider/models.rb +40 -0
  60. data/lib/oauth2/provider/models/access_token.rb +54 -0
  61. data/lib/oauth2/provider/models/active_record.rb +30 -0
  62. data/lib/oauth2/provider/models/active_record/access_token.rb +13 -0
  63. data/lib/oauth2/provider/models/active_record/authorization.rb +16 -0
  64. data/lib/oauth2/provider/models/active_record/authorization_code.rb +13 -0
  65. data/lib/oauth2/provider/models/active_record/client.rb +15 -0
  66. data/lib/oauth2/provider/models/authorization.rb +40 -0
  67. data/lib/oauth2/provider/models/authorization_code.rb +27 -0
  68. data/lib/oauth2/provider/models/client.rb +28 -0
  69. data/lib/oauth2/provider/models/mongoid.rb +30 -0
  70. data/lib/oauth2/provider/models/mongoid/access_token.rb +40 -0
  71. data/lib/oauth2/provider/models/mongoid/authorization.rb +32 -0
  72. data/lib/oauth2/provider/models/mongoid/authorization_code.rb +43 -0
  73. data/lib/oauth2/provider/models/mongoid/client.rb +40 -0
  74. data/lib/oauth2/provider/rack.rb +11 -0
  75. data/lib/oauth2/provider/rack/access_token_handler.rb +103 -0
  76. data/lib/oauth2/provider/rack/authorization_code_request.rb +74 -0
  77. data/lib/oauth2/provider/rack/authorization_codes_support.rb +25 -0
  78. data/lib/oauth2/provider/rack/middleware.rb +28 -0
  79. data/lib/oauth2/provider/rack/resource_request.rb +91 -0
  80. data/lib/oauth2/provider/rack/responses.rb +34 -0
  81. data/lib/oauth2/provider/rails.rb +37 -0
  82. data/lib/oauth2/provider/rails/controller_authentication.rb +21 -0
  83. data/lib/oauth2/provider/random.rb +30 -0
  84. data/lib/oauth2/provider/version.rb +5 -0
  85. data/oauth2-provider.gemspec +35 -0
  86. data/spec/models/access_token_spec.rb +123 -0
  87. data/spec/models/authorization_code_spec.rb +115 -0
  88. data/spec/models/authorization_spec.rb +110 -0
  89. data/spec/models/client_spec.rb +75 -0
  90. data/spec/requests/access_tokens_controller_spec.rb +360 -0
  91. data/spec/requests/authentication_spec.rb +150 -0
  92. data/spec/requests/authorization_codes_support_spec.rb +157 -0
  93. data/spec/schema.rb +38 -0
  94. data/spec/set_backend_env_to_mongoid.rb +1 -0
  95. data/spec/spec_helper.rb +27 -0
  96. data/spec/support/activerecord_backend.rb +18 -0
  97. data/spec/support/factories.rb +56 -0
  98. data/spec/support/macros.rb +46 -0
  99. data/spec/support/mongoid_backend.rb +34 -0
  100. data/spec/support/rack.rb +32 -0
  101. metadata +373 -0
@@ -0,0 +1,34 @@
1
+ require 'addressable/uri'
2
+
3
+ module OAuth2::Provider::Rack::Responses
4
+ def self.unauthorized(error = nil)
5
+ challenge = "OAuth2"
6
+ challenge << %{ error="#{error}"} if error
7
+ [401, {'Content-Type' => 'text/plain', 'Content-Length' => '0', 'WWW-Authenticate' => challenge}, []]
8
+ end
9
+
10
+ def self.only_supported(supported)
11
+ [405, {'Allow' => supported}, ["Only #{supported} requests allowed"]]
12
+ end
13
+
14
+ def self.json_error(error, options = {})
15
+ description = %{, "error_description": "#{options[:description]}"} if options[:description]
16
+ [options[:status] || 400, {'Content-Type' => 'application/json'}, [%{{"error": "#{error}"#{description}}}]]
17
+ end
18
+
19
+ def self.redirect_with_error(error, uri)
20
+ [302, {'Location' => append_to_uri(uri, :error => error)}, []]
21
+ end
22
+
23
+ def self.redirect_with_code(code, uri)
24
+ [302, {'Location' => append_to_uri(uri, :code => code)}, []]
25
+ end
26
+
27
+ private
28
+
29
+ def self.append_to_uri(uri, parameters = {})
30
+ u = Addressable::URI.parse(uri)
31
+ u.query_values = (u.query_values || {}).merge(parameters)
32
+ u.to_s
33
+ end
34
+ end
@@ -0,0 +1,37 @@
1
+ require 'oauth2/provider'
2
+
3
+ module OAuth2::Provider::Rails
4
+ autoload :ControllerAuthentication, 'oauth2/provider/rails/controller_authentication'
5
+
6
+ class Railtie < Rails::Railtie
7
+ config.oauth2_provider = ActiveSupport::OrderedOptions.new
8
+ config.oauth2_provider.activerecord = ActiveSupport::OrderedOptions.new
9
+ config.oauth2_provider.mongoid = ActiveSupport::OrderedOptions.new
10
+
11
+ initializer "oauth2_provider.config" do |app|
12
+ app.config.oauth2_provider.except(:activerecord, :mongoid).each do |k,v|
13
+ OAuth2::Provider.send "#{k}=", v
14
+ end
15
+
16
+ app.config.oauth2_provider.activerecord.each do |k, v|
17
+ OAuth2::Provider::Models::ActiveRecord.send "#{k}=", v
18
+ end
19
+
20
+ app.config.oauth2_provider.mongoid.each do |k, v|
21
+ OAuth2::Provider::Models::Mongoid.send "#{k}=", v
22
+ end
23
+
24
+ OAuth2::Provider.activate
25
+ end
26
+
27
+ initializer "oauth2_provider.initialize_controller" do |app|
28
+ ActionController::Base.module_eval do
29
+ include OAuth2::Provider::Rails::ControllerAuthentication
30
+ end
31
+ end
32
+
33
+ initializer "oauth2_provider.initialize_middleware" do |app|
34
+ app.middleware.use ::OAuth2::Provider::Rack::Middleware
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,21 @@
1
+ require 'oauth2/provider'
2
+
3
+ module OAuth2::Provider::Rails::ControllerAuthentication
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+ def authenticate_with_oauth(options = {})
8
+ around_filter AuthenticationFilter.new(options.delete(:scope)), options
9
+ end
10
+
11
+ class AuthenticationFilter
12
+ def initialize(scope = nil)
13
+ @scope = scope
14
+ end
15
+
16
+ def filter(controller, &block)
17
+ controller.request.env['oauth2'].authenticate_request! :scope => @scope, &block
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,30 @@
1
+ require 'oauth2/provider'
2
+
3
+ module OAuth2::Provider::Random
4
+ module Base62
5
+ CHARS = ('0'..'9').to_a + ('a'..'z').to_a + ('A'..'Z').to_a
6
+
7
+ # Adapted from http://refactormycode.com/codes/125-base-62-encoding
8
+ def self.encode(i)
9
+ return '0' if i == 0
10
+ s = ''
11
+ while i > 0
12
+ s << CHARS[i.modulo(62)]
13
+ i /= 62
14
+ end
15
+ s.reverse!
16
+ s
17
+ end
18
+ end
19
+
20
+ def base62(length = 8)
21
+ number = ActiveSupport::SecureRandom.random_number(62 ** length)
22
+ Base62.encode(number).rjust(length, '0')
23
+ end
24
+
25
+ def base36(length = 8)
26
+ ActiveSupport::SecureRandom.random_number(36 ** length).to_s(36).rjust(length, '0')
27
+ end
28
+
29
+ module_function :base62, :base36
30
+ end
@@ -0,0 +1,5 @@
1
+ module OAuth2
2
+ module Provider
3
+ VERSION = "0.0.16"
4
+ end
5
+ end
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "oauth2/provider/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "oauth2-provider"
7
+ s.version = OAuth2::Provider::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Tom Ward"]
10
+ s.email = ["tom@popdog.net"]
11
+ s.homepage = "http://tomafro.net"
12
+ s.summary = %q{OAuth2 Provider, extracted from api.hashblue.com}
13
+ s.description = %q{OAuth2 Provider, extracted from api.hashblue.com}
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+
20
+ # Main dependencies
21
+ s.add_dependency 'activesupport', '~>3.0.1'
22
+ s.add_dependency 'addressable', '~>2.2'
23
+
24
+ # Development only dependencies
25
+ s.add_development_dependency 'rails', '~>3.0.1'
26
+ s.add_development_dependency 'rspec-rails', '~>2.1.0'
27
+ s.add_development_dependency 'rake', '~>0.8.7'
28
+ s.add_development_dependency 'sqlite3-ruby', '~>1.3.1'
29
+ s.add_development_dependency 'timecop', '~>0.3.4'
30
+ s.add_development_dependency 'yajl-ruby', '~>0.7.5'
31
+ s.add_development_dependency 'mongoid', '2.0.0.rc.6'
32
+ s.add_development_dependency 'bson', '1.2.0'
33
+ s.add_development_dependency 'bson_ext', '1.2.0'
34
+ s.add_development_dependency 'sdoc', '~>0.2.20'
35
+ end
@@ -0,0 +1,123 @@
1
+ require 'spec_helper'
2
+
3
+ describe OAuth2::Provider.access_token_class do
4
+ describe "any instance" do
5
+ subject do
6
+ OAuth2::Provider.access_token_class.new :authorization => build_authorization
7
+ end
8
+
9
+ it "is valid with an access grant, expiry time and access token" do
10
+ subject.expires_at.should_not be_nil
11
+ subject.access_token.should_not be_nil
12
+ subject.authorization.should_not be_nil
13
+
14
+ subject.should be_valid
15
+ end
16
+
17
+ it "is invalid without an access token" do
18
+ subject.access_token = nil
19
+ subject.should_not be_valid
20
+ end
21
+
22
+ it "is invalid without an access grant" do
23
+ subject.authorization = nil
24
+ subject.should_not be_valid
25
+ end
26
+
27
+ it "is invalid when expires_at isn't set" do
28
+ subject.expires_at = nil
29
+ subject.should_not be_valid
30
+ end
31
+
32
+ it "is invalid if expires_at is later than the authorization's value" do
33
+ subject.authorization.expires_at = 1.minute.from_now
34
+ subject.expires_at = 10.minutes.from_now
35
+ subject.should_not be_valid
36
+ end
37
+
38
+ it "returns time in seconds until expiry when expires_in called" do
39
+ subject.expires_at = 60.minutes.from_now
40
+ subject.expires_in.should == (60 * 60)
41
+ end
42
+
43
+ it "returns 0 for expired_in when already expired" do
44
+ subject.expires_at = 60.minutes.ago
45
+ subject.expires_in.should == 0
46
+ end
47
+
48
+ it "include expires_in, refresh_token and access token as JSON format" do
49
+ subject.as_json.should == {"expires_in" => subject.expires_in, "access_token" => subject.access_token, "refresh_token" => subject.refresh_token}
50
+ end
51
+
52
+ it "include only expires_in and access token as JSON format if no refresh token set" do
53
+ subject.refresh_token = nil
54
+ subject.as_json.should == {"expires_in" => subject.expires_in, "access_token" => subject.access_token}
55
+ end
56
+
57
+ it "is refreshable, if it has a refresh token" do
58
+ subject.refresh_token = 'abcd1234'
59
+ subject.should be_refreshable
60
+ end
61
+
62
+ it "is not refreshable if it has no refresh token" do
63
+ subject.refresh_token = nil
64
+ subject.should_not be_refreshable
65
+ end
66
+
67
+ it "is not refreshable if it has a refresh token, but its authorization has expired" do
68
+ subject.refresh_token = 'abcd1234'
69
+ subject.authorization.expires_at = 60.minutes.ago
70
+ subject.should_not be_refreshable
71
+ end
72
+ end
73
+
74
+ describe "a new instance" do
75
+ subject do
76
+ OAuth2::Provider.access_token_class.new
77
+ end
78
+
79
+ it "is assigned a randomly generated access token" do
80
+ subject.access_token.should_not be_nil
81
+ OAuth2::Provider.access_token_class.new.access_token.should_not be_nil
82
+ subject.access_token.should_not == OAuth2::Provider.access_token_class.new.access_token
83
+ end
84
+
85
+ it "is assigned a randomly generated refresh token" do
86
+ subject.refresh_token.should_not be_nil
87
+ OAuth2::Provider.access_token_class.new.refresh_token.should_not be_nil
88
+ subject.access_token.should_not == OAuth2::Provider.access_token_class.new.refresh_token
89
+ end
90
+
91
+ it "expires in 1 month by default" do
92
+ subject.expires_at.should == 1.month.from_now
93
+ end
94
+ end
95
+
96
+ describe "refreshing an existing token" do
97
+ subject do
98
+ OAuth2::Provider.access_token_class.create! :authorization => create_authorization, :expires_at => 23.days.ago
99
+ end
100
+
101
+ it "returns a new access token with the same client, resource_owner and scope, but a new expiry time" do
102
+ result = OAuth2::Provider.access_token_class.refresh_with(subject.refresh_token)
103
+ result.should_not be_nil
104
+ result.expires_at.should == 1.month.from_now
105
+ result.authorization.should == subject.authorization
106
+ end
107
+
108
+ it "returns token with expires_at set to authorization.expires_at if validation would fail otherwise" do
109
+ subject.authorization.update_attributes(:expires_at => 5.minutes.from_now)
110
+ result = OAuth2::Provider.access_token_class.refresh_with(subject.refresh_token)
111
+ result.expires_at.should == 5.minutes.from_now
112
+ end
113
+
114
+ it "returns nil if the provided token doesn't match" do
115
+ OAuth2::Provider.access_token_class.refresh_with('wrong').should be_nil
116
+ end
117
+
118
+ it "returns nil if the existing refresh token is nil, whatever value is provided" do
119
+ subject.update_attributes(:refresh_token => nil)
120
+ OAuth2::Provider.access_token_class.refresh_with(nil).should be_nil
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,115 @@
1
+ require 'spec_helper'
2
+
3
+ describe OAuth2::Provider.authorization_code_class do
4
+ describe "any instance" do
5
+ subject do
6
+ OAuth2::Provider.authorization_code_class.new(
7
+ :authorization => create_authorization,
8
+ :redirect_uri => "http://redirect.example.com/callback"
9
+ )
10
+ end
11
+
12
+ it "is valid with an access grant, expiry time, redirect uri and code" do
13
+ subject.should be_valid
14
+ end
15
+
16
+ it "is invalid without a redirect_uri" do
17
+ subject.redirect_uri = nil
18
+ subject.should_not be_valid
19
+ end
20
+
21
+ it "is invalid without a code" do
22
+ subject.code = nil
23
+ subject.should_not be_valid
24
+ end
25
+
26
+ it "is invalid without an access grant" do
27
+ subject.authorization = nil
28
+ subject.should_not be_valid
29
+ end
30
+
31
+ it "is invalid when expires_at isn't set" do
32
+ subject.expires_at = nil
33
+ subject.should_not be_valid
34
+ end
35
+
36
+ it "has expired when expires_at is in the past" do
37
+ subject.expires_at = 1.second.ago
38
+ subject.should be_expired
39
+ end
40
+
41
+ it "has not expired when expires_at is now or in the future" do
42
+ subject.expires_at = Time.now
43
+ subject.should_not be_expired
44
+ end
45
+ end
46
+
47
+ describe "a new instance" do
48
+ subject do
49
+ OAuth2::Provider.authorization_code_class.new
50
+ end
51
+
52
+ it "is assigned a randomly generated code" do
53
+ subject.code.should_not be_nil
54
+ OAuth2::Provider.authorization_code_class.new.code.should_not be_nil
55
+ subject.code.should_not == OAuth2::Provider.authorization_code_class.new.code
56
+ end
57
+
58
+ it "expires in 1 minute by default" do
59
+ subject.expires_at.should == 1.minute.from_now
60
+ end
61
+ end
62
+
63
+ describe "a saved instance" do
64
+ subject do
65
+ OAuth2::Provider.authorization_code_class.create!(
66
+ :authorization => create_authorization,
67
+ :redirect_uri => "https://client.example.com/callback/here"
68
+ )
69
+ end
70
+
71
+ it "can be claimed with the correct code and redirect_uri" do
72
+ OAuth2::Provider.authorization_code_class.claim(subject.code, subject.redirect_uri).should_not be_nil
73
+ end
74
+
75
+ it "returns an access token when claimed" do
76
+ OAuth2::Provider.authorization_code_class.claim(subject.code, subject.redirect_uri).should be_instance_of(OAuth2::Provider.access_token_class)
77
+ end
78
+
79
+ it "can't be claimed twice" do
80
+ OAuth2::Provider.authorization_code_class.claim(subject.code, subject.redirect_uri)
81
+ OAuth2::Provider.authorization_code_class.claim(subject.code, subject.redirect_uri).should be_nil
82
+ end
83
+
84
+ it "can't be claimed without a matching code" do
85
+ OAuth2::Provider.authorization_code_class.claim("incorrectCode", subject.redirect_uri).should be_nil
86
+ end
87
+
88
+ it "can't be claimed without a matching redirect_uri" do
89
+ OAuth2::Provider.authorization_code_class.claim(subject.code, "https://wrong.example.com").should be_nil
90
+ end
91
+
92
+ it "can't be claimed once expired" do
93
+ Timecop.travel subject.expires_at + 1.minute
94
+ OAuth2::Provider.authorization_code_class.claim(subject.code, subject.redirect_uri).should be_nil
95
+ end
96
+ end
97
+
98
+ describe "the access token returned when a code is claimed" do
99
+ subject do
100
+ @code = OAuth2::Provider.authorization_code_class.create!(
101
+ :authorization => create_authorization,
102
+ :redirect_uri => "https://client.example.com/callback/here"
103
+ )
104
+ OAuth2::Provider.authorization_code_class.claim(@code.code, @code.redirect_uri)
105
+ end
106
+
107
+ it "is saved to the database" do
108
+ subject.should_not be_new_record
109
+ end
110
+
111
+ it "has same access grant as claimed code" do
112
+ subject.authorization.should == @code.authorization
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,110 @@
1
+ require 'spec_helper'
2
+
3
+ describe OAuth2::Provider.authorization_class do
4
+ describe "any instance" do
5
+ subject do
6
+ result = OAuth2::Provider.authorization_class.new :client => create_client
7
+ end
8
+
9
+ it "is valid with a client" do
10
+ subject.client.should_not be_nil
11
+ subject.should be_valid
12
+ end
13
+
14
+ it "is invalid without a client" do
15
+ subject.client = nil
16
+ subject.should_not be_valid
17
+ end
18
+
19
+ it "has a given scope, if scope string includes scope" do
20
+ subject.scope = "first second third"
21
+ subject.should have_scope("first")
22
+ subject.should have_scope("second")
23
+ subject.should have_scope("third")
24
+ end
25
+
26
+ it "doesn't have a given scope, if scope string doesn't scope" do
27
+ subject.scope = "first second third"
28
+ subject.should_not have_scope("fourth")
29
+ end
30
+ end
31
+
32
+ describe "a new instance" do
33
+ subject do
34
+ OAuth2::Provider.authorization_class.new
35
+ end
36
+
37
+ it "has no expiry time by default" do
38
+ subject.expires_at.should be_nil
39
+ end
40
+
41
+ it "is never expired" do
42
+ subject.should_not be_expired
43
+ Timecop.travel(100.years.from_now)
44
+ subject.should_not be_expired
45
+ end
46
+ end
47
+
48
+ describe "after being persisted and restored" do
49
+ before :each do
50
+ @client = create_client
51
+ @owner = create_resource_owner
52
+ @original = OAuth2::Provider.authorization_class.create!(:client => @client, :resource_owner => @owner, :expires_at => 1.year.from_now)
53
+ end
54
+
55
+ subject do
56
+ OAuth2::Provider.authorization_class.find(@original.id)
57
+ end
58
+
59
+ it "remembers client" do
60
+ subject.client.should eql(@client)
61
+ end
62
+
63
+ it "remembers resource owner" do
64
+ subject.resource_owner.should eql(@owner)
65
+ end
66
+ end
67
+
68
+ describe "obtain all authorizations for a resource owner" do
69
+ before :each do
70
+ @client = create_client
71
+ @owner = create_resource_owner
72
+ @authorization = OAuth2::Provider.authorization_class.create!(:client => @client, :resource_owner => @owner, :expires_at => 1.year.from_now)
73
+ end
74
+
75
+ subject do
76
+ OAuth2::Provider.authorization_class.all_for(@owner)
77
+ end
78
+
79
+ it "returns correct number of authorizations" do
80
+ subject.count.should eql(1)
81
+ end
82
+
83
+ it "should hold information on the authorized client" do
84
+ subject[0].client.should eql(@client)
85
+ end
86
+ end
87
+
88
+ describe "being revoked" do
89
+ subject do
90
+ OAuth2::Provider.authorization_class.create! :client => create_client
91
+ end
92
+
93
+ it "destroys itself" do
94
+ subject.revoke
95
+ subject.should be_destroyed
96
+ end
97
+
98
+ it "destroys any related authorization codes" do
99
+ subject.authorization_codes.create! :redirect_uri => 'https://example.com'
100
+ subject.revoke
101
+ subject.authorization_codes.should be_empty
102
+ end
103
+
104
+ it "destroys any related access tokens" do
105
+ subject.access_tokens.create!
106
+ subject.revoke
107
+ subject.access_tokens.should be_empty
108
+ end
109
+ end
110
+ end