rodauth-rails 0.1.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 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