ditty 0.7.1 → 0.10.1

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.
Files changed (185) hide show
  1. checksums.yaml +4 -4
  2. data/.env.test +2 -0
  3. data/.gitignore +3 -0
  4. data/.pryrc +2 -0
  5. data/.rubocop.yml +24 -8
  6. data/.travis.yml +4 -8
  7. data/CNAME +1 -0
  8. data/Dockerfile +18 -0
  9. data/Gemfile.ci +0 -15
  10. data/Rakefile +5 -4
  11. data/Readme.md +24 -2
  12. data/_config.yml +1 -0
  13. data/config.ru +4 -4
  14. data/ditty.gemspec +31 -20
  15. data/docs/CNAME +1 -0
  16. data/docs/_config.yml +1 -0
  17. data/docs/index.md +34 -0
  18. data/exe/ditty +2 -0
  19. data/lib/ditty.rb +30 -4
  20. data/lib/ditty/cli.rb +38 -5
  21. data/lib/ditty/components/ditty.rb +82 -0
  22. data/lib/ditty/controllers/application_controller.rb +267 -0
  23. data/lib/ditty/controllers/{audit_logs.rb → audit_logs_controller.rb} +5 -7
  24. data/lib/ditty/controllers/{auth.rb → auth_controller.rb} +56 -32
  25. data/lib/ditty/controllers/{component.rb → component_controller.rb} +35 -24
  26. data/lib/ditty/controllers/{main.rb → main_controller.rb} +7 -7
  27. data/lib/ditty/controllers/roles_controller.rb +23 -0
  28. data/lib/ditty/controllers/user_login_traits_controller.rb +46 -0
  29. data/lib/ditty/controllers/{users.rb → users_controller.rb} +17 -20
  30. data/lib/ditty/db.rb +9 -5
  31. data/lib/ditty/emails/base.rb +48 -34
  32. data/lib/ditty/generators/crud_generator.rb +114 -0
  33. data/lib/ditty/generators/migration_generator.rb +26 -0
  34. data/lib/ditty/generators/project_generator.rb +52 -0
  35. data/lib/ditty/helpers/authentication.rb +6 -5
  36. data/lib/ditty/helpers/component.rb +11 -2
  37. data/lib/ditty/helpers/pundit.rb +24 -8
  38. data/lib/ditty/helpers/response.rb +38 -15
  39. data/lib/ditty/helpers/views.rb +48 -6
  40. data/lib/ditty/listener.rb +44 -14
  41. data/lib/ditty/memcached.rb +8 -0
  42. data/lib/ditty/middleware/accept_extension.rb +4 -2
  43. data/lib/ditty/middleware/error_catchall.rb +4 -2
  44. data/lib/ditty/models/audit_log.rb +1 -0
  45. data/lib/ditty/models/base.rb +13 -0
  46. data/lib/ditty/models/identity.rb +10 -7
  47. data/lib/ditty/models/role.rb +2 -0
  48. data/lib/ditty/models/user.rb +40 -3
  49. data/lib/ditty/models/user_login_trait.rb +17 -0
  50. data/lib/ditty/policies/audit_log_policy.rb +6 -6
  51. data/lib/ditty/policies/role_policy.rb +3 -3
  52. data/lib/ditty/policies/user_login_trait_policy.rb +45 -0
  53. data/lib/ditty/policies/user_policy.rb +3 -3
  54. data/lib/ditty/rubocop.rb +3 -0
  55. data/lib/ditty/seed.rb +2 -0
  56. data/lib/ditty/services/authentication.rb +31 -15
  57. data/lib/ditty/services/email.rb +22 -12
  58. data/lib/ditty/services/logger.rb +30 -13
  59. data/lib/ditty/services/pagination_wrapper.rb +9 -5
  60. data/lib/ditty/services/settings.rb +19 -7
  61. data/lib/ditty/tasks/ditty.rake +127 -0
  62. data/lib/ditty/tasks/omniauth-ldap.rake +43 -0
  63. data/lib/ditty/templates/.gitignore +5 -0
  64. data/lib/ditty/templates/.rspec +2 -0
  65. data/lib/ditty/templates/.rubocop.yml +7 -0
  66. data/lib/ditty/templates/Rakefile +12 -0
  67. data/lib/ditty/templates/application.rb +12 -0
  68. data/lib/ditty/templates/config.ru +37 -0
  69. data/lib/ditty/templates/controller.rb.erb +64 -0
  70. data/lib/ditty/templates/env.example +4 -0
  71. data/lib/ditty/templates/lib/project.rb.erb +5 -0
  72. data/lib/ditty/templates/migration.rb.erb +7 -0
  73. data/lib/ditty/templates/model.rb.erb +26 -0
  74. data/lib/ditty/templates/pids/.empty_directory +0 -0
  75. data/lib/ditty/templates/policy.rb.erb +48 -0
  76. data/{public → lib/ditty/templates/public}/browserconfig.xml +0 -0
  77. data/lib/ditty/templates/public/css/sb-admin-2.min.css +10 -0
  78. data/lib/ditty/templates/public/css/styles.css +13 -0
  79. data/lib/ditty/templates/public/favicon.ico +0 -0
  80. data/{public → lib/ditty/templates/public}/images/apple-icon.png +0 -0
  81. data/{public → lib/ditty/templates/public}/images/favicon-16x16.png +0 -0
  82. data/{public → lib/ditty/templates/public}/images/favicon-32x32.png +0 -0
  83. data/{public → lib/ditty/templates/public}/images/launcher-icon-1x.png +0 -0
  84. data/{public → lib/ditty/templates/public}/images/launcher-icon-2x.png +0 -0
  85. data/{public → lib/ditty/templates/public}/images/launcher-icon-4x.png +0 -0
  86. data/{public → lib/ditty/templates/public}/images/mstile-150x150.png +0 -0
  87. data/{public → lib/ditty/templates/public}/images/safari-pinned-tab.svg +0 -0
  88. data/lib/ditty/templates/public/js/sb-admin-2.min.js +7 -0
  89. data/lib/ditty/templates/public/js/scripts.js +1 -0
  90. data/{public/manifest.json → lib/ditty/templates/public/manifest.json.erb} +2 -2
  91. data/lib/ditty/templates/settings.yml.erb +19 -0
  92. data/lib/ditty/templates/sidekiq.rb +18 -0
  93. data/lib/ditty/templates/sidekiq.yml +9 -0
  94. data/lib/ditty/templates/spec_helper.rb +43 -0
  95. data/lib/ditty/templates/type.rb.erb +21 -0
  96. data/lib/ditty/templates/views/display.haml.tt +20 -0
  97. data/lib/ditty/templates/views/edit.haml.tt +10 -0
  98. data/lib/ditty/templates/views/form.haml.tt +11 -0
  99. data/lib/ditty/templates/views/index.haml.tt +29 -0
  100. data/lib/ditty/templates/views/new.haml.tt +10 -0
  101. data/lib/ditty/version.rb +1 -1
  102. data/lib/rubocop/cop/ditty/call_services_directly.rb +42 -0
  103. data/migrate/20181209_add_user_login_traits.rb +16 -0
  104. data/migrate/20181209_extend_audit_log.rb +12 -0
  105. data/migrate/20190220_add_parent_id_to_roles.rb +9 -0
  106. data/spec/ditty/api_spec.rb +51 -0
  107. data/spec/ditty/controllers/roles_spec.rb +67 -0
  108. data/spec/ditty/controllers/user_login_traits_spec.rb +72 -0
  109. data/spec/ditty/controllers/users_spec.rb +72 -0
  110. data/spec/ditty/emails/base_spec.rb +76 -0
  111. data/spec/ditty/emails/forgot_password_spec.rb +20 -0
  112. data/spec/ditty/helpers/component_spec.rb +85 -0
  113. data/spec/ditty/models/user_spec.rb +36 -0
  114. data/spec/ditty/services/email_spec.rb +36 -0
  115. data/spec/ditty/services/logger_spec.rb +68 -0
  116. data/spec/ditty/services/settings_spec.rb +63 -0
  117. data/spec/ditty_spec.rb +9 -0
  118. data/spec/factories.rb +46 -0
  119. data/spec/fixtures/logger.yml +17 -0
  120. data/spec/fixtures/section.yml +3 -0
  121. data/spec/fixtures/settings.yml +8 -0
  122. data/spec/spec_helper.rb +51 -0
  123. data/spec/support/api_shared_examples.rb +250 -0
  124. data/spec/support/crud_shared_examples.rb +145 -0
  125. data/views/403.haml +2 -0
  126. data/views/404.haml +2 -4
  127. data/views/500.haml +11 -0
  128. data/views/audit_logs/index.haml +32 -28
  129. data/views/auth/forgot_password.haml +32 -16
  130. data/views/auth/identity.haml +14 -13
  131. data/views/auth/ldap.haml +17 -0
  132. data/views/auth/login.haml +23 -17
  133. data/views/auth/register.haml +20 -18
  134. data/views/auth/register_identity.haml +27 -12
  135. data/views/auth/reset_password.haml +36 -19
  136. data/views/blank.haml +43 -0
  137. data/views/emails/forgot_password.haml +1 -1
  138. data/views/emails/layouts/action.haml +10 -6
  139. data/views/emails/layouts/alert.haml +2 -1
  140. data/views/emails/layouts/billing.haml +2 -1
  141. data/views/embedded.haml +17 -11
  142. data/views/error.haml +8 -3
  143. data/views/index.haml +1 -1
  144. data/views/layout.haml +45 -30
  145. data/views/partials/actions.haml +15 -14
  146. data/views/partials/content_tag.haml +0 -0
  147. data/views/partials/delete_form.haml +1 -1
  148. data/views/partials/filter_control.haml +2 -2
  149. data/views/partials/footer.haml +13 -5
  150. data/views/partials/form_control.haml +30 -19
  151. data/views/partials/form_tag.haml +1 -1
  152. data/views/partials/navitems.haml +42 -0
  153. data/views/partials/notifications.haml +12 -8
  154. data/views/partials/pager.haml +44 -25
  155. data/views/partials/search.haml +15 -11
  156. data/views/partials/sidebar.haml +15 -37
  157. data/views/partials/sort_ui.haml +2 -0
  158. data/views/partials/timespan_selector.haml +64 -0
  159. data/views/partials/topbar.haml +53 -0
  160. data/views/partials/user_associations.haml +32 -0
  161. data/views/quick_start.haml +23 -0
  162. data/views/roles/display.haml +27 -6
  163. data/views/roles/edit.haml +3 -3
  164. data/views/roles/form.haml +1 -0
  165. data/views/roles/index.haml +23 -14
  166. data/views/roles/new.haml +2 -2
  167. data/views/user_login_traits/display.haml +32 -0
  168. data/views/user_login_traits/edit.haml +10 -0
  169. data/views/user_login_traits/form.haml +5 -0
  170. data/views/user_login_traits/index.haml +28 -0
  171. data/views/user_login_traits/new.haml +10 -0
  172. data/views/users/display.haml +15 -16
  173. data/views/users/edit.haml +3 -3
  174. data/views/users/form.haml +0 -0
  175. data/views/users/index.haml +31 -24
  176. data/views/users/login_traits.haml +25 -0
  177. data/views/users/new.haml +2 -2
  178. data/views/users/profile.haml +17 -15
  179. data/views/users/user.haml +1 -1
  180. metadata +314 -76
  181. data/lib/ditty/components/app.rb +0 -77
  182. data/lib/ditty/controllers/application.rb +0 -175
  183. data/lib/ditty/controllers/roles.rb +0 -16
  184. data/lib/ditty/rake_tasks.rb +0 -102
  185. data/views/partials/navbar.haml +0 -23
@@ -1,23 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'ditty/controllers/component'
3
+ require 'ditty/controllers/component_controller'
4
4
  require 'ditty/models/user'
5
+ require 'ditty/models/user_login_trait'
5
6
  require 'ditty/policies/user_policy'
6
7
  require 'ditty/models/identity'
7
8
  require 'ditty/policies/identity_policy'
8
9
 
9
10
  module Ditty
10
- class Users < Ditty::Component
11
+ class UsersController < ::Ditty::ComponentController
11
12
  SEARCHABLE = %i[name surname email].freeze
12
13
 
13
14
  set model_class: User
14
15
  set track_actions: true
15
16
 
16
- def find_template(views, name, engine, &block)
17
- super(views, name, engine, &block) # Root
18
- super(::Ditty::App.view_folder, name, engine, &block) # Ditty
19
- end
20
-
21
17
  # New
22
18
  get '/new' do
23
19
  authorize settings.model_class, :create
@@ -32,8 +28,8 @@ module Ditty
32
28
 
33
29
  locals = { title: heading(:new) }
34
30
 
35
- user_params = permitted_attributes(User, :create)
36
- identity_params = permitted_attributes(Identity, :create)
31
+ user_params = permitted_parameters(User, :create)
32
+ identity_params = permitted_parameters(Identity, :create)
37
33
  user_params['email'] = identity_params['username']
38
34
  roles = user_params.delete('role_id')
39
35
 
@@ -42,25 +38,24 @@ module Ditty
42
38
 
43
39
  DB.transaction(isolation: :serializable) do
44
40
  begin
45
- identity.save
41
+ identity.save_changes
46
42
  rescue Sequel::ValidationFailed
47
43
  raise unless request.accept? 'text/html'
44
+
48
45
  status 400
49
46
  locals = { title: heading(:new), entity: user, identity: identity }
50
47
  return haml(:"#{view_location}/new", locals: locals)
51
48
  end
52
- user.save
49
+ user.save_changes
53
50
  user.add_identity identity
54
51
 
55
- if roles
56
- roles.each do |role_id|
57
- user.add_role(role_id) unless user.roles.map(&:id).include? role_id.to_i
58
- end
52
+ roles&.each do |role_id|
53
+ user.add_role(role_id) unless user.roles.map(&:id).include? role_id.to_i
59
54
  end
60
55
  user.check_roles
61
56
  end
62
57
 
63
- broadcast(:component_create, target: self)
58
+ broadcast(:component_create, target: self, entity: user)
64
59
  create_response(user)
65
60
  end
66
61
 
@@ -70,10 +65,10 @@ module Ditty
70
65
  halt 404 unless entity
71
66
  authorize entity, :update
72
67
 
73
- values = permitted_attributes(settings.model_class, :update)
68
+ values = permitted_parameters(settings.model_class, :update)
74
69
  roles = values.delete('role_id')
75
70
  entity.set values
76
- entity.save # Will trigger a Sequel::ValidationFailed exception if the model is incorrect
71
+ entity.save_changes # Will trigger a Sequel::ValidationFailed exception if the model is incorrect
77
72
 
78
73
  if roles
79
74
  entity.remove_all_roles
@@ -99,9 +94,10 @@ module Ditty
99
94
  return redirect back
100
95
  end
101
96
 
102
- values = permitted_attributes(Identity, :create)
97
+ values = permitted_parameters(Identity, :create)
103
98
  identity.set values
104
- if identity.valid? && identity.save
99
+ if identity.valid?
100
+ identity.save_changes
105
101
  broadcast(:identity_update_password, target: self)
106
102
  flash[:success] = 'Password Updated'
107
103
  redirect back
@@ -134,6 +130,7 @@ module Ditty
134
130
  halt 404 unless entity
135
131
  authorize entity, :read
136
132
 
133
+ flash[:redirect_to] = request.path
137
134
  haml :"#{view_location}/profile", locals: { entity: entity, identity: entity.identity.first, title: 'My Account' }
138
135
  end
139
136
  end
data/lib/ditty/db.rb CHANGED
@@ -8,7 +8,7 @@ require 'active_support/core_ext/object/blank'
8
8
  pool_timeout = (ENV['DB_POOL_TIMEOUT'] || 5).to_i
9
9
 
10
10
  if defined? DB
11
- Ditty::Services::Logger.instance.warn 'Database connection already set up'
11
+ ::Ditty::Services::Logger.warn 'Database connection already set up'
12
12
  elsif ENV['DATABASE_URL'].blank? == false
13
13
  # Delete DATABASE_URL from the environment, so it isn't accidently
14
14
  # passed to subprocesses. DATABASE_URL may contain passwords.
@@ -18,12 +18,16 @@ elsif ENV['DATABASE_URL'].blank? == false
18
18
  )
19
19
 
20
20
  DB.sql_log_level = (ENV['SEQUEL_LOGGING_LEVEL'] || :debug).to_sym
21
- DB.loggers << Ditty::Services::Logger.instance
21
+ DB.loggers << ::Ditty::Services::Logger if ENV['DB_DEBUG'].to_i == 1
22
22
  DB.extension(:pagination)
23
+ DB.extension(:schema_caching)
24
+ DB.load_schema_cache?('./config/schema.dump')
23
25
 
24
- Sequel::Model.plugin :validation_helpers
25
- Sequel::Model.plugin :update_or_create
26
+ Sequel::Model.plugin :auto_validations
27
+ Sequel::Model.plugin :string_stripper
26
28
  Sequel::Model.plugin :timestamps, update_on_create: true
29
+ Sequel::Model.plugin :update_or_create
30
+ Sequel::Model.plugin :validation_helpers
27
31
  else
28
- Ditty::Services::Logger.instance.error 'No database connection set up'
32
+ ::Ditty::Services::Logger.error 'No database connection set up'
29
33
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'haml'
2
- require 'ditty/components/app'
4
+ require 'ditty/components/ditty'
3
5
 
4
6
  module Ditty
5
7
  module Emails
@@ -15,60 +17,72 @@ module Ditty
15
17
  def deliver!(to = nil, locals = {})
16
18
  options[:to] = to unless to.nil?
17
19
  @locals.merge!(locals)
18
- %i[to from subject].each do |param|
19
- mail.send(param, options[param]) if options[param]
20
+ %i[to from subject content_type].each do |param|
21
+ next unless options[param]
22
+
23
+ @locals[param] ||= options[param]
24
+ mail.send(param, options[param])
25
+ end
26
+ html = content
27
+ mail.html_part do
28
+ body html
20
29
  end
21
- mail.body content
22
30
  mail.deliver!
23
31
  end
24
32
 
25
33
  def method_missing(method, *args, &block)
26
34
  return super unless respond_to_missing?(method)
35
+
27
36
  mail.send(method, *args, &block)
28
37
  end
29
38
 
30
39
  def respond_to_missing?(method, _include_private = false)
31
- mail.respond_to? method
40
+ return true if mail.respond_to?(method)
41
+
42
+ super
32
43
  end
33
44
 
34
45
  private
35
46
 
36
- def content
37
- result = Haml::Engine.new(content_haml).render(Object.new, locals)
38
- return result unless options[:layout]
39
- Haml::Engine.new(layout_haml).render(Object.new, content: result)
40
- end
47
+ def content
48
+ result = Haml::Engine.new(content_haml).render(Object.new, locals)
49
+ return result unless options[:layout]
41
50
 
42
- def content_haml
43
- read_template(options[:view])
44
- end
51
+ Haml::Engine.new(layout_haml).render(Object.new, locals.merge(content: result))
52
+ end
45
53
 
46
- def layout_haml
47
- read_template("layouts/#{options[:layout]}") if options[:layout]
48
- end
54
+ def content_haml
55
+ read_template(options[:view])
56
+ end
49
57
 
50
- def read_template(template)
51
- File.read(find_template("emails/#{template}"))
52
- end
58
+ def layout_haml
59
+ read_template("layouts/#{options[:layout]}") if options[:layout]
60
+ end
53
61
 
54
- def base_options
55
- { subject: '(No Subject)', from: 'no-reply@ditty.io', view: :base }
56
- end
62
+ def read_template(template)
63
+ File.read(find_template("emails/#{template}"))
64
+ end
57
65
 
58
- def find_template(file)
59
- template = File.expand_path("./views/#{file}.haml")
60
- return template if File.file? template
61
- template = File.expand_path("./#{file}.haml", App.view_folder)
62
- return template if File.file? template
63
- file
64
- end
66
+ def base_options
67
+ { subject: '(No Subject)', from: 'no-reply@ditty.io', view: :base, content_type: 'text/html; charset=UTF-8' }
68
+ end
65
69
 
66
- class << self
67
- def deliver!(to = nil, options = {})
68
- locals = options[:locals] || {}
69
- new(options).deliver!(to, locals)
70
+ def find_template(file)
71
+ template = File.expand_path("./views/#{file}.haml")
72
+ return template if File.file? template
73
+
74
+ template = File.expand_path("./#{file}.haml", App.view_folder)
75
+ return template if File.file? template
76
+
77
+ file
78
+ end
79
+
80
+ class << self
81
+ def deliver!(to = nil, options = {})
82
+ locals = options[:locals] || {}
83
+ new(options).deliver!(to, locals)
84
+ end
70
85
  end
71
- end
72
86
  end
73
87
  end
74
88
  end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thor/group'
4
+ require 'active_support/inflector'
5
+
6
+ module Ditty
7
+ module Generators
8
+ class CrudGenerator < Thor::Group
9
+ include Thor::Actions
10
+ attr_reader :namespace, :folder, :views_folder, :controller_name, :model_name, :policy_name # , :file_name
11
+
12
+ desc 'Create a CRUD Endpoint including the Model, Controller, Policy, Views and GraphQL Types'
13
+ argument :name, type: :string, desc: 'Name of the Model, eg. MyApp::User'
14
+
15
+ # --no-views make views optional
16
+ class_option :views, type: :boolean, default: true, desc: 'Generate views for controller'
17
+
18
+ def self.source_root
19
+ File.dirname(__FILE__)
20
+ end
21
+
22
+ def setup
23
+ @namespace = name.deconstantize
24
+ @folder = namespace.underscore
25
+ @model_name = name.demodulize
26
+ @views_folder = File.join('views', model_name.pluralize.underscore)
27
+ @controller_name = "#{model_name.pluralize}Controller"
28
+ @policy_name = "#{model_name}Policy"
29
+ end
30
+
31
+ def create_model
32
+ filename = File.join("lib/#{folder}/models", "#{model_name.underscore}.rb")
33
+ template '../templates/model.rb.erb', filename
34
+ rescue StandardError => e
35
+ puts "Could not generate model for #{model_name}: #{e.message}"
36
+ end
37
+
38
+ def create_controller
39
+ filename = File.join("lib/#{folder}/controllers", "#{controller_name.underscore}.rb")
40
+ template '../templates/controller.rb.erb', filename
41
+ # TODO: Insert the route into the component file
42
+ # insert_into_file 'config.ru', "use #{class_name}\n", after: 'run ApplicationController\n'
43
+ rescue StandardError => e
44
+ puts "Could not generate controller for #{model_name}: #{e.message}"
45
+ end
46
+
47
+ def create_policy
48
+ filename = File.join("lib/#{folder}/policies", "#{policy_name.underscore}.rb")
49
+ template '../templates/policy.rb.erb', filename
50
+ rescue StandardError => e
51
+ puts "Could not generate policy for #{model_name}: #{e.message}"
52
+ end
53
+
54
+ def create_type
55
+ filename = File.join("lib/#{folder}/types", "#{model_name.underscore}_type.rb")
56
+ template '../templates/type.rb.erb', filename
57
+ rescue StandardError => e
58
+ puts "Could not generate type for #{model_name}: #{e.message}"
59
+ end
60
+
61
+ def create_views
62
+ return unless options[:views]
63
+
64
+ directory '../templates/views', views_folder
65
+ end
66
+
67
+ private
68
+
69
+ def meta_columns
70
+ %i[id guid slug created_at updated_at]
71
+ end
72
+
73
+ def columns
74
+ require "#{folder}/models/#{model_name.underscore}"
75
+ name.constantize.columns
76
+ rescue StandardError
77
+ []
78
+ end
79
+
80
+ def schema
81
+ require "#{folder}/models/#{model_name.underscore}"
82
+ name.constantize.db_schema
83
+ rescue StandardError
84
+ []
85
+ end
86
+
87
+ def many_to_ones
88
+ DB.foreign_key_list(model_name.underscore.pluralize)
89
+ end
90
+
91
+ def name_column(table)
92
+ candidates = DB.schema(table.to_sym).to_h.keys - DB.foreign_key_list(table.to_sym).map do |e|
93
+ e[:columns]
94
+ end.flatten
95
+ (candidates - meta_columns).first
96
+ end
97
+
98
+ def graphql_types
99
+ @graphql_types ||= Hash.new('String').merge(
100
+ integer: 'Integer',
101
+ boolean: 'Boolean',
102
+ datetime: 'GraphQL::Types::ISO8601DateTime'
103
+ )
104
+ end
105
+
106
+ def input_types
107
+ @input_types ||= Hash.new('text').merge(
108
+ integer: 'number',
109
+ datetime: 'date'
110
+ )
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thor/group'
4
+ require 'active_support/inflector'
5
+
6
+ module Ditty
7
+ module Generators
8
+ class MigrationGenerator < Thor::Group
9
+ include Thor::Actions
10
+
11
+ attr_reader :namespace, :folder
12
+
13
+ desc 'Creates a new Sequel migration for the current project'
14
+ argument :name, type: :string, desc: 'Name of the migration'
15
+
16
+ def self.source_root
17
+ File.expand_path('../templates', __dir__)
18
+ end
19
+
20
+ def create_model
21
+ filename = File.join('migrations', "#{Time.now.strftime('%Y%m%d')}_#{name.underscore}.rb")
22
+ template '../templates/migration.rb.erb', filename
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thor/group'
4
+ require 'active_support/inflector'
5
+
6
+ module Ditty
7
+ module Generators
8
+ class ProjectGenerator < Thor::Group
9
+ include Thor::Actions
10
+
11
+ attr_reader :name, :namespace, :folder
12
+
13
+ desc 'Initialize a new Ditty project in the current folder'
14
+
15
+ def setup
16
+ @name = File.basename(Dir.getwd)
17
+ @folder = @name.underscore
18
+ @namespace = folder.classify
19
+ @name = @name.titleize
20
+ end
21
+
22
+ def self.source_root
23
+ File.expand_path('../templates', __dir__)
24
+ end
25
+
26
+ def create_startup_files
27
+ directory 'logs'
28
+ directory 'pids'
29
+ directory 'public'
30
+ directory '../../../views', 'views'
31
+ copy_file '.gitignore', './.gitignore'
32
+ copy_file 'env.example', './.env'
33
+ copy_file '.rubocop.yml', './.rubocop.yml'
34
+ copy_file '.rspec', './.rspec'
35
+
36
+ template 'lib/project.rb.erb', "lib/#{folder}.rb"
37
+
38
+ copy_file 'application.rb', './application.rb'
39
+ copy_file 'config.ru', './config.ru'
40
+ copy_file 'Rakefile', './Rakefile'
41
+ copy_file 'sidekiq.rb', './config/sidekiq.rb'
42
+ copy_file 'sidekiq.yml', './config/sidekiq.yml'
43
+
44
+ copy_file 'spec_helper.rb', './specs/spec_helper.rb'
45
+ copy_file '../../../spec/support/api_shared_examples.rb', './specs/support/api_shared_examples.rb'
46
+ copy_file '../../../spec/support/crud_shared_examples.rb', './specs/support/crud_shared_examples.rb'
47
+
48
+ template 'settings.yml.erb', './config/settings.yml'
49
+ end
50
+ end
51
+ end
52
+ end
@@ -1,14 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'ditty/models/user'
4
- require 'ditty/models/role'
5
- require 'ditty/models/identity'
6
4
 
7
5
  module Ditty
8
6
  module Helpers
9
7
  module Authentication
10
8
  def current_user
11
9
  return nil if current_user_id.nil?
10
+
12
11
  @current_user ||= User[current_user_id]
13
12
  end
14
13
 
@@ -19,8 +18,9 @@ module Ditty
19
18
  end
20
19
 
21
20
  def current_user_id
22
- return env['rack.session']['user_id'] if env['rack.session']
23
- env['omniauth.auth'].uid if env['omniauth.auth']
21
+ return env['rack.session']['user_id'] if env['rack.session'] && env['rack.session']['user_id']
22
+
23
+ env['omniauth.auth']&.uid
24
24
  end
25
25
 
26
26
  def authenticate
@@ -33,11 +33,12 @@ module Ditty
33
33
 
34
34
  def authenticate!
35
35
  raise NotAuthenticated unless authenticated?
36
+
36
37
  true
37
38
  end
38
39
 
39
40
  def logout
40
- env['rack.session'].delete('user_id') unless env['rack.session'].nil?
41
+ env['rack.session']&.delete('user_id')
41
42
  env.delete('omniauth.auth')
42
43
  end
43
44
  end