active_authentication 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +61 -5
- data/app/controllers/active_authentication/omniauth_callbacks_controller.rb +30 -0
- data/app/views/active_authentication/shared/_links.html.erb +6 -0
- data/config/locales/en.yml +7 -0
- data/config/locales/es.yml +7 -0
- data/lib/active_authentication/controller/authenticatable.rb +49 -0
- data/lib/active_authentication/controller/lockable.rb +13 -13
- data/lib/active_authentication/controller/timeoutable.rb +26 -0
- data/lib/active_authentication/controller/trackable.rb +4 -4
- data/lib/active_authentication/controller.rb +1 -40
- data/lib/active_authentication/engine.rb +7 -5
- data/lib/active_authentication/model/omniauthable.rb +11 -0
- data/lib/active_authentication/model/timeoutable.rb +15 -0
- data/lib/active_authentication/model.rb +1 -1
- data/lib/active_authentication/routes.rb +5 -0
- data/lib/active_authentication/version.rb +1 -1
- data/lib/active_authentication.rb +10 -0
- data/lib/generators/active_authentication/install/install_generator.rb +5 -3
- data/lib/generators/active_authentication/install/templates/initializer.rb +3 -0
- data/lib/generators/active_authentication/install/templates/migration.rb +8 -8
- data/lib/generators/active_authentication/omniauthable/omniauthable_generator.rb +13 -0
- metadata +13 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bcea0e32ac726157bf24da3c6eedfc34ede7c74e69300db47ec93932aa6a1150
|
4
|
+
data.tar.gz: 92bc3f0bf9c9529816af4b018c5890ed11b94706f25b68a8669e76ff78cb9519
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 777d5861edbc543fef9d24c88ce0f39bc8457f46d9c4f78ea9335e68455de6c0aa1ac08f06f3e9e1c57e78d5542ea57e06e48ff08d380db6182dd73591e70533
|
7
|
+
data.tar.gz: 7ff2c591a3ae8169f91607ba2916f62dac48cd96e0566cc3507738067e065cce572b5cec312be40459d4089081d8854ee31b30d748b246f1769fcd0498c230d2
|
data/README.md
CHANGED
@@ -13,15 +13,16 @@ A pure Rails authentication solution.
|
|
13
13
|
* Authenticatable: provides the standard email/password authentication. It's the only concern that can't be turned off.
|
14
14
|
* Confirmable: allows users to confirm their email addresses.
|
15
15
|
* Lockable: locks users after a number of failed sign in attempts.
|
16
|
+
* Omniauthable: allows users to sign up and sign in using a third party service through Omniauth. Turned off by default.
|
16
17
|
* Recoverable: allows users to reset their password.
|
17
18
|
* Registerable: allows users to sign up and edit their profile.
|
19
|
+
* Timeoutable: expires sessions after a period of inactivity. Turned off by default.
|
18
20
|
* Trackable: tracks users sign in count, timestamps and ip addresses.
|
19
21
|
|
20
22
|
Planned concerns:
|
21
23
|
|
22
24
|
* MagicLinkable: to allow users to sign in with a magic link.
|
23
|
-
*
|
24
|
-
* Timeoutable: to expire sessions after a period of inactivity.
|
25
|
+
* Invitable: to allow users to invite other users.
|
25
26
|
|
26
27
|
## Installation
|
27
28
|
|
@@ -51,7 +52,13 @@ After installing the gem, you need to generate the `User` model. To generate it,
|
|
51
52
|
$ rails generate active_authentication:install
|
52
53
|
```
|
53
54
|
|
54
|
-
This command will generate the `User` model, add the `active_authentication` route, and generate an initializer (`config/initializers/active_authentication.rb`) where you can configure the concerns.
|
55
|
+
This command will generate the `User` model, add the `active_authentication` route, and generate an initializer (`config/initializers/active_authentication.rb`) where you can configure the concerns. By default, this command enables all concerns. If you want to use a subset of the concerns, you can specify them:
|
56
|
+
|
57
|
+
```bash
|
58
|
+
$ rails generate active_authentication:install confirmable
|
59
|
+
```
|
60
|
+
|
61
|
+
In this example, only the confirmable concern will be enabled (along with authenticatable, which can't be turned off).
|
55
62
|
|
56
63
|
You will need to set up the default url options in your `config/environments/development.rb`:
|
57
64
|
|
@@ -69,13 +76,13 @@ If you look at the `User` model (in `app/models/user.rb`), you will notice there
|
|
69
76
|
|
70
77
|
```ruby
|
71
78
|
class User < ApplicationRecord
|
72
|
-
authenticates_with :confirmable, :lockable, :recoverable, :registerable, :trackable
|
79
|
+
authenticates_with :confirmable, :lockable, :recoverable, :registerable, :timeoutable, :trackable
|
73
80
|
end
|
74
81
|
```
|
75
82
|
|
76
83
|
Notice that `:authenticatable` is not in the list. This is because you cannot turn it off.
|
77
84
|
|
78
|
-
By default, all concerns are turned on. But you can turn
|
85
|
+
By default, all concerns are turned on except omniauthable. But you can turn it on by adding it to the list, and similarly, you can turn any concern off by just removing them from the list. If you plan to not use any concerns, you can replace `authenticates_with` with `authenticates`.
|
79
86
|
|
80
87
|
### Filters and helpers
|
81
88
|
|
@@ -91,6 +98,35 @@ Then, to verify if there's an authenticated user, you can use the `user_signed_i
|
|
91
98
|
|
92
99
|
Similarly, you can use `current_user` to access the current authenticated user.
|
93
100
|
|
101
|
+
### Omniauthable
|
102
|
+
|
103
|
+
ActiveAuthentication's implementation of OmniAuth allows you to sign in and/or sign up with your third party accounts or sign up with ActiveAuthentication and later connect your third party accounts to ActiveAuthentication's User. To accomplish this, ActiveAuthentication relies on an `Authentication` model which can be created with the `active_authentication:omniauthable` generator.
|
104
|
+
|
105
|
+
To set up the omniauthable concern you must configure your OmniAuth providers as you would do with plain OmniAuth. There's no OmniAuth config in ActiveAuthentication. For example, in `config/initializers/omniauth.rb` you would set the middleware:
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
Rails.application.config.middleware.use OmniAuth::Builder do
|
109
|
+
provider :facebook, ENV["FACEBOOK_APP_ID"], ENV["FACEBOOK_APP_SECRET"]
|
110
|
+
provider :google_oauth2, ENV["GOOGLE_CLIENT_ID"], ENV["GOOGLE_CLIENT_SECRET"]
|
111
|
+
# ... and any other omniauth strategies
|
112
|
+
end
|
113
|
+
```
|
114
|
+
|
115
|
+
And then you need to run the omniauthable generator to generate the `Authentication` model:
|
116
|
+
|
117
|
+
```bash
|
118
|
+
$ rails g active_authentication:omniauthable
|
119
|
+
```
|
120
|
+
|
121
|
+
The User model has many Authentication models associated, to allow you to connect your user with multiple third party services if required.
|
122
|
+
|
123
|
+
By adding the `:omniauthable` concern to your `User` model, the following routes will be added to your app:
|
124
|
+
|
125
|
+
* `/auth/:provider` to redirect your users to the provider consent screen
|
126
|
+
* `/auth/:provider/callback` to actually sign in/sign up with the given providers
|
127
|
+
|
128
|
+
The sign in and sign up views will show a link to sign in or sign up with each provider you configured if and only if you set the `ActiveAuthentication.omniauth_providers` setting in your ActiveAuthentication initializer.
|
129
|
+
|
94
130
|
## Customization
|
95
131
|
|
96
132
|
### Concerns configuration
|
@@ -111,6 +147,26 @@ If you're not using all the concerns, you might want to copy only the views you
|
|
111
147
|
$ rails generate active_authentication:views -v sessions
|
112
148
|
```
|
113
149
|
|
150
|
+
### Omniauthable
|
151
|
+
|
152
|
+
By default, ActiveAuthentication stores the `provider`, `uid` and `auth_data` in the `Authentication` model. There are some cases where you want to store, for example, the first name and last name in the `User` model to avoid digging into the `auth_data` hash each time. Or if you have multiple authentications, you might want to pull first and last name on registration and later allow the user to change them. To pull that data from an Authentication object at sign up, you don't really need to change the controller, instead you can add a callback to your Authentication model, like this:
|
153
|
+
|
154
|
+
```ruby
|
155
|
+
class Authentication < ApplicationRecord
|
156
|
+
before_validation :update_user_attributes, if: ->(auth) { auth.auth_data.present? && auth.user.present? }
|
157
|
+
|
158
|
+
private
|
159
|
+
|
160
|
+
def update_user_attributes
|
161
|
+
first_name, last_name = auth_data.dig("info", "first_name"), auth_data.dig("info", "last_name")
|
162
|
+
|
163
|
+
user.update first_name: first_name, last_name: last_name
|
164
|
+
end
|
165
|
+
end
|
166
|
+
```
|
167
|
+
|
168
|
+
Note: this example assumes `first_name:string` and `last_name:string` have been added to the User model and are required. Optional first_name and last_name can be handled similarly.
|
169
|
+
|
114
170
|
## Contributing
|
115
171
|
|
116
172
|
You can open an issue or a PR in GitHub.
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class ActiveAuthentication::OmniauthCallbacksController < ApplicationController
|
2
|
+
def create
|
3
|
+
auth = request.env["omniauth.auth"]
|
4
|
+
provider = auth["provider"]
|
5
|
+
|
6
|
+
@authentication = Authentication.find_or_create_by uid: auth["uid"], provider: provider
|
7
|
+
|
8
|
+
@authentication.update auth_data: auth.as_json
|
9
|
+
|
10
|
+
if user_signed_in?
|
11
|
+
if @authentication.user == current_user
|
12
|
+
redirect_to root_path, notice: t(".already_linked", provider: provider)
|
13
|
+
else
|
14
|
+
@authentication.update user: current_user
|
15
|
+
redirect_to root_path, notice: t(".successfully_linked", provider: provider)
|
16
|
+
end
|
17
|
+
elsif @authentication.user.blank?
|
18
|
+
@user = User.find_or_initialize_by email: auth.dig("info", "email")
|
19
|
+
@user.password = SecureRandom.hex if @user.new_record?
|
20
|
+
|
21
|
+
@authentication.update user: @user
|
22
|
+
|
23
|
+
sign_in @authentication.user
|
24
|
+
redirect_to root_path, notice: t(".successfully_signed_up", provider: provider)
|
25
|
+
else
|
26
|
+
sign_in @authentication.user
|
27
|
+
redirect_to root_path, notice: t("active_authentication.sessions.create.success")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -6,6 +6,12 @@
|
|
6
6
|
<p><%= link_to t(".sign_up"), new_registration_path %></p>
|
7
7
|
<% end %>
|
8
8
|
|
9
|
+
<% if User.omniauthable? && (controller_name == "sessions" || controller_name == "registrations") %>
|
10
|
+
<% ActiveAuthentication.omniauth_providers.each do |provider| %>
|
11
|
+
<p><%= link_to t(".sign_in_or_sign_up_with", provider: provider), omniauth_path(provider) %></p>
|
12
|
+
<% end %>
|
13
|
+
<% end %>
|
14
|
+
|
9
15
|
<% if User.recoverable? && controller_name != "registrations" && controller_name != "passwords" %>
|
10
16
|
<p><%= link_to t(".reset_password"), new_password_path %></p>
|
11
17
|
<% end %>
|
data/config/locales/en.yml
CHANGED
@@ -14,6 +14,7 @@ en:
|
|
14
14
|
already_signed_in: You are already signed in.
|
15
15
|
form_errors: "%{errors} prohibited this user from being saved:"
|
16
16
|
locked: Your account has been locked after %{count} failed attempts. Unlock instructions will be sent to your email.
|
17
|
+
timedout: Your session expired. Sign in again to continue.
|
17
18
|
unauthenticated: You need to sign in or sign up before continuing.
|
18
19
|
mailer:
|
19
20
|
email_confirmation_instructions:
|
@@ -31,6 +32,11 @@ en:
|
|
31
32
|
subject: Unlock instructions
|
32
33
|
unlock: Unlock your account
|
33
34
|
unlock_below: 'You can unlock your account by clicking the link below:'
|
35
|
+
omniauth_callbacks:
|
36
|
+
create:
|
37
|
+
already_linked: Your %{provider} account has already been linked.
|
38
|
+
successfully_linked: Your %{provider} account has been succesfully linked.
|
39
|
+
successfully_signed_up: You have signed up successfully with %{provider}.
|
34
40
|
passwords:
|
35
41
|
create:
|
36
42
|
success: Password reset instructions will be sent to your email.
|
@@ -72,6 +78,7 @@ en:
|
|
72
78
|
send_email_confirmation_instructions: Didn't receive confirmation instructions?
|
73
79
|
send_unlock_instructions: Didn't receive unlock instructions?
|
74
80
|
sign_in: Sign in
|
81
|
+
sign_in_or_sign_up_with: Sign in or sign up with %{provider}
|
75
82
|
sign_up: Sign up
|
76
83
|
unlocks:
|
77
84
|
create:
|
data/config/locales/es.yml
CHANGED
@@ -14,6 +14,7 @@ es:
|
|
14
14
|
already_signed_in: Ya iniciaste sesión.
|
15
15
|
form_errors: "%{errors} no permitieron guardar este elemento:"
|
16
16
|
locked: Tu cuenta fue bloqueada después de %{count} intentos fallidos. Te enviaremos un email con las instrucciones de desbloqueo.
|
17
|
+
timedout: Tu sesión expiró. Iniciá sesión nuevamente para continuar.
|
17
18
|
unauthenticated: Tenés que iniciar sesión antes de continuar.
|
18
19
|
mailer:
|
19
20
|
email_confirmation_instructions:
|
@@ -31,6 +32,11 @@ es:
|
|
31
32
|
subject: Instrucciones de desbloqueo
|
32
33
|
unlock: Desbloquear cuenta
|
33
34
|
unlock_below: 'Podés desbloquear tu contraseña haciendo click en el siguiente link:'
|
35
|
+
omniauth_callbacks:
|
36
|
+
create:
|
37
|
+
already_linked: Tu cuenta de %{provider} ya fue enlazada.
|
38
|
+
successfully_linked: Tu cuenta de %{provider} fue enlazada exitosamente.
|
39
|
+
successfully_signed_up: Te registraste exitosamente con %{provider}.
|
34
40
|
passwords:
|
35
41
|
create:
|
36
42
|
success: Te enviaremos un email con las instrucciones de para recuperar tu contraseña.
|
@@ -72,6 +78,7 @@ es:
|
|
72
78
|
send_email_confirmation_instructions: "¿No recibiste las instrucciones de confirmación?"
|
73
79
|
send_unlock_instructions: "¿No recibiste las instrucciones de desbloqueo?"
|
74
80
|
sign_in: Iniciar sesión
|
81
|
+
sign_in_or_sign_up_with: Iniciar sesión o crear una cuenta con %{provider}
|
75
82
|
sign_up: Crear una cuenta
|
76
83
|
unlocks:
|
77
84
|
create:
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module ActiveAuthentication
|
2
|
+
module Controller
|
3
|
+
module Authenticatable
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
helper_method :current_user
|
8
|
+
helper_method :user_signed_in?
|
9
|
+
end
|
10
|
+
|
11
|
+
def authenticate_user!
|
12
|
+
redirect_to new_session_path, alert: t("active_authentication.failure.unauthenticated") unless user_signed_in?
|
13
|
+
end
|
14
|
+
|
15
|
+
def current_user
|
16
|
+
Current.user ||= user_from_session
|
17
|
+
end
|
18
|
+
|
19
|
+
def require_no_authentication
|
20
|
+
redirect_to root_path, alert: t("active_authentication.failure.already_signed_in") if user_signed_in?
|
21
|
+
end
|
22
|
+
|
23
|
+
def sign_in(user)
|
24
|
+
reset_session
|
25
|
+
Current.user = user
|
26
|
+
session[:user_id] = user.id
|
27
|
+
end
|
28
|
+
|
29
|
+
def sign_out
|
30
|
+
reset_session
|
31
|
+
Current.user = nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def user_signed_in?
|
35
|
+
current_user.present?
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def scope
|
41
|
+
User
|
42
|
+
end
|
43
|
+
|
44
|
+
def user_from_session
|
45
|
+
User.find_by id: session[:user_id]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -6,24 +6,24 @@ module ActiveAuthentication
|
|
6
6
|
included do
|
7
7
|
set_callback :failed_sign_in, :before, :increment_failed_attempts
|
8
8
|
set_callback :failed_sign_in, :after, :set_alert
|
9
|
+
end
|
9
10
|
|
10
|
-
|
11
|
+
private
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
def increment_failed_attempts
|
14
|
+
user = User.find_by email: params[:email]
|
15
|
+
user&.increment_failed_attempts
|
16
|
+
end
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
def scope
|
19
|
+
User.unlocked
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
-
|
22
|
+
def set_alert
|
23
|
+
user = User.find_by email: params[:email]
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
end
|
25
|
+
if user&.locked?
|
26
|
+
flash[:alert] = t "active_authentication.failure.locked", count: user.failed_attempts
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module ActiveAuthentication
|
2
|
+
module Controller
|
3
|
+
module Timeoutable
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
before_action :sign_out_user_if_timedout, if: :user_signed_in?
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def sign_out_user_if_timedout
|
13
|
+
last_request_at = session[:last_request_at].yield_self do |timestamp|
|
14
|
+
Time.at(timestamp).utc if timestamp.present?
|
15
|
+
end
|
16
|
+
|
17
|
+
if current_user.timedout?(last_request_at)
|
18
|
+
sign_out
|
19
|
+
redirect_to root_path, alert: t("active_authentication.failure.timedout")
|
20
|
+
end
|
21
|
+
|
22
|
+
session[:last_request_at] = Time.now.utc.to_i
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -1,48 +1,9 @@
|
|
1
1
|
module ActiveAuthentication
|
2
2
|
module Controller
|
3
3
|
extend ActiveSupport::Concern
|
4
|
-
include ActiveSupport::Callbacks
|
5
4
|
|
6
5
|
included do
|
7
|
-
|
8
|
-
helper_method :user_signed_in?
|
9
|
-
end
|
10
|
-
|
11
|
-
def authenticate_user!
|
12
|
-
redirect_to new_session_path, alert: t("active_authentication.failure.unauthenticated") unless user_signed_in?
|
13
|
-
end
|
14
|
-
|
15
|
-
def current_user
|
16
|
-
Current.user ||= user_from_session
|
17
|
-
end
|
18
|
-
|
19
|
-
def require_no_authentication
|
20
|
-
redirect_to root_path, alert: t("active_authentication.failure.already_signed_in") if user_signed_in?
|
21
|
-
end
|
22
|
-
|
23
|
-
def sign_in(user)
|
24
|
-
reset_session
|
25
|
-
Current.user = user
|
26
|
-
session[:user_id] = user.id
|
27
|
-
end
|
28
|
-
|
29
|
-
def sign_out
|
30
|
-
reset_session
|
31
|
-
Current.user = nil
|
32
|
-
end
|
33
|
-
|
34
|
-
def user_signed_in?
|
35
|
-
current_user.present?
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def scope
|
41
|
-
User
|
42
|
-
end
|
43
|
-
|
44
|
-
def user_from_session
|
45
|
-
User.find_by id: session[:user_id]
|
6
|
+
include Authenticatable
|
46
7
|
end
|
47
8
|
end
|
48
9
|
end
|
@@ -3,14 +3,16 @@ require "active_authentication/model"
|
|
3
3
|
|
4
4
|
module ActiveAuthentication
|
5
5
|
class Engine < ::Rails::Engine
|
6
|
-
initializer
|
7
|
-
ActiveSupport.on_load :action_controller_base do
|
8
|
-
include ActiveAuthentication::Controller
|
9
|
-
end
|
10
|
-
|
6
|
+
initializer "active_authentication.model" do
|
11
7
|
ActiveSupport.on_load :active_record do
|
12
8
|
include ActiveAuthentication::Model
|
13
9
|
end
|
14
10
|
end
|
11
|
+
|
12
|
+
initializer "active_authentication.controller" do
|
13
|
+
ActiveSupport.on_load :action_controller_base do
|
14
|
+
include ActiveAuthentication::Controller
|
15
|
+
end
|
16
|
+
end
|
15
17
|
end
|
16
18
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module ActiveAuthentication
|
2
|
+
module Model
|
3
|
+
module Timeoutable
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
ApplicationController.send :include, ActiveAuthentication::Controller::Timeoutable
|
8
|
+
end
|
9
|
+
|
10
|
+
def timedout?(last_request_at)
|
11
|
+
last_request_at && last_request_at <= ActiveAuthentication.timeout_in.ago
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -2,7 +2,7 @@ module ActiveAuthentication
|
|
2
2
|
module Model
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
|
-
CONCERNS = %i[authenticatable confirmable lockable recoverable registerable trackable]
|
5
|
+
CONCERNS = %i[authenticatable confirmable lockable omniauthable recoverable registerable timeoutable trackable]
|
6
6
|
|
7
7
|
class_methods do
|
8
8
|
def authenticates_with(*concerns)
|
@@ -22,6 +22,11 @@ module ActionDispatch::Routing
|
|
22
22
|
resources :unlocks, param: :token, only: [:new, :create, :show]
|
23
23
|
end
|
24
24
|
|
25
|
+
def omniauthable
|
26
|
+
get "auth/:provider", to: "omniauth_callbacks#pass", as: :omniauth
|
27
|
+
get "auth/:provider/callback", to: "omniauth_callbacks#create", as: :omniauth_callback
|
28
|
+
end
|
29
|
+
|
25
30
|
def registerable
|
26
31
|
resources :registrations, only: [:new, :create]
|
27
32
|
resource :profile, only: [:edit, :update, :destroy], path: :profile, controller: :registrations
|
@@ -10,7 +10,9 @@ module ActiveAuthentication
|
|
10
10
|
autoload :Model, "active_authentication/model"
|
11
11
|
|
12
12
|
module Controller
|
13
|
+
autoload :Authenticatable, "active_authentication/controller/authenticatable"
|
13
14
|
autoload :Lockable, "active_authentication/controller/lockable"
|
15
|
+
autoload :Timeoutable, "active_authentication/controller/timeoutable"
|
14
16
|
autoload :Trackable, "active_authentication/controller/trackable"
|
15
17
|
end
|
16
18
|
|
@@ -18,8 +20,10 @@ module ActiveAuthentication
|
|
18
20
|
autoload :Authenticatable, "active_authentication/model/authenticatable"
|
19
21
|
autoload :Confirmable, "active_authentication/model/confirmable"
|
20
22
|
autoload :Lockable, "active_authentication/model/lockable"
|
23
|
+
autoload :Omniauthable, "active_authentication/model/omniauthable"
|
21
24
|
autoload :Recoverable, "active_authentication/model/recoverable"
|
22
25
|
autoload :Registerable, "active_authentication/model/registerable"
|
26
|
+
autoload :Timeoutable, "active_authentication/model/timeoutable"
|
23
27
|
autoload :Trackable, "active_authentication/model/trackable"
|
24
28
|
end
|
25
29
|
|
@@ -37,6 +41,12 @@ module ActiveAuthentication
|
|
37
41
|
config_accessor :unlock_token_expires_in, default: 24.hours
|
38
42
|
config_accessor :max_failed_attempts, default: 10
|
39
43
|
|
44
|
+
# omniauthable
|
45
|
+
config_accessor :omniauth_providers, default: []
|
46
|
+
|
40
47
|
# recoverable
|
41
48
|
config_accessor :password_reset_token_expires_in, default: 1.hour
|
49
|
+
|
50
|
+
# timeoutable
|
51
|
+
config_accessor :timeout_in, default: 30.minutes
|
42
52
|
end
|
@@ -3,6 +3,8 @@ class ActiveAuthentication::InstallGenerator < Rails::Generators::Base
|
|
3
3
|
|
4
4
|
source_root File.expand_path("templates", __dir__)
|
5
5
|
|
6
|
+
argument :concerns, type: :array, default: %w[confirmable lockable recoverable registerable trackable], banner: "concern concern"
|
7
|
+
|
6
8
|
desc "Creates the User model, the active_authentication initializer, and adds the active_authentication route."
|
7
9
|
|
8
10
|
def self.next_migration_number(dirname)
|
@@ -13,12 +15,12 @@ class ActiveAuthentication::InstallGenerator < Rails::Generators::Base
|
|
13
15
|
invoke "active_record:model", %w[User], migration: false, skip_collision_check: true
|
14
16
|
|
15
17
|
if behavior == :invoke
|
16
|
-
inject_into_class "app/models/user.rb", "User", " authenticates_with
|
18
|
+
inject_into_class "app/models/user.rb", "User", " authenticates_with #{concerns.map { ":#{_1}" }.join(", ")}\n"
|
17
19
|
end
|
18
20
|
end
|
19
21
|
|
20
22
|
def generate_migration
|
21
|
-
migration_template "migration.rb", "db/migrate/create_users.rb", migration_version: migration_version, ip_column: ip_column
|
23
|
+
migration_template "migration.rb", "db/migrate/create_users.rb", concerns: concerns, migration_version: migration_version, ip_column: ip_column
|
22
24
|
end
|
23
25
|
|
24
26
|
def add_route
|
@@ -48,6 +50,6 @@ class ActiveAuthentication::InstallGenerator < Rails::Generators::Base
|
|
48
50
|
end
|
49
51
|
|
50
52
|
def postgresql?
|
51
|
-
ar_config.present? && ar_config[
|
53
|
+
ar_config.present? && ar_config.with_indifferent_access[:adapter] == "postgresql"
|
52
54
|
end
|
53
55
|
end
|
@@ -6,18 +6,18 @@ class CreateUsers < ActiveRecord::Migration<%= migration_version %>
|
|
6
6
|
t.string :password_digest, null: false
|
7
7
|
|
8
8
|
# confirmable
|
9
|
-
t.string :unconfirmed_email
|
9
|
+
<%= "# " unless concerns.include? "confirmable" -%>t.string :unconfirmed_email
|
10
10
|
|
11
11
|
# lockable
|
12
|
-
t.integer :failed_attempts, null: false, default: 0
|
13
|
-
t.datetime :locked_at
|
12
|
+
<%= "# " unless concerns.include? "lockable" -%>t.integer :failed_attempts, null: false, default: 0
|
13
|
+
<%= "# " unless concerns.include? "lockable" -%>t.datetime :locked_at
|
14
14
|
|
15
15
|
# trackable
|
16
|
-
t.integer :sign_in_count, null: false, default: 0
|
17
|
-
t.datetime :current_sign_in_at
|
18
|
-
t.datetime :last_sign_in_at
|
19
|
-
t.<%= ip_column %> :current_sign_in_ip
|
20
|
-
t.<%= ip_column %> :last_sign_in_ip
|
16
|
+
<%= "# " unless concerns.include? "trackable" -%>t.integer :sign_in_count, null: false, default: 0
|
17
|
+
<%= "# " unless concerns.include? "trackable" -%>t.datetime :current_sign_in_at
|
18
|
+
<%= "# " unless concerns.include? "trackable" -%>t.datetime :last_sign_in_at
|
19
|
+
<%= "# " unless concerns.include? "trackable" -%>t.<%= ip_column %> :current_sign_in_ip
|
20
|
+
<%= "# " unless concerns.include? "trackable" -%>t.<%= ip_column %> :last_sign_in_ip
|
21
21
|
|
22
22
|
t.timestamps
|
23
23
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class ActiveAuthentication::OmniauthableGenerator < Rails::Generators::Base
|
2
|
+
source_root File.expand_path("templates", __dir__)
|
3
|
+
|
4
|
+
desc "Creates the Authentication model"
|
5
|
+
|
6
|
+
def generate_model
|
7
|
+
invoke "active_record:model", %w[Authentication uid:string provider:string user:references auth_data:json], skip_collision_check: true
|
8
|
+
|
9
|
+
if behavior == :invoke
|
10
|
+
inject_into_class "app/models/authentication.rb", "Authentication", " validates :provider, presence: true\n validates :uid, presence: true, uniqueness: {scope: :provider}\n"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_authentication
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Patricio Mac Adden
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-05-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -49,6 +49,7 @@ files:
|
|
49
49
|
- README.md
|
50
50
|
- Rakefile
|
51
51
|
- app/controllers/active_authentication/confirmations_controller.rb
|
52
|
+
- app/controllers/active_authentication/omniauth_callbacks_controller.rb
|
52
53
|
- app/controllers/active_authentication/passwords_controller.rb
|
53
54
|
- app/controllers/active_authentication/registrations_controller.rb
|
54
55
|
- app/controllers/active_authentication/sessions_controller.rb
|
@@ -70,7 +71,9 @@ files:
|
|
70
71
|
- config/locales/es.yml
|
71
72
|
- lib/active_authentication.rb
|
72
73
|
- lib/active_authentication/controller.rb
|
74
|
+
- lib/active_authentication/controller/authenticatable.rb
|
73
75
|
- lib/active_authentication/controller/lockable.rb
|
76
|
+
- lib/active_authentication/controller/timeoutable.rb
|
74
77
|
- lib/active_authentication/controller/trackable.rb
|
75
78
|
- lib/active_authentication/current.rb
|
76
79
|
- lib/active_authentication/engine.rb
|
@@ -78,8 +81,10 @@ files:
|
|
78
81
|
- lib/active_authentication/model/authenticatable.rb
|
79
82
|
- lib/active_authentication/model/confirmable.rb
|
80
83
|
- lib/active_authentication/model/lockable.rb
|
84
|
+
- lib/active_authentication/model/omniauthable.rb
|
81
85
|
- lib/active_authentication/model/recoverable.rb
|
82
86
|
- lib/active_authentication/model/registerable.rb
|
87
|
+
- lib/active_authentication/model/timeoutable.rb
|
83
88
|
- lib/active_authentication/model/trackable.rb
|
84
89
|
- lib/active_authentication/routes.rb
|
85
90
|
- lib/active_authentication/test/helpers.rb
|
@@ -87,6 +92,7 @@ files:
|
|
87
92
|
- lib/generators/active_authentication/install/install_generator.rb
|
88
93
|
- lib/generators/active_authentication/install/templates/initializer.rb
|
89
94
|
- lib/generators/active_authentication/install/templates/migration.rb
|
95
|
+
- lib/generators/active_authentication/omniauthable/omniauthable_generator.rb
|
90
96
|
- lib/generators/active_authentication/views/views_generator.rb
|
91
97
|
homepage: https://github.com/sinaptia/active_authentication
|
92
98
|
licenses:
|
@@ -94,7 +100,8 @@ licenses:
|
|
94
100
|
metadata:
|
95
101
|
homepage_uri: https://github.com/sinaptia/active_authentication
|
96
102
|
source_code_uri: https://github.com/sinaptia/active_authentication
|
97
|
-
|
103
|
+
changelog_uri: https://github.com/sinaptia/active_authentication/blob/main/CHANGELOG.md
|
104
|
+
post_install_message:
|
98
105
|
rdoc_options: []
|
99
106
|
require_paths:
|
100
107
|
- lib
|
@@ -109,8 +116,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
109
116
|
- !ruby/object:Gem::Version
|
110
117
|
version: '0'
|
111
118
|
requirements: []
|
112
|
-
rubygems_version: 3.
|
113
|
-
signing_key:
|
119
|
+
rubygems_version: 3.5.3
|
120
|
+
signing_key:
|
114
121
|
specification_version: 4
|
115
122
|
summary: A pure Rails authentication solution
|
116
123
|
test_files: []
|