rockstart 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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +100 -0
- data/Rakefile +19 -0
- data/lib/generators/rockstart/USAGE +13 -0
- data/lib/generators/rockstart/devise/USAGE +9 -0
- data/lib/generators/rockstart/devise/devise_generator.rb +258 -0
- data/lib/generators/rockstart/devise/templates/controllers/passwords_controller.rb +56 -0
- data/lib/generators/rockstart/devise/templates/controllers/registrations_controller.rb +88 -0
- data/lib/generators/rockstart/devise/templates/controllers/sessions_controller.rb +32 -0
- data/lib/generators/rockstart/devise/templates/create_user_migration.rb.tt +11 -0
- data/lib/generators/rockstart/devise/templates/models/user.rb +42 -0
- data/lib/generators/rockstart/devise/templates/spec/factories/users.rb +17 -0
- data/lib/generators/rockstart/devise/templates/spec/models/user_spec.rb +64 -0
- data/lib/generators/rockstart/devise/templates/spec/requests/users/passwords_spec.rb +202 -0
- data/lib/generators/rockstart/devise/templates/spec/requests/users/registrations_spec.rb +445 -0
- data/lib/generators/rockstart/devise/templates/spec/requests/users/sessions_spec.rb +171 -0
- data/lib/generators/rockstart/devise/templates/spec/support/devise_request_spec_helper.rb +29 -0
- data/lib/generators/rockstart/devise/templates/translations.en.yml +4 -0
- data/lib/generators/rockstart/docker/USAGE +10 -0
- data/lib/generators/rockstart/docker/docker_generator.rb +86 -0
- data/lib/generators/rockstart/docker/templates/app/Dockerfile-app +47 -0
- data/lib/generators/rockstart/docker/templates/docker-compose.test.yml +29 -0
- data/lib/generators/rockstart/docker/templates/docker-compose.yml +47 -0
- data/lib/generators/rockstart/docker/templates/dockerignore +16 -0
- data/lib/generators/rockstart/docker/templates/dotenv.docker.tt +4 -0
- data/lib/generators/rockstart/docker/templates/localhost_domains.ext.tt +7 -0
- data/lib/generators/rockstart/docker/templates/setup-localhost.tt +27 -0
- data/lib/generators/rockstart/docker/templates/web/Dockerfile-web +15 -0
- data/lib/generators/rockstart/docker/templates/web/nginx.conf +62 -0
- data/lib/generators/rockstart/frontend_helpers/USAGE +8 -0
- data/lib/generators/rockstart/frontend_helpers/frontend_helpers_generator.rb +65 -0
- data/lib/generators/rockstart/frontend_helpers/templates/application_urls.rb +26 -0
- data/lib/generators/rockstart/frontend_helpers/templates/application_urls_helper.rb +20 -0
- data/lib/generators/rockstart/frontend_helpers/templates/titles.en.yml.tt +5 -0
- data/lib/generators/rockstart/logging/USAGE +8 -0
- data/lib/generators/rockstart/logging/logging_generator.rb +12 -0
- data/lib/generators/rockstart/logging/templates/rockstart/lograge_initializer.rb +50 -0
- data/lib/generators/rockstart/postgres/USAGE +8 -0
- data/lib/generators/rockstart/postgres/postgres_generator.rb +32 -0
- data/lib/generators/rockstart/postgres/templates/config/database.yml.tt +18 -0
- data/lib/generators/rockstart/postgres/templates/migration.rb.tt +7 -0
- data/lib/generators/rockstart/pundit/USAGE +8 -0
- data/lib/generators/rockstart/pundit/pundit_generator.rb +32 -0
- data/lib/generators/rockstart/pundit/templates/app/controllers/concerns/pundit_error_handling.rb +29 -0
- data/lib/generators/rockstart/pundit/templates/app/policies/application_policy.rb +71 -0
- data/lib/generators/rockstart/pundit/templates/app/policies/user_policy.rb +47 -0
- data/lib/generators/rockstart/pundit/templates/config/locales/pundit.en.yml +6 -0
- data/lib/generators/rockstart/pundit/templates/lib/templates/pundit/policy/policy.rb +36 -0
- data/lib/generators/rockstart/pundit/templates/lib/templates/rspec/policy/policy_spec.rb +58 -0
- data/lib/generators/rockstart/pundit/templates/spec/policies/user_policy_spec.rb +95 -0
- data/lib/generators/rockstart/pundit/templates/spec/support/pundit_matchers.rb +7 -0
- data/lib/generators/rockstart/quality/USAGE +10 -0
- data/lib/generators/rockstart/quality/quality_generator.rb +28 -0
- data/lib/generators/rockstart/quality/templates/quality.rake +4 -0
- data/lib/generators/rockstart/quality/templates/rubocop.rake +4 -0
- data/lib/generators/rockstart/quality/templates/rubocop.yml +45 -0
- data/lib/generators/rockstart/rockstart_generator.rb +77 -0
- data/lib/generators/rockstart/rspec/USAGE +8 -0
- data/lib/generators/rockstart/rspec/rspec_generator.rb +70 -0
- data/lib/generators/rockstart/rspec/templates/dotenv.development +1 -0
- data/lib/generators/rockstart/rspec/templates/dotenv.test +1 -0
- data/lib/generators/rockstart/rspec/templates/rspec_templates/model/model_spec.rb +13 -0
- data/lib/generators/rockstart/rspec/templates/support/factory_bot.rb +6 -0
- data/lib/generators/rockstart/rspec/templates/support/shoulda_matchers.rb +9 -0
- data/lib/generators/rockstart/rspec/templates/support/test_helpers.rb +9 -0
- data/lib/generators/rockstart/scaffold_templates/USAGE +8 -0
- data/lib/generators/rockstart/scaffold_templates/scaffold_templates_generator.rb +39 -0
- data/lib/generators/rockstart/scaffold_templates/templates/api_controller.rb.tt +96 -0
- data/lib/generators/rockstart/scaffold_templates/templates/controller.rb.tt +126 -0
- data/lib/generators/rockstart/scaffold_templates/templates/rspec/scaffold/api_request_spec.rb +139 -0
- data/lib/generators/rockstart/scaffold_templates/templates/rspec/scaffold/request_spec.rb +408 -0
- data/lib/generators/rockstart/security/USAGE +13 -0
- data/lib/generators/rockstart/security/security_generator.rb +108 -0
- data/lib/generators/rockstart/security/templates/brakeman.rake +6 -0
- data/lib/generators/rockstart/security/templates/bundler_audit.rake +4 -0
- data/lib/generators/rockstart/security/templates/cache_support.rb +18 -0
- data/lib/generators/rockstart/security/templates/content_security_policy_initializer.rb.tt +56 -0
- data/lib/generators/rockstart/security/templates/content_security_spec.rb.tt +83 -0
- data/lib/generators/rockstart/security/templates/csp_violations_controller.rb +39 -0
- data/lib/generators/rockstart/security/templates/rack_attack.rb +98 -0
- data/lib/generators/rockstart/security/templates/security.rake +9 -0
- data/lib/generators/rockstart/security/templates/session_store_initializer.rb.tt +7 -0
- data/lib/generators/rockstart/smtp_mailer/USAGE +8 -0
- data/lib/generators/rockstart/smtp_mailer/smtp_mailer_generator.rb +30 -0
- data/lib/generators/rockstart/smtp_mailer/templates/config/initializers/action_mailer.rb +10 -0
- data/lib/generators/rockstart/tailwindcss/USAGE +8 -0
- data/lib/generators/rockstart/tailwindcss/tailwindcss_generator.rb +30 -0
- data/lib/generators/rockstart/tailwindcss/templates/application.css +3 -0
- data/lib/generators/rockstart/tailwindcss/templates/postcss.config.js +32 -0
- data/lib/rockstart/base_generator.rb +32 -0
- data/lib/rockstart/env.rb +16 -0
- data/lib/rockstart/railtie.rb +6 -0
- data/lib/rockstart/version.rb +5 -0
- data/lib/rockstart.rb +9 -0
- data/lib/tasks/rockstart_tasks.rake +5 -0
- metadata +187 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 9ba7c0a5317e53f705cd38bd10ada153e28d5adab8ac3b4d8a182a6312a8a5e7
|
|
4
|
+
data.tar.gz: 9113486cc9d6f7087d91fa29a54e7c39fda7fb2daf0a386e3739913432344c5a
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 3742b345254b2baf3eb6433af39d686c90bc9c80308128d738b47ea031112b1fd6b888c0f603953439dd60f5349662b279ac94bf2a7858bacb565c31238d82ac
|
|
7
|
+
data.tar.gz: 8c3a806404352d26ab4f424d71ddb315378d4eb33fa9be666872328f3890f337d993aa6560d31d63a5334ebd8e9411d6b95a8586d441b2a11d3c09d9b947d83d
|
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright 2020 Ben Morrall
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Rockstart
|
|
2
|
+
A collection of generators to rapidly start and update ready-to-run Rails Applications.
|
|
3
|
+
|
|
4
|
+
## Usage
|
|
5
|
+
Most applications can be configured using the standard generator:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bundle exec rails g rockstart
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
For those wanting more control; Rockstart provides a number of generators that can be used as required.
|
|
12
|
+
|
|
13
|
+
### Postgres
|
|
14
|
+
Rockstart creates a config/database.yml suitable for Heroku or Docker installations.
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
bundle exec rails g rockstart:postgres
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Docker
|
|
21
|
+
Rockstart can configure your Rails
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
bundle exec rails g rockstart:docker
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
It uses the current Ruby Version, your Rails configuration, along with the current Application Name, to generate a Dockerfile with sensible defaults.
|
|
28
|
+
|
|
29
|
+
### RSpec
|
|
30
|
+
|
|
31
|
+
Rockstart can pre-configure RSpec for your repository.
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
bundle exec rails g rockstart:rspec
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Security
|
|
38
|
+
|
|
39
|
+
Rockstart can install a rake task for checking the security of your app
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
bundle exec rails g rockstart:security
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Quality
|
|
46
|
+
|
|
47
|
+
Rockstart can add tasks for maintaining the quality of your codebase.
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
bundle exec rails g rockstart:quality
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
It will install [rubocop-rails](https://github.com/rubocop-hq/rubocop-rails), add a basic set of rule guidelines and auto-generates a configuration file to highlight any existing problems.
|
|
54
|
+
|
|
55
|
+
Provides a "quality" rake task, which runs all code quality tests on your Application.
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
bundle exec rake quality
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Frontend Helpers
|
|
62
|
+
|
|
63
|
+
Installs helpers for easy developer of Frontend Interfaces:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
bundle exec rails g rockstart:frontend_helpers
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Tailwind CSS
|
|
70
|
+
|
|
71
|
+
[Tailwind CSS](https://tailwindcss.com) is a CSS framework for rapidly prototyping applications.
|
|
72
|
+
|
|
73
|
+
Install it, via Webpacker, by running:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
bundle exec rails g rockstart:tailwindcss
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Installation
|
|
80
|
+
Add this line to your application's Gemfile:
|
|
81
|
+
|
|
82
|
+
```ruby
|
|
83
|
+
gem 'rockstart', group: :development
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
And then execute:
|
|
87
|
+
```bash
|
|
88
|
+
$ bundle
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Or install it yourself as:
|
|
92
|
+
```bash
|
|
93
|
+
$ gem install rockstart
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Contributing
|
|
97
|
+
Contribution directions go here.
|
|
98
|
+
|
|
99
|
+
## License
|
|
100
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require "bundler/setup"
|
|
5
|
+
rescue LoadError
|
|
6
|
+
puts "You must `gem install bundler` and `bundle install` to run rake tasks"
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
require "rdoc/task"
|
|
10
|
+
|
|
11
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
|
12
|
+
rdoc.rdoc_dir = "rdoc"
|
|
13
|
+
rdoc.title = "Rockstart"
|
|
14
|
+
rdoc.options << "--line-numbers"
|
|
15
|
+
rdoc.rdoc_files.include("README.md")
|
|
16
|
+
rdoc.rdoc_files.include("lib/**/*.rb")
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
require "bundler/gem_tasks"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Description:
|
|
2
|
+
Configures an application with the default rockstart setup
|
|
3
|
+
|
|
4
|
+
Example:
|
|
5
|
+
rails generate rockstart
|
|
6
|
+
|
|
7
|
+
This will run the following generators:
|
|
8
|
+
rockstart:logging
|
|
9
|
+
rockstart:rspec
|
|
10
|
+
rockstart:quality
|
|
11
|
+
rockstart:postgres (depending on database)
|
|
12
|
+
rockstart:smtp_mailer
|
|
13
|
+
rockstart:docker
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rockstart/base_generator"
|
|
4
|
+
|
|
5
|
+
class Rockstart::DeviseGenerator < Rockstart::BaseGenerator
|
|
6
|
+
include Rails::Generators::Migration
|
|
7
|
+
|
|
8
|
+
# Implement the required interface for Rails::Generators::Migration.
|
|
9
|
+
def self.next_migration_number(dirname)
|
|
10
|
+
next_migration_number = current_migration_number(dirname) + 1
|
|
11
|
+
ActiveRecord::Migration.next_migration_number(next_migration_number)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
source_root File.expand_path("templates", __dir__)
|
|
15
|
+
|
|
16
|
+
class_option :devise_layout, type: :string,
|
|
17
|
+
desc: "Custom layout used by all devise controllers",
|
|
18
|
+
default: "application"
|
|
19
|
+
|
|
20
|
+
class_option :pundit, type: :boolean,
|
|
21
|
+
desc: "Include Pundit support",
|
|
22
|
+
default: true
|
|
23
|
+
|
|
24
|
+
class_option :skip_controllers, type: :boolean,
|
|
25
|
+
desc: "Skip Generating custom Devise Controllers",
|
|
26
|
+
default: false
|
|
27
|
+
|
|
28
|
+
class_option :skip_migration, type: :boolean,
|
|
29
|
+
desc: "Skip create user model migration generation",
|
|
30
|
+
default: false
|
|
31
|
+
|
|
32
|
+
class_option :skip_model, type: :boolean,
|
|
33
|
+
desc: "Skip model generation",
|
|
34
|
+
default: false
|
|
35
|
+
|
|
36
|
+
def add_namae_gem
|
|
37
|
+
gem "namae"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def add_user_model
|
|
41
|
+
directory "models", "app/models"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def add_user_migration
|
|
45
|
+
return if options[:skip_migration]
|
|
46
|
+
|
|
47
|
+
migration_template "create_user_migration.rb.tt", "db/migrate/create_users.rb"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def install_devise
|
|
51
|
+
gem "devise"
|
|
52
|
+
|
|
53
|
+
bundle_install do
|
|
54
|
+
Dir.mktmpdir do |dir|
|
|
55
|
+
generate_devise_install(dir)
|
|
56
|
+
directory File.join(dir, "config"), "config"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def add_devise_controllers
|
|
62
|
+
return if options[:skip_controllers]
|
|
63
|
+
|
|
64
|
+
Bundler.with_clean_env do
|
|
65
|
+
Dir.mktmpdir do |dir|
|
|
66
|
+
generate_devise_controllers(dir)
|
|
67
|
+
add_pundit_support(dir) if options[:pundit]
|
|
68
|
+
devise_controllers.each do |controller|
|
|
69
|
+
copy_file File.join(dir, controller_path(controller)), controller_path(controller)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def generate_user_model
|
|
76
|
+
return if options[:skip_model]
|
|
77
|
+
|
|
78
|
+
Bundler.with_clean_env do
|
|
79
|
+
generate "devise", "User"
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def inject_routes
|
|
84
|
+
return if options[:skip_controllers]
|
|
85
|
+
|
|
86
|
+
controller_templates = devise_controllers.map do |controller|
|
|
87
|
+
" #{controller}: \"users/#{controller}\""
|
|
88
|
+
end.join(",\n")
|
|
89
|
+
|
|
90
|
+
gsub_file "config/routes.rb", /devise_for :users.*$$/ do
|
|
91
|
+
["devise_for :users, controllers: {", controller_templates, " }"].join("\n")
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def add_rspec_coverage
|
|
96
|
+
directory "spec"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def update_application_url_concerns
|
|
100
|
+
change_application_url("url_for_authentication", "new_user_session_path")
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def add_testing_variables
|
|
104
|
+
append_file ".env.development", "DEVISE_MAILER_SENDER=devise-mailer@localhost\n"
|
|
105
|
+
append_file ".env.test", "DEVISE_MAILER_SENDER=devise-mailer@example.com\n"
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
private
|
|
109
|
+
|
|
110
|
+
def rails5_and_up?
|
|
111
|
+
Rails::VERSION::MAJOR >= 5
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def migration_version
|
|
115
|
+
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]" if rails5_and_up?
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def generate_devise_install(dir)
|
|
119
|
+
initializer = build_devise_install_generator(dir)
|
|
120
|
+
initializer.invoke_all
|
|
121
|
+
|
|
122
|
+
update_initializer(dir)
|
|
123
|
+
make_devise_paranoid(dir)
|
|
124
|
+
send_email_on_email_change(dir)
|
|
125
|
+
send_email_on_password_change(dir)
|
|
126
|
+
add_translations(dir)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def build_devise_install_generator(dir)
|
|
130
|
+
require "generators/devise/install_generator"
|
|
131
|
+
|
|
132
|
+
initializer = ::Devise::Generators::InstallGenerator.new(
|
|
133
|
+
report_stream: StringIO.new
|
|
134
|
+
)
|
|
135
|
+
initializer.destination_root = dir
|
|
136
|
+
initializer
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def update_initializer(dir)
|
|
140
|
+
gsub_file devise_initializer(dir),
|
|
141
|
+
/config\.mailer_sender = ['"][^'"]+['']/,
|
|
142
|
+
'config.mailer_sender = ENV.fetch("DEVISE_MAILER_SENDER",' \
|
|
143
|
+
" Rails.application.credentials.devise_mailer_sender)"
|
|
144
|
+
gsub_file devise_initializer(dir),
|
|
145
|
+
/config\.secret_key = ['"][^'"]+['']/,
|
|
146
|
+
'config.secret_key = ENV.fetch("DEVISE_SECRET_KEY")'
|
|
147
|
+
gsub_file devise_initializer(dir),
|
|
148
|
+
/config\.pepper = ['"][^'"]+['']/,
|
|
149
|
+
'config.pepper = ENV.fetch("DEVISE_PEPPER")'
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def make_devise_paranoid(dir)
|
|
153
|
+
gsub_file devise_initializer(dir),
|
|
154
|
+
/config\.paranoid = (true|false)/,
|
|
155
|
+
"config.paranoid = true"
|
|
156
|
+
uncomment_lines devise_initializer(dir), /config\.paranoid = true/
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def send_email_on_email_change(dir)
|
|
160
|
+
gsub_file devise_initializer(dir),
|
|
161
|
+
/config\.send_email_changed_notification = (true|false)/,
|
|
162
|
+
"config.send_email_changed_notification = true"
|
|
163
|
+
uncomment_lines devise_initializer(dir), /config\.send_email_changed_notification = true/
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def send_email_on_password_change(dir)
|
|
167
|
+
gsub_file devise_initializer(dir),
|
|
168
|
+
/config\.send_password_change_notification = (true|false)/,
|
|
169
|
+
"config.send_password_change_notification = true"
|
|
170
|
+
uncomment_lines devise_initializer(dir), /config\.send_password_change_notification = true/
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def add_translations(dir)
|
|
174
|
+
inject_into_file File.join(dir, "config/locales/devise.en.yml"), after: /failure:$/ do
|
|
175
|
+
"\n deleted_account: " \
|
|
176
|
+
"\"You've deleted your account. Please contact support if you want to recover it!\""
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def devise_initializer(dir)
|
|
181
|
+
File.join(dir, "config", "initializers", "devise.rb")
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def generate_devise_controllers(dir)
|
|
185
|
+
require "generators/devise/controllers_generator"
|
|
186
|
+
|
|
187
|
+
initializer = build_devise_controllers_generator(dir)
|
|
188
|
+
initializer.scope = "users"
|
|
189
|
+
initializer.invoke_all
|
|
190
|
+
|
|
191
|
+
devise_controllers.each do |controller|
|
|
192
|
+
add_layout_to_controller(dir, controller)
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def build_devise_controllers_generator(dir)
|
|
197
|
+
initializer = ::Devise::Generators::ControllersGenerator.new(
|
|
198
|
+
report_stream: StringIO.new
|
|
199
|
+
)
|
|
200
|
+
initializer.destination_root = dir
|
|
201
|
+
initializer.source_paths.insert(1, File.join(self.class.source_root, "controllers"))
|
|
202
|
+
initializer
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def add_layout_to_controller(dir, controller)
|
|
206
|
+
inject_into_file File.join(dir, controller_path(controller)), after: /< Devise::.*$/ do
|
|
207
|
+
"\n layout \"#{options[:devise_layout]}\"\n"
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# Replace Generic resource routes with users
|
|
211
|
+
gsub_file File.join(dir, controller_path(controller)), "/resource", "/users"
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def add_pundit_support(dir)
|
|
215
|
+
use_pundit_for_update_user_details(dir)
|
|
216
|
+
add_pudit_authorize_current_user_method(dir)
|
|
217
|
+
add_pudit_authorize_current_user_callback(dir)
|
|
218
|
+
add_pudit_error_handling_concern(dir)
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def use_pundit_for_update_user_details(dir)
|
|
222
|
+
gsub_file File.join(dir, controller_path("registrations")),
|
|
223
|
+
/\.permit\(:account_update.*\)/,
|
|
224
|
+
".permit(:account_update, keys: policy(current_user).permitted_attributes_for_update)"
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def add_pudit_authorize_current_user_method(dir)
|
|
228
|
+
inject_into_file File.join(dir, controller_path("registrations")), after: "protected\n" do
|
|
229
|
+
"\n" + <<~'METHOD'.gsub(/([^\n]*)\n/, " \\1\n")
|
|
230
|
+
# Ensure the logged in user is able to update or destroy their account
|
|
231
|
+
def authorize_current_user
|
|
232
|
+
authorize current_user
|
|
233
|
+
end
|
|
234
|
+
METHOD
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def add_pudit_authorize_current_user_callback(dir)
|
|
239
|
+
inject_into_file File.join(dir, controller_path("registrations")),
|
|
240
|
+
after: /before_action :configure_account_update_params.*$/ do
|
|
241
|
+
"\n before_action :authorize_current_user, only: %i[edit update destroy]"
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def add_pudit_error_handling_concern(dir)
|
|
246
|
+
inject_into_file File.join(dir, controller_path("registrations")), after: /< Devise::.*$/ do
|
|
247
|
+
"\n include PunditErrorHandling\n"
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
def controller_path(controller)
|
|
252
|
+
File.join("app", "controllers", "users", "#{controller}_controller.rb")
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def devise_controllers
|
|
256
|
+
%w[sessions passwords registrations]
|
|
257
|
+
end
|
|
258
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Updated Passwords Controller provided by rockstart
|
|
4
|
+
class Users::PasswordsController < Devise::PasswordsController
|
|
5
|
+
# Store reset token in session so that it is not in Referer
|
|
6
|
+
before_action :move_reset_token_to_session, only: [:edit]
|
|
7
|
+
|
|
8
|
+
# GET /resource/password/new
|
|
9
|
+
# def new
|
|
10
|
+
# super
|
|
11
|
+
# end
|
|
12
|
+
|
|
13
|
+
# POST /resource/password
|
|
14
|
+
# def create
|
|
15
|
+
# super
|
|
16
|
+
# end
|
|
17
|
+
|
|
18
|
+
# GET /resource/password/edit?reset_password_token=abcdef
|
|
19
|
+
def edit
|
|
20
|
+
super
|
|
21
|
+
resource.reset_password_token = session[:reset_password_token]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# PUT /resource/password
|
|
25
|
+
# def update
|
|
26
|
+
# super
|
|
27
|
+
# end
|
|
28
|
+
|
|
29
|
+
protected
|
|
30
|
+
|
|
31
|
+
def move_reset_token_to_session
|
|
32
|
+
token = params.delete(:reset_password_token)
|
|
33
|
+
return unless token
|
|
34
|
+
|
|
35
|
+
session[:reset_password_token] = token
|
|
36
|
+
redirect_to edit_password_path(resource_class.new)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def assert_reset_token_passed
|
|
40
|
+
session[:reset_password_token].blank? && super
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def sign_in(resource_name, resource)
|
|
44
|
+
session.delete(:reset_password_token)
|
|
45
|
+
super
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# def after_resetting_password_path_for(resource)
|
|
49
|
+
# super(resource)
|
|
50
|
+
# end
|
|
51
|
+
|
|
52
|
+
# The path used after sending reset password instructions
|
|
53
|
+
# def after_sending_reset_password_instructions_path_for(resource_name)
|
|
54
|
+
# super(resource_name)
|
|
55
|
+
# end
|
|
56
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Updated Registrations Controller provided by rockstart
|
|
4
|
+
class Users::RegistrationsController < Devise::RegistrationsController
|
|
5
|
+
# before_action :configure_sign_up_params, only: %i[create]
|
|
6
|
+
before_action :configure_account_update_params, only: %i[update]
|
|
7
|
+
|
|
8
|
+
# GET /users/sign_up
|
|
9
|
+
# def new
|
|
10
|
+
# super
|
|
11
|
+
# end
|
|
12
|
+
|
|
13
|
+
# POST /users
|
|
14
|
+
# def create
|
|
15
|
+
# super
|
|
16
|
+
# end
|
|
17
|
+
|
|
18
|
+
# GET /users/edit
|
|
19
|
+
# def edit
|
|
20
|
+
# super
|
|
21
|
+
# end
|
|
22
|
+
|
|
23
|
+
# PUT /users
|
|
24
|
+
# def update
|
|
25
|
+
# super
|
|
26
|
+
# end
|
|
27
|
+
|
|
28
|
+
# DELETE /users
|
|
29
|
+
def destroy
|
|
30
|
+
resource.soft_delete
|
|
31
|
+
Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
|
|
32
|
+
set_flash_message :notice, :destroyed
|
|
33
|
+
yield resource if block_given?
|
|
34
|
+
respond_with_navigational(resource) { redirect_to after_sign_out_path_for(resource_name) }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# GET /users/cancel
|
|
38
|
+
# Forces the session data which is usually expired after sign
|
|
39
|
+
# in to be expired now. This is useful if the user wants to
|
|
40
|
+
# cancel oauth signing in/up in the middle of the process,
|
|
41
|
+
# removing all OAuth session data.
|
|
42
|
+
# def cancel
|
|
43
|
+
# super
|
|
44
|
+
# end
|
|
45
|
+
|
|
46
|
+
protected
|
|
47
|
+
|
|
48
|
+
# If you have extra params to permit, append them to the sanitizer.
|
|
49
|
+
# def configure_sign_up_params
|
|
50
|
+
# devise_parameter_sanitizer.permit(:sign_up, keys: [:attribute])
|
|
51
|
+
# end
|
|
52
|
+
|
|
53
|
+
# If you have extra params to permit, append them to the sanitizer.
|
|
54
|
+
def configure_account_update_params
|
|
55
|
+
devise_parameter_sanitizer.permit(:account_update, keys: %i[name])
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# The path used after deleting account
|
|
59
|
+
def after_sign_out_path_for(_resource)
|
|
60
|
+
new_user_registration_path
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# The path used after sign up.
|
|
64
|
+
# def after_sign_up_path_for(resource)
|
|
65
|
+
# super(resource)
|
|
66
|
+
# end
|
|
67
|
+
|
|
68
|
+
# The path used after sign up for inactive accounts.
|
|
69
|
+
# def after_inactive_sign_up_path_for(resource)
|
|
70
|
+
# super(resource)
|
|
71
|
+
# end
|
|
72
|
+
|
|
73
|
+
# Allow the user to edit their account without providing a password
|
|
74
|
+
def update_resource(resource, params)
|
|
75
|
+
if account_update_params[:password].blank?
|
|
76
|
+
resource.update_without_password(params)
|
|
77
|
+
else
|
|
78
|
+
super
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def account_update_params
|
|
83
|
+
super.tap do |params|
|
|
84
|
+
# Ensure password confirmation is included with password
|
|
85
|
+
params[:password_confirmation] ||= "" if params[:password].present?
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Updated Sessions Controller provided by rockstart
|
|
4
|
+
class Users::SessionsController < Devise::SessionsController
|
|
5
|
+
# before_action :configure_sign_in_params, only: [:create]
|
|
6
|
+
|
|
7
|
+
# GET /resource/sign_in
|
|
8
|
+
# def new
|
|
9
|
+
# super
|
|
10
|
+
# end
|
|
11
|
+
|
|
12
|
+
# POST /resource/sign_in
|
|
13
|
+
# def create
|
|
14
|
+
# super
|
|
15
|
+
# end
|
|
16
|
+
|
|
17
|
+
# DELETE /resource/sign_out
|
|
18
|
+
# def destroy
|
|
19
|
+
# super
|
|
20
|
+
# end
|
|
21
|
+
|
|
22
|
+
protected
|
|
23
|
+
|
|
24
|
+
def after_sign_out_path_for(_resource)
|
|
25
|
+
url_for_authentication
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# If you have extra params to permit, append them to the sanitizer.
|
|
29
|
+
# def configure_sign_in_params
|
|
30
|
+
# devise_parameter_sanitizer.permit(:sign_in, keys: [:attribute])
|
|
31
|
+
# end
|
|
32
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class CreateUsers < ActiveRecord::Migration<%= migration_version %>
|
|
4
|
+
def change
|
|
5
|
+
create_table :users, id: :uuid do |t|
|
|
6
|
+
t.string :name
|
|
7
|
+
t.boolean :admin, default: false, null: false
|
|
8
|
+
t.datetime :deleted_at
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# User model used to represent registered User
|
|
4
|
+
class User < ApplicationRecord
|
|
5
|
+
# Include default devise modules. Others available are:
|
|
6
|
+
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
|
|
7
|
+
devise :database_authenticatable, :registerable,
|
|
8
|
+
:recoverable, :rememberable, :validatable
|
|
9
|
+
|
|
10
|
+
# email:string
|
|
11
|
+
# name:string
|
|
12
|
+
# admin:boolean
|
|
13
|
+
# deleted_at:datetime
|
|
14
|
+
|
|
15
|
+
delegate :given, :family, to: :namae
|
|
16
|
+
|
|
17
|
+
# instead of deleting users, mark them as soft deleted
|
|
18
|
+
def soft_delete
|
|
19
|
+
update_attribute(:deleted_at, Time.current)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# [devise] ensure user account is active
|
|
23
|
+
def active_for_authentication?
|
|
24
|
+
super && !deleted_at?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# [devise] provide a custom message for a soft-deleted account
|
|
28
|
+
def inactive_message
|
|
29
|
+
!deleted_at? ? super : :deleted_account
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def to_s
|
|
33
|
+
# Use the stored name value for labels
|
|
34
|
+
(name_changed? ? name_was : name) || (id? ? "User ##{id}" : "Guest User")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def namae
|
|
40
|
+
@namae ||= Namae::Name.parse(name)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
FactoryBot.define do
|
|
4
|
+
factory :user do
|
|
5
|
+
email { Faker::Internet.email }
|
|
6
|
+
password { Faker::Internet.password }
|
|
7
|
+
name { Faker::Name.name }
|
|
8
|
+
|
|
9
|
+
trait :admin do
|
|
10
|
+
admin { true }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
trait :soft_deleted do
|
|
14
|
+
deleted_at { Time.zone.now }
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|