rodauth-rails 1.5.1 → 1.5.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +36 -0
- data/README.md +17 -14
- data/lib/generators/rodauth/install_generator.rb +13 -2
- data/lib/generators/rodauth/migration/sequel/base.erb +3 -8
- data/lib/generators/rodauth/migration_generator.rb +25 -10
- data/lib/generators/rodauth/templates/test/fixtures/accounts.yml +10 -0
- data/lib/generators/rodauth/views_generator.rb +18 -5
- data/lib/rodauth/rails/app.rb +6 -0
- data/lib/rodauth/rails/feature/base.rb +3 -1
- data/lib/rodauth/rails/feature/instrumentation.rb +1 -1
- data/lib/rodauth/rails/tasks.rake +19 -5
- data/lib/rodauth/rails/version.rb +1 -1
- data/rodauth-rails.gemspec +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b9640fa912cb535846cd94b3df3361e9763f2267107205287783885e587e774b
|
4
|
+
data.tar.gz: d135e8e958f0210b22fe694ba2a77e6d4fde74df339b8ec06440ac0f83771c90
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1067a2467e0f7dacbfe3a703d6f1e4ad561c9dc7a72fbe3942a20b43b8892211c2509ec3b71c47ba30bf16bea0f7163f8ecb82a5aceaabb23f01a5705d256d12
|
7
|
+
data.tar.gz: ce2464227d1c0a5e5bc3452f05c392787b61fd6b3c530a89c99047c69a4bcceabf08778aaa169c57fa39dbae80efdb455b334881f04b069099fab7b666dc1cfe
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,39 @@
|
|
1
|
+
## 1.5.5 (2022-08-04)
|
2
|
+
|
3
|
+
* Don't raise `ArgumentError` when calling `#current_account` without being logged in (@benkoshy)
|
4
|
+
|
5
|
+
* Abort `rodauth:views` generator when unknown feature was specified (@janko)
|
6
|
+
|
7
|
+
* Abort `rodauth:migration` generator when unknown feature was specified (@janko)
|
8
|
+
|
9
|
+
## 1.5.4 (2022-07-21)
|
10
|
+
|
11
|
+
* Generate account fixtures in `spec/fixtures` directory when using RSpec (@benkoshy)
|
12
|
+
|
13
|
+
* Generate account fixtures in `test/fixtures` directory instead of `app/test/fixtures` (@benkoshy)
|
14
|
+
|
15
|
+
* Use string status column values in generated accounts fixture (@janko)
|
16
|
+
|
17
|
+
* Create integer status column in generated Sequel migration (@janko)
|
18
|
+
|
19
|
+
* Store password hash in accounts table in generated Sequel migration (@janko)
|
20
|
+
|
21
|
+
## 1.5.3 (2022-07-21)
|
22
|
+
|
23
|
+
*Yanked*
|
24
|
+
|
25
|
+
## 1.5.2 (2022-07-03)
|
26
|
+
|
27
|
+
* Bump Rodauth dependency version to 2.25+ (@janko)
|
28
|
+
|
29
|
+
* Generate fixture file for accounts on `rodauth:install` (@benkoshy)
|
30
|
+
|
31
|
+
* Fix error about undefined `controller_path` method in `newrelic_rpm` gem instrumentation (@janko)
|
32
|
+
|
33
|
+
* Don't display disabled routes in `rodauth:routes` (@janko)
|
34
|
+
|
35
|
+
* Display HTTP verbs of endpoints in `rodauth:routes` rake task (@janko)
|
36
|
+
|
1
37
|
## 1.5.1 (2022-06-19)
|
2
38
|
|
3
39
|
* Fix syntax for creating `citext` PG extension in Sequel base migration (@Empact)
|
data/README.md
CHANGED
@@ -14,6 +14,7 @@ Provides Rails integration for the [Rodauth] authentication framework.
|
|
14
14
|
🎥 Screencasts:
|
15
15
|
|
16
16
|
* [Rails Authentication with Rodauth](https://www.youtube.com/watch?v=2hDpNikacf0)
|
17
|
+
* [Multifactor Authentication with Rodauth](https://www.youtube.com/watch?v=9ON-kgXpz2A&list=PLkGQXZLACDTGKsaRWstkHQdm2CUmT3SZ-) ([TOTP](https://youtu.be/9ON-kgXpz2A), [Recovery Codes](https://youtu.be/lkFCcE1Q5-w))
|
17
18
|
|
18
19
|
📚 Articles:
|
19
20
|
|
@@ -66,7 +67,7 @@ Next, run the install generator:
|
|
66
67
|
$ rails generate rodauth:install
|
67
68
|
```
|
68
69
|
|
69
|
-
Or if you want Rodauth endpoints to be exposed via JSON API:
|
70
|
+
Or if you want Rodauth endpoints to be exposed via [JSON API]:
|
70
71
|
|
71
72
|
```sh
|
72
73
|
$ rails generate rodauth:install --json # regular authentication using the Rails session
|
@@ -110,18 +111,18 @@ $ rails rodauth:routes
|
|
110
111
|
```
|
111
112
|
Routes handled by RodauthApp:
|
112
113
|
|
113
|
-
/login rodauth.login_path
|
114
|
-
/create-account rodauth.create_account_path
|
115
|
-
/verify-account-resend rodauth.verify_account_resend_path
|
116
|
-
/verify-account rodauth.verify_account_path
|
117
|
-
/change-password rodauth.change_password_path
|
118
|
-
/change-login rodauth.change_login_path
|
119
|
-
/logout rodauth.logout_path
|
120
|
-
/remember rodauth.remember_path
|
121
|
-
/reset-password-request rodauth.reset_password_request_path
|
122
|
-
/reset-password rodauth.reset_password_path
|
123
|
-
/verify-login-change rodauth.verify_login_change_path
|
124
|
-
/close-account rodauth.close_account_path
|
114
|
+
GET/POST /login rodauth.login_path
|
115
|
+
GET/POST /create-account rodauth.create_account_path
|
116
|
+
GET/POST /verify-account-resend rodauth.verify_account_resend_path
|
117
|
+
GET/POST /verify-account rodauth.verify_account_path
|
118
|
+
GET/POST /change-password rodauth.change_password_path
|
119
|
+
GET/POST /change-login rodauth.change_login_path
|
120
|
+
GET/POST /logout rodauth.logout_path
|
121
|
+
GET/POST /remember rodauth.remember_path
|
122
|
+
GET/POST /reset-password-request rodauth.reset_password_request_path
|
123
|
+
GET/POST /reset-password rodauth.reset_password_path
|
124
|
+
GET/POST /verify-login-change rodauth.verify_login_change_path
|
125
|
+
GET/POST /close-account rodauth.close_account_path
|
125
126
|
```
|
126
127
|
|
127
128
|
Using this information, you can add some basic authentication links to your
|
@@ -381,6 +382,7 @@ class RodauthController < ApplicationController
|
|
381
382
|
when rodauth.login_path,
|
382
383
|
rodauth.create_account_path,
|
383
384
|
rodauth.verify_account_path,
|
385
|
+
rodauth.verify_account_resend_path,
|
384
386
|
rodauth.reset_password_path,
|
385
387
|
rodauth.reset_password_request_path
|
386
388
|
"authentication"
|
@@ -1178,7 +1180,7 @@ License](https://opensource.org/licenses/MIT).
|
|
1178
1180
|
|
1179
1181
|
Everyone interacting in the rodauth-rails project's codebases, issue trackers,
|
1180
1182
|
chat rooms and mailing lists is expected to follow the [code of
|
1181
|
-
conduct](
|
1183
|
+
conduct](CODE_OF_CONDUCT.md).
|
1182
1184
|
|
1183
1185
|
[Rodauth]: https://github.com/jeremyevans/rodauth
|
1184
1186
|
[Sequel]: https://github.com/jeremyevans/sequel
|
@@ -1214,3 +1216,4 @@ conduct](https://github.com/janko/rodauth-rails/blob/master/CODE_OF_CONDUCT.md).
|
|
1214
1216
|
[custom mailer worker]: https://github.com/janko/rodauth-rails/wiki/Custom-Mailer-Worker
|
1215
1217
|
[Turbo]: https://turbo.hotwired.dev/
|
1216
1218
|
[rodauth-model]: https://github.com/janko/rodauth-model
|
1219
|
+
[JSON API]: https://github.com/janko/rodauth-rails/wiki/JSON-API
|
@@ -70,6 +70,17 @@ module Rodauth
|
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
+
def create_fixtures
|
74
|
+
test_unit_options = ::Rails.application.config.generators.options[:test_unit]
|
75
|
+
if test_unit_options[:fixture] && test_unit_options[:fixture_replacement].nil?
|
76
|
+
if ::Rails.application.config.generators.options[:rails][:test_framework] == :rspec
|
77
|
+
template "test/fixtures/accounts.yml", "spec/fixtures/accounts.yml"
|
78
|
+
else
|
79
|
+
template "test/fixtures/accounts.yml", "test/fixtures/accounts.yml"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
73
84
|
def show_instructions
|
74
85
|
readme "INSTRUCTIONS" if behavior == :invoke
|
75
86
|
end
|
@@ -77,8 +88,8 @@ module Rodauth
|
|
77
88
|
private
|
78
89
|
|
79
90
|
def migration_features
|
80
|
-
features = [
|
81
|
-
features <<
|
91
|
+
features = ["base", "reset_password", "verify_account", "verify_login_change"]
|
92
|
+
features << "remember" unless jwt?
|
82
93
|
features
|
83
94
|
end
|
84
95
|
|
@@ -13,16 +13,11 @@ create_table :accounts do
|
|
13
13
|
<% else -%>
|
14
14
|
String :email, null: false
|
15
15
|
<% end -%>
|
16
|
-
|
16
|
+
Integer :status, null: false, default: 1
|
17
17
|
<% if db.supports_partial_indexes? -%>
|
18
|
-
index :email, unique: true, where: { status: [
|
18
|
+
index :email, unique: true, where: { status: [1, 2] }
|
19
19
|
<% else -%>
|
20
20
|
index :email, unique: true
|
21
21
|
<% end -%>
|
22
|
-
|
23
|
-
|
24
|
-
# Used if storing password hashes in a separate table (default)
|
25
|
-
create_table :account_password_hashes do
|
26
|
-
foreign_key :id, :accounts, primary_key: true, type: :Bignum
|
27
|
-
String :password_hash, null: false
|
22
|
+
String :password_hash
|
28
23
|
end
|
@@ -17,7 +17,7 @@ module Rodauth
|
|
17
17
|
desc: "Name of the generated migration file"
|
18
18
|
|
19
19
|
def create_rodauth_migration
|
20
|
-
|
20
|
+
validate_features or return
|
21
21
|
|
22
22
|
migration_template "db/migrate/create_rodauth.rb", File.join(db_migrate_path, "#{migration_name}.rb")
|
23
23
|
end
|
@@ -30,7 +30,6 @@ module Rodauth
|
|
30
30
|
|
31
31
|
def migration_content
|
32
32
|
features
|
33
|
-
.select { |feature| File.exist?(migration_chunk(feature)) }
|
34
33
|
.map { |feature| File.read(migration_chunk(feature)) }
|
35
34
|
.map { |content| erb_eval(content) }
|
36
35
|
.join("\n")
|
@@ -45,19 +44,37 @@ module Rodauth
|
|
45
44
|
end
|
46
45
|
end
|
47
46
|
|
47
|
+
def migration_chunk(feature)
|
48
|
+
"#{MIGRATION_DIR}/#{feature}.erb"
|
49
|
+
end
|
50
|
+
|
51
|
+
def validate_features
|
52
|
+
if features.empty?
|
53
|
+
say "No features specified!", :yellow
|
54
|
+
false
|
55
|
+
elsif (features - valid_features).any?
|
56
|
+
say "No available migration for feature(s): #{(features - valid_features).join(", ")}", :red
|
57
|
+
false
|
58
|
+
else
|
59
|
+
true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def valid_features
|
64
|
+
Dir["#{MIGRATION_DIR}/*.erb"].map { |filename| File.basename(filename, ".erb") }
|
65
|
+
end
|
66
|
+
|
48
67
|
if defined?(::ActiveRecord::Railtie) # Active Record
|
49
68
|
include ::ActiveRecord::Generators::Migration
|
50
69
|
|
70
|
+
MIGRATION_DIR = "#{__dir__}/migration/active_record"
|
71
|
+
|
51
72
|
def db_migrate_path
|
52
73
|
return "db/migrate" unless ActiveRecord.version >= Gem::Version.new("5.0")
|
53
74
|
|
54
75
|
super
|
55
76
|
end
|
56
77
|
|
57
|
-
def migration_chunk(feature)
|
58
|
-
"#{__dir__}/migration/active_record/#{feature}.erb"
|
59
|
-
end
|
60
|
-
|
61
78
|
def migration_version
|
62
79
|
return unless ActiveRecord.version >= Gem::Version.new("5.0")
|
63
80
|
|
@@ -95,6 +112,8 @@ module Rodauth
|
|
95
112
|
else # Sequel
|
96
113
|
include ::Rails::Generators::Migration
|
97
114
|
|
115
|
+
MIGRATION_DIR = "#{__dir__}/migration/sequel"
|
116
|
+
|
98
117
|
def self.next_migration_number(dirname)
|
99
118
|
next_migration_number = current_migration_number(dirname) + 1
|
100
119
|
[Time.now.utc.strftime('%Y%m%d%H%M%S'), format('%.14d', next_migration_number)].max
|
@@ -104,10 +123,6 @@ module Rodauth
|
|
104
123
|
"db/migrate"
|
105
124
|
end
|
106
125
|
|
107
|
-
def migration_chunk(feature)
|
108
|
-
"#{__dir__}/migration/sequel/#{feature}.erb"
|
109
|
-
end
|
110
|
-
|
111
126
|
def db
|
112
127
|
db = ::Sequel::DATABASES.first if defined?(::Sequel)
|
113
128
|
db or fail Rodauth::Rails::Error, "missing Sequel database connection"
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
2
|
+
one:
|
3
|
+
email: freddie@queen.com
|
4
|
+
password_hash: <%%= BCrypt::Password.create("password", cost: BCrypt::Engine::MIN_COST) %>
|
5
|
+
status: verified
|
6
|
+
|
7
|
+
two:
|
8
|
+
email: brian@queen.com
|
9
|
+
password_hash: <%%= BCrypt::Password.create("password", cost: BCrypt::Engine::MIN_COST) %>
|
10
|
+
status: verified
|
@@ -46,10 +46,7 @@ module Rodauth
|
|
46
46
|
}
|
47
47
|
|
48
48
|
def create_views
|
49
|
-
|
50
|
-
list |= VIEWS[feature] || []
|
51
|
-
list |= VIEWS[DEPENDENCIES[feature]] || []
|
52
|
-
end
|
49
|
+
validate_features or return
|
53
50
|
|
54
51
|
views.each do |view|
|
55
52
|
copy_file "app/views/rodauth/#{view}.html.erb", "app/views/#{directory}/#{view}.html.erb" do |content|
|
@@ -63,13 +60,29 @@ module Rodauth
|
|
63
60
|
|
64
61
|
private
|
65
62
|
|
63
|
+
def views
|
64
|
+
features.inject([]) do |list, feature|
|
65
|
+
list |= VIEWS.fetch(feature)
|
66
|
+
list |= VIEWS[DEPENDENCIES[feature]] || []
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def validate_features
|
71
|
+
if (features - VIEWS.keys).any?
|
72
|
+
say "No available view template for feature(s): #{(features - VIEWS.keys).join(", ")}", :error
|
73
|
+
false
|
74
|
+
else
|
75
|
+
true
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
66
79
|
def features
|
67
80
|
if options[:all]
|
68
81
|
VIEWS.keys
|
69
82
|
elsif selected_features
|
70
83
|
selected_features.map(&:to_sym)
|
71
84
|
else
|
72
|
-
rodauth_configuration.features
|
85
|
+
rodauth_configuration.features & VIEWS.keys
|
73
86
|
end
|
74
87
|
end
|
75
88
|
|
data/lib/rodauth/rails/app.rb
CHANGED
@@ -59,6 +59,12 @@ module Rodauth
|
|
59
59
|
rodauth(name) or fail ArgumentError, "unknown rodauth configuration: #{name.inspect}"
|
60
60
|
end
|
61
61
|
|
62
|
+
# The newrelic_rpm gem expects this when we pass the roda class as
|
63
|
+
# :controller in instrumentation payload.
|
64
|
+
def self.controller_path
|
65
|
+
name.underscore
|
66
|
+
end
|
67
|
+
|
62
68
|
module RequestMethods
|
63
69
|
def rodauth(name = nil)
|
64
70
|
prefix = scope.rodauth(name).prefix
|
@@ -6,20 +6,34 @@ namespace :rodauth do
|
|
6
6
|
|
7
7
|
app.opts[:rodauths].each do |configuration_name, auth_class|
|
8
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
|
9
22
|
|
10
|
-
routes = auth_class.routes.map do |handle_method|
|
11
23
|
path_method = "#{handle_method.to_s.sub(/\Ahandle_/, "")}_path"
|
12
24
|
|
13
25
|
[
|
14
|
-
|
26
|
+
verbs.join("/"),
|
27
|
+
"#{rodauth.prefix}#{path}",
|
15
28
|
"rodauth#{configuration_name && "(:#{configuration_name})"}.#{path_method}",
|
16
29
|
]
|
17
30
|
end
|
18
31
|
|
19
|
-
|
32
|
+
verbs_padding = routes.map { |verbs, _, _| verbs.length }.max
|
33
|
+
path_padding = routes.map { |_, path, _| path.length }.max
|
20
34
|
|
21
|
-
route_lines = routes.map do |path, code|
|
22
|
-
"#{path.ljust(
|
35
|
+
route_lines = routes.map do |verbs, path, code|
|
36
|
+
"#{verbs.ljust(verbs_padding)} #{path.ljust(path_padding)} #{code}"
|
23
37
|
end
|
24
38
|
|
25
39
|
puts "\n #{route_lines.join("\n ")}" unless route_lines.empty?
|
data/rodauth-rails.gemspec
CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.require_paths = ["lib"]
|
18
18
|
|
19
19
|
spec.add_dependency "railties", ">= 4.2", "< 8"
|
20
|
-
spec.add_dependency "rodauth", "~> 2.
|
20
|
+
spec.add_dependency "rodauth", "~> 2.25"
|
21
21
|
spec.add_dependency "roda", "~> 3.55"
|
22
22
|
spec.add_dependency "sequel-activerecord_connection", "~> 1.1"
|
23
23
|
spec.add_dependency "rodauth-model", "~> 0.2"
|
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.5.
|
4
|
+
version: 1.5.5
|
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-
|
11
|
+
date: 2022-08-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -36,14 +36,14 @@ dependencies:
|
|
36
36
|
requirements:
|
37
37
|
- - "~>"
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: '2.
|
39
|
+
version: '2.25'
|
40
40
|
type: :runtime
|
41
41
|
prerelease: false
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '2.
|
46
|
+
version: '2.25'
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: roda
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -271,6 +271,7 @@ files:
|
|
271
271
|
- lib/generators/rodauth/templates/config/initializers/rodauth.rb
|
272
272
|
- lib/generators/rodauth/templates/config/initializers/sequel.rb
|
273
273
|
- lib/generators/rodauth/templates/db/migrate/create_rodauth.rb
|
274
|
+
- lib/generators/rodauth/templates/test/fixtures/accounts.yml
|
274
275
|
- lib/generators/rodauth/views_generator.rb
|
275
276
|
- lib/rodauth-rails.rb
|
276
277
|
- lib/rodauth/rails.rb
|