eucalypt 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/README.md +26 -0
- data/Rakefile +2 -0
- data/bin/eucalypt +3 -0
- data/eucalypt.gemspec +39 -0
- data/lib/eucalypt/app.rb +6 -0
- data/lib/eucalypt/controller.rb +10 -0
- data/lib/eucalypt/errors.rb +109 -0
- data/lib/eucalypt/eucalypt-blog/helpers.rb +106 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/__base__.rb +22 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/__require__.rb +1 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/cli/blog.rb +65 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/generators/article.rb +28 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/generators/controller.rb +14 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/generators/helper.rb +12 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/generators/list.rb +74 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/generators/views.rb +20 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/controller/controller.tt +33 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/controller/controller_spec.tt +43 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/helper/helper.tt +5 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/helper/helper_spec.tt +9 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/views/article.erb +1 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/views/article_layout.erb +10 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/views/article_md.tt +9 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/views/articles.erb +1 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/views/articles_layout.erb +10 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog/templates/views/search.erb +1 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog-article/cli/article.rb +120 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog-article-edit/cli/edit-datetime.rb +113 -0
- data/lib/eucalypt/eucalypt-blog/namespaces/blog-article-edit/cli/edit-urltitle.rb +75 -0
- data/lib/eucalypt/eucalypt-core/cli/__base__.rb +11 -0
- data/lib/eucalypt/eucalypt-core/cli/console.rb +15 -0
- data/lib/eucalypt/eucalypt-core/cli/core.rb +6 -0
- data/lib/eucalypt/eucalypt-core/cli/help.rb +11 -0
- data/lib/eucalypt/eucalypt-core/cli/init.rb +71 -0
- data/lib/eucalypt/eucalypt-core/cli/launch.rb +33 -0
- data/lib/eucalypt/eucalypt-core/cli/test.rb +16 -0
- data/lib/eucalypt/eucalypt-core/cli/version.rb +11 -0
- data/lib/eucalypt/eucalypt-core/templates/Gemfile.tt +35 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/.gitignore +48 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/.travis.yml +8 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/Procfile +1 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/Rakefile +7 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/assets/fonts/.empty_directory +0 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/assets/images/.empty_directory +0 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/assets/scripts/application.js +17 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/assets/stylesheets/__partials__.scss +16 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/assets/stylesheets/application.scss +17 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/assets/stylesheets/partials/_mixins.scss +54 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/controllers/application_controller.rb +7 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/helpers/application_helper.rb +3 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/models/.empty_directory +0 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/static/.empty_directory +0 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/static/readme.yml +34 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/views/index.erb +0 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/views/layouts/main.erb +9 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app/views/partials/.empty_directory +0 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/app.rb +42 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/config/active_record.rb +6 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/config/asset_pipeline.rb +15 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/config/database.yml +16 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/config/initializers/.empty_directory +0 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/config/logging.rb +27 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/config/manifest.rb +15 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/config.ru +10 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/log/.empty_directory +0 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/spec/controllers/application_controller_spec.rb +9 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/spec/helpers/application_helper_spec.rb +9 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/spec/models/.empty_directory +0 -0
- data/lib/eucalypt/eucalypt-core/templates/eucalypt/spec/spec_helper.rb +18 -0
- data/lib/eucalypt/eucalypt-destroy/helpers.rb +77 -0
- data/lib/eucalypt/eucalypt-destroy/namespaces/destroy/cli/destroy-controller.rb +16 -0
- data/lib/eucalypt/eucalypt-destroy/namespaces/destroy/cli/destroy-helper.rb +16 -0
- data/lib/eucalypt/eucalypt-destroy/namespaces/destroy/cli/destroy-model.rb +16 -0
- data/lib/eucalypt/eucalypt-destroy/namespaces/destroy/cli/destroy-scaffold.rb +63 -0
- data/lib/eucalypt/eucalypt-destroy/namespaces/destroy/cli/destroy.rb +21 -0
- data/lib/eucalypt/eucalypt-generate/.gitkeep +0 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate/cli/generate-scaffold.rb +62 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate/cli/generate.rb +24 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-controller/cli/generate-controller.rb +29 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-controller/generators/controller.rb +45 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-controller/templates/controller/controller.tt +3 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-controller/templates/controller/policy_rest_controller.tt +71 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-controller/templates/controller/rest_controller.tt +28 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-controller/templates/controller_spec.tt +9 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-helper/cli/generate-helper.rb +23 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-helper/generators/helper.rb +24 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-helper/templates/helper.tt +3 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-helper/templates/helper_spec.tt +9 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-model/cli/generate-model.rb +26 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-model/generators/model.rb +25 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-model/templates/model.tt +3 -0
- data/lib/eucalypt/eucalypt-generate/namespaces/generate-model/templates/model_spec.tt +8 -0
- data/lib/eucalypt/eucalypt-migration/helpers.rb +93 -0
- data/lib/eucalypt/eucalypt-migration/migration_base.tt +4 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration/cli/migration.rb +39 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-add/cli/add-column.rb +25 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-add/cli/add-index.rb +25 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-add/cli/add.rb +18 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-add/generators/column.rb +46 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-add/generators/index.rb +52 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-blank/cli/blank.rb +22 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-blank/generators/blank.rb +28 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-change/cli/change-column.rb +23 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-change/cli/change.rb +17 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-change/generators/column.rb +46 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-create/cli/create-table.rb +25 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-create/cli/create.rb +17 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-create/generators/table.rb +53 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-drop/cli/drop-column.rb +22 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-drop/cli/drop-index.rb +23 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-drop/cli/drop-table.rb +22 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-drop/cli/drop.rb +19 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-drop/generators/column.rb +38 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-drop/generators/index.rb +48 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-drop/generators/table.rb +37 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-rename/cli/rename-column.rb +22 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-rename/cli/rename-index.rb +22 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-rename/cli/rename-table.rb +24 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-rename/cli/rename.rb +19 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-rename/generators/column.rb +39 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-rename/generators/index.rb +39 -0
- data/lib/eucalypt/eucalypt-migration/namespaces/migration-rename/generators/table.rb +38 -0
- data/lib/eucalypt/eucalypt-security/helpers.rb +22 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security/cli/security.rb +31 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-policy/cli/security-policy.rb +91 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-policy/generators/policy.rb +31 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-policy/templates/create_policy_roles_migration.tt +11 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-policy/templates/policy.tt +16 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-policy-permission/cli/security-policy-permission.rb +62 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-policy-permission/generators/policy-permission.rb +28 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-policy-permission/templates/add_permission_to_policy_migration.tt +5 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-policy-role/cli/security-policy-role.rb +66 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-pundit/cli/security-pundit.rb +79 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-pundit/generators/role.rb +24 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-pundit/templates/create_roles_migration.tt +7 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-pundit/templates/pundit.tt +4 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-warden/cli/security-warden.rb +61 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-warden/generators/auth_controller.rb +34 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-warden/generators/user.rb +37 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-warden/templates/auth_controller.tt +25 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-warden/templates/auth_login.tt +1 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-warden/templates/create_users_table_migration.tt +9 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-warden/templates/user.tt +16 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-warden/templates/warden.tt +35 -0
- data/lib/eucalypt/eucalypt-security/namespaces/security-warden/user_confirm.rb +38 -0
- data/lib/eucalypt/helpers/colorize.rb +27 -0
- data/lib/eucalypt/helpers/gemfile.rb +48 -0
- data/lib/eucalypt/helpers/inflect.rb +79 -0
- data/lib/eucalypt/helpers/messages.rb +31 -0
- data/lib/eucalypt/helpers/migration.rb +85 -0
- data/lib/eucalypt/helpers/numeric.rb +10 -0
- data/lib/eucalypt/helpers.rb +6 -0
- data/lib/eucalypt/list.rb +39 -0
- data/lib/eucalypt/static.rb +48 -0
- data/lib/eucalypt/version.rb +3 -0
- data/lib/eucalypt.rb +19 -0
- metadata +373 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_support/core_ext'
|
3
|
+
require 'thor'
|
4
|
+
require 'eucalypt/helpers'
|
5
|
+
require 'eucalypt/eucalypt-generate/namespaces/generate/cli/generate'
|
6
|
+
|
7
|
+
module Eucalypt
|
8
|
+
class Security < Thor
|
9
|
+
module Helpers
|
10
|
+
include Eucalypt::Helpers
|
11
|
+
include Eucalypt::Helpers::Messages
|
12
|
+
using Colorize
|
13
|
+
|
14
|
+
def create_config_file(type, directory)
|
15
|
+
config_relative = File.join 'config', "#{type}.rb"
|
16
|
+
config_file = File.join(directory, config_relative)
|
17
|
+
Out.warning "#{type.to_s.capitalize} config file #{config_relative.colorize(:bold)} already exists." if File.file? config_file
|
18
|
+
template "#{type}.tt", config_file
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'eucalypt/errors'
|
2
|
+
require 'eucalypt/eucalypt-security/namespaces/security-warden/cli/security-warden'
|
3
|
+
require 'eucalypt/eucalypt-security/namespaces/security-pundit/cli/security-pundit'
|
4
|
+
require 'eucalypt/eucalypt-security/namespaces/security-policy/cli/security-policy'
|
5
|
+
require 'eucalypt/helpers'
|
6
|
+
|
7
|
+
module Eucalypt
|
8
|
+
class Security < Thor
|
9
|
+
include Thor::Actions
|
10
|
+
include Eucalypt::Helpers
|
11
|
+
using Colorize
|
12
|
+
|
13
|
+
class << self
|
14
|
+
require 'eucalypt/list'
|
15
|
+
include Eucalypt::List
|
16
|
+
def banner(task, namespace = false, subcommand = true)
|
17
|
+
basename + ' ' + task.formatted_usage(self, true, subcommand).split(':').join(' ')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
register(Eucalypt::SecurityWarden, 'warden', 'warden [COMMAND]', 'Configure Warden authentication'.colorize(:grey))
|
22
|
+
register(Eucalypt::SecurityPundit, 'pundit', 'pundit [COMMAND]', 'Configure Pundit authorization'.colorize(:grey))
|
23
|
+
register(Eucalypt::SecurityPolicy, 'policy', 'policy [COMMAND]', 'Pundit policy commands'.colorize(:grey))
|
24
|
+
end
|
25
|
+
|
26
|
+
class CLI < Thor
|
27
|
+
include Eucalypt::Helpers
|
28
|
+
using Colorize
|
29
|
+
register(Security, 'security', 'security [COMMAND]', 'Manage authentication and authorization'.colorize(:grey))
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'eucalypt/errors'
|
3
|
+
require 'eucalypt/helpers'
|
4
|
+
require 'eucalypt/eucalypt-security/namespaces/security-policy/generators/policy'
|
5
|
+
require 'eucalypt/eucalypt-security/namespaces/security-policy-permission/cli/security-policy-permission'
|
6
|
+
require 'eucalypt/eucalypt-security/namespaces/security-policy-role/cli/security-policy-role'
|
7
|
+
|
8
|
+
module Eucalypt
|
9
|
+
class SecurityPolicy < Thor
|
10
|
+
include Thor::Actions
|
11
|
+
include Eucalypt::Helpers
|
12
|
+
using Colorize
|
13
|
+
|
14
|
+
method_option :permissions, type: :array, aliases: '-p', default: [], desc: "Permissions to generate along with the policy"
|
15
|
+
desc "generate [NAME]", "Create a new Pundit policy".colorize(:grey)
|
16
|
+
def generate(name)
|
17
|
+
directory = File.expand_path('.')
|
18
|
+
if Eucalypt.app? directory
|
19
|
+
# Check for authorization gems
|
20
|
+
return unless Gemfile.check(%w[pundit], 'eucalypt security pundit setup', directory)
|
21
|
+
|
22
|
+
# Check for user model
|
23
|
+
unless File.exist? File.join(directory, 'app', 'models', 'user.rb')
|
24
|
+
Eucalypt::Error.no_user_model
|
25
|
+
return
|
26
|
+
end
|
27
|
+
|
28
|
+
# Check for role model
|
29
|
+
unless File.exist? File.join(directory, 'app', 'models', 'role.rb')
|
30
|
+
Eucalypt::Error.no_role_model
|
31
|
+
return
|
32
|
+
end
|
33
|
+
|
34
|
+
policy = Inflect.new(:policy, name)
|
35
|
+
|
36
|
+
policy_generator = Eucalypt::Generators::Policy.new
|
37
|
+
policy_generator.destination_root = directory
|
38
|
+
|
39
|
+
# Generate policy file
|
40
|
+
policy_generator.generate(name: name)
|
41
|
+
|
42
|
+
# Create policy roles table
|
43
|
+
policy_generator.generate_policy_roles_migration(policy: policy.resource)
|
44
|
+
|
45
|
+
# Create policy role model
|
46
|
+
Dir.chdir(directory) do
|
47
|
+
Eucalypt::CLI.start(['generate', 'model', "#{policy.resource}_role", '--no-spec', '--no-table'])
|
48
|
+
end
|
49
|
+
|
50
|
+
# Add validation to role model
|
51
|
+
role_model_file = File.join directory, 'app', 'models', "#{policy.resource}_role.rb"
|
52
|
+
File.open(role_model_file) do |f|
|
53
|
+
insert = " validates :permission, uniqueness: true"
|
54
|
+
inject_into_class(role_model_file, "#{policy.resource}_role".camelize, "#{insert}\n") unless f.read.include? insert
|
55
|
+
end
|
56
|
+
|
57
|
+
# Add policy column to user roles table
|
58
|
+
Dir.chdir(directory) do
|
59
|
+
args = %w[migration add column]
|
60
|
+
args << 'roles'
|
61
|
+
args << policy.resource
|
62
|
+
args << 'string'
|
63
|
+
args << %w[-o default:default]
|
64
|
+
args.flatten!
|
65
|
+
Eucalypt::CLI.start(args)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Generate permissions
|
69
|
+
options[:permissions].each do |permission|
|
70
|
+
Eucalypt::CLI.start(['security', 'policy', 'permission', 'generate', policy.resource, permission])
|
71
|
+
end
|
72
|
+
else
|
73
|
+
Eucalypt::Error.wrong_directory
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
#def destroy()
|
78
|
+
#end
|
79
|
+
|
80
|
+
class << self
|
81
|
+
require 'eucalypt/list'
|
82
|
+
include Eucalypt::List
|
83
|
+
def banner(task, namespace = false, subcommand = true)
|
84
|
+
"#{basename} security #{task.formatted_usage(self, true, subcommand).split(':').join(' ')}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
register(Eucalypt::SecurityPolicyPermission, 'permission', 'permission [COMMAND]', 'Pundit policy permission commands'.colorize(:grey))
|
89
|
+
register(Eucalypt::SecurityPolicyRole, 'role', 'role [COMMAND]', 'Pundit policy role commands'.colorize(:grey))
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_support/core_ext'
|
3
|
+
require 'thor'
|
4
|
+
require 'eucalypt/helpers'
|
5
|
+
|
6
|
+
module Eucalypt
|
7
|
+
module Generators
|
8
|
+
class Policy < Thor::Group
|
9
|
+
include Thor::Actions
|
10
|
+
include Eucalypt::Helpers
|
11
|
+
|
12
|
+
def self.source_root
|
13
|
+
File.join File.dirname(__dir__), 'templates'
|
14
|
+
end
|
15
|
+
|
16
|
+
def generate(name:)
|
17
|
+
policy = Inflect.new(:policy, name)
|
18
|
+
config = {class_name: policy.class_name, resource: policy.resource, constant: policy.constant}
|
19
|
+
template('policy.tt', policy.file_path, config)
|
20
|
+
end
|
21
|
+
|
22
|
+
def generate_policy_roles_migration(policy:)
|
23
|
+
sleep 1
|
24
|
+
migration = Eucalypt::Helpers::Migration[title: "create_#{policy}_roles", template: 'create_policy_roles_migration.tt']
|
25
|
+
return unless migration.create_anyway? if migration.exists?
|
26
|
+
config = {migration_title: migration.title.camelize, policy: policy}
|
27
|
+
template migration.template, migration.file_path, config
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class <%= config[:migration_title] %> < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
|
2
|
+
def change
|
3
|
+
create_table :<%= config[:policy] %>_roles do |t|
|
4
|
+
t.string :permission, null: false
|
5
|
+
t.boolean :admin, default: true
|
6
|
+
t.boolean :default, default: false
|
7
|
+
end
|
8
|
+
|
9
|
+
add_index :<%= config[:policy] %>_roles, :permission, unique: true
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class <%= config[:class_name] %>
|
2
|
+
attr_reader :user, :<%= config[:resource] %>
|
3
|
+
|
4
|
+
def initialize(user, <%= config[:resource] %>)
|
5
|
+
@user = user
|
6
|
+
@<%= config[:resource] %> = <%= config[:resource] %>
|
7
|
+
end
|
8
|
+
|
9
|
+
if ActiveRecord::Base.connection.table_exists?(:<%= config[:resource] %>_roles)
|
10
|
+
<%= config[:constant] %>Role.pluck(:permission).each do |permission|
|
11
|
+
define_method("#{permission}?") do
|
12
|
+
<%= config[:constant] %>Role.find_by(permission: permission).send(user.role.<%= config[:resource] %>)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'eucalypt/errors'
|
3
|
+
require 'eucalypt/helpers'
|
4
|
+
require 'eucalypt/eucalypt-security/namespaces/security-policy-permission/generators/policy-permission'
|
5
|
+
|
6
|
+
module Eucalypt
|
7
|
+
class SecurityPolicyPermission < Thor
|
8
|
+
include Thor::Actions
|
9
|
+
include Eucalypt::Helpers
|
10
|
+
using Colorize
|
11
|
+
|
12
|
+
desc "generate [POLICY] [PERMISSION]", "Create a new Pundit policy permission".colorize(:grey)
|
13
|
+
def generate(name, permission)
|
14
|
+
directory = File.expand_path('.')
|
15
|
+
if Eucalypt.app? directory
|
16
|
+
# Check for authorization gems
|
17
|
+
return unless Gemfile.check(%w[pundit], 'eucalypt security pundit setup', directory)
|
18
|
+
|
19
|
+
# Check for user model
|
20
|
+
unless File.exist? File.join(directory, 'app', 'models', 'user.rb')
|
21
|
+
Eucalypt::Error.no_user_model
|
22
|
+
return
|
23
|
+
end
|
24
|
+
|
25
|
+
# Check for role model
|
26
|
+
unless File.exist? File.join(directory, 'app', 'models', 'role.rb')
|
27
|
+
Eucalypt::Error.no_role_model
|
28
|
+
return
|
29
|
+
end
|
30
|
+
|
31
|
+
policy = Inflect.new(:policy, name)
|
32
|
+
|
33
|
+
# Check for policy file and policy role model
|
34
|
+
policy_file = File.join(directory, 'app', 'policies', policy.file_name)
|
35
|
+
policy_role_model = File.join(directory, 'app', 'models', "#{policy.resource}_role.rb")
|
36
|
+
unless File.exist?(policy_file) && File.exist?(policy_role_model)
|
37
|
+
Eucalypt::Error.no_policy(policy.resource)
|
38
|
+
return
|
39
|
+
end
|
40
|
+
|
41
|
+
policy_permission = Eucalypt::Generators::PolicyPermission.new
|
42
|
+
policy_permission.destination_root = directory
|
43
|
+
|
44
|
+
# Add permission record to policy role table
|
45
|
+
policy_permission.generate(policy_name: policy.resource, permission: Inflect.resource_keep_inflection(permission))
|
46
|
+
else
|
47
|
+
Eucalypt::Error.wrong_directory
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# def destroy()
|
52
|
+
# end
|
53
|
+
|
54
|
+
class << self
|
55
|
+
require 'eucalypt/list'
|
56
|
+
include Eucalypt::List
|
57
|
+
def banner(task, namespace = false, subcommand = true)
|
58
|
+
"#{basename} security policy #{task.formatted_usage(self, true, subcommand).split(':').join(' ')}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_support/core_ext'
|
3
|
+
require 'thor'
|
4
|
+
require 'eucalypt/helpers'
|
5
|
+
|
6
|
+
module Eucalypt
|
7
|
+
module Generators
|
8
|
+
class PolicyPermission < Thor::Group
|
9
|
+
include Thor::Actions
|
10
|
+
include Eucalypt::Helpers
|
11
|
+
|
12
|
+
def self.source_root
|
13
|
+
File.join File.dirname(__dir__), 'templates'
|
14
|
+
end
|
15
|
+
|
16
|
+
def generate(policy_name:, permission:)
|
17
|
+
sleep 1
|
18
|
+
migration = Eucalypt::Helpers::Migration[
|
19
|
+
title: "add_#{permission}_permission_to_#{policy_name}_policy",
|
20
|
+
template: 'add_permission_to_policy_migration.tt'
|
21
|
+
]
|
22
|
+
return unless migration.create_anyway? if migration.exists?
|
23
|
+
config = {migration_title: migration.title.camelize, policy_name: policy_name, permission: permission}
|
24
|
+
template migration.template, migration.file_path, config
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/eucalypt/eucalypt-security/namespaces/security-policy-role/cli/security-policy-role.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'eucalypt/errors'
|
3
|
+
require 'eucalypt/helpers'
|
4
|
+
|
5
|
+
module Eucalypt
|
6
|
+
class SecurityPolicyRole < Thor
|
7
|
+
include Thor::Actions
|
8
|
+
include Eucalypt::Helpers
|
9
|
+
using Colorize
|
10
|
+
|
11
|
+
desc "generate [POLICY] [ROLE]", "Create a new Pundit policy role".colorize(:grey)
|
12
|
+
def generate(name, role)
|
13
|
+
directory = File.expand_path('.')
|
14
|
+
if Eucalypt.app? directory
|
15
|
+
# Check for authorization gems
|
16
|
+
return unless Gemfile.check(%w[pundit], 'eucalypt security pundit setup', directory)
|
17
|
+
|
18
|
+
# Check for user model
|
19
|
+
unless File.exist? File.join(directory, 'app', 'models', 'user.rb')
|
20
|
+
Eucalypt::Error.no_user_model
|
21
|
+
return
|
22
|
+
end
|
23
|
+
|
24
|
+
# Check for role model
|
25
|
+
unless File.exist? File.join(directory, 'app', 'models', 'role.rb')
|
26
|
+
Eucalypt::Error.no_role_model
|
27
|
+
return
|
28
|
+
end
|
29
|
+
|
30
|
+
policy = Inflect.new(:policy, name)
|
31
|
+
|
32
|
+
# Check for policy file and policy role model
|
33
|
+
policy_file = File.join(directory, 'app', 'policies', policy.file_name)
|
34
|
+
policy_role_model = File.join(directory, 'app', 'models', "#{policy.resource}_role.rb")
|
35
|
+
unless File.exist?(policy_file) && File.exist?(policy_role_model)
|
36
|
+
Eucalypt::Error.no_policy(policy.resource)
|
37
|
+
return
|
38
|
+
end
|
39
|
+
|
40
|
+
# Add role column to policy roles table
|
41
|
+
Dir.chdir(directory) do
|
42
|
+
args = %w[migration add column]
|
43
|
+
args << "#{policy.resource}_roles"
|
44
|
+
args << Inflect.resource(role)
|
45
|
+
args << 'boolean'
|
46
|
+
args << %w[-o default:false]
|
47
|
+
args.flatten!
|
48
|
+
Eucalypt::CLI.start(args)
|
49
|
+
end
|
50
|
+
else
|
51
|
+
Eucalypt::Error.wrong_directory
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# def destroy()
|
56
|
+
# end
|
57
|
+
|
58
|
+
class << self
|
59
|
+
require 'eucalypt/list'
|
60
|
+
include Eucalypt::List
|
61
|
+
def banner(task, namespace = false, subcommand = true)
|
62
|
+
"#{basename} security policy #{task.formatted_usage(self, true, subcommand).split(':').join(' ')}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'eucalypt/helpers'
|
3
|
+
require 'eucalypt/eucalypt-security/helpers'
|
4
|
+
require 'eucalypt/eucalypt-security/namespaces/security-pundit/generators/role'
|
5
|
+
|
6
|
+
module Eucalypt
|
7
|
+
class SecurityPundit < Thor
|
8
|
+
include Thor::Actions
|
9
|
+
include Eucalypt::Helpers
|
10
|
+
include Eucalypt::Helpers::Messages
|
11
|
+
include Eucalypt::Helpers::Gemfile
|
12
|
+
include Eucalypt::Security::Helpers
|
13
|
+
using Colorize
|
14
|
+
|
15
|
+
def self.source_root
|
16
|
+
File.join File.dirname(__dir__), 'templates'
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "setup", "Set up Pundit authorization".colorize(:grey)
|
20
|
+
def setup
|
21
|
+
directory = File.expand_path('.')
|
22
|
+
if Eucalypt.app? directory
|
23
|
+
# Check if user model exists
|
24
|
+
user_model_file = File.join(directory, 'app', 'models', 'user.rb')
|
25
|
+
unless File.file? user_model_file
|
26
|
+
Eucalypt::Error.no_user_model
|
27
|
+
return
|
28
|
+
end
|
29
|
+
|
30
|
+
Out.setup "Setting up Pundit authorization..."
|
31
|
+
|
32
|
+
# Add Pundit to Gemfile
|
33
|
+
gemfile_add('Authorization', {pundit: '~> 2.0'}, directory)
|
34
|
+
|
35
|
+
# Create Pundit config file
|
36
|
+
create_config_file(:pundit, directory)
|
37
|
+
|
38
|
+
# Create roles migration
|
39
|
+
Eucalypt::Generators::Role.new.generate_roles_migration
|
40
|
+
|
41
|
+
# Create Role model
|
42
|
+
role_model_file = File.join(directory, 'app', 'models', 'role.rb')
|
43
|
+
Out.warning "Role model already exists." if File.file? role_model_file
|
44
|
+
Dir.chdir(directory) do
|
45
|
+
Eucalypt::CLI.start(%w[generate model role --no-spec --no-table])
|
46
|
+
end
|
47
|
+
|
48
|
+
# Add belongs_to to Role model
|
49
|
+
File.open(role_model_file) do |f|
|
50
|
+
insert = " belongs_to :user"
|
51
|
+
inject_into_class(role_model_file, 'Role', "#{insert}\n") unless f.read.include? insert
|
52
|
+
end
|
53
|
+
|
54
|
+
# Add relationship to User model
|
55
|
+
File.open(user_model_file) do |f|
|
56
|
+
contents = f.read
|
57
|
+
insert = " has_one :role, dependent: :destroy\n"
|
58
|
+
inject_into_file(user_model_file, insert, before: / include BCrypt/) unless contents.include? insert
|
59
|
+
insert = " after_save :create_role\n\n"
|
60
|
+
inject_into_file(user_model_file, insert, before: / include BCrypt/) unless contents.include? insert
|
61
|
+
insert = "\n private\n\n def create_role\n self.role = Role.new\n end\n"
|
62
|
+
inject_into_file(user_model_file, insert, before: /^end/) unless contents.include? insert
|
63
|
+
end
|
64
|
+
|
65
|
+
Out.info "Ensure you run `#{'rake db:migrate'.colorize(:bold)}` to create the necessary tables for Pundit."
|
66
|
+
else
|
67
|
+
Eucalypt::Error.wrong_directory
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class << self
|
72
|
+
require 'eucalypt/list'
|
73
|
+
include Eucalypt::List
|
74
|
+
def banner(task, namespace = false, subcommand = true)
|
75
|
+
"#{basename} security #{task.formatted_usage(self, true, subcommand).split(':').join(' ')}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_support/core_ext'
|
3
|
+
require 'thor'
|
4
|
+
require 'eucalypt/helpers'
|
5
|
+
|
6
|
+
module Eucalypt
|
7
|
+
module Generators
|
8
|
+
class Role < Thor::Group
|
9
|
+
include Thor::Actions
|
10
|
+
include Eucalypt::Helpers
|
11
|
+
|
12
|
+
def self.source_root
|
13
|
+
File.join File.dirname(__dir__), 'templates'
|
14
|
+
end
|
15
|
+
|
16
|
+
def generate_roles_migration
|
17
|
+
sleep 1
|
18
|
+
migration = Eucalypt::Helpers::Migration[title: "create_roles", template: 'create_roles_migration.tt']
|
19
|
+
return unless migration.create_anyway? if migration.exists?
|
20
|
+
template migration.template, migration.file_path
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'eucalypt/helpers'
|
3
|
+
require 'eucalypt/eucalypt-security/helpers'
|
4
|
+
require 'eucalypt/eucalypt-security/namespaces/security-warden/generators/user'
|
5
|
+
require 'eucalypt/eucalypt-security/namespaces/security-warden/generators/auth_controller'
|
6
|
+
|
7
|
+
module Eucalypt
|
8
|
+
class SecurityWarden < Thor
|
9
|
+
include Thor::Actions
|
10
|
+
include Eucalypt::Helpers
|
11
|
+
include Eucalypt::Helpers::Messages
|
12
|
+
include Eucalypt::Helpers::Gemfile
|
13
|
+
include Eucalypt::Security::Helpers
|
14
|
+
using Colorize
|
15
|
+
|
16
|
+
def self.source_root
|
17
|
+
File.join File.dirname(__dir__), 'templates'
|
18
|
+
end
|
19
|
+
|
20
|
+
option :controller, type: :boolean, default: true, desc: "Include an authentication controller"
|
21
|
+
desc "setup", "Set up Warden authentication".colorize(:grey)
|
22
|
+
def setup
|
23
|
+
directory = File.expand_path('.')
|
24
|
+
if Eucalypt.app? directory
|
25
|
+
Out.setup "Setting up Warden authentication..."
|
26
|
+
|
27
|
+
# Add Warden and BCrypt to Gemfile
|
28
|
+
gemfile_add('Authentication and encryption', {warden: '~> 1.2', bcrypt: '~> 3.1'}, directory)
|
29
|
+
|
30
|
+
# Create Warden config file
|
31
|
+
create_config_file(:warden, directory)
|
32
|
+
|
33
|
+
user = Eucalypt::Generators::User.new
|
34
|
+
|
35
|
+
# Create user migration
|
36
|
+
user.generate_migration
|
37
|
+
|
38
|
+
# Create user model
|
39
|
+
user.generate_model(directory)
|
40
|
+
|
41
|
+
if options[:controller]
|
42
|
+
auth_controller = Eucalypt::Generators::AuthController.new
|
43
|
+
auth_controller.destination_root = directory
|
44
|
+
auth_controller.generate
|
45
|
+
end
|
46
|
+
|
47
|
+
Out.info "Ensure you run `#{'rake db:migrate'.colorize(:bold)}` to create the necessary tables for Warden."
|
48
|
+
else
|
49
|
+
Eucalypt::Error.wrong_directory
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class << self
|
54
|
+
require 'eucalypt/list'
|
55
|
+
include Eucalypt::List
|
56
|
+
def banner(task, namespace = false, subcommand = true)
|
57
|
+
"#{basename} security #{task.formatted_usage(self, true, subcommand).split(':').join(' ')}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_support/core_ext'
|
3
|
+
require 'thor'
|
4
|
+
require 'eucalypt/helpers'
|
5
|
+
|
6
|
+
module Eucalypt
|
7
|
+
module Generators
|
8
|
+
class AuthController < Thor::Group
|
9
|
+
include Thor::Actions
|
10
|
+
include Eucalypt::Helpers
|
11
|
+
using String::Builder
|
12
|
+
|
13
|
+
def self.source_root
|
14
|
+
File.join File.dirname(__dir__), 'templates'
|
15
|
+
end
|
16
|
+
|
17
|
+
def generate
|
18
|
+
template 'auth_controller.tt', File.join('app', 'controllers', 'authentication_controller.rb')
|
19
|
+
|
20
|
+
config = {}
|
21
|
+
config[:data] = String.build do |s|
|
22
|
+
s << "<%=\n"
|
23
|
+
s << " form_for :user, '/auth/login' do\n"
|
24
|
+
s << " text_field :username\n"
|
25
|
+
s << " password_field :password\n"
|
26
|
+
s << " submit 'Login'\n"
|
27
|
+
s << " end\n"
|
28
|
+
s << "%>"
|
29
|
+
end
|
30
|
+
template 'auth_login.tt', File.join('app', 'views', 'authentication', 'login.erb'), config
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_support/core_ext'
|
3
|
+
require 'thor'
|
4
|
+
require 'eucalypt/helpers'
|
5
|
+
require 'active_record'
|
6
|
+
|
7
|
+
module Eucalypt
|
8
|
+
module Generators
|
9
|
+
class User < Thor::Group
|
10
|
+
include Thor::Actions
|
11
|
+
include Eucalypt::Helpers
|
12
|
+
include Eucalypt::Helpers::Messages
|
13
|
+
|
14
|
+
def self.source_root
|
15
|
+
File.join File.dirname(__dir__), 'templates'
|
16
|
+
end
|
17
|
+
|
18
|
+
def generate_migration
|
19
|
+
sleep 1
|
20
|
+
migration = Eucalypt::Helpers::Migration[title: 'create_users', template: 'create_users_table_migration.tt']
|
21
|
+
return unless migration.create_anyway? if migration.exists?
|
22
|
+
template migration.template, migration.file_path
|
23
|
+
end
|
24
|
+
|
25
|
+
def generate_model(directory)
|
26
|
+
model_file = File.join(directory, 'app', 'models', 'user.rb')
|
27
|
+
|
28
|
+
if File.file? model_file
|
29
|
+
Out.warning 'User model already exists.'
|
30
|
+
return
|
31
|
+
end
|
32
|
+
|
33
|
+
template 'user.tt', model_file
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class AuthenticationController < Eucalypt::Controller(route: '/auth')
|
2
|
+
helpers AuthenticationHelper if defined? AuthenticationHelper
|
3
|
+
|
4
|
+
get '/login' do
|
5
|
+
redirect '/' if current_user
|
6
|
+
erb :'authentication/login', layout: false
|
7
|
+
end
|
8
|
+
|
9
|
+
post '/login' do
|
10
|
+
redirect '/' if current_user
|
11
|
+
authenticate
|
12
|
+
redirect session[:return_to] || '/'
|
13
|
+
end
|
14
|
+
|
15
|
+
get '/logout' do
|
16
|
+
env['warden'].logout
|
17
|
+
redirect to '/login'
|
18
|
+
end
|
19
|
+
|
20
|
+
post '/invalid' do
|
21
|
+
session[:return_to] = env['warden.options'][:attempted_path]
|
22
|
+
status 403 # Unauthenticated
|
23
|
+
redirect to '/login'
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= config[:data] %>
|