authem 2.0.1 → 2.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c768903ff4928e45f93a0df8fa1620a9485a8078
4
- data.tar.gz: 2b9dca77151effe7aa26791163305660d31434bf
3
+ metadata.gz: 7d89fb3efe1897f6405ff311cc4041995c47b87c
4
+ data.tar.gz: 55af0e6279f7222c79453826a938844d06fdff59
5
5
  SHA512:
6
- metadata.gz: cb8715fe07acad644f4784a006b80d308766811b6a9918b4ad3632a2bf6d491750e3941553afbd8001a396bfeb9a7b8db87e0f46cb81be72a005097635559c12
7
- data.tar.gz: 6bd3bb132620135a416ddbe9202353ae9fd732d049843eb37b0b79b6bdfd425c3da0176f4e429868dc92e9d6bfa4583d29b829966aeb63bd21d47bd21d0cf621
6
+ metadata.gz: 1edf72a5c758c9feb280ac87a6edff176d9aebcd49951a72d7f25c7aa26dbfdf3ca516a382ffec2c5d071587780c2943823b7c5a3ee239d84826b4806f3143a0
7
+ data.tar.gz: 9892818aec6d3b5cd73e06cc2bb3648240a1ec418ae5545e52ddc37434fa242dee28b574db96c294775f028e20b905d927240b3ccda815a3afb5e30e1c5fd810
@@ -1,3 +1,15 @@
1
+ ### 2.1.0 ###
2
+
3
+ * Rails 5 compatibility
4
+
5
+ ### 2.0.2 ###
6
+
7
+ * Signing up resets CSRF token [[PR](https://github.com/paulelliott/authem/pull/27)]
8
+
9
+ ### 2.0.1 ###
10
+
11
+ * Add JRuby support
12
+
1
13
  ### 2.0.0 ###
2
14
 
3
15
  * Complete rewrite from scratch
@@ -6,7 +6,7 @@ Authem is an email-based authentication library for ruby web apps.
6
6
 
7
7
  ## Compatibility
8
8
 
9
- Authem requires Ruby 2.0.0 or newer
9
+ Authem requires Ruby 1.9.3 or newer
10
10
 
11
11
  [![Build Status](https://secure.travis-ci.org/paulelliott/authem.png)](http://travis-ci.org/paulelliott/authem)
12
12
  [![Code Climate](https://codeclimate.com/github/paulelliott/authem.png)](https://codeclimate.com/github/paulelliott/authem)
@@ -1,6 +1,14 @@
1
+ require "active_support/all"
1
2
  require "authem/railtie"
2
- require "authem/user"
3
3
  require "authem/version"
4
4
 
5
5
  module Authem
6
+ autoload :Controller, "authem/controller"
7
+ autoload :Role, "authem/role"
8
+ autoload :Session, "authem/session"
9
+ autoload :Support, "authem/support"
10
+ autoload :Token, "authem/token"
11
+ autoload :User, "authem/user"
12
+ autoload :AmbigousRoleError, "authem/errors/ambigous_role"
13
+ autoload :UnknownRoleError, "authem/errors/unknown_role"
6
14
  end
@@ -1,6 +1,3 @@
1
- require "active_support/concern"
2
- require "authem/role"
3
-
4
1
  module Authem
5
2
  module Controller
6
3
  extend ActiveSupport::Concern
@@ -10,6 +7,7 @@ module Authem
10
7
  module SessionManagementMethods
11
8
  def sign_in(model, options={})
12
9
  role = options.fetch(:as){ self.class.authem_role_for(model) }
10
+ session.delete :_csrf_token if session.respond_to?(:delete)
13
11
  public_send "sign_in_#{role}", model, options
14
12
  end
15
13
 
@@ -1,4 +1,3 @@
1
- require "authem/controller"
2
1
  require "rails/railtie"
3
2
 
4
3
  module Authem
@@ -1,10 +1,8 @@
1
- require "authem/support"
2
-
3
1
  module Authem
4
2
  class Role
5
3
  attr_reader :controller, :name, :options
6
4
 
7
- METHODS = %w[current sign_in signed_in? require sign_out clear_for deny_access].map(&:to_sym)
5
+ METHODS = %w[current sign_in signed_in? require_role sign_out clear_for deny_access].map(&:to_sym)
8
6
 
9
7
  METHODS.each do |method_name|
10
8
  define_method method_name do |controller, *args|
@@ -1,5 +1,4 @@
1
1
  require "active_record"
2
- require "authem/token"
3
2
 
4
3
  module Authem
5
4
  class Session < ::ActiveRecord::Base
@@ -1,8 +1,3 @@
1
- require "active_support/core_ext/module/delegation"
2
- require "authem/session"
3
- require "authem/errors/ambigous_role"
4
- require "authem/errors/unknown_role"
5
-
6
1
  module Authem
7
2
  class Support
8
3
  attr_reader :role, :controller
@@ -15,7 +10,7 @@ module Authem
15
10
  if ivar_defined?
16
11
  ivar_get
17
12
  else
18
- ivar_set fetch_subject_by_token
13
+ ivar_set(fetch_subject_by_token)
19
14
  end
20
15
  end
21
16
 
@@ -45,7 +40,7 @@ module Authem
45
40
  Authem::Session.by_subject(record).where(role: role_name).delete_all
46
41
  end
47
42
 
48
- def require
43
+ def require_role
49
44
  unless signed_in?
50
45
  session[:return_to_url] = request.url unless request.xhr?
51
46
  controller.send "deny_#{role_name}_access"
@@ -87,12 +82,11 @@ module Authem
87
82
  end
88
83
 
89
84
  def save_cookie(auth_session)
90
- cookie_value = {
85
+ cookies.signed[key] = {
91
86
  value: auth_session.token,
92
87
  expires: auth_session.expires_at,
93
88
  domain: :all
94
89
  }
95
- cookies.signed[key] = cookie_value
96
90
  end
97
91
 
98
92
  def get_auth_session_by_token(token)
@@ -1,5 +1,3 @@
1
- require "authem/token"
2
-
3
1
  module Authem
4
2
  module User
5
3
  extend ActiveSupport::Concern
@@ -1,3 +1,3 @@
1
1
  module Authem
2
- VERSION = "2.0.1".freeze
2
+ VERSION = "2.1.0".freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: authem
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Elliott
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-09-25 00:00:00.000000000 Z
12
+ date: 2016-03-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -29,14 +29,14 @@ dependencies:
29
29
  name: railties
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - "~>"
32
+ - - ">="
33
33
  - !ruby/object:Gem::Version
34
34
  version: '4.0'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - "~>"
39
+ - - ">="
40
40
  - !ruby/object:Gem::Version
41
41
  version: '4.0'
42
42
  - !ruby/object:Gem::Dependency
@@ -61,20 +61,9 @@ executables: []
61
61
  extensions: []
62
62
  extra_rdoc_files: []
63
63
  files:
64
- - ".gitignore"
65
- - ".rspec"
66
- - ".ruby-gemset"
67
- - ".ruby-version"
68
- - ".travis.yml"
69
- - Appraisals
70
64
  - CHANGELOG.md
71
- - Gemfile
72
65
  - LICENSE
73
- - README.markdown
74
- - Rakefile
75
- - authem.gemspec
76
- - gemfiles/rails_4.0.gemfile
77
- - gemfiles/rails_4.1.gemfile
66
+ - README.md
78
67
  - lib/authem.rb
79
68
  - lib/authem/controller.rb
80
69
  - lib/authem/errors/ambigous_role.rb
@@ -91,14 +80,6 @@ files:
91
80
  - lib/generators/authem/user/templates/create_table_migration.rb
92
81
  - lib/generators/authem/user/templates/model.rb
93
82
  - lib/generators/authem/user/user_generator.rb
94
- - spec/controller_spec.rb
95
- - spec/session_spec.rb
96
- - spec/spec_helper.rb
97
- - spec/support/active_record.rb
98
- - spec/support/i18n.rb
99
- - spec/support/time.rb
100
- - spec/token_spec.rb
101
- - spec/user_spec.rb
102
83
  homepage: https://github.com/paulelliott/authem
103
84
  licenses:
104
85
  - MIT
@@ -119,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
100
  version: '0'
120
101
  requirements: []
121
102
  rubyforge_project:
122
- rubygems_version: 2.4.1
103
+ rubygems_version: 2.5.1
123
104
  signing_key:
124
105
  specification_version: 4
125
106
  summary: Authem authenticates them by email
data/.gitignore DELETED
@@ -1,3 +0,0 @@
1
- pkg
2
- Gemfile.lock
3
- gemfiles/*.lock
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --colour
2
- --format progress
@@ -1 +0,0 @@
1
- authem
@@ -1 +0,0 @@
1
- ruby-2.1.3
@@ -1,8 +0,0 @@
1
- gemfile:
2
- - gemfiles/rails_4.0.gemfile
3
- - gemfiles/rails_4.1.gemfile
4
- rvm:
5
- - jruby-19mode
6
- - 1.9.3
7
- - 2.0.0
8
- - 2.1.1
data/Appraisals DELETED
@@ -1,12 +0,0 @@
1
- appraise "rails-4.1" do
2
- gem "activerecord", "~> 4.1.0", require: "active_record"
3
- gem "bcrypt", "~> 3.1"
4
- gem "railties", "~> 4.0"
5
- end
6
-
7
- appraise "rails-4.0" do
8
- gem "activerecord", "~> 4.0.0", require: "active_record"
9
- gem "bcrypt", "~> 3.1"
10
- gem "railties", "~> 4.0"
11
- gem "protected_attributes"
12
- end
data/Gemfile DELETED
@@ -1,11 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gem "appraisal"
4
-
5
- group :test do
6
- gem "rspec", "~> 3.0"
7
- gem "rake", "~> 10.3"
8
- gem "sqlite3", platform: :ruby
9
- gem "activerecord-jdbcsqlite3-adapter", platform: :jruby
10
- gem "pry"
11
- end
data/Rakefile DELETED
@@ -1,12 +0,0 @@
1
- require "bundler/setup"
2
- require "bundler/gem_tasks"
3
-
4
- if !ENV["APPRAISAL_INITIALIZED"] && !ENV["TRAVIS"]
5
- require "appraisal/task"
6
- Appraisal::Task.new
7
- task default: :appraisal
8
- else
9
- require "rspec/core/rake_task"
10
- RSpec::Core::RakeTask.new
11
- task default: :spec
12
- end
@@ -1,25 +0,0 @@
1
- # coding: utf-8
2
- lib = File.expand_path("../lib", __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'authem/version'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "authem"
8
- spec.version = Authem::VERSION
9
- spec.authors = ["Paul Elliott", "Pavel Pravosud"]
10
- spec.email = ["paul@codingfrontier.com", "pavel@pravosud.com"]
11
- spec.summary = "Authem authenticates them by email"
12
- spec.description = "Authem provides a simple solution for email-based authentication"
13
- spec.homepage = "https://github.com/paulelliott/authem"
14
- spec.license = "MIT"
15
-
16
- spec.required_ruby_version = ">= 1.9.3"
17
-
18
- spec.files = `git ls-files`.split($/)
19
- spec.test_files = spec.files.grep("spec")
20
- spec.require_path = "lib"
21
-
22
- spec.add_dependency "activesupport", ">= 4.0.4"
23
- spec.add_dependency "railties", "~> 4.0"
24
- spec.add_dependency "bcrypt", "~> 3.1"
25
- end
@@ -1,17 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "appraisal"
6
- gem "activerecord", "~> 4.0.0", :require => "active_record"
7
- gem "bcrypt", "~> 3.1"
8
- gem "railties", "~> 4.0"
9
- gem "protected_attributes"
10
-
11
- group :test do
12
- gem "rspec", "~> 3.0"
13
- gem "rake", "~> 10.3"
14
- gem "sqlite3", :platform => :ruby
15
- gem "activerecord-jdbcsqlite3-adapter", :platform => :jruby
16
- gem "pry"
17
- end
@@ -1,16 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "appraisal"
6
- gem "activerecord", "~> 4.1.0", :require => "active_record"
7
- gem "bcrypt", "~> 3.1"
8
- gem "railties", "~> 4.0"
9
-
10
- group :test do
11
- gem "rspec", "~> 3.0"
12
- gem "rake", "~> 10.3"
13
- gem "sqlite3", :platform => :ruby
14
- gem "activerecord-jdbcsqlite3-adapter", :platform => :jruby
15
- gem "pry"
16
- end
@@ -1,413 +0,0 @@
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
@@ -1,52 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Authem::Session do
4
- class User < ActiveRecord::Base
5
- self.table_name = :users
6
- end
7
-
8
- let(:user){ User.create(email: "joe@example.com") }
9
- let(:role){ :user }
10
-
11
- it "generates secure token on creation" do
12
- expect(Authem::Token).to receive(:generate).and_return("a secure token")
13
- model = described_class.create(role: role, subject: user)
14
- expect(model.token).to eq("a secure token")
15
- end
16
-
17
- it "set expires_at attribute according to ttl" do
18
- model = described_class.create(role: role, subject: user, ttl: 30.minutes)
19
- expect(model.expires_at).to be_within(1.second).of(30.minutes.from_now)
20
- end
21
-
22
- it "uses default ttl if value is not provided" do
23
- model = described_class.create(role: role, subject: user)
24
- expect(model.expires_at).to be_within(1.second).of(30.days.from_now)
25
- end
26
-
27
- context "scopes" do
28
- def create_session_with_expiration(expires_at)
29
- described_class.create(
30
- role: role,
31
- subject: user,
32
- expires_at: expires_at
33
- )
34
- end
35
-
36
- let!(:expired_session){ create_session_with_expiration(1.day.ago) }
37
- let!(:active_session){ create_session_with_expiration(1.week.from_now) }
38
- let(:active_scope){ described_class.active }
39
- let(:expired_scope){ described_class.expired }
40
-
41
- specify ".active filters out expired sessions" do
42
- expect(active_scope).to include(active_session)
43
- expect(active_scope).not_to include(expired_session)
44
- end
45
-
46
- specify ".expired filters out active sessions" do
47
- expect(expired_scope).to include(expired_session)
48
- expect(expired_scope).not_to include(active_session)
49
- end
50
- end
51
-
52
- end
@@ -1,4 +0,0 @@
1
- require "bundler/setup"
2
- require "authem"
3
-
4
- Dir[File.expand_path("../support/**/*.rb", __FILE__)].each(&method(:require))
@@ -1,45 +0,0 @@
1
- require "active_record"
2
-
3
- ActiveRecord::Migration.verbose = false
4
-
5
- ActiveRecord::Base.establish_connection(
6
- adapter: "sqlite3",
7
- database: ":memory:"
8
- )
9
-
10
- class CreateUsersMigration < ActiveRecord::Migration
11
- def up
12
- create_table :users do |t|
13
- t.string :email
14
- t.string :password_digest
15
- t.string :password_reset_token
16
- end
17
- end
18
- end
19
-
20
- class CreateSessionsMigration < ActiveRecord::Migration
21
- def up
22
- create_table :authem_sessions do |t|
23
- t.string :role, null: false
24
- t.references :subject, null: false, polymorphic: true
25
- t.string :token, null: false
26
- t.datetime :expires_at, null: false
27
- t.integer :ttl, null: false
28
- t.timestamps
29
- end
30
- end
31
- end
32
-
33
- RSpec.configure do |config|
34
- config.before :suite do
35
- CreateUsersMigration.new.up
36
- CreateSessionsMigration.new.up
37
- end
38
-
39
- config.around do |example|
40
- ActiveRecord::Base.transaction do
41
- example.run
42
- raise ActiveRecord::Rollback
43
- end
44
- end
45
- end
@@ -1 +0,0 @@
1
- I18n.enforce_available_locales = false
@@ -1 +0,0 @@
1
- Time.zone_default = ActiveSupport::TimeZone["UTC"]
@@ -1,10 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Authem::Token do
4
- context ".generate" do
5
- subject{ described_class.generate }
6
- it "generates a secure token 60 chars long" do
7
- expect(subject.length).to eq(60)
8
- end
9
- end
10
- end
@@ -1,116 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Authem::User do
4
-
5
- class TestUser < ActiveRecord::Base
6
- self.table_name = :users
7
- include Authem::User
8
-
9
-
10
- def self.create(opts={})
11
- opts = {email: "joe@example.com", password: "password"}.merge(opts)
12
- super(
13
- email: opts[:email],
14
- password: opts[:password],
15
- password_confirmation: opts[:password]
16
- )
17
- end
18
- end
19
-
20
- it "downcases email" do
21
- record = TestUser.new
22
- record.email = "JOE@EXAMPLE.COM"
23
- expect(record.email).to eq("joe@example.com")
24
- end
25
-
26
- subject(:user){ TestUser.create }
27
-
28
- context "#authenticate" do
29
- it "returns record if password is correct" do
30
- expect(user.authenticate("password")).to eq(user)
31
- end
32
-
33
- it "returns false if password is incorrect" do
34
- expect(user.authenticate("notright")).to be_falsy
35
- end
36
-
37
- it "returns false if password is nil" do
38
- expect(user.authenticate(nil)).to be_falsy
39
- end
40
- end
41
-
42
- context "#password_reset_token" do
43
- it "generates token on record creation" do
44
- expect(user.password_reset_token).to be_present
45
- end
46
- end
47
-
48
- context "#reset_password" do
49
- it "changes the password if on successful update" do
50
- expect{ user.reset_password "123", "123" }.to change{ user.reload.password_digest }
51
- end
52
-
53
- it "regenerates password reset token on successful update" do
54
- expect{ user.reset_password "123", "123" }.to change{ user.reload.password_reset_token }
55
- end
56
-
57
- it "does not change password on error" do
58
- expect{ user.reset_password "123", "321" }.not_to change{ user.reload.password_digest }
59
- expect{ user.reset_password "123", "" }.not_to change{ user.reload.password_digest }
60
- expect{ user.reset_password nil, "321" }.not_to change{ user.reload.password_digest }
61
- expect{ user.reset_password nil, nil }.not_to change{ user.reload.password_digest }
62
- end
63
-
64
- it "does not change password reset token on error" do
65
- expect{ user.reset_password "123", "321" }.not_to change{ user.reload.password_reset_token }
66
- expect{ user.reset_password "123", "" }.not_to change{ user.reload.password_reset_token }
67
- expect{ user.reset_password nil, "321" }.not_to change{ user.reload.password_reset_token }
68
- expect{ user.reset_password nil, nil }.not_to change{ user.reload.password_reset_token }
69
- end
70
-
71
- it "returns true if when password change is successful" do
72
- expect(user.reset_password("123", "123")).to be_truthy
73
- end
74
-
75
- it "returns false when confirmation does not match" do
76
- expect(user.reset_password("123", "321")).to be_falsy
77
- end
78
-
79
- it "adds an error when confirmation does not match" do
80
- user.reset_password("123", "321")
81
- expect(user.errors).to include(:password_confirmation)
82
- end
83
-
84
- it "adds and error when password is blank" do
85
- user.reset_password(nil, "")
86
- expect(user.errors).to include(:password)
87
- end
88
-
89
- it "returns false when password is blank" do
90
- expect(user.reset_password("", "")).to be_falsy
91
- end
92
- end
93
-
94
- context "validations" do
95
- it "allows properly formatted emails" do
96
- record = TestUser.create(email: "joe@example.com")
97
- expect(record.errors).not_to include(:email)
98
- end
99
-
100
- it "validates email presence" do
101
- record = TestUser.create(email: nil)
102
- expect(record.errors).to include(:email)
103
- end
104
-
105
- it "validates email format" do
106
- record = TestUser.create(email: "joe-at-example-com")
107
- expect(record.errors).to include(:email)
108
- end
109
-
110
- it "validates email uniqueness" do
111
- TestUser.create email: "joe@example.com"
112
- record = TestUser.create(email: "JOE@EXAMPLE.COM")
113
- expect(record.errors).to include(:email)
114
- end
115
- end
116
- end