rodauth-rails 1.10.0 → 1.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +27 -17
- data/lib/rodauth/rails/app.rb +4 -3
- data/lib/rodauth/rails/tasks/routes.rb +70 -0
- data/lib/rodauth/rails/tasks.rake +6 -36
- data/lib/rodauth/rails/version.rb +1 -1
- data/lib/rodauth/rails.rb +12 -3
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f902ae05472454543304221221b9681c7dab3d231d6551c7e82b6c4c1570dc8
|
4
|
+
data.tar.gz: b3a1948fb603be978bddea73a44b8109f4e3c76e132b2da3a8e6aad1b36f3d14
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8547335032c3e0851406932463cd62e2377c16db2145e0da6abb8a7f20745c20f9e8d54bd2b57599e335a4f9b37078cf7f1c17caa53b4dab60105c410a401469
|
7
|
+
data.tar.gz: dd84bd6d57a4e8e78a6412a7ac38befa7d75ef693a6788014d383d3800a4535af71fa24239f8b0521cecc7c598766f48b2034a016a2a15235cfa9f9d2dd52761
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
## 1.11.0 (2023-08-21)
|
2
|
+
|
3
|
+
* Exclude WebAuthn JS routes in `rodauth:routes`, since those stop being relevant with custom JS (@janko)
|
4
|
+
|
5
|
+
* Separate HTTP verbs with `|` symbol in `rodauth:routes` for consistency with `rails routes` (@janko)
|
6
|
+
|
7
|
+
* Include two factor manage & auth JSON POST routes in `rodauth:routes` task (@janko)
|
8
|
+
|
9
|
+
* Make `rodauth:routes` rake task appear in `rails -T` list (@janko)
|
10
|
+
|
11
|
+
* Accept plugin options in `Rodauth::Rails.lib` (@janko)
|
12
|
+
|
13
|
+
* Support skipping loading Roda `render` plugin by passing `render: false` (@janko)
|
14
|
+
|
1
15
|
## 1.10.0 (2023-07-26)
|
2
16
|
|
3
17
|
* Add `Rodauth::Rails.lib` for easier usage of Rodauth as a library in Rails apps (@janko)
|
data/README.md
CHANGED
@@ -134,18 +134,18 @@ $ rails rodauth:routes
|
|
134
134
|
```
|
135
135
|
Routes handled by RodauthApp:
|
136
136
|
|
137
|
-
GET
|
138
|
-
GET
|
139
|
-
GET
|
140
|
-
GET
|
141
|
-
GET
|
142
|
-
GET
|
143
|
-
GET
|
144
|
-
GET
|
145
|
-
GET
|
146
|
-
GET
|
147
|
-
GET
|
148
|
-
GET
|
137
|
+
GET|POST /login rodauth.login_path
|
138
|
+
GET|POST /create-account rodauth.create_account_path
|
139
|
+
GET|POST /verify-account-resend rodauth.verify_account_resend_path
|
140
|
+
GET|POST /verify-account rodauth.verify_account_path
|
141
|
+
GET|POST /change-password rodauth.change_password_path
|
142
|
+
GET|POST /change-login rodauth.change_login_path
|
143
|
+
GET|POST /logout rodauth.logout_path
|
144
|
+
GET|POST /remember rodauth.remember_path
|
145
|
+
GET|POST /reset-password-request rodauth.reset_password_request_path
|
146
|
+
GET|POST /reset-password rodauth.reset_password_path
|
147
|
+
GET|POST /verify-login-change rodauth.verify_login_change_path
|
148
|
+
GET|POST /close-account rodauth.close_account_path
|
149
149
|
```
|
150
150
|
|
151
151
|
Using this information, you can add some basic authentication links to your
|
@@ -236,7 +236,7 @@ level. You can do this via the built-in `authenticated` routing constraint:
|
|
236
236
|
```rb
|
237
237
|
# config/routes.rb
|
238
238
|
Rails.application.routes.draw do
|
239
|
-
constraints Rodauth::Rails.
|
239
|
+
constraints Rodauth::Rails.authenticate do
|
240
240
|
# ... authenticated routes ...
|
241
241
|
end
|
242
242
|
end
|
@@ -249,7 +249,7 @@ called with the Rodauth instance:
|
|
249
249
|
# config/routes.rb
|
250
250
|
Rails.application.routes.draw do
|
251
251
|
# require multifactor authentication to be setup
|
252
|
-
constraints Rodauth::Rails.
|
252
|
+
constraints Rodauth::Rails.authenticate { |rodauth| rodauth.uses_two_factor_authentication? } do
|
253
253
|
# ...
|
254
254
|
end
|
255
255
|
end
|
@@ -260,7 +260,7 @@ You can specify a different Rodauth configuration by passing the configuration n
|
|
260
260
|
```rb
|
261
261
|
# config/routes.rb
|
262
262
|
Rails.application.routes.draw do
|
263
|
-
constraints Rodauth::Rails.
|
263
|
+
constraints Rodauth::Rails.authenticate(:admin) do
|
264
264
|
# ...
|
265
265
|
end
|
266
266
|
end
|
@@ -712,12 +712,22 @@ RodauthMain.login(login: "email@example.com", password: "secret123")
|
|
712
712
|
RodauthMain.close_account(account_login: "email@example.com")
|
713
713
|
```
|
714
714
|
|
715
|
-
Note that you'll want to skip requiring `rodauth-rails` on Rails boot,
|
715
|
+
Note that you'll want to skip requiring `rodauth-rails` on Rails boot, to avoid it automatically inserting the Rodauth middleware, and remove some unnecessary files generated by the install generator.
|
716
716
|
|
717
717
|
```rb
|
718
718
|
# Gemfile
|
719
719
|
gem "rodauth-rails", require: false
|
720
720
|
```
|
721
|
+
```sh
|
722
|
+
$ rm config/initializers/rodauth.rb app/misc/rodauth_app.rb app/controllers/rodauth_controller.rb
|
723
|
+
```
|
724
|
+
|
725
|
+
The `Rodauth::Rails.lib` call will forward any Rodauth [plugin options] passed to it:
|
726
|
+
|
727
|
+
```rb
|
728
|
+
# skips loading Roda render plugin and Tilt gem (used for rendering built-in templates)
|
729
|
+
Rodauth::Rails.lib(render: false) { ... }
|
730
|
+
```
|
721
731
|
|
722
732
|
## Testing
|
723
733
|
|
@@ -929,7 +939,7 @@ class RodauthApp < Rodauth::Rails::App
|
|
929
939
|
configure(:admin) { ... }
|
930
940
|
|
931
941
|
# plugin options
|
932
|
-
configure(RodauthMain, json: :only)
|
942
|
+
configure(RodauthMain, json: :only, render: false)
|
933
943
|
end
|
934
944
|
```
|
935
945
|
|
data/lib/rodauth/rails/app.rb
CHANGED
@@ -18,16 +18,17 @@ module Rodauth
|
|
18
18
|
end
|
19
19
|
|
20
20
|
plugin :hooks
|
21
|
-
plugin :render, layout: false
|
22
21
|
plugin :pass
|
23
22
|
|
24
23
|
def self.configure(*args, **options, &block)
|
25
24
|
auth_class = args.shift if args[0].is_a?(Class)
|
26
|
-
|
25
|
+
auth_class ||= Class.new(Rodauth::Rails::Auth)
|
26
|
+
name = args.shift if args[0].is_a?(Symbol)
|
27
27
|
|
28
28
|
fail ArgumentError, "need to pass optional Rodauth::Auth subclass and optional configuration name" if args.any?
|
29
29
|
|
30
|
-
|
30
|
+
# we'll render Rodauth's built-in view templates within Rails layouts
|
31
|
+
plugin :render, layout: false unless options[:render] == false
|
31
32
|
|
32
33
|
plugin :rodauth, auth_class: auth_class, name: name, csrf: false, flash: false, json: true, **options, &block
|
33
34
|
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Rodauth
|
2
|
+
module Rails
|
3
|
+
module Tasks
|
4
|
+
class Routes
|
5
|
+
IGNORE = [:webauthn_setup_js, :webauthn_auth_js, :webauthn_autofill_js]
|
6
|
+
JSON_POST = [:two_factor_manage, :two_factor_auth]
|
7
|
+
|
8
|
+
attr_reader :auth_class
|
9
|
+
|
10
|
+
def initialize(auth_class)
|
11
|
+
@auth_class = auth_class
|
12
|
+
end
|
13
|
+
|
14
|
+
def call
|
15
|
+
routes = auth_class.route_hash.map do |path, handle_method|
|
16
|
+
route_name = handle_method.to_s.sub(/\Ahandle_/, "").to_sym
|
17
|
+
next if IGNORE.include?(route_name)
|
18
|
+
verbs = route_verbs(route_name)
|
19
|
+
|
20
|
+
[
|
21
|
+
verbs.join("|"),
|
22
|
+
"#{rodauth.prefix}#{path}",
|
23
|
+
"rodauth#{configuration_name && "(:#{configuration_name})"}.#{route_name}_path",
|
24
|
+
]
|
25
|
+
end
|
26
|
+
|
27
|
+
routes.compact!
|
28
|
+
padding = routes.transpose.map { |string| string.map(&:length).max }
|
29
|
+
|
30
|
+
output_lines = routes.map do |columns|
|
31
|
+
[columns[0].ljust(padding[0]), columns[1].ljust(padding[1]), columns[2]].join(" ")
|
32
|
+
end
|
33
|
+
|
34
|
+
puts "\n #{output_lines.join("\n ")}"
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def route_verbs(route_name)
|
40
|
+
file_path, start_line = rodauth.method(:"_handle_#{route_name}").source_location
|
41
|
+
lines = File.foreach(file_path).to_a
|
42
|
+
indentation = lines[start_line - 1][/^\s+/]
|
43
|
+
verbs = []
|
44
|
+
|
45
|
+
lines[start_line..-1].each do |code|
|
46
|
+
verbs << :GET if code.include?("r.get") && !rodauth.only_json?
|
47
|
+
verbs << :POST if code.include?("r.post")
|
48
|
+
break if code.start_with?("#{indentation}end")
|
49
|
+
end
|
50
|
+
|
51
|
+
verbs << :POST if rodauth.features.include?(:json) && JSON_POST.include?(route_name)
|
52
|
+
verbs
|
53
|
+
end
|
54
|
+
|
55
|
+
def rodauth
|
56
|
+
auth_class.new(scope)
|
57
|
+
end
|
58
|
+
|
59
|
+
def scope
|
60
|
+
auth_class.roda_class.new({})
|
61
|
+
end
|
62
|
+
|
63
|
+
def configuration_name
|
64
|
+
auth_class.configuration_name
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
@@ -1,42 +1,12 @@
|
|
1
|
+
require "rodauth/rails/tasks/routes"
|
2
|
+
|
1
3
|
namespace :rodauth do
|
4
|
+
desc "Lists endpoints that will be routed by your Rodauth app"
|
2
5
|
task routes: :environment do
|
3
|
-
|
4
|
-
|
5
|
-
puts "Routes handled by #{app}:"
|
6
|
-
|
7
|
-
app.opts[:rodauths].each do |configuration_name, auth_class|
|
8
|
-
rodauth = auth_class.allocate
|
9
|
-
only_json = rodauth.method(:only_json?).owner != Rodauth::Base && rodauth.only_json?
|
10
|
-
|
11
|
-
routes = auth_class.route_hash.map do |path, handle_method|
|
12
|
-
file_path, start_line = rodauth.method(:"_#{handle_method}").source_location
|
13
|
-
lines = File.foreach(file_path).to_a
|
14
|
-
indentation = lines[start_line - 1][/^\s+/]
|
15
|
-
verbs = []
|
16
|
-
|
17
|
-
lines[start_line..-1].each do |code|
|
18
|
-
verbs << :GET if code.include?("r.get") && !only_json
|
19
|
-
verbs << :POST if code.include?("r.post")
|
20
|
-
break if code.start_with?("#{indentation}end")
|
21
|
-
end
|
22
|
-
|
23
|
-
path_method = "#{handle_method.to_s.sub(/\Ahandle_/, "")}_path"
|
24
|
-
|
25
|
-
[
|
26
|
-
verbs.join("/"),
|
27
|
-
"#{rodauth.prefix}#{path}",
|
28
|
-
"rodauth#{configuration_name && "(:#{configuration_name})"}.#{path_method}",
|
29
|
-
]
|
30
|
-
end
|
31
|
-
|
32
|
-
verbs_padding = routes.map { |verbs, _, _| verbs.length }.max
|
33
|
-
path_padding = routes.map { |_, path, _| path.length }.max
|
34
|
-
|
35
|
-
route_lines = routes.map do |verbs, path, code|
|
36
|
-
"#{verbs.ljust(verbs_padding)} #{path.ljust(path_padding)} #{code}"
|
37
|
-
end
|
6
|
+
puts "Routes handled by #{Rodauth::Rails.app}:"
|
38
7
|
|
39
|
-
|
8
|
+
Rodauth::Rails.app.opts[:rodauths].each_value do |auth_class|
|
9
|
+
Rodauth::Rails::Tasks::Routes.new(auth_class).call
|
40
10
|
end
|
41
11
|
end
|
42
12
|
end
|
data/lib/rodauth/rails.rb
CHANGED
@@ -16,9 +16,9 @@ module Rodauth
|
|
16
16
|
@middleware = true
|
17
17
|
|
18
18
|
class << self
|
19
|
-
def lib(&block)
|
19
|
+
def lib(**options, &block)
|
20
20
|
c = Class.new(Rodauth::Rails::App)
|
21
|
-
c.configure(json: false) do
|
21
|
+
c.configure(json: false, **options) do
|
22
22
|
enable :internal_request
|
23
23
|
instance_exec(&block)
|
24
24
|
end
|
@@ -57,8 +57,17 @@ module Rodauth
|
|
57
57
|
Rodauth::Model.new(app.rodauth!(name), **options)
|
58
58
|
end
|
59
59
|
|
60
|
-
#
|
60
|
+
# Routing constraint that requires authenticated account.
|
61
|
+
def authenticate(name = nil, &condition)
|
62
|
+
lambda do |request|
|
63
|
+
rodauth = request.env.fetch ["rodauth", *name].join(".")
|
64
|
+
rodauth.require_account
|
65
|
+
condition.nil? || condition.call(rodauth)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
61
69
|
def authenticated(name = nil, &condition)
|
70
|
+
warn "Rodauth::Rails.authenticated has been deprecated in favor of Rodauth::Rails.authenticate, which additionally requires existence of the account record."
|
62
71
|
lambda do |request|
|
63
72
|
rodauth = request.env.fetch ["rodauth", *name].join(".")
|
64
73
|
rodauth.require_authentication
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rodauth-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Janko Marohnić
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-08-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -328,6 +328,7 @@ files:
|
|
328
328
|
- lib/rodauth/rails/model.rb
|
329
329
|
- lib/rodauth/rails/railtie.rb
|
330
330
|
- lib/rodauth/rails/tasks.rake
|
331
|
+
- lib/rodauth/rails/tasks/routes.rb
|
331
332
|
- lib/rodauth/rails/test.rb
|
332
333
|
- lib/rodauth/rails/test/controller.rb
|
333
334
|
- lib/rodauth/rails/version.rb
|
@@ -351,7 +352,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
351
352
|
- !ruby/object:Gem::Version
|
352
353
|
version: '0'
|
353
354
|
requirements: []
|
354
|
-
rubygems_version: 3.4.
|
355
|
+
rubygems_version: 3.4.10
|
355
356
|
signing_key:
|
356
357
|
specification_version: 4
|
357
358
|
summary: Provides Rails integration for Rodauth.
|