rodauth-rails 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d146993e77acfbe027e5cfe399cc13cfe16d2e967d73b0caf149c1363a222b9b
4
+ data.tar.gz: f77401bec1bfabd12cb87285e3e6a42b9b7ca7bf0fb986a32b27babba7d49d72
5
+ SHA512:
6
+ metadata.gz: 7592679984260110c5cd702601d9c9841fc5c5e8980790aad8bb223997851d06c43045361a91ab7ad6c7bb0b113a79bd52e26e5de3a488e7269cf1e3bdf2ecaa
7
+ data.tar.gz: 70fa3b31cffff7cecb98cf2951a35bd2dd4f6ca65cd4d9b49494d94be0858e73aa5d292d2292053d1b847921f05212b8c8d3b0b2ffd81aed4e191916749d4249
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Janko Marohnić
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,589 @@
1
+ # rodauth-rails
2
+
3
+ Provides Rails integration for the [Rodauth] authentication framework.
4
+
5
+ ## Resources
6
+
7
+ * [Rodauth documentation](http://rodauth.jeremyevans.net/documentation.html)
8
+ * [rodauth-rails wiki](https://github.com/janko/rodauth-rails/wiki)
9
+ * [Rails demo](https://github.com/janko/rodauth-demo-rails)
10
+
11
+ ## Installation
12
+
13
+ Add the gem to your Gemfile:
14
+
15
+ ```rb
16
+ gem "rodauth-rails", "~> 0.1"
17
+ ```
18
+
19
+ Then run `bundle install`.
20
+
21
+ Next, run the install generator:
22
+
23
+ ```
24
+ $ rails generate rodauth:install
25
+ ```
26
+
27
+ The generator will create the following files:
28
+
29
+ * Rodauth migration at `db/migrate/*_create_rodauth.rb`
30
+ * Rodauth initializer at `config/initializers/rodauth.rb`
31
+ * Sequel initializer at `config/initializers/sequel.rb` for ActiveRecord integration
32
+ * Rodauth app at `lib/rodauth_app.rb`
33
+ * Rodauth controller at `app/controllers/rodauth_controller.rb`
34
+ * Account model at `app/models/account.rb`
35
+
36
+ ### Migration
37
+
38
+ The migration file creates tables required by Rodauth. You're encouraged to
39
+ review the migration, and modify it to only create tables for features you
40
+ intend to use.
41
+
42
+ ```rb
43
+ # db/migrate/*_create_rodauth.rb
44
+ class CreateRodauth < ActiveRecord::Migration
45
+ def change
46
+ create_table :accounts do |t| ... end
47
+ create_table :account_password_hashes do |t| ... end
48
+ create_table :account_password_reset_keys do |t| ... end
49
+ create_table :account_verification_keys do |t| ... end
50
+ create_table :account_login_change_keys do |t| ... end
51
+ create_table :account_remember_keys do |t| ... end
52
+ # ...
53
+ end
54
+ end
55
+ ```
56
+
57
+ Once you're done, you can run the migration:
58
+
59
+ ```
60
+ $ rails db:migrate
61
+ ```
62
+
63
+ ### Rodauth initializer
64
+
65
+ The Rodauth initializer assigns the constant for your Rodauth app, which will
66
+ be called by the Rack middleware that's added in front of your Rails router.
67
+
68
+ ```rb
69
+ # config/initializers/rodauth.rb
70
+ Rodauth::Rails.configure do |config|
71
+ config.app = "RodauthApp"
72
+ end
73
+ ```
74
+
75
+ ### Sequel initializer
76
+
77
+ Rodauth uses [Sequel] for database interaction. If you're using ActiveRecord,
78
+ an additional initializer will be created which configures Sequel to use the
79
+ ActiveRecord connection.
80
+
81
+ ```rb
82
+ # config/initializers/sequel.rb
83
+ require "sequel/core"
84
+
85
+ # initialize the appropriate Sequel adapter without creating a connection
86
+ DB = Sequel.postgres(test: false)
87
+ # have Sequel use ActiveRecord's connection for database interaction
88
+ DB.extension :activerecord_connection
89
+ ```
90
+
91
+ ### Rodauth app
92
+
93
+ Your Rodauth app is created in the `lib/` directory, which comes with a default
94
+ set of authentication features enabled, as well as extensive examples on ways
95
+ you can configure authentication behaviour.
96
+
97
+ ```rb
98
+ # lib/rodauth_app.rb
99
+ class RodauthApp < Rodauth::Rails::App
100
+ configure do
101
+ # authentication configuration
102
+ end
103
+
104
+ route do |r|
105
+ # request handling
106
+ end
107
+ end
108
+ ```
109
+
110
+ Note that Rails doesn't autoload files in the `lib/` directory by default, so
111
+ make sure to add `lib/` to your `config.autoload_paths`:
112
+
113
+ ```rb
114
+ # config/application.rb
115
+ module YourApp
116
+ class Application < Rails::Application
117
+ # ...
118
+ config.autoload_paths += %W[#{config.root}/lib]
119
+ end
120
+ end
121
+ ```
122
+
123
+ ### Controller
124
+
125
+ Your Rodauth app will by default use `RodauthController` for view rendering
126
+ and CSRF protection.
127
+
128
+ ```rb
129
+ # app/controllers/rodauth_controller.rb
130
+ class RodauthController < ApplicationController
131
+ end
132
+ ```
133
+
134
+ ### Account Model
135
+
136
+ Rodauth stores user accounts in the `accounts` table, so the generator will
137
+ also create an `Account` model for custom use.
138
+
139
+ ```rb
140
+ # app/models/account.rb
141
+ class Account < ApplicationRecord
142
+ end
143
+ ```
144
+
145
+ ## Getting started
146
+
147
+ Let's start by adding some basic authentication navigation links to our home
148
+ page:
149
+
150
+ ```erb
151
+ <ul>
152
+ <% if rodauth.authenticated? %>
153
+ <li><%= link_to "Sign out", rodauth.logout_path, method: :post %></li>
154
+ <% else %>
155
+ <li><%= link_to "Sign in", rodauth.login_path %></li>
156
+ <li><%= link_to "Sign up", rodauth.create_account_path %></li>
157
+ <% end %>
158
+ </ul>
159
+ ```
160
+
161
+ These links are fully functional, feel free to visit them and interact with the
162
+ pages. The templates that ship with Rodauth aim to provide a complete
163
+ authentication experience, and the forms use [Boostrap] markup.
164
+
165
+ Let's also add the `#current_account` method for retrieving the account of the
166
+ the authenticated session:
167
+
168
+ ```rb
169
+ # app/controllers/application_controller.rb
170
+ class ApplicationController < ActionController::Base
171
+ private
172
+
173
+ def current_account
174
+ @current_account ||= Account.find(rodauth.session_value)
175
+ end
176
+ helper_method :current_account
177
+ end
178
+ ```
179
+ ```erb
180
+ <p>Authenticated as: <%= current_account.email %></p>
181
+ ```
182
+
183
+ ### Requiring authentication
184
+
185
+ Next, we'll likely want to require authentication for certain sections/pages of
186
+ our app. We can do this in our Rodauth app's routing block, which helps keep
187
+ the authentication logic encapsulated:
188
+
189
+ ```rb
190
+ # lib/rodauth_app.rb
191
+ class RodauthApp < Rodauth::Rails::App
192
+ # ...
193
+ route do |r|
194
+ # ...
195
+ r.rodauth # route rodauth requests
196
+
197
+ # require authentication for /dashboard/* and /account/* routes
198
+ if r.path.start_with?("/dashboard") || r.path.start_with?("/account")
199
+ rodauth.require_authentication # redirect to login page if not authenticated
200
+ end
201
+ end
202
+ end
203
+ ```
204
+
205
+ We can also require authentication at the controller layer:
206
+
207
+ ```rb
208
+ # app/controllers/application_controller.rb
209
+ class ApplicationController < ActionController::Base
210
+ private
211
+
212
+ def authenticate
213
+ rodauth.require_authentication # redirect to login page if not authenticated
214
+ end
215
+ end
216
+ ```
217
+ ```rb
218
+ # app/controllers/dashboard_controller.rb
219
+ class DashboardController < ApplicationController
220
+ before_action :authenticate
221
+ end
222
+ ```
223
+ ```rb
224
+ # app/controllers/posts_controller.rb
225
+ class PostsController < ApplicationController
226
+ before_action :authenticate, except: [:index, :show]
227
+ end
228
+ ```
229
+
230
+ Or at the Rails router level:
231
+
232
+ ```rb
233
+ # config/routes.rb
234
+ Rails.application.routes.draw do
235
+ constraints -> (r) { r.env["rodauth"].require_authentication } do
236
+ namespace :admin do
237
+ # ...
238
+ end
239
+ end
240
+ end
241
+ ```
242
+
243
+ ### Views
244
+
245
+ The templates built into Rodauth are useful when getting started, but at some
246
+ point we'll probably want more control over the markup. For that we can run the
247
+ following command:
248
+
249
+ ```sh
250
+ $ rails generate rodauth:views
251
+ ```
252
+
253
+ This will generate views for the default set of Rodauth features into the
254
+ `app/views/rodauth` directory, which will be automatically picked up by the
255
+ `RodauthController`.
256
+
257
+ You can pass a list of Rodauth features to the generator to create views for
258
+ these features (this will not remove any existing views):
259
+
260
+ ```sh
261
+ $ rails generate rodauth:views --features login create_account lockout otp
262
+ ```
263
+
264
+ Or you can generate views for all features:
265
+
266
+ ```sh
267
+ $ rails generate rodauth:views --all
268
+ ```
269
+
270
+ You can also tell the generator to create views into another directory (in this
271
+ case don't forget to rename the Rodauth controller accordingly).
272
+
273
+ ```sh
274
+ # generates views into app/views/authentication
275
+ $ rails generate rodauth:views --name authentication
276
+ ```
277
+
278
+ #### Layout
279
+
280
+ To use different layouts for different Rodauth views, you can compare the
281
+ request path in the layout method:
282
+
283
+ ```rb
284
+ class RodauthController < ApplicationController
285
+ layout :rodauth_layout
286
+
287
+ private
288
+
289
+ def rodauth_layout
290
+ case request.path
291
+ when rodauth.login_path,
292
+ rodauth.create_account_path,
293
+ rodauth.verify_account_path,
294
+ rodauth.reset_password_path,
295
+ rodauth.reset_password_request_path
296
+ "authentication"
297
+ else
298
+ "dashboard"
299
+ end
300
+ end
301
+ end
302
+ ```
303
+
304
+ ### Mailer
305
+
306
+ Rodauth may send emails as part of the authentication flow. Most email settings
307
+ can be customized:
308
+
309
+ ```rb
310
+ # lib/rodauth_app.rb
311
+ class RodauthApp < Rodauth::Rails::App
312
+ # ...
313
+ configure do
314
+ # ...
315
+ # general settings
316
+ email_from "no-reply@myapp.com"
317
+ email_subject_prefix "[MyApp] "
318
+ send_email(&:deliver_later)
319
+ # ...
320
+ # feature settings
321
+ verify_account_email_subject "Verify your account"
322
+ verify_account_email_body { "Verify your account by visting this link: #{verify_account_email_link}" }
323
+ # ...
324
+ end
325
+ end
326
+ ```
327
+
328
+ This is convenient when starting out, but eventually you might want to use your
329
+ own mailer. You can start by running the following command:
330
+
331
+ ```sh
332
+ $ rails generate rodauth:mailer
333
+ ```
334
+
335
+ This will create a `RodauthMailer` with the associated mailer views in
336
+ `app/views/rodauth_mailer` directory.
337
+
338
+ ```rb
339
+ # app/mailers/rodauth_mailer.rb
340
+ class RodauthMailer < ApplicationMailer
341
+ def verify_account(recipient, email_link) ... end
342
+ def reset_password(recipient, email_link) ... end
343
+ def verify_login_change(recipient, old_login, new_login, email_link) ... end
344
+ def password_changed(recipient) ... end
345
+ # def email_auth(recipient, email_link) ... end
346
+ # def unlock_account(recipient, email_link) ... end
347
+ end
348
+ ```
349
+
350
+ You can then uncomment the lines in your Rodauth configuration to have it call
351
+ your mailer. If you've enabled additional authentication features, make sure to
352
+ override their `send_*_email` methods as well.
353
+
354
+ ```rb
355
+ # lib/rodauth_app.rb
356
+ class RodauthApp < Rodauth::Rails::App
357
+ # ...
358
+ configure do
359
+ # ...
360
+ send_reset_password_email do
361
+ RodauthMailer.reset_password(email_to, password_reset_email_link).deliver_now
362
+ end
363
+ send_verify_account_email do
364
+ RodauthMailer.verify_account(email_to, verify_account_email_link).deliver_now
365
+ end
366
+ send_verify_login_change_email do |login|
367
+ RodauthMailer.verify_login_change(login, verify_login_change_old_login, verify_login_change_new_login, verify_login_change_email_link).deliver_now
368
+ end
369
+ send_password_changed_email do
370
+ RodauthMailer.password_changed(email_to).deliver_now
371
+ end
372
+ # send_email_auth_email do
373
+ # RodauthMailer.email_auth(email_to, email_auth_email_link).deliver_now
374
+ # end
375
+ # send_unlock_account_email do
376
+ # RodauthMailer.unlock_account(email_to, unlock_account_email_link).deliver_now
377
+ # end
378
+ # ...
379
+ end
380
+ end
381
+ ```
382
+
383
+ ## How it works
384
+
385
+ ### Middleware
386
+
387
+ rodauth-rails inserts a `Rodauth::Rails::Middleware` into your middleware
388
+ stack, which calls your Rodauth app for each request, before the request
389
+ reaches the Rails router.
390
+
391
+ ```sh
392
+ $ rails middleware
393
+ ...
394
+ use Rodauth::Rails::Middleware
395
+ run MyApp::Application.routes
396
+ ```
397
+
398
+ The Rodauth app stores the `Rodauth::Auth` instance in the Rack env hash, which
399
+ is then available in your Rails app:
400
+
401
+ ```rb
402
+ request.env["rodauth"] #=> #<Rodauth::Auth>
403
+ request.env["rodauth.secondary"] #=> #<Rodauth::Auth> (if using multiple configurations)
404
+ ```
405
+
406
+ For convenience, this object can be accessed via the `#rodauth` method in views
407
+ and controllers:
408
+
409
+ ```rb
410
+ class MyController < ApplicationController
411
+ def my_action
412
+ rodauth #=> #<Rodauth::Auth>
413
+ rodauth(:secondary) #=> #<Rodauth::Auth> (if using multiple configurations)
414
+ end
415
+ end
416
+ ```
417
+ ```erb
418
+ <% rodauth #=> #<Rodauth::Auth> %>
419
+ <% rodauth(:secondary) #=> #<Rodauth::Auth> (if using multiple configurations) %>
420
+ ```
421
+
422
+ ### App
423
+
424
+ The `Rodauth::Rails::App` class is a [Roda] subclass that provides Rails
425
+ integration for Rodauth:
426
+
427
+ * uses Rails' flash instead of Roda's
428
+ * uses Rails' CSRF protection instead of Roda's
429
+ * sets [HMAC] secret to Rails' secret key base
430
+ * uses ActionController for rendering templates
431
+ * uses ActionMailer for sending emails
432
+
433
+ The `configure { ... }` method wraps configuring the Rodauth plugin, forwarding
434
+ any additional [options].
435
+
436
+ ```rb
437
+ configure { ... } # defining default Rodauth configuration
438
+ configure(json: true) # passing options to the Rodauth plugin
439
+ configure(:secondary) { ... } # defining multiple Rodauth configurations
440
+ ```
441
+
442
+ ### Sequel
443
+
444
+ Rodauth uses the [Sequel] library for database queries, due to more advanced
445
+ database usage (SQL expressions, database-agnostic date arithmetic, SQL
446
+ function calls).
447
+
448
+ If ActiveRecord is used in the application, the `rodauth:install` generator
449
+ will have automatically configured Sequel to reuse ActiveRecord's database
450
+ connection (using the [sequel-activerecord_connection] gem).
451
+
452
+ This means that, from the usage perspective, Sequel can be considered just
453
+ as an implementation detail of Rodauth.
454
+
455
+ ## Configuring
456
+
457
+ For the list of configuration methods provided by Rodauth, see the [feature
458
+ documentation].
459
+
460
+ The `rails` feature rodauth-rails loads is customizable as well, here is the
461
+ list of its configuration methods:
462
+
463
+ | Name | Description |
464
+ | :---- | :---------- |
465
+ | `rails_render(**options)` | Renders the template with given render options. |
466
+ | `rails_csrf_tag` | Hidden field added to Rodauth templates containing the CSRF token. |
467
+ | `rails_csrf_param` | Value of the `name` attribute for the CSRF tag. |
468
+ | `rails_csrf_token` | Value of the `value` attribute for the CSRF tag. |
469
+ | `rails_check_csrf!` | Verifies the authenticity token for the current request. |
470
+ | `rails_controller_instance` | Instance of the controller with the request env context. |
471
+ | `rails_controller` | Controller class to use for rendering and CSRF protection. |
472
+
473
+ The `Rodauth::Rails` module has a few config settings available as well:
474
+
475
+ | Name | Description |
476
+ | :----- | :---------- |
477
+ | `app` | Constant name of your Rodauth app, which is called by the middleware. |
478
+ | `middleware` | Whether to insert the middleware into the Rails application's middleware stack. Defaults to `true`. |
479
+
480
+ ```rb
481
+ # config/initializers/rodauth.rb
482
+ Rodauth::Rails.configure do |config|
483
+ config.app = "RodauthApp"
484
+ config.middleware = true
485
+ end
486
+ ```
487
+
488
+ ## Testing
489
+
490
+ If you're writing system tests, it's generally better to go through the actual
491
+ authentication flow with tools like Capybara, and to not use any stubbing.
492
+
493
+ In functional and integration tests you can just make requests to Rodauth
494
+ routes:
495
+
496
+ ```rb
497
+ # test/controllers/posts_controller_test.rb
498
+ class PostsControllerTest < ActionDispatch::IntegrationTest
499
+ test "should require authentication" do
500
+ get posts_url
501
+ assert_redirected_to "/login"
502
+
503
+ login
504
+ get posts_url
505
+ assert_response :success
506
+
507
+ logout
508
+ assert_redirected_to "/login"
509
+ end
510
+
511
+ private
512
+
513
+ def login(login: "user@example.com", password: "secret")
514
+ post "/create-account", params: {
515
+ "login" => login,
516
+ "password" => password,
517
+ "password-confirm" => password,
518
+ }
519
+
520
+ post "/login", params: {
521
+ "login" => login,
522
+ "password" => password,
523
+ }
524
+ end
525
+
526
+ def logout
527
+ post "/logout"
528
+ end
529
+ end
530
+ ```
531
+
532
+ ## Rodauth defaults
533
+
534
+ rodauth-rails changes some of the default Rodauth settings for easier setup:
535
+
536
+ ### Database functions
537
+
538
+ By default on PostgreSQL, MySQL, and Microsoft SQL Server, Rodauth uses
539
+ database functions to access password hashes, with the user running the
540
+ application unable to get direct access to password hashes. This reduces the
541
+ risk of an attacker being able to access password hashes and use them to attack
542
+ other sites.
543
+
544
+ While this is useful additional security, it is also more complex to set up and
545
+ to reason about, as it requires having two different database users and making
546
+ sure the correct migration is run for the correct user.
547
+
548
+ To keep with Rails' "convention over configuration" doctrine, rodauth-rails
549
+ disables the use of database functions, though it can still be turned back on.
550
+
551
+ ### Account statuses
552
+
553
+ The recommended [Rodauth migration] stores possible account status values in a
554
+ separate table, and creates a foreign key on the accounts table, which ensures
555
+ only a valid status value will be persisted.
556
+
557
+ Unfortunately, this doesn't work when the database is restored from the schema
558
+ file, in which case the account statuses table will be empty. This happens in
559
+ tests by default, but it's also commonly done in development.
560
+
561
+ To address this, rodauth-rails modifies the setup to store account status text
562
+ directly in the accounts table. If you're worried about invalid status values
563
+ creeping in, you may use enums instead. Alternatively, you can still go back to
564
+ the setup recommended by Rodauth.
565
+
566
+ ## License
567
+
568
+ The gem is available as open source under the terms of the [MIT
569
+ License](https://opensource.org/licenses/MIT).
570
+
571
+ ## Code of Conduct
572
+
573
+ Everyone interacting in the rodauth-rails project's codebases, issue trackers,
574
+ chat rooms and mailing lists is expected to follow the [code of
575
+ conduct](https://github.com/janko/rodauth-rails/blob/master/CODE_OF_CONDUCT.md).
576
+
577
+ [Rodauth]: https://github.com/jeremyevans/rodauth
578
+ [Sequel]: https://github.com/jeremyevans/sequel
579
+ [rendering views outside of controllers]: https://blog.bigbinary.com/2016/01/08/rendering-views-outside-of-controllers-in-rails-5.html
580
+ [feature documentation]: http://rodauth.jeremyevans.net/documentation.html
581
+ [Rodauth plugin]: https://github.com/jeremyevans/rodauth/#label-Plugin+Options
582
+ [Bootstrap]: https://getbootstrap.com/
583
+ [Roda]: http://roda.jeremyevans.net/
584
+ [HMAC]: http://rodauth.jeremyevans.net/rdoc/files/README_rdoc.html#label-HMAC
585
+ [database authentication functions]: http://rodauth.jeremyevans.net/rdoc/files/README_rdoc.html#label-Password+Hash+Access+Via+Database+Functions
586
+ [multiple configurations]: http://rodauth.jeremyevans.net/rdoc/files/README_rdoc.html#label-With+Multiple+Configurations
587
+ [views]: /app/views/rodauth
588
+ [Rodauth migration]: http://rodauth.jeremyevans.net/rdoc/files/README_rdoc.html#label-Creating+tables
589
+ [sequel-activerecord_connection]: https://github.com/janko/sequel-activerecord_connection
@@ -0,0 +1,65 @@
1
+ require "rails/generators/base"
2
+ require "rails/generators/migration"
3
+ require "rails/generators/active_record"
4
+ require "rodauth/version"
5
+
6
+ module Rodauth
7
+ module Rails
8
+ module Generators
9
+ class InstallGenerator < ::Rails::Generators::Base
10
+ include ::Rails::Generators::Migration
11
+
12
+ source_root "#{__dir__}/templates"
13
+ namespace "rodauth:install"
14
+
15
+ def create_rodauth_migration
16
+ return unless defined?(ActiveRecord::Base)
17
+
18
+ migration_template "db/migrate/create_rodauth.rb", "db/migrate/create_rodauth.rb"
19
+ end
20
+
21
+ def create_rodauth_initializer
22
+ template "config/initializers/rodauth.rb"
23
+ end
24
+
25
+ def create_sequel_initializer
26
+ return unless defined?(ActiveRecord::Base)
27
+ return unless %w[postgresql mysql2 sqlite3].include?(adapter)
28
+
29
+ template "config/initializers/sequel.rb"
30
+ end
31
+
32
+ def create_rodauth_app
33
+ template "lib/rodauth_app.rb"
34
+ end
35
+
36
+ def create_rodauth_controller
37
+ template "app/controllers/rodauth_controller.rb"
38
+ end
39
+
40
+ def create_account_model
41
+ return unless defined?(ActiveRecord::Base)
42
+
43
+ template "app/models/account.rb"
44
+ end
45
+
46
+ private
47
+
48
+ # required by #migration_template action
49
+ def self.next_migration_number(dirname)
50
+ ActiveRecord::Generators::Base.next_migration_number(dirname)
51
+ end
52
+
53
+ def migration_version
54
+ if ActiveRecord.version >= Gem::Version.new("5.0.0")
55
+ "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
56
+ end
57
+ end
58
+
59
+ def adapter
60
+ ActiveRecord::Base.connection_config.fetch(:adapter)
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end