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
@@ -1,23 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'ditty/controllers/
|
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
|
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 =
|
36
|
-
identity_params =
|
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.
|
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.
|
49
|
+
user.save_changes
|
53
50
|
user.add_identity identity
|
54
51
|
|
55
|
-
|
56
|
-
roles.
|
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 =
|
68
|
+
values = permitted_parameters(settings.model_class, :update)
|
74
69
|
roles = values.delete('role_id')
|
75
70
|
entity.set values
|
76
|
-
entity.
|
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 =
|
97
|
+
values = permitted_parameters(Identity, :create)
|
103
98
|
identity.set values
|
104
|
-
if identity.valid?
|
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.
|
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.
|
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 :
|
25
|
-
Sequel::Model.plugin :
|
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.
|
32
|
+
::Ditty::Services::Logger.error 'No database connection set up'
|
29
33
|
end
|
data/lib/ditty/emails/base.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'haml'
|
2
|
-
require 'ditty/components/
|
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
|
-
|
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?
|
40
|
+
return true if mail.respond_to?(method)
|
41
|
+
|
42
|
+
super
|
32
43
|
end
|
33
44
|
|
34
45
|
private
|
35
46
|
|
36
|
-
|
37
|
-
|
38
|
-
|
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
|
-
|
43
|
-
|
44
|
-
end
|
51
|
+
Haml::Engine.new(layout_haml).render(Object.new, locals.merge(content: result))
|
52
|
+
end
|
45
53
|
|
46
|
-
|
47
|
-
|
48
|
-
|
54
|
+
def content_haml
|
55
|
+
read_template(options[:view])
|
56
|
+
end
|
49
57
|
|
50
|
-
|
51
|
-
|
52
|
-
|
58
|
+
def layout_haml
|
59
|
+
read_template("layouts/#{options[:layout]}") if options[:layout]
|
60
|
+
end
|
53
61
|
|
54
|
-
|
55
|
-
|
56
|
-
|
62
|
+
def read_template(template)
|
63
|
+
File.read(find_template("emails/#{template}"))
|
64
|
+
end
|
57
65
|
|
58
|
-
|
59
|
-
|
60
|
-
|
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
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
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
|
-
|
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']
|
41
|
+
env['rack.session']&.delete('user_id')
|
41
42
|
env.delete('omniauth.auth')
|
42
43
|
end
|
43
44
|
end
|