authtown 0.2.0 → 0.3.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: 5618c4b915887279ad6bfd3ba639756a63b92d1361fe3c5ef7d64fc1a9787f08
4
- data.tar.gz: 488925cf2004d158d77893acfa68566469e19b29e03abfe48d6469b4a00ebbf8
3
+ metadata.gz: 1d2619b2daf3aa55e9406234f5ebffcc6120db6b88c11b86f220349e3b1f55fc
4
+ data.tar.gz: 27d16fd12a96f4e4cda4d0c642b780768df4380132c1b93ad1c2de354ff5e58b
5
5
  SHA512:
6
- metadata.gz: 89644f9c86b9202faa8616c868956aa59a1f668418737092cb27181ba2a4d147886b6566a24c7110f3d91176acb279b92999c2cdd07b476b16466a9d4cdca1ea
7
- data.tar.gz: 7323afa6ab4142c31a4eaf5f3e22d64fa8a7b0a106075328b299413bf2e7569ddad1017c7b428ca00a44938fd1a703b722def67e258c772816f75b8b3118b9cb
6
+ metadata.gz: 0afe6909ccf879aba4e28484f3f83b035613e80e43940e1a4aba3c0b3dd67f9aae7cc3f55122ce4276eaf21426829e9c515b57b6293a431beb8acd1ab416641d
7
+ data.tar.gz: 37e8e4f7b0c438050eee6321cea152c0f776667262dee23859698c902184b6d8f69fdfd628d2e28e410e1aa40df050bd3ed43e1d0f03dba82fd5e108c3a250b8
data/.rubocop.yml CHANGED
@@ -21,3 +21,6 @@ AllCops:
21
21
  - script/**/*
22
22
  - test/fixtures/**/*
23
23
  - vendor/**/*
24
+
25
+ Metrics/ParameterLists:
26
+ Enabled: false
data/CHANGELOG.md CHANGED
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.3.0] - 2024-04-07
11
+
12
+ - Refactor how Bridgetown's view layer is integrated with Rodauth, improve performance
13
+
10
14
  ## [0.2.0] - 2024-04-03
11
15
 
12
16
  - Integration with new bridgetown_sequel gem tested
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Metrics/BlockLength
4
+ # @param config [Bridgetown::Configuration::ConfigurationDSL]
5
+ # @param rodauth_config [Proc]
6
+ # @param account_landing_page [String] relative URL to redirect to upon login / create account
7
+ # @param user_class_resolver [Proc] return the class of the user model
8
+ # @param user_name_field [String] save a name when creating a new user, or set to nil to skip
9
+ Bridgetown.initializer :authtown do |
10
+ config,
11
+ rodauth_config: nil,
12
+ account_landing_page: "/account/profile",
13
+ user_class_resolver: -> { User },
14
+ user_name_field: :first_name
15
+ |
16
+
17
+ config.authtown ||= {}
18
+ config.authtown.user_class_resolver ||= user_class_resolver
19
+
20
+ config.only :server do
21
+ require "authtown/routes/rodauth"
22
+
23
+ # @param app [Class<Roda>]
24
+ config.roda do |app|
25
+ app.prepend Authtown::ViewMixin
26
+
27
+ secret = ENV.fetch("RODA_SECRET_KEY")
28
+ app.plugin(:sessions, secret:)
29
+
30
+ app.plugin :rodauth, render: false do
31
+ enable :login, :logout, :create_account, :remember, :reset_password, :internal_request
32
+ hmac_secret secret
33
+
34
+ base_url config.url
35
+
36
+ prefix "/auth"
37
+
38
+ login_redirect account_landing_page
39
+ create_account_redirect account_landing_page
40
+ logout_redirect "/"
41
+
42
+ set_deadline_values? true # for remember, etc.
43
+ # TODO: why isn't this working? might be a schema issue with old AR:
44
+ remember_deadline_interval days: 30
45
+ extend_remember_deadline? true
46
+
47
+ login_label "Email Address"
48
+ login_button "Sign In"
49
+
50
+ accounts_table :users
51
+ account_password_hash_column :password_hash
52
+
53
+ require_login_confirmation? false
54
+ require_password_confirmation? false
55
+
56
+ # Require passwords to have at least 8 characters
57
+ password_minimum_length 8
58
+
59
+ # Don't allow passwords to be too long, to prevent long password DoS attacks
60
+ password_maximum_length 64
61
+
62
+ reset_password_email_sent_redirect "/account/reset-link-sent"
63
+ reset_password_autologin? true
64
+ reset_password_redirect account_landing_page
65
+
66
+ before_create_account do
67
+ # Ensure timestamps get saved
68
+ account[:created_at] = account[:updated_at] = Time.now
69
+ next unless user_name_field
70
+
71
+ # Save name details
72
+ account[user_name_field] = param(user_name_field) if param(user_name_field)
73
+ end
74
+
75
+ after_login do
76
+ remember_login
77
+ end
78
+
79
+ instance_exec(&rodauth_config) if rodauth_config
80
+ end
81
+ end
82
+ end
83
+
84
+ # Register your builder:
85
+ config.builder Authtown::Builder
86
+ end
87
+ # rubocop:enable Metrics/BlockLength
@@ -10,9 +10,10 @@ module Authtown
10
10
 
11
11
  init_current_user
12
12
 
13
- # hook :authtown, :initialized do |rodauth|
14
- # Lifeform::Form.rodauth = rodauth
15
- # end
13
+ # @example hook usage:
14
+ # hook :authtown, :initialized do |rodauth|
15
+ # Lifeform::Form.rodauth = rodauth
16
+ # end
16
17
  Bridgetown::Hooks.trigger(:authtown, :initialized, rodauth)
17
18
 
18
19
  r.on "auth" do
@@ -23,9 +24,8 @@ module Authtown
23
24
  def init_current_user
24
25
  Authtown::Current.user =
25
26
  if rodauth.logged_in?
26
- account_id = rodauth.account_from_session[:id]
27
- user_class = bridgetown_site.config.authtown.user_class_resolver.()
28
- user_class[account_id]
27
+ # load existing account hash into Model:
28
+ bridgetown_site.config.authtown.user_class_resolver.().(rodauth.account_from_session)
29
29
  end
30
30
  end
31
31
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Authtown
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
@@ -3,44 +3,64 @@
3
3
  module Authtown::ViewMixin
4
4
  def locals = @_route_locals
5
5
 
6
- # TODO: this is super hacky
6
+ def current_user = Authtown::Current.user
7
+
8
+ ### Compatibility layer to translate Rodauth view calls to Bridgetown Routing
9
+
10
+ # Return a single hash combining the template and opts arguments.
11
+ def parse_template_opts(template, opts)
12
+ opts = opts.to_h
13
+ if template.is_a?(Hash)
14
+ opts.merge!(template)
15
+ else
16
+ opts[:template] = template
17
+ opts
18
+ end
19
+ end
20
+
21
+ def find_template(opts) = opts
22
+
23
+ def template_path(opts) = opts[:template]
24
+
25
+ def login_failed_reset_password_request_form
26
+ # part of reset_password internals…no-op since we're rendering our own forms
27
+ end
28
+
7
29
  def view(*args, view_class: Bridgetown::ERBView, **kwargs) # rubocop:disable Metrics
8
30
  kwargs = args.first if args.first.is_a?(Hash)
9
31
 
10
- # If we're farming out to another view, let's go!
11
- unless kwargs.empty?
12
- response["X-Bridgetown-SSR"] = "1"
32
+ return super if kwargs.empty? # regular Bridgetown behavior
13
33
 
14
- # UGH, hate special casing this
15
- if kwargs.dig(:locals, :rodauth)&.prefix
16
- kwargs[:template] =
17
- "#{kwargs.dig(:locals, :rodauth).prefix.delete_prefix("/")}/#{kwargs[:template]}"
18
- end
34
+ unless kwargs.dig(:locals, :rodauth)
35
+ raise "The `view' method with keyword arguments should only be used by Rodauth internally. " \
36
+ "It is not supported by Bridgetown's view layer."
37
+ end
19
38
 
20
- Bridgetown::Routes::Manifest.generate_manifest(bridgetown_site).each do |route|
21
- file, localized_file_slugs = route
39
+ if kwargs.dig(:locals, :rodauth)&.prefix
40
+ kwargs[:template] =
41
+ "#{kwargs.dig(:locals, :rodauth).prefix.delete_prefix("/")}/#{kwargs[:template]}"
42
+ end
22
43
 
23
- file_slug = localized_file_slugs.first
44
+ # TODO: this should really be some sort of exposed method from the routes plugin
45
+ response["X-Bridgetown-SSR"] = "1"
24
46
 
25
- next unless file_slug == kwargs[:template]
47
+ Bridgetown::Routes::Manifest.generate_manifest(bridgetown_site).each do |route|
48
+ file, localized_file_slugs = route
26
49
 
27
- Bridgetown::Routes::CodeBlocks.eval_route_file file, file_slug, self
28
- route_block = Bridgetown::Routes::CodeBlocks.route_block(file_slug)
29
- response.instance_variable_set(
30
- :@_route_file_code, route_block.instance_variable_get(:@_route_file_code)
31
- ) # could be nil
32
- @_route_locals = kwargs[:locals]
33
- return instance_exec(request, &route_block)
34
- end
50
+ file_slug = localized_file_slugs.first
35
51
 
36
- Bridgetown.logger.warn("Template not found: #{kwargs[:template]}")
37
- return nil # couldn't find template, 404
52
+ next unless file_slug == kwargs[:template]
53
+
54
+ Bridgetown::Routes::CodeBlocks.eval_route_file file, file_slug, self
55
+ route_block = Bridgetown::Routes::CodeBlocks.route_block(file_slug)
56
+ response.instance_variable_set(
57
+ :@_route_file_code, route_block.instance_variable_get(:@_route_file_code)
58
+ ) # could be nil
59
+ @_route_locals = kwargs[:locals]
60
+ return instance_exec(request, &route_block)
38
61
  end
39
62
 
40
- response._fake_resource_view(
41
- view_class:, roda_app: self, bridgetown_site:
42
- )
63
+ Bridgetown.logger.warn("Rodauth template not found: #{kwargs[:template]}")
64
+ nil # couldn't find template, 404
43
65
  end
44
-
45
- def current_user = Authtown::Current.user
46
66
  end
data/lib/authtown.rb CHANGED
@@ -51,81 +51,4 @@ class Authtown::Current
51
51
  end
52
52
  end
53
53
 
54
- # rubocop:disable Metrics/BlockLength
55
- # @param config [Bridgetown::Configuration::ConfigurationDSL]
56
- # @param rodauth_config [Proc]
57
- Bridgetown.initializer :authtown do |
58
- config,
59
- rodauth_config: nil,
60
- account_landing_page: "/account/profile",
61
- user_class_resolver: -> { User }
62
- |
63
-
64
- config.authtown ||= {}
65
- config.authtown.user_class_resolver ||= user_class_resolver
66
-
67
- config.only :server do
68
- require "authtown/routes/rodauth"
69
-
70
- # @param app [Class<Roda>]
71
- config.roda do |app|
72
- app.prepend Authtown::ViewMixin
73
-
74
- secret = ENV.fetch("RODA_SECRET_KEY")
75
- app.plugin(:sessions, secret:)
76
-
77
- app.plugin :rodauth do
78
- enable :login, :logout, :create_account, :remember, :reset_password, :internal_request
79
- hmac_secret secret
80
-
81
- base_url config.url
82
-
83
- prefix "/auth"
84
-
85
- login_redirect account_landing_page
86
- create_account_redirect account_landing_page
87
- logout_redirect "/"
88
-
89
- set_deadline_values? true # for remember, etc.
90
- remember_deadline_interval days: 30 # TODO: why isn't this working?!
91
- extend_remember_deadline? true
92
-
93
- login_label "Email Address"
94
- login_button "Sign In"
95
-
96
- accounts_table :users
97
- account_password_hash_column :password_hash
98
-
99
- require_login_confirmation? false
100
- require_password_confirmation? false
101
-
102
- # Require passwords to have at least 8 characters
103
- password_minimum_length 8
104
-
105
- # Don't allow passwords to be too long, to prevent long password DoS attacks
106
- password_maximum_length 64
107
-
108
- reset_password_email_sent_redirect "/account/reset-link-sent"
109
- reset_password_autologin? true
110
- reset_password_redirect account_landing_page
111
-
112
- before_create_account do
113
- # Make sure timestamps get saved
114
- account[:created_at] = account[:updated_at] = Time.now
115
-
116
- account[:first_name] = param(:first_name) if param(:first_name)
117
- end
118
-
119
- after_login do
120
- remember_login
121
- end
122
-
123
- instance_exec(&rodauth_config) if rodauth_config
124
- end
125
- end
126
- end
127
-
128
- # Register your builder:
129
- config.builder Authtown::Builder
130
- end
131
- # rubocop:enable Metrics/BlockLength
54
+ require "authtown/initializer"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: authtown
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bridgetown Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-03 00:00:00.000000000 Z
11
+ date: 2024-04-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bridgetown
@@ -132,6 +132,7 @@ files:
132
132
  - bridgetown.automation.rb
133
133
  - lib/authtown.rb
134
134
  - lib/authtown/builder.rb
135
+ - lib/authtown/initializer.rb
135
136
  - lib/authtown/routes/rodauth.rb
136
137
  - lib/authtown/version.rb
137
138
  - lib/authtown/view_mixin.rb