devise_oauth2_providable 1.0.1 → 1.0.2

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.
@@ -1,10 +1,7 @@
1
- require 'expirable_token'
2
-
3
1
  class Devise::Oauth2Providable::AccessToken < ActiveRecord::Base
4
- include ExpirableToken
5
- self.default_lifetime = 15.minutes
2
+ expires_according_to :access_token_expires_in
6
3
 
7
- before_validation :restrict_expires_at, :if => :refresh_token
4
+ before_validation :restrict_expires_at, :on => :create, :if => :refresh_token
8
5
  belongs_to :refresh_token
9
6
 
10
7
  def token_response
@@ -20,6 +17,6 @@ class Devise::Oauth2Providable::AccessToken < ActiveRecord::Base
20
17
  private
21
18
 
22
19
  def restrict_expires_at
23
- self.expires_at = [self.expires_at, refresh_token.expires_at].min
20
+ self.expires_at = [self.expires_at, refresh_token.expires_at].compact.min
24
21
  end
25
22
  end
@@ -1,7 +1,6 @@
1
- require 'expirable_token'
2
-
3
1
  class Devise::Oauth2Providable::AuthorizationCode < ActiveRecord::Base
4
- include ExpirableToken
2
+ expires_according_to :authorization_code_expires_in
3
+
5
4
  def access_token
6
5
  @access_token ||= expired! && user.access_tokens.create(:client => client)
7
6
  end
@@ -1,7 +1,5 @@
1
- require 'expirable_token'
2
-
3
1
  class Devise::Oauth2Providable::RefreshToken < ActiveRecord::Base
4
- include ExpirableToken
5
- self.default_lifetime = 1.month
2
+ expires_according_to :refresh_token_expires_in
3
+
6
4
  has_many :access_tokens
7
5
  end
@@ -21,6 +21,8 @@ Gem::Specification.new do |s|
21
21
  s.add_development_dependency(%q<sqlite3>, ['1.3.4'])
22
22
  s.add_development_dependency(%q<shoulda-matchers>, ['1.0.0.beta3'])
23
23
  s.add_development_dependency(%q<pry>, ['0.9.6.2'])
24
+ s.add_development_dependency(%q<factory_girl>, ['2.2.0'])
25
+ s.add_development_dependency(%q<factory_girl_rspec>, ['0.0.1'])
24
26
 
25
27
  s.files = `git ls-files`.split("\n")
26
28
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -1,9 +1,14 @@
1
1
  module Devise
2
2
  module Oauth2Providable
3
3
  class Engine < Rails::Engine
4
+ config.devise_oauth2_providable = ActiveSupport::OrderedOptions.new
5
+ config.devise_oauth2_providable.access_token_expires_in = 15.minutes
6
+ config.devise_oauth2_providable.refresh_token_expires_in = 1.month
7
+ config.devise_oauth2_providable.authorization_code_expires_in = 1.minute
8
+
4
9
  engine_name 'oauth2'
5
10
  isolate_namespace Devise::Oauth2Providable
6
- initializer "devise_oauth2_providable.initialize_application" do |app|
11
+ initializer "devise_oauth2_providable.initialize_application", :before=> :load_config_initializers do |app|
7
12
  app.config.filter_parameters << :client_secret
8
13
  end
9
14
  end
@@ -0,0 +1,57 @@
1
+ require 'active_support/concern'
2
+ require 'active_record'
3
+
4
+ module Devise
5
+ module Oauth2Providable
6
+ module ExpirableToken
7
+ extend ActiveSupport::Concern
8
+
9
+ module ClassMethods
10
+ def expires_according_to(config_name)
11
+ cattr_accessor :default_lifetime
12
+ self.default_lifetime = Rails.application.config.devise_oauth2_providable[config_name]
13
+
14
+ belongs_to :user
15
+ belongs_to :client
16
+
17
+ after_initialize :init_token, :on => :create, :unless => :token?
18
+ after_initialize :init_expires_at, :on => :create, :unless => :expires_at?
19
+ validates :expires_at, :presence => true
20
+ validates :client, :presence => true
21
+ validates :token, :presence => true, :uniqueness => true
22
+
23
+ scope :not_expired, lambda {
24
+ where(self.arel_table[:expires_at].gteq(Time.now.utc))
25
+ }
26
+ default_scope not_expired
27
+
28
+ include LocalInstanceMethods
29
+ end
30
+ end
31
+
32
+ module LocalInstanceMethods
33
+ # number of seconds until the token expires
34
+ def expires_in
35
+ (expires_at - Time.now.utc).to_i
36
+ end
37
+
38
+ # forcefully expire the token
39
+ def expired!
40
+ self.expires_at = Time.now.utc
41
+ self.save!
42
+ end
43
+
44
+ private
45
+
46
+ def init_token
47
+ self.token = Devise::Oauth2Providable.random_id
48
+ end
49
+ def init_expires_at
50
+ self.expires_at = self.default_lifetime.from_now
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ ActiveRecord::Base.send :include, Devise::Oauth2Providable::ExpirableToken
@@ -8,7 +8,7 @@ module Devise
8
8
  end
9
9
 
10
10
  def authenticate!
11
- if client && code = client.authorization_codes.valid.find_by_token(params[:code])
11
+ if client && code = client.authorization_codes.find_by_token(params[:code])
12
12
  success! code.user
13
13
  elsif !halted?
14
14
  oauth_error! :invalid_grant, 'invalid authorization code request'
@@ -9,7 +9,7 @@ module Devise
9
9
  end
10
10
  def authenticate!
11
11
  @req.setup!
12
- token = Devise::Oauth2Providable::AccessToken.valid.find_by_token @req.access_token
12
+ token = Devise::Oauth2Providable::AccessToken.find_by_token @req.access_token
13
13
  env[Devise::Oauth2Providable::CLIENT_ENV_REF] = token.client if token
14
14
  resource = token ? token.user : nil
15
15
  if validate(resource)
@@ -8,7 +8,7 @@ module Devise
8
8
  end
9
9
 
10
10
  def authenticate!
11
- if client && refresh_token = client.refresh_tokens.valid.find_by_token(params[:refresh_token])
11
+ if client && refresh_token = client.refresh_tokens.find_by_token(params[:refresh_token])
12
12
  env[Devise::Oauth2Providable::REFRESH_TOKEN_ENV_REF] = refresh_token
13
13
  success! refresh_token.user
14
14
  elsif !halted?
@@ -1,5 +1,5 @@
1
1
  module Devise
2
2
  module Oauth2Providable
3
- VERSION = "1.0.1"
3
+ VERSION = "1.0.2"
4
4
  end
5
5
  end
@@ -1,6 +1,7 @@
1
1
  require 'devise'
2
2
  require 'rack/oauth2'
3
3
  require 'devise/oauth2_providable/engine'
4
+ require 'devise/oauth2_providable/expirable_token'
4
5
  require 'devise/oauth2_providable/strategies/oauth2_providable_strategy'
5
6
  require 'devise/oauth2_providable/strategies/oauth2_password_grant_type_strategy'
6
7
  require 'devise/oauth2_providable/strategies/oauth2_refresh_token_grant_type_strategy'
@@ -3,8 +3,8 @@ require 'spec_helper'
3
3
  describe ProtectedController do
4
4
 
5
5
  describe 'get :index' do
6
+ with :client
6
7
  before do
7
- client = Devise::Oauth2Providable::Client.create! :name => 'test', :redirect_uri => 'http://localhost:3000', :website => 'http://localhost'
8
8
  @user = User.create! :email => 'foo@example.com'
9
9
  @token = Devise::Oauth2Providable::AccessToken.create! :client => client, :user => @user
10
10
  end
@@ -40,6 +40,12 @@ module Dummy
40
40
 
41
41
  # Version of your assets, change this if you want to expire all your assets
42
42
  config.assets.version = '1.0'
43
+
44
+
45
+ # (optional) configure token expiration
46
+ # config.devise_oauth2_providable.access_token_expires_in = 1.second # 15.minute default
47
+ # config.devise_oauth2_providable.refresh_token_expires_in = 1.minute # 1.month default
48
+ # config.devise_oauth2_providable.authorization_token_expires_in = 5.seconds # 1.minute default
43
49
  end
44
50
  end
45
51
 
@@ -0,0 +1,5 @@
1
+ Factory.define :client, :class => 'Devise::Oauth2Providable::Client' do |f|
2
+ f.name 'test'
3
+ f.website 'http://localhost'
4
+ f.redirect_uri 'http://localhost:3000'
5
+ end
@@ -3,15 +3,15 @@ require 'spec_helper'
3
3
  describe Devise::Strategies::Oauth2AuthorizationCodeGrantTypeStrategy do
4
4
  describe 'POST /oauth2/token' do
5
5
  describe 'with grant_type=authorization_code' do
6
+ with :client
6
7
  context 'with valid params' do
7
8
  before do
8
9
  @user = User.create! :email => 'ryan@socialcast.com', :password => 'test'
9
- @client = Devise::Oauth2Providable::Client.create! :name => 'example', :redirect_uri => 'http://localhost', :website => 'http://localhost'
10
- @authorization_code = @user.authorization_codes.create(:client_id => @client, :redirect_uri => @client.redirect_uri)
10
+ @authorization_code = @user.authorization_codes.create(:client_id => client, :redirect_uri => client.redirect_uri)
11
11
  params = {
12
12
  :grant_type => 'authorization_code',
13
- :client_id => @client.identifier,
14
- :client_secret => @client.secret,
13
+ :client_id => client.identifier,
14
+ :client_secret => client.secret,
15
15
  :code => @authorization_code.token
16
16
  }
17
17
 
@@ -32,14 +32,14 @@ describe Devise::Strategies::Oauth2AuthorizationCodeGrantTypeStrategy do
32
32
  end
33
33
  end
34
34
  context 'with invalid authorization_code' do
35
+ with :client
35
36
  before do
36
37
  @user = User.create! :email => 'ryan@socialcast.com', :password => 'test'
37
- @client = Devise::Oauth2Providable::Client.create! :name => 'example', :redirect_uri => 'http://localhost', :website => 'http://localhost'
38
- @authorization_code = @user.authorization_codes.create(:client_id => @client, :redirect_uri => @client.redirect_uri)
38
+ @authorization_code = @user.authorization_codes.create(:client_id => client, :redirect_uri => client.redirect_uri)
39
39
  params = {
40
40
  :grant_type => 'authorization_code',
41
- :client_id => @client.identifier,
42
- :client_secret => @client.secret,
41
+ :client_id => client.identifier,
42
+ :client_secret => client.secret,
43
43
  :refresh_token => 'invalid'
44
44
  }
45
45
 
@@ -4,14 +4,14 @@ describe Devise::Strategies::Oauth2PasswordGrantTypeStrategy do
4
4
  describe 'POST /oauth2/token' do
5
5
  describe 'with grant_type=password' do
6
6
  context 'with valid params' do
7
+ with :client
7
8
  before do
8
9
  @user = User.create! :email => 'ryan@socialcast.com', :password => 'test'
9
- @client = Devise::Oauth2Providable::Client.create! :name => 'example', :redirect_uri => 'http://localhost', :website => 'http://localhost'
10
10
 
11
11
  params = {
12
12
  :grant_type => 'password',
13
- :client_id => @client.identifier,
14
- :client_secret => @client.secret,
13
+ :client_id => client.identifier,
14
+ :client_secret => client.secret,
15
15
  :username => @user.email,
16
16
  :password => 'test'
17
17
  }
@@ -27,14 +27,14 @@ describe Devise::Strategies::Oauth2PasswordGrantTypeStrategy do
27
27
  end
28
28
  end
29
29
  context 'with invalid params' do
30
+ with :client
30
31
  before do
31
32
  @user = User.create! :email => 'ryan@socialcast.com', :password => 'test'
32
- @client = Devise::Oauth2Providable::Client.create! :name => 'example', :redirect_uri => 'http://localhost', :website => 'http://localhost'
33
33
 
34
34
  params = {
35
35
  :grant_type => 'password',
36
- :client_id => @client.identifier,
37
- :client_secret => @client.secret,
36
+ :client_id => client.identifier,
37
+ :client_secret => client.secret,
38
38
  :username => @user.email,
39
39
  :password => 'bar'
40
40
  }
@@ -4,14 +4,14 @@ describe Devise::Strategies::Oauth2RefreshTokenGrantTypeStrategy do
4
4
  describe 'POST /oauth2/token' do
5
5
  describe 'with grant_type=refresh_token' do
6
6
  context 'with valid params' do
7
+ with :client
7
8
  before do
8
9
  @user = User.create! :email => 'ryan@socialcast.com', :password => 'test'
9
- @client = Devise::Oauth2Providable::Client.create! :name => 'example', :redirect_uri => 'http://localhost', :website => 'http://localhost'
10
- @refresh_token = @client.refresh_tokens.create! :user => @user
10
+ @refresh_token = client.refresh_tokens.create! :user => @user
11
11
  params = {
12
12
  :grant_type => 'refresh_token',
13
- :client_id => @client.identifier,
14
- :client_secret => @client.secret,
13
+ :client_id => client.identifier,
14
+ :client_secret => client.secret,
15
15
  :refresh_token => @refresh_token.token
16
16
  }
17
17
 
@@ -34,12 +34,12 @@ describe Devise::Strategies::Oauth2RefreshTokenGrantTypeStrategy do
34
34
  context 'with invalid refresh_token' do
35
35
  before do
36
36
  @user = User.create! :email => 'ryan@socialcast.com', :password => 'test'
37
- @client = Devise::Oauth2Providable::Client.create! :name => 'example', :redirect_uri => 'http://localhost', :website => 'http://localhost'
38
- @refresh_token = @client.refresh_tokens.create! :user => @user
37
+ client = Devise::Oauth2Providable::Client.create! :name => 'example', :redirect_uri => 'http://localhost', :website => 'http://localhost'
38
+ @refresh_token = client.refresh_tokens.create! :user => @user
39
39
  params = {
40
40
  :grant_type => 'refresh_token',
41
- :client_id => @client.identifier,
42
- :client_secret => @client.secret,
41
+ :client_id => client.identifier,
42
+ :client_secret => client.secret,
43
43
  :refresh_token => 'invalid'
44
44
  }
45
45
 
@@ -4,8 +4,8 @@ describe Devise::Oauth2Providable::AccessToken do
4
4
  it { Devise::Oauth2Providable::AccessToken.table_name.should == 'oauth2_access_tokens' }
5
5
 
6
6
  describe 'basic access token instance' do
7
+ with :client
7
8
  subject do
8
- client = Devise::Oauth2Providable::Client.create! :name => 'test', :redirect_uri => 'http://localhost:3000', :website => 'http://localhost'
9
9
  Devise::Oauth2Providable::AccessToken.create! :client => client
10
10
  end
11
11
  it { should validate_presence_of :token }
@@ -22,17 +22,30 @@ describe Devise::Oauth2Providable::AccessToken do
22
22
  it { should have_db_index :expires_at }
23
23
  end
24
24
 
25
- describe 'refresh token expires before access token expires_at' do
26
- before do
27
- @soon = 1.minute.from_now
28
- client = Devise::Oauth2Providable::Client.create! :name => 'test', :redirect_uri => 'http://localhost:3000', :website => 'http://localhost'
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
25
+ describe '#expires_at' do
26
+ context 'when refresh token does not expire before access token' do
27
+ with :client
28
+ before do
29
+ @later = 1.year.from_now
30
+ @refresh_token = client.refresh_tokens.create!
31
+ @refresh_token.expires_at = @soon
32
+ @access_token = Devise::Oauth2Providable::AccessToken.create! :client => client, :refresh_token => @refresh_token
33
+ end
34
+ focus 'should not set the access token expires_at to equal refresh token' do
35
+ @access_token.expires_at.should_not == @later
36
+ end
32
37
  end
33
- it 'should set the access token expires_at to equal refresh token' do
34
- @access_token.expires_at.should eq @soon
38
+ context 'when refresh token expires before access token' do
39
+ with :client
40
+ before do
41
+ @soon = 1.minute.from_now
42
+ @refresh_token = client.refresh_tokens.create!
43
+ @refresh_token.expires_at = @soon
44
+ @access_token = Devise::Oauth2Providable::AccessToken.create! :client => client, :refresh_token => @refresh_token
45
+ end
46
+ it 'should set the access token expires_at to equal refresh token' do
47
+ @access_token.expires_at.should == @soon
48
+ end
35
49
  end
36
50
  end
37
51
  end
38
-
@@ -2,8 +2,8 @@ require 'spec_helper'
2
2
 
3
3
  describe Devise::Oauth2Providable::AuthorizationCode do
4
4
  describe 'basic authorization code instance' do
5
+ with :client
5
6
  subject do
6
- client = Devise::Oauth2Providable::Client.create! :name => 'test', :redirect_uri => 'http://localhost:3000', :website => 'http://localhost'
7
7
  Devise::Oauth2Providable::AuthorizationCode.create! :client => client
8
8
  end
9
9
  it { should validate_presence_of :token }
@@ -4,8 +4,8 @@ describe Devise::Oauth2Providable::RefreshToken do
4
4
  it { Devise::Oauth2Providable::RefreshToken.table_name.should == 'oauth2_refresh_tokens' }
5
5
 
6
6
  describe 'basic refresh token instance' do
7
+ with :client
7
8
  subject do
8
- client = Devise::Oauth2Providable::Client.create! :name => 'test', :redirect_uri => 'http://localhost:3000', :website => 'http://localhost'
9
9
  Devise::Oauth2Providable::RefreshToken.create! :client => client
10
10
  end
11
11
  it { should validate_presence_of :token }
data/spec/spec_helper.rb CHANGED
@@ -2,9 +2,15 @@
2
2
  ENV["RAILS_ENV"] = "test"
3
3
  require File.expand_path("../dummy/config/environment.rb", __FILE__)
4
4
 
5
+ require 'pry'
5
6
  require 'rspec/rails'
6
7
  require 'shoulda-matchers'
7
- require 'pry'
8
+
9
+ require 'factory_girl_rspec'
10
+ FactoryGirl.definition_file_paths = [
11
+ File.join(File.dirname(__FILE__), 'factories')
12
+ ]
13
+ FactoryGirl.find_definitions
8
14
 
9
15
  ENGINE_RAILS_ROOT=File.join(File.dirname(__FILE__), '../')
10
16
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devise_oauth2_providable
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 1
10
- version: 1.0.1
9
+ - 2
10
+ version: 1.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ryan Sonnek
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-10-27 00:00:00 Z
18
+ date: 2011-10-28 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: rails
@@ -132,6 +132,38 @@ dependencies:
132
132
  version: 0.9.6.2
133
133
  version_requirements: *id007
134
134
  type: :development
135
+ - !ruby/object:Gem::Dependency
136
+ name: factory_girl
137
+ prerelease: false
138
+ requirement: &id008 !ruby/object:Gem::Requirement
139
+ none: false
140
+ requirements:
141
+ - - "="
142
+ - !ruby/object:Gem::Version
143
+ hash: 7
144
+ segments:
145
+ - 2
146
+ - 2
147
+ - 0
148
+ version: 2.2.0
149
+ version_requirements: *id008
150
+ type: :development
151
+ - !ruby/object:Gem::Dependency
152
+ name: factory_girl_rspec
153
+ prerelease: false
154
+ requirement: &id009 !ruby/object:Gem::Requirement
155
+ none: false
156
+ requirements:
157
+ - - "="
158
+ - !ruby/object:Gem::Version
159
+ hash: 29
160
+ segments:
161
+ - 0
162
+ - 0
163
+ - 1
164
+ version: 0.0.1
165
+ version_requirements: *id009
166
+ type: :development
135
167
  description: Rails3 engine that adds OAuth2 Provider support to any application built with Devise authentication
136
168
  email:
137
169
  - ryan@socialcast.com
@@ -163,6 +195,7 @@ files:
163
195
  - db/migrate/20111014160714_create_devise_oauth2_providable_schema.rb
164
196
  - devise_oauth2_providable.gemspec
165
197
  - lib/devise/oauth2_providable/engine.rb
198
+ - lib/devise/oauth2_providable/expirable_token.rb
166
199
  - lib/devise/oauth2_providable/models/oauth2_authorization_code_grantable.rb
167
200
  - lib/devise/oauth2_providable/models/oauth2_password_grantable.rb
168
201
  - lib/devise/oauth2_providable/models/oauth2_providable.rb
@@ -174,7 +207,6 @@ files:
174
207
  - lib/devise/oauth2_providable/strategies/oauth2_refresh_token_grant_type_strategy.rb
175
208
  - lib/devise/oauth2_providable/version.rb
176
209
  - lib/devise_oauth2_providable.rb
177
- - lib/expirable_token.rb
178
210
  - script/rails
179
211
  - spec/controllers/protected_controller_spec.rb
180
212
  - spec/dummy/Rakefile
@@ -215,6 +247,7 @@ files:
215
247
  - spec/dummy/public/500.html
216
248
  - spec/dummy/public/favicon.ico
217
249
  - spec/dummy/script/rails
250
+ - spec/factories/client_factory.rb
218
251
  - spec/integration/oauth2_authorization_token_grant_type_strategy_spec.rb
219
252
  - spec/integration/oauth2_password_grant_type_strategy_spec.rb
220
253
  - spec/integration/oauth2_refresh_token_grant_type_strategy_spec.rb
@@ -302,6 +335,7 @@ test_files:
302
335
  - spec/dummy/public/500.html
303
336
  - spec/dummy/public/favicon.ico
304
337
  - spec/dummy/script/rails
338
+ - spec/factories/client_factory.rb
305
339
  - spec/integration/oauth2_authorization_token_grant_type_strategy_spec.rb
306
340
  - spec/integration/oauth2_password_grant_type_strategy_spec.rb
307
341
  - spec/integration/oauth2_refresh_token_grant_type_strategy_spec.rb
@@ -1,41 +0,0 @@
1
- module ExpirableToken
2
- def self.included(klass)
3
- klass.class_eval do
4
- cattr_accessor :default_lifetime
5
- self.default_lifetime = 1.minute
6
-
7
- belongs_to :user
8
- belongs_to :client
9
-
10
- before_validation :init_token, :on => :create, :unless => :token?
11
- before_validation :init_expires_at, :on => :create, :unless => :expires_at?
12
- validates :expires_at, :presence => true
13
- validates :client, :presence => true
14
- validates :token, :presence => true, :uniqueness => true
15
-
16
- # TODO: this should be a default scope once rails default_scope supports lambda's
17
- scope :valid, lambda {
18
- where(self.arel_table[:expires_at].gteq(Time.now.utc))
19
- }
20
- end
21
- end
22
-
23
- def expires_in
24
- (expires_at - Time.now.utc).to_i
25
- end
26
-
27
- def expired!
28
- self.expires_at = Time.now.utc
29
- self.save!
30
- end
31
-
32
- private
33
-
34
- def init_token
35
- self.token = Devise::Oauth2Providable.random_id
36
- end
37
- def init_expires_at
38
- self.expires_at = self.default_lifetime.from_now
39
- end
40
- end
41
-