eucalypt 0.8.0 → 0.9.0
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/LICENSE +2 -2
- data/README.md +27 -4
- data/lib/eucalypt.rb +0 -1
- data/lib/eucalypt/core/cli/init.rb +0 -7
- data/lib/eucalypt/errors.rb +0 -24
- data/lib/eucalypt/generate/namespaces/generate-controller/cli/generate-controller.rb +1 -3
- data/lib/eucalypt/generate/namespaces/generate-controller/generators/controller.rb +2 -4
- data/lib/eucalypt/generate/namespaces/generate/cli/generate-scaffold.rb +1 -15
- data/lib/eucalypt/helpers/inflect.rb +1 -1
- data/lib/eucalypt/load.rb +1 -3
- data/lib/eucalypt/migration/namespaces/migration/cli/migration.rb +1 -0
- data/lib/eucalypt/version.rb +1 -1
- metadata +2 -28
- data/lib/eucalypt/generate/namespaces/generate-controller/templates/controller/policy_rest_controller.tt +0 -96
- data/lib/eucalypt/security/confirm.rb +0 -38
- data/lib/eucalypt/security/helpers.rb +0 -22
- data/lib/eucalypt/security/namespaces/security-policy-permission/cli/security-policy-permission.rb +0 -60
- data/lib/eucalypt/security/namespaces/security-policy-permission/generators/policy-permission.rb +0 -28
- data/lib/eucalypt/security/namespaces/security-policy-permission/templates/add_permission_to_policy_migration.tt +0 -5
- data/lib/eucalypt/security/namespaces/security-policy-role/cli/security-policy-role.rb +0 -64
- data/lib/eucalypt/security/namespaces/security-policy/cli/security-policy.rb +0 -81
- data/lib/eucalypt/security/namespaces/security-policy/generators/policy.rb +0 -41
- data/lib/eucalypt/security/namespaces/security-policy/templates/create_policy_roles_migration.tt +0 -11
- data/lib/eucalypt/security/namespaces/security-policy/templates/policy.tt +0 -8
- data/lib/eucalypt/security/namespaces/security-policy/templates/policy_role.tt +0 -3
- data/lib/eucalypt/security/namespaces/security-pundit/cli/security-pundit.rb +0 -77
- data/lib/eucalypt/security/namespaces/security-pundit/generators/role.rb +0 -24
- data/lib/eucalypt/security/namespaces/security-pundit/templates/create_roles_migration.tt +0 -7
- data/lib/eucalypt/security/namespaces/security-pundit/templates/pundit.tt +0 -11
- data/lib/eucalypt/security/namespaces/security-warden/cli/security-warden.rb +0 -77
- data/lib/eucalypt/security/namespaces/security-warden/generators/auth_controller.rb +0 -34
- data/lib/eucalypt/security/namespaces/security-warden/generators/user.rb +0 -37
- data/lib/eucalypt/security/namespaces/security-warden/templates/auth_controller.tt +0 -25
- data/lib/eucalypt/security/namespaces/security-warden/templates/auth_login.tt +0 -1
- data/lib/eucalypt/security/namespaces/security-warden/templates/create_users_table_migration.tt +0 -9
- data/lib/eucalypt/security/namespaces/security-warden/templates/user.tt +0 -16
- data/lib/eucalypt/security/namespaces/security-warden/templates/warden.tt +0 -35
- data/lib/eucalypt/security/namespaces/security/cli/security.rb +0 -29
- data/lib/eucalypt/security/permissions.rb +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '059e655c54b7cb64868221dfe948c1463bc3b11b50ab52ad633911f5b39b94f0'
|
4
|
+
data.tar.gz: adcb2767cda8d8645c7fc364076010a1240d12a6ee660e375a6b145986d7eb2e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49fcbe9658765775d525f96636756b6f7a7d1021b3ca4d9733345c5bfbf527d0ddbfd858d8e0112bdd9f1158050ff77d373856e9bdebafb3ae1ccc58822f8796
|
7
|
+
data.tar.gz: 1852878c661320e2a65cb5593decadc5dc3bfafe77b3cb4e1a374c902cf2868557be5acc68186a95c32a35ab7da3e15e07a4f8591607ffb222cc14dbb2f98d89
|
data/LICENSE
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
MIT License
|
2
2
|
|
3
|
-
Copyright (c) 2018-2020 Edwin Onuonga
|
3
|
+
Copyright (c) 2018-2020 Edwin Onuonga <ed@eonu.net>
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
18
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
-
SOFTWARE.
|
21
|
+
SOFTWARE.
|
data/README.md
CHANGED
@@ -104,11 +104,34 @@ The structure of a generated application looks like the following:
|
|
104
104
|
| JS compressing | [Uglifier](https://github.com/lautis/uglifier) |
|
105
105
|
| Logging | [Lumberjack](https://github.com/bdurand/lumberjack) |
|
106
106
|
| Specs | [RSpec](http://rspec.info/) + [Rack-Test](https://github.com/rack-test/rack-test) + [Shoulda-Matchers](http://matchers.shoulda.io/) |
|
107
|
-
| Encryption | [BCrypt](https://github.com/codahale/bcrypt-ruby) |
|
108
|
-
| Authentication | [Warden](https://github.com/wardencommunity/warden) |
|
109
|
-
| Authorization | [Pundit](https://github.com/varvet/pundit) |
|
110
107
|
|
111
|
-
|
108
|
+
# Contributors
|
109
|
+
|
110
|
+
<table>
|
111
|
+
<thead>
|
112
|
+
<tr>
|
113
|
+
<th align="center">
|
114
|
+
<a href="https://github.com/eonu">
|
115
|
+
<img src="https://avatars0.githubusercontent.com/u/24795571?s=460&v=4" alt="Edwin Onuonga" width="60px">
|
116
|
+
<br/><sub><b>Edwin Onuonga</b></sub>
|
117
|
+
</a>
|
118
|
+
<br/>
|
119
|
+
<a href="mailto:ed@eonu.net">✉️</a>
|
120
|
+
<a href="https://eonu.net">🌍</a>
|
121
|
+
</th>
|
122
|
+
<th align="center">
|
123
|
+
<a href="https://github.com/ahmgeek">
|
124
|
+
<img src="https://avatars3.githubusercontent.com/u/4132009?s=460&v=4" alt="Ahmad" width="60px">
|
125
|
+
<br/><sub><b>Ahmad</b></sub>
|
126
|
+
</a>
|
127
|
+
<br/>
|
128
|
+
<a href="mailto:ahmgeek@icloud.com">✉️</a>
|
129
|
+
<a href="https://ahmgeek.com/">🌍</a>
|
130
|
+
</th>
|
131
|
+
<!-- Add more <th></th> blocks for more contributors -->
|
132
|
+
</tr>
|
133
|
+
</thead>
|
134
|
+
</table>
|
112
135
|
|
113
136
|
<p align="center">
|
114
137
|
<b>Eucalypt</b> © 2018-2020, Edwin Onuonga - Released under the <a href="http://mit-license.org/">MIT</a> License.<br/>
|
data/lib/eucalypt.rb
CHANGED
@@ -3,7 +3,6 @@ require 'eucalypt/core/cli/core'
|
|
3
3
|
require 'eucalypt/blog/namespaces/blog/cli/blog'
|
4
4
|
require 'eucalypt/generate/namespaces/generate/cli/generate'
|
5
5
|
require 'eucalypt/destroy/namespaces/destroy/cli/destroy'
|
6
|
-
require 'eucalypt/security/namespaces/security/cli/security'
|
7
6
|
require 'eucalypt/migration/namespaces/migration/cli/migration'
|
8
7
|
require 'eucalypt/static'
|
9
8
|
require 'eucalypt/controller'
|
@@ -10,8 +10,6 @@ module Eucalypt
|
|
10
10
|
option :blog, type: :boolean, default: false, aliases: '-b', desc: 'Set up the blog environment'
|
11
11
|
option :route, type: :string, default: 'blog', aliases: '-r', desc: 'Specify a route for the blog application'
|
12
12
|
option :silence, type: :boolean, default: false, aliases: '-s', desc: 'Silence `git init` and `bundle install` commands'
|
13
|
-
option :warden, type: :boolean, default: false, aliases: '-w', desc: 'Set up Warden authentication'
|
14
|
-
option :pundit, type: :boolean, default: false, aliases: '-p', desc: 'Set up Pundit authorization'
|
15
13
|
desc "init [NAME]", "Sets up your application".colorize(:grey)
|
16
14
|
def init(name)
|
17
15
|
current_directory = File.expand_path ?.
|
@@ -56,11 +54,6 @@ module Eucalypt
|
|
56
54
|
end
|
57
55
|
end
|
58
56
|
|
59
|
-
inside(root) do
|
60
|
-
Eucalypt::CLI.start %w[security warden setup] if options[:warden]
|
61
|
-
Eucalypt::CLI.start %w[security pundit setup] if options[:warden] && options[:pundit]
|
62
|
-
end
|
63
|
-
|
64
57
|
puts if options[:git] || options[:bundle]
|
65
58
|
inside(root) { run(options[:silence] ? 'git init --quiet' : 'git init') } if options[:git]
|
66
59
|
puts if options[:git] && options[:bundle]
|
data/lib/eucalypt/errors.rb
CHANGED
@@ -54,30 +54,6 @@ module Eucalypt
|
|
54
54
|
puts " - Ensure you have run the setup command `#{command.colorize(:bold)}`."
|
55
55
|
end
|
56
56
|
|
57
|
-
def no_user_model
|
58
|
-
Out.error "Couldn't find a user model."
|
59
|
-
puts
|
60
|
-
Out.info
|
61
|
-
command = 'eucalypt security warden setup'
|
62
|
-
puts " - Ensure you have run the setup command `#{command.colorize(:bold)}`."
|
63
|
-
end
|
64
|
-
|
65
|
-
def no_role_model
|
66
|
-
Out.error "Couldn't find a role model."
|
67
|
-
puts
|
68
|
-
Out.info
|
69
|
-
command = 'eucalypt security pundit setup'
|
70
|
-
puts " - Ensure you have run the setup command `#{command.colorize(:bold)}`."
|
71
|
-
end
|
72
|
-
|
73
|
-
def no_policy(policy_name)
|
74
|
-
Out.error "Couldn't find a #{policy_name} role model or policy file."
|
75
|
-
puts
|
76
|
-
Out.info
|
77
|
-
command = "eucalypt security policy g #{policy_name}"
|
78
|
-
puts " - Ensure you have run the setup command `#{command.colorize(:bold)}`."
|
79
|
-
end
|
80
|
-
|
81
57
|
def invalid_columns(invalid_declarations, invalid_types)
|
82
58
|
puts if invalid_declarations.any? || invalid_types.any?
|
83
59
|
if invalid_declarations.any?
|
@@ -14,13 +14,12 @@ module Eucalypt
|
|
14
14
|
File.join File.dirname(__dir__), 'templates'
|
15
15
|
end
|
16
16
|
|
17
|
-
def generate(spec: true, rest: false,
|
17
|
+
def generate(spec: true, rest: false, name:)
|
18
18
|
controller = Inflect.new(:controller, name)
|
19
19
|
|
20
20
|
route = '/' << (rest ? controller.route_name.pluralize : controller.route_name)
|
21
21
|
|
22
22
|
controller_file_name = String.build do |s|
|
23
|
-
s << 'policy_' if policy
|
24
23
|
s << 'rest_' if rest
|
25
24
|
s << 'controller.tt'
|
26
25
|
end
|
@@ -34,8 +33,7 @@ module Eucalypt
|
|
34
33
|
class_name: controller.class_name,
|
35
34
|
helper_class_name: helper.class_name,
|
36
35
|
resource: controller.resource,
|
37
|
-
resources: controller.resources
|
38
|
-
headless: headless
|
36
|
+
resources: controller.resources
|
39
37
|
}
|
40
38
|
|
41
39
|
template(controller_template, controller.file_path, config)
|
@@ -9,8 +9,6 @@ module Eucalypt
|
|
9
9
|
|
10
10
|
option :no, aliases: '-n', type: :array, default: [], enum: %w[m ms c cs h hs], desc: "Omit specified scaffold files"
|
11
11
|
option :rest, aliases: '-r', type: :boolean, default: false, desc: "Generate REST routes for the controller"
|
12
|
-
option :policy, aliases: '-p', type: :boolean, default: false, desc: "Generate a policy with the scaffold"
|
13
|
-
option :headless, type: :boolean, aliases: '-H', default: false, desc: "Policy with no associated model"
|
14
12
|
option :table, type: :boolean, default: true, desc: "Generate a table migration"
|
15
13
|
desc "scaffold [NAME] *[COLUMN∶TYPE]", "Generates a scaffold".colorize(:grey)
|
16
14
|
def scaffold(name, *columns)
|
@@ -40,24 +38,12 @@ module Eucalypt
|
|
40
38
|
if controller
|
41
39
|
controller = Eucalypt::Generators::Controller.new
|
42
40
|
controller.destination_root = directory
|
43
|
-
policy = options[:rest] && options[:policy]
|
44
|
-
headless = options[:policy] && options[:headless]
|
45
41
|
controller.generate(
|
46
42
|
name: name,
|
47
43
|
spec: controller_spec,
|
48
|
-
rest: options[:rest]
|
49
|
-
policy: policy,
|
50
|
-
headless: headless
|
44
|
+
rest: options[:rest]
|
51
45
|
)
|
52
46
|
end
|
53
|
-
|
54
|
-
if options[:policy]
|
55
|
-
args = ['security', 'policy', 'generate', name]
|
56
|
-
args << '--headless' if options[:headless]
|
57
|
-
args << %w[-p read add edit delete] if options[:rest]
|
58
|
-
args.flatten!
|
59
|
-
Eucalypt::CLI.start(args)
|
60
|
-
end
|
61
47
|
else
|
62
48
|
Eucalypt::Error.wrong_directory
|
63
49
|
end
|
data/lib/eucalypt/load.rb
CHANGED
@@ -10,9 +10,7 @@ ApplicationController.helpers ApplicationHelper if defined? ApplicationHelper
|
|
10
10
|
|
11
11
|
Eucalypt.require 'app', 'helpers', '{main_helper.rb}'
|
12
12
|
Eucalypt.require 'app', 'controllers', 'main_controller.rb'
|
13
|
-
Eucalypt.require 'app', '{models
|
14
|
-
Eucalypt.require 'app', '{models,policies,helpers,controllers}', '*.rb'
|
13
|
+
Eucalypt.require 'app', '{models,helpers,controllers}', '*.rb'
|
15
14
|
|
16
|
-
require 'eucalypt/security/permissions'
|
17
15
|
require 'eucalypt/core/helpers/default_index'
|
18
16
|
require 'eucalypt/core/helpers/maintenance'
|
data/lib/eucalypt/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eucalypt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Edwin Onuonga
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-07-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -268,7 +268,6 @@ files:
|
|
268
268
|
- lib/eucalypt/generate/namespaces/generate-controller/cli/generate-controller.rb
|
269
269
|
- lib/eucalypt/generate/namespaces/generate-controller/generators/controller.rb
|
270
270
|
- lib/eucalypt/generate/namespaces/generate-controller/templates/controller/controller.tt
|
271
|
-
- lib/eucalypt/generate/namespaces/generate-controller/templates/controller/policy_rest_controller.tt
|
272
271
|
- lib/eucalypt/generate/namespaces/generate-controller/templates/controller/rest_controller.tt
|
273
272
|
- lib/eucalypt/generate/namespaces/generate-controller/templates/controller_spec.tt
|
274
273
|
- lib/eucalypt/generate/namespaces/generate-helper/cli/generate-helper.rb
|
@@ -321,31 +320,6 @@ files:
|
|
321
320
|
- lib/eucalypt/migration/namespaces/migration-rename/generators/table.rb
|
322
321
|
- lib/eucalypt/migration/namespaces/migration/cli/migration.rb
|
323
322
|
- lib/eucalypt/root.rb
|
324
|
-
- lib/eucalypt/security/confirm.rb
|
325
|
-
- lib/eucalypt/security/helpers.rb
|
326
|
-
- lib/eucalypt/security/namespaces/security-policy-permission/cli/security-policy-permission.rb
|
327
|
-
- lib/eucalypt/security/namespaces/security-policy-permission/generators/policy-permission.rb
|
328
|
-
- lib/eucalypt/security/namespaces/security-policy-permission/templates/add_permission_to_policy_migration.tt
|
329
|
-
- lib/eucalypt/security/namespaces/security-policy-role/cli/security-policy-role.rb
|
330
|
-
- lib/eucalypt/security/namespaces/security-policy/cli/security-policy.rb
|
331
|
-
- lib/eucalypt/security/namespaces/security-policy/generators/policy.rb
|
332
|
-
- lib/eucalypt/security/namespaces/security-policy/templates/create_policy_roles_migration.tt
|
333
|
-
- lib/eucalypt/security/namespaces/security-policy/templates/policy.tt
|
334
|
-
- lib/eucalypt/security/namespaces/security-policy/templates/policy_role.tt
|
335
|
-
- lib/eucalypt/security/namespaces/security-pundit/cli/security-pundit.rb
|
336
|
-
- lib/eucalypt/security/namespaces/security-pundit/generators/role.rb
|
337
|
-
- lib/eucalypt/security/namespaces/security-pundit/templates/create_roles_migration.tt
|
338
|
-
- lib/eucalypt/security/namespaces/security-pundit/templates/pundit.tt
|
339
|
-
- lib/eucalypt/security/namespaces/security-warden/cli/security-warden.rb
|
340
|
-
- lib/eucalypt/security/namespaces/security-warden/generators/auth_controller.rb
|
341
|
-
- lib/eucalypt/security/namespaces/security-warden/generators/user.rb
|
342
|
-
- lib/eucalypt/security/namespaces/security-warden/templates/auth_controller.tt
|
343
|
-
- lib/eucalypt/security/namespaces/security-warden/templates/auth_login.tt
|
344
|
-
- lib/eucalypt/security/namespaces/security-warden/templates/create_users_table_migration.tt
|
345
|
-
- lib/eucalypt/security/namespaces/security-warden/templates/user.tt
|
346
|
-
- lib/eucalypt/security/namespaces/security-warden/templates/warden.tt
|
347
|
-
- lib/eucalypt/security/namespaces/security/cli/security.rb
|
348
|
-
- lib/eucalypt/security/permissions.rb
|
349
323
|
- lib/eucalypt/static.rb
|
350
324
|
- lib/eucalypt/version.rb
|
351
325
|
homepage: https://eucalypt.gitbook.io/eucalypt
|
@@ -1,96 +0,0 @@
|
|
1
|
-
class <%= config[:class_name] %> < Eucalypt::Controller(route: '<%= config[:route] %>')
|
2
|
-
helpers <%= config[:helper_class_name] %> if defined? <%= config[:helper_class_name] %>
|
3
|
-
|
4
|
-
# You can use the following authentication helper methods in your views:
|
5
|
-
# `current_user` - The User model object for the current user.
|
6
|
-
# `authenticated?` (alias `logged_in?`) - Whether or not a user is logged in.
|
7
|
-
|
8
|
-
# You can also use authorization helpers in your views.
|
9
|
-
# These are useful for conditional displays to users with the correct permissions.
|
10
|
-
# - e.g. Showing a form for editing <%= config[:resources] %>
|
11
|
-
<% if config[:headless] %>
|
12
|
-
# Authorization helpers are used in the following way (if using headless policies):
|
13
|
-
# - `authorized?(:<%= config[:resource] %>, :read?)`
|
14
|
-
# - `authorized?(:<%= config[:resource] %>, :add?)`
|
15
|
-
# - `authorized?(:<%= config[:resource] %>, :edit?)`
|
16
|
-
# - `authorized?(:<%= config[:resource] %>, :delete?)`
|
17
|
-
<% else %>
|
18
|
-
# Authorization helpers are used in the following way:
|
19
|
-
# - `authorized?(<%= config[:constant] %>, :read?)`
|
20
|
-
# - `authorized?(<%= config[:constant] %>, :add?)`
|
21
|
-
# - `authorized?(<%= config[:constant] %>, :edit?)`
|
22
|
-
# - `authorized?(<%= config[:constant] %>, :delete?)`
|
23
|
-
<% end %>
|
24
|
-
# GET - Browse
|
25
|
-
get '/' do
|
26
|
-
# NOTE: To skip browse permission checks, comment out the `authenticate` and `authorize` lines.
|
27
|
-
authenticate
|
28
|
-
authorize <%= config[:constant] %>, :read?
|
29
|
-
@<%= config[:resources] %> = <%= config[:constant] %>.all
|
30
|
-
# Render the <%= config[:resources] %> as JSON, or create a view
|
31
|
-
content_type :json
|
32
|
-
@<%= config[:resources] %>.to_json
|
33
|
-
rescue Pundit::NotAuthorizedError
|
34
|
-
status 401 # Unauthorized
|
35
|
-
redirect '/'
|
36
|
-
end
|
37
|
-
|
38
|
-
# GET - Read
|
39
|
-
get '/:id' do |id|
|
40
|
-
# NOTE: To skip read permission checks, comment out the `authenticate` and `authorize` lines.
|
41
|
-
authenticate
|
42
|
-
@<%= config[:resource] %> = <%= config[:constant] %>.find id
|
43
|
-
authorize @<%= config[:resource] %>, :read?
|
44
|
-
# Render the <%= config[:resource] %> as JSON, or create a view
|
45
|
-
content_type :json
|
46
|
-
@<%= config[:resource] %>.to_json
|
47
|
-
rescue ActiveRecord::RecordNotFound
|
48
|
-
status 404 # Resource not found
|
49
|
-
redirect to '/'
|
50
|
-
rescue Pundit::NotAuthorizedError
|
51
|
-
status 401 # Unauthorized
|
52
|
-
redirect to '/'
|
53
|
-
end
|
54
|
-
|
55
|
-
# POST - Edit
|
56
|
-
post '/:id/edit' do |id|
|
57
|
-
authenticate
|
58
|
-
<%= config[:resource] %> = <%= config[:constant] %>.find id
|
59
|
-
authorize <%= config[:resource] %>, :edit?
|
60
|
-
<%= config[:resource] %>.update! params['<%= config[:resource] %>']
|
61
|
-
redirect to "/#{id}"
|
62
|
-
rescue ActiveRecord::RecordNotFound
|
63
|
-
status 404 # Resource not found
|
64
|
-
redirect to "/#{id}"
|
65
|
-
rescue Pundit::NotAuthorizedError
|
66
|
-
status 401 # Unauthorized
|
67
|
-
redirect to '/'
|
68
|
-
end
|
69
|
-
|
70
|
-
# POST - Add
|
71
|
-
post '/' do
|
72
|
-
authenticate
|
73
|
-
<%= config[:resource] %> = <%= config[:constant] %>.new params['<%= config[:resource] %>']
|
74
|
-
authorize <%= config[:resource] %>, :add?
|
75
|
-
<%= config[:resource] %>.save!
|
76
|
-
redirect to "/#{<%= config[:resource] %>.id}"
|
77
|
-
rescue Pundit::NotAuthorizedError
|
78
|
-
status 401 # Unauthorized
|
79
|
-
redirect to '/'
|
80
|
-
end
|
81
|
-
|
82
|
-
# POST - Delete
|
83
|
-
post '/:id/delete' do |id|
|
84
|
-
authenticate
|
85
|
-
<%= config[:resource] %> = <%= config[:constant] %>.find id
|
86
|
-
authorize <%= config[:resource] %>, :delete?
|
87
|
-
<%= config[:resource] %>.destroy!
|
88
|
-
redirect to '/'
|
89
|
-
rescue ActiveRecord::RecordNotFound
|
90
|
-
status 404 # Resource not found
|
91
|
-
redirect to "/#{id}"
|
92
|
-
rescue Pundit::NotAuthorizedError
|
93
|
-
status 401 # Unauthorized
|
94
|
-
redirect to '/'
|
95
|
-
end
|
96
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
class User < ActiveRecord::Base
|
2
|
-
def with_confirm(*fields)
|
3
|
-
return if fields.empty?
|
4
|
-
fields.map(&:to_sym).each {|field| instance_variable_set "@with_confirm_#{field}", true }
|
5
|
-
class_eval do
|
6
|
-
attr_accessor *fields.map {|field| "#{field}_confirmation".to_sym }
|
7
|
-
attr_reader *fields.map {|field| field.to_sym }.reject {|field| field != :password}
|
8
|
-
end
|
9
|
-
|
10
|
-
fields.each do |field|
|
11
|
-
confirm = "confirm_#{field}".to_sym
|
12
|
-
define_singleton_method confirm do
|
13
|
-
if instance_variable_get "@with_#{confirm}"
|
14
|
-
case field
|
15
|
-
when :password
|
16
|
-
return if @password.nil?
|
17
|
-
unless authenticate @password_confirmation
|
18
|
-
errors.add :password_confirmation, "Passwords don't match"
|
19
|
-
end
|
20
|
-
else
|
21
|
-
actual = self.send field
|
22
|
-
return if actual.nil?
|
23
|
-
confirmation = instance_variable_get "@#{field}_confirmation"
|
24
|
-
unless actual == confirmation
|
25
|
-
errors.add "#{field}_confirmation", "#{field.to_s.pluralize.capitalize} don't match"
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
class_eval do
|
32
|
-
private confirm
|
33
|
-
validate confirm
|
34
|
-
end
|
35
|
-
end
|
36
|
-
self
|
37
|
-
end
|
38
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
require 'active_support'
|
2
|
-
require 'active_support/core_ext'
|
3
|
-
require 'thor'
|
4
|
-
require 'eucalypt/helpers'
|
5
|
-
require '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
|
data/lib/eucalypt/security/namespaces/security-policy-permission/cli/security-policy-permission.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
require 'thor'
|
2
|
-
require 'eucalypt/errors'
|
3
|
-
require 'eucalypt/helpers'
|
4
|
-
require 'eucalypt/security/namespaces/security-policy-permission/generators/policy-permission'
|
5
|
-
require 'eucalypt/list'
|
6
|
-
|
7
|
-
module Eucalypt
|
8
|
-
class SecurityPolicyPermission < Thor
|
9
|
-
include Thor::Actions
|
10
|
-
include Eucalypt::Helpers
|
11
|
-
using Colorize
|
12
|
-
extend Eucalypt::List
|
13
|
-
|
14
|
-
desc "generate [POLICY] [PERMISSION]", "Create a new Pundit policy permission".colorize(:grey)
|
15
|
-
def generate(name, permission)
|
16
|
-
directory = File.expand_path('.')
|
17
|
-
if Eucalypt.app? directory
|
18
|
-
# Check for authorization gems
|
19
|
-
return unless Gemfile.check(%w[pundit], 'eucalypt security pundit setup', directory)
|
20
|
-
|
21
|
-
# Check for user model
|
22
|
-
unless File.exist? File.join(directory, 'app', 'models', 'user.rb')
|
23
|
-
Eucalypt::Error.no_user_model
|
24
|
-
return
|
25
|
-
end
|
26
|
-
|
27
|
-
# Check for role model
|
28
|
-
unless File.exist? File.join(directory, 'app', 'models', 'role.rb')
|
29
|
-
Eucalypt::Error.no_role_model
|
30
|
-
return
|
31
|
-
end
|
32
|
-
|
33
|
-
policy = Inflect.new(:policy, name)
|
34
|
-
|
35
|
-
# Check for policy file and policy role model
|
36
|
-
policy_file = File.join(directory, 'app', 'policies', policy.file_name)
|
37
|
-
policy_role_model = File.join(directory, 'app', 'models', 'roles', "#{policy.resource}_role.rb")
|
38
|
-
unless File.exist?(policy_file) && File.exist?(policy_role_model)
|
39
|
-
Eucalypt::Error.no_policy(policy.resource)
|
40
|
-
return
|
41
|
-
end
|
42
|
-
|
43
|
-
policy_permission = Eucalypt::Generators::PolicyPermission.new
|
44
|
-
policy_permission.destination_root = directory
|
45
|
-
|
46
|
-
# Add permission record to policy role table
|
47
|
-
policy_permission.generate(policy_name: policy.resource, permission: Inflect.resource_keep_inflection(permission))
|
48
|
-
else
|
49
|
-
Eucalypt::Error.wrong_directory
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
# def destroy()
|
54
|
-
# end
|
55
|
-
|
56
|
-
def self.banner(task, namespace = false, subcommand = true)
|
57
|
-
"#{basename} security policy #{task.formatted_usage(self, true, subcommand).split(':').join(' ')}"
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
data/lib/eucalypt/security/namespaces/security-policy-permission/generators/policy-permission.rb
DELETED
@@ -1,28 +0,0 @@
|
|
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
|
@@ -1,64 +0,0 @@
|
|
1
|
-
require 'thor'
|
2
|
-
require 'eucalypt/errors'
|
3
|
-
require 'eucalypt/helpers'
|
4
|
-
require 'eucalypt/list'
|
5
|
-
|
6
|
-
module Eucalypt
|
7
|
-
class SecurityPolicyRole < Thor
|
8
|
-
include Thor::Actions
|
9
|
-
include Eucalypt::Helpers
|
10
|
-
using Colorize
|
11
|
-
extend Eucalypt::List
|
12
|
-
|
13
|
-
desc "generate [POLICY] [ROLE]", "Create a new Pundit policy role".colorize(:grey)
|
14
|
-
def generate(name, role)
|
15
|
-
directory = File.expand_path('.')
|
16
|
-
if Eucalypt.app? directory
|
17
|
-
# Check for authorization gems
|
18
|
-
return unless Gemfile.check(%w[pundit], 'eucalypt security pundit setup', directory)
|
19
|
-
|
20
|
-
# Check for user model
|
21
|
-
unless File.exist? File.join(directory, 'app', 'models', 'user.rb')
|
22
|
-
Eucalypt::Error.no_user_model
|
23
|
-
return
|
24
|
-
end
|
25
|
-
|
26
|
-
# Check for role model
|
27
|
-
unless File.exist? File.join(directory, 'app', 'models', 'role.rb')
|
28
|
-
Eucalypt::Error.no_role_model
|
29
|
-
return
|
30
|
-
end
|
31
|
-
|
32
|
-
policy = Inflect.new(:policy, name)
|
33
|
-
|
34
|
-
# Check for policy file and policy role model
|
35
|
-
policy_file = File.join(directory, 'app', 'policies', policy.file_name)
|
36
|
-
policy_role_model = File.join(directory, 'app', 'models', 'roles', "#{policy.resource}_role.rb")
|
37
|
-
unless File.exist?(policy_file) && File.exist?(policy_role_model)
|
38
|
-
Eucalypt::Error.no_policy(policy.resource)
|
39
|
-
return
|
40
|
-
end
|
41
|
-
|
42
|
-
# Add role column to policy roles table
|
43
|
-
Dir.chdir(directory) do
|
44
|
-
args = %w[migration add column]
|
45
|
-
args << "#{policy.resource}_roles"
|
46
|
-
args << Inflect.resource(role)
|
47
|
-
args << 'boolean'
|
48
|
-
args << %w[-o default:false]
|
49
|
-
args.flatten!
|
50
|
-
Eucalypt::CLI.start(args)
|
51
|
-
end
|
52
|
-
else
|
53
|
-
Eucalypt::Error.wrong_directory
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
# def destroy()
|
58
|
-
# end
|
59
|
-
|
60
|
-
def self.banner(task, namespace = false, subcommand = true)
|
61
|
-
"#{basename} security policy #{task.formatted_usage(self, true, subcommand).split(':').join(' ')}"
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
@@ -1,81 +0,0 @@
|
|
1
|
-
require 'thor'
|
2
|
-
require 'eucalypt/errors'
|
3
|
-
require 'eucalypt/helpers'
|
4
|
-
require 'eucalypt/security/namespaces/security-policy/generators/policy'
|
5
|
-
require 'eucalypt/security/namespaces/security-policy-permission/cli/security-policy-permission'
|
6
|
-
require 'eucalypt/security/namespaces/security-policy-role/cli/security-policy-role'
|
7
|
-
require 'eucalypt/list'
|
8
|
-
|
9
|
-
module Eucalypt
|
10
|
-
class SecurityPolicy < Thor
|
11
|
-
include Thor::Actions
|
12
|
-
include Eucalypt::Helpers
|
13
|
-
using Colorize
|
14
|
-
extend Eucalypt::List
|
15
|
-
|
16
|
-
option :headless, type: :boolean, aliases: '-H', default: false, desc: "Policy with no associated model"
|
17
|
-
option :permissions, type: :array, aliases: '-p', default: [], desc: "Permissions to generate along with the policy"
|
18
|
-
desc "generate [NAME]", "Create a new Pundit policy".colorize(:grey)
|
19
|
-
def generate(name)
|
20
|
-
directory = File.expand_path('.')
|
21
|
-
if Eucalypt.app? directory
|
22
|
-
# Check for authorization gems
|
23
|
-
return unless Gemfile.check(%w[pundit], 'eucalypt security pundit setup', directory)
|
24
|
-
|
25
|
-
# Check for user model
|
26
|
-
unless File.exist? File.join(directory, 'app', 'models', 'user.rb')
|
27
|
-
Eucalypt::Error.no_user_model
|
28
|
-
return
|
29
|
-
end
|
30
|
-
|
31
|
-
# Check for role model
|
32
|
-
unless File.exist? File.join(directory, 'app', 'models', 'role.rb')
|
33
|
-
Eucalypt::Error.no_role_model
|
34
|
-
return
|
35
|
-
end
|
36
|
-
|
37
|
-
policy = Inflect.new(:policy, name)
|
38
|
-
|
39
|
-
policy_generator = Eucalypt::Generators::Policy.new
|
40
|
-
policy_generator.destination_root = directory
|
41
|
-
|
42
|
-
# Generate policy file
|
43
|
-
policy_generator.generate(headless: options[:headless], name: name)
|
44
|
-
|
45
|
-
# Create policy roles table
|
46
|
-
policy_generator.generate_policy_roles_migration(policy: policy.resource)
|
47
|
-
|
48
|
-
# Create policy role model
|
49
|
-
policy_generator.generate_policy_role_model(policy: policy)
|
50
|
-
|
51
|
-
# Add policy column to user roles table
|
52
|
-
Dir.chdir(directory) do
|
53
|
-
args = %w[migration add column]
|
54
|
-
args << 'roles'
|
55
|
-
args << policy.resource
|
56
|
-
args << 'string'
|
57
|
-
args << %w[-o default:default]
|
58
|
-
args.flatten!
|
59
|
-
Eucalypt::CLI.start(args)
|
60
|
-
end
|
61
|
-
|
62
|
-
# Generate permissions
|
63
|
-
options[:permissions].each do |permission|
|
64
|
-
Eucalypt::CLI.start(['security', 'policy', 'permission', 'generate', policy.resource, permission])
|
65
|
-
end
|
66
|
-
else
|
67
|
-
Eucalypt::Error.wrong_directory
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
#def destroy()
|
72
|
-
#end
|
73
|
-
|
74
|
-
def self.banner(task, namespace = false, subcommand = true)
|
75
|
-
"#{basename} security #{task.formatted_usage(self, true, subcommand).split(':').join(' ')}"
|
76
|
-
end
|
77
|
-
|
78
|
-
register(Eucalypt::SecurityPolicyPermission, 'permission', 'permission [COMMAND]', 'Pundit policy permission commands'.colorize(:grey))
|
79
|
-
register(Eucalypt::SecurityPolicyRole, 'role', 'role [COMMAND]', 'Pundit policy role commands'.colorize(:grey))
|
80
|
-
end
|
81
|
-
end
|
@@ -1,41 +0,0 @@
|
|
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(headless:, name:)
|
17
|
-
policy = Inflect.new(:policy, name)
|
18
|
-
config = {class_name: policy.class_name, resource: policy.resource, constant: policy.constant, headless: headless}
|
19
|
-
template 'policy.tt', policy.file_path, config
|
20
|
-
end
|
21
|
-
|
22
|
-
def generate_policy_role_model(policy:)
|
23
|
-
roles_directory = File.join 'app', 'models', 'roles'
|
24
|
-
role_model_file = File.join roles_directory, "#{policy.resource}_role.rb"
|
25
|
-
|
26
|
-
empty_directory roles_directory unless File.directory? roles_directory
|
27
|
-
|
28
|
-
config = {constant: policy.constant}
|
29
|
-
template 'policy_role.tt', role_model_file, config
|
30
|
-
end
|
31
|
-
|
32
|
-
def generate_policy_roles_migration(policy:)
|
33
|
-
sleep 1
|
34
|
-
migration = Eucalypt::Helpers::Migration[title: "create_#{policy}_roles", template: 'create_policy_roles_migration.tt']
|
35
|
-
return unless migration.create_anyway? if migration.exists?
|
36
|
-
config = {migration_title: migration.title.camelize, policy: policy}
|
37
|
-
template migration.template, migration.file_path, config
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
data/lib/eucalypt/security/namespaces/security-policy/templates/create_policy_roles_migration.tt
DELETED
@@ -1,11 +0,0 @@
|
|
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
|
@@ -1,8 +0,0 @@
|
|
1
|
-
class <%= config[:class_name] %><%= " < Struct.new(:user, :#{config[:resource]})" if config[:headless] %>
|
2
|
-
attr_reader :user, :<%= config[:resource] %>
|
3
|
-
|
4
|
-
def initialize(user, <%= config[:resource] %>)
|
5
|
-
@user = user
|
6
|
-
@<%= config[:resource] %> = <%= config[:resource] %>
|
7
|
-
end
|
8
|
-
end
|
@@ -1,77 +0,0 @@
|
|
1
|
-
require 'thor'
|
2
|
-
require 'eucalypt/helpers'
|
3
|
-
require 'eucalypt/security/helpers'
|
4
|
-
require 'eucalypt/security/namespaces/security-pundit/generators/role'
|
5
|
-
require 'eucalypt/list'
|
6
|
-
|
7
|
-
module Eucalypt
|
8
|
-
class SecurityPundit < 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
|
-
extend Eucalypt::List
|
16
|
-
|
17
|
-
def self.source_root
|
18
|
-
File.join File.dirname(__dir__), 'templates'
|
19
|
-
end
|
20
|
-
|
21
|
-
desc "setup", "Set up Pundit authorization".colorize(:grey)
|
22
|
-
def setup
|
23
|
-
directory = File.expand_path('.')
|
24
|
-
if Eucalypt.app? directory
|
25
|
-
# Check if user model exists
|
26
|
-
user_model_file = File.join(directory, 'app', 'models', 'user.rb')
|
27
|
-
unless File.file? user_model_file
|
28
|
-
Eucalypt::Error.no_user_model
|
29
|
-
return
|
30
|
-
end
|
31
|
-
|
32
|
-
Out.setup "Setting up Pundit authorization..."
|
33
|
-
|
34
|
-
# Add Pundit to Gemfile
|
35
|
-
gemfile_add('Authorization', {pundit: '~> 2.0'}, directory)
|
36
|
-
|
37
|
-
# Create Pundit config file
|
38
|
-
create_config_file(:pundit, directory)
|
39
|
-
|
40
|
-
# Create roles migration
|
41
|
-
Eucalypt::Generators::Role.new.generate_roles_migration
|
42
|
-
|
43
|
-
# Create Role model
|
44
|
-
role_model_file = File.join(directory, 'app', 'models', 'role.rb')
|
45
|
-
Out.warning "Role model already exists." if File.file? role_model_file
|
46
|
-
Dir.chdir(directory) do
|
47
|
-
Eucalypt::CLI.start(%w[generate model role --no-spec --no-table])
|
48
|
-
end
|
49
|
-
|
50
|
-
# Add belongs_to to Role model
|
51
|
-
File.open(role_model_file) do |f|
|
52
|
-
insert = " belongs_to :user"
|
53
|
-
inject_into_class(role_model_file, 'Role', "#{insert}\n") unless f.read.include? insert
|
54
|
-
end
|
55
|
-
|
56
|
-
# Add relationship to User model
|
57
|
-
File.open(user_model_file) do |f|
|
58
|
-
contents = f.read
|
59
|
-
insert = " has_one :role, dependent: :destroy\n"
|
60
|
-
inject_into_file(user_model_file, insert, before: / include BCrypt/) unless contents.include? insert
|
61
|
-
insert = " after_save :create_role\n\n"
|
62
|
-
inject_into_file(user_model_file, insert, before: / include BCrypt/) unless contents.include? insert
|
63
|
-
insert = "\n private\n\n def create_role\n self.role = Role.new\n end\n"
|
64
|
-
inject_into_file(user_model_file, insert, before: /^end/) unless contents.include? insert
|
65
|
-
end
|
66
|
-
|
67
|
-
Out.info "Ensure you run `#{'eucalypt rake db:migrate'.colorize(:bold)}` to create the necessary tables for Pundit."
|
68
|
-
else
|
69
|
-
Eucalypt::Error.wrong_directory
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def self.banner(task, namespace = false, subcommand = true)
|
74
|
-
"#{basename} security #{task.formatted_usage(self, true, subcommand).split(':').join(' ')}"
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
@@ -1,24 +0,0 @@
|
|
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
|
@@ -1,77 +0,0 @@
|
|
1
|
-
require 'thor'
|
2
|
-
require 'eucalypt/helpers'
|
3
|
-
require 'eucalypt/security/helpers'
|
4
|
-
require 'eucalypt/security/namespaces/security-warden/generators/user'
|
5
|
-
require 'eucalypt/security/namespaces/security-warden/generators/auth_controller'
|
6
|
-
require 'eucalypt/list'
|
7
|
-
|
8
|
-
module Eucalypt
|
9
|
-
class SecurityWarden < Thor
|
10
|
-
include Thor::Actions
|
11
|
-
include Eucalypt::Helpers
|
12
|
-
include Eucalypt::Helpers::Messages
|
13
|
-
include Eucalypt::Helpers::Gemfile
|
14
|
-
include Eucalypt::Security::Helpers
|
15
|
-
using Colorize
|
16
|
-
using String::Builder
|
17
|
-
extend Eucalypt::List
|
18
|
-
|
19
|
-
def self.source_root
|
20
|
-
File.join File.dirname(__dir__), 'templates'
|
21
|
-
end
|
22
|
-
|
23
|
-
option :controller, type: :boolean, default: true, desc: "Include an authentication controller"
|
24
|
-
desc "setup", "Set up Warden authentication".colorize(:grey)
|
25
|
-
def setup
|
26
|
-
directory = File.expand_path('.')
|
27
|
-
if Eucalypt.app? directory
|
28
|
-
Out.setup "Setting up Warden authentication..."
|
29
|
-
|
30
|
-
# Add Warden and BCrypt to Gemfile
|
31
|
-
gemfile_add('Authentication and encryption', {warden: '~> 1.2', bcrypt: '~> 3.1'}, directory)
|
32
|
-
|
33
|
-
# Create Warden config file
|
34
|
-
create_config_file(:warden, directory)
|
35
|
-
|
36
|
-
# Add middleware to config.ru
|
37
|
-
middleware = String.build do |s|
|
38
|
-
s << "\nuse Warden::Manager do |config|\n"
|
39
|
-
s << " config.serialize_into_session{|user| user.id}\n"
|
40
|
-
s << " config.serialize_from_session{|id| User.find(id)}\n"
|
41
|
-
s << " config.scope_defaults :default, strategies: [:password], action: 'auth/invalid'\n"
|
42
|
-
s << " config.failure_app = self\n"
|
43
|
-
s << "end\n"
|
44
|
-
end
|
45
|
-
|
46
|
-
config_ru = File.join(directory, 'config.ru')
|
47
|
-
|
48
|
-
File.open config_ru do |f|
|
49
|
-
contents = f.read
|
50
|
-
inject_into_file(config_ru, middleware, after: /require_relative 'app'\n/) unless contents.include? 'use Warden::Manager'
|
51
|
-
end
|
52
|
-
|
53
|
-
user = Eucalypt::Generators::User.new
|
54
|
-
|
55
|
-
# Create user migration
|
56
|
-
user.generate_migration
|
57
|
-
|
58
|
-
# Create user model
|
59
|
-
user.generate_model(directory)
|
60
|
-
|
61
|
-
if options[:controller]
|
62
|
-
auth_controller = Eucalypt::Generators::AuthController.new
|
63
|
-
auth_controller.destination_root = directory
|
64
|
-
auth_controller.generate
|
65
|
-
end
|
66
|
-
|
67
|
-
Out.info "Ensure you run `#{'eucalypt rake db:migrate'.colorize(:bold)}` to create the necessary tables for Warden."
|
68
|
-
else
|
69
|
-
Eucalypt::Error.wrong_directory
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def self.banner(task, namespace = false, subcommand = true)
|
74
|
-
"#{basename} security #{task.formatted_usage(self, true, subcommand).split(':').join(' ')}"
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
@@ -1,34 +0,0 @@
|
|
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
|
@@ -1,37 +0,0 @@
|
|
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
|
@@ -1,25 +0,0 @@
|
|
1
|
-
class AuthenticationController < Eucalypt::Controller(route: '/auth')
|
2
|
-
helpers AuthenticationHelper if defined? AuthenticationHelper
|
3
|
-
|
4
|
-
get '/login' do
|
5
|
-
redirect '/' if authenticated?
|
6
|
-
erb :'authentication/login', layout: false
|
7
|
-
end
|
8
|
-
|
9
|
-
post '/login' do
|
10
|
-
redirect '/' if authenticated?
|
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
|
@@ -1 +0,0 @@
|
|
1
|
-
<%= config[:data] %>
|
@@ -1,16 +0,0 @@
|
|
1
|
-
require 'eucalypt/security/confirm'
|
2
|
-
class User < ActiveRecord::Base
|
3
|
-
validates :username, presence: true, uniqueness: true
|
4
|
-
validates :encrypted_password, presence: true
|
5
|
-
|
6
|
-
include BCrypt
|
7
|
-
|
8
|
-
def authenticate(attempt)
|
9
|
-
Password.new(self.encrypted_password) == attempt
|
10
|
-
end
|
11
|
-
|
12
|
-
def password=(entered_password)
|
13
|
-
@password = Password.create(entered_password)
|
14
|
-
self.encrypted_password = @password
|
15
|
-
end
|
16
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
class ApplicationController < Sinatra::Base
|
2
|
-
# Configure Warden for authentication
|
3
|
-
enable :sessions
|
4
|
-
|
5
|
-
Warden::Manager.before_failure {|env,opts| env['REQUEST_METHOD'] = 'POST'}
|
6
|
-
|
7
|
-
Warden::Strategies.add(:password) do
|
8
|
-
def valid?
|
9
|
-
params['user'] && params['user']['username'] && params['user']['password']
|
10
|
-
end
|
11
|
-
def authenticate!
|
12
|
-
unless (user = User.find_by_username params['user']['username'])
|
13
|
-
fail! 'The username you entered does not exist'
|
14
|
-
else
|
15
|
-
user.authenticate(params['user']['password']) ? success!(user) : fail!('Could not log in')
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
helpers do
|
21
|
-
def current_user
|
22
|
-
env['warden'].user
|
23
|
-
end
|
24
|
-
|
25
|
-
def authenticated?
|
26
|
-
!!current_user
|
27
|
-
end
|
28
|
-
|
29
|
-
def authenticate
|
30
|
-
env['warden'].authenticate!
|
31
|
-
end
|
32
|
-
|
33
|
-
alias_method :logged_in?, :authenticated?
|
34
|
-
end
|
35
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
require 'eucalypt/errors'
|
2
|
-
require 'eucalypt/security/namespaces/security-warden/cli/security-warden'
|
3
|
-
require 'eucalypt/security/namespaces/security-pundit/cli/security-pundit'
|
4
|
-
require 'eucalypt/security/namespaces/security-policy/cli/security-policy'
|
5
|
-
require 'eucalypt/helpers'
|
6
|
-
require 'eucalypt/list'
|
7
|
-
|
8
|
-
module Eucalypt
|
9
|
-
class Security < Thor
|
10
|
-
include Thor::Actions
|
11
|
-
include Eucalypt::Helpers
|
12
|
-
using Colorize
|
13
|
-
extend Eucalypt::List
|
14
|
-
|
15
|
-
def self.banner(task, namespace = false, subcommand = true)
|
16
|
-
basename + ' ' + task.formatted_usage(self, true, subcommand).split(':').join(' ')
|
17
|
-
end
|
18
|
-
|
19
|
-
register(Eucalypt::SecurityWarden, 'warden', 'warden [COMMAND]', 'Configure Warden authentication'.colorize(:grey))
|
20
|
-
register(Eucalypt::SecurityPundit, 'pundit', 'pundit [COMMAND]', 'Configure Pundit authorization'.colorize(:grey))
|
21
|
-
register(Eucalypt::SecurityPolicy, 'policy', 'policy [COMMAND]', 'Pundit policy commands'.colorize(:grey))
|
22
|
-
end
|
23
|
-
|
24
|
-
class CLI < Thor
|
25
|
-
include Eucalypt::Helpers
|
26
|
-
using Colorize
|
27
|
-
register(Security, 'security', 'security [COMMAND]', 'Manage authentication and authorization'.colorize(:grey))
|
28
|
-
end
|
29
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
require 'active_record'
|
2
|
-
require 'active_support/core_ext'
|
3
|
-
|
4
|
-
Eucalypt.glob('app', '{policies}', '*.rb') do |file|
|
5
|
-
policy_name = File.basename file, '.rb'
|
6
|
-
policy_constant = policy_name.camelize.constantize
|
7
|
-
resource_name = policy_name.gsub '_policy', ''
|
8
|
-
roles_name = "#{resource_name}_roles"
|
9
|
-
role_constant_name = roles_name.singularize.camelize
|
10
|
-
role_constant = role_constant_name.constantize
|
11
|
-
|
12
|
-
if ActiveRecord::Base.connection.table_exists? roles_name
|
13
|
-
level = ActiveRecord::Base.logger.level
|
14
|
-
begin
|
15
|
-
ActiveRecord::Base.logger.level = :unknown
|
16
|
-
role_constant.pluck(:permission).each do |permission|
|
17
|
-
policy_constant.define_method "#{permission}?" do
|
18
|
-
role_constant.find_by(permission: permission).send(user.role.send resource_name)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
rescue => exception
|
22
|
-
throw exception
|
23
|
-
ensure
|
24
|
-
ActiveRecord::Base.logger.level = level
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|