eucalypt 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|