rodauth-rails 1.0.0 → 1.1.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 +4 -0
- data/LICENSE.txt +1 -1
- data/README.md +174 -135
- data/lib/generators/rodauth/templates/app/misc/rodauth_app.rb +3 -14
- data/lib/rodauth/rails/app.rb +17 -0
- data/lib/rodauth/rails/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8643f8a912963b78be7d03a815b813688304f4e4b2777a1fdade807f79a4c712
|
4
|
+
data.tar.gz: 31aadb16115fc826750b7d160dcb572ae9c24255d99a7c640abef5fd157bd319
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dd27d717b3a01f0b5f43e346c0cd839e2703ee0db44f7503eb6ce80f7cffd4493f4ed9e208db474af56af536f675444170f16a6d47435e1f4ce2af38a7487916
|
7
|
+
data.tar.gz: bbac5b7492751e76886a5bcd275af78aada1026d2cd95ddee732817e8d7a5a154f559e5c27ce08606d444a1ffd4640f8522744bd13939f6491288d57c986fea0
|
data/CHANGELOG.md
CHANGED
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -95,8 +95,8 @@ config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
|
|
95
95
|
|
96
96
|
### Routes
|
97
97
|
|
98
|
-
Because requests to Rodauth endpoints are handled by
|
99
|
-
|
98
|
+
Because requests to Rodauth endpoints are handled by a Rack middleware (and not
|
99
|
+
a Rails controller), Rodauth routes will not show in `rails routes`.
|
100
100
|
|
101
101
|
Use the `rodauth:routes` rake task to view the list of endpoints based on
|
102
102
|
currently loaded features:
|
@@ -609,21 +609,12 @@ them under a name.
|
|
609
609
|
```rb
|
610
610
|
# app/misc/rodauth_app.rb
|
611
611
|
class RodauthApp < Rodauth::Rails::App
|
612
|
-
# primary configuration
|
613
|
-
configure
|
614
|
-
|
615
|
-
# secondary configuration
|
616
|
-
configure RodauthAdmin, :admin
|
612
|
+
configure RodauthMain # primary configuration
|
613
|
+
configure RodauthAdmin, :admin # secondary configuration
|
617
614
|
|
618
615
|
route do |r|
|
619
|
-
r.rodauth
|
620
|
-
|
621
|
-
r.on "admin" do
|
622
|
-
r.rodauth(:admin)
|
623
|
-
break # allow routing of other /admin/* requests to continue to Rails
|
624
|
-
end
|
625
|
-
|
626
|
-
# ...
|
616
|
+
r.rodauth # route primary rodauth requests
|
617
|
+
r.rodauth(:admin) # route secondary rodauth requests
|
627
618
|
end
|
628
619
|
end
|
629
620
|
```
|
@@ -635,7 +626,6 @@ class RodauthAdmin < Rodauth::Rails::Auth
|
|
635
626
|
prefix "/admin"
|
636
627
|
session_key_prefix "admin_"
|
637
628
|
remember_cookie_key "_admin_remember" # if using remember feature
|
638
|
-
# ...
|
639
629
|
|
640
630
|
# search views in `app/views/admin/rodauth` directory
|
641
631
|
rails_controller { Admin::RodauthController }
|
@@ -717,10 +707,6 @@ RodauthApp.rodauth.verify_account(account_login: "user@example.com")
|
|
717
707
|
RodauthApp.rodauth(:admin).close_account(account_login: "user@example.com")
|
718
708
|
```
|
719
709
|
|
720
|
-
The rodauth-rails gem additionally updates the internal rack env hash with your
|
721
|
-
`config.action_mailer.default_url_options`, which is used for generating email
|
722
|
-
links.
|
723
|
-
|
724
710
|
### Generating URLs
|
725
711
|
|
726
712
|
For generating authentication URLs outside of a request use the
|
@@ -781,104 +767,6 @@ Rodauth::Rails.rodauth(session: { two_factor_auth_setup: true })
|
|
781
767
|
Rodauth::Rails.rodauth(:admin, params: { "param" => "value" })
|
782
768
|
```
|
783
769
|
|
784
|
-
## How it works
|
785
|
-
|
786
|
-
### Middleware
|
787
|
-
|
788
|
-
rodauth-rails inserts a `Rodauth::Rails::Middleware` into your middleware
|
789
|
-
stack, which calls your Rodauth app for each request, before the request
|
790
|
-
reaches the Rails router.
|
791
|
-
|
792
|
-
```sh
|
793
|
-
$ rails middleware
|
794
|
-
...
|
795
|
-
use Rodauth::Rails::Middleware
|
796
|
-
run MyApp::Application.routes
|
797
|
-
```
|
798
|
-
|
799
|
-
The Rodauth app stores the `Rodauth::Auth` instance in the Rack env hash, which
|
800
|
-
is then available in your Rails app:
|
801
|
-
|
802
|
-
```rb
|
803
|
-
request.env["rodauth"] #=> #<Rodauth::Auth>
|
804
|
-
request.env["rodauth.admin"] #=> #<Rodauth::Auth> (if using multiple configurations)
|
805
|
-
```
|
806
|
-
|
807
|
-
For convenience, this object can be accessed via the `#rodauth` method in views
|
808
|
-
and controllers:
|
809
|
-
|
810
|
-
```rb
|
811
|
-
class MyController < ApplicationController
|
812
|
-
def my_action
|
813
|
-
rodauth #=> #<Rodauth::Auth>
|
814
|
-
rodauth(:admin) #=> #<Rodauth::Auth> (if using multiple configurations)
|
815
|
-
end
|
816
|
-
end
|
817
|
-
```
|
818
|
-
```erb
|
819
|
-
<% rodauth #=> #<Rodauth::Auth> %>
|
820
|
-
<% rodauth(:admin) #=> #<Rodauth::Auth> (if using multiple configurations) %>
|
821
|
-
```
|
822
|
-
|
823
|
-
### App
|
824
|
-
|
825
|
-
The `Rodauth::Rails::App` class is a [Roda] subclass that provides Rails
|
826
|
-
integration for Rodauth:
|
827
|
-
|
828
|
-
* uses Action Dispatch flash instead of Roda's
|
829
|
-
* uses Action Dispatch CSRF protection instead of Roda's
|
830
|
-
* sets [HMAC] secret to Rails' secret key base
|
831
|
-
* uses Action Controller for rendering templates
|
832
|
-
* runs Action Controller callbacks & rescue handlers around Rodauth actions
|
833
|
-
* uses Action Mailer for sending emails
|
834
|
-
|
835
|
-
The `configure` method wraps configuring the Rodauth plugin, forwarding
|
836
|
-
any additional [plugin options].
|
837
|
-
|
838
|
-
```rb
|
839
|
-
class RodauthApp < Rodauth::Rails::App
|
840
|
-
configure { ... } # defining default Rodauth configuration
|
841
|
-
configure(json: true) { ... } # passing options to the Rodauth plugin
|
842
|
-
configure(:admin) { ... } # defining multiple Rodauth configurations
|
843
|
-
end
|
844
|
-
```
|
845
|
-
|
846
|
-
The `route` block is provided by Roda, and it's called on each request before
|
847
|
-
it reaches the Rails router.
|
848
|
-
|
849
|
-
```rb
|
850
|
-
class RodauthApp < Rodauth::Rails::App
|
851
|
-
route do |r|
|
852
|
-
# ... called before each request ...
|
853
|
-
end
|
854
|
-
end
|
855
|
-
```
|
856
|
-
|
857
|
-
Since `Rodauth::Rails::App` is just a Roda subclass, you can do anything you
|
858
|
-
would with a Roda app, such as loading additional Roda plugins:
|
859
|
-
|
860
|
-
```rb
|
861
|
-
class RodauthApp < Rodauth::Rails::App
|
862
|
-
plugin :request_headers # easier access to request headers
|
863
|
-
plugin :typecast_params # methods for conversion of request params
|
864
|
-
plugin :default_headers, { "Foo" => "Bar" }
|
865
|
-
# ...
|
866
|
-
end
|
867
|
-
```
|
868
|
-
|
869
|
-
### Sequel
|
870
|
-
|
871
|
-
Rodauth uses the [Sequel] library for database queries, due to more advanced
|
872
|
-
database usage (SQL expressions, database-agnostic date arithmetic, SQL
|
873
|
-
function calls).
|
874
|
-
|
875
|
-
If ActiveRecord is used in the application, the `rodauth:install` generator
|
876
|
-
will have automatically configured Sequel to reuse ActiveRecord's database
|
877
|
-
connection, using the [sequel-activerecord_connection] gem.
|
878
|
-
|
879
|
-
This means that, from the usage perspective, Sequel can be considered just
|
880
|
-
as an implementation detail of Rodauth.
|
881
|
-
|
882
770
|
## Configuring
|
883
771
|
|
884
772
|
### Configuration methods
|
@@ -897,23 +785,6 @@ methods:
|
|
897
785
|
| `rails_controller` | Controller class to use for rendering and CSRF protection. |
|
898
786
|
| `rails_account_model` | Model class connected with the accounts table. |
|
899
787
|
|
900
|
-
### General configuration
|
901
|
-
|
902
|
-
The `Rodauth::Rails` module has a few config settings available as well:
|
903
|
-
|
904
|
-
| Name | Description |
|
905
|
-
| :----- | :---------- |
|
906
|
-
| `app` | Constant name of your Rodauth app, which is called by the middleware. |
|
907
|
-
| `middleware` | Whether to insert the middleware into the Rails application's middleware stack. Defaults to `true`. |
|
908
|
-
|
909
|
-
```rb
|
910
|
-
# config/initializers/rodauth.rb
|
911
|
-
Rodauth::Rails.configure do |config|
|
912
|
-
config.app = "RodauthApp"
|
913
|
-
config.middleware = true
|
914
|
-
end
|
915
|
-
```
|
916
|
-
|
917
788
|
For the list of configuration methods provided by Rodauth, see the [feature
|
918
789
|
documentation].
|
919
790
|
|
@@ -926,7 +797,9 @@ auth class:
|
|
926
797
|
```rb
|
927
798
|
class RodauthMain < Rodauth::Rails::Auth
|
928
799
|
configure do
|
800
|
+
# ...
|
929
801
|
password_match? { |password| ldap_valid?(password) }
|
802
|
+
# ...
|
930
803
|
end
|
931
804
|
|
932
805
|
# Example external identities table
|
@@ -1013,6 +886,172 @@ class RodauthApp < Rodauth::Rails::App
|
|
1013
886
|
end
|
1014
887
|
```
|
1015
888
|
|
889
|
+
## How it works
|
890
|
+
|
891
|
+
### Rack middleware
|
892
|
+
|
893
|
+
The railtie inserts [`Rodauth::Rails::Middleware`](/lib/rodauth/rails/middleware.rb)
|
894
|
+
at the end of the middleware stack, which calls your Rodauth app around each request.
|
895
|
+
|
896
|
+
```sh
|
897
|
+
$ rails middleware
|
898
|
+
# ...
|
899
|
+
# use Rodauth::Rails::Middleware
|
900
|
+
# run MyApp::Application.routes
|
901
|
+
```
|
902
|
+
|
903
|
+
It can be inserted at any point in the middleware stack:
|
904
|
+
|
905
|
+
```rb
|
906
|
+
Rodauth::Rails.configure do |config|
|
907
|
+
config.middleware = false # disable auto-insertion
|
908
|
+
end
|
909
|
+
|
910
|
+
Rails.application.config.middleware.insert_before AnotherMiddleware, Rodauth::Rails::Middleware
|
911
|
+
```
|
912
|
+
|
913
|
+
The middleware retrieves the Rodauth app via `Rodauth::Rails.app`, which is
|
914
|
+
specified as a string to keep the class autoloadable and reloadable in
|
915
|
+
development.
|
916
|
+
|
917
|
+
```rb
|
918
|
+
Rodauth::Rails.configure do |config|
|
919
|
+
config.app = "RodauthApp"
|
920
|
+
end
|
921
|
+
```
|
922
|
+
|
923
|
+
In addition to Zeitwerk compatibility, this extra layer catches Rodauth redirects
|
924
|
+
that happen on the controller level (e.g. when calling
|
925
|
+
`rodauth.require_authentication` in a `before_action` filter).
|
926
|
+
|
927
|
+
### Roda app
|
928
|
+
|
929
|
+
The [`Rodauth::Rails::App`](/lib/rodauth/rails/app.rb) class is a [Roda]
|
930
|
+
subclass that provides a convenience layer for Rodauth:
|
931
|
+
|
932
|
+
* uses Action Dispatch flash messages
|
933
|
+
* provides syntax sugar for loading the rodauth plugin
|
934
|
+
* saves Rodauth object(s) to Rack env hash
|
935
|
+
* propagates edited headers to Rails responses
|
936
|
+
|
937
|
+
#### Configure block
|
938
|
+
|
939
|
+
The `configure` call loads the rodauth plugin. By convention, it receives an
|
940
|
+
auth class and configuration name as positional arguments (forwarded as
|
941
|
+
`:auth_class` and `:name` plugin options), a block for anonymous auth classes,
|
942
|
+
and also accepts any additional plugin options.
|
943
|
+
|
944
|
+
```rb
|
945
|
+
class RodauthApp < Rodauth::Rails::App
|
946
|
+
# named auth class
|
947
|
+
configure(RodauthMain)
|
948
|
+
configure(RodauthAdmin, :admin)
|
949
|
+
|
950
|
+
# anonymous auth class
|
951
|
+
configure { ... }
|
952
|
+
configure(:admin) { ... }
|
953
|
+
|
954
|
+
# plugin options
|
955
|
+
configure(RodauthMain, json: :only)
|
956
|
+
end
|
957
|
+
```
|
958
|
+
|
959
|
+
#### Route block
|
960
|
+
|
961
|
+
The `route` block is called for each request, before it reaches the Rails
|
962
|
+
router, and it's yielded the request object.
|
963
|
+
|
964
|
+
```rb
|
965
|
+
class RodauthApp < Rodauth::Rails::App
|
966
|
+
route do |r|
|
967
|
+
# called before each request
|
968
|
+
end
|
969
|
+
end
|
970
|
+
```
|
971
|
+
|
972
|
+
#### Routing prefix
|
973
|
+
|
974
|
+
If you use a routing prefix, you don't need to add a call to `r.on` like with
|
975
|
+
vanilla Rodauth, as `r.rodauth` has been modified to automatically route the
|
976
|
+
prefix.
|
977
|
+
|
978
|
+
```rb
|
979
|
+
class RodauthApp < Rodauth::Rails::App
|
980
|
+
configure do
|
981
|
+
prefix "/user"
|
982
|
+
end
|
983
|
+
|
984
|
+
route do |r|
|
985
|
+
r.rodauth # no need to wrap with `r.on("user") { ... }`
|
986
|
+
end
|
987
|
+
end
|
988
|
+
```
|
989
|
+
|
990
|
+
### Auth class
|
991
|
+
|
992
|
+
The [`Rodauth::Rails::Auth`](/lib/rodauth/rails/auth.rb) class is a subclass of
|
993
|
+
`Rodauth::Auth`, which preloads the `rails` rodauth feature, sets [HMAC] secret to
|
994
|
+
Rails' secret key base, and modifies some [configuration defaults](#rodauth-defaults).
|
995
|
+
|
996
|
+
```rb
|
997
|
+
class RodauthMain < Rodauth::Rails::Auth
|
998
|
+
configure do
|
999
|
+
# authentication configuration
|
1000
|
+
end
|
1001
|
+
end
|
1002
|
+
```
|
1003
|
+
|
1004
|
+
### Rodauth feature
|
1005
|
+
|
1006
|
+
The [`rails`](/lib/rodauth/rails/feature.rb) Rodauth feature loaded by
|
1007
|
+
`Rodauth::Rails::Auth` provides the main part of the Rails integration for Rodauth:
|
1008
|
+
|
1009
|
+
* uses Action View for template rendering
|
1010
|
+
* uses Action Dispatch for CSRF protection
|
1011
|
+
* runs Action Controller callbacks and rescue from blocks around Rodauth requests
|
1012
|
+
* uses Action Mailer to create and deliver emails
|
1013
|
+
* uses Action Controller instrumentation around Rodauth requests
|
1014
|
+
* uses Action Mailer's default URL options when calling Rodauth outside of a request
|
1015
|
+
|
1016
|
+
### Controller
|
1017
|
+
|
1018
|
+
The Rodauth app stores the `Rodauth::Rails::Auth` instances in the Rack env
|
1019
|
+
hash, which is then available in your Rails app:
|
1020
|
+
|
1021
|
+
```rb
|
1022
|
+
request.env["rodauth"] #=> #<RodauthMain>
|
1023
|
+
request.env["rodauth.admin"] #=> #<RodauthAdmin> (if using multiple configurations)
|
1024
|
+
```
|
1025
|
+
|
1026
|
+
For convenience, this object can be accessed via the `#rodauth` method in views
|
1027
|
+
and controllers:
|
1028
|
+
|
1029
|
+
```rb
|
1030
|
+
class MyController < ApplicationController
|
1031
|
+
def my_action
|
1032
|
+
rodauth #=> #<RodauthMain>
|
1033
|
+
rodauth(:admin) #=> #<RodauthAdmin> (if using multiple configurations)
|
1034
|
+
end
|
1035
|
+
end
|
1036
|
+
```
|
1037
|
+
```erb
|
1038
|
+
<% rodauth #=> #<RodauthMain> %>
|
1039
|
+
<% rodauth(:admin) #=> #<RodauthAdmin> (if using multiple configurations) %>
|
1040
|
+
```
|
1041
|
+
|
1042
|
+
### Sequel
|
1043
|
+
|
1044
|
+
Rodauth uses the [Sequel] library for database interaction, which offers
|
1045
|
+
powerful APIs for building advanced queries (it supports SQL expressions,
|
1046
|
+
database-agnostic date arithmetic, SQL function calls).
|
1047
|
+
|
1048
|
+
If you're using Active Record in your application, the `rodauth:install`
|
1049
|
+
generator automatically configures Sequel to reuse ActiveRecord's database
|
1050
|
+
connection, using the [sequel-activerecord_connection] gem.
|
1051
|
+
|
1052
|
+
This means that, from the usage perspective, Sequel can be considered just
|
1053
|
+
as an implementation detail of Rodauth.
|
1054
|
+
|
1016
1055
|
## Rodauth defaults
|
1017
1056
|
|
1018
1057
|
rodauth-rails changes some of the default Rodauth settings for easier setup:
|
@@ -12,12 +12,9 @@ class RodauthApp < Rodauth::Rails::App
|
|
12
12
|
<% end -%>
|
13
13
|
r.rodauth # route rodauth requests
|
14
14
|
|
15
|
-
# ==> Authenticating
|
15
|
+
# ==> Authenticating requests
|
16
16
|
# Call `rodauth.require_authentication` for requests that you want to
|
17
|
-
# require authentication for.
|
18
|
-
#
|
19
|
-
# next if r.path.start_with?("/docs") # skip authentication for documentation pages
|
20
|
-
# next if session[:admin] # skip authentication for admins
|
17
|
+
# require authentication for. For example:
|
21
18
|
#
|
22
19
|
# # authenticate /dashboard/* and /account/* requests
|
23
20
|
# if r.path.start_with?("/dashboard") || r.path.start_with?("/account")
|
@@ -25,14 +22,6 @@ class RodauthApp < Rodauth::Rails::App
|
|
25
22
|
# end
|
26
23
|
|
27
24
|
# ==> Secondary configurations
|
28
|
-
# r.
|
29
|
-
# r.rodauth(:admin)
|
30
|
-
#
|
31
|
-
# unless rodauth(:admin).logged_in?
|
32
|
-
# rodauth(:admin).require_http_basic_auth
|
33
|
-
# end
|
34
|
-
#
|
35
|
-
# break # allow the Rails app to handle other "/admin/*" requests
|
36
|
-
# end
|
25
|
+
# r.rodauth(:admin) # route admin rodauth requests
|
37
26
|
end
|
38
27
|
end
|
data/lib/rodauth/rails/app.rb
CHANGED
@@ -25,6 +25,8 @@ module Rodauth
|
|
25
25
|
auth_class ||= Class.new(Rodauth::Rails::Auth)
|
26
26
|
|
27
27
|
plugin :rodauth, auth_class: auth_class, name: name, csrf: false, flash: false, json: true, **options, &block
|
28
|
+
|
29
|
+
self::RodaRequest.include RequestMethods
|
28
30
|
end
|
29
31
|
|
30
32
|
before do
|
@@ -44,6 +46,21 @@ module Rodauth
|
|
44
46
|
def self.rodauth!(name)
|
45
47
|
rodauth(name) or fail ArgumentError, "unknown rodauth configuration: #{name.inspect}"
|
46
48
|
end
|
49
|
+
|
50
|
+
module RequestMethods
|
51
|
+
def rodauth(name = nil)
|
52
|
+
prefix = scope.rodauth(name).prefix
|
53
|
+
|
54
|
+
if prefix.present? && remaining_path == path_info
|
55
|
+
on prefix[1..-1] do
|
56
|
+
super
|
57
|
+
break # forward other `{prefix}/*` requests to the rails router
|
58
|
+
end
|
59
|
+
else
|
60
|
+
super
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
47
64
|
end
|
48
65
|
end
|
49
66
|
end
|
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.1.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:
|
11
|
+
date: 2022-01-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|