sorcery 0.4.1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sorcery might be problematic. Click here for more details.
- data/README.rdoc +1 -1
- data/VERSION +1 -1
- data/lib/sorcery.rb +7 -0
- data/lib/sorcery/crypto_providers/bcrypt.rb +2 -4
- data/lib/sorcery/initializers/initializer.rb +1 -0
- data/lib/sorcery/model.rb +21 -1
- data/lib/sorcery/test_helpers.rb +0 -47
- data/lib/sorcery/test_helpers/internal.rb +55 -0
- data/lib/sorcery/test_helpers/internal/rails.rb +52 -0
- data/lib/sorcery/test_helpers/internal/sinatra.rb +122 -0
- data/lib/sorcery/test_helpers/rails.rb +5 -43
- data/lib/sorcery/test_helpers/sinatra.rb +59 -102
- data/sorcery.gemspec +5 -2
- data/spec/Gemfile +1 -1
- data/spec/Gemfile.lock +12 -4
- data/spec/rails3/Gemfile +1 -1
- data/spec/rails3/Gemfile.lock +2 -2
- data/spec/rails3/spec/controller_activity_logging_spec.rb +2 -4
- data/spec/rails3/spec/controller_oauth_spec.rb +3 -3
- data/spec/rails3/spec/controller_session_timeout_spec.rb +20 -19
- data/spec/rails3/spec/controller_spec.rb +6 -16
- data/spec/rails3/spec/spec_helper.rb +2 -2
- data/spec/rails3/spec/user_activation_spec.rb +2 -12
- data/spec/rails3/spec/user_brute_force_protection_spec.rb +2 -30
- data/spec/rails3/spec/user_remember_me_spec.rb +3 -11
- data/spec/rails3/spec/user_reset_password_spec.rb +13 -14
- data/spec/rails3/spec/user_spec.rb +18 -2
- data/spec/sinatra/Gemfile +1 -1
- data/spec/sinatra/Gemfile.lock +2 -2
- data/spec/sinatra/spec/controller_session_timeout_spec.rb +23 -22
- data/spec/sinatra/spec/spec_helper.rb +2 -1
- metadata +5 -2
data/README.rdoc
CHANGED
@@ -28,7 +28,7 @@ Example Rails 3 app using sorcery: https://github.com/NoamB/sorcery-example-app
|
|
28
28
|
|
29
29
|
Example Sinatra app using sorcery: https://github.com/NoamB/sorcery-example-app-sinatra
|
30
30
|
|
31
|
-
Documentation: http://rubydoc.info/gems/sorcery/0.4.
|
31
|
+
Documentation: http://rubydoc.info/gems/sorcery/0.4.2/frames
|
32
32
|
|
33
33
|
Check out the tutorials in the github wiki!
|
34
34
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.2
|
data/lib/sorcery.rb
CHANGED
@@ -48,7 +48,14 @@ module Sorcery
|
|
48
48
|
module TestHelpers
|
49
49
|
autoload :Rails, 'sorcery/test_helpers/rails'
|
50
50
|
autoload :Sinatra, 'sorcery/test_helpers/sinatra'
|
51
|
+
autoload :Internal, 'sorcery/test_helpers/internal'
|
52
|
+
module Internal
|
53
|
+
autoload :Rails, 'sorcery/test_helpers/internal/rails'
|
54
|
+
autoload :Sinatra, 'sorcery/test_helpers/internal/sinatra'
|
55
|
+
end
|
56
|
+
|
51
57
|
end
|
58
|
+
|
52
59
|
|
53
60
|
require 'sorcery/engine' if defined?(Rails) && Rails::VERSION::MAJOR == 3
|
54
61
|
require 'sorcery/sinatra' if defined?(Sinatra)
|
@@ -30,11 +30,9 @@ module Sorcery
|
|
30
30
|
#
|
31
31
|
# gem install bcrypt-ruby
|
32
32
|
#
|
33
|
-
#
|
33
|
+
# Update your initializer to use it:
|
34
34
|
#
|
35
|
-
#
|
36
|
-
# c.encryption_algorithm = :bcrypt
|
37
|
-
# end
|
35
|
+
# config.encryption_algorithm = :bcrypt
|
38
36
|
#
|
39
37
|
# You are good to go!
|
40
38
|
class BCrypt
|
@@ -9,6 +9,7 @@ Rails.application.config.sorcery.configure do |config|
|
|
9
9
|
# config.not_authenticated_action = :not_authenticated # what controller action to call for non-authenticated users. You can also override 'not_authenticated' instead.
|
10
10
|
# config.save_return_to_url = true # when a non logged in user tries to enter a page that requires login, save the URL he wanted to reach,
|
11
11
|
# and send him there after login, using 'redirect_back_or_to'.
|
12
|
+
# subclasses_inherit_config = false # make this configuration inheritable for subclasses. Useful for ActiveRecord's STI.
|
12
13
|
|
13
14
|
# -- session timeout --
|
14
15
|
# config.session_timeout = 3600 # how long in seconds to keep the session alive.
|
data/lib/sorcery/model.rb
CHANGED
@@ -22,19 +22,23 @@ module Sorcery
|
|
22
22
|
begin
|
23
23
|
include Submodules.const_get(mod.to_s.split("_").map {|p| p.capitalize}.join(""))
|
24
24
|
rescue NameError
|
25
|
-
# don't stop on a missing submodule.
|
25
|
+
# don't stop on a missing submodule. Needed because some submodules are only defined in the controller side.
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
+
# This runs the options block set in the initializer on the model class.
|
30
31
|
::Sorcery::Controller::Config.user_config.tap{|blk| blk.call(@sorcery_config) if blk}
|
31
32
|
|
33
|
+
# add virtual password accessor and ORM callbacks
|
32
34
|
self.class_eval do
|
33
35
|
attr_accessor @sorcery_config.password_attribute_name
|
34
36
|
attr_protected @sorcery_config.crypted_password_attribute_name, @sorcery_config.salt_attribute_name
|
35
37
|
before_save :encrypt_password, :if => Proc.new { |record| record.send(sorcery_config.password_attribute_name).present? }
|
36
38
|
after_save :clear_virtual_password, :if => Proc.new { |record| record.send(sorcery_config.password_attribute_name).present? }
|
37
39
|
end
|
40
|
+
|
41
|
+
@sorcery_config.after_config << :add_config_inheritence if @sorcery_config.subclasses_inherit_config
|
38
42
|
@sorcery_config.after_config.each { |c| send(c) }
|
39
43
|
end
|
40
44
|
end
|
@@ -76,6 +80,20 @@ module Sorcery
|
|
76
80
|
@sorcery_config.encryption_provider.matches?(crypted, *tokens)
|
77
81
|
end
|
78
82
|
|
83
|
+
def add_config_inheritence
|
84
|
+
self.class_eval do
|
85
|
+
def self.inherited(subclass)
|
86
|
+
subclass.class_eval do
|
87
|
+
class << self
|
88
|
+
attr_accessor :sorcery_config
|
89
|
+
end
|
90
|
+
end
|
91
|
+
subclass.sorcery_config = sorcery_config
|
92
|
+
super
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
79
97
|
end
|
80
98
|
|
81
99
|
module InstanceMethods
|
@@ -133,6 +151,7 @@ module Sorcery
|
|
133
151
|
:salt_attribute_name, # change default salt attribute.
|
134
152
|
:stretches, # how many times to apply encryption to the password.
|
135
153
|
:encryption_key, # encryption key used to encrypt reversible encryptions such as AES256.
|
154
|
+
:subclasses_inherit_config, # make this configuration inheritable for subclasses. Useful for ActiveRecord's STI.
|
136
155
|
|
137
156
|
:submodules, # configured in config/application.rb
|
138
157
|
:before_authenticate, # an array of method names to call before authentication completes. used internally.
|
@@ -156,6 +175,7 @@ module Sorcery
|
|
156
175
|
:@salt_join_token => "",
|
157
176
|
:@salt_attribute_name => :salt,
|
158
177
|
:@stretches => nil,
|
178
|
+
:@subclasses_inherit_config => false,
|
159
179
|
:@before_authenticate => [],
|
160
180
|
:@after_config => []
|
161
181
|
}
|
data/lib/sorcery/test_helpers.rb
CHANGED
@@ -1,52 +1,5 @@
|
|
1
1
|
module Sorcery
|
2
|
-
# This file will be included in the spec_helper file.
|
3
2
|
module TestHelpers
|
4
|
-
def self.included(base)
|
5
|
-
# reducing default cost for specs speed
|
6
|
-
CryptoProviders::BCrypt.class_eval do
|
7
|
-
class << self
|
8
|
-
def cost
|
9
|
-
1
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
# a patch to fix a bug in testing that happens when you 'destroy' a session twice.
|
16
|
-
# After the first destroy, the session is an ordinary hash, and then when destroy is called again there's an exception.
|
17
|
-
class ::Hash
|
18
|
-
def destroy
|
19
|
-
clear
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def create_new_user(attributes_hash = nil)
|
24
|
-
user_attributes_hash = attributes_hash || {:username => 'gizmo', :email => "bla@bla.com", :password => 'secret'}
|
25
|
-
@user = User.new(user_attributes_hash)
|
26
|
-
@user.save!
|
27
|
-
@user
|
28
|
-
end
|
29
3
|
|
30
|
-
def create_new_external_user(provider, attributes_hash = nil)
|
31
|
-
user_attributes_hash = attributes_hash || {:username => 'gizmo', :authentications_attributes => [{:provider => provider, :uid => 123}]}
|
32
|
-
@user = User.new(user_attributes_hash)
|
33
|
-
@user.save!
|
34
|
-
@user
|
35
|
-
end
|
36
|
-
|
37
|
-
def sorcery_model_property_set(property, *values)
|
38
|
-
User.class_eval do
|
39
|
-
sorcery_config.send(:"#{property}=", *values)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
# reload user class between specs
|
46
|
-
# so it will be possible to test the different submodules in isolation
|
47
|
-
def reload_user_class
|
48
|
-
Object.send(:remove_const,:User)
|
49
|
-
load 'user.rb'
|
50
|
-
end
|
51
4
|
end
|
52
5
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Sorcery
|
2
|
+
module TestHelpers
|
3
|
+
# Internal TestHelpers are used to test the gem, internally, and should not be used to test apps *using* sorcery.
|
4
|
+
# This file will be included in the spec_helper file.
|
5
|
+
module Internal
|
6
|
+
def self.included(base)
|
7
|
+
# reducing default cost for specs speed
|
8
|
+
CryptoProviders::BCrypt.class_eval do
|
9
|
+
class << self
|
10
|
+
def cost
|
11
|
+
1
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# a patch to fix a bug in testing that happens when you 'destroy' a session twice.
|
18
|
+
# After the first destroy, the session is an ordinary hash, and then when destroy is called again there's an exception.
|
19
|
+
class ::Hash
|
20
|
+
def destroy
|
21
|
+
clear
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def create_new_user(attributes_hash = nil)
|
26
|
+
user_attributes_hash = attributes_hash || {:username => 'gizmo', :email => "bla@bla.com", :password => 'secret'}
|
27
|
+
@user = User.new(user_attributes_hash)
|
28
|
+
@user.save!
|
29
|
+
@user
|
30
|
+
end
|
31
|
+
|
32
|
+
def create_new_external_user(provider, attributes_hash = nil)
|
33
|
+
user_attributes_hash = attributes_hash || {:username => 'gizmo', :authentications_attributes => [{:provider => provider, :uid => 123}]}
|
34
|
+
@user = User.new(user_attributes_hash)
|
35
|
+
@user.save!
|
36
|
+
@user
|
37
|
+
end
|
38
|
+
|
39
|
+
def sorcery_model_property_set(property, *values)
|
40
|
+
User.class_eval do
|
41
|
+
sorcery_config.send(:"#{property}=", *values)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
# reload user class between specs
|
48
|
+
# so it will be possible to test the different submodules in isolation
|
49
|
+
def reload_user_class
|
50
|
+
Object.send(:remove_const,:User)
|
51
|
+
load 'user.rb'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Sorcery
|
2
|
+
module TestHelpers
|
3
|
+
module Internal
|
4
|
+
module Rails
|
5
|
+
include ::Sorcery::TestHelpers::Rails
|
6
|
+
|
7
|
+
SUBMODUELS_AUTO_ADDED_CONTROLLER_FILTERS = [:register_last_activity_time_to_db, :deny_banned_user, :validate_session]
|
8
|
+
|
9
|
+
def sorcery_reload!(submodules = [], options = {})
|
10
|
+
reload_user_class
|
11
|
+
|
12
|
+
# return to no-module configuration
|
13
|
+
::Sorcery::Controller::Config.init!
|
14
|
+
::Sorcery::Controller::Config.reset!
|
15
|
+
|
16
|
+
# remove all plugin before_filters so they won't fail other tests.
|
17
|
+
# I don't like this way, but I didn't find another.
|
18
|
+
# hopefully it won't break until Rails 4.
|
19
|
+
ApplicationController._process_action_callbacks.delete_if {|c| SUBMODUELS_AUTO_ADDED_CONTROLLER_FILTERS.include?(c.filter) }
|
20
|
+
|
21
|
+
# configure
|
22
|
+
::Sorcery::Controller::Config.submodules = submodules
|
23
|
+
::Sorcery::Controller::Config.user_class = nil
|
24
|
+
ActionController::Base.send(:include,::Sorcery::Controller)
|
25
|
+
|
26
|
+
::Sorcery::Controller::Config.user_config do |user|
|
27
|
+
options.each do |property,value|
|
28
|
+
user.send(:"#{property}=", value)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
User.authenticates_with_sorcery!
|
32
|
+
end
|
33
|
+
|
34
|
+
def sorcery_controller_property_set(property, value)
|
35
|
+
::Sorcery::Controller::Config.send(:"#{property}=", value)
|
36
|
+
end
|
37
|
+
|
38
|
+
def sorcery_controller_external_property_set(provider, property, value)
|
39
|
+
::Sorcery::Controller::Config.send(provider).send(:"#{property}=", value)
|
40
|
+
end
|
41
|
+
|
42
|
+
# This helper is used to fake multiple users signing in in tests.
|
43
|
+
# It does so by clearing @current_user, thus allowing a new user to login,
|
44
|
+
# all this without calling the :logout action explicitly.
|
45
|
+
# A dirty dirty hack.
|
46
|
+
def clear_user_without_logout
|
47
|
+
subject.instance_variable_set(:@current_user,nil)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
module Sorcery
|
2
|
+
module TestHelpers
|
3
|
+
module Internal
|
4
|
+
module Sinatra
|
5
|
+
|
6
|
+
class ::Sinatra::Application
|
7
|
+
class << self
|
8
|
+
attr_accessor :sorcery_vars
|
9
|
+
end
|
10
|
+
@sorcery_vars = {}
|
11
|
+
|
12
|
+
# NOTE: see before and after test filters in filters.rb
|
13
|
+
|
14
|
+
def save_instance_vars
|
15
|
+
instance_variables.each do |var|
|
16
|
+
self.class.sorcery_vars[:"#{var.to_s.delete("@")}"] = instance_variable_get(var)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
::RSpec::Matchers.define :redirect_to do |expected|
|
22
|
+
match do |actual|
|
23
|
+
actual.status == 302 && actual.location == expected
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_sinatra_app(app)
|
28
|
+
while app.class != ::Sinatra::Application do
|
29
|
+
app = app.instance_variable_get(:@app)
|
30
|
+
end
|
31
|
+
app
|
32
|
+
end
|
33
|
+
|
34
|
+
def login_user(user=nil)
|
35
|
+
user ||= @user
|
36
|
+
get_sinatra_app(subject).send(:login_user,user)
|
37
|
+
get_sinatra_app(subject).send(:after_login!,user,[user.username,'secret'])
|
38
|
+
end
|
39
|
+
|
40
|
+
def logout_user
|
41
|
+
get_sinatra_app(subject).send(:logout)
|
42
|
+
end
|
43
|
+
|
44
|
+
def clear_user_without_logout
|
45
|
+
get_sinatra_app(subject).instance_variable_set(:@current_user,nil)
|
46
|
+
end
|
47
|
+
|
48
|
+
def assigns
|
49
|
+
::Sinatra::Application.sorcery_vars
|
50
|
+
end
|
51
|
+
|
52
|
+
class SessionData
|
53
|
+
def initialize(cookies)
|
54
|
+
@cookies = cookies
|
55
|
+
@data = cookies['rack.session']
|
56
|
+
if @data
|
57
|
+
@data = @data.unpack("m*").first
|
58
|
+
@data = Marshal.load(@data)
|
59
|
+
else
|
60
|
+
@data = {}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def [](key)
|
65
|
+
@data[key]
|
66
|
+
end
|
67
|
+
|
68
|
+
def []=(key, value)
|
69
|
+
@data[key] = value
|
70
|
+
session_data = Marshal.dump(@data)
|
71
|
+
session_data = [session_data].pack("m*")
|
72
|
+
@cookies.merge("rack.session=#{Rack::Utils.escape(session_data)}", URI.parse("//example.org//"))
|
73
|
+
raise "session variable not set" unless @cookies['rack.session'] == session_data
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def session
|
78
|
+
SessionData.new(rack_test_session.instance_variable_get(:@rack_mock_session).cookie_jar)
|
79
|
+
end
|
80
|
+
|
81
|
+
def cookies
|
82
|
+
rack_test_session.instance_variable_get(:@rack_mock_session).cookie_jar
|
83
|
+
end
|
84
|
+
|
85
|
+
def sorcery_reload!(submodules = [], options = {})
|
86
|
+
reload_user_class
|
87
|
+
|
88
|
+
# return to no-module configuration
|
89
|
+
::Sorcery::Controller::Config.init!
|
90
|
+
::Sorcery::Controller::Config.reset!
|
91
|
+
|
92
|
+
# clear all filters
|
93
|
+
::Sinatra::Application.instance_variable_set(:@filters,{:before => [],:after => []})
|
94
|
+
::Sinatra::Application.class_eval do
|
95
|
+
load File.join(File.dirname(__FILE__),'..','..','..','..','spec','sinatra','filters.rb')
|
96
|
+
end
|
97
|
+
|
98
|
+
# configure
|
99
|
+
::Sorcery::Controller::Config.submodules = submodules
|
100
|
+
::Sorcery::Controller::Config.user_class = nil
|
101
|
+
::Sinatra::Application.send(:include, Sorcery::Controller::Adapters::Sinatra)
|
102
|
+
::Sinatra::Application.send(:include, Sorcery::Controller)
|
103
|
+
|
104
|
+
::Sorcery::Controller::Config.user_config do |user|
|
105
|
+
options.each do |property,value|
|
106
|
+
user.send(:"#{property}=", value)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
User.authenticates_with_sorcery!
|
110
|
+
end
|
111
|
+
|
112
|
+
def sorcery_controller_property_set(property, value)
|
113
|
+
::Sorcery::Controller::Config.send(:"#{property}=", value)
|
114
|
+
end
|
115
|
+
|
116
|
+
def sorcery_controller_external_property_set(provider, property, value)
|
117
|
+
::Sorcery::Controller::Config.send(provider).send(:"#{property}=", value)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -1,54 +1,16 @@
|
|
1
1
|
module Sorcery
|
2
2
|
module TestHelpers
|
3
3
|
module Rails
|
4
|
-
|
5
|
-
|
6
|
-
def sorcery_reload!(submodules = [], options = {})
|
7
|
-
reload_user_class
|
8
|
-
|
9
|
-
# return to no-module configuration
|
10
|
-
::Sorcery::Controller::Config.init!
|
11
|
-
::Sorcery::Controller::Config.reset!
|
12
|
-
|
13
|
-
# remove all plugin before_filters so they won't fail other tests.
|
14
|
-
# I don't like this way, but I didn't find another.
|
15
|
-
# hopefully it won't break until Rails 4.
|
16
|
-
ApplicationController._process_action_callbacks.delete_if {|c| SUBMODUELS_AUTO_ADDED_CONTROLLER_FILTERS.include?(c.filter) }
|
17
|
-
|
18
|
-
# configure
|
19
|
-
::Sorcery::Controller::Config.submodules = submodules
|
20
|
-
::Sorcery::Controller::Config.user_class = nil
|
21
|
-
ActionController::Base.send(:include,::Sorcery::Controller)
|
22
|
-
|
23
|
-
::Sorcery::Controller::Config.user_config do |user|
|
24
|
-
options.each do |property,value|
|
25
|
-
user.send(:"#{property}=", value)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
User.authenticates_with_sorcery!
|
29
|
-
end
|
30
|
-
|
31
|
-
def sorcery_controller_property_set(property, value)
|
32
|
-
::Sorcery::Controller::Config.send(:"#{property}=", value)
|
33
|
-
end
|
34
|
-
|
35
|
-
def sorcery_controller_external_property_set(provider, property, value)
|
36
|
-
::Sorcery::Controller::Config.send(provider).send(:"#{property}=", value)
|
37
|
-
end
|
38
|
-
|
4
|
+
# logins a user and calls all callbacks
|
39
5
|
def login_user(user = nil)
|
40
6
|
user ||= @user
|
41
|
-
|
42
|
-
|
7
|
+
@controller.send(:login_user,user)
|
8
|
+
@controller.send(:after_login!,user,[user.send(user.sorcery_config.username_attribute_name),'secret'])
|
43
9
|
end
|
44
10
|
|
45
11
|
def logout_user
|
46
|
-
|
47
|
-
end
|
48
|
-
|
49
|
-
def clear_user_without_logout
|
50
|
-
subject.instance_variable_set(:@current_user,nil)
|
12
|
+
@controller.send(:logout)
|
51
13
|
end
|
52
14
|
end
|
53
15
|
end
|
54
|
-
end
|
16
|
+
end
|
@@ -1,127 +1,84 @@
|
|
1
1
|
module Sorcery
|
2
2
|
module TestHelpers
|
3
3
|
module Sinatra
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
def self.included(base)
|
5
|
+
base.send(:include, InstanceMethods)
|
6
|
+
base.send(:include, CookieSessionMethods)
|
7
|
+
::Sinatra::Base.class_eval do
|
8
|
+
class << self
|
9
|
+
attr_accessor :rack_test_session
|
9
10
|
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
class ::Sinatra::Application
|
14
|
-
class << self
|
15
|
-
attr_accessor :sorcery_vars
|
16
|
-
end
|
17
|
-
@sorcery_vars = {}
|
18
11
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
12
|
+
def self.inherited(subclass)
|
13
|
+
super
|
14
|
+
subclass.class_eval do
|
15
|
+
class << self
|
16
|
+
attr_accessor :rack_test_session
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
include CookieSessionMethods
|
22
|
+
|
23
|
+
def rack_test_session
|
24
|
+
self.class.rack_test_session
|
24
25
|
end
|
25
26
|
end
|
26
27
|
end
|
27
|
-
|
28
|
-
::RSpec::Matchers.define :redirect_to do |expected|
|
29
|
-
match do |actual|
|
30
|
-
actual.status == 302 && actual.location == expected
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def get_sinatra_app(app)
|
35
|
-
while app.class != ::Sinatra::Application do
|
36
|
-
app = app.instance_variable_get(:@app)
|
37
|
-
end
|
38
|
-
app
|
39
|
-
end
|
40
|
-
|
41
|
-
def login_user(user=nil)
|
42
|
-
user ||= @user
|
43
|
-
get_sinatra_app(subject).send(:login_user,user)
|
44
|
-
get_sinatra_app(subject).send(:after_login!,user,[user.username,'secret'])
|
45
|
-
end
|
46
|
-
|
47
|
-
def logout_user
|
48
|
-
get_sinatra_app(subject).send(:logout)
|
49
|
-
end
|
50
28
|
|
51
|
-
|
52
|
-
get_sinatra_app(
|
53
|
-
|
54
|
-
|
55
|
-
def assigns
|
56
|
-
::Sinatra::Application.sorcery_vars
|
57
|
-
end
|
58
|
-
|
59
|
-
class SessionData
|
60
|
-
def initialize(cookies)
|
61
|
-
@cookies = cookies
|
62
|
-
@data = cookies['rack.session']
|
63
|
-
if @data
|
64
|
-
@data = @data.unpack("m*").first
|
65
|
-
@data = Marshal.load(@data)
|
66
|
-
else
|
67
|
-
@data = {}
|
29
|
+
module InstanceMethods
|
30
|
+
def get_sinatra_app(app)
|
31
|
+
while !app.kind_of? ::Sinatra::Base do
|
32
|
+
app = app.instance_variable_get(:@app)
|
68
33
|
end
|
34
|
+
app
|
69
35
|
end
|
70
36
|
|
71
|
-
def
|
72
|
-
@
|
37
|
+
def login_user(user=nil)
|
38
|
+
user ||= @user
|
39
|
+
get_sinatra_app(app).send(:login_user, user)
|
40
|
+
get_sinatra_app(app).send(:after_login!, user, [user.send(user.sorcery_config.username_attribute_name), 'secret'])
|
73
41
|
end
|
74
42
|
|
75
|
-
def
|
76
|
-
|
77
|
-
session_data = Marshal.dump(@data)
|
78
|
-
session_data = [session_data].pack("m*")
|
79
|
-
@cookies.merge("rack.session=#{Rack::Utils.escape(session_data)}", URI.parse("//example.org//"))
|
80
|
-
raise "session variable not set" unless @cookies['rack.session'] == session_data
|
43
|
+
def logout_user
|
44
|
+
get_sinatra_app(app).send(:logout)
|
81
45
|
end
|
82
46
|
end
|
83
47
|
|
84
|
-
|
85
|
-
SessionData
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
48
|
+
module CookieSessionMethods
|
49
|
+
class SessionData
|
50
|
+
def initialize(cookies)
|
51
|
+
@cookies = cookies
|
52
|
+
@data = cookies['rack.session']
|
53
|
+
if @data
|
54
|
+
@data = @data.unpack("m*").first
|
55
|
+
@data = Marshal.load(@data)
|
56
|
+
else
|
57
|
+
@data = {}
|
58
|
+
end
|
59
|
+
end
|
94
60
|
|
95
|
-
|
96
|
-
|
97
|
-
|
61
|
+
def [](key)
|
62
|
+
@data[key]
|
63
|
+
end
|
98
64
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
::Sinatra::Application.send(:include, Sorcery::Controller)
|
110
|
-
|
111
|
-
::Sorcery::Controller::Config.user_config do |user|
|
112
|
-
options.each do |property,value|
|
113
|
-
user.send(:"#{property}=", value)
|
65
|
+
def []=(key, value)
|
66
|
+
@data[key] = value
|
67
|
+
session_data = Marshal.dump(@data)
|
68
|
+
session_data = [session_data].pack("m*")
|
69
|
+
@cookies.merge("rack.session=#{Rack::Utils.escape(session_data)}", URI.parse("//example.org//"))
|
70
|
+
raise "session variable not set" unless @cookies['rack.session'] == session_data
|
71
|
+
end
|
72
|
+
|
73
|
+
def clear
|
74
|
+
@data = {}
|
114
75
|
end
|
115
76
|
end
|
116
|
-
User.authenticates_with_sorcery!
|
117
|
-
end
|
118
|
-
|
119
|
-
def sorcery_controller_property_set(property, value)
|
120
|
-
::Sorcery::Controller::Config.send(:"#{property}=", value)
|
121
|
-
end
|
122
77
|
|
123
|
-
|
124
|
-
|
78
|
+
def session
|
79
|
+
SessionData.new(rack_test_session.instance_variable_get(:@rack_mock_session).cookie_jar)
|
80
|
+
end
|
81
|
+
|
125
82
|
end
|
126
83
|
end
|
127
84
|
end
|
data/sorcery.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{sorcery}
|
8
|
-
s.version = "0.4.
|
8
|
+
s.version = "0.4.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Noam Ben Ari"]
|
12
|
-
s.date = %q{2011-04-
|
12
|
+
s.date = %q{2011-04-30}
|
13
13
|
s.description = %q{Provides common authentication needs such as signing in/out, activating by email and resetting password.}
|
14
14
|
s.email = %q{nbenari@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -66,6 +66,9 @@ Gem::Specification.new do |s|
|
|
66
66
|
"lib/sorcery/railties/tasks.rake",
|
67
67
|
"lib/sorcery/sinatra.rb",
|
68
68
|
"lib/sorcery/test_helpers.rb",
|
69
|
+
"lib/sorcery/test_helpers/internal.rb",
|
70
|
+
"lib/sorcery/test_helpers/internal/rails.rb",
|
71
|
+
"lib/sorcery/test_helpers/internal/sinatra.rb",
|
69
72
|
"lib/sorcery/test_helpers/rails.rb",
|
70
73
|
"lib/sorcery/test_helpers/sinatra.rb",
|
71
74
|
"sorcery.gemspec",
|
data/spec/Gemfile
CHANGED
data/spec/Gemfile.lock
CHANGED
@@ -1,7 +1,14 @@
|
|
1
1
|
PATH
|
2
|
-
remote:
|
2
|
+
remote: ../
|
3
3
|
specs:
|
4
|
-
sorcery (0.4.
|
4
|
+
sorcery (0.4.2)
|
5
|
+
bcrypt-ruby (~> 2.1.4)
|
6
|
+
json (>= 1.5.1)
|
7
|
+
oauth (>= 0.4.4)
|
8
|
+
oauth (>= 0.4.4)
|
9
|
+
oauth2 (>= 0.1.1)
|
10
|
+
oauth2 (>= 0.1.1)
|
11
|
+
rails (>= 3.0.0)
|
5
12
|
|
6
13
|
GEM
|
7
14
|
remote: http://rubygems.org/
|
@@ -36,7 +43,7 @@ GEM
|
|
36
43
|
addressable (2.2.4)
|
37
44
|
archive-tar-minitar (0.5.2)
|
38
45
|
arel (2.0.6)
|
39
|
-
bcrypt-ruby (2.1.
|
46
|
+
bcrypt-ruby (2.1.4)
|
40
47
|
builder (2.1.2)
|
41
48
|
columnize (0.3.2)
|
42
49
|
diff-lcs (1.1.2)
|
@@ -47,6 +54,7 @@ GEM
|
|
47
54
|
multipart-post (~> 1.1.0)
|
48
55
|
rack (< 2, >= 1.1.0)
|
49
56
|
i18n (0.5.0)
|
57
|
+
json (1.5.1)
|
50
58
|
linecache19 (0.5.11)
|
51
59
|
ruby_core_source (>= 0.1.4)
|
52
60
|
mail (2.2.13)
|
@@ -118,4 +126,4 @@ DEPENDENCIES
|
|
118
126
|
rspec (~> 2.5.0)
|
119
127
|
ruby-debug19
|
120
128
|
simplecov (>= 0.3.8)
|
121
|
-
sorcery (
|
129
|
+
sorcery (>= 0.1.0)!
|
data/spec/rails3/Gemfile
CHANGED
data/spec/rails3/Gemfile.lock
CHANGED
@@ -2,7 +2,7 @@ PATH
|
|
2
2
|
remote: ../../../
|
3
3
|
specs:
|
4
4
|
oauth (0.4.4)
|
5
|
-
sorcery (0.4.
|
5
|
+
sorcery (0.4.2)
|
6
6
|
bcrypt-ruby (~> 2.1.4)
|
7
7
|
json (>= 1.5.1)
|
8
8
|
oauth (>= 0.4.4)
|
@@ -131,6 +131,6 @@ DEPENDENCIES
|
|
131
131
|
rspec-rails (~> 2.5.0)
|
132
132
|
ruby-debug19
|
133
133
|
simplecov (>= 0.3.8)
|
134
|
-
sorcery (
|
134
|
+
sorcery (>= 0.1.0)!
|
135
135
|
sqlite3-ruby
|
136
136
|
timecop
|
@@ -22,10 +22,8 @@ describe ApplicationController do
|
|
22
22
|
after(:each) do
|
23
23
|
User.delete_all
|
24
24
|
end
|
25
|
-
|
26
|
-
|
27
|
-
subject.should respond_to(:current_users)
|
28
|
-
end
|
25
|
+
|
26
|
+
specify { subject.should respond_to(:current_users) }
|
29
27
|
|
30
28
|
it "'current_users' should be empty when no users are logged in" do
|
31
29
|
subject.current_users.size.should == 0
|
@@ -31,7 +31,7 @@ describe ApplicationController do
|
|
31
31
|
ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/external")
|
32
32
|
end
|
33
33
|
# ----------------- OAuth -----------------------
|
34
|
-
describe ApplicationController, "'
|
34
|
+
describe ApplicationController, "'using external API to login'" do
|
35
35
|
|
36
36
|
before(:each) do
|
37
37
|
stub_all_oauth_requests!
|
@@ -64,7 +64,7 @@ describe ApplicationController do
|
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
-
describe ApplicationController, "'create_from'" do
|
67
|
+
describe ApplicationController, "using 'create_from'" do
|
68
68
|
before(:each) do
|
69
69
|
stub_all_oauth_requests!
|
70
70
|
User.delete_all
|
@@ -90,7 +90,7 @@ describe ApplicationController do
|
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
93
|
-
describe ApplicationController, "OAuth with User Activation features" do
|
93
|
+
describe ApplicationController, "using OAuth with User Activation features" do
|
94
94
|
before(:all) do
|
95
95
|
ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/activation")
|
96
96
|
sorcery_reload!([:user_activation,:external], :user_activation_mailer => ::SorceryMailer)
|
@@ -29,26 +29,27 @@ describe ApplicationController do
|
|
29
29
|
response.should be_a_redirect
|
30
30
|
end
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
32
|
+
context "with 'session_timeout_from_last_action'" do
|
33
|
+
it "should not logout if there was activity" do
|
34
|
+
sorcery_controller_property_set(:session_timeout_from_last_action, true)
|
35
|
+
get :test_login, :username => 'gizmo', :password => 'secret'
|
36
|
+
Timecop.travel(Time.now+0.3)
|
37
|
+
get :test_should_be_logged_in
|
38
|
+
session[:user_id].should_not be_nil
|
39
|
+
Timecop.travel(Time.now+0.3)
|
40
|
+
get :test_should_be_logged_in
|
41
|
+
session[:user_id].should_not be_nil
|
42
|
+
response.should be_a_success
|
43
|
+
end
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
45
|
+
it "with 'session_timeout_from_last_action' should logout if there was no activity" do
|
46
|
+
sorcery_controller_property_set(:session_timeout_from_last_action, true)
|
47
|
+
get :test_login, :username => 'gizmo', :password => 'secret'
|
48
|
+
Timecop.travel(Time.now+0.6)
|
49
|
+
get :test_should_be_logged_in
|
50
|
+
session[:user_id].should be_nil
|
51
|
+
response.should be_a_redirect
|
52
|
+
end
|
51
53
|
end
|
52
|
-
|
53
54
|
end
|
54
55
|
end
|
@@ -37,21 +37,13 @@ describe ApplicationController do
|
|
37
37
|
sorcery_controller_property_set(:user_class, User)
|
38
38
|
end
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
it "should respond to the instance method logout" do
|
45
|
-
should respond_to(:logout)
|
46
|
-
end
|
40
|
+
specify { should respond_to(:login) }
|
41
|
+
|
42
|
+
specify { should respond_to(:logout) }
|
47
43
|
|
48
|
-
|
49
|
-
should respond_to(:logged_in?)
|
50
|
-
end
|
44
|
+
specify { should respond_to(:logged_in?) }
|
51
45
|
|
52
|
-
|
53
|
-
should respond_to(:current_user)
|
54
|
-
end
|
46
|
+
specify { should respond_to(:current_user) }
|
55
47
|
|
56
48
|
it "login(username,password) should return the user when success and set the session with user.id" do
|
57
49
|
get :test_login, :username => 'gizmo', :password => 'secret'
|
@@ -93,9 +85,7 @@ describe ApplicationController do
|
|
93
85
|
subject.current_user.should == false
|
94
86
|
end
|
95
87
|
|
96
|
-
|
97
|
-
should respond_to(:require_login)
|
98
|
-
end
|
88
|
+
specify { should respond_to(:require_login) }
|
99
89
|
|
100
90
|
it "should call the configured 'not_authenticated_action' when authenticate before_filter fails" do
|
101
91
|
session[:user_id] = nil
|
@@ -57,23 +57,17 @@ describe "User with activation submodule" do
|
|
57
57
|
sorcery_reload!([:user_activation], :user_activation_mailer => ::SorceryMailer)
|
58
58
|
end
|
59
59
|
|
60
|
-
|
60
|
+
before(:each) do
|
61
61
|
create_new_user
|
62
|
-
@user.activation_token.should_not be_nil
|
63
62
|
end
|
64
63
|
|
65
64
|
it "should initialize user state to 'pending'" do
|
66
|
-
create_new_user
|
67
65
|
@user.activation_state.should == "pending"
|
68
66
|
end
|
69
67
|
|
70
|
-
|
71
|
-
create_new_user
|
72
|
-
@user.should respond_to(:activate!)
|
73
|
-
end
|
68
|
+
specify { @user.should respond_to(:activate!) }
|
74
69
|
|
75
70
|
it "should clear activation code and change state to 'active' on activation" do
|
76
|
-
create_new_user
|
77
71
|
activation_token = @user.activation_token
|
78
72
|
@user.activate!
|
79
73
|
@user2 = User.find(@user.id) # go to db to make sure it was saved and not just in memory
|
@@ -89,7 +83,6 @@ describe "User with activation submodule" do
|
|
89
83
|
end
|
90
84
|
|
91
85
|
it "subsequent saves do not send activation email" do
|
92
|
-
create_new_user
|
93
86
|
old_size = ActionMailer::Base.deliveries.size
|
94
87
|
@user.username = "Shauli"
|
95
88
|
@user.save!
|
@@ -97,14 +90,12 @@ describe "User with activation submodule" do
|
|
97
90
|
end
|
98
91
|
|
99
92
|
it "should send the user an activation success email on successful activation" do
|
100
|
-
create_new_user
|
101
93
|
old_size = ActionMailer::Base.deliveries.size
|
102
94
|
@user.activate!
|
103
95
|
ActionMailer::Base.deliveries.size.should == old_size + 1
|
104
96
|
end
|
105
97
|
|
106
98
|
it "subsequent saves do not send activation success email" do
|
107
|
-
create_new_user
|
108
99
|
@user.activate!
|
109
100
|
old_size = ActionMailer::Base.deliveries.size
|
110
101
|
@user.username = "Shauli"
|
@@ -121,7 +112,6 @@ describe "User with activation submodule" do
|
|
121
112
|
|
122
113
|
it "activation success email is optional" do
|
123
114
|
sorcery_model_property_set(:activation_success_email_method_name, nil)
|
124
|
-
create_new_user
|
125
115
|
old_size = ActionMailer::Base.deliveries.size
|
126
116
|
@user.activate!
|
127
117
|
ActionMailer::Base.deliveries.size.should == old_size
|
@@ -21,13 +21,8 @@ describe "User with brute_force_protection submodule" do
|
|
21
21
|
User.sorcery_config.reset!
|
22
22
|
end
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
it "should respond to 'lock_expires_at'" do
|
29
|
-
@user.should respond_to(:failed_logins_count)
|
30
|
-
end
|
24
|
+
specify { @user.should respond_to(:failed_logins_count) }
|
25
|
+
specify { @user.should respond_to(:lock_expires_at) }
|
31
26
|
|
32
27
|
it "should enable configuration option 'failed_logins_count_attribute_name'" do
|
33
28
|
sorcery_model_property_set(:failed_logins_count_attribute_name, :my_count)
|
@@ -49,28 +44,5 @@ describe "User with brute_force_protection submodule" do
|
|
49
44
|
User.sorcery_config.login_lock_time_period.should == 2.hours
|
50
45
|
end
|
51
46
|
end
|
52
|
-
|
53
|
-
# ----------------- PLUGIN ACTIVATED -----------------------
|
54
|
-
describe User, "when activated with sorcery" do
|
55
|
-
|
56
|
-
before(:all) do
|
57
|
-
sorcery_reload!([:brute_force_protection])
|
58
|
-
end
|
59
|
-
|
60
|
-
before(:each) do
|
61
|
-
User.delete_all
|
62
|
-
end
|
63
|
-
|
64
|
-
# it "should increment failed_logins_count on a failed login" do
|
65
|
-
# create_new_user
|
66
|
-
#
|
67
|
-
# end
|
68
|
-
#
|
69
|
-
# it "should set lock expiry (effectively lock user) when failed_logins_count reaches max within max period" do
|
70
|
-
# create_new_user
|
71
|
-
# @user.lock_expires_at.should == Time.now.utc + 30
|
72
|
-
# end
|
73
|
-
|
74
|
-
end
|
75
47
|
|
76
48
|
end
|
@@ -13,6 +13,7 @@ describe "User with remember_me submodule" do
|
|
13
13
|
describe User, "loaded plugin configuration" do
|
14
14
|
before(:all) do
|
15
15
|
sorcery_reload!([:remember_me])
|
16
|
+
create_new_user
|
16
17
|
end
|
17
18
|
|
18
19
|
after(:each) do
|
@@ -29,32 +30,23 @@ describe "User with remember_me submodule" do
|
|
29
30
|
User.sorcery_config.remember_me_token_expires_at_attribute_name.should equal(:my_expires)
|
30
31
|
end
|
31
32
|
|
32
|
-
|
33
|
-
create_new_user
|
34
|
-
@user.should respond_to(:remember_me!)
|
35
|
-
end
|
33
|
+
specify { @user.should respond_to(:remember_me!) }
|
36
34
|
|
37
|
-
|
38
|
-
create_new_user
|
39
|
-
@user.should respond_to(:forget_me!)
|
40
|
-
end
|
35
|
+
specify { @user.should respond_to(:forget_me!) }
|
41
36
|
|
42
37
|
it "should generate a new token on 'remember_me!'" do
|
43
|
-
create_new_user
|
44
38
|
@user.remember_me_token.should be_nil
|
45
39
|
@user.remember_me!
|
46
40
|
@user.remember_me_token.should_not be_nil
|
47
41
|
end
|
48
42
|
|
49
43
|
it "should set an expiration based on 'remember_me_for' attribute" do
|
50
|
-
create_new_user
|
51
44
|
sorcery_model_property_set(:remember_me_for, 2 * 60 * 60 * 24)
|
52
45
|
@user.remember_me!
|
53
46
|
@user.remember_me_token_expires_at.to_s.should == (Time.now + 2 * 60 * 60 * 24).utc.to_s
|
54
47
|
end
|
55
48
|
|
56
49
|
it "should delete the token and expiration on 'forget_me!'" do
|
57
|
-
create_new_user
|
58
50
|
@user.remember_me!
|
59
51
|
@user.remember_me_token.should_not be_nil
|
60
52
|
@user.forget_me!
|
@@ -20,21 +20,20 @@ describe "User with reset_password submodule" do
|
|
20
20
|
User.sorcery_config.reset!
|
21
21
|
end
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
@user.should respond_to(:reset_password!)
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
User.should respond_to(:load_from_reset_password_token)
|
23
|
+
context "API" do
|
24
|
+
before(:all) do
|
25
|
+
create_new_user
|
26
|
+
end
|
27
|
+
|
28
|
+
specify { @user.should respond_to(:deliver_reset_password_instructions!) }
|
29
|
+
|
30
|
+
specify { @user.should respond_to(:reset_password!) }
|
31
|
+
|
32
|
+
it "should respond to .load_from_reset_password_token" do
|
33
|
+
User.should respond_to(:load_from_reset_password_token)
|
34
|
+
end
|
36
35
|
end
|
37
|
-
|
36
|
+
|
38
37
|
it "should allow configuration option 'reset_password_token_attribute_name'" do
|
39
38
|
sorcery_model_property_set(:reset_password_token_attribute_name, :my_code)
|
40
39
|
User.sorcery_config.reset_password_token_attribute_name.should equal(:my_code)
|
@@ -9,6 +9,9 @@ describe "User with no submodules (core)" do
|
|
9
9
|
describe User, "when app has plugin loaded" do
|
10
10
|
it "should respond to the plugin activation class method" do
|
11
11
|
ActiveRecord::Base.should respond_to(:authenticates_with_sorcery!)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "User should respond_to .authenticates_with_sorcery!" do
|
12
15
|
User.should respond_to(:authenticates_with_sorcery!)
|
13
16
|
end
|
14
17
|
end
|
@@ -109,8 +112,21 @@ describe "User with no submodules (core)" do
|
|
109
112
|
User.authenticate(@user.send(User.sorcery_config.username_attribute_name), 'wrong!').should be_false
|
110
113
|
end
|
111
114
|
|
112
|
-
|
113
|
-
|
115
|
+
specify { User.should respond_to(:encrypt) }
|
116
|
+
|
117
|
+
it "subclass should inherit config if defined so" do
|
118
|
+
sorcery_reload!([],{:subclasses_inherit_config => true})
|
119
|
+
class Admin < User
|
120
|
+
end
|
121
|
+
Admin.sorcery_config.should_not be_nil
|
122
|
+
Admin.sorcery_config.should == User.sorcery_config
|
123
|
+
end
|
124
|
+
|
125
|
+
it "subclass should not inherit config if not defined so" do
|
126
|
+
sorcery_reload!([],{:subclasses_inherit_config => false})
|
127
|
+
class Admin2 < User
|
128
|
+
end
|
129
|
+
Admin2.sorcery_config.should be_nil
|
114
130
|
end
|
115
131
|
end
|
116
132
|
|
data/spec/sinatra/Gemfile
CHANGED
data/spec/sinatra/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ../../
|
3
3
|
specs:
|
4
|
-
sorcery (0.4.
|
4
|
+
sorcery (0.4.2)
|
5
5
|
bcrypt-ruby (~> 2.1.4)
|
6
6
|
json (>= 1.5.1)
|
7
7
|
oauth (>= 0.4.4)
|
@@ -129,6 +129,6 @@ DEPENDENCIES
|
|
129
129
|
ruby-debug19
|
130
130
|
simplecov (>= 0.3.8)
|
131
131
|
sinatra (>= 1.2.0)
|
132
|
-
sorcery (
|
132
|
+
sorcery (>= 0.1.0)!
|
133
133
|
sqlite3-ruby
|
134
134
|
timecop
|
@@ -28,29 +28,30 @@ describe Sinatra::Application do
|
|
28
28
|
last_response.should be_a_redirect
|
29
29
|
end
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
31
|
+
context "with 'session_timeout_from_last_action'" do
|
32
|
+
it "should not logout if there was activity" do
|
33
|
+
session[:user_id] = nil
|
34
|
+
sorcery_controller_property_set(:session_timeout,2)
|
35
|
+
sorcery_controller_property_set(:session_timeout_from_last_action, true)
|
36
|
+
get "/test_login", :username => 'gizmo', :password => 'secret'
|
37
|
+
Timecop.travel(Time.now+1)
|
38
|
+
get "/test_should_be_logged_in"
|
39
|
+
session[:user_id].should_not be_nil
|
40
|
+
Timecop.travel(Time.now+1)
|
41
|
+
get "/test_should_be_logged_in"
|
42
|
+
session[:user_id].should_not be_nil
|
43
|
+
last_response.should be_ok
|
44
|
+
end
|
44
45
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
46
|
+
it "should logout if there was no activity" do
|
47
|
+
sorcery_controller_property_set(:session_timeout,0.5)
|
48
|
+
sorcery_controller_property_set(:session_timeout_from_last_action, true)
|
49
|
+
get "/test_login", :username => 'gizmo', :password => 'secret'
|
50
|
+
Timecop.travel(Time.now+0.6)
|
51
|
+
get "/test_should_be_logged_in"
|
52
|
+
session[:user_id].should be_nil
|
53
|
+
last_response.should be_a_redirect
|
54
|
+
end
|
53
55
|
end
|
54
|
-
|
55
56
|
end
|
56
57
|
end
|
@@ -20,8 +20,9 @@ end
|
|
20
20
|
|
21
21
|
Rspec.configure do |config|
|
22
22
|
config.send(:include, RSpecMixinExample)
|
23
|
-
config.send(:include, ::Sorcery::TestHelpers)
|
24
23
|
config.send(:include, ::Sorcery::TestHelpers::Sinatra)
|
24
|
+
config.send(:include, ::Sorcery::TestHelpers::Internal)
|
25
|
+
config.send(:include, ::Sorcery::TestHelpers::Internal::Sinatra)
|
25
26
|
config.before(:suite) do
|
26
27
|
ActiveRecord::Migrator.migrate("#{APP_ROOT}/db/migrate/core")
|
27
28
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: sorcery
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.4.
|
5
|
+
version: 0.4.2
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Noam Ben Ari
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-04-
|
13
|
+
date: 2011-04-30 00:00:00 +03:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -248,6 +248,9 @@ files:
|
|
248
248
|
- lib/sorcery/railties/tasks.rake
|
249
249
|
- lib/sorcery/sinatra.rb
|
250
250
|
- lib/sorcery/test_helpers.rb
|
251
|
+
- lib/sorcery/test_helpers/internal.rb
|
252
|
+
- lib/sorcery/test_helpers/internal/rails.rb
|
253
|
+
- lib/sorcery/test_helpers/internal/sinatra.rb
|
251
254
|
- lib/sorcery/test_helpers/rails.rb
|
252
255
|
- lib/sorcery/test_helpers/sinatra.rb
|
253
256
|
- sorcery.gemspec
|