authem 1.5.0 → 2.0.0
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.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +6 -0
- data/Appraisals +12 -0
- data/CHANGELOG.md +42 -0
- data/Gemfile +10 -0
- data/README.markdown +15 -1
- data/Rakefile +11 -5
- data/authem.gemspec +25 -0
- data/gemfiles/rails_4.0.gemfile +16 -0
- data/gemfiles/rails_4.1.gemfile +15 -0
- data/lib/authem.rb +4 -10
- data/lib/authem/controller.rb +50 -0
- data/lib/authem/errors/ambigous_role.rb +8 -0
- data/lib/authem/errors/unknown_role.rb +7 -0
- data/lib/authem/railtie.rb +12 -0
- data/lib/authem/role.rb +62 -0
- data/lib/authem/session.rb +41 -0
- data/lib/authem/support.rb +129 -0
- data/lib/authem/token.rb +5 -5
- data/lib/authem/user.rb +27 -13
- data/lib/authem/version.rb +1 -1
- data/lib/generators/authem/session/session_generator.rb +12 -0
- data/lib/generators/authem/session/templates/create_sessions.rb +15 -0
- data/lib/generators/authem/user/templates/create_table_migration.rb +22 -0
- data/lib/generators/authem/user/templates/model.rb +11 -0
- data/lib/generators/authem/user/user_generator.rb +13 -0
- data/spec/controller_spec.rb +413 -0
- data/spec/session_spec.rb +52 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/support/active_record.rb +45 -0
- data/spec/support/i18n.rb +1 -0
- data/spec/support/time.rb +1 -0
- data/spec/token_spec.rb +10 -0
- data/spec/user_spec.rb +115 -0
- metadata +42 -112
- data/lib/authem/base_user.rb +0 -54
- data/lib/authem/config.rb +0 -21
- data/lib/authem/controller_support.rb +0 -51
- data/lib/authem/sorcery_user.rb +0 -24
- data/lib/generators/authem/model/model_generator.rb +0 -23
data/lib/authem/token.rb
CHANGED
data/lib/authem/user.rb
CHANGED
@@ -1,21 +1,35 @@
|
|
1
|
-
|
2
|
-
extend ::ActiveSupport::Concern
|
3
|
-
include Authem::BaseUser
|
1
|
+
require "authem/token"
|
4
2
|
|
5
|
-
|
6
|
-
|
3
|
+
module Authem
|
4
|
+
module User
|
5
|
+
extend ActiveSupport::Concern
|
7
6
|
|
8
|
-
|
7
|
+
included do
|
8
|
+
has_many :authem_sessions, as: :subject, class_name: "Authem::Session"
|
9
|
+
has_secure_password
|
9
10
|
|
10
|
-
|
11
|
+
validates :email,
|
12
|
+
uniqueness: true,
|
13
|
+
presence: true,
|
14
|
+
format: { with: /\A\S+@\S+\z/, allow_blank: true }
|
11
15
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
16
|
+
before_create{ self.password_reset_token = Authem::Token.generate }
|
17
|
+
end
|
18
|
+
|
19
|
+
def email=(value)
|
20
|
+
super value.try(:downcase)
|
21
|
+
end
|
22
|
+
|
23
|
+
def reset_password(password, confirmation)
|
24
|
+
if password.blank?
|
25
|
+
errors.add :password, :blank
|
26
|
+
return false
|
17
27
|
end
|
28
|
+
|
29
|
+
self.password = password
|
30
|
+
self.password_confirmation = confirmation
|
31
|
+
|
32
|
+
update_column :password_reset_token, Authem::Token.generate if save
|
18
33
|
end
|
19
34
|
end
|
20
|
-
|
21
35
|
end
|
data/lib/authem/version.rb
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
require "rails/generators/active_record"
|
2
|
+
|
3
|
+
module Authem
|
4
|
+
class SessionGenerator < ActiveRecord::Generators::Base
|
5
|
+
argument :name, type: :string, default: 'unused but required by activerecord'
|
6
|
+
source_root File.expand_path("../templates", __FILE__)
|
7
|
+
|
8
|
+
def copy_session_migration
|
9
|
+
migration_template "create_sessions.rb", "db/migrate/create_authem_sessions.rb"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class CreateAuthemSessions < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :authem_sessions do |t|
|
4
|
+
t.string :role, null: false
|
5
|
+
t.references :subject, null: false, polymorphic: true
|
6
|
+
t.string :token, null: false, limit: 60
|
7
|
+
t.datetime :expires_at, null: false
|
8
|
+
t.integer :ttl, null: false
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
|
12
|
+
add_index :authem_sessions, %i[expires_at token], unique: true
|
13
|
+
add_index :authem_sessions, %i[expires_at subject_type subject_id], name: 'index_authem_sessions_subject'
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class <%= migration_class_name %> < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :<%= table_name %> do |t|
|
4
|
+
t.string :email, null: false
|
5
|
+
t.string :password_digest, null: false
|
6
|
+
t.string :password_reset_token, null: false, limit: 60
|
7
|
+
<% attributes.each do |attribute| -%>
|
8
|
+
<% if attribute.password_digest? -%>
|
9
|
+
t.string :password_digest<%= attribute.inject_options %>
|
10
|
+
<% else -%>
|
11
|
+
t.<%= attribute.type %> :<%= attribute.name %><%= attribute.inject_options %>
|
12
|
+
<% end -%>
|
13
|
+
<% end -%>
|
14
|
+
<% if options[:timestamps] %>
|
15
|
+
t.timestamps
|
16
|
+
<% end -%>
|
17
|
+
end
|
18
|
+
<% attributes_with_index.each do |attribute| -%>
|
19
|
+
add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
|
20
|
+
<% end -%>
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<% module_namespacing do -%>
|
2
|
+
class <%= class_name %> < <%= parent_class_name.classify %>
|
3
|
+
include Authem::User
|
4
|
+
<% attributes.select(&:reference?).each do |attribute| -%>
|
5
|
+
belongs_to :<%= attribute.name %><%= ', polymorphic: true' if attribute.polymorphic? %>
|
6
|
+
<% end -%>
|
7
|
+
<% if attributes.any?(&:password_digest?) -%>
|
8
|
+
has_secure_password
|
9
|
+
<% end -%>
|
10
|
+
end
|
11
|
+
<% end -%>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "rails/generators/active_record/model/model_generator"
|
2
|
+
|
3
|
+
module Authem
|
4
|
+
class UserGenerator < ActiveRecord::Generators::ModelGenerator
|
5
|
+
source_root File.expand_path("../templates", __FILE__)
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def migration_template(_, migration_file_name)
|
10
|
+
super "create_table_migration.rb", migration_file_name
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,413 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Authem::Controller do
|
4
|
+
class User < ActiveRecord::Base
|
5
|
+
self.table_name = :users
|
6
|
+
end
|
7
|
+
|
8
|
+
module MyNamespace
|
9
|
+
class SuperUser < ActiveRecord::Base
|
10
|
+
self.table_name = :users
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class BaseController
|
15
|
+
include Authem::Controller
|
16
|
+
|
17
|
+
class << self
|
18
|
+
def helper_methods_list
|
19
|
+
@helper_methods_list ||= []
|
20
|
+
end
|
21
|
+
|
22
|
+
def helper_method(*methods)
|
23
|
+
helper_methods_list.concat methods
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def clear_session!
|
28
|
+
session.clear
|
29
|
+
end
|
30
|
+
|
31
|
+
def reloaded
|
32
|
+
original_session, original_cookies = session, cookies
|
33
|
+
|
34
|
+
self.class.new.tap do |controller|
|
35
|
+
controller.class_eval do
|
36
|
+
define_method(:session){ original_session }
|
37
|
+
define_method(:cookies){ original_cookies }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def session
|
45
|
+
@_session ||= HashWithIndifferentAccess.new
|
46
|
+
end
|
47
|
+
|
48
|
+
def cookies
|
49
|
+
@_cookies ||= Cookies.new
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class Cookies < HashWithIndifferentAccess
|
54
|
+
attr_reader :expires_at
|
55
|
+
|
56
|
+
def permanent
|
57
|
+
self
|
58
|
+
end
|
59
|
+
|
60
|
+
alias_method :signed, :permanent
|
61
|
+
|
62
|
+
def []=(key, value)
|
63
|
+
if value.kind_of?(Hash) && value.key?(:expires)
|
64
|
+
@expires_at = value[:expires]
|
65
|
+
super key, value.fetch(:value)
|
66
|
+
else
|
67
|
+
super
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def delete(key, *)
|
72
|
+
super key
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def build_controller
|
77
|
+
controller_klass.new
|
78
|
+
end
|
79
|
+
|
80
|
+
let(:controller){ build_controller.tap{ |c| allow(c).to receive(:request){ request }}}
|
81
|
+
let(:view_helpers){ controller_klass.helper_methods_list }
|
82
|
+
let(:cookies){ controller.send(:cookies) }
|
83
|
+
let(:session){ controller.send(:session) }
|
84
|
+
let(:reloaded_controller){ controller.reloaded }
|
85
|
+
let(:request_url){ "http://example.com/foo" }
|
86
|
+
let(:request){ double("Request", url: request_url, xhr?: false) }
|
87
|
+
|
88
|
+
context "with one role" do
|
89
|
+
let(:user){ User.create(email: "joe@example.com") }
|
90
|
+
let(:controller_klass){ Class.new(BaseController){ authem_for :user }}
|
91
|
+
|
92
|
+
it "has current_user method" do
|
93
|
+
expect(controller).to respond_to(:current_user)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "has sign_in_user method" do
|
97
|
+
expect(controller).to respond_to(:sign_in_user)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "has clear_all_user_sessions_for method" do
|
101
|
+
expect(controller).to respond_to(:clear_all_user_sessions_for)
|
102
|
+
end
|
103
|
+
|
104
|
+
it "has require_user method" do
|
105
|
+
expect(controller).to respond_to(:require_user)
|
106
|
+
end
|
107
|
+
|
108
|
+
it "has user_signed_in? method" do
|
109
|
+
expect(controller).to respond_to(:user_signed_in?)
|
110
|
+
end
|
111
|
+
|
112
|
+
it "has redirect_back_or_to method" do
|
113
|
+
expect(controller).to respond_to(:redirect_back_or_to)
|
114
|
+
end
|
115
|
+
|
116
|
+
it "can clear all sessions using clear_all_sessions method" do
|
117
|
+
expect(controller).to receive(:clear_all_user_sessions_for).with(user)
|
118
|
+
controller.clear_all_sessions_for user
|
119
|
+
end
|
120
|
+
|
121
|
+
it "defines view helpers" do
|
122
|
+
expect(view_helpers).to include(:current_user)
|
123
|
+
expect(view_helpers).to include(:user_signed_in?)
|
124
|
+
end
|
125
|
+
|
126
|
+
it "raises error when calling clear_all_sessions_for with nil" do
|
127
|
+
expect{ controller.clear_all_sessions_for nil }.to raise_error(ArgumentError)
|
128
|
+
expect{ controller.clear_all_user_sessions_for nil }.to raise_error(ArgumentError)
|
129
|
+
end
|
130
|
+
|
131
|
+
it "can sign in user using sign_in_user method" do
|
132
|
+
controller.sign_in_user user
|
133
|
+
expect(controller.current_user).to eq(user)
|
134
|
+
expect(reloaded_controller.current_user).to eq(user)
|
135
|
+
end
|
136
|
+
|
137
|
+
it "can show status of current session with user_signed_in? method" do
|
138
|
+
expect{ controller.sign_in user }.to change(controller, :user_signed_in?).from(false).to(true)
|
139
|
+
expect{ controller.sign_out user }.to change(controller, :user_signed_in?).from(true).to(false)
|
140
|
+
end
|
141
|
+
|
142
|
+
it "can store session token in a cookie when :remember option is used" do
|
143
|
+
expect{ controller.sign_in user, remember: true }.to change(cookies, :size).by(1)
|
144
|
+
end
|
145
|
+
|
146
|
+
it "throws NotImplementedError when require strategy is not defined" do
|
147
|
+
message = "No strategy for require_user defined. Please define `deny_user_access` method in your controller"
|
148
|
+
expect{ controller.require_user }.to raise_error(NotImplementedError, message)
|
149
|
+
end
|
150
|
+
|
151
|
+
it "can require authenticated user with require_user method" do
|
152
|
+
def controller.deny_user_access; redirect_to :custom_path; end
|
153
|
+
expect(controller).to receive(:redirect_to).with(:custom_path)
|
154
|
+
expect{ controller.require_user }.to change{ session[:return_to_url] }.from(nil).to(request_url)
|
155
|
+
end
|
156
|
+
|
157
|
+
it "sets cookie expiration date when :remember options is used" do
|
158
|
+
controller.sign_in user, remember: true, ttl: 1.week
|
159
|
+
expect(cookies.expires_at).to be_within(1.second).of(1.week.from_now)
|
160
|
+
end
|
161
|
+
|
162
|
+
it "can restore user from cookie when session is lost" do
|
163
|
+
controller.sign_in user, remember: true
|
164
|
+
controller.clear_session!
|
165
|
+
expect(controller.reloaded.current_user).to eq(user)
|
166
|
+
end
|
167
|
+
|
168
|
+
it "does not use cookies by default" do
|
169
|
+
expect{ controller.sign_in user }.not_to change(cookies, :size)
|
170
|
+
end
|
171
|
+
|
172
|
+
it "returns session object on sign in" do
|
173
|
+
result = controller.sign_in_user(user)
|
174
|
+
expect(result).to be_kind_of(::Authem::Session)
|
175
|
+
end
|
176
|
+
|
177
|
+
it "allows to specify ttl using sign_in_user with ttl option" do
|
178
|
+
session = controller.sign_in_user(user, ttl: 40.minutes)
|
179
|
+
expect(session.ttl).to eq(40.minutes)
|
180
|
+
end
|
181
|
+
|
182
|
+
it "forgets user after session has expired" do
|
183
|
+
session = controller.sign_in(user)
|
184
|
+
session.update_column :expires_at, 1.minute.ago
|
185
|
+
expect(reloaded_controller.current_user).to be_nil
|
186
|
+
end
|
187
|
+
|
188
|
+
it "renews session ttl each time it is used" do
|
189
|
+
session = controller.sign_in(user, ttl: 1.day)
|
190
|
+
session.update_column :expires_at, 1.minute.from_now
|
191
|
+
reloaded_controller.current_user
|
192
|
+
expect(session.reload.expires_at).to be_within(1.second).of(1.day.from_now)
|
193
|
+
end
|
194
|
+
|
195
|
+
it "renews cookie expiration date each time it is used" do
|
196
|
+
session = controller.sign_in(user, ttl: 1.day, remember: true)
|
197
|
+
session.update_column :ttl, 30.days
|
198
|
+
reloaded_controller.current_user
|
199
|
+
expect(cookies.expires_at).to be_within(1.second).of(30.days.from_now)
|
200
|
+
end
|
201
|
+
|
202
|
+
it "can sign in using sign_in method" do
|
203
|
+
expect(controller).to receive(:sign_in_user).with(user, {})
|
204
|
+
controller.sign_in user
|
205
|
+
end
|
206
|
+
|
207
|
+
it "allows to specify ttl using sign_in method with ttl option" do
|
208
|
+
session = controller.sign_in(user, ttl: 40.minutes)
|
209
|
+
expect(session.ttl).to eq(40.minutes)
|
210
|
+
end
|
211
|
+
|
212
|
+
it "raises an error when trying to sign in unknown model" do
|
213
|
+
model = MyNamespace::SuperUser.create(email: "admin@example.com")
|
214
|
+
message = "Unknown authem role: #{model.inspect}"
|
215
|
+
expect{ controller.sign_in model }.to raise_error(Authem::UnknownRoleError, message)
|
216
|
+
end
|
217
|
+
|
218
|
+
it "raises an error when trying to sign in nil" do
|
219
|
+
expect{ controller.sign_in nil }.to raise_error(ArgumentError)
|
220
|
+
expect{ controller.sign_in_user nil }.to raise_error(ArgumentError)
|
221
|
+
end
|
222
|
+
|
223
|
+
it "has sign_out_user method" do
|
224
|
+
expect(controller).to respond_to(:sign_out_user)
|
225
|
+
end
|
226
|
+
|
227
|
+
context "when user is signed in" do
|
228
|
+
let(:sign_in_options){ Hash.new }
|
229
|
+
|
230
|
+
before do
|
231
|
+
controller.sign_in user, sign_in_options
|
232
|
+
expect(controller.current_user).to eq(user)
|
233
|
+
end
|
234
|
+
|
235
|
+
after do
|
236
|
+
expect(controller.current_user).to be_nil
|
237
|
+
expect(reloaded_controller.current_user).to be_nil
|
238
|
+
end
|
239
|
+
|
240
|
+
it "can sign out using sign_out_user method" do
|
241
|
+
controller.sign_out_user
|
242
|
+
end
|
243
|
+
|
244
|
+
it "can sign out using sign_out method" do
|
245
|
+
controller.sign_out user
|
246
|
+
end
|
247
|
+
|
248
|
+
context "with cookies" do
|
249
|
+
let(:sign_in_options){{ remember: true }}
|
250
|
+
|
251
|
+
after{ expect(cookies).to be_empty }
|
252
|
+
|
253
|
+
it "removes session token from cookies on sign out" do
|
254
|
+
controller.sign_out_user
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
context "with multiple sessions across devices" do
|
260
|
+
let(:first_device){ controller }
|
261
|
+
let(:second_device){ build_controller }
|
262
|
+
|
263
|
+
before do
|
264
|
+
first_device.sign_in user
|
265
|
+
second_device.sign_in user
|
266
|
+
end
|
267
|
+
|
268
|
+
it "signs out all currently active sessions on all devices" do
|
269
|
+
expect{ first_device.clear_all_user_sessions_for user }.to change(Authem::Session, :count).by(-2)
|
270
|
+
expect(second_device.reloaded.current_user).to be_nil
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
it "raises an error when calling sign_out with nil" do
|
275
|
+
expect{ controller.sign_out nil }.to raise_error(ArgumentError)
|
276
|
+
end
|
277
|
+
|
278
|
+
it "persists session in database" do
|
279
|
+
expect{ controller.sign_in user }.to change(Authem::Session, :count).by(1)
|
280
|
+
end
|
281
|
+
|
282
|
+
it "removes database session on sign out" do
|
283
|
+
controller.sign_in user
|
284
|
+
expect{ controller.sign_out user }.to change(Authem::Session, :count).by(-1)
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
context "with multiple roles" do
|
289
|
+
let(:admin){ MyNamespace::SuperUser.create(email: "admin@example.com") }
|
290
|
+
let(:controller_klass) do
|
291
|
+
Class.new(BaseController) do
|
292
|
+
authem_for :user
|
293
|
+
authem_for :admin, model: MyNamespace::SuperUser
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
it "has current_admin method" do
|
298
|
+
expect(controller).to respond_to(:current_admin)
|
299
|
+
end
|
300
|
+
|
301
|
+
it "has sign_in_admin method" do
|
302
|
+
expect(controller).to respond_to(:sign_in_admin)
|
303
|
+
end
|
304
|
+
|
305
|
+
it "can sign in admin using sign_in_admin method" do
|
306
|
+
controller.sign_in_admin admin
|
307
|
+
expect(controller.current_admin).to eq(admin)
|
308
|
+
expect(reloaded_controller.current_admin).to eq(admin)
|
309
|
+
end
|
310
|
+
|
311
|
+
it "can sign in using sign_in method" do
|
312
|
+
expect(controller).to receive(:sign_in_admin).with(admin, {})
|
313
|
+
controller.sign_in admin
|
314
|
+
end
|
315
|
+
|
316
|
+
context "with signed in user and admin" do
|
317
|
+
let(:user){ User.create(email: "joe@example.com") }
|
318
|
+
|
319
|
+
before do
|
320
|
+
controller.sign_in_user user
|
321
|
+
controller.sign_in_admin admin
|
322
|
+
end
|
323
|
+
|
324
|
+
after do
|
325
|
+
expect(controller.current_admin).to eq(admin)
|
326
|
+
expect(reloaded_controller.current_admin).to eq(admin)
|
327
|
+
end
|
328
|
+
|
329
|
+
it "can sign out user separately from admin using sign_out_user" do
|
330
|
+
controller.sign_out_user
|
331
|
+
end
|
332
|
+
|
333
|
+
it "can sign out user separately from admin using sign_out" do
|
334
|
+
controller.sign_out user
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
context "multiple roles with same model class" do
|
340
|
+
let(:user){ User.create(email: "joe@example.com") }
|
341
|
+
let(:customer){ User.create(email: "shmoe@example.com") }
|
342
|
+
let(:controller_klass) do
|
343
|
+
Class.new(BaseController) do
|
344
|
+
authem_for :user
|
345
|
+
authem_for :customer, model: User
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
it "can sign in user separately from customer" do
|
350
|
+
controller.sign_in_user user
|
351
|
+
expect(controller.current_user).to eq(user)
|
352
|
+
expect(controller.current_customer).to be_nil
|
353
|
+
expect(reloaded_controller.current_user).to eq(user)
|
354
|
+
expect(reloaded_controller.current_customer).to be_nil
|
355
|
+
end
|
356
|
+
|
357
|
+
it "can sign in customer and user separately" do
|
358
|
+
controller.sign_in_user user
|
359
|
+
controller.sign_in_customer customer
|
360
|
+
expect(controller.current_user).to eq(user)
|
361
|
+
expect(controller.current_customer).to eq(customer)
|
362
|
+
expect(reloaded_controller.current_user).to eq(user)
|
363
|
+
expect(reloaded_controller.current_customer).to eq(customer)
|
364
|
+
end
|
365
|
+
|
366
|
+
it "raises the error when sign in can't guess the model properly" do
|
367
|
+
message = "Ambigous match for #{user.inspect}: user, customer"
|
368
|
+
expect{ controller.sign_in user }.to raise_error(Authem::AmbigousRoleError, message)
|
369
|
+
end
|
370
|
+
|
371
|
+
it "allows to specify role with special :as option" do
|
372
|
+
expect(controller).to receive(:sign_in_customer).with(user, as: :customer)
|
373
|
+
controller.sign_in user, as: :customer
|
374
|
+
end
|
375
|
+
|
376
|
+
it "raises the error when sign out can't guess the model properly" do
|
377
|
+
message = "Ambigous match for #{user.inspect}: user, customer"
|
378
|
+
expect{ controller.sign_out user }.to raise_error(Authem::AmbigousRoleError, message)
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
context "redirect after authentication" do
|
383
|
+
let(:controller_klass){ Class.new(BaseController){ authem_for :user }}
|
384
|
+
|
385
|
+
context "with saved url" do
|
386
|
+
before{ session[:return_to_url] = :my_url }
|
387
|
+
|
388
|
+
it "redirects back to saved url if it's available" do
|
389
|
+
expect(controller).to receive(:redirect_to).with(:my_url, notice: "foo")
|
390
|
+
controller.redirect_back_or_to :root, notice: "foo"
|
391
|
+
end
|
392
|
+
|
393
|
+
it "removes values from session after successful redirect" do
|
394
|
+
expect(controller).to receive(:redirect_to).with(:my_url, {})
|
395
|
+
expect{ controller.redirect_back_or_to :root }.to change{ session[:return_to_url] }.from(:my_url).to(nil)
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
399
|
+
it "redirects to specified url if there is no saved value" do
|
400
|
+
expect(controller).to receive(:redirect_to).with(:root, notice: "foo")
|
401
|
+
controller.redirect_back_or_to :root, notice: "foo"
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
context "when defining authem" do
|
406
|
+
it "settings do not propagate to parent controller" do
|
407
|
+
parent_klass = Class.new(BaseController){ authem_for :user }
|
408
|
+
child_klass = Class.new(parent_klass){ authem_for :member }
|
409
|
+
expect(child_klass.authem_roles.size).to eq(2)
|
410
|
+
expect(parent_klass.authem_roles.size).to eq(1)
|
411
|
+
end
|
412
|
+
end
|
413
|
+
end
|