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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 34d196440d63f28b871b42b21686018546c3e98df2239f69611847a0b3a2546a
4
- data.tar.gz: d73de73af3c8985be686bf512c7b15bdf9bf27ecda1bfe30ad8d8a21964f0de0
3
+ metadata.gz: 8643f8a912963b78be7d03a815b813688304f4e4b2777a1fdade807f79a4c712
4
+ data.tar.gz: 31aadb16115fc826750b7d160dcb572ae9c24255d99a7c640abef5fd157bd319
5
5
  SHA512:
6
- metadata.gz: acddd3554346ce6f7048ac56a59e0f0439312668fbf8e94450fd23d4d2464ad82655e221e6e15cd5755ef9207c49fe56c6fb67d95bbb764989ec39c6ff4df46a
7
- data.tar.gz: a2be70d18c1ac8f1d6fca8eaef39a54c88a468dc96140eff05b5bb6bf9c901b93de64fd71c9dc27ef302edf643d024e34141b9258b3879a75e0aa96af28b7a27
6
+ metadata.gz: dd27d717b3a01f0b5f43e346c0cd839e2703ee0db44f7503eb6ce80f7cffd4493f4ed9e208db474af56af536f675444170f16a6d47435e1f4ce2af38a7487916
7
+ data.tar.gz: bbac5b7492751e76886a5bcd275af78aada1026d2cd95ddee732817e8d7a5a154f559e5c27ce08606d444a1ffd4640f8522744bd13939f6491288d57c986fea0
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 1.1.0 (2022-01-16)
2
+
3
+ * Automatically route the path prefix in `r.rodauth` if one has been set (@janko)
4
+
1
5
  ## 1.0.0 (2021-12-25)
2
6
 
3
7
  * Set Rodauth's email subject in the generated mailer (@janko)
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2020 Janko Marohnić
3
+ Copyright (c) 2020-2022 Janko Marohnić
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
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 the Rodauth middleware, and
99
- not a Rails controller, Rodauth routes will not show in `rails routes`.
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 RodauthMain
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 Requests
15
+ # ==> Authenticating requests
16
16
  # Call `rodauth.require_authentication` for requests that you want to
17
- # require authentication for. Some examples:
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.on "admin" do
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
@@ -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
@@ -1,5 +1,5 @@
1
1
  module Rodauth
2
2
  module Rails
3
- VERSION = "1.0.0"
3
+ VERSION = "1.1.0"
4
4
  end
5
5
  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.0.0
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: 2021-12-25 00:00:00.000000000 Z
11
+ date: 2022-01-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties