ditty 0.8.0 → 0.10.2

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 (169) 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 +23 -4
  6. data/.travis.yml +4 -8
  7. data/CNAME +1 -0
  8. data/Dockerfile +18 -0
  9. data/Gemfile.ci +0 -17
  10. data/Rakefile +2 -2
  11. data/_config.yml +1 -0
  12. data/config.ru +4 -4
  13. data/ditty.gemspec +28 -18
  14. data/docs/CNAME +1 -0
  15. data/docs/_config.yml +1 -0
  16. data/docs/index.md +34 -0
  17. data/exe/ditty +2 -0
  18. data/lib/ditty/cli.rb +41 -5
  19. data/lib/ditty/components/{app.rb → ditty.rb} +18 -16
  20. data/lib/ditty/controllers/{application.rb → application_controller.rb} +63 -34
  21. data/lib/ditty/controllers/{audit_logs.rb → audit_logs_controller.rb} +4 -2
  22. data/lib/ditty/controllers/{auth.rb → auth_controller.rb} +22 -18
  23. data/lib/ditty/controllers/{component.rb → component_controller.rb} +23 -20
  24. data/lib/ditty/controllers/{main.rb → main_controller.rb} +6 -2
  25. data/lib/ditty/controllers/roles_controller.rb +23 -0
  26. data/lib/ditty/controllers/user_login_traits_controller.rb +46 -0
  27. data/lib/ditty/controllers/{users.rb → users_controller.rb} +13 -11
  28. data/lib/ditty/db.rb +7 -5
  29. data/lib/ditty/emails/base.rb +37 -32
  30. data/lib/ditty/generators/crud_generator.rb +114 -0
  31. data/lib/ditty/generators/migration_generator.rb +26 -0
  32. data/lib/ditty/generators/project_generator.rb +52 -0
  33. data/lib/ditty/helpers/component.rb +2 -1
  34. data/lib/ditty/helpers/pundit.rb +24 -8
  35. data/lib/ditty/helpers/response.rb +15 -13
  36. data/lib/ditty/helpers/views.rb +28 -6
  37. data/lib/ditty/listener.rb +6 -4
  38. data/lib/ditty/memcached.rb +8 -0
  39. data/lib/ditty/middleware/accept_extension.rb +2 -2
  40. data/lib/ditty/middleware/error_catchall.rb +2 -2
  41. data/lib/ditty/models/base.rb +9 -0
  42. data/lib/ditty/models/identity.rb +11 -7
  43. data/lib/ditty/models/role.rb +1 -0
  44. data/lib/ditty/models/user.rb +23 -2
  45. data/lib/ditty/policies/role_policy.rb +1 -1
  46. data/lib/ditty/policies/user_login_trait_policy.rb +1 -1
  47. data/lib/ditty/policies/user_policy.rb +1 -1
  48. data/lib/ditty/services/authentication.rb +27 -16
  49. data/lib/ditty/services/email.rb +19 -15
  50. data/lib/ditty/services/logger.rb +26 -20
  51. data/lib/ditty/services/pagination_wrapper.rb +7 -5
  52. data/lib/ditty/services/settings.rb +7 -6
  53. data/lib/ditty/tasks/ditty.rake +19 -1
  54. data/lib/ditty/tasks/omniauth-ldap.rake +2 -2
  55. data/lib/ditty/templates/.gitignore +5 -0
  56. data/lib/ditty/templates/.rspec +2 -0
  57. data/lib/ditty/templates/.rubocop.yml +7 -0
  58. data/lib/ditty/templates/Rakefile +12 -0
  59. data/lib/ditty/templates/application.rb +12 -0
  60. data/lib/ditty/templates/config.ru +37 -0
  61. data/lib/ditty/templates/controller.rb.erb +64 -0
  62. data/lib/ditty/templates/env.example +4 -0
  63. data/lib/ditty/templates/lib/project.rb.erb +5 -0
  64. data/lib/ditty/templates/logs/.empty_directory +0 -0
  65. data/lib/ditty/templates/migration.rb.erb +7 -0
  66. data/lib/ditty/templates/model.rb.erb +26 -0
  67. data/lib/ditty/templates/pids/.empty_directory +0 -0
  68. data/lib/ditty/templates/policy.rb.erb +48 -0
  69. data/{public → lib/ditty/templates/public}/browserconfig.xml +0 -0
  70. data/lib/ditty/templates/public/css/sb-admin-2.min.css +10 -0
  71. data/lib/ditty/templates/public/css/styles.css +13 -0
  72. data/lib/ditty/templates/public/favicon.ico +0 -0
  73. data/{public → lib/ditty/templates/public}/images/apple-icon.png +0 -0
  74. data/{public → lib/ditty/templates/public}/images/favicon-16x16.png +0 -0
  75. data/{public → lib/ditty/templates/public}/images/favicon-32x32.png +0 -0
  76. data/{public → lib/ditty/templates/public}/images/launcher-icon-1x.png +0 -0
  77. data/{public → lib/ditty/templates/public}/images/launcher-icon-2x.png +0 -0
  78. data/{public → lib/ditty/templates/public}/images/launcher-icon-4x.png +0 -0
  79. data/{public → lib/ditty/templates/public}/images/mstile-150x150.png +0 -0
  80. data/{public → lib/ditty/templates/public}/images/safari-pinned-tab.svg +0 -0
  81. data/lib/ditty/templates/public/js/sb-admin-2.min.js +7 -0
  82. data/lib/ditty/templates/public/js/scripts.js +1 -0
  83. data/{public/manifest.json → lib/ditty/templates/public/manifest.json.erb} +2 -2
  84. data/lib/ditty/templates/settings.yml.erb +29 -0
  85. data/lib/ditty/templates/sidekiq.rb +18 -0
  86. data/lib/ditty/templates/sidekiq.yml +9 -0
  87. data/lib/ditty/templates/spec_helper.rb +43 -0
  88. data/lib/ditty/templates/type.rb.erb +21 -0
  89. data/lib/ditty/templates/views/display.haml.tt +20 -0
  90. data/lib/ditty/templates/views/edit.haml.tt +10 -0
  91. data/lib/ditty/templates/views/form.haml.tt +11 -0
  92. data/lib/ditty/templates/views/index.haml.tt +29 -0
  93. data/lib/ditty/templates/views/new.haml.tt +10 -0
  94. data/lib/ditty/version.rb +1 -1
  95. data/lib/ditty.rb +6 -4
  96. data/lib/rubocop/cop/ditty/call_services_directly.rb +2 -2
  97. data/migrate/20181209_add_user_login_traits.rb +4 -4
  98. data/migrate/20190220_add_parent_id_to_roles.rb +9 -0
  99. data/spec/ditty/api_spec.rb +51 -0
  100. data/spec/ditty/controllers/roles_spec.rb +67 -0
  101. data/spec/ditty/controllers/user_login_traits_spec.rb +72 -0
  102. data/spec/ditty/controllers/users_spec.rb +72 -0
  103. data/spec/ditty/emails/base_spec.rb +76 -0
  104. data/spec/ditty/emails/forgot_password_spec.rb +20 -0
  105. data/spec/ditty/helpers/component_spec.rb +85 -0
  106. data/spec/ditty/models/user_spec.rb +36 -0
  107. data/spec/ditty/services/email_spec.rb +36 -0
  108. data/spec/ditty/services/logger_spec.rb +68 -0
  109. data/spec/ditty/services/settings_spec.rb +63 -0
  110. data/spec/ditty_spec.rb +9 -0
  111. data/spec/factories.rb +46 -0
  112. data/spec/fixtures/logger.yml +17 -0
  113. data/spec/fixtures/section.yml +3 -0
  114. data/spec/fixtures/settings.yml +8 -0
  115. data/spec/spec_helper.rb +51 -0
  116. data/spec/support/api_shared_examples.rb +250 -0
  117. data/spec/support/crud_shared_examples.rb +145 -0
  118. data/views/403.haml +1 -1
  119. data/views/404.haml +2 -4
  120. data/views/500.haml +11 -0
  121. data/views/audit_logs/index.haml +32 -33
  122. data/views/auth/forgot_password.haml +32 -16
  123. data/views/auth/identity.haml +14 -13
  124. data/views/auth/ldap.haml +2 -2
  125. data/views/auth/login.haml +23 -17
  126. data/views/auth/register.haml +20 -18
  127. data/views/auth/register_identity.haml +27 -12
  128. data/views/auth/reset_password.haml +36 -19
  129. data/views/blank.haml +43 -0
  130. data/views/embedded.haml +17 -11
  131. data/views/index.haml +1 -1
  132. data/views/layout.haml +45 -30
  133. data/views/partials/actions.haml +15 -14
  134. data/views/partials/content_tag.haml +0 -0
  135. data/views/partials/delete_form.haml +1 -1
  136. data/views/partials/filter_control.haml +2 -2
  137. data/views/partials/footer.haml +6 -5
  138. data/views/partials/form_control.haml +19 -12
  139. data/views/partials/form_tag.haml +1 -1
  140. data/views/partials/navitems.haml +42 -0
  141. data/views/partials/notifications.haml +12 -8
  142. data/views/partials/pager.haml +44 -25
  143. data/views/partials/search.haml +15 -11
  144. data/views/partials/sidebar.haml +15 -37
  145. data/views/partials/sort_ui.haml +2 -0
  146. data/views/partials/topbar.haml +53 -0
  147. data/views/partials/user_associations.haml +32 -0
  148. data/views/quick_start.haml +23 -0
  149. data/views/roles/display.haml +27 -6
  150. data/views/roles/edit.haml +3 -3
  151. data/views/roles/form.haml +1 -0
  152. data/views/roles/index.haml +23 -16
  153. data/views/roles/new.haml +2 -2
  154. data/views/user_login_traits/display.haml +4 -4
  155. data/views/user_login_traits/edit.haml +3 -3
  156. data/views/user_login_traits/index.haml +23 -25
  157. data/views/user_login_traits/new.haml +2 -2
  158. data/views/users/display.haml +14 -15
  159. data/views/users/edit.haml +3 -3
  160. data/views/users/form.haml +0 -0
  161. data/views/users/index.haml +31 -24
  162. data/views/users/login_traits.haml +6 -8
  163. data/views/users/new.haml +2 -2
  164. data/views/users/profile.haml +15 -15
  165. data/views/users/user.haml +1 -1
  166. metadata +271 -63
  167. data/lib/ditty/controllers/roles.rb +0 -13
  168. data/lib/ditty/controllers/user_login_traits.rb +0 -18
  169. data/views/partials/navbar.haml +0 -22
@@ -17,13 +17,14 @@ require 'rack/contrib'
17
17
  require 'rack/csrf'
18
18
 
19
19
  module Ditty
20
- class Application < Sinatra::Base
20
+ class ApplicationController < Sinatra::Base
21
21
  include ActiveSupport::Inflector
22
22
 
23
- set :root, ENV['APP_ROOT'] || ::File.expand_path(::File.dirname(__FILE__) + '/../../../')
23
+ set :root, ENV['APP_ROOT'] || ::File.expand_path("#{::File.dirname(__FILE__)}/../../../")
24
24
  set :map_path, nil
25
25
  set :view_location, nil
26
26
  set :view_folder, nil
27
+ set :base_path, nil
27
28
  set :model_class, nil
28
29
  set :raise_sinatra_param_exceptions, true
29
30
  set track_actions: false
@@ -35,14 +36,13 @@ module Ditty
35
36
 
36
37
  register Sinatra::Flash, Sinatra::RespondWith
37
38
 
38
- use Rack::Csrf, raise: ENV['APP_ENV'] == 'development' unless ENV['APP_ENV'] == 'test'
39
- use Rack::PostBodyContentTypeParser
39
+ use Rack::JSONBodyParser
40
40
  use Rack::MethodOverride
41
41
  use Rack::NestedParams
42
42
 
43
43
  helpers do
44
44
  def logger
45
- Ditty::Services::Logger.instance
45
+ ::Ditty::Services::Logger
46
46
  end
47
47
 
48
48
  def base_path
@@ -51,9 +51,9 @@ module Ditty
51
51
 
52
52
  def view_location
53
53
  return settings.view_location if settings.view_location
54
- return underscore(pluralize(demodulize(settings.model_class))) if settings.model_class
55
54
 
56
- underscore(demodulize(self.class))
55
+ loc = demodulize(settings.model_class || self.class)
56
+ pluralize(underscore(loc.gsub(/Controller\Z/, '')))
57
57
  end
58
58
 
59
59
  def browser
@@ -61,24 +61,26 @@ module Ditty
61
61
  end
62
62
 
63
63
  def config(name, default = '')
64
- Ditty::Services::Settings[name] || default
64
+ ::Ditty::Services::Settings[name] || default
65
65
  end
66
66
  end
67
67
 
68
68
  def view_folders
69
69
  folders = ['./views']
70
70
  folders << settings.view_folder if settings.view_folder
71
- folders << Ditty::App.view_folder
71
+ folders << ::Ditty::Ditty.view_folder
72
72
  end
73
73
 
74
74
  def find_template(views, name, engine, &block)
75
75
  # Backwards compatability
76
- return super(views, name, engine, &block) if settings.view_folder.nil? && self.class.name.split('::').first != 'Ditty'
76
+ if settings.view_folder.nil? && self.class.name.split('::').first != 'Ditty'
77
+ return super(views, name, engine, &block)
78
+ end
77
79
 
78
80
  view_folders.each do |folder|
79
81
  super(folder, name, engine, &block) # Root
80
82
  end
81
- raise Ditty::TemplateNotFoundError, "Could not find template `#{name}`"
83
+ raise ::Ditty::TemplateNotFoundError, "Could not find template `#{name}`"
82
84
  end
83
85
 
84
86
  configure :production do
@@ -92,7 +94,7 @@ module Ditty
92
94
 
93
95
  configure :production, :development do
94
96
  disable :logging
95
- use Rack::CommonLogger, Ditty::Services::Logger.instance
97
+ use Rack::CommonLogger, ::Ditty::Services::Logger
96
98
  end
97
99
 
98
100
  not_found do
@@ -102,7 +104,11 @@ module Ditty
102
104
  haml :'404', locals: { title: '4 oh 4' }, layout: layout
103
105
  end
104
106
  format.json do
105
- json code: 404, errors: ['Not Found']
107
+ if response.body.empty?
108
+ json code: 404, errors: ['Not Found']
109
+ else
110
+ [404, response.body]
111
+ end
106
112
  end
107
113
  end
108
114
  end
@@ -134,30 +140,47 @@ module Ditty
134
140
  end
135
141
  end
136
142
 
137
- error Sequel::ValidationFailed do
143
+ error ::Sinatra::Param::InvalidParameterError do
138
144
  respond_to do |format|
139
- entity = env['sinatra.error'].model
140
- errors = env['sinatra.error'].errors
141
145
  status 400
142
146
  format.html do
143
- action = entity.id ? :edit : :new
144
- haml :"#{view_location}/#{action}", locals: { entity: entity, title: heading(action) }, layout: layout
147
+ flash.now[:danger] = env['sinatra.error'].message
148
+ haml :'400', locals: { title: '4 oh oh' }, layout: layout
145
149
  end
146
150
  format.json do
147
- json code: 400, errors: errors, full_errors: errors.full_messages
151
+ json code: 400, errors: { env['sinatra.error'].param => env['sinatra.error'].message },
152
+ full_errors: [env['sinatra.error'].message]
153
+ end
154
+ end
155
+ end
156
+
157
+ error ::Sequel::NoMatchingRow do
158
+ respond_to do |format|
159
+ status 404
160
+ format.html do
161
+ haml :'404', locals: { title: '4 oh 4' }, layout: layout
162
+ end
163
+ format.json do
164
+ if response.body.empty?
165
+ json code: 404, errors: ['Not Found']
166
+ else
167
+ [404, response.body]
168
+ end
148
169
  end
149
170
  end
150
171
  end
151
172
 
152
- error Sinatra::Param::InvalidParameterError do
173
+ error ::Sequel::ValidationFailed do
153
174
  respond_to do |format|
175
+ entity = env['sinatra.error'].model
176
+ errors = env['sinatra.error'].errors
154
177
  status 400
155
178
  format.html do
156
- flash.now[:danger] = env['sinatra.error'].message
157
- haml :'400', locals: { title: '4 oh oh' }, layout: layout
179
+ action = entity.id ? :edit : :new
180
+ haml :"#{view_location}/#{action}", locals: { entity: entity, title: heading(action) }, layout: layout
158
181
  end
159
182
  format.json do
160
- json code: 400, errors: { env['sinatra.error'].param => env['sinatra.error'].message }, full_errors: [env['sinatra.error'].message]
183
+ json code: 400, errors: errors, full_errors: errors.full_messages
161
184
  end
162
185
  end
163
186
  end
@@ -177,7 +200,7 @@ module Ditty
177
200
  end
178
201
  end
179
202
 
180
- error Ditty::TemplateNotFoundError do
203
+ error ::Ditty::TemplateNotFoundError do
181
204
  # TODO: Display a better error message
182
205
  error = env['sinatra.error']
183
206
  broadcast(:application_error, error)
@@ -207,30 +230,36 @@ module Ditty
207
230
 
208
231
  before(/.*/) do
209
232
  logger.info "Running with #{self.class} - #{request.path_info}"
210
- if request.path =~ /.*\.json\Z/
233
+ if /.*\.json\Z/.match?(request.path)
211
234
  content_type :json
212
235
  request.path_info = request.path_info.gsub(/.json$/, '')
213
- elsif request.path =~ /.*\.csv\Z/
236
+ elsif /.*\.csv\Z/.match?(request.path)
214
237
  content_type :csv
215
238
  request.path_info = request.path_info.gsub(/.csv$/, '')
216
239
  elsif request.env['ACCEPT']
217
240
  content_type request.env['ACCEPT']
218
- else
219
- content_type(:json) if request.accept.count.eql?(1) && request.accept.first.to_s.eql?('*/*')
241
+ elsif request.accept.count.eql?(1) && request.accept.first.to_s.eql?('*/*')
242
+ content_type(:json)
220
243
  end
221
244
  end
222
245
 
223
246
  after do
224
247
  return if params[:layout].nil?
248
+ return unless response.body.respond_to?(:map)
225
249
 
226
- response.body = response.body.map do |resp|
227
- document = Oga.parse_html(resp)
228
- document.css('a').each do |elm|
229
- unless (href = elm.get('href')).nil?
230
- elm.set 'href', with_layout(href)
250
+ begin
251
+ orig = response.body
252
+ response.body = response.body.map do |resp|
253
+ document = Oga.parse_html(resp)
254
+ document.css('a').each do |elm|
255
+ unless (href = elm.get('href')).nil?
256
+ elm.set 'href', with_layout(href)
257
+ end
231
258
  end
259
+ document.to_xml
232
260
  end
233
- document.to_xml
261
+ rescue StandardError => _e
262
+ orig
234
263
  end
235
264
  end
236
265
  end
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'ditty/controllers/component'
3
+ require 'ditty/controllers/component_controller'
4
4
  require 'ditty/models/audit_log'
5
5
  require 'ditty/policies/audit_log_policy'
6
6
 
7
7
  module Ditty
8
- class AuditLogs < Ditty::Component
8
+ class AuditLogsController < ::Ditty::ComponentController
9
9
  set model_class: AuditLog
10
10
 
11
11
  SEARCHABLE = %i[details platform device browser ip_address].freeze
@@ -25,6 +25,8 @@ module Ditty
25
25
  end
26
26
 
27
27
  def list
28
+ return super if params[:sort]
29
+
28
30
  super.order(:created_at).reverse
29
31
  end
30
32
 
@@ -1,16 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'ditty/controllers/application'
3
+ require 'ditty/controllers/application_controller'
4
4
  require 'ditty/services/email'
5
5
  require 'securerandom'
6
6
 
7
7
  module Ditty
8
- class Auth < Application
8
+ class AuthController < ApplicationController
9
9
  set track_actions: true
10
10
 
11
11
  def redirect_path
12
12
  return "#{settings.map_path}/" if omniauth_redirect_path.nil?
13
- return "#{settings.map_path}/" if omniauth_redirect_path =~ %r{/#{settings.map_path}/auth/?}
13
+ return "#{settings.map_path}/" if omniauth_redirect_path.match? %r{/#{settings.map_path}/auth/?}
14
14
 
15
15
  omniauth_redirect_path
16
16
  end
@@ -24,7 +24,7 @@ module Ditty
24
24
 
25
25
  broadcast("before_#{provider}_login".to_sym, env['omniauth.auth'])
26
26
  user = User.first(email: env['omniauth.auth']['info']['email'])
27
- user = register_user if user.nil? && authorize(current_user, :register?)
27
+ user = register_user if user.nil? && authorize(::Ditty::User, :register?)
28
28
  return failed_login if user.nil?
29
29
 
30
30
  broadcast("#{provider}_login".to_sym, user)
@@ -67,7 +67,7 @@ module Ditty
67
67
  authorize ::Ditty::Identity, :login
68
68
  redirect settings.map_path if authenticated?
69
69
 
70
- haml :'auth/login', locals: { title: 'Log In' }
70
+ haml :'auth/login', locals: { title: 'Log In' }, layout: :blank
71
71
  end
72
72
 
73
73
  # Custom login form for LDAP to allow CSRF checks. Set the `request_path` for
@@ -76,13 +76,13 @@ module Ditty
76
76
  authorize ::Ditty::Identity, :login
77
77
  redirect settings.map_path if authenticated?
78
78
 
79
- haml :'auth/ldap', locals: { title: 'Company Log In' }
79
+ haml :'auth/ldap', locals: { title: 'Company Log In' }, layout: :blank
80
80
  end
81
81
 
82
82
  get '/forgot-password' do
83
83
  authorize ::Ditty::Identity, :forgot_password
84
84
 
85
- haml :'auth/forgot_password', locals: { title: 'Forgot your password?' }
85
+ haml :'auth/forgot_password', locals: { title: 'Forgot your password?' }, layout: :blank
86
86
  end
87
87
 
88
88
  post '/forgot-password' do
@@ -96,15 +96,18 @@ module Ditty
96
96
  token = SecureRandom.hex(16)
97
97
  identity.update(reset_token: token, reset_requested: Time.now)
98
98
  # Send Email
99
- reset_url = "#{request.base_url}#{settings.map_path}/reset-password?token=#{token}"
100
- Ditty::Services::Email.deliver(
99
+ reset_url = "#{request.base_url}#{settings.map_path}/auth/reset-password?token=#{token}"
100
+ ::Ditty::Services::Email.deliver(
101
101
  :forgot_password,
102
102
  email,
103
103
  locals: { identity: identity, reset_url: reset_url, request: request }
104
104
  )
105
105
  end
106
106
  flash[:info] = 'An email was sent to the email provided with instructions on how to reset your password'
107
- redirect '/login'
107
+ redirect "#{settings.map_path}/auth/login"
108
+ rescue Sinatra::Param::InvalidParameterError
109
+ flash[:warning] = 'Email address not provided'
110
+ redirect back
108
111
  end
109
112
 
110
113
  get '/reset-password' do
@@ -114,7 +117,7 @@ module Ditty
114
117
  identity = Identity[reset_token: params[:token]]
115
118
  halt 404 unless identity&.reset_requested && identity.reset_requested > (Time.now - (24 * 60 * 60))
116
119
 
117
- haml :'auth/reset_password', locals: { title: 'Reset your password', identity: identity }
120
+ haml :'auth/reset_password', locals: { title: 'Reset your password', identity: identity }, layout: :blank
118
121
  end
119
122
 
120
123
  put '/reset-password' do
@@ -124,15 +127,15 @@ module Ditty
124
127
  halt 404 unless identity
125
128
  authorize identity, :reset_password
126
129
 
127
- identity_params = permitted_attributes(Identity, :update)
130
+ identity_params = permitted_parameters(Identity, :update)
128
131
  identity.set identity_params.merge(reset_token: nil, reset_requested: nil)
129
- if identity.valid? && identity.save
132
+ if identity.valid? && identity.save_changes
130
133
  broadcast(:identity_update_password, target: self)
131
134
  flash[:success] = 'Password Updated'
132
135
  redirect "#{settings.map_path}/auth/login"
133
136
  else
134
137
  broadcast(:identity_update_password_failed, target: self)
135
- haml :'auth/reset_password', locals: { title: 'Reset your password', identity: identity }
138
+ haml :'auth/reset_password', locals: { title: 'Reset your password', identity: identity }, layout: :blank
136
139
  end
137
140
  end
138
141
 
@@ -141,7 +144,7 @@ module Ditty
141
144
  authorize ::Ditty::User.new, :register
142
145
 
143
146
  identity = Identity.new
144
- haml :'auth/register', locals: { title: 'Register', identity: identity }
147
+ haml :'auth/register', locals: { title: 'Register', identity: identity }, layout: :blank
145
148
  end
146
149
 
147
150
  # Register Action
@@ -152,8 +155,9 @@ module Ditty
152
155
  authorize user, :register
153
156
 
154
157
  begin
158
+ identity.valid?
155
159
  DB.transaction do
156
- user.save
160
+ user.save_changes
157
161
  user.add_identity identity
158
162
  broadcast(:user_register, target: self, values: { user: user })
159
163
  flash[:info] = 'Successfully Registered. Please log in'
@@ -161,7 +165,7 @@ module Ditty
161
165
  end
162
166
  rescue Sequel::ValidationFailed
163
167
  flash.now[:warning] = 'Could not complete the registration. Please try again.'
164
- haml :'auth/register', locals: { identity: identity }
168
+ haml :'auth/register', locals: { identity: identity }, layout: :blank
165
169
  end
166
170
  end
167
171
 
@@ -172,7 +176,7 @@ module Ditty
172
176
 
173
177
  halt 200 if request.xhr?
174
178
  flash[:info] = 'Logged Out'
175
- redirect(Ditty::Services::Settings[:logout_redirect_path] || "#{settings.map_path}/")
179
+ redirect(::Ditty::Services::Settings[:logout_redirect_path] || "#{settings.map_path}/")
176
180
  end
177
181
 
178
182
  # Unauthenticated
@@ -1,12 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'ditty/controllers/application'
3
+ require 'ditty/controllers/application_controller'
4
4
  require 'ditty/helpers/component'
5
5
  require 'ditty/helpers/response'
6
6
  require 'sinatra/json'
7
7
 
8
8
  module Ditty
9
- class Component < Application
9
+ class ComponentController < ApplicationController
10
+ use Rack::Csrf, raise: ENV['APP_ENV'] == 'development' unless ENV['APP_ENV'] == 'test'
11
+
10
12
  helpers Helpers::Component, Helpers::Response
11
13
 
12
14
  set base_path: nil
@@ -16,7 +18,12 @@ module Ditty
16
18
  set heading: nil
17
19
 
18
20
  def read(id)
19
- dataset.first(settings.model_class.primary_key => id)
21
+ dataset.with_pk(id)
22
+ end
23
+
24
+ def read!(id)
25
+ halt 404 unless (entity = read(id))
26
+ entity
20
27
  end
21
28
 
22
29
  def skip_verify!
@@ -25,15 +32,15 @@ module Ditty
25
32
 
26
33
  def trigger(event, attribs = {})
27
34
  attribs[:target] ||= self
28
- send(event, attribs) if self.respond_to? event
35
+ send(event, attribs) if respond_to? event
29
36
  broadcast(event, attribs)
30
37
  end
31
38
 
32
39
  after do
33
40
  return if settings.environment == 'production'
34
41
 
35
- if (response.successful? || response.redirection?) && @skip_verify == false
36
- verify_authorized if settings.environment != 'production'
42
+ if (response.successful? || response.redirection?) && @skip_verify == false && (settings.environment != 'production')
43
+ verify_authorized
37
44
  end
38
45
  end
39
46
 
@@ -58,8 +65,7 @@ module Ditty
58
65
  get '/new/?' do
59
66
  authorize settings.model_class, :create
60
67
 
61
- entity = settings.model_class.new(permitted_attributes(settings.model_class, :create))
62
- session[:redirect_to] = request.fullpath
68
+ entity = settings.model_class.new(permitted_parameters(settings.model_class, :create))
63
69
  haml :"#{view_location}/new",
64
70
  locals: { entity: entity, title: heading(:new) },
65
71
  layout: layout
@@ -67,11 +73,11 @@ module Ditty
67
73
 
68
74
  # Create
69
75
  post '/' do
70
- entity = settings.model_class.new(permitted_attributes(settings.model_class, :create))
76
+ entity = settings.model_class.new(permitted_parameters(settings.model_class, :create))
71
77
  authorize entity, :create
72
78
 
73
79
  entity.db.transaction do
74
- entity.save # Will trigger a Sequel::ValidationFailed exception if the model is incorrect
80
+ entity.save_changes # Will trigger a Sequel::ValidationFailed exception if the model is incorrect
75
81
  trigger :component_create, entity: entity
76
82
  end
77
83
 
@@ -80,8 +86,7 @@ module Ditty
80
86
 
81
87
  # Read
82
88
  get '/:id/?' do |id|
83
- entity = read(id)
84
- halt 404 unless entity
89
+ entity = read!(id)
85
90
  authorize entity, :read
86
91
 
87
92
  trigger :component_read, entity: entity
@@ -90,10 +95,10 @@ module Ditty
90
95
 
91
96
  # Update Form
92
97
  get '/:id/edit/?' do |id|
93
- entity = read(id)
94
- halt 404 unless entity
98
+ entity = read!(id)
95
99
  authorize entity, :update
96
100
 
101
+ flash[:redirect_to] = "#{base_path}/#{entity.display_id}" unless flash.keep(:redirect_to)
97
102
  haml :"#{view_location}/edit",
98
103
  locals: { entity: entity, title: heading(:edit) },
99
104
  layout: layout
@@ -101,13 +106,12 @@ module Ditty
101
106
 
102
107
  # Update
103
108
  put '/:id/?' do |id|
104
- entity = read(id)
105
- halt 404 unless entity
109
+ entity = read!(id)
106
110
  authorize entity, :update
107
111
 
108
112
  entity.db.transaction do
109
- entity.set(permitted_attributes(settings.model_class, :update))
110
- entity.save # Will trigger a Sequel::ValidationFailed exception if the model is incorrect
113
+ entity.set(permitted_parameters(settings.model_class, :update))
114
+ entity.save_changes # Will trigger a Sequel::ValidationFailed exception if the model is incorrect
111
115
  trigger :component_update, entity: entity
112
116
  end
113
117
 
@@ -115,8 +119,7 @@ module Ditty
115
119
  end
116
120
 
117
121
  delete '/:id/?' do |id|
118
- entity = read(id)
119
- halt 404 unless entity
122
+ entity = read!(id)
120
123
  authorize entity, :delete
121
124
 
122
125
  entity.db.transaction do