minimalist_authentication 3.2.0 → 3.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +7 -0
- data/app/controllers/passwords_controller.rb +1 -1
- data/app/validators/password_exclusivity_validator.rb +10 -0
- data/lib/minimalist_authentication/controller.rb +32 -17
- data/lib/minimalist_authentication/sessions.rb +1 -2
- data/lib/minimalist_authentication/test_helper.rb +6 -6
- data/lib/minimalist_authentication/user.rb +21 -43
- data/lib/minimalist_authentication/version.rb +1 -1
- data/lib/minimalist_authentication.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c1755b9e403888ec8c63f8e41fd9a1286a45a983a7860e2e929bae4b8f2743cf
|
4
|
+
data.tar.gz: b8463c45d6240b16fff848d553050c14c8d3c3ddc3a2d6520e67860a1b59bf5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6cffe51b8c6d48b71241e390fa79c46ec45fba7ee4cca744c079f6f6db0be88f5311424f0f615d183b6aec9bb685e25a5c2135360bec5e19d35cc23374dda27a
|
7
|
+
data.tar.gz: 10a06e82b2fdb2a22f59842221959408b49b43d7df801560d741179884beb192bde9c6d78e7972ecf30b2ee5f8ea603235d2f561c8913d2646ffc1e0fc0a3355
|
data/README.md
CHANGED
@@ -26,6 +26,13 @@ bin/rails generate model user active:boolean username:string password_digest:str
|
|
26
26
|
|
27
27
|
|
28
28
|
## Example
|
29
|
+
Create a Current class that inherits from ActiveSupport::CurrentAttributes with a user attribute (app/models/current.rb)
|
30
|
+
```ruby
|
31
|
+
class Current < ActiveSupport::CurrentAttributes
|
32
|
+
attribute :user
|
33
|
+
end
|
34
|
+
```
|
35
|
+
|
29
36
|
Include MinimalistAuthentication::User in your user model (app/models/user.rb)
|
30
37
|
```ruby
|
31
38
|
class User < ApplicationRecord
|
@@ -14,7 +14,7 @@ class PasswordsController < ApplicationController
|
|
14
14
|
|
15
15
|
# Update user's password
|
16
16
|
def update
|
17
|
-
if user.update(password_params
|
17
|
+
if user.update(password_params)
|
18
18
|
redirect_to new_session_path, notice: t(".notice")
|
19
19
|
else
|
20
20
|
render :edit, status: :unprocessable_entity
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class PasswordExclusivityValidator < ActiveModel::EachValidator
|
4
|
+
# Ensure password does not match username or email.
|
5
|
+
def validate_each(record, attribute, value)
|
6
|
+
%w[username email].each do |field|
|
7
|
+
record.errors.add(attribute, "can not match #{field}") if value.casecmp?(record.try(field))
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -5,8 +5,11 @@ module MinimalistAuthentication
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
7
|
included do
|
8
|
-
#
|
9
|
-
|
8
|
+
# Loads the user object from the session and assigns it to Current.user
|
9
|
+
before_action :load_current_user
|
10
|
+
|
11
|
+
# Requires an authorized user for all actions
|
12
|
+
# Use skip_before_action to allow access to specific actions
|
10
13
|
before_action :authorization_required
|
11
14
|
|
12
15
|
helper MinimalistAuthentication::ApplicationHelper
|
@@ -14,35 +17,47 @@ module MinimalistAuthentication
|
|
14
17
|
helper_method :current_user, :logged_in?, :authorized?
|
15
18
|
end
|
16
19
|
|
17
|
-
|
20
|
+
# Returns true if the user is logged in
|
21
|
+
# Override this method in your controller to customize authorization
|
22
|
+
def authorized?(_action = action_name, _resource = controller_name)
|
23
|
+
logged_in?
|
24
|
+
end
|
18
25
|
|
26
|
+
# Returns the current user from the client application Current class
|
19
27
|
def current_user
|
20
|
-
|
28
|
+
::Current.user
|
21
29
|
end
|
22
30
|
|
23
|
-
|
24
|
-
|
31
|
+
# Returns true if a current user is present, otherwise returns false
|
32
|
+
def logged_in?
|
33
|
+
current_user.present?
|
25
34
|
end
|
26
35
|
|
27
|
-
|
28
|
-
|
36
|
+
# Logs in a user by setting the session key and updating the Current user
|
37
|
+
# Should only be called after a successful authentication
|
38
|
+
def update_current_user(user)
|
39
|
+
reset_session
|
40
|
+
session[MinimalistAuthentication.session_key] = user.id
|
41
|
+
::Current.user = user
|
29
42
|
end
|
30
43
|
|
31
|
-
|
32
|
-
|
44
|
+
private
|
45
|
+
|
46
|
+
def access_denied
|
47
|
+
store_location if request.get? && !logged_in?
|
48
|
+
redirect_to new_session_path
|
33
49
|
end
|
34
50
|
|
35
|
-
def
|
36
|
-
|
51
|
+
def authorization_required
|
52
|
+
authorized? || access_denied
|
37
53
|
end
|
38
54
|
|
39
|
-
def
|
40
|
-
|
55
|
+
def find_session_user
|
56
|
+
MinimalistAuthentication.user_model.find_enabled(session[MinimalistAuthentication.session_key])
|
41
57
|
end
|
42
58
|
|
43
|
-
def
|
44
|
-
|
45
|
-
redirect_to new_session_path
|
59
|
+
def load_current_user
|
60
|
+
Current.user = find_session_user
|
46
61
|
end
|
47
62
|
|
48
63
|
def store_location
|
@@ -42,9 +42,8 @@ module MinimalistAuthentication
|
|
42
42
|
|
43
43
|
def log_in_user
|
44
44
|
self.return_to = session["return_to"]
|
45
|
-
|
45
|
+
update_current_user(authenticated_user)
|
46
46
|
authenticated_user.logged_in
|
47
|
-
session[MinimalistAuthentication.configuration.session_key] = authenticated_user.id
|
48
47
|
end
|
49
48
|
|
50
49
|
def user_params
|
@@ -5,22 +5,22 @@ module MinimalistAuthentication
|
|
5
5
|
PASSWORD = "test-password"
|
6
6
|
PASSWORD_DIGEST = BCrypt::Password.create(PASSWORD, cost: BCrypt::Engine::MIN_COST)
|
7
7
|
|
8
|
-
def login_as(user_fixture_name, password = PASSWORD)
|
9
|
-
post session_path, params: { user: { email: users(user_fixture_name).email, password: } }
|
10
|
-
end
|
11
|
-
|
12
8
|
def current_user
|
13
9
|
@current_user ||= load_user_from_session
|
14
10
|
end
|
15
11
|
|
12
|
+
def login_as(user_fixture_name, password = PASSWORD)
|
13
|
+
post session_path, params: { user: { email: users(user_fixture_name).email, password: } }
|
14
|
+
end
|
15
|
+
|
16
16
|
private
|
17
17
|
|
18
18
|
def load_user_from_session
|
19
|
-
MinimalistAuthentication.
|
19
|
+
MinimalistAuthentication.user_model.find(session_user_id) if session_user_id
|
20
20
|
end
|
21
21
|
|
22
22
|
def session_user_id
|
23
|
-
@request.session[MinimalistAuthentication.
|
23
|
+
@request.session[MinimalistAuthentication.session_key]
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -6,8 +6,6 @@ module MinimalistAuthentication
|
|
6
6
|
module User
|
7
7
|
extend ActiveSupport::Concern
|
8
8
|
|
9
|
-
GUEST_USER_EMAIL = "guest"
|
10
|
-
|
11
9
|
included do
|
12
10
|
has_secure_password
|
13
11
|
|
@@ -15,9 +13,6 @@ module MinimalistAuthentication
|
|
15
13
|
password_salt.last(10)
|
16
14
|
end
|
17
15
|
|
18
|
-
# Force validations for a blank password.
|
19
|
-
attribute :password_required, :boolean, default: false
|
20
|
-
|
21
16
|
# Email validations
|
22
17
|
validates(
|
23
18
|
:email,
|
@@ -29,10 +24,13 @@ module MinimalistAuthentication
|
|
29
24
|
|
30
25
|
# Password validations
|
31
26
|
# Adds validations for minimum password length and exclusivity.
|
32
|
-
# has_secure_password
|
33
|
-
|
34
|
-
|
35
|
-
|
27
|
+
# has_secure_password includes validations for presence, maximum length, confirmation, and password_challenge.
|
28
|
+
validates(
|
29
|
+
:password,
|
30
|
+
password_exclusivity: true,
|
31
|
+
length: { minimum: :password_minimum },
|
32
|
+
allow_blank: true
|
33
|
+
)
|
36
34
|
|
37
35
|
# Active scope
|
38
36
|
scope :active, ->(state = true) { where(active: state) }
|
@@ -54,11 +52,6 @@ module MinimalistAuthentication
|
|
54
52
|
active(false)
|
55
53
|
end
|
56
54
|
|
57
|
-
# Returns a frozen user with the email set to GUEST_USER_EMAIL.
|
58
|
-
def guest
|
59
|
-
new(email: GUEST_USER_EMAIL).freeze
|
60
|
-
end
|
61
|
-
|
62
55
|
# Minimum password length
|
63
56
|
def password_minimum = 12
|
64
57
|
end
|
@@ -74,15 +67,9 @@ module MinimalistAuthentication
|
|
74
67
|
active?
|
75
68
|
end
|
76
69
|
|
77
|
-
# Remove the has_secure_password password blank error if
|
70
|
+
# Remove the has_secure_password password blank error if user is inactive.
|
78
71
|
def errors
|
79
|
-
super.tap { |errors| errors.delete(:password, :blank)
|
80
|
-
end
|
81
|
-
|
82
|
-
# Returns true if the user is not active.
|
83
|
-
def inactive?
|
84
|
-
MinimalistAuthentication.deprecator.warn("Calling #inactive? is deprecated.")
|
85
|
-
!active?
|
72
|
+
super.tap { |errors| errors.delete(:password, :blank) if inactive? }
|
86
73
|
end
|
87
74
|
|
88
75
|
# Returns true if password matches the hashed_password, otherwise returns false.
|
@@ -93,9 +80,19 @@ module MinimalistAuthentication
|
|
93
80
|
authenticate(password)
|
94
81
|
end
|
95
82
|
|
96
|
-
#
|
83
|
+
# Deprecated method to check if the user is a guest. Returns false because the guest user has been removed.
|
97
84
|
def guest?
|
98
|
-
|
85
|
+
MinimalistAuthentication.deprecator.warn(<<-MSG.squish)
|
86
|
+
Calling #guest? is deprecated. Use #MinimalistAuthentication::Controller#logged_in? to
|
87
|
+
check for the presence of a current_user instead.
|
88
|
+
MSG
|
89
|
+
|
90
|
+
false
|
91
|
+
end
|
92
|
+
|
93
|
+
# Returns true if the user is not active.
|
94
|
+
def inactive?
|
95
|
+
!active?
|
99
96
|
end
|
100
97
|
|
101
98
|
# Sets #last_logged_in_at to the current time without updating the updated_at timestamp.
|
@@ -103,32 +100,13 @@ module MinimalistAuthentication
|
|
103
100
|
update_column(:last_logged_in_at, Time.current)
|
104
101
|
end
|
105
102
|
|
106
|
-
# Checks for password presence
|
107
|
-
def password?
|
108
|
-
password.present?
|
109
|
-
end
|
110
|
-
|
111
103
|
private
|
112
104
|
|
113
|
-
# Ensure password does not match username or email.
|
114
|
-
def password_exclusivity
|
115
|
-
%w[username email].each do |field|
|
116
|
-
errors.add(:password, "can not match #{field}") if password.casecmp?(try(field))
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
105
|
# Return true if the user matches the owner of the provided token.
|
121
106
|
def token_owner?(purpose, token)
|
122
107
|
self.class.find_by_token_for(purpose, token) == self
|
123
108
|
end
|
124
109
|
|
125
|
-
# Require password for active users that either do no have a password hash
|
126
|
-
# stored OR are attempting to set a new password. Set **password_required**
|
127
|
-
# to true to force validations even when the password field is blank.
|
128
|
-
def validate_password?
|
129
|
-
active? && (password_digest.blank? || password? || password_required?)
|
130
|
-
end
|
131
|
-
|
132
110
|
# Validate email for all users.
|
133
111
|
# Applications can turn off email validation by setting the validate_email
|
134
112
|
# configuration attribute to false.
|
@@ -12,7 +12,7 @@ require "minimalist_authentication/test_helper"
|
|
12
12
|
|
13
13
|
module MinimalistAuthentication
|
14
14
|
class << self
|
15
|
-
delegate :user_model, to: :configuration
|
15
|
+
delegate :session_key, :user_model, to: :configuration
|
16
16
|
|
17
17
|
def deprecator
|
18
18
|
@deprecator ||= ActiveSupport::Deprecation.new("4.0", name)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: minimalist_authentication
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.2.
|
4
|
+
version: 3.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aaron Baldwin
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2024-
|
12
|
+
date: 2024-12-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bcrypt
|
@@ -63,6 +63,7 @@ files:
|
|
63
63
|
- app/helpers/minimalist_authentication/application_helper.rb
|
64
64
|
- app/mailers/application_mailer.rb
|
65
65
|
- app/mailers/minimalist_authentication_mailer.rb
|
66
|
+
- app/validators/password_exclusivity_validator.rb
|
66
67
|
- app/views/email_verifications/new.html.erb
|
67
68
|
- app/views/email_verifications/show.html.erb
|
68
69
|
- app/views/emails/edit.html.erb
|