rodauth-rails 1.8.0 → 1.10.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/CHANGELOG.md +22 -0
- data/README.md +155 -243
- data/lib/generators/rodauth/install_generator.rb +1 -1
- data/lib/generators/rodauth/migration/active_record/active_sessions.erb +2 -2
- data/lib/generators/rodauth/migration/active_record/audit_logging.erb +2 -2
- data/lib/generators/rodauth/migration/active_record/email_auth.erb +1 -1
- data/lib/generators/rodauth/migration/active_record/otp.erb +1 -1
- data/lib/generators/rodauth/migration/active_record/password_expiration.erb +1 -1
- data/lib/generators/rodauth/migration/active_record/reset_password.erb +1 -1
- data/lib/generators/rodauth/migration/active_record/sms_codes.erb +1 -1
- data/lib/generators/rodauth/migration/active_record/verify_account.erb +2 -2
- data/lib/generators/rodauth/migration/active_record/webauthn.erb +1 -1
- data/lib/generators/rodauth/migration_generator.rb +2 -22
- data/lib/generators/rodauth/templates/app/mailers/rodauth_mailer.rb.tt +7 -7
- data/lib/generators/rodauth/templates/app/misc/rodauth_main.rb.tt +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/_login_form.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/login.html.erb +2 -2
- data/lib/generators/rodauth/templates/app/views/rodauth/multi_phase_login.html.erb +2 -2
- data/lib/generators/rodauth/templates/app/views/rodauth/tailwind/_login_form.html.erb +1 -1
- data/lib/generators/rodauth/templates/app/views/rodauth/tailwind/login.html.erb +2 -2
- data/lib/generators/rodauth/templates/app/views/rodauth/tailwind/multi_phase_login.html.erb +2 -2
- data/lib/generators/rodauth/templates/app/views/rodauth/tailwind/webauthn_autofill.html.erb +10 -0
- data/lib/generators/rodauth/templates/app/views/rodauth/webauthn_autofill.html.erb +10 -0
- data/lib/generators/rodauth/templates/app/views/rodauth_mailer/unlock_account.text.erb +1 -1
- data/lib/generators/rodauth/templates/db/migrate/create_rodauth.rb.tt +1 -1
- data/lib/generators/rodauth/views_generator.rb +3 -12
- data/lib/rodauth/rails/app.rb +7 -9
- data/lib/rodauth/rails/feature/base.rb +5 -29
- data/lib/rodauth/rails/feature/render.rb +1 -1
- data/lib/rodauth/rails/railtie.rb +2 -6
- data/lib/rodauth/rails/version.rb +1 -1
- data/lib/rodauth/rails.rb +10 -10
- data/rodauth-rails.gemspec +2 -2
- metadata +9 -9
- data/lib/generators/rodauth/templates/app/views/rodauth/_login_form_header.html.erb +0 -3
- data/lib/generators/rodauth/templates/app/views/rodauth/tailwind/_login_form_header.html.erb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: adfcbce27e52d0a53b5cd670489635c841dff9e2809c92be059286943894db6c
|
4
|
+
data.tar.gz: e98584823e926c810bc66366496df5fb3c8eed0f38e291b76b9f132480941a9c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 845b037926a9372522da9b3507b5fd2959454bc24198f72a7832d9025ccd27f9bac3790823577e1e68c3a1e1a076472e1629825973c37cc932e2b63299e1408b
|
7
|
+
data.tar.gz: af417d7bbe9732c677ca15c6796817554fe68d5f8f3db8001b56a736db33382f3efd8f86952509d038f45f449f76d3c9ea61f1a7f5a29c1cef5f45e72cf1c9ce
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
## 1.10.0 (2023-07-26)
|
2
|
+
|
3
|
+
* Add `Rodauth::Rails.lib` for easier usage of Rodauth as a library in Rails apps (@janko)
|
4
|
+
|
5
|
+
## 1.9.0 (2023-05-22)
|
6
|
+
|
7
|
+
* Add support for webauthn_autofill feature to the views generator (@janko)
|
8
|
+
|
9
|
+
* Generate view templates for two_factor_base feature only if explicitly specified (@janko)
|
10
|
+
|
11
|
+
* Set `login_param "email"` in generated Rodauth configuration (@janko)
|
12
|
+
|
13
|
+
* Handle Trilogy adapter in generators (@janko)
|
14
|
+
|
15
|
+
* Use `email_subject_prefix` in generated mailer (@janko)
|
16
|
+
|
17
|
+
* Fix typo in `unlock_account` email template (@zavan)
|
18
|
+
|
19
|
+
* Retrieve current account using `account!` in `#rails_account` method (@janko)
|
20
|
+
|
21
|
+
* Drop support for Rails 4.2 (@janko)
|
22
|
+
|
1
23
|
## 1.8.0 (2023-02-25)
|
2
24
|
|
3
25
|
* Add table argument to `rodauth:install` generator (@janko)
|
data/README.md
CHANGED
@@ -24,6 +24,7 @@ Provides Rails integration for the [Rodauth] authentication framework.
|
|
24
24
|
* [How to build an OIDC provider using rodauth-oauth on Rails](https://honeyryderchuck.gitlab.io/httpx/2021/03/15/oidc-provider-on-rails-using-rodauth-oauth.html)
|
25
25
|
* [What It Took to Build a Rails Integration for Rodauth](https://janko.io/what-it-took-to-build-a-rails-integration-for-rodauth/)
|
26
26
|
* [Social Login in Rails with Rodauth](https://janko.io/social-login-in-rails-with-rodauth/)
|
27
|
+
* [Passkey Authentication with Rodauth](https://janko.io/passkey-authentication-with-rodauth/)
|
27
28
|
|
28
29
|
## Why Rodauth?
|
29
30
|
|
@@ -31,16 +32,13 @@ There are already several popular authentication solutions for Rails (Devise,
|
|
31
32
|
Sorcery, Clearance, Authlogic), so why would you choose Rodauth? Here are some
|
32
33
|
of the advantages that stand out for me:
|
33
34
|
|
34
|
-
* multifactor authentication ([TOTP][otp], [SMS codes][sms_codes], [recovery codes][recovery_codes], [
|
35
|
+
* multifactor authentication ([TOTP][otp], [SMS codes][sms_codes], [recovery codes][recovery_codes], [passkeys][webauthn])
|
35
36
|
* standardized [JSON API support][json] for every feature (including [JWT][jwt])
|
36
37
|
* enterprise security features ([password complexity][password_complexity], [disallow password reuse][disallow_password_reuse], [password expiration][password_expiration], [session expiration][session_expiration], [single session][single_session], [account expiration][account_expiration])
|
37
|
-
* [email
|
38
|
-
* [audit logging][audit_logging]
|
38
|
+
* passwordless authentication ([email][email_auth], [passkeys][webauthn_login])
|
39
|
+
* [audit logging][audit_logging] for any action
|
39
40
|
* ability to protect password hashes even in case of SQL injection ([more details][password protection])
|
40
|
-
*
|
41
|
-
* uniform configuration DSL (any setting can be static or dynamic)
|
42
|
-
* consistent before/after hooks around everything
|
43
|
-
* dedicated object encapsulating all authentication logic
|
41
|
+
* uniform configuration DSL with before/after hooks around everything
|
44
42
|
|
45
43
|
### Sequel
|
46
44
|
|
@@ -188,25 +186,6 @@ current_account #=> #<Account id=123 email="user@example.com">
|
|
188
186
|
current_account.email #=> "user@example.com"
|
189
187
|
```
|
190
188
|
|
191
|
-
If the session is logged in, but the account doesn't exist in the database, the
|
192
|
-
session will be reset.
|
193
|
-
|
194
|
-
#### Custom account model
|
195
|
-
|
196
|
-
The `#rails_account` method will try to infer the account model class from the
|
197
|
-
configured accounts table name. However, if the model class cannot be inferred
|
198
|
-
from the table name, you can configure it manually:
|
199
|
-
|
200
|
-
```rb
|
201
|
-
# app/misc/rodauth_main.rb
|
202
|
-
class RodauthMain < Rodauth::Rails::Auth
|
203
|
-
configure do
|
204
|
-
# ...
|
205
|
-
rails_account_model { Authentication::Account } # custom model name
|
206
|
-
end
|
207
|
-
end
|
208
|
-
```
|
209
|
-
|
210
189
|
### Requiring authentication
|
211
190
|
|
212
191
|
You'll likely want to require authentication for certain parts of your app,
|
@@ -222,8 +201,8 @@ class RodauthApp < Rodauth::Rails::App
|
|
222
201
|
# ...
|
223
202
|
r.rodauth # route rodauth requests
|
224
203
|
|
225
|
-
# require authentication for /dashboard/*
|
226
|
-
if r.path.start_with?("/dashboard")
|
204
|
+
# require authentication for /dashboard/* routes
|
205
|
+
if r.path.start_with?("/dashboard")
|
227
206
|
rodauth.require_account # redirect to login page if not authenticated
|
228
207
|
end
|
229
208
|
end
|
@@ -248,12 +227,6 @@ class DashboardController < ApplicationController
|
|
248
227
|
before_action :authenticate
|
249
228
|
end
|
250
229
|
```
|
251
|
-
```rb
|
252
|
-
# app/controllers/posts_controller.rb
|
253
|
-
class PostsController < ApplicationController
|
254
|
-
before_action :authenticate, except: [:index, :show]
|
255
|
-
end
|
256
|
-
```
|
257
230
|
|
258
231
|
#### Routing constraints
|
259
232
|
|
@@ -282,42 +255,83 @@ Rails.application.routes.draw do
|
|
282
255
|
end
|
283
256
|
```
|
284
257
|
|
285
|
-
|
258
|
+
You can specify a different Rodauth configuration by passing the configuration name:
|
286
259
|
|
287
260
|
```rb
|
288
261
|
# config/routes.rb
|
289
262
|
Rails.application.routes.draw do
|
290
|
-
|
291
|
-
constraints Rodauth::Rails.authenticated { |rodauth| rodauth.rails_account.admin? } do
|
263
|
+
constraints Rodauth::Rails.authenticated(:admin) do
|
292
264
|
# ...
|
293
265
|
end
|
294
266
|
end
|
295
267
|
```
|
296
268
|
|
297
|
-
|
269
|
+
If you need something more custom, you can always create the routing constraint
|
270
|
+
manually:
|
298
271
|
|
299
272
|
```rb
|
300
273
|
# config/routes.rb
|
301
274
|
Rails.application.routes.draw do
|
302
|
-
constraints
|
303
|
-
#
|
275
|
+
constraints -> (r) { !r.env["rodauth"].logged_in? } do # or env["rodauth.admin"]
|
276
|
+
# routes when the user is not logged in
|
304
277
|
end
|
305
278
|
end
|
306
279
|
```
|
307
280
|
|
308
|
-
|
309
|
-
|
281
|
+
### Controller
|
282
|
+
|
283
|
+
Your Rodauth configuration is connected to a Rails controller (`RodauthController` by default), and
|
284
|
+
it automatically executes any callbacks and rescue handlers defined on it (or the parent controller)
|
285
|
+
around Rodauth endpoints.
|
310
286
|
|
311
287
|
```rb
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
288
|
+
class RodauthController < ApplicationController
|
289
|
+
before_action :set_locale # executes before Rodauth endpoints
|
290
|
+
rescue_from("MyApp::SomeError") { |exception| ... } # rescues around Rodauth endpoints
|
291
|
+
end
|
292
|
+
```
|
293
|
+
|
294
|
+
#### Calling controller methods
|
295
|
+
|
296
|
+
You can call any controller methods from your Rodauth configuration via `rails_controller_eval`:
|
297
|
+
|
298
|
+
```rb
|
299
|
+
# app/controllers/application_controller.rb
|
300
|
+
class ApplicationController < ActionController::Base
|
301
|
+
private
|
302
|
+
def setup_tracking(account_id)
|
303
|
+
# ... some implementation ...
|
304
|
+
end
|
305
|
+
end
|
306
|
+
```
|
307
|
+
```rb
|
308
|
+
# app/misc/rodauth_main.rb
|
309
|
+
class RodauthMain < Rodauth::Rails::Auth
|
310
|
+
configure do
|
311
|
+
after_create_account do
|
312
|
+
rails_controller_eval { setup_tracking(account_id) }
|
313
|
+
end
|
316
314
|
end
|
317
315
|
end
|
318
316
|
```
|
319
317
|
|
320
|
-
###
|
318
|
+
### Rails URL helpers
|
319
|
+
|
320
|
+
Inside Rodauth configuration and the `route` block you can access Rails route
|
321
|
+
helpers through `#rails_routes`:
|
322
|
+
|
323
|
+
```rb
|
324
|
+
# app/misc/rodauth_main.rb
|
325
|
+
class RodauthMain < Rodauth::Rails::Auth
|
326
|
+
configure do
|
327
|
+
login_redirect { rails_routes.activity_path }
|
328
|
+
change_password_redirect { rails_routes.profile_path }
|
329
|
+
change_login_redirect { rails_routes.profile_path }
|
330
|
+
end
|
331
|
+
end
|
332
|
+
```
|
333
|
+
|
334
|
+
## Views
|
321
335
|
|
322
336
|
The templates built into Rodauth are useful when getting started, but soon
|
323
337
|
you'll want to start editing the markup. You can run the following command to
|
@@ -349,10 +363,10 @@ $ rails generate rodauth:views --all
|
|
349
363
|
Use `--name` to generate views for a different Rodauth configuration:
|
350
364
|
|
351
365
|
```sh
|
352
|
-
$ rails generate rodauth:views webauthn --name admin
|
366
|
+
$ rails generate rodauth:views webauthn two_factor_base --name admin
|
353
367
|
```
|
354
368
|
|
355
|
-
|
369
|
+
### Page titles
|
356
370
|
|
357
371
|
The generated configuration sets `title_instance_variable` to make page titles
|
358
372
|
available in your views via `@page_title` instance variable, which you can then
|
@@ -362,9 +376,7 @@ use in your layout:
|
|
362
376
|
# app/misc/rodauth_main.rb
|
363
377
|
class RodauthMain < Rodauth::Rails::Auth
|
364
378
|
configure do
|
365
|
-
# ...
|
366
379
|
title_instance_variable :@page_title
|
367
|
-
# ...
|
368
380
|
end
|
369
381
|
end
|
370
382
|
```
|
@@ -376,28 +388,11 @@ end
|
|
376
388
|
<title><%= @page_title || "Default title" %></title>
|
377
389
|
<!-- ... -->
|
378
390
|
</head>
|
379
|
-
|
380
|
-
<!-- ... -->
|
381
|
-
</body>
|
391
|
+
<!-- ... -->
|
382
392
|
</html>
|
383
393
|
```
|
384
394
|
|
385
|
-
|
386
|
-
generated Rodauth views, giving it the result of the corresponding
|
387
|
-
`*_page_title` method:
|
388
|
-
|
389
|
-
```erb
|
390
|
-
<!-- app/views/rodauth/login.html.erb -->
|
391
|
-
<%= content_for :page_title, rodauth.login_page_title %>
|
392
|
-
<!-- ... -->
|
393
|
-
```
|
394
|
-
```erb
|
395
|
-
<!-- app/views/rodauth/change_password.html.erb -->
|
396
|
-
<%= content_for :page_title, rodauth.change_password_page_title %>
|
397
|
-
<!-- ... -->
|
398
|
-
```
|
399
|
-
|
400
|
-
#### Layout
|
395
|
+
### Layout
|
401
396
|
|
402
397
|
To use different layouts for different Rodauth views, you can compare the
|
403
398
|
request path in the layout method:
|
@@ -425,7 +420,7 @@ class RodauthController < ApplicationController
|
|
425
420
|
end
|
426
421
|
```
|
427
422
|
|
428
|
-
|
423
|
+
### Turbo
|
429
424
|
|
430
425
|
[Turbo] has been disabled by default on all built-in and generated view
|
431
426
|
templates, because some Rodauth actions (multi-phase login, adding recovery
|
@@ -434,7 +429,7 @@ codes) aren't Turbo-compatible, as they return 200 responses on POST requests.
|
|
434
429
|
That being said, most of Rodauth *is* Turbo-compatible, so feel free to enable
|
435
430
|
Turbo for actions where you want to use it.
|
436
431
|
|
437
|
-
|
432
|
+
## Mailer
|
438
433
|
|
439
434
|
The install generator will create `RodauthMailer` with default email templates,
|
440
435
|
and configure Rodauth features that send emails as part of the authentication
|
@@ -443,73 +438,45 @@ flow to use it.
|
|
443
438
|
```rb
|
444
439
|
# app/mailers/rodauth_mailer.rb
|
445
440
|
class RodauthMailer < ApplicationMailer
|
446
|
-
def verify_account(account_id, key)
|
447
|
-
|
448
|
-
end
|
449
|
-
def
|
450
|
-
|
451
|
-
end
|
452
|
-
def verify_login_change(account_id, old_login, new_login, key)
|
453
|
-
# ...
|
454
|
-
end
|
455
|
-
def password_changed(account_id)
|
456
|
-
# ...
|
457
|
-
end
|
458
|
-
# def email_auth(account_id, key)
|
459
|
-
# ...
|
460
|
-
# end
|
461
|
-
# def unlock_account(account_id, key)
|
462
|
-
# ...
|
463
|
-
# end
|
441
|
+
def verify_account(account_id, key) ... end
|
442
|
+
def reset_password(account_id, key) ... end
|
443
|
+
def verify_login_change(account_id, key) ... end
|
444
|
+
def password_changed(account_id) ... end
|
445
|
+
# def email_auth(account_id, key) ... end
|
446
|
+
# def unlock_account(account_id, key) ... end
|
464
447
|
end
|
465
448
|
```
|
466
449
|
```rb
|
467
450
|
# app/misc/rodauth_main.rb
|
468
451
|
class RodauthMain < Rodauth::Rails::Auth
|
469
452
|
configure do
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
end
|
477
|
-
create_verify_login_change_email do |_login|
|
478
|
-
RodauthMailer.verify_login_change(account_id, verify_login_change_old_login, verify_login_change_new_login, verify_login_change_key_value)
|
479
|
-
end
|
480
|
-
create_password_changed_email do
|
481
|
-
RodauthMailer.password_changed(account_id)
|
482
|
-
end
|
483
|
-
# create_email_auth_email do
|
484
|
-
# RodauthMailer.email_auth(account_id, email_auth_key_value)
|
485
|
-
# end
|
486
|
-
# create_unlock_account_email do
|
487
|
-
# RodauthMailer.unlock_account(account_id, unlock_account_key_value)
|
488
|
-
# end
|
453
|
+
create_reset_password_email { RodauthMailer.reset_password(account_id, reset_password_key_value) }
|
454
|
+
create_verify_account_email { RodauthMailer.verify_account(account_id, verify_account_key_value) }
|
455
|
+
create_verify_login_change_email { |_login| RodauthMailer.verify_login_change(account_id, verify_login_change_key_value) }
|
456
|
+
create_password_changed_email { RodauthMailer.password_changed(account_id) }
|
457
|
+
# create_email_auth_email { RodauthMailer.email_auth(account_id, email_auth_key_value) }
|
458
|
+
# create_unlock_account_email { RodauthMailer.unlock_account(account_id, unlock_account_key_value) }
|
489
459
|
send_email do |email|
|
490
460
|
# queue email delivery on the mailer after the transaction commits
|
491
461
|
db.after_commit { email.deliver_later }
|
492
462
|
end
|
493
|
-
# ...
|
494
463
|
end
|
495
464
|
end
|
496
465
|
```
|
497
466
|
|
498
467
|
This configuration calls `#deliver_later`, which uses Active Job to deliver
|
499
|
-
emails in a background job.
|
500
|
-
|
501
|
-
deliveries. However, if you want to send emails synchronously, you can modify
|
502
|
-
the configuration to call `#deliver_now` instead.
|
468
|
+
emails in a background job. If you want to send emails synchronously, you can
|
469
|
+
modify the configuration to call `#deliver_now` instead.
|
503
470
|
|
504
471
|
If you're using a background processing library without an Active Job adapter,
|
505
472
|
or a 3rd-party service for sending transactional emails, see [this wiki
|
506
473
|
page][custom mailer worker] on how to set it up.
|
507
474
|
|
508
|
-
|
475
|
+
## Migrations
|
509
476
|
|
510
477
|
The install generator will create a migration for tables used by the Rodauth
|
511
478
|
features enabled by default. For any additional features, you can use the
|
512
|
-
migration generator
|
479
|
+
migration generator to create the required tables:
|
513
480
|
|
514
481
|
```sh
|
515
482
|
$ rails generate rodauth:migration otp sms_codes recovery_codes
|
@@ -525,10 +492,10 @@ class CreateRodauthOtpSmsCodesRecoveryCodes < ActiveRecord::Migration
|
|
525
492
|
end
|
526
493
|
```
|
527
494
|
|
528
|
-
|
495
|
+
### Table prefix
|
529
496
|
|
530
497
|
If you're storing account records in a table other than `accounts`, you'll want
|
531
|
-
to specify the
|
498
|
+
to specify the appropriate table prefix when generating new migrations:
|
532
499
|
|
533
500
|
```sh
|
534
501
|
$ rails generate rodauth:migration base active_sessions --prefix user
|
@@ -549,7 +516,7 @@ class CreateRodauthUserBaseActiveSessions < ActiveRecord::Migration
|
|
549
516
|
end
|
550
517
|
```
|
551
518
|
|
552
|
-
|
519
|
+
### Custom migration name
|
553
520
|
|
554
521
|
You can change the default migration name:
|
555
522
|
|
@@ -573,37 +540,23 @@ tables used by enabled authentication features.
|
|
573
540
|
|
574
541
|
```rb
|
575
542
|
class Account < ActiveRecord::Base # Sequel::Model
|
576
|
-
include Rodauth::Rails.model # or
|
543
|
+
include Rodauth::Rails.model # or Rodauth::Rails.model(:admin)
|
577
544
|
end
|
578
545
|
```
|
579
|
-
|
580
|
-
The password attribute can be used to set or clear the password hash. It
|
581
|
-
handles both storing the password hash in a column on the accounts table, or in
|
582
|
-
a separate table.
|
583
|
-
|
584
546
|
```rb
|
547
|
+
# setting password hash
|
585
548
|
account = Account.create!(email: "user@example.com", password: "secret123")
|
586
|
-
|
587
|
-
# when password hash is stored in a column on the accounts table
|
588
549
|
account.password_hash #=> "$2a$12$k/Ub1I2iomi84RacqY89Hu4.M0vK7klRnRtzorDyvOkVI.hKhkNw."
|
589
550
|
|
590
|
-
#
|
591
|
-
account.
|
592
|
-
account.password_hash.password_hash #=> "$2a$12$k/Ub1..." (inaccessible when using database authentication functions)
|
593
|
-
|
594
|
-
account.password = nil # clears password hash
|
551
|
+
# clearing password hash
|
552
|
+
account.password = nil
|
595
553
|
account.password_hash #=> nil
|
596
|
-
```
|
597
|
-
|
598
|
-
The associations are defined for tables used by enabled authentication features:
|
599
554
|
|
600
|
-
|
555
|
+
# associations
|
601
556
|
account.remember_key #=> #<Account::RememberKey> (record from `account_remember_keys` table)
|
602
557
|
account.active_session_keys #=> [#<Account::ActiveSessionKey>,...] (records from `account_active_session_keys` table)
|
603
558
|
```
|
604
559
|
|
605
|
-
See the [rodauth-model] documentation for more details.
|
606
|
-
|
607
560
|
## Multiple configurations
|
608
561
|
|
609
562
|
If you need to handle multiple types of accounts that require different
|
@@ -649,43 +602,9 @@ Then in your application you can reference the secondary Rodauth instance:
|
|
649
602
|
rodauth(:admin).login_path #=> "/admin/login"
|
650
603
|
```
|
651
604
|
|
652
|
-
|
653
|
-
configuration to the database
|
654
|
-
that
|
655
|
-
|
656
|
-
### Sharing configuration
|
657
|
-
|
658
|
-
If there are common settings that you want to share between Rodauth
|
659
|
-
configurations, you can do so via inheritance:
|
660
|
-
|
661
|
-
```rb
|
662
|
-
# app/misc/rodauth_base.rb
|
663
|
-
class RodauthBase < Rodauth::Rails::Auth
|
664
|
-
# common settings that are shared between multiple configurations
|
665
|
-
configure do
|
666
|
-
enable :login, :logout
|
667
|
-
login_return_to_requested_location? true
|
668
|
-
logout_redirect "/"
|
669
|
-
# ...
|
670
|
-
end
|
671
|
-
end
|
672
|
-
```
|
673
|
-
```rb
|
674
|
-
# app/misc/rodauth_main.rb
|
675
|
-
class RodauthMain < RodauthBase # inherit common settings
|
676
|
-
configure do
|
677
|
-
# ... customize main ...
|
678
|
-
end
|
679
|
-
end
|
680
|
-
```
|
681
|
-
```rb
|
682
|
-
# app/misc/rodauth_admin.rb
|
683
|
-
class RodauthAdmin < RodauthBase # inherit common settings
|
684
|
-
configure do
|
685
|
-
# ... customize admin ...
|
686
|
-
end
|
687
|
-
end
|
688
|
-
```
|
605
|
+
You'll likely want to save the information of which account belongs to which
|
606
|
+
configuration to the database, see [this guide][account types] on how you can do
|
607
|
+
that. Note that you can also [share configuration via inheritance][inheritance].
|
689
608
|
|
690
609
|
## Outside of a request
|
691
610
|
|
@@ -772,6 +691,34 @@ Rodauth::Rails.rodauth(session: { two_factor_auth_setup: true })
|
|
772
691
|
Rodauth::Rails.rodauth(:admin, params: { "param" => "value" })
|
773
692
|
```
|
774
693
|
|
694
|
+
### Using as a library
|
695
|
+
|
696
|
+
Rodauth offers a `Rodauth.lib` method for configuring Rodauth so that it can be used as a library, instead of routing requests (see [internal_request] feature). This gem provides a `Rodauth::Rails.lib` counterpart that does the same but with Rails integration:
|
697
|
+
|
698
|
+
```rb
|
699
|
+
# app/misc/rodauth_main.rb
|
700
|
+
require "rodauth/rails"
|
701
|
+
require "sequel/core"
|
702
|
+
|
703
|
+
RodauthMain = Rodauth::Rails.lib do
|
704
|
+
enable :create_account, :login, :close_account
|
705
|
+
db Sequel.postgres(extensions: :activerecord_connection, keep_reference: false)
|
706
|
+
# ...
|
707
|
+
end
|
708
|
+
```
|
709
|
+
```rb
|
710
|
+
RodauthMain.create_account(login: "email@example.com", password: "secret123")
|
711
|
+
RodauthMain.login(login: "email@example.com", password: "secret123")
|
712
|
+
RodauthMain.close_account(account_login: "email@example.com")
|
713
|
+
```
|
714
|
+
|
715
|
+
Note that you'll want to skip requiring `rodauth-rails` on Rails boot, so that it doesn't insert the middleware automatically, and remove the initializer.
|
716
|
+
|
717
|
+
```rb
|
718
|
+
# Gemfile
|
719
|
+
gem "rodauth-rails", require: false
|
720
|
+
```
|
721
|
+
|
775
722
|
## Testing
|
776
723
|
|
777
724
|
For system and integration tests, which run the whole middleware stack,
|
@@ -791,13 +738,13 @@ end
|
|
791
738
|
```
|
792
739
|
|
793
740
|
One can write `ActionDispatch::IntegrationTest` test helpers for `login` and
|
794
|
-
`logout` by making requests to the
|
741
|
+
`logout` by making requests to the Rodauth endpoints:
|
795
742
|
|
796
743
|
```rb
|
797
744
|
# test/controllers/articles_controller_test.rb
|
798
745
|
class ArticlesControllerTest < ActionDispatch::IntegrationTest
|
799
|
-
def login(
|
800
|
-
post "/login", params: {
|
746
|
+
def login(email, password)
|
747
|
+
post "/login", params: { email: email, password: password }
|
801
748
|
assert_redirected_to "/"
|
802
749
|
end
|
803
750
|
|
@@ -849,87 +796,48 @@ methods:
|
|
849
796
|
| `rails_controller` | Controller class to use for rendering and CSRF protection. |
|
850
797
|
| `rails_account_model` | Model class connected with the accounts table. |
|
851
798
|
|
799
|
+
```rb
|
800
|
+
class RodauthMain < Rodauth::Rails::Auth
|
801
|
+
configure do
|
802
|
+
rails_controller { Authentication::RodauthController }
|
803
|
+
rails_account_model { Authentication::Account }
|
804
|
+
end
|
805
|
+
end
|
806
|
+
```
|
807
|
+
|
852
808
|
For the list of configuration methods provided by Rodauth, see the [feature
|
853
809
|
documentation].
|
854
810
|
|
855
811
|
### Defining custom methods
|
856
812
|
|
857
813
|
All Rodauth configuration methods are just syntax sugar for defining instance
|
858
|
-
methods on the auth class. You can also define your own custom methods
|
859
|
-
auth class:
|
814
|
+
methods on the auth class. You can also define your own custom methods:
|
860
815
|
|
861
816
|
```rb
|
862
817
|
class RodauthMain < Rodauth::Rails::Auth
|
863
818
|
configure do
|
864
|
-
# ...
|
865
819
|
password_match? { |password| ldap_valid?(password) }
|
866
|
-
# ...
|
867
820
|
end
|
868
821
|
|
869
|
-
|
870
|
-
|
871
|
-
db[:account_identities].where(account_id: account_id).all
|
822
|
+
def admin?
|
823
|
+
rails_account.admin?
|
872
824
|
end
|
873
825
|
|
874
826
|
private
|
875
827
|
|
876
|
-
# Example LDAP authentication
|
877
828
|
def ldap_valid?(password)
|
878
829
|
SimpleLdapAuthenticator.valid?(account[:email], password)
|
879
830
|
end
|
880
831
|
end
|
881
832
|
```
|
882
833
|
```rb
|
883
|
-
rodauth.
|
884
|
-
```
|
885
|
-
|
886
|
-
### Rails URL helpers
|
887
|
-
|
888
|
-
Inside Rodauth configuration and the `route` block you can access Rails route
|
889
|
-
helpers through `#rails_routes`:
|
890
|
-
|
891
|
-
```rb
|
892
|
-
# app/misc/rodauth_main.rb
|
893
|
-
class RodauthMain < Rodauth::Rails::Auth
|
894
|
-
configure do
|
895
|
-
login_redirect { rails_routes.activity_path }
|
896
|
-
change_password_redirect { rails_routes.profile_path }
|
897
|
-
change_login_redirect { rails_routes.profile_path }
|
898
|
-
end
|
899
|
-
end
|
900
|
-
```
|
901
|
-
|
902
|
-
### Calling controller methods
|
903
|
-
|
904
|
-
When using Rodauth before/after hooks or generally overriding your Rodauth
|
905
|
-
configuration, in some cases you might want to call methods defined on your
|
906
|
-
controllers. You can do so with `rails_controller_eval`, for example:
|
907
|
-
|
908
|
-
```rb
|
909
|
-
# app/controllers/application_controller.rb
|
910
|
-
class ApplicationController < ActionController::Base
|
911
|
-
private
|
912
|
-
def setup_tracking(account_id)
|
913
|
-
# ... some implementation ...
|
914
|
-
end
|
915
|
-
end
|
916
|
-
```
|
917
|
-
```rb
|
918
|
-
# app/misc/rodauth_main.rb
|
919
|
-
class RodauthMain < Rodauth::Rails::Auth
|
920
|
-
configure do
|
921
|
-
after_create_account do
|
922
|
-
rails_controller_eval { setup_tracking(account_id) }
|
923
|
-
end
|
924
|
-
end
|
925
|
-
end
|
834
|
+
rodauth.admin? #=> true
|
926
835
|
```
|
927
836
|
|
928
837
|
### Single-file configuration
|
929
838
|
|
930
|
-
If you would prefer
|
931
|
-
|
932
|
-
anonymous auth class.
|
839
|
+
If you would prefer, you can have all your Rodauth logic contained inside the
|
840
|
+
Rodauth app class:
|
933
841
|
|
934
842
|
```rb
|
935
843
|
# app/misc/rodauth_app.rb
|
@@ -952,6 +860,19 @@ class RodauthApp < Rodauth::Rails::App
|
|
952
860
|
end
|
953
861
|
```
|
954
862
|
|
863
|
+
### Manually inserting middleware
|
864
|
+
|
865
|
+
You can choose to insert the Rodauth middleware somewhere earlier than
|
866
|
+
in front of the Rails router:
|
867
|
+
|
868
|
+
```rb
|
869
|
+
Rodauth::Rails.configure do |config|
|
870
|
+
config.middleware = false # disable auto-insertion
|
871
|
+
end
|
872
|
+
|
873
|
+
Rails.application.config.middleware.insert_before AnotherMiddleware, Rodauth::Rails::Middleware
|
874
|
+
```
|
875
|
+
|
955
876
|
## How it works
|
956
877
|
|
957
878
|
### Rack middleware
|
@@ -966,16 +887,6 @@ $ rails middleware
|
|
966
887
|
# run MyApp::Application.routes
|
967
888
|
```
|
968
889
|
|
969
|
-
It can be inserted at any point in the middleware stack:
|
970
|
-
|
971
|
-
```rb
|
972
|
-
Rodauth::Rails.configure do |config|
|
973
|
-
config.middleware = false # disable auto-insertion
|
974
|
-
end
|
975
|
-
|
976
|
-
Rails.application.config.middleware.insert_before AnotherMiddleware, Rodauth::Rails::Middleware
|
977
|
-
```
|
978
|
-
|
979
890
|
The middleware retrieves the Rodauth app via `Rodauth::Rails.app`, which is
|
980
891
|
specified as a string to keep the class autoloadable and reloadable in
|
981
892
|
development.
|
@@ -1227,12 +1138,12 @@ conduct](CODE_OF_CONDUCT.md).
|
|
1227
1138
|
[sms_codes]: http://rodauth.jeremyevans.net/rdoc/files/doc/sms_codes_rdoc.html
|
1228
1139
|
[recovery_codes]: http://rodauth.jeremyevans.net/rdoc/files/doc/recovery_codes_rdoc.html
|
1229
1140
|
[webauthn]: http://rodauth.jeremyevans.net/rdoc/files/doc/webauthn_rdoc.html
|
1141
|
+
[webauthn_login]: http://rodauth.jeremyevans.net/rdoc/files/doc/webauthn_login_rdoc.html
|
1230
1142
|
[json]: http://rodauth.jeremyevans.net/rdoc/files/doc/json_rdoc.html
|
1231
1143
|
[jwt]: http://rodauth.jeremyevans.net/rdoc/files/doc/jwt_rdoc.html
|
1232
1144
|
[email_auth]: http://rodauth.jeremyevans.net/rdoc/files/doc/email_auth_rdoc.html
|
1233
1145
|
[audit_logging]: http://rodauth.jeremyevans.net/rdoc/files/doc/audit_logging_rdoc.html
|
1234
1146
|
[password protection]: https://github.com/jeremyevans/rodauth#label-Password+Hash+Access+Via+Database+Functions
|
1235
|
-
[bruteforce tokens]: https://github.com/jeremyevans/rodauth#label-Tokens
|
1236
1147
|
[password_complexity]: http://rodauth.jeremyevans.net/rdoc/files/doc/password_complexity_rdoc.html
|
1237
1148
|
[disallow_password_reuse]: http://rodauth.jeremyevans.net/rdoc/files/doc/disallow_password_reuse_rdoc.html
|
1238
1149
|
[password_expiration]: http://rodauth.jeremyevans.net/rdoc/files/doc/password_expiration_rdoc.html
|
@@ -1247,3 +1158,4 @@ conduct](CODE_OF_CONDUCT.md).
|
|
1247
1158
|
[Turbo]: https://turbo.hotwired.dev/
|
1248
1159
|
[rodauth-model]: https://github.com/janko/rodauth-model
|
1249
1160
|
[JSON API]: https://github.com/janko/rodauth-rails/wiki/JSON-API
|
1161
|
+
[inheritance]: http://rodauth.jeremyevans.net/rdoc/files/doc/guides/share_configuration_rdoc.html
|