rodauth-rails 1.2.0 โ†’ 1.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f93b80457e9c6e9ea6083974e05514de8e605b0f9a4015fe765ffc1c4059c5ee
4
- data.tar.gz: '06877735d144b893b1a7a08f125e34316196679e47038112c6df215e352268c6'
3
+ metadata.gz: b1f519c5d15eb6c70585c8cfa625106dec267b4e7f666daeeb9499ef61c656e7
4
+ data.tar.gz: 1bc84d1dba6ab9ab884a56f47419e207655c90f1d71d32b009575ab169fc0b3d
5
5
  SHA512:
6
- metadata.gz: 7f26bf373cb8a64e2e0d5156aff9ca94e468d9eb257dcd2e34f702d43a6506bacdc7a22bd85090ddefddc972ebb25b22f3012bca2f21b84aece970d138159166
7
- data.tar.gz: b5811e6ae069e71f7cd8be35b9bd884c463aa709a1be4abc6fd792bf747ba7aabe0d7aa2f3f4f7c43466f153b163912d55957d0fd84d1314b37ac60ca4a5b221
6
+ metadata.gz: 88ccdb974fe6b6dd0e797cf5307656c80d7038c820eab897b277b6c22bd1bc61cc00e7e39295d2a98fc313530ad658c6be80e043dde595d3514c3a51fa0572a4
7
+ data.tar.gz: d17fc8142a16f18ff485446d94e68ed4672faa64edfa8aaac3b400e9060f9638575a577ff232b83a1360a58e8655199c1ab88972f77a3af0f45d76f3514b7df5
data/CHANGELOG.md CHANGED
@@ -1,3 +1,21 @@
1
+ ## 1.3.0 (2022-04-01)
2
+
3
+ * Store password hash on the `accounts` table in generated Rodauth migration and configuration (@janko)
4
+
5
+ * Add support for controller testing with Minitest or RSpec (@janko)
6
+
7
+ * Fix `enum` declaration in generated `Account` model for Active Record < 7.0 (@janko)
8
+
9
+ * Ensure `require_login_redirect` points to the login page even if the login route changes (@janko)
10
+
11
+ ## 1.2.2 (2022-02-22)
12
+
13
+ * Fix flash messages not being preserved through consecutive redirects (@janko)
14
+
15
+ ## 1.2.1 (2022-02-19)
16
+
17
+ * Change `accounts.status` column type from string to integer (@zhongsheng)
18
+
1
19
  ## 1.2.0 (2022-02-11)
2
20
 
3
21
  * Work around Active Record 4.2 not supporting procs for literal SQL column default (@janko)
data/README.md CHANGED
@@ -4,15 +4,18 @@ Provides Rails integration for the [Rodauth] authentication framework.
4
4
 
5
5
  ## Resources
6
6
 
7
- Useful links:
7
+ ๐Ÿ”— Useful links:
8
8
 
9
9
  * [Rodauth documentation](http://rodauth.jeremyevans.net/documentation.html)
10
10
  * [Rails demo](https://github.com/janko/rodauth-demo-rails)
11
11
  * [JSON API guide](https://github.com/janko/rodauth-rails/wiki/JSON-API)
12
12
  * [OmniAuth guide](https://github.com/janko/rodauth-rails/wiki/OmniAuth)
13
- * [Testing guide](https://github.com/janko/rodauth-rails/wiki/Testing)
14
13
 
15
- Articles:
14
+ ๐ŸŽฅ Screencasts:
15
+
16
+ * [Rails Authentication with Rodauth](https://www.youtube.com/watch?v=2hDpNikacf0)
17
+
18
+ ๐Ÿ“š Articles:
16
19
 
17
20
  * [Rodauth: A Refreshing Authentication Solution for Ruby](https://janko.io/rodauth-a-refreshing-authentication-solution-for-ruby/)
18
21
  * [Rails Authentication with Rodauth](https://janko.io/adding-authentication-in-rails-with-rodauth/)
@@ -36,7 +39,7 @@ of the advantages that stand out for me:
36
39
  * consistent before/after hooks around everything
37
40
  * dedicated object encapsulating all authentication logic
38
41
 
39
- One commmon concern is the fact that, unlike most other authentication
42
+ One common concern is the fact that, unlike most other authentication
40
43
  frameworks for Rails, Rodauth uses [Sequel] for database interaction instead of
41
44
  Active Record. There are good reasons for this, and to make Rodauth work
42
45
  smoothly alongside Active Record, rodauth-rails configures Sequel to [reuse
@@ -779,6 +782,86 @@ Rodauth::Rails.rodauth(session: { two_factor_auth_setup: true })
779
782
  Rodauth::Rails.rodauth(:admin, params: { "param" => "value" })
780
783
  ```
781
784
 
785
+ ## Testing
786
+
787
+ For system and integration tests, which run the whole middleware stack,
788
+ authentication can be exercised normally via HTTP endpoints. See [this wiki
789
+ page](https://github.com/janko/rodauth-rails/wiki/Testing) for some examples.
790
+
791
+ For controller tests, you can log in accounts by modifying the session:
792
+
793
+ ```rb
794
+ # app/controllers/articles_controller.rb
795
+ class ArticlesController < ApplicationController
796
+ before_action -> { rodauth.require_authentication }
797
+
798
+ def index
799
+ # ...
800
+ end
801
+ end
802
+ ```
803
+ ```rb
804
+ # test/controllers/articles_controller_test.rb
805
+ class ArticlesControllerTest < ActionController::TestCase
806
+ test "required authentication" do
807
+ get :index
808
+
809
+ assert_response 302
810
+ assert_redirected_to "/login"
811
+ assert_equal "Please login to continue", flash[:alert]
812
+
813
+ account = Account.create!(email: "user@example.com", password: "secret", status: "verified")
814
+ login(account)
815
+
816
+ get :index
817
+ assert_response 200
818
+
819
+ logout
820
+
821
+ get :index
822
+ assert_response 302
823
+ assert_equal "Please login to continue", flash[:alert]
824
+ end
825
+
826
+ private
827
+
828
+ # Manually modify the session into what Rodauth expects.
829
+ def login(account)
830
+ session[:account_id] = account.id
831
+ session[:authenticated_by] = ["password"] # or ["password", "totp"] for MFA
832
+ end
833
+
834
+ def logout
835
+ session.clear
836
+ end
837
+ end
838
+ ```
839
+
840
+ If you're using multiple configurations with different session prefixes, you'll need
841
+ to make sure to use those in controller tests as well:
842
+
843
+ ```rb
844
+ class RodauthAdmin < Rodauth::Rails::Auth
845
+ configure do
846
+ session_key_prefix "admin_"
847
+ end
848
+ end
849
+ ```
850
+ ```rb
851
+ # in a controller test:
852
+ session[:admin_account_id] = account.id
853
+ session[:admin_authenticated_by] = ["password"]
854
+ ```
855
+
856
+ If you want to access the Rodauth instance in controller tests, you can do so
857
+ through the controller instance:
858
+
859
+ ```rb
860
+ # in a controller test:
861
+ @controller.rodauth #=> #<RodauthMain ...>
862
+ @controller.rodauth(:admin) #=> #<RodauthAdmin ...>
863
+ ```
864
+
782
865
  ## Configuring
783
866
 
784
867
  ### Configuration methods
@@ -3,23 +3,18 @@ enable_extension "citext"
3
3
 
4
4
  <% end -%>
5
5
  create_table :accounts<%= primary_key_type %> do |t|
6
+ t.integer :status, null: false, default: 1
6
7
  <% case activerecord_adapter -%>
7
8
  <% when "postgresql" -%>
8
9
  t.citext :email, null: false
9
10
  <% else -%>
10
11
  t.string :email, null: false
11
12
  <% end -%>
12
- t.string :status, null: false, default: 1
13
13
  <% case activerecord_adapter -%>
14
14
  <% when "postgresql", "sqlite3" -%>
15
15
  t.index :email, unique: true, where: "status IN (1, 2)"
16
16
  <% else -%>
17
17
  t.index :email, unique: true
18
18
  <% end -%>
19
- end
20
-
21
- # Used if storing password hashes in a separate table (default)
22
- create_table :account_password_hashes<%= primary_key_type %> do |t|
23
- t.foreign_key :accounts, column: :id
24
- t.string :password_hash, null: false
19
+ t.string :password_hash
25
20
  end
@@ -35,7 +35,7 @@ class RodauthMain < Rodauth::Rails::Auth
35
35
  account_status_column :status
36
36
 
37
37
  # Store password hash in a column instead of a separate table.
38
- # account_password_hash_column :password_digest
38
+ account_password_hash_column :password_hash
39
39
 
40
40
  # Set password when creating account instead of when verifying.
41
41
  verify_account_set_password? false
@@ -138,6 +138,9 @@ class RodauthMain < Rodauth::Rails::Auth
138
138
 
139
139
  # Redirect to login page after password reset.
140
140
  reset_password_redirect { login_path }
141
+
142
+ # Ensure requiring login follows login route changes.
143
+ require_login_redirect { login_path }
141
144
  <% end -%>
142
145
 
143
146
  # ==> Deadlines
@@ -1,4 +1,8 @@
1
1
  class Account < ApplicationRecord
2
2
  include Rodauth::Rails.model
3
+ <% if ActiveRecord.version >= Gem::Version.new("7.0") -%>
3
4
  enum :status, unverified: 1, verified: 2, closed: 3
5
+ <% else -%>
6
+ enum status: { unverified: 1, verified: 2, closed: 3 }
7
+ <% end -%>
4
8
  end
@@ -8,8 +8,7 @@ module Rodauth
8
8
  end
9
9
 
10
10
  def self.configure(app)
11
- app.before { request.flash } # load flash
12
- app.after { request.commit_flash } # save flash
11
+ app.after { request.commit_flash }
13
12
  end
14
13
 
15
14
  module InstanceMethods
@@ -40,7 +40,7 @@ module Rodauth
40
40
  begin
41
41
  result = catch(:halt) { yield }
42
42
 
43
- response = ActionDispatch::Response.new *(result || [404, {}, []])
43
+ response = ActionDispatch::Response.new(*(result || [404, {}, []]))
44
44
  payload[:response] = response
45
45
  payload[:status] = response.status
46
46
 
@@ -1,5 +1,6 @@
1
1
  require "rodauth/rails/middleware"
2
2
  require "rodauth/rails/controller_methods"
3
+ require "rodauth/rails/test"
3
4
 
4
5
  require "rails"
5
6
 
@@ -21,6 +22,14 @@ module Rodauth
21
22
  initializer "rodauth.test" do
22
23
  # Rodauth uses RACK_ENV to set the default bcrypt hash cost
23
24
  ENV["RACK_ENV"] = "test" if ::Rails.env.test?
25
+
26
+ if ActionPack.version >= Gem::Version.new("5.0")
27
+ ActiveSupport.on_load(:action_controller_test_case) do
28
+ include Rodauth::Rails::Test::Controller
29
+ end
30
+ else
31
+ ActionController::TestCase.include Rodauth::Rails::Test::Controller
32
+ end
24
33
  end
25
34
 
26
35
  rake_tasks do
@@ -0,0 +1,41 @@
1
+ require "active_support/concern"
2
+
3
+ module Rodauth
4
+ module Rails
5
+ module Test
6
+ module Controller
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ setup :setup_rodauth
11
+ end
12
+
13
+ def process(*)
14
+ catch_rodauth { super }
15
+ end
16
+ ruby2_keywords(:process) if respond_to?(:ruby2_keywords, true)
17
+
18
+ private
19
+
20
+ def setup_rodauth
21
+ Rodauth::Rails.app.opts[:rodauths].each do |name, auth_class|
22
+ scope = auth_class.roda_class.new(request.env)
23
+ request.env[["rodauth", *name].join(".")] = auth_class.new(scope)
24
+ end
25
+ end
26
+
27
+ def catch_rodauth(&block)
28
+ result = catch(:halt, &block)
29
+
30
+ if result.is_a?(Array) # rodauth response
31
+ response.status = result[0]
32
+ response.headers.merge! result[1]
33
+ response.body = result[2]
34
+ end
35
+
36
+ response
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,7 @@
1
+ module Rodauth
2
+ module Rails
3
+ module Test
4
+ autoload :Controller, "rodauth/rails/test/controller"
5
+ end
6
+ end
7
+ end
@@ -1,5 +1,5 @@
1
1
  module Rodauth
2
2
  module Rails
3
- VERSION = "1.2.0"
3
+ VERSION = "1.3.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.2.0
4
+ version: 1.3.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: 2022-02-11 00:00:00.000000000 Z
11
+ date: 2022-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -247,6 +247,8 @@ files:
247
247
  - lib/rodauth/rails/model/associations.rb
248
248
  - lib/rodauth/rails/railtie.rb
249
249
  - lib/rodauth/rails/tasks.rake
250
+ - lib/rodauth/rails/test.rb
251
+ - lib/rodauth/rails/test/controller.rb
250
252
  - lib/rodauth/rails/version.rb
251
253
  - rodauth-rails.gemspec
252
254
  homepage: https://github.com/janko/rodauth-rails