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.
- 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
|
|