ditty 0.7.1 → 0.10.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.env.test +2 -0
- data/.gitignore +3 -0
- data/.pryrc +2 -0
- data/.rubocop.yml +24 -8
- data/.travis.yml +4 -8
- data/CNAME +1 -0
- data/Dockerfile +18 -0
- data/Gemfile.ci +0 -15
- data/Rakefile +5 -4
- data/Readme.md +24 -2
- data/_config.yml +1 -0
- data/config.ru +4 -4
- data/ditty.gemspec +31 -20
- data/docs/CNAME +1 -0
- data/docs/_config.yml +1 -0
- data/docs/index.md +34 -0
- data/exe/ditty +2 -0
- data/lib/ditty.rb +30 -4
- data/lib/ditty/cli.rb +38 -5
- data/lib/ditty/components/ditty.rb +82 -0
- data/lib/ditty/controllers/application_controller.rb +267 -0
- data/lib/ditty/controllers/{audit_logs.rb → audit_logs_controller.rb} +5 -7
- data/lib/ditty/controllers/{auth.rb → auth_controller.rb} +56 -32
- data/lib/ditty/controllers/{component.rb → component_controller.rb} +35 -24
- data/lib/ditty/controllers/{main.rb → main_controller.rb} +7 -7
- data/lib/ditty/controllers/roles_controller.rb +23 -0
- data/lib/ditty/controllers/user_login_traits_controller.rb +46 -0
- data/lib/ditty/controllers/{users.rb → users_controller.rb} +17 -20
- data/lib/ditty/db.rb +9 -5
- data/lib/ditty/emails/base.rb +48 -34
- data/lib/ditty/generators/crud_generator.rb +114 -0
- data/lib/ditty/generators/migration_generator.rb +26 -0
- data/lib/ditty/generators/project_generator.rb +52 -0
- data/lib/ditty/helpers/authentication.rb +6 -5
- data/lib/ditty/helpers/component.rb +11 -2
- data/lib/ditty/helpers/pundit.rb +24 -8
- data/lib/ditty/helpers/response.rb +38 -15
- data/lib/ditty/helpers/views.rb +48 -6
- data/lib/ditty/listener.rb +44 -14
- data/lib/ditty/memcached.rb +8 -0
- data/lib/ditty/middleware/accept_extension.rb +4 -2
- data/lib/ditty/middleware/error_catchall.rb +4 -2
- data/lib/ditty/models/audit_log.rb +1 -0
- data/lib/ditty/models/base.rb +13 -0
- data/lib/ditty/models/identity.rb +10 -7
- data/lib/ditty/models/role.rb +2 -0
- data/lib/ditty/models/user.rb +40 -3
- data/lib/ditty/models/user_login_trait.rb +17 -0
- data/lib/ditty/policies/audit_log_policy.rb +6 -6
- data/lib/ditty/policies/role_policy.rb +3 -3
- data/lib/ditty/policies/user_login_trait_policy.rb +45 -0
- data/lib/ditty/policies/user_policy.rb +3 -3
- data/lib/ditty/rubocop.rb +3 -0
- data/lib/ditty/seed.rb +2 -0
- data/lib/ditty/services/authentication.rb +31 -15
- data/lib/ditty/services/email.rb +22 -12
- data/lib/ditty/services/logger.rb +30 -13
- data/lib/ditty/services/pagination_wrapper.rb +9 -5
- data/lib/ditty/services/settings.rb +19 -7
- data/lib/ditty/tasks/ditty.rake +127 -0
- data/lib/ditty/tasks/omniauth-ldap.rake +43 -0
- data/lib/ditty/templates/.gitignore +5 -0
- data/lib/ditty/templates/.rspec +2 -0
- data/lib/ditty/templates/.rubocop.yml +7 -0
- data/lib/ditty/templates/Rakefile +12 -0
- data/lib/ditty/templates/application.rb +12 -0
- data/lib/ditty/templates/config.ru +37 -0
- data/lib/ditty/templates/controller.rb.erb +64 -0
- data/lib/ditty/templates/env.example +4 -0
- data/lib/ditty/templates/lib/project.rb.erb +5 -0
- data/lib/ditty/templates/migration.rb.erb +7 -0
- data/lib/ditty/templates/model.rb.erb +26 -0
- data/lib/ditty/templates/pids/.empty_directory +0 -0
- data/lib/ditty/templates/policy.rb.erb +48 -0
- data/{public → lib/ditty/templates/public}/browserconfig.xml +0 -0
- data/lib/ditty/templates/public/css/sb-admin-2.min.css +10 -0
- data/lib/ditty/templates/public/css/styles.css +13 -0
- data/lib/ditty/templates/public/favicon.ico +0 -0
- data/{public → lib/ditty/templates/public}/images/apple-icon.png +0 -0
- data/{public → lib/ditty/templates/public}/images/favicon-16x16.png +0 -0
- data/{public → lib/ditty/templates/public}/images/favicon-32x32.png +0 -0
- data/{public → lib/ditty/templates/public}/images/launcher-icon-1x.png +0 -0
- data/{public → lib/ditty/templates/public}/images/launcher-icon-2x.png +0 -0
- data/{public → lib/ditty/templates/public}/images/launcher-icon-4x.png +0 -0
- data/{public → lib/ditty/templates/public}/images/mstile-150x150.png +0 -0
- data/{public → lib/ditty/templates/public}/images/safari-pinned-tab.svg +0 -0
- data/lib/ditty/templates/public/js/sb-admin-2.min.js +7 -0
- data/lib/ditty/templates/public/js/scripts.js +1 -0
- data/{public/manifest.json → lib/ditty/templates/public/manifest.json.erb} +2 -2
- data/lib/ditty/templates/settings.yml.erb +19 -0
- data/lib/ditty/templates/sidekiq.rb +18 -0
- data/lib/ditty/templates/sidekiq.yml +9 -0
- data/lib/ditty/templates/spec_helper.rb +43 -0
- data/lib/ditty/templates/type.rb.erb +21 -0
- data/lib/ditty/templates/views/display.haml.tt +20 -0
- data/lib/ditty/templates/views/edit.haml.tt +10 -0
- data/lib/ditty/templates/views/form.haml.tt +11 -0
- data/lib/ditty/templates/views/index.haml.tt +29 -0
- data/lib/ditty/templates/views/new.haml.tt +10 -0
- data/lib/ditty/version.rb +1 -1
- data/lib/rubocop/cop/ditty/call_services_directly.rb +42 -0
- data/migrate/20181209_add_user_login_traits.rb +16 -0
- data/migrate/20181209_extend_audit_log.rb +12 -0
- data/migrate/20190220_add_parent_id_to_roles.rb +9 -0
- data/spec/ditty/api_spec.rb +51 -0
- data/spec/ditty/controllers/roles_spec.rb +67 -0
- data/spec/ditty/controllers/user_login_traits_spec.rb +72 -0
- data/spec/ditty/controllers/users_spec.rb +72 -0
- data/spec/ditty/emails/base_spec.rb +76 -0
- data/spec/ditty/emails/forgot_password_spec.rb +20 -0
- data/spec/ditty/helpers/component_spec.rb +85 -0
- data/spec/ditty/models/user_spec.rb +36 -0
- data/spec/ditty/services/email_spec.rb +36 -0
- data/spec/ditty/services/logger_spec.rb +68 -0
- data/spec/ditty/services/settings_spec.rb +63 -0
- data/spec/ditty_spec.rb +9 -0
- data/spec/factories.rb +46 -0
- data/spec/fixtures/logger.yml +17 -0
- data/spec/fixtures/section.yml +3 -0
- data/spec/fixtures/settings.yml +8 -0
- data/spec/spec_helper.rb +51 -0
- data/spec/support/api_shared_examples.rb +250 -0
- data/spec/support/crud_shared_examples.rb +145 -0
- data/views/403.haml +2 -0
- data/views/404.haml +2 -4
- data/views/500.haml +11 -0
- data/views/audit_logs/index.haml +32 -28
- data/views/auth/forgot_password.haml +32 -16
- data/views/auth/identity.haml +14 -13
- data/views/auth/ldap.haml +17 -0
- data/views/auth/login.haml +23 -17
- data/views/auth/register.haml +20 -18
- data/views/auth/register_identity.haml +27 -12
- data/views/auth/reset_password.haml +36 -19
- data/views/blank.haml +43 -0
- data/views/emails/forgot_password.haml +1 -1
- data/views/emails/layouts/action.haml +10 -6
- data/views/emails/layouts/alert.haml +2 -1
- data/views/emails/layouts/billing.haml +2 -1
- data/views/embedded.haml +17 -11
- data/views/error.haml +8 -3
- data/views/index.haml +1 -1
- data/views/layout.haml +45 -30
- data/views/partials/actions.haml +15 -14
- data/views/partials/content_tag.haml +0 -0
- data/views/partials/delete_form.haml +1 -1
- data/views/partials/filter_control.haml +2 -2
- data/views/partials/footer.haml +13 -5
- data/views/partials/form_control.haml +30 -19
- data/views/partials/form_tag.haml +1 -1
- data/views/partials/navitems.haml +42 -0
- data/views/partials/notifications.haml +12 -8
- data/views/partials/pager.haml +44 -25
- data/views/partials/search.haml +15 -11
- data/views/partials/sidebar.haml +15 -37
- data/views/partials/sort_ui.haml +2 -0
- data/views/partials/timespan_selector.haml +64 -0
- data/views/partials/topbar.haml +53 -0
- data/views/partials/user_associations.haml +32 -0
- data/views/quick_start.haml +23 -0
- data/views/roles/display.haml +27 -6
- data/views/roles/edit.haml +3 -3
- data/views/roles/form.haml +1 -0
- data/views/roles/index.haml +23 -14
- data/views/roles/new.haml +2 -2
- data/views/user_login_traits/display.haml +32 -0
- data/views/user_login_traits/edit.haml +10 -0
- data/views/user_login_traits/form.haml +5 -0
- data/views/user_login_traits/index.haml +28 -0
- data/views/user_login_traits/new.haml +10 -0
- data/views/users/display.haml +15 -16
- data/views/users/edit.haml +3 -3
- data/views/users/form.haml +0 -0
- data/views/users/index.haml +31 -24
- data/views/users/login_traits.haml +25 -0
- data/views/users/new.haml +2 -2
- data/views/users/profile.haml +17 -15
- data/views/users/user.haml +1 -1
- metadata +314 -76
- data/lib/ditty/components/app.rb +0 -77
- data/lib/ditty/controllers/application.rb +0 -175
- data/lib/ditty/controllers/roles.rb +0 -16
- data/lib/ditty/rake_tasks.rb +0 -102
- data/views/partials/navbar.haml +0 -23
data/lib/ditty/cli.rb
CHANGED
@@ -1,23 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# https://nandovieira.com/creating-generators-and-executables-with-thor
|
2
|
-
require 'dotenv/load'
|
4
|
+
require 'dotenv/load' rescue LoadError # rubocop:disable Style/RescueModifier - Ignore dotenv/load errors
|
3
5
|
require 'thor'
|
4
|
-
require 'ditty'
|
5
|
-
require 'ditty/rake_tasks'
|
6
6
|
require 'rack'
|
7
7
|
require 'rake'
|
8
|
+
require 'ditty/db' if ENV['DATABASE_URL']
|
9
|
+
require 'ditty/generators/crud_generator'
|
10
|
+
require 'ditty/generators/project_generator'
|
11
|
+
require 'ditty/generators/migration_generator'
|
12
|
+
require 'ditty/components/ditty'
|
13
|
+
|
14
|
+
# TODO: Component generator
|
15
|
+
# TODO: Add requires into application.rb
|
16
|
+
# TODO: Add requires into schema.rb
|
8
17
|
|
9
18
|
module Ditty
|
10
19
|
class CLI < Thor
|
11
20
|
include Thor::Actions
|
12
21
|
|
22
|
+
register ::Ditty::Generators::CrudGenerator, 'crud', 'crud NAME', 'Generate a CRUD endpoint'
|
23
|
+
|
24
|
+
register ::Ditty::Generators::ProjectGenerator, 'init', 'init', 'Initialize a Ditty Project'
|
25
|
+
|
26
|
+
register ::Ditty::Generators::MigrationGenerator, 'migration', 'migration NAME', 'Create a new Sequel migration'
|
27
|
+
|
28
|
+
default_task :server
|
29
|
+
|
13
30
|
desc 'server', 'Start the Ditty server'
|
14
31
|
require './application' if File.exist?('application.rb')
|
32
|
+
require 'ditty/db' unless defined?(DB)
|
33
|
+
::Ditty::Components.tasks
|
15
34
|
def server
|
16
35
|
# Ensure the token files are present
|
17
36
|
Rake::Task['ditty:generate_tokens'].invoke
|
18
37
|
|
19
38
|
# Prep Ditty
|
20
|
-
Rake::Task['ditty:prep'].invoke
|
39
|
+
Rake::Task['ditty:prep:folders'].invoke
|
40
|
+
Rake::Task['ditty:prep:migrations'].invoke
|
21
41
|
|
22
42
|
# Check the migrations
|
23
43
|
Rake::Task['ditty:migrate:check'].invoke
|
@@ -34,11 +54,24 @@ module Ditty
|
|
34
54
|
desc 'migrate', 'Run the Ditty migrations'
|
35
55
|
def migrate
|
36
56
|
# Prep Ditty
|
37
|
-
Rake::Task['ditty:prep'].invoke
|
57
|
+
Rake::Task['ditty:prep:migrations'].invoke
|
38
58
|
|
39
59
|
# Run the migrations
|
40
60
|
Rake::Task['ditty:migrate:up'].invoke
|
41
61
|
puts 'Ditty Migrations Executed'
|
62
|
+
|
63
|
+
Rake::Task['ditty:dump_schema'].invoke
|
64
|
+
puts 'Ditty DB Schema Dumped'
|
65
|
+
end
|
66
|
+
|
67
|
+
desc 'seed', 'Seed the predefined seeding data'
|
68
|
+
def seed
|
69
|
+
Rake::Task['ditty:seed'].invoke
|
70
|
+
end
|
71
|
+
|
72
|
+
desc 'console', 'Open a fully loaded console'
|
73
|
+
def console
|
74
|
+
Rake::Task['ditty:console'].invoke
|
42
75
|
end
|
43
76
|
end
|
44
77
|
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ditty'
|
4
|
+
require 'ditty/services/settings'
|
5
|
+
|
6
|
+
module Ditty
|
7
|
+
class Ditty
|
8
|
+
def self.load
|
9
|
+
controllers = File.expand_path('../controllers', __dir__)
|
10
|
+
Dir.glob("#{controllers}/*.rb").sort.each { |f| require f }
|
11
|
+
|
12
|
+
require 'ditty/models/user'
|
13
|
+
require 'ditty/models/role'
|
14
|
+
require 'ditty/models/identity'
|
15
|
+
require 'ditty/models/audit_log'
|
16
|
+
require 'ditty/models/user_login_trait'
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.configure(_container)
|
20
|
+
require 'ditty/db' unless defined? ::DB
|
21
|
+
require 'ditty/listener'
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.migrations
|
25
|
+
File.expand_path('../../../migrate', __dir__)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.view_folder
|
29
|
+
File.expand_path('../../../views', __dir__)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.routes
|
33
|
+
load
|
34
|
+
{
|
35
|
+
'/' => ::Ditty::MainController,
|
36
|
+
'/auth' => ::Ditty::AuthController,
|
37
|
+
'/users' => ::Ditty::UsersController,
|
38
|
+
'/roles' => ::Ditty::RolesController,
|
39
|
+
'/audit-logs' => ::Ditty::AuditLogsController,
|
40
|
+
'/login-traits' => ::Ditty::UserLoginTraitsController
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.navigation(_request)
|
45
|
+
load
|
46
|
+
|
47
|
+
[
|
48
|
+
{
|
49
|
+
group: 'User Management',
|
50
|
+
order: 50,
|
51
|
+
icon: 'lock',
|
52
|
+
target: ::Ditty::User,
|
53
|
+
items: [
|
54
|
+
{ order: 10, link: '/users/', text: 'Users', target: ::Ditty::User, icon: 'user' },
|
55
|
+
{ order: 20, link: '/roles/', text: 'Roles', target: ::Ditty::Role, icon: 'check-square' },
|
56
|
+
{ order: 30, link: '/audit-logs/', text: 'Audit Logs', target: ::Ditty::AuditLog, icon: 'history' },
|
57
|
+
{ order: 40, link: '/login-traits/', text: 'User Login Traits', target: ::Ditty::UserLoginTrait,
|
58
|
+
icon: 'list' }
|
59
|
+
]
|
60
|
+
}
|
61
|
+
]
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.seeder
|
65
|
+
proc do
|
66
|
+
load
|
67
|
+
|
68
|
+
sa = ::Ditty::Role.find_or_create(name: 'super_admin')
|
69
|
+
admin = ::Ditty::Role.find_or_create(name: 'admin') { |e| e.parent = sa }
|
70
|
+
::Ditty::Role.find_or_create(name: 'user') { |e| e.parent = admin }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.tasks
|
75
|
+
Kernel.load 'ditty/tasks/ditty.rake'
|
76
|
+
auth_settings = ::Ditty::Services::Settings[:authentication] || {}
|
77
|
+
Kernel.load 'ditty/tasks/omniauth-ldap.rake' if auth_settings.key?(:ldap)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
Ditty::Components.register_component(:ditty, Ditty::Ditty)
|
@@ -0,0 +1,267 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'browser/browser'
|
4
|
+
require 'wisper'
|
5
|
+
require 'oga'
|
6
|
+
require 'sinatra/base'
|
7
|
+
require 'sinatra/flash'
|
8
|
+
require 'sinatra/param'
|
9
|
+
require 'sinatra/respond_with'
|
10
|
+
require 'ditty/helpers/views'
|
11
|
+
require 'ditty/helpers/pundit'
|
12
|
+
require 'ditty/helpers/authentication'
|
13
|
+
require 'ditty/services/logger'
|
14
|
+
require 'active_support'
|
15
|
+
require 'active_support/inflector'
|
16
|
+
require 'rack/contrib'
|
17
|
+
require 'rack/csrf'
|
18
|
+
|
19
|
+
module Ditty
|
20
|
+
class ApplicationController < Sinatra::Base
|
21
|
+
include ActiveSupport::Inflector
|
22
|
+
|
23
|
+
set :root, ENV['APP_ROOT'] || ::File.expand_path("#{::File.dirname(__FILE__)}/../../../")
|
24
|
+
set :map_path, nil
|
25
|
+
set :view_location, nil
|
26
|
+
set :view_folder, nil
|
27
|
+
set :base_path, nil
|
28
|
+
set :model_class, nil
|
29
|
+
set :raise_sinatra_param_exceptions, true
|
30
|
+
set track_actions: false
|
31
|
+
|
32
|
+
# The order here is important, since Wisper has a deprecated method respond_with method
|
33
|
+
helpers Wisper::Publisher
|
34
|
+
helpers Helpers::Pundit, Helpers::Views, Helpers::Authentication
|
35
|
+
helpers Sinatra::Param
|
36
|
+
|
37
|
+
register Sinatra::Flash, Sinatra::RespondWith
|
38
|
+
|
39
|
+
use Rack::Csrf, raise: ENV['APP_ENV'] == 'development' unless ENV['APP_ENV'] == 'test'
|
40
|
+
use Rack::JSONBodyParser
|
41
|
+
use Rack::MethodOverride
|
42
|
+
use Rack::NestedParams
|
43
|
+
|
44
|
+
helpers do
|
45
|
+
def logger
|
46
|
+
::Ditty::Services::Logger
|
47
|
+
end
|
48
|
+
|
49
|
+
def base_path
|
50
|
+
settings.base_path || "#{settings.map_path}/#{dasherize(view_location)}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def view_location
|
54
|
+
return settings.view_location if settings.view_location
|
55
|
+
|
56
|
+
loc = demodulize(settings.model_class || self.class)
|
57
|
+
pluralize(underscore(loc.gsub(/Controller\Z/, '')))
|
58
|
+
end
|
59
|
+
|
60
|
+
def browser
|
61
|
+
Browser.new(request.user_agent, accept_language: request.env['HTTP_ACCEPT_LANGUAGE'])
|
62
|
+
end
|
63
|
+
|
64
|
+
def config(name, default = '')
|
65
|
+
::Ditty::Services::Settings[name] || default
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def view_folders
|
70
|
+
folders = ['./views']
|
71
|
+
folders << settings.view_folder if settings.view_folder
|
72
|
+
folders << ::Ditty::Ditty.view_folder
|
73
|
+
end
|
74
|
+
|
75
|
+
def find_template(views, name, engine, &block)
|
76
|
+
# Backwards compatability
|
77
|
+
if settings.view_folder.nil? && self.class.name.split('::').first != 'Ditty'
|
78
|
+
return super(views, name, engine, &block)
|
79
|
+
end
|
80
|
+
|
81
|
+
view_folders.each do |folder|
|
82
|
+
super(folder, name, engine, &block) # Root
|
83
|
+
end
|
84
|
+
raise ::Ditty::TemplateNotFoundError, "Could not find template `#{name}`"
|
85
|
+
end
|
86
|
+
|
87
|
+
configure :production do
|
88
|
+
disable :show_exceptions
|
89
|
+
set :dump_errors, false
|
90
|
+
end
|
91
|
+
|
92
|
+
configure :development do
|
93
|
+
set :show_exceptions, :after_handler
|
94
|
+
end
|
95
|
+
|
96
|
+
configure :production, :development do
|
97
|
+
disable :logging
|
98
|
+
use Rack::CommonLogger, ::Ditty::Services::Logger
|
99
|
+
end
|
100
|
+
|
101
|
+
not_found do
|
102
|
+
respond_to do |format|
|
103
|
+
status 404
|
104
|
+
format.html do
|
105
|
+
haml :'404', locals: { title: '4 oh 4' }, layout: layout
|
106
|
+
end
|
107
|
+
format.json do
|
108
|
+
if response.body.empty?
|
109
|
+
json code: 404, errors: ['Not Found']
|
110
|
+
else
|
111
|
+
[404, response.body]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
error Helpers::NotAuthenticated, ::Pundit::NotAuthorizedError do
|
118
|
+
# TODO: Check if this is logged / tracked
|
119
|
+
if authenticated?
|
120
|
+
respond_to do |format|
|
121
|
+
status 403
|
122
|
+
format.html do
|
123
|
+
flash.now[:danger] = 'Cannot perform that action at the moment.'
|
124
|
+
haml :'403', locals: { title: 'Forbidden' }, layout: layout
|
125
|
+
end
|
126
|
+
format.json do
|
127
|
+
json code: 403, errors: ['Forbidden']
|
128
|
+
end
|
129
|
+
end
|
130
|
+
else
|
131
|
+
respond_to do |format|
|
132
|
+
format.html do
|
133
|
+
flash[:warning] = 'Please log in first.'
|
134
|
+
redirect with_layout("#{settings.map_path}/auth/login")
|
135
|
+
end
|
136
|
+
format.json do
|
137
|
+
status 401
|
138
|
+
json code: 401, errors: ['Not Authenticated']
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
error ::Sinatra::Param::InvalidParameterError do
|
145
|
+
respond_to do |format|
|
146
|
+
status 400
|
147
|
+
format.html do
|
148
|
+
flash.now[:danger] = env['sinatra.error'].message
|
149
|
+
haml :'400', locals: { title: '4 oh oh' }, layout: layout
|
150
|
+
end
|
151
|
+
format.json do
|
152
|
+
json code: 400, errors: { env['sinatra.error'].param => env['sinatra.error'].message },
|
153
|
+
full_errors: [env['sinatra.error'].message]
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
error ::Sequel::NoMatchingRow do
|
159
|
+
respond_to do |format|
|
160
|
+
status 404
|
161
|
+
format.html do
|
162
|
+
haml :'404', locals: { title: '4 oh 4' }, layout: layout
|
163
|
+
end
|
164
|
+
format.json do
|
165
|
+
if response.body.empty?
|
166
|
+
json code: 404, errors: ['Not Found']
|
167
|
+
else
|
168
|
+
[404, response.body]
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
error ::Sequel::ValidationFailed do
|
175
|
+
respond_to do |format|
|
176
|
+
entity = env['sinatra.error'].model
|
177
|
+
errors = env['sinatra.error'].errors
|
178
|
+
status 400
|
179
|
+
format.html do
|
180
|
+
action = entity.id ? :edit : :new
|
181
|
+
haml :"#{view_location}/#{action}", locals: { entity: entity, title: heading(action) }, layout: layout
|
182
|
+
end
|
183
|
+
format.json do
|
184
|
+
json code: 400, errors: errors, full_errors: errors.full_messages
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
error ::Sequel::ForeignKeyConstraintViolation do
|
190
|
+
error = env['sinatra.error']
|
191
|
+
broadcast(:application_error, error)
|
192
|
+
logger.error error
|
193
|
+
respond_to do |format|
|
194
|
+
status 400
|
195
|
+
format.html do
|
196
|
+
haml :error, locals: { title: 'Something went wrong', error: error }, layout: layout
|
197
|
+
end
|
198
|
+
format.json do
|
199
|
+
json code: 400, errors: ['Invalid Relation Specified']
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
error ::Ditty::TemplateNotFoundError do
|
205
|
+
# TODO: Display a better error message
|
206
|
+
error = env['sinatra.error']
|
207
|
+
broadcast(:application_error, error)
|
208
|
+
logger.error error
|
209
|
+
respond_to do |format|
|
210
|
+
status 500
|
211
|
+
format.html do
|
212
|
+
haml :error, locals: { title: 'Template not found', error: error }, layout: layout
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
error do
|
218
|
+
error = env['sinatra.error']
|
219
|
+
broadcast(:application_error, error)
|
220
|
+
logger.error error
|
221
|
+
respond_to do |format|
|
222
|
+
status 500
|
223
|
+
format.html do
|
224
|
+
haml :error, locals: { title: 'Something went wrong', error: error }, layout: layout
|
225
|
+
end
|
226
|
+
format.json do
|
227
|
+
json code: 500, errors: ['Something went wrong']
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
before(/.*/) do
|
233
|
+
logger.info "Running with #{self.class} - #{request.path_info}"
|
234
|
+
if /.*\.json\Z/.match?(request.path)
|
235
|
+
content_type :json
|
236
|
+
request.path_info = request.path_info.gsub(/.json$/, '')
|
237
|
+
elsif /.*\.csv\Z/.match?(request.path)
|
238
|
+
content_type :csv
|
239
|
+
request.path_info = request.path_info.gsub(/.csv$/, '')
|
240
|
+
elsif request.env['ACCEPT']
|
241
|
+
content_type request.env['ACCEPT']
|
242
|
+
elsif request.accept.count.eql?(1) && request.accept.first.to_s.eql?('*/*')
|
243
|
+
content_type(:json)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
after do
|
248
|
+
return if params[:layout].nil?
|
249
|
+
return unless response.body.respond_to?(:map)
|
250
|
+
|
251
|
+
begin
|
252
|
+
orig = response.body
|
253
|
+
response.body = response.body.map do |resp|
|
254
|
+
document = Oga.parse_html(resp)
|
255
|
+
document.css('a').each do |elm|
|
256
|
+
unless (href = elm.get('href')).nil?
|
257
|
+
elm.set 'href', with_layout(href)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
document.to_xml
|
261
|
+
end
|
262
|
+
rescue StandardError => _e
|
263
|
+
orig
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
@@ -1,13 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'ditty/controllers/
|
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
|
8
|
+
class AuditLogsController < ::Ditty::ComponentController
|
9
9
|
set model_class: AuditLog
|
10
10
|
|
11
|
+
SEARCHABLE = %i[details platform device browser ip_address].freeze
|
11
12
|
FILTERS = [
|
12
13
|
{ name: :user, field: 'user.email' },
|
13
14
|
{ name: :action }
|
@@ -23,12 +24,9 @@ module Ditty
|
|
23
24
|
end
|
24
25
|
end
|
25
26
|
|
26
|
-
def find_template(views, name, engine, &block)
|
27
|
-
super(views, name, engine, &block) # Root
|
28
|
-
super(::Ditty::App.view_folder, name, engine, &block) # Ditty
|
29
|
-
end
|
30
|
-
|
31
27
|
def list
|
28
|
+
return super if params[:sort]
|
29
|
+
|
32
30
|
super.order(:created_at).reverse
|
33
31
|
end
|
34
32
|
|