opro 0.4.2 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,8 @@
1
1
  ## master
2
2
 
3
+ ## 0.4.3
4
+ - [#20] Bugfix: expires_in not correctly recalculated after auth_grant refreshed (@nvh)
5
+
3
6
  ## 0.4.2
4
7
  - Fix jRuby compatibility in `Opro.convert_to_lambda`
5
8
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.2
1
+ 0.4.3
@@ -7,15 +7,10 @@ class Opro::Oauth::TestsController < OproController
7
7
  end
8
8
 
9
9
  def show
10
- result = if valid_oauth?
11
- {:status => 200, :message => 'OAuth worked!', :params => params, :user_id => oauth_user.id }
12
- else
13
- {:status => :unauthorized, :message => "OAuth did not work :( #{generate_oauth_error_message!}", :params => params}
14
- end
15
-
10
+ result = oauth_result(params)
16
11
  respond_to do |format|
17
12
  format.html do
18
- render :text => result.to_json, :status => result[:status], :layout => true
13
+ render :text => result.to_json, :status => result[:status], :layout => true
19
14
  end
20
15
  format.json do
21
16
  render :json => result, :status => result[:status]
@@ -24,15 +19,10 @@ class Opro::Oauth::TestsController < OproController
24
19
  end
25
20
 
26
21
  def create
27
- result = if valid_oauth?
28
- {:status => 200, :message => 'OAuth worked!', :params => params, :user_id => oauth_user.id }
29
- else
30
- {:status => :unauthorized, :message => "OAuth did not work :( #{generate_oauth_error_message!}", :params => params}
31
- end
32
-
22
+ result = oauth_result(params)
33
23
  respond_to do |format|
34
24
  format.html do
35
- render :text => result.to_json, :status => result[:status], :layout => true
25
+ render :text => result.to_json, :status => result[:status], :layout => true
36
26
  end
37
27
  format.json do
38
28
  render :json => result, :status => result[:status]
@@ -56,4 +46,14 @@ class Opro::Oauth::TestsController < OproController
56
46
  end
57
47
  end
58
48
  end
49
+
50
+ private
51
+
52
+ def oauth_result(options)
53
+ if valid_oauth?
54
+ {:status => 200, :message => 'OAuth worked!', :params => options, :user_id => oauth_user.id }
55
+ else
56
+ {:status => :unauthorized, :message => "OAuth did not work :( #{generate_oauth_error_message!}", :params => params}
57
+ end
58
+ end
59
59
  end
@@ -11,33 +11,40 @@ class Opro::Oauth::TokenController < OproController
11
11
  application = Opro::Oauth::ClientApp.authenticate(params[:client_id], params[:client_secret])
12
12
 
13
13
  if application.nil?
14
- render :json => {:error => "Could not find application based on client_id=#{params[:client_id]}
15
- and client_secret=#{params[:client_secret]}"}, :status => :unauthorized
16
- return
14
+ render :json => {:error => app_not_found_error(params)}, :status => :unauthorized and return
17
15
  end
18
16
 
19
17
  if params[:code]
20
18
  auth_grant = Opro::Oauth::AuthGrant.auth_with_code!(params[:code], application.id)
21
19
  elsif params[:refresh_token]
22
- auth_grant = Opro::Oauth::AuthGrant.refresh_tokens!(params[:refresh_token], application.id)
20
+ auth_grant = Opro::Oauth::AuthGrant.find_for_refresh(params[:refresh_token], application.id)
23
21
  elsif params[:password].present? || params[:grant_type] == "password"|| params[:grant_type] == "bearer"
24
22
  user = ::Opro.find_user_for_all_auths!(self, params) if Opro.password_exchange_enabled? && oauth_valid_password_auth?(params[:client_id], params[:client_secret])
25
23
  auth_grant = Opro::Oauth::AuthGrant.auth_with_user!(user, application.id) if user.present?
26
24
  end
27
25
 
28
26
  if auth_grant.blank?
29
- msg = "Could not find a user that belongs to this application"
30
- msg << " & has a refresh_token=#{params[:refresh_token]}" if params[:refresh_token]
31
- msg << " & has been granted a code=#{params[:code]}" if params[:code]
32
- msg << " using username and password" if params[:password]
33
- render :json => {:error => msg }, :status => :unauthorized
34
- return
27
+ render :json => {:error => debug_error_msg(params) }, :status => :unauthorized and return
35
28
  end
36
29
 
37
- auth_grant.generate_expires_at!
30
+ auth_grant.refresh!
38
31
  render :json => { :access_token => auth_grant.access_token,
39
32
  :refresh_token => auth_grant.refresh_token,
40
33
  :expires_in => auth_grant.expires_in }
41
34
  end
42
35
 
36
+ private
37
+
38
+ def debug_error_msg(options)
39
+ msg = "Could not find a user that belongs to this application"
40
+ msg << " & has a refresh_token=#{options[:refresh_token]}" if options[:refresh_token]
41
+ msg << " & has been granted a code=#{options[:code]}" if options[:code]
42
+ msg << " using username and password" if options[:password]
43
+ msg
44
+ end
45
+
46
+ def app_not_found_error(options)
47
+ "Could not find application based on client_id=#{options[:client_id]} and client_secret=#{options[:client_secret]}"
48
+ end
49
+
43
50
  end
@@ -12,7 +12,7 @@ class Opro::Oauth::AuthGrant < ActiveRecord::Base
12
12
  validates :code, :uniqueness => true
13
13
  validates :access_token, :uniqueness => true
14
14
 
15
- before_create :generate_tokens!, :generate_expires_at!
15
+ before_create :refresh
16
16
 
17
17
  alias_attribute :token, :access_token
18
18
 
@@ -60,29 +60,21 @@ class Opro::Oauth::AuthGrant < ActiveRecord::Base
60
60
  auth_grant
61
61
  end
62
62
 
63
- def self.refresh_tokens!(refresh_token, application_id)
64
- auth_grant = self.where("refresh_token = ? AND application_id = ?", refresh_token, application_id).first
65
- if auth_grant.present?
66
- auth_grant.generate_tokens!
67
- auth_grant.generate_expires_at!
68
- auth_grant.save!
69
- end
70
- auth_grant
63
+ def self.find_for_refresh(refresh_token, application_id)
64
+ self.where("refresh_token = ? AND application_id = ?", refresh_token, application_id).first
71
65
  end
72
66
 
73
- def generate_expires_at!
74
- if ::Opro.require_refresh_within.present?
75
- self.access_token_expires_at = Time.now + ::Opro.require_refresh_within
76
- else
77
- self.access_token_expires_at = nil
78
- end
79
- true
67
+ # generates tokens, expires_at and saves
68
+ def refresh!
69
+ refresh
70
+ save!
80
71
  end
81
72
 
82
- def generate_tokens!
83
- self.code = unique_token_for(:code)
84
- self.access_token = unique_token_for(:access_token)
85
- self.refresh_token = unique_token_for(:refresh_token)
73
+ # generates tokens, expires_at
74
+ def refresh
75
+ generate_tokens!
76
+ generate_expires_at!
77
+ self
86
78
  end
87
79
 
88
80
  # used to guarantee that we are generating unique codes, access_tokens and refresh_tokens
@@ -102,4 +94,22 @@ class Opro::Oauth::AuthGrant < ActiveRecord::Base
102
94
  redirect_uri << "&state=#{state}" if state.present?
103
95
  redirect_uri
104
96
  end
97
+
98
+ private
99
+ # use refresh instead
100
+ def generate_expires_at!
101
+ if ::Opro.require_refresh_within.present?
102
+ self.access_token_expires_at = Time.now + ::Opro.require_refresh_within
103
+ else
104
+ self.access_token_expires_at = nil
105
+ end
106
+ true
107
+ end
108
+
109
+ # use refresh instead
110
+ def generate_tokens!
111
+ self.code = unique_token_for(:code)
112
+ self.access_token = unique_token_for(:access_token)
113
+ self.refresh_token = unique_token_for(:refresh_token)
114
+ end
105
115
  end
@@ -6,7 +6,8 @@ module ActionDispatch::Routing
6
6
  skip_routes = options[:except].is_a?(Array) ? options[:except] : [options[:except]]
7
7
  controllers = options[:controllers] || {}
8
8
 
9
- match 'oauth/new' => 'opro/oauth/auth#new', :as => 'oauth_new'
9
+ oauth_new_controller = controllers[:oauth_new] || 'opro/oauth/auth'
10
+ match 'oauth/new' => "#{oauth_new_controller}#new", :as => 'oauth_new'
10
11
  match 'oauth/authorize' => 'opro/oauth/auth#create', :as => 'oauth_authorize'
11
12
  match 'oauth/token' => 'opro/oauth/token#create', :as => 'oauth_token'
12
13
 
@@ -25,4 +26,3 @@ module ActionDispatch::Routing
25
26
  end
26
27
  end
27
28
  end
28
-
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "opro"
8
- s.version = "0.4.2"
8
+ s.version = "0.4.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["schneems"]
12
- s.date = "2012-11-07"
12
+ s.date = "2012-11-17"
13
13
  s.description = " Enable OAuth clients (iphone, android, web sites, etc.) to access and use your Rails application, what you do with it is up to you"
14
14
  s.email = "richard.schneeman@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -124,7 +124,7 @@ Gem::Specification.new do |s|
124
124
  s.homepage = "http://github.com/schneems/opro"
125
125
  s.licenses = ["MIT"]
126
126
  s.require_paths = ["lib"]
127
- s.rubygems_version = "1.8.24"
127
+ s.rubygems_version = "1.8.10"
128
128
  s.summary = "oPRO turns your Rails application into an OAuth Provider"
129
129
 
130
130
  if s.respond_to? :specification_version then
@@ -23,10 +23,10 @@ class OauthTokenTest < ActionDispatch::IntegrationTest
23
23
 
24
24
  json_hash = JSON.parse(response.body)
25
25
  assert json_hash["access_token"]
26
- assert_equal json_hash["access_token"], auth_grant.access_token
26
+ assert_equal json_hash["access_token"], auth_grant.reload.access_token
27
27
 
28
28
  assert json_hash["refresh_token"]
29
- assert_equal json_hash["refresh_token"], auth_grant.refresh_token
29
+ assert_equal json_hash["refresh_token"], auth_grant.reload.refresh_token
30
30
  end
31
31
 
32
32
 
@@ -25,7 +25,8 @@ class RefreshTokenTest < ActionDispatch::IntegrationTest
25
25
  params = {:client_id => @client_app.client_id ,
26
26
  :client_secret => @client_app.client_secret,
27
27
  :code => @auth_grant.code}
28
- as_user(@user).post oauth_token_path(params)
28
+
29
+ post oauth_token_path(params)
29
30
  json_hash = JSON.parse(response.body)
30
31
  assert_equal json_hash['expires_in'], @auth_grant.expires_in
31
32
  end
@@ -37,7 +38,7 @@ class RefreshTokenTest < ActionDispatch::IntegrationTest
37
38
 
38
39
  Timecop.travel(2.days.from_now)
39
40
 
40
- as_user(@user).post oauth_token_path(params)
41
+ post oauth_token_path(params)
41
42
 
42
43
  json_hash = JSON.parse(response.body)
43
44
  refute_equal json_hash['access_token'], @auth_grant.access_token
@@ -51,4 +52,37 @@ class RefreshTokenTest < ActionDispatch::IntegrationTest
51
52
  assert_equal json_hash['expires_in'], auth_grant.expires_in
52
53
  end
53
54
 
55
+ test "after expires in period, access_token is no longer valid" do
56
+ Timecop.freeze(@client_app.created_at)
57
+ params = {:client_id => @client_app.client_id ,
58
+ :client_secret => @client_app.client_secret,
59
+ :code => @auth_grant.code}
60
+
61
+ post oauth_token_path(params)
62
+ json_hash = JSON.parse(response.body)
63
+ expires_in = json_hash['expires_in']
64
+ access_token = json_hash['access_token']
65
+
66
+ # should be valid
67
+ Timecop.travel(expires_in.seconds.from_now - 1.second)
68
+ get oauth_test_path(:show_me_the_money, access_token: access_token)
69
+ assert_equal 200, response.status
70
+
71
+ # should not be valid
72
+ Timecop.travel(expires_in.seconds.from_now + 1.second)
73
+ get oauth_test_path(:show_me_the_money, access_token: access_token)
74
+ refute_equal 200, response.status
75
+
76
+
77
+ params = {:client_id => @client_app.client_id ,
78
+ :client_secret => @client_app.client_secret,
79
+ :refresh_token => @auth_grant.reload.refresh_token}
80
+
81
+ # make it valid again by refreshing the token
82
+ post oauth_token_path(params)
83
+ access_token = JSON.parse(response.body)['access_token']
84
+ get oauth_test_path(:show_me_the_money, access_token: access_token)
85
+ assert_equal 200, response.status
86
+ end
87
+
54
88
  end
metadata CHANGED
@@ -1,240 +1,159 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opro
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.4.2
4
+ version: 0.4.3
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - schneems
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-07 00:00:00.000000000 Z
12
+ date: 2012-11-17 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
16
- version_requirements: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - ! '>='
19
- - !ruby/object:Gem::Version
20
- version: 3.1.0
16
+ requirement: &70297244933200 !ruby/object:Gem::Requirement
21
17
  none: false
22
- requirement: !ruby/object:Gem::Requirement
23
18
  requirements:
24
19
  - - ! '>='
25
20
  - !ruby/object:Gem::Version
26
21
  version: 3.1.0
27
- none: false
28
- prerelease: false
29
22
  type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70297244933200
30
25
  - !ruby/object:Gem::Dependency
31
26
  name: rails
32
- version_requirements: !ruby/object:Gem::Requirement
33
- requirements:
34
- - - ! '>='
35
- - !ruby/object:Gem::Version
36
- version: 3.1.0
27
+ requirement: &70297244932520 !ruby/object:Gem::Requirement
37
28
  none: false
38
- requirement: !ruby/object:Gem::Requirement
39
29
  requirements:
40
30
  - - ! '>='
41
31
  - !ruby/object:Gem::Version
42
32
  version: 3.1.0
43
- none: false
44
- prerelease: false
45
33
  type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70297244932520
46
36
  - !ruby/object:Gem::Dependency
47
37
  name: kramdown
48
- version_requirements: !ruby/object:Gem::Requirement
49
- requirements:
50
- - - ! '>='
51
- - !ruby/object:Gem::Version
52
- version: !binary |-
53
- MA==
38
+ requirement: &70297244931780 !ruby/object:Gem::Requirement
54
39
  none: false
55
- requirement: !ruby/object:Gem::Requirement
56
40
  requirements:
57
41
  - - ! '>='
58
42
  - !ruby/object:Gem::Version
59
- version: !binary |-
60
- MA==
61
- none: false
62
- prerelease: false
43
+ version: '0'
63
44
  type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70297244931780
64
47
  - !ruby/object:Gem::Dependency
65
48
  name: mocha
66
- version_requirements: !ruby/object:Gem::Requirement
67
- requirements:
68
- - - ! '>='
69
- - !ruby/object:Gem::Version
70
- version: !binary |-
71
- MA==
49
+ requirement: &70297244931120 !ruby/object:Gem::Requirement
72
50
  none: false
73
- requirement: !ruby/object:Gem::Requirement
74
51
  requirements:
75
52
  - - ! '>='
76
53
  - !ruby/object:Gem::Version
77
- version: !binary |-
78
- MA==
79
- none: false
80
- prerelease: false
54
+ version: '0'
81
55
  type: :development
56
+ prerelease: false
57
+ version_requirements: *70297244931120
82
58
  - !ruby/object:Gem::Dependency
83
59
  name: timecop
84
- version_requirements: !ruby/object:Gem::Requirement
85
- requirements:
86
- - - ! '>='
87
- - !ruby/object:Gem::Version
88
- version: !binary |-
89
- MA==
60
+ requirement: &70297244930600 !ruby/object:Gem::Requirement
90
61
  none: false
91
- requirement: !ruby/object:Gem::Requirement
92
62
  requirements:
93
63
  - - ! '>='
94
64
  - !ruby/object:Gem::Version
95
- version: !binary |-
96
- MA==
97
- none: false
98
- prerelease: false
65
+ version: '0'
99
66
  type: :development
67
+ prerelease: false
68
+ version_requirements: *70297244930600
100
69
  - !ruby/object:Gem::Dependency
101
70
  name: jeweler
102
- version_requirements: !ruby/object:Gem::Requirement
103
- requirements:
104
- - - ~>
105
- - !ruby/object:Gem::Version
106
- version: 1.6.4
71
+ requirement: &70297244930000 !ruby/object:Gem::Requirement
107
72
  none: false
108
- requirement: !ruby/object:Gem::Requirement
109
73
  requirements:
110
74
  - - ~>
111
75
  - !ruby/object:Gem::Version
112
76
  version: 1.6.4
113
- none: false
114
- prerelease: false
115
77
  type: :development
78
+ prerelease: false
79
+ version_requirements: *70297244930000
116
80
  - !ruby/object:Gem::Dependency
117
81
  name: bundler
118
- version_requirements: !ruby/object:Gem::Requirement
119
- requirements:
120
- - - ! '>='
121
- - !ruby/object:Gem::Version
122
- version: 1.1.3
82
+ requirement: &70297244929400 !ruby/object:Gem::Requirement
123
83
  none: false
124
- requirement: !ruby/object:Gem::Requirement
125
84
  requirements:
126
85
  - - ! '>='
127
86
  - !ruby/object:Gem::Version
128
87
  version: 1.1.3
129
- none: false
130
- prerelease: false
131
88
  type: :development
89
+ prerelease: false
90
+ version_requirements: *70297244929400
132
91
  - !ruby/object:Gem::Dependency
133
92
  name: capybara
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ! '>='
137
- - !ruby/object:Gem::Version
138
- version: 0.4.0
93
+ requirement: &70297244928580 !ruby/object:Gem::Requirement
139
94
  none: false
140
- requirement: !ruby/object:Gem::Requirement
141
95
  requirements:
142
96
  - - ! '>='
143
97
  - !ruby/object:Gem::Version
144
98
  version: 0.4.0
145
- none: false
146
- prerelease: false
147
99
  type: :development
100
+ prerelease: false
101
+ version_requirements: *70297244928580
148
102
  - !ruby/object:Gem::Dependency
149
103
  name: launchy
150
- version_requirements: !ruby/object:Gem::Requirement
151
- requirements:
152
- - - ! '>='
153
- - !ruby/object:Gem::Version
154
- version: !binary |-
155
- MA==
104
+ requirement: &70297244927960 !ruby/object:Gem::Requirement
156
105
  none: false
157
- requirement: !ruby/object:Gem::Requirement
158
106
  requirements:
159
107
  - - ! '>='
160
108
  - !ruby/object:Gem::Version
161
- version: !binary |-
162
- MA==
163
- none: false
164
- prerelease: false
109
+ version: '0'
165
110
  type: :development
111
+ prerelease: false
112
+ version_requirements: *70297244927960
166
113
  - !ruby/object:Gem::Dependency
167
114
  name: sqlite3
168
- version_requirements: !ruby/object:Gem::Requirement
169
- requirements:
170
- - - ! '>='
171
- - !ruby/object:Gem::Version
172
- version: !binary |-
173
- MA==
115
+ requirement: &70297244927220 !ruby/object:Gem::Requirement
174
116
  none: false
175
- requirement: !ruby/object:Gem::Requirement
176
117
  requirements:
177
118
  - - ! '>='
178
119
  - !ruby/object:Gem::Version
179
- version: !binary |-
180
- MA==
181
- none: false
182
- prerelease: false
120
+ version: '0'
183
121
  type: :development
122
+ prerelease: false
123
+ version_requirements: *70297244927220
184
124
  - !ruby/object:Gem::Dependency
185
125
  name: activerecord-jdbcsqlite3-adapter
186
- version_requirements: !ruby/object:Gem::Requirement
187
- requirements:
188
- - - ! '>='
189
- - !ruby/object:Gem::Version
190
- version: !binary |-
191
- MA==
126
+ requirement: &70297244926520 !ruby/object:Gem::Requirement
192
127
  none: false
193
- requirement: !ruby/object:Gem::Requirement
194
128
  requirements:
195
129
  - - ! '>='
196
130
  - !ruby/object:Gem::Version
197
- version: !binary |-
198
- MA==
199
- none: false
200
- prerelease: false
131
+ version: '0'
201
132
  type: :development
133
+ prerelease: false
134
+ version_requirements: *70297244926520
202
135
  - !ruby/object:Gem::Dependency
203
136
  name: jdbc-sqlite3
204
- version_requirements: !ruby/object:Gem::Requirement
205
- requirements:
206
- - - ! '>='
207
- - !ruby/object:Gem::Version
208
- version: !binary |-
209
- MA==
137
+ requirement: &70297244925900 !ruby/object:Gem::Requirement
210
138
  none: false
211
- requirement: !ruby/object:Gem::Requirement
212
139
  requirements:
213
140
  - - ! '>='
214
141
  - !ruby/object:Gem::Version
215
- version: !binary |-
216
- MA==
217
- none: false
218
- prerelease: false
142
+ version: '0'
219
143
  type: :development
144
+ prerelease: false
145
+ version_requirements: *70297244925900
220
146
  - !ruby/object:Gem::Dependency
221
147
  name: devise
222
- version_requirements: !ruby/object:Gem::Requirement
223
- requirements:
224
- - - ! '>='
225
- - !ruby/object:Gem::Version
226
- version: !binary |-
227
- MA==
148
+ requirement: &70297244925300 !ruby/object:Gem::Requirement
228
149
  none: false
229
- requirement: !ruby/object:Gem::Requirement
230
150
  requirements:
231
151
  - - ! '>='
232
152
  - !ruby/object:Gem::Version
233
- version: !binary |-
234
- MA==
235
- none: false
236
- prerelease: false
153
+ version: '0'
237
154
  type: :development
155
+ prerelease: false
156
+ version_requirements: *70297244925300
238
157
  description: ! ' Enable OAuth clients (iphone, android, web sites, etc.) to access
239
158
  and use your Rails application, what you do with it is up to you'
240
159
  email: richard.schneeman@gmail.com
@@ -350,32 +269,29 @@ files:
350
269
  homepage: http://github.com/schneems/opro
351
270
  licenses:
352
271
  - MIT
353
- post_install_message:
272
+ post_install_message:
354
273
  rdoc_options: []
355
274
  require_paths:
356
275
  - lib
357
276
  required_ruby_version: !ruby/object:Gem::Requirement
277
+ none: false
358
278
  requirements:
359
279
  - - ! '>='
360
280
  - !ruby/object:Gem::Version
281
+ version: '0'
361
282
  segments:
362
283
  - 0
363
- hash: 2
364
- version: !binary |-
365
- MA==
366
- none: false
284
+ hash: -2443235425097345828
367
285
  required_rubygems_version: !ruby/object:Gem::Requirement
286
+ none: false
368
287
  requirements:
369
288
  - - ! '>='
370
289
  - !ruby/object:Gem::Version
371
- version: !binary |-
372
- MA==
373
- none: false
290
+ version: '0'
374
291
  requirements: []
375
- rubyforge_project:
376
- rubygems_version: 1.8.24
377
- signing_key:
292
+ rubyforge_project:
293
+ rubygems_version: 1.8.10
294
+ signing_key:
378
295
  specification_version: 3
379
296
  summary: oPRO turns your Rails application into an OAuth Provider
380
297
  test_files: []
381
- ...