kowl 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (250) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +7 -0
  3. data/README.md +383 -0
  4. data/bin/console +14 -0
  5. data/bin/kowl +106 -0
  6. data/bin/setup +13 -0
  7. data/lib/kowl/actions.rb +240 -0
  8. data/lib/kowl/docker.rb +447 -0
  9. data/lib/kowl/generators/README.md +5 -0
  10. data/lib/kowl/generators/action_generator.rb +113 -0
  11. data/lib/kowl/generators/admin_generator.rb +114 -0
  12. data/lib/kowl/generators/assets_generator.rb +188 -0
  13. data/lib/kowl/generators/base.rb +40 -0
  14. data/lib/kowl/generators/circleci_generator.rb +11 -0
  15. data/lib/kowl/generators/config_generator.rb +180 -0
  16. data/lib/kowl/generators/controller_generator.rb +64 -0
  17. data/lib/kowl/generators/database_generator.rb +42 -0
  18. data/lib/kowl/generators/decorators_generator.rb +16 -0
  19. data/lib/kowl/generators/docker_generator.rb +40 -0
  20. data/lib/kowl/generators/dotfiles_generator.rb +73 -0
  21. data/lib/kowl/generators/libs_generator.rb +19 -0
  22. data/lib/kowl/generators/mailer_generator.rb +58 -0
  23. data/lib/kowl/generators/misc_generator.rb +20 -0
  24. data/lib/kowl/generators/overrides/app_base.rb +15 -0
  25. data/lib/kowl/generators/overrides/app_builder.rb +58 -0
  26. data/lib/kowl/generators/overrides/app_generator.rb +249 -0
  27. data/lib/kowl/generators/pages_generator.rb +46 -0
  28. data/lib/kowl/generators/routes_generator.rb +20 -0
  29. data/lib/kowl/generators/sidekiq_generator.rb +31 -0
  30. data/lib/kowl/generators/staging_generator.rb +14 -0
  31. data/lib/kowl/generators/test_generator.rb +42 -0
  32. data/lib/kowl/generators/text_files_generator.rb +41 -0
  33. data/lib/kowl/generators/users_and_auth_generator.rb +143 -0
  34. data/lib/kowl/generators/uuid_generator.rb +39 -0
  35. data/lib/kowl/generators/views_and_helpers_generator.rb +104 -0
  36. data/lib/kowl/geodb.rb +96 -0
  37. data/lib/kowl/helpers.rb +139 -0
  38. data/lib/kowl/templates/Gemfile.erb.tt +253 -0
  39. data/lib/kowl/templates/README.md.erb +33 -0
  40. data/lib/kowl/templates/app/assets/javascripts/semantic.js.tt +26 -0
  41. data/lib/kowl/templates/app/assets/stylesheets/administrate/application.scss +44 -0
  42. data/lib/kowl/templates/app/assets/stylesheets/bootstrap/_custom_styling.scss +38 -0
  43. data/lib/kowl/templates/app/assets/stylesheets/bootstrap/application-mailer.scss +1 -0
  44. data/lib/kowl/templates/app/assets/stylesheets/bootstrap/application.scss +14 -0
  45. data/lib/kowl/templates/app/assets/stylesheets/bootstrap/components/_alerts.scss +7 -0
  46. data/lib/kowl/templates/app/assets/stylesheets/bootstrap/components/_errors.scss +28 -0
  47. data/lib/kowl/templates/app/assets/stylesheets/bootstrap/components/_navbar.scss +17 -0
  48. data/lib/kowl/templates/app/assets/stylesheets/bootstrap/variables.scss +6 -0
  49. data/lib/kowl/templates/app/assets/stylesheets/semantic/_custom_styling.scss +20 -0
  50. data/lib/kowl/templates/app/assets/stylesheets/semantic/application.scss +24 -0
  51. data/lib/kowl/templates/app/controllers/admin/application_controller.rb +29 -0
  52. data/lib/kowl/templates/app/controllers/admin/login_activities_controller.rb +29 -0
  53. data/lib/kowl/templates/app/controllers/admin/users_controller.rb +37 -0
  54. data/lib/kowl/templates/app/controllers/concerns/auth/authentication.rb +18 -0
  55. data/lib/kowl/templates/app/controllers/concerns/auth/authorization.rb +20 -0
  56. data/lib/kowl/templates/app/controllers/concerns/auth/error_handlers.rb +27 -0
  57. data/lib/kowl/templates/app/controllers/concerns/noauth/error_handlers.rb +25 -0
  58. data/lib/kowl/templates/app/controllers/users_controller.rb +17 -0
  59. data/lib/kowl/templates/app/dashboards/login_activity_dashboard.rb.tt +59 -0
  60. data/lib/kowl/templates/app/dashboards/rich_text_body_dashboard.rb.tt +17 -0
  61. data/lib/kowl/templates/app/dashboards/user_dashboard.rb.tt +60 -0
  62. data/lib/kowl/templates/app/fields/gravatar_field.rb +10 -0
  63. data/lib/kowl/templates/app/fields/rich_text_area_field.rb +8 -0
  64. data/lib/kowl/templates/app/inputs/rich_text_area_input.rb +11 -0
  65. data/lib/kowl/templates/app/javascript/administrate/components/date_time_picker.js.tt +32 -0
  66. data/lib/kowl/templates/app/javascript/administrate/components/table.js.tt +49 -0
  67. data/lib/kowl/templates/app/javascript/administrate/index.js +3 -0
  68. data/lib/kowl/templates/app/javascript/packs/administrate.js.tt +21 -0
  69. data/lib/kowl/templates/app/javascript/packs/semantic.js +11 -0
  70. data/lib/kowl/templates/app/mailers/application_mailer.rb +7 -0
  71. data/lib/kowl/templates/app/mailers/devise_mailer.rb +5 -0
  72. data/lib/kowl/templates/app/models/login_activity.rb.tt +29 -0
  73. data/lib/kowl/templates/app/models/user.rb.tt +72 -0
  74. data/lib/kowl/templates/app/policies/application_policy.rb +38 -0
  75. data/lib/kowl/templates/app/policies/login_activity_policy.rb +35 -0
  76. data/lib/kowl/templates/app/policies/user_policy.rb +43 -0
  77. data/lib/kowl/templates/app/views/admin/templates/navigation.erb.tt +23 -0
  78. data/lib/kowl/templates/app/views/admin/views/application/_javascript.html.erb +21 -0
  79. data/lib/kowl/templates/app/views/admin/views/users/_collection.html.erb +102 -0
  80. data/lib/kowl/templates/app/views/admin/views/users/_form.html.erb +46 -0
  81. data/lib/kowl/templates/app/views/admin/views/users/edit.html.erb +36 -0
  82. data/lib/kowl/templates/app/views/admin/views/users/index.html.erb +66 -0
  83. data/lib/kowl/templates/app/views/fields/gravatar_field/_form.html.erb +6 -0
  84. data/lib/kowl/templates/app/views/fields/gravatar_field/_index.html.erb +1 -0
  85. data/lib/kowl/templates/app/views/fields/gravatar_field/_show.html.erb +1 -0
  86. data/lib/kowl/templates/app/views/fields/rich_text_area_field/_form.html.erb +6 -0
  87. data/lib/kowl/templates/app/views/fields/rich_text_area_field/_index.html.erb +1 -0
  88. data/lib/kowl/templates/app/views/fields/rich_text_area_field/_show.html.erb +1 -0
  89. data/lib/kowl/templates/app/views/layouts/admin.html.erb.tt +47 -0
  90. data/lib/kowl/templates/app/views/layouts/devise_mailer.html.erb +14 -0
  91. data/lib/kowl/templates/app/views/pages/welcome/bootstrap.html.erb +18 -0
  92. data/lib/kowl/templates/app/views/pages/welcome/bootstrap.html.haml +17 -0
  93. data/lib/kowl/templates/app/views/pages/welcome/bootstrap.html.slim +17 -0
  94. data/lib/kowl/templates/app/views/pages/welcome/default.html.erb +0 -0
  95. data/lib/kowl/templates/app/views/pages/welcome/default.html.haml +0 -0
  96. data/lib/kowl/templates/app/views/pages/welcome/default.html.slim +0 -0
  97. data/lib/kowl/templates/app/views/pages/welcome/semantic.html.erb +20 -0
  98. data/lib/kowl/templates/app/views/pages/welcome/semantic.html.haml +17 -0
  99. data/lib/kowl/templates/app/views/pages/welcome/semantic.html.slim +17 -0
  100. data/lib/kowl/templates/app/views/shared/footer/bootstrap.html.erb.tt +5 -0
  101. data/lib/kowl/templates/app/views/shared/footer/bootstrap.html.haml.tt +3 -0
  102. data/lib/kowl/templates/app/views/shared/footer/bootstrap.html.slim.tt +3 -0
  103. data/lib/kowl/templates/app/views/shared/footer/semantic.html.erb.tt +7 -0
  104. data/lib/kowl/templates/app/views/shared/footer/semantic.html.haml.tt +5 -0
  105. data/lib/kowl/templates/app/views/shared/footer/semantic.html.slim.tt +5 -0
  106. data/lib/kowl/templates/app/views/shared/navigation/bootstrap.html.erb.tt +51 -0
  107. data/lib/kowl/templates/app/views/shared/navigation/bootstrap.html.haml.tt +36 -0
  108. data/lib/kowl/templates/app/views/shared/navigation/bootstrap.html.slim.tt +36 -0
  109. data/lib/kowl/templates/app/views/shared/navigation/semantic.html.erb.tt +48 -0
  110. data/lib/kowl/templates/app/views/shared/navigation/semantic.html.haml.tt +36 -0
  111. data/lib/kowl/templates/app/views/shared/navigation/semantic.html.slim.tt +36 -0
  112. data/lib/kowl/templates/app/workers/scheduler/pghero_scheduler.rb +11 -0
  113. data/lib/kowl/templates/config/autoprefixer.yml +4 -0
  114. data/lib/kowl/templates/config/db/mysql.yml.tt +43 -0
  115. data/lib/kowl/templates/config/db/oracle.yml.tt +29 -0
  116. data/lib/kowl/templates/config/db/postgresql.yml.tt +37 -0
  117. data/lib/kowl/templates/config/db/sqlite3.yml.tt +20 -0
  118. data/lib/kowl/templates/config/db/sqlserver.yml.tt +28 -0
  119. data/lib/kowl/templates/config/initializers/administrate.rb.tt +9 -0
  120. data/lib/kowl/templates/config/initializers/bullet.rb +21 -0
  121. data/lib/kowl/templates/config/initializers/devise-security.rb +44 -0
  122. data/lib/kowl/templates/config/initializers/devise_argon2.rb +29 -0
  123. data/lib/kowl/templates/config/initializers/faker.rb +6 -0
  124. data/lib/kowl/templates/config/initializers/generators.rb.tt +31 -0
  125. data/lib/kowl/templates/config/initializers/geocoder.rb +10 -0
  126. data/lib/kowl/templates/config/initializers/letter_opener.rb +13 -0
  127. data/lib/kowl/templates/config/initializers/lockbox.rb +11 -0
  128. data/lib/kowl/templates/config/initializers/logging.rb +6 -0
  129. data/lib/kowl/templates/config/initializers/lograge.rb +7 -0
  130. data/lib/kowl/templates/config/initializers/logstop.rb +4 -0
  131. data/lib/kowl/templates/config/initializers/middleware.rb +9 -0
  132. data/lib/kowl/templates/config/initializers/oj.rb +7 -0
  133. data/lib/kowl/templates/config/initializers/pagy.rb.tt +16 -0
  134. data/lib/kowl/templates/config/initializers/postmark.rb +8 -0
  135. data/lib/kowl/templates/config/initializers/rack_attack.rb.tt +71 -0
  136. data/lib/kowl/templates/config/initializers/sass.rb +5 -0
  137. data/lib/kowl/templates/config/initializers/sidekiq.rb +11 -0
  138. data/lib/kowl/templates/config/initializers/simpleform/semantic.rb +225 -0
  139. data/lib/kowl/templates/config/initializers/slim.rb +6 -0
  140. data/lib/kowl/templates/config/initializers/sparkpost.rb +13 -0
  141. data/lib/kowl/templates/config/routes.rb.tt +28 -0
  142. data/lib/kowl/templates/config/sidekiq.yml.tt +17 -0
  143. data/lib/kowl/templates/db/migrations/create_action_text_tables.action_text.rb.tt +16 -0
  144. data/lib/kowl/templates/db/migrations/create_active_storage_tables.active_storage.rb.tt +29 -0
  145. data/lib/kowl/templates/db/migrations/devise.rb.tt +59 -0
  146. data/lib/kowl/templates/db/migrations/login_activities.rb.tt +41 -0
  147. data/lib/kowl/templates/db/seeds.rb.tt +14 -0
  148. data/lib/kowl/templates/docker/Dockerfile.alpine.tt +92 -0
  149. data/lib/kowl/templates/docker/Dockerfile.debian.tt +133 -0
  150. data/lib/kowl/templates/docker/docker-compose.yml.tt +55 -0
  151. data/lib/kowl/templates/docker/mysql/Dockerfile.tt +15 -0
  152. data/lib/kowl/templates/dotfiles/Aptfile.tt +34 -0
  153. data/lib/kowl/templates/dotfiles/Brewfile.tt +49 -0
  154. data/lib/kowl/templates/dotfiles/Procfile.tt +12 -0
  155. data/lib/kowl/templates/dotfiles/codeclimate.yml +76 -0
  156. data/lib/kowl/templates/dotfiles/coffeelint.json +10 -0
  157. data/lib/kowl/templates/dotfiles/coffeelintignore +15 -0
  158. data/lib/kowl/templates/dotfiles/dockerignore +23 -0
  159. data/lib/kowl/templates/dotfiles/editorconfig +13 -0
  160. data/lib/kowl/templates/dotfiles/env.tt +58 -0
  161. data/lib/kowl/templates/dotfiles/erb-lint.yml +10 -0
  162. data/lib/kowl/templates/dotfiles/erdconfig.tt +24 -0
  163. data/lib/kowl/templates/dotfiles/eslintignore +20 -0
  164. data/lib/kowl/templates/dotfiles/eslintrc.js +31 -0
  165. data/lib/kowl/templates/dotfiles/fasterer.yml +14 -0
  166. data/lib/kowl/templates/dotfiles/foreman +1 -0
  167. data/lib/kowl/templates/dotfiles/gitattributes +15 -0
  168. data/lib/kowl/templates/dotfiles/gitignore +69 -0
  169. data/lib/kowl/templates/dotfiles/haml-lint.yml +23 -0
  170. data/lib/kowl/templates/dotfiles/jsbeautifyrc +15 -0
  171. data/lib/kowl/templates/dotfiles/jshintrc +3 -0
  172. data/lib/kowl/templates/dotfiles/mailmap +3 -0
  173. data/lib/kowl/templates/dotfiles/nvmrc +1 -0
  174. data/lib/kowl/templates/dotfiles/prettierignore +21 -0
  175. data/lib/kowl/templates/dotfiles/prettierrc.js +62 -0
  176. data/lib/kowl/templates/dotfiles/pryrc +7 -0
  177. data/lib/kowl/templates/dotfiles/rspec +3 -0
  178. data/lib/kowl/templates/dotfiles/rubocop.yml.tt +78 -0
  179. data/lib/kowl/templates/dotfiles/scss-lint.yml +132 -0
  180. data/lib/kowl/templates/dotfiles/simplecov +19 -0
  181. data/lib/kowl/templates/dotfiles/slim-lint.yml +23 -0
  182. data/lib/kowl/templates/dotfiles/slugignore +10 -0
  183. data/lib/kowl/templates/dotfiles/yamllint +7 -0
  184. data/lib/kowl/templates/dotfiles/yarnclean +46 -0
  185. data/lib/kowl/templates/lib/tasks/stats.rake +42 -0
  186. data/lib/kowl/templates/tests/factories/README.md +0 -0
  187. data/lib/kowl/templates/tests/factories/login_activity.rb +11 -0
  188. data/lib/kowl/templates/tests/factories/user.rb +11 -0
  189. data/lib/kowl/templates/tests/minitest/README.md +3 -0
  190. data/lib/kowl/templates/tests/minitest/application_system_test_case.rb +7 -0
  191. data/lib/kowl/templates/tests/minitest/controllers/pages_controller_test.rb +10 -0
  192. data/lib/kowl/templates/tests/minitest/models/login_activity_test.rb +8 -0
  193. data/lib/kowl/templates/tests/minitest/models/user_test.rb +15 -0
  194. data/lib/kowl/templates/tests/minitest/policies/login_activity_policy_test.rb +7 -0
  195. data/lib/kowl/templates/tests/minitest/policies/user_policy_test.rb +7 -0
  196. data/lib/kowl/templates/tests/minitest/support/capybara.rb +38 -0
  197. data/lib/kowl/templates/tests/minitest/support/database_cleaner.rb +20 -0
  198. data/lib/kowl/templates/tests/minitest/support/database_cleaner_support.rb +15 -0
  199. data/lib/kowl/templates/tests/minitest/support/deferred_garbage_collection.rb +21 -0
  200. data/lib/kowl/templates/tests/minitest/support/devise.rb +16 -0
  201. data/lib/kowl/templates/tests/minitest/support/factories.rb +6 -0
  202. data/lib/kowl/templates/tests/minitest/support/formulaic.rb +8 -0
  203. data/lib/kowl/templates/tests/minitest/support/helpers/devise_helper.rb +57 -0
  204. data/lib/kowl/templates/tests/minitest/support/papertrail.rb +17 -0
  205. data/lib/kowl/templates/tests/minitest/support/pundit.rb +0 -0
  206. data/lib/kowl/templates/tests/minitest/support/shoulda.rb +11 -0
  207. data/lib/kowl/templates/tests/minitest/support/simplecov.rb +8 -0
  208. data/lib/kowl/templates/tests/minitest/test_helper.rb +17 -0
  209. data/lib/kowl/templates/tests/rspec/README.md +9 -0
  210. data/lib/kowl/templates/tests/rspec/controllers/admin/application_controller_spec.rb +12 -0
  211. data/lib/kowl/templates/tests/rspec/controllers/admin/users_controller_spec.rb +14 -0
  212. data/lib/kowl/templates/tests/rspec/controllers/pages_controller_spec.rb +10 -0
  213. data/lib/kowl/templates/tests/rspec/features/README.md +15 -0
  214. data/lib/kowl/templates/tests/rspec/features/visitor_sign_up_spec.rb +25 -0
  215. data/lib/kowl/templates/tests/rspec/helpers/application_helper_spec.rb +7 -0
  216. data/lib/kowl/templates/tests/rspec/helpers/pages_helper_spec.rb +15 -0
  217. data/lib/kowl/templates/tests/rspec/models/login_activity_spec.rb +11 -0
  218. data/lib/kowl/templates/tests/rspec/models/user_spec.rb +21 -0
  219. data/lib/kowl/templates/tests/rspec/policies/login_activity_policy_spec.rb +59 -0
  220. data/lib/kowl/templates/tests/rspec/policies/user_policy_spec.rb +56 -0
  221. data/lib/kowl/templates/tests/rspec/rails_helper.rb +72 -0
  222. data/lib/kowl/templates/tests/rspec/requests/pages_spec.rb +11 -0
  223. data/lib/kowl/templates/tests/rspec/spec_helper.rb +96 -0
  224. data/lib/kowl/templates/tests/rspec/support/bullet.rb +17 -0
  225. data/lib/kowl/templates/tests/rspec/support/capybara.rb +37 -0
  226. data/lib/kowl/templates/tests/rspec/support/controller_testing.rb +10 -0
  227. data/lib/kowl/templates/tests/rspec/support/database_cleaner.rb +55 -0
  228. data/lib/kowl/templates/tests/rspec/support/deferred_garbage_collection.rb +32 -0
  229. data/lib/kowl/templates/tests/rspec/support/devise.rb +21 -0
  230. data/lib/kowl/templates/tests/rspec/support/factories.rb +5 -0
  231. data/lib/kowl/templates/tests/rspec/support/formulaic.rb +8 -0
  232. data/lib/kowl/templates/tests/rspec/support/helpers/devise_helpers.rb +56 -0
  233. data/lib/kowl/templates/tests/rspec/support/papertrail.rb +5 -0
  234. data/lib/kowl/templates/tests/rspec/support/pi_ci.rb +6 -0
  235. data/lib/kowl/templates/tests/rspec/support/pundit.rb +6 -0
  236. data/lib/kowl/templates/tests/rspec/support/shoulda.rb +10 -0
  237. data/lib/kowl/templates/tests/rspec/support/sidekiq.rb +10 -0
  238. data/lib/kowl/templates/tests/rspec/support/simplecov.rb +7 -0
  239. data/lib/kowl/templates/tests/rspec/support/warden.rb +8 -0
  240. data/lib/kowl/templates/text_files/AUTHORS.md +4 -0
  241. data/lib/kowl/templates/text_files/CHANGELOG.md.tt +12 -0
  242. data/lib/kowl/templates/text_files/CODE_OF_CONDUCT.md +76 -0
  243. data/lib/kowl/templates/text_files/TODO.md +7 -0
  244. data/lib/kowl/templates/text_files/VERSION +1 -0
  245. data/lib/kowl/templates/text_files/humans.txt.tt +15 -0
  246. data/lib/kowl/templates/text_files/robots.txt.tt +6 -0
  247. data/lib/kowl/templates/text_files/security.txt +6 -0
  248. data/lib/kowl/version.rb +9 -0
  249. data/lib/kowl.rb +18 -0
  250. metadata +404 -0
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ApplicationMailer < ActionMailer::Base
4
+ # The DEFAULT_EMAIL should be set in your .env file
5
+ default from: ENV.fetch('DEFAULT_EMAIL'){ 'noreply@example.com' }
6
+ layout 'mailer'
7
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class DeviseMailer < Devise::Mailer
4
+ layout 'devise_mailer'
5
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ class LoginActivity < ApplicationRecord
4
+ # == Attributes =====================================
5
+ <%- if options[:encrypt] -%>
6
+ encrypts :identity, :ip
7
+ blind_index :identity, :ip
8
+ <%- end -%>
9
+
10
+ # == Constants ======================================
11
+
12
+ # == Extensions =====================================
13
+
14
+ # == Relationships ==================================
15
+ belongs_to :user, polymorphic: true, optional: true
16
+
17
+ # == Validations ====================================
18
+
19
+ # == Scopes =========================================
20
+ # This is used, by default to only show successful logins
21
+ # => This will remove users that are seeded, creates, and/or failed attempts
22
+ default_scope -> { where(user_type: 'User') }
23
+
24
+ # == Callbacks ======================================
25
+
26
+ # == ClassMethods ===================================
27
+
28
+ # == InstanceMethods ================================
29
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ class User < ApplicationRecord
4
+ # == Attributes =====================================
5
+ alias_attribute :avatar, :email
6
+ <%- unless options[:skip_mailer] -%>
7
+ def devise_mailer
8
+ DeviseMailer
9
+ end
10
+ <%- end -%>
11
+ <%- if options[:encrypt] -%>
12
+ # Encrypted user attributes
13
+ encrypts :email
14
+ blind_index :email
15
+ <%- end -%>
16
+
17
+ def self.policy_class
18
+ UserPolicy
19
+ end
20
+
21
+ # == Constants =====================================
22
+ enum role: { superuser: 0, staff: 1, user: 2, visitor: 3 }
23
+ # enum role: { superuser: 'superuser', staff: 'staff', user: 'user', visitor: 'visitor' }
24
+
25
+ # == Extensions ====================================
26
+ # Include default devise modules. Others available are:
27
+ # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
28
+ devise :database_authenticatable, :registerable,
29
+ :recoverable, :rememberable, :secure_validatable,
30
+ :lockable, :timeoutable, :trackable,
31
+ email_validation: false # Since we are using valid_email validator for a stricter email validator
32
+ # https://github.com/micke/valid_email2/issues/121
33
+
34
+ # == Relationships =================================
35
+ <%- if options[:database] == 'sqlserver' -%>
36
+ has_many :login_activities, as: :user, dependent: :delete_all, inverse_of: :user # devise audit log
37
+ <%- else -%>
38
+ has_many :login_activities, -> { order(created_at: :desc) }, as: :user, dependent: :delete_all, inverse_of: :user # devise audit log
39
+ <%- end -%>
40
+
41
+ # == Validations ===================================
42
+ # minimum length of 5 to match: a@a.a
43
+ validates :email, presence: true, 'valid_email_2/email': { disposable: false }, length: { minimum: 5, maximum: 255 }, uniqueness: { case_sensitive: false }, allow_nil: false
44
+ validates :role, presence: true, inclusion: { in: roles.keys }, allow_nil: false
45
+
46
+ # == Scopes ========================================
47
+
48
+ # == Callbacks =====================================
49
+ # Before any validations ensure a default role is set
50
+ before_validation do
51
+ self.role ||= :user
52
+ end
53
+
54
+ # == Class Methods =================================
55
+ def admin?
56
+ role?(:superuser)
57
+ end
58
+
59
+ def staff?
60
+ role?(:staff)
61
+ end
62
+
63
+ def staff_member?
64
+ role?(:superuser) || role?(:staff)
65
+ end
66
+
67
+ def role?(role)
68
+ self.role == role.to_s
69
+ end
70
+
71
+ # == Instance Methods ==============================
72
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ApplicationPolicy
4
+ attr_reader :current_user, :record
5
+
6
+ def initialize(current_user, record)
7
+ raise Pundit::NotAuthorizedError, 'must be logged in' unless current_user
8
+
9
+ @current_user = current_user
10
+ @record = record
11
+ end
12
+
13
+ def admin?
14
+ current_user.admin? if current_user.present?
15
+ end
16
+
17
+ def staff?
18
+ current_user.staff? if current_user.present?
19
+ end
20
+
21
+ # Used to verify if the persons role is set to either superuser or staff
22
+ def staff_member?
23
+ admin? || staff?
24
+ end
25
+
26
+ class Scope
27
+ attr_reader :user, :scope
28
+
29
+ def initialize(user, scope)
30
+ @user = user
31
+ @scope = scope
32
+ end
33
+
34
+ def resolve
35
+ scope.all
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ class LoginActivityPolicy < ApplicationPolicy
4
+ def show?
5
+ # Only display all login activity if the current user is an admin
6
+ # => Otherwise if the user is a staff member, only display login activity for everyone who isn't an admin
7
+ # => If somehow a user hits this page, only allow them to see login activity for themselves
8
+ admin? || (staff? && record.user.role != 'superuser') || (staff_member? && current_user.id == record.user_id)
9
+ end
10
+
11
+ def index?
12
+ admin? || current_user.id == record.user_id
13
+ end
14
+
15
+ # All audit logs should not be modifiable, by any means
16
+ def edit?
17
+ false
18
+ end
19
+
20
+ def new?
21
+ edit?
22
+ end
23
+
24
+ def create?
25
+ edit?
26
+ end
27
+
28
+ def update?
29
+ edit?
30
+ end
31
+
32
+ def destroy?
33
+ edit?
34
+ end
35
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UserPolicy < ApplicationPolicy
4
+ def index?
5
+ admin?
6
+ end
7
+
8
+ # Account should not be create-able, unless someone is explicitly signing up to create an account
9
+ def new?
10
+ false
11
+ end
12
+
13
+ def create?
14
+ false
15
+ end
16
+
17
+ def show?
18
+ # Admins should be able to see all users
19
+ # Staff members should only be able to see people who aren't superusers
20
+ # And everyone should see records for themselves
21
+ admin? || (staff? && record.role != 'superuser') || (staff_member? && current_user.id == record.id)
22
+ end
23
+
24
+ def update?
25
+ # Ensure only superusers can edit other superusers.
26
+ # => This is because we don't want a staff member editing a superuser/manager's account
27
+ # => If the current_user only has the staff as role they can only edit someone who isn't a superuser
28
+ admin? || (staff? && record.role != 'superuser') || (staff_member? && current_user.id == record.id)
29
+ end
30
+
31
+ def edit?
32
+ update?
33
+ end
34
+
35
+ def destroy?
36
+ # This was added because a user shouldn't be able to delete themselves from the admin dashboard
37
+ admin? && current_user.id != record.id
38
+ end
39
+
40
+ def impersonate?
41
+ admin? && current_user.id != record.id
42
+ end
43
+ end
@@ -0,0 +1,23 @@
1
+ <%%#
2
+ # Navigation
3
+
4
+ This partial is used to display the navigation in Administrate.
5
+ By default, the navigation contains navigation links
6
+ for all resources in the admin dashboard,
7
+ as defined by the routes in the `admin/` namespace
8
+ %>
9
+
10
+ <nav class="navigation" role="navigation">
11
+ <%%= link_to "#{icon('fas', 'home')} Homepage".html_safe, root_path, class: 'navigation__link navigation__link--inactive', title: 'Return to homepage' %>
12
+ <%% Administrate::Namespace.new(namespace).resources_with_index_route.each do |resource| %>
13
+ <%%= link_to(
14
+ display_resource_name(resource),
15
+ resource_index_route(resource),
16
+ class: "navigation__link navigation__link--#{nav_link_state(resource)}"
17
+ ) if valid_action? :index, resource %>
18
+ <%% end %>
19
+ <%- unless options[:skip_sidekiq] -%>
20
+ <%%= link_to('Sidekiq', '/sidekiq', class: 'navigation__link navigation__link--inactive') if current_user.admin? %>
21
+ <%- end -%>
22
+ <%%= link_to('LetterOpener'.html_safe, '/letter_opener', class: 'navigation__link navigation__link--inactive') if Rails.env.development? && current_user.admin? %>
23
+ </nav>
@@ -0,0 +1,21 @@
1
+ <%#
2
+ # Javascript Partial
3
+ https://github.com/thoughtbot/administrate/wiki/Rails-6-&-Webpacker
4
+
5
+ This partial imports the necessary javascript on each page.
6
+ By default, it includes the application JS,
7
+ but each page can define additional JS sources
8
+ by providing a `content_for(:javascript)` block.
9
+
10
+ Administrate::Engine.javascripts.each do |js_path|
11
+ <= echo javascript_include_tag js_path
12
+ <% end
13
+ %>
14
+
15
+ <%= yield :javascript %>
16
+ <% if Rails.env.test? %>
17
+ <%= javascript_tag do %>
18
+ $.fx.off = true;
19
+ $.ajaxSetup({ async: false });
20
+ <% end %>
21
+ <% end %>
@@ -0,0 +1,102 @@
1
+ <%#
2
+ # Collection
3
+
4
+ This partial is used on the `index` and `show` pages
5
+ to display a collection of resources in an HTML table.
6
+
7
+ ## Local variables:
8
+
9
+ - `collection_presenter`:
10
+ An instance of [Administrate::Page::Collection][1].
11
+ The table presenter uses `ResourceDashboard::COLLECTION_ATTRIBUTES` to determine
12
+ the columns displayed in the table
13
+ - `resources`:
14
+ An ActiveModel::Relation collection of resources to be displayed in the table.
15
+ By default, the number of resources is limited by pagination
16
+ or by a hard limit to prevent excessive page load times
17
+
18
+ [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Collection
19
+ %>
20
+ <table aria-labelledby="<%= table_title %>">
21
+ <thead>
22
+ <tr>
23
+ <td>&nbsp;</td>
24
+ <% collection_presenter.attribute_types.each do |attr_name, attr_type| %>
25
+ <th class="cell-label
26
+ cell-label--<%= attr_type.html_class %>
27
+ cell-label--<%= collection_presenter.ordered_html_class(attr_name) %>"
28
+ scope="col"
29
+ role="columnheader"
30
+ aria-sort="<%= sort_order(collection_presenter.ordered_html_class(attr_name)) %>">
31
+ <%= link_to(sanitized_order_params(page, collection_field_name).merge(
32
+ collection_presenter.order_params_for(attr_name, key: collection_field_name)
33
+ )) do %>
34
+ <%= t(
35
+ "helpers.label.#{collection_presenter.resource_name}.#{attr_name}",
36
+ default: attr_name.to_s,
37
+ ).titleize %>
38
+ <% if collection_presenter.ordered_by?(attr_name) %>
39
+ <span class="cell-label__sort-indicator cell-label__sort-indicator--<%= collection_presenter.ordered_html_class(attr_name) %>">
40
+ <svg aria-hidden="true">
41
+ <use xlink:href="#icon-up-caret" />
42
+ </svg>
43
+ </span>
44
+ <% end %>
45
+ <% end %>
46
+ </th>
47
+ <% end %>
48
+ <% [valid_action?(:edit, collection_presenter.resource_name),
49
+ valid_action?(:destroy, collection_presenter.resource_name)].count(true).times do %>
50
+ <th scope="col"></th>
51
+ <% end %>
52
+ </tr>
53
+ </thead>
54
+
55
+ <tbody>
56
+ <% resources.each do |resource| %>
57
+ <%- if show_action? :show, resource %>
58
+ <tr class="js-table-row"
59
+ tabindex="0"
60
+ <% if valid_action? :show, collection_presenter.resource_name %>
61
+ <%= %(role=link data-url=#{polymorphic_path([namespace, resource])}) %>
62
+ <% end %>
63
+ >
64
+ <td>
65
+ <%- if resource.class.to_s == "User" && policy(resource).impersonate? %>
66
+ <%= link_to (raw icon('fas','theater-masks')), impersonate_user_path(resource.id) %>
67
+ <% end %>
68
+ </td>
69
+ <% collection_presenter.attributes_for(resource).each do |attribute| %>
70
+ <td class="cell-data cell-data--<%= attribute.html_class %>">
71
+ <% if show_action? :show, resource -%>
72
+ <a href="<%= polymorphic_path([namespace, resource]) -%>"
73
+ class="action-show"
74
+ >
75
+ <%= render_field attribute %>
76
+ </a>
77
+ <% end -%>
78
+ </td>
79
+ <% end %>
80
+
81
+ <% if valid_action? :edit, collection_presenter.resource_name %>
82
+ <td><%= link_to(
83
+ t("administrate.actions.edit"),
84
+ [:edit, namespace, resource],
85
+ class: "action-edit",
86
+ ) if show_action? :edit, resource%></td>
87
+ <% end %>
88
+
89
+ <% if valid_action? :destroy, collection_presenter.resource_name %>
90
+ <td><%= link_to(
91
+ t("administrate.actions.destroy"),
92
+ [namespace, resource],
93
+ class: "text-color-red",
94
+ method: :delete,
95
+ data: { confirm: t("administrate.actions.confirm") }
96
+ ) if show_action? :destroy, resource %></td>
97
+ <% end %>
98
+ </tr>
99
+ <% end %>
100
+ <% end %>
101
+ </tbody>
102
+ </table>
@@ -0,0 +1,46 @@
1
+ <%#
2
+ # Form Partial
3
+
4
+ This partial is rendered on a resource's `new` and `edit` pages,
5
+ and renders all form fields for a resource's editable attributes.
6
+
7
+ ## Local variables:
8
+
9
+ - `page`:
10
+ An instance of [Administrate::Page::Form][1].
11
+ Contains helper methods to display a form,
12
+ and knows which attributes should be displayed in the resource's form.
13
+
14
+ [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Form
15
+ %>
16
+
17
+ <%= form_for([namespace, page.resource], html: { class: "form" }) do |f| %>
18
+ <% if page.resource.errors.any? %>
19
+ <div id="error_explanation">
20
+ <h2>
21
+ <%= t(
22
+ "administrate.form.errors",
23
+ pluralized_errors: pluralize(page.resource.errors.count, t("administrate.form.error")),
24
+ resource_name: display_resource_name(page.resource_name)
25
+ ) %>
26
+ </h2>
27
+
28
+ <ul>
29
+ <% page.resource.errors.full_messages.each do |message| %>
30
+ <li class="flash-error"><%= message %></li>
31
+ <% end %>
32
+ </ul>
33
+ </div>
34
+ <% end %>
35
+
36
+ <% page.attributes.each do |attribute| -%>
37
+ <% next if attribute.attribute == :role && !current_user.admin? %>
38
+ <div class="field-unit field-unit--<%= attribute.html_class %>">
39
+ <%= render_field attribute, f: f %>
40
+ </div>
41
+ <% end -%>
42
+
43
+ <div class="form-actions">
44
+ <%= f.submit %>
45
+ </div>
46
+ <% end %>
@@ -0,0 +1,36 @@
1
+ <%#
2
+ # Edit
3
+
4
+ This view is the template for the edit page.
5
+
6
+ It displays a header, and renders the `_form` partial to do the heavy lifting.
7
+
8
+ ## Local variables:
9
+
10
+ - `page`:
11
+ An instance of [Administrate::Page::Form][1].
12
+ Contains helper methods to help display a form,
13
+ and knows which attributes should be displayed in the resource's form.
14
+
15
+ [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Form
16
+ %>
17
+
18
+ <% content_for(:title) { t("administrate.actions.edit_resource", name: page.page_title) } %>
19
+
20
+ <header class="main-content__header" role="banner">
21
+ <h1 class="main-content__page-title">
22
+ <%= content_for(:title) %>
23
+ </h1>
24
+
25
+ <div>
26
+ <%= link_to(
27
+ t("administrate.actions.show_resource", name: page.page_title),
28
+ [namespace, page.resource],
29
+ class: "button",
30
+ ) if valid_action?(:show) && show_action?(:show, page.resource) %>
31
+ </div>
32
+ </header>
33
+
34
+ <section class="main-content__body">
35
+ <%= render "form", page: page %>
36
+ </section>
@@ -0,0 +1,66 @@
1
+ <%#
2
+ # Index
3
+
4
+ This view is the template for the index page.
5
+ It is responsible for rendering the search bar, header and pagination.
6
+ It renders the `_table` partial to display details about the resources.
7
+
8
+ ## Local variables:
9
+
10
+ - `page`:
11
+ An instance of [Administrate::Page::Collection][1].
12
+ Contains helper methods to help display a table,
13
+ and knows which attributes should be displayed in the resource's table.
14
+ - `resources`:
15
+ An instance of `ActiveRecord::Relation` containing the resources
16
+ that match the user's search criteria.
17
+ By default, these resources are passed to the table partial to be displayed.
18
+ - `search_term`:
19
+ A string containing the term the user has searched for, if any.
20
+ - `show_search_bar`:
21
+ A boolean that determines if the search bar should be shown.
22
+
23
+ [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Collection
24
+ %>
25
+
26
+ <% content_for(:title) do %>
27
+ <%= display_resource_name(page.resource_name) %>
28
+ <% end %>
29
+
30
+ <header class="main-content__header" role="banner">
31
+ <h1 class="main-content__page-title" id="page-title">
32
+ <%= content_for(:title) %>
33
+ </h1>
34
+
35
+ <% if show_search_bar %>
36
+ <%= render(
37
+ "search",
38
+ search_term: search_term,
39
+ resource_name: display_resource_name(page.resource_name)
40
+ ) %>
41
+ <% end %>
42
+
43
+ <div>
44
+ <%= link_to(
45
+ t(
46
+ "administrate.actions.new_resource",
47
+ name: page.resource_name.titleize.downcase
48
+ ),
49
+ [:new, namespace, page.resource_path],
50
+ class: "button",
51
+ ) if valid_action?(:new) && show_action?(:new, new_resource) %>
52
+ </div>
53
+ </header>
54
+
55
+ <section class="main-content__body main-content__body--flush">
56
+ <%= render(
57
+ "collection",
58
+ collection_presenter: page,
59
+ collection_field_name: resource_name,
60
+ page: page,
61
+ resources: resources,
62
+ table_title: "page-title"
63
+ ) %>
64
+
65
+ <%= paginate resources %>
66
+ </section>
@@ -0,0 +1,6 @@
1
+ <div class="field-unit__label">
2
+ <%= f.label field.attribute %>
3
+ </div>
4
+ <div class="field-unit__field">
5
+ <%= f.text_field field.attribute %>
6
+ </div>
@@ -0,0 +1 @@
1
+ <%= image_tag field.gravatar_url %>
@@ -0,0 +1 @@
1
+ <%= image_tag field.gravatar_url %>
@@ -0,0 +1,6 @@
1
+ <div class="field-unit__label">
2
+ <%= f.label field.attribute %>
3
+ </div>
4
+ <div class="field-unit__field">
5
+ <%= f.rich_text_area(field.attribute) %>
6
+ </div>
@@ -0,0 +1,47 @@
1
+ <%#
2
+ # Application Layout
3
+
4
+ This view template is used as the layout
5
+ for every page that Administrate generates.
6
+
7
+ By default, it renders:
8
+ - Navigation
9
+ - Content for a search bar
10
+ (if provided by a `content_for` block in a nested page)
11
+ - Flashes
12
+ - Links to stylesheets and JavaScripts
13
+ %>
14
+
15
+ <!DOCTYPE html>
16
+ <html lang="<%%= I18n.locale %>">
17
+ <head>
18
+ <meta charset="utf-8">
19
+ <meta name="robots" content="noodp, noydir, index, follow">
20
+ <meta name="viewport" content="initial-scale=1">
21
+ <%%- set_meta_tags title: (content_for(:title) || 'Dashboard') %>
22
+ <%%= display_meta_tags site: '<%= app_name.titleize %>' %>
23
+ <%- unless options[:skip_javascript] -%>
24
+ <%%= javascript_pack_tag 'administrate'<%= options[:skip_turbolinks] ? '' : ", 'data-turbolinks-track': 'reload'" -%> %>
25
+ <%- end -%>
26
+ <%%= render "stylesheet" %>
27
+ <%%= csrf_meta_tags %>
28
+ <%- unless options[:skip_turbolinks] || options[:skip_javascript] -%>
29
+ <meta name="turbolinks-root" content="/admin">
30
+ <%- end -%>
31
+ </head>
32
+ <body>
33
+ <div class="app-container">
34
+ <%%= render "navigation" -%>
35
+ <main class="main-content" role="main">
36
+ <%%= render "flashes" -%>
37
+ <%%= yield %>
38
+ </main>
39
+ </div>
40
+ <div style="display: none; width: 0; height: 0; overflow: hidden; position: absolute">
41
+ <%%= render "icons" %>
42
+ </div>
43
+ <%- unless options[:skip_javascript] -%>
44
+ <%%= render "javascript" %>
45
+ <%- end -%>
46
+ </body>
47
+ </html>
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5
+ <%= stylesheet_link_tag "application-mailer", media: "all" %>
6
+ </head>
7
+ <body class="bg-light">
8
+ <div class="container-fluid">
9
+ <div class="card card-body my-3">
10
+ <%= yield %>
11
+ </div>
12
+ </div>
13
+ </body>
14
+ </html>
@@ -0,0 +1,18 @@
1
+ <h2><%= title('Welcome') %></h2>
2
+ <p class="lead">
3
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
4
+ Mauris maximus vulputate gravida.
5
+ Integer eget mauris at orci molestie porta.
6
+ </p>
7
+ <p>
8
+ In scelerisque leo vitae lacus commodo, eu tincidunt nisi suscipit.
9
+ Pellentesque at sapien duiDuis sit amet arcu non ante sodales varius.
10
+ Fusce nibh nulla, mollis a dolor eu, iaculis pharetra lectus.
11
+ Sed turpis quam, imperdiet ut faucibus sit amet, efficitur ut nulla.
12
+ Duis non accumsan lacus.
13
+ Vestibulum nec diam quis dui convallis rhoncus quis sit amet massa.
14
+ Maecenas ac est purus. Aliquam erat volutpat.
15
+ Vestibulum tempus pharetra viverra.
16
+ Etiam vestibulum et elit in vulputate.
17
+ Quisque eget elementum purus, id volutpat augue.
18
+ </p>
@@ -0,0 +1,17 @@
1
+ %h2 = title('Welcome')
2
+ %p.lead
3
+ | Lorem ipsum dolor sit amet, consectetur adipiscing elit.
4
+ | Mauris maximus vulputate gravida.
5
+ | Integer eget mauris at orci molestie porta.
6
+
7
+ %p
8
+ | In scelerisque leo vitae lacus commodo, eu tincidunt nisi suscipit.
9
+ | Pellentesque at sapien duiDuis sit amet arcu non ante sodales varius.
10
+ | Fusce nibh nulla, mollis a dolor eu, iaculis pharetra lectus.
11
+ | Sed turpis quam, imperdiet ut faucibus sit amet, efficitur ut nulla.
12
+ | Duis non accumsan lacus.
13
+ | Vestibulum nec diam quis dui convallis rhoncus quis sit amet massa.
14
+ | Maecenas ac est purus. Aliquam erat volutpat.
15
+ | Vestibulum tempus pharetra viverra.
16
+ | Etiam vestibulum et elit in vulputate.
17
+ | Quisque eget elementum purus, id volutpat augue.