brycesch-devise_oauth2_providable 1.1.7

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 (91) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +35 -0
  3. data/.ruby_gemset +1 -0
  4. data/.ruby_version +1 -0
  5. data/CONTRIBUTORS.txt +6 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +160 -0
  9. data/Rakefile +8 -0
  10. data/app/controllers/devise/oauth2_providable/authorizations_controller.rb +59 -0
  11. data/app/controllers/devise/oauth2_providable/tokens_controller.rb +35 -0
  12. data/app/models/devise/oauth2_providable/access_token.rb +25 -0
  13. data/app/models/devise/oauth2_providable/authorization_code.rb +3 -0
  14. data/app/models/devise/oauth2_providable/client.rb +26 -0
  15. data/app/models/devise/oauth2_providable/refresh_token.rb +6 -0
  16. data/app/views/devise/oauth2_providable/authorizations/_form.html.erb +7 -0
  17. data/app/views/devise/oauth2_providable/authorizations/error.html.erb +4 -0
  18. data/app/views/devise/oauth2_providable/authorizations/new.html.erb +4 -0
  19. data/config/routes.rb +6 -0
  20. data/db/migrate/20111014160714_create_devise_oauth2_providable_schema.rb +58 -0
  21. data/devise_oauth2_providable.gemspec +33 -0
  22. data/lib/devise/oauth2_providable/engine.rb +16 -0
  23. data/lib/devise/oauth2_providable/expirable_token.rb +56 -0
  24. data/lib/devise/oauth2_providable/models/oauth2_authorization_code_grantable.rb +6 -0
  25. data/lib/devise/oauth2_providable/models/oauth2_password_grantable.rb +6 -0
  26. data/lib/devise/oauth2_providable/models/oauth2_providable.rb +13 -0
  27. data/lib/devise/oauth2_providable/models/oauth2_refresh_token_grantable.rb +6 -0
  28. data/lib/devise/oauth2_providable/strategies/oauth2_authorization_code_grant_type_strategy.rb +21 -0
  29. data/lib/devise/oauth2_providable/strategies/oauth2_grant_type_strategy.rb +44 -0
  30. data/lib/devise/oauth2_providable/strategies/oauth2_password_grant_type_strategy.rb +22 -0
  31. data/lib/devise/oauth2_providable/strategies/oauth2_providable_strategy.rb +31 -0
  32. data/lib/devise/oauth2_providable/strategies/oauth2_refresh_token_grant_type_strategy.rb +22 -0
  33. data/lib/devise/oauth2_providable/version.rb +5 -0
  34. data/lib/devise_oauth2_providable.rb +41 -0
  35. data/script/rails +6 -0
  36. data/spec/controllers/authorizations_controller_spec.rb +32 -0
  37. data/spec/controllers/protected_controller_spec.rb +43 -0
  38. data/spec/controllers/tokens_controller_spec.rb +50 -0
  39. data/spec/dummy/Rakefile +7 -0
  40. data/spec/dummy/app/assets/javascripts/application.js +7 -0
  41. data/spec/dummy/app/assets/stylesheets/application.css +7 -0
  42. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  43. data/spec/dummy/app/controllers/protected_controller.rb +7 -0
  44. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  45. data/spec/dummy/app/mailers/.gitkeep +0 -0
  46. data/spec/dummy/app/models/.gitkeep +0 -0
  47. data/spec/dummy/app/models/user.rb +3 -0
  48. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  49. data/spec/dummy/config.ru +4 -0
  50. data/spec/dummy/config/application.rb +51 -0
  51. data/spec/dummy/config/boot.rb +10 -0
  52. data/spec/dummy/config/database.yml +25 -0
  53. data/spec/dummy/config/environment.rb +5 -0
  54. data/spec/dummy/config/environments/development.rb +32 -0
  55. data/spec/dummy/config/environments/production.rb +62 -0
  56. data/spec/dummy/config/environments/test.rb +42 -0
  57. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  58. data/spec/dummy/config/initializers/devise.rb +259 -0
  59. data/spec/dummy/config/initializers/inflections.rb +10 -0
  60. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  61. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  62. data/spec/dummy/config/initializers/session_store.rb +8 -0
  63. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  64. data/spec/dummy/config/locales/devise.en.yml +58 -0
  65. data/spec/dummy/config/locales/en.yml +5 -0
  66. data/spec/dummy/config/routes.rb +7 -0
  67. data/spec/dummy/db/migrate/20111014142838_create_users.rb +9 -0
  68. data/spec/dummy/db/migrate/20111014161437_create_devise_oauth2_providable_schema.rb +55 -0
  69. data/spec/dummy/db/schema.rb +78 -0
  70. data/spec/dummy/lib/assets/.gitkeep +0 -0
  71. data/spec/dummy/public/404.html +26 -0
  72. data/spec/dummy/public/422.html +26 -0
  73. data/spec/dummy/public/500.html +26 -0
  74. data/spec/dummy/public/favicon.ico +0 -0
  75. data/spec/dummy/script/rails +6 -0
  76. data/spec/factories/client_factory.rb +7 -0
  77. data/spec/factories/user_factory.rb +6 -0
  78. data/spec/integration/oauth2_authorization_token_grant_type_strategy_spec.rb +137 -0
  79. data/spec/integration/oauth2_password_grant_type_strategy_spec.rb +174 -0
  80. data/spec/integration/oauth2_refresh_token_grant_type_strategy_spec.rb +138 -0
  81. data/spec/lib/devise_oauth2_providable_spec.rb +7 -0
  82. data/spec/models/access_token_spec.rb +50 -0
  83. data/spec/models/authorization_code_spec.rb +21 -0
  84. data/spec/models/client_spec.rb +17 -0
  85. data/spec/models/refresh_token_spec.rb +23 -0
  86. data/spec/models/user_spec.rb +6 -0
  87. data/spec/routing/authorizations_routing_spec.rb +16 -0
  88. data/spec/routing/tokens_routing_spec.rb +9 -0
  89. data/spec/spec_helper.rb +33 -0
  90. data/spec/support/match_json.rb +6 -0
  91. metadata +330 -0
@@ -0,0 +1,174 @@
1
+ require 'spec_helper'
2
+
3
+ describe Devise::Strategies::Oauth2PasswordGrantTypeStrategy do
4
+ describe 'POST /oauth2/token' do
5
+ describe 'with grant_type=password' do
6
+ context 'with valid params' do
7
+ let(:client) { FactoryGirl.create :client }
8
+ before do
9
+ @user = User.create! :email => 'ryan@socialcast.com', :password => 'test'
10
+
11
+ params = {
12
+ :grant_type => 'password',
13
+ :client_id => client.identifier,
14
+ :client_secret => client.secret,
15
+ :username => @user.email,
16
+ :password => 'test'
17
+ }
18
+
19
+ post '/oauth2/token', params
20
+ end
21
+ it { response.code.to_i.should == 200 }
22
+ it { response.content_type.should == 'application/json' }
23
+ it 'returns json' do
24
+ token = Devise::Oauth2Providable::AccessToken.last
25
+ expected = token.token_response
26
+ response.body.should match_json(expected)
27
+ end
28
+ end
29
+ context 'with valid params and client id/secret in basic auth header' do
30
+ let(:client) { FactoryGirl.create :client }
31
+ before do
32
+ @user = User.create! :email => 'ryan@socialcast.com', :password => 'test'
33
+
34
+ params = {
35
+ :grant_type => 'password',
36
+ :username => @user.email,
37
+ :password => 'test'
38
+ }
39
+
40
+ auth_header = ActionController::HttpAuthentication::Basic.encode_credentials client.identifier, client.secret
41
+ post '/oauth2/token', params, 'HTTP_AUTHORIZATION' => auth_header
42
+ end
43
+ it { response.code.to_i.should == 200 }
44
+ it { response.content_type.should == 'application/json' }
45
+ it 'returns json' do
46
+ # puts response.body
47
+ token = Devise::Oauth2Providable::AccessToken.last
48
+ expected = token.token_response
49
+ response.body.should match_json(expected)
50
+ end
51
+ end
52
+ context 'with invalid client id in basic auth header' do
53
+ let(:client) { FactoryGirl.create :client }
54
+ before do
55
+ @user = User.create! :email => 'ryan@socialcast.com', :password => 'test'
56
+ params = {
57
+ :grant_type => 'password',
58
+ :username => @user.email,
59
+ :password => 'test'
60
+ }
61
+ auth_header = ActionController::HttpAuthentication::Basic.encode_credentials 'invalid client id', client.secret
62
+ post '/oauth2/token', params, 'HTTP_AUTHORIZATION' => auth_header
63
+ end
64
+ it { response.code.to_i.should == 400 }
65
+ it { response.content_type.should == 'application/json' }
66
+ it 'returns json' do
67
+ expected = {
68
+ :error_description => "invalid client credentials",
69
+ :error => "invalid_client"
70
+ }
71
+ response.body.should match_json(expected)
72
+ end
73
+ end
74
+ context 'with invalid client secret in basic auth header' do
75
+ let(:client) { FactoryGirl.create :client }
76
+ before do
77
+ @user = User.create! :email => 'ryan@socialcast.com', :password => 'test'
78
+ params = {
79
+ :grant_type => 'password',
80
+ :username => @user.email,
81
+ :password => 'test'
82
+ }
83
+ auth_header = ActionController::HttpAuthentication::Basic.encode_credentials client.identifier, 'invalid secret'
84
+ post '/oauth2/token', params, 'HTTP_AUTHORIZATION' => auth_header
85
+ end
86
+ it { response.code.to_i.should == 400 }
87
+ it { response.content_type.should == 'application/json' }
88
+ it 'returns json' do
89
+ expected = {
90
+ :error_description => "invalid client credentials",
91
+ :error => "invalid_client"
92
+ }
93
+ response.body.should match_json(expected)
94
+ end
95
+ end
96
+ context 'with invalid password' do
97
+ let(:client) { FactoryGirl.create :client }
98
+ before do
99
+ @user = User.create! :email => 'ryan@socialcast.com', :password => 'test'
100
+
101
+ params = {
102
+ :grant_type => 'password',
103
+ :client_id => client.identifier,
104
+ :client_secret => client.secret,
105
+ :username => @user.email,
106
+ :password => 'bar'
107
+ }
108
+
109
+ post '/oauth2/token', params
110
+ end
111
+ it { response.code.to_i.should == 400 }
112
+ it { response.content_type.should == 'application/json' }
113
+ it 'returns json' do
114
+ expected = {
115
+ :error_description => "invalid password authentication request",
116
+ :error => "invalid_grant"
117
+ }
118
+ response.body.should match_json(expected)
119
+ end
120
+ end
121
+ context 'with invalid client_id' do
122
+ let(:client) { FactoryGirl.create :client }
123
+ before do
124
+ @user = User.create! :email => 'ryan@socialcast.com', :password => 'test'
125
+
126
+ params = {
127
+ :grant_type => 'password',
128
+ :client_id => 'invalid',
129
+ :client_secret => client.secret,
130
+ :username => @user.email,
131
+ :password => 'test'
132
+ }
133
+
134
+ post '/oauth2/token', params
135
+ end
136
+ it { response.code.to_i.should == 400 }
137
+ it { response.content_type.should == 'application/json' }
138
+ it 'returns json' do
139
+ expected = {
140
+ :error_description => "invalid client credentials",
141
+ :error => "invalid_client"
142
+ }
143
+ response.body.should match_json(expected)
144
+ end
145
+ end
146
+ context 'with invalid client_secret' do
147
+ let(:client) { FactoryGirl.create :client }
148
+ before do
149
+ @user = User.create! :email => 'ryan@socialcast.com', :password => 'test'
150
+
151
+ params = {
152
+ :grant_type => 'password',
153
+ :client_id => client.identifier,
154
+ :client_secret => 'invalid',
155
+ :username => @user.email,
156
+ :password => 'test'
157
+ }
158
+
159
+ post '/oauth2/token', params
160
+ end
161
+ it { response.code.to_i.should == 400 }
162
+ it { response.content_type.should == 'application/json' }
163
+ it 'returns json' do
164
+ expected = {
165
+ :error_description => "invalid client credentials",
166
+ :error => "invalid_client"
167
+ }
168
+ response.body.should match_json(expected)
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end
174
+
@@ -0,0 +1,138 @@
1
+ require 'spec_helper'
2
+
3
+ describe Devise::Strategies::Oauth2RefreshTokenGrantTypeStrategy do
4
+ describe 'POST /oauth2/token' do
5
+ describe 'with grant_type=refresh_token' do
6
+ context 'with valid params' do
7
+ let(:user) { FactoryGirl.create :user }
8
+ let(:client) { FactoryGirl.create :client }
9
+ before do
10
+ @refresh_token = client.refresh_tokens.create! :user => user
11
+ params = {
12
+ :grant_type => 'refresh_token',
13
+ :client_id => client.identifier,
14
+ :client_secret => client.secret,
15
+ :refresh_token => @refresh_token.token
16
+ }
17
+
18
+ post '/oauth2/token', params
19
+ end
20
+ it { response.code.to_i.should == 200 }
21
+ it { response.content_type.should == 'application/json' }
22
+ it 'returns json' do
23
+ token = Devise::Oauth2Providable::AccessToken.last
24
+ refresh_token = @refresh_token
25
+ expected = {
26
+ :token_type => 'bearer',
27
+ :expires_in => 899,
28
+ :refresh_token => refresh_token.token,
29
+ :access_token => token.token
30
+ }
31
+ response.body.should match_json(expected)
32
+ end
33
+ end
34
+ context 'with expired refresh_token' do
35
+ let(:user) { FactoryGirl.create :user }
36
+ let(:client) { FactoryGirl.create :client }
37
+ before do
38
+ timenow = 2.days.from_now
39
+ allow(Time).to receive(:now).and_return(timenow)
40
+ @refresh_token = client.refresh_tokens.create! :user => user
41
+ params = {
42
+ :grant_type => 'refresh_token',
43
+ :client_id => client.identifier,
44
+ :client_secret => client.secret,
45
+ :refresh_token => @refresh_token.token
46
+ }
47
+ allow(Time).to receive(:now).and_return(timenow + 2.months)
48
+
49
+ post '/oauth2/token', params
50
+ end
51
+ it { response.code.to_i.should == 400 }
52
+ it { response.content_type.should == 'application/json' }
53
+ it 'returns json' do
54
+ expected = {
55
+ :error => 'invalid_grant',
56
+ :error_description => 'invalid refresh token'
57
+ }
58
+ response.body.should match_json(expected)
59
+ end
60
+ end
61
+ context 'with invalid refresh_token' do
62
+ let(:user) { FactoryGirl.create :user }
63
+ let(:client) { FactoryGirl.create :client }
64
+ before do
65
+ @refresh_token = client.refresh_tokens.create! :user => user
66
+ params = {
67
+ :grant_type => 'refresh_token',
68
+ :client_id => client.identifier,
69
+ :client_secret => client.secret,
70
+ :refresh_token => 'invalid'
71
+ }
72
+
73
+ post '/oauth2/token', params
74
+ end
75
+ it { response.code.to_i.should == 400 }
76
+ it { response.content_type.should == 'application/json' }
77
+ it 'returns json' do
78
+ token = Devise::Oauth2Providable::AccessToken.last
79
+ refresh_token = @refresh_token
80
+ expected = {
81
+ :error => 'invalid_grant',
82
+ :error_description => 'invalid refresh token'
83
+ }
84
+ response.body.should match_json(expected)
85
+ end
86
+ end
87
+ context 'with invalid client_id' do
88
+ let(:user) { FactoryGirl.create :user }
89
+ let(:client) { FactoryGirl.create :client }
90
+ before do
91
+ @refresh_token = client.refresh_tokens.create! :user => user
92
+ params = {
93
+ :grant_type => 'refresh_token',
94
+ :client_id => 'invalid',
95
+ :client_secret => client.secret,
96
+ :refresh_token => @refresh_token.token
97
+ }
98
+
99
+ post '/oauth2/token', params
100
+ end
101
+ it { response.code.to_i.should == 400 }
102
+ it { response.content_type.should == 'application/json' }
103
+ it 'returns json' do
104
+ expected = {
105
+ :error => 'invalid_client',
106
+ :error_description => 'invalid client credentials'
107
+ }
108
+ response.body.should match_json(expected)
109
+ end
110
+ end
111
+ context 'with invalid client_secret' do
112
+ let(:user) { FactoryGirl.create :user }
113
+ let(:client) { FactoryGirl.create :client }
114
+ before do
115
+ @refresh_token = client.refresh_tokens.create! :user => user
116
+ params = {
117
+ :grant_type => 'refresh_token',
118
+ :client_id => client.identifier,
119
+ :client_secret => 'invalid',
120
+ :refresh_token => @refresh_token.token
121
+ }
122
+
123
+ post '/oauth2/token', params
124
+ end
125
+ it { response.code.to_i.should == 400 }
126
+ it { response.content_type.should == 'application/json' }
127
+ it 'returns json' do
128
+ expected = {
129
+ :error => 'invalid_client',
130
+ :error_description => 'invalid client credentials'
131
+ }
132
+ response.body.should match_json(expected)
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
138
+
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe Devise::Oauth2Providable do
4
+ it 'should be defined' do
5
+ # success
6
+ end
7
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ describe Devise::Oauth2Providable::AccessToken do
4
+ it { Devise::Oauth2Providable::AccessToken.table_name.should == 'oauth2_access_tokens' }
5
+
6
+ describe 'basic access token instance' do
7
+ let(:client) { FactoryGirl.create :client }
8
+ subject do
9
+ Devise::Oauth2Providable::AccessToken.create! :client => client
10
+ end
11
+ it { should validate_presence_of :token }
12
+ it { should validate_uniqueness_of :token }
13
+ it { should belong_to :user }
14
+ it { should belong_to :client }
15
+ it { should validate_presence_of :client }
16
+ it { should validate_presence_of :expires_at }
17
+ it { should belong_to :refresh_token }
18
+ it { should have_db_index :client_id }
19
+ it { should have_db_index :user_id }
20
+ it { should have_db_index(:token).unique(true) }
21
+ it { should have_db_index :expires_at }
22
+ end
23
+
24
+ describe '#expires_at' do
25
+ context 'when refresh token does not expire before access token' do
26
+ let(:client) { FactoryGirl.create :client }
27
+ before do
28
+ @later = 1.year.from_now
29
+ @refresh_token = client.refresh_tokens.create!
30
+ @refresh_token.expires_at = @soon
31
+ @access_token = Devise::Oauth2Providable::AccessToken.create! :client => client, :refresh_token => @refresh_token
32
+ end
33
+ focus 'should not set the access token expires_at to equal refresh token' do
34
+ @access_token.expires_at.should_not == @later
35
+ end
36
+ end
37
+ context 'when refresh token expires before access token' do
38
+ let(:client) { FactoryGirl.create :client }
39
+ before do
40
+ @soon = 1.minute.from_now
41
+ @refresh_token = client.refresh_tokens.create!
42
+ @refresh_token.expires_at = @soon
43
+ @access_token = Devise::Oauth2Providable::AccessToken.create! :client => client, :refresh_token => @refresh_token
44
+ end
45
+ it 'should set the access token expires_at to equal refresh token' do
46
+ @access_token.expires_at.should == @soon
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe Devise::Oauth2Providable::AuthorizationCode do
4
+ describe 'basic authorization code instance' do
5
+ let(:client) { FactoryGirl.create :client }
6
+ subject do
7
+ Devise::Oauth2Providable::AuthorizationCode.create! :client => client
8
+ end
9
+ it { should validate_presence_of :token }
10
+ it { should validate_uniqueness_of :token }
11
+ it { should belong_to :user }
12
+ it { should belong_to :client }
13
+ it { should validate_presence_of :client }
14
+ it { should validate_presence_of :expires_at }
15
+ it { should have_db_index :client_id }
16
+ it { should have_db_index :user_id }
17
+ it { should have_db_index(:token).unique(true) }
18
+ it { should have_db_index :expires_at }
19
+ end
20
+ end
21
+
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe Devise::Oauth2Providable::Client do
4
+ it { Devise::Oauth2Providable::Client.table_name.should == 'oauth2_clients' }
5
+
6
+ describe 'basic client instance' do
7
+ let(:client) { FactoryGirl.create :client }
8
+ subject { client }
9
+ it { should validate_presence_of :name }
10
+ it { should validate_uniqueness_of :name }
11
+ it { should validate_presence_of :website }
12
+ it { should validate_uniqueness_of :identifier }
13
+ it { should have_db_index(:identifier).unique(true) }
14
+ it { should have_many :refresh_tokens }
15
+ it { should have_many :authorization_codes }
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe Devise::Oauth2Providable::RefreshToken do
4
+ it { Devise::Oauth2Providable::RefreshToken.table_name.should == 'oauth2_refresh_tokens' }
5
+
6
+ describe 'basic refresh token instance' do
7
+ let(:client) { FactoryGirl.create :client }
8
+ subject do
9
+ Devise::Oauth2Providable::RefreshToken.create! :client => client
10
+ end
11
+ it { should validate_presence_of :token }
12
+ it { should validate_uniqueness_of :token }
13
+ it { should belong_to :user }
14
+ it { should belong_to :client }
15
+ it { should validate_presence_of :client }
16
+ it { should validate_presence_of :expires_at }
17
+ it { should have_many :access_tokens }
18
+ it { should have_db_index :client_id }
19
+ it { should have_db_index :user_id }
20
+ it { should have_db_index(:token).unique(true) }
21
+ it { should have_db_index :expires_at }
22
+ end
23
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ describe User do
4
+ it { should have_many :access_tokens }
5
+ it { should have_many :authorization_codes }
6
+ end