petergate 3.0.0 → 3.1.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/.gitignore +2 -2
- data/.ruby-version +1 -1
- data/Gemfile +13 -40
- data/README.md +76 -28
- data/Rakefile +5 -2
- data/lib/generators/petergate/install_generator.rb +0 -1
- data/lib/petergate/action_controller/base.rb +31 -4
- data/lib/petergate/active_record/base.rb +29 -6
- data/lib/petergate/version.rb +1 -1
- data/lib/templates/rails/scaffold_controller/controller.rb +10 -11
- data/petergate.gemspec +27 -4
- metadata +55 -14
- data/.travis.yml +0 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 458fdd69a1955dde44434ec3ba661af445de0b754b09b8d61dfd7e959ba33632
|
|
4
|
+
data.tar.gz: 5b99cfc5fb9d622d9b9b47a9777b3fe3bc51bc520b45ee52a29dfdbc633b3c7d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: af0027d006aa080fe77ce5467ac3ec036d84d2ad3211caf21d267914fc18b46680ff3722dbc855801b7026bfdeeb420ffc5e53cac10611f78a82d063d2178486
|
|
7
|
+
data.tar.gz: 686f7f73c012fc240a9734599cd2106e35dbe0b0694bff964aab9114fb3f8de9ff78a7a83dfcc57a39c10cce7c124cb05a592a2a5594dbe763cc198d0cc513fb
|
data/.gitignore
CHANGED
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.0
|
|
1
|
+
3.2.0
|
data/Gemfile
CHANGED
|
@@ -1,43 +1,16 @@
|
|
|
1
|
-
source
|
|
2
|
-
ruby '3.0.1'
|
|
1
|
+
source "https://rubygems.org"
|
|
3
2
|
|
|
4
|
-
#
|
|
3
|
+
# Declares the runtime dependencies.
|
|
5
4
|
gemspec
|
|
6
|
-
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
|
|
7
|
-
gem 'rails', '~> 6.0.3.4'
|
|
8
|
-
|
|
9
|
-
# Use sqlite3 as the database for Active Record
|
|
10
|
-
gem 'sqlite3'
|
|
11
|
-
# Use SCSS for stylesheets
|
|
12
|
-
gem 'sass-rails', '~> 5.0.4'
|
|
13
|
-
# Use Uglifier as compressor for JavaScript assets
|
|
14
|
-
gem 'uglifier', '>= 1.3.0'
|
|
15
|
-
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
|
|
16
|
-
# gem 'therubyracer', platforms: :ruby
|
|
17
|
-
|
|
18
|
-
# Use jquery as the JavaScript library
|
|
19
|
-
gem 'jquery-rails'
|
|
20
|
-
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
|
|
21
|
-
gem 'turbolinks'
|
|
22
|
-
gem "minitest-rails", "~> 6.0.1"
|
|
23
|
-
gem "minitest-reporters"
|
|
24
|
-
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
|
|
25
|
-
gem 'jbuilder', '~> 2.0'
|
|
26
|
-
# bundle exec rake doc:rails generates the API under doc/api.
|
|
27
|
-
gem 'sdoc', '~> 0.4.0', group: :doc
|
|
28
|
-
|
|
29
|
-
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
|
|
30
|
-
gem 'devise'
|
|
31
|
-
|
|
32
|
-
# Use ActiveModel has_secure_password
|
|
33
|
-
# gem 'bcrypt', '~> 3.1.7'
|
|
34
|
-
|
|
35
|
-
# Use unicorn as the app server
|
|
36
|
-
# gem 'unicorn'
|
|
37
|
-
|
|
38
|
-
# Use Capistrano for deployment
|
|
39
|
-
# gem 'capistrano-rails', group: :development
|
|
40
|
-
|
|
41
|
-
# Use debugger
|
|
42
|
-
# gem 'debugger', group: [:development, :test]
|
|
43
5
|
|
|
6
|
+
# The default development target. gemfiles/ holds the CI matrix across the
|
|
7
|
+
# supported Rails versions. The suite boots a minimal Rails app instead of a
|
|
8
|
+
# dummy app, so it needs the full framework plus a database to talk to.
|
|
9
|
+
gem "rails", "~> 8.1"
|
|
10
|
+
gem "sqlite3", "~> 2.0"
|
|
11
|
+
gem "rake", ">= 13.0"
|
|
12
|
+
|
|
13
|
+
# Devise is not a dependency of the gem -- petergate only needs the three
|
|
14
|
+
# authentication methods the README documents. It is here so one test can prove
|
|
15
|
+
# a real Devise app satisfies that contract.
|
|
16
|
+
gem "devise"
|
data/README.md
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
[](https://github.com/elorest/petergate)
|
|
2
2
|
|
|
3
|
-
[](https://gitter.im/isaacsloan/petergate?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
|
3
|
+
[](https://github.com/elorest/petergate/actions/workflows/ci.yml)
|
|
5
4
|
[](http://badge.fury.io/rb/petergate)
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
|
|
9
|
-
> If you like the straight forward and effective nature of [Strong Parameters](https://github.com/rails/strong_parameters) and suspect that [cancan](https://github.com/ryanb/cancan) might be overkill for your project then you'll love [Petergate's](https://github.com/
|
|
8
|
+
> If you like the straight forward and effective nature of [Strong Parameters](https://github.com/rails/strong_parameters) and suspect that [cancan](https://github.com/ryanb/cancan) might be overkill for your project then you'll love [Petergate's](https://github.com/elorest/petergate) easy to use and read action and content based authorizations.
|
|
10
9
|
>
|
|
11
10
|
> -- <cite>1 Peter 3:41</cite>
|
|
12
11
|
|
|
12
|
+
Requirements
|
|
13
|
+
------
|
|
14
|
+
Rails 7.1 through 8.1 on Ruby 3.2 through 3.4 are covered by CI. Older Rails
|
|
15
|
+
versions are permitted by the gemspec but are not verified.
|
|
16
|
+
|
|
13
17
|
Installation
|
|
14
18
|
------
|
|
15
19
|
##### Get the gem
|
|
@@ -27,16 +31,19 @@ Or install it yourself as:
|
|
|
27
31
|
|
|
28
32
|
##### Prerequisites: Setup Authentication (Devise)
|
|
29
33
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
and called User.
|
|
34
|
+
The generator writes into `app/models/user.rb`, so a model named `User` is the
|
|
35
|
+
supported setup.
|
|
33
36
|
|
|
34
|
-
If you're using [devise](https://github.com/
|
|
37
|
+
If you're using [devise](https://github.com/heartcombo/devise) you're in luck,
|
|
38
|
+
otherwise you'll have to add the following methods to your project:
|
|
35
39
|
|
|
36
40
|
current_user
|
|
37
41
|
after_sign_in_path_for(current_user)
|
|
38
42
|
authenticate_user!
|
|
39
43
|
|
|
44
|
+
You also need a `root` route: a refused visitor who isn't signed in is sent
|
|
45
|
+
there.
|
|
46
|
+
|
|
40
47
|
##### Run the generators
|
|
41
48
|
|
|
42
49
|
rails g petergate:install
|
|
@@ -60,18 +67,32 @@ petergate(roles: [:admin, :editor], multiple: false)
|
|
|
60
67
|
############################################################################################
|
|
61
68
|
```
|
|
62
69
|
|
|
70
|
+
With `multiple: false` the role is stored in the column as a plain string. With
|
|
71
|
+
`multiple: true` the roles are stored as a YAML array, so query them through the
|
|
72
|
+
generated scopes below rather than by matching the column directly.
|
|
73
|
+
|
|
63
74
|
##### Instance Methods
|
|
64
75
|
|
|
65
76
|
```ruby
|
|
66
77
|
user.role => :editor
|
|
67
78
|
user.roles => [:editor, :user]
|
|
68
79
|
user.roles=(v) #sets roles
|
|
69
|
-
user.available_roles => [:admin, :editor]
|
|
70
|
-
user.has_roles?(:admin, :
|
|
80
|
+
user.available_roles => [:admin, :editor, :user]
|
|
81
|
+
user.has_roles?(:admin, :editor) # true if the user has any of the roles passed in
|
|
82
|
+
user.has_role?(:admin) # alias of has_roles?
|
|
71
83
|
```
|
|
72
84
|
##### Class Methods
|
|
73
85
|
|
|
74
|
-
|
|
86
|
+
A scope is defined for each configured role, named `role_` plus the pluralized
|
|
87
|
+
role name:
|
|
88
|
+
|
|
89
|
+
```ruby
|
|
90
|
+
User.role_admins # => users holding :admin
|
|
91
|
+
User.role_editors # => users holding :editor
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
So `petergate(roles: [:admin, :teacher])` gives you `User.role_admins` and
|
|
95
|
+
`User.role_teachers`.
|
|
75
96
|
|
|
76
97
|
#### Controllers
|
|
77
98
|
|
|
@@ -84,6 +105,25 @@ access all: [:show, :index], user: {except: [:destroy]}, company_admin: :all
|
|
|
84
105
|
access [:all, :user] => [:show, :index]
|
|
85
106
|
```
|
|
86
107
|
|
|
108
|
+
The key is a role, or an array of roles. `all` covers everyone, including
|
|
109
|
+
visitors who aren't signed in. The value is one of:
|
|
110
|
+
|
|
111
|
+
| Value | Meaning |
|
|
112
|
+
| --- | --- |
|
|
113
|
+
| `[:show, :index]` | just those actions |
|
|
114
|
+
| `:all` | every action on the controller |
|
|
115
|
+
| `{except: [:destroy]}` | every action except those |
|
|
116
|
+
|
|
117
|
+
`:root_admin` is not a rule you write -- a user holding it bypasses the rules
|
|
118
|
+
entirely.
|
|
119
|
+
|
|
120
|
+
Rules declared on a parent controller are inherited by its subclasses, so a
|
|
121
|
+
single `access` line on `ApplicationController` can cover a whole app.
|
|
122
|
+
|
|
123
|
+
`access` works the same way in an `ActionController::API` controller. There a
|
|
124
|
+
refused request answers with a bare `403`, and an unauthenticated one with
|
|
125
|
+
`401`, instead of redirecting.
|
|
126
|
+
|
|
87
127
|
Inside your views you can use logged_in?(:admin, :customer, :etc) to show or hide content.
|
|
88
128
|
|
|
89
129
|
```erb
|
|
@@ -93,16 +133,13 @@ Inside your views you can use logged_in?(:admin, :customer, :etc) to show or hid
|
|
|
93
133
|
If you need to access available roles within your project you can by calling:
|
|
94
134
|
|
|
95
135
|
```ruby
|
|
96
|
-
User::ROLES
|
|
97
|
-
#
|
|
98
|
-
User.first.available_roles
|
|
99
|
-
# ROLES is a CONSTANT and will still work from within the User model instance methods
|
|
100
|
-
# like in this default setter:
|
|
101
|
-
|
|
102
|
-
def roles=(v)
|
|
103
|
-
self[:roles] = v.map(&:to_sym).to_a.select{|r| r.size > 0 && ROLES.include?(r)}
|
|
104
|
-
end
|
|
136
|
+
User::ROLES # => [:admin, :editor, :user]
|
|
137
|
+
User.first.available_roles # the same list, from an instance
|
|
105
138
|
```
|
|
139
|
+
|
|
140
|
+
`ROLES` is a constant on the model, so it is also reachable from your own
|
|
141
|
+
instance methods. A subclass shares its parent's roles.
|
|
142
|
+
|
|
106
143
|
If you need to deny access you can use the forbidden! method:
|
|
107
144
|
|
|
108
145
|
```ruby
|
|
@@ -121,7 +158,7 @@ access user: [:show, :index], message: "You shall not pass"
|
|
|
121
158
|
#### User Admin Example Form for Multiple Roles
|
|
122
159
|
|
|
123
160
|
```slim
|
|
124
|
-
=
|
|
161
|
+
= form_with model: @user do |f|
|
|
125
162
|
- if @user.errors.any?
|
|
126
163
|
#error_explanation
|
|
127
164
|
h2 = "#{pluralize(@user.errors.count, "error")} prohibited this user from being saved:"
|
|
@@ -135,10 +172,10 @@ access user: [:show, :index], message: "You shall not pass"
|
|
|
135
172
|
- if @user.new_record? || params[:passwd]
|
|
136
173
|
.field
|
|
137
174
|
= f.label :password
|
|
138
|
-
= f.
|
|
175
|
+
= f.password_field :password
|
|
139
176
|
.field
|
|
140
177
|
= f.label :password_confirmation
|
|
141
|
-
= f.
|
|
178
|
+
= f.password_field :password_confirmation
|
|
142
179
|
.field
|
|
143
180
|
= f.label :roles
|
|
144
181
|
= f.select :roles, @user.available_roles, {}, {multiple: true}
|
|
@@ -148,7 +185,7 @@ access user: [:show, :index], message: "You shall not pass"
|
|
|
148
185
|
#### User Admin Example Form for Single Role Mode
|
|
149
186
|
|
|
150
187
|
```slim
|
|
151
|
-
=
|
|
188
|
+
= form_with model: @user do |f|
|
|
152
189
|
- if @user.errors.any?
|
|
153
190
|
#error_explanation
|
|
154
191
|
h2 = "#{pluralize(@user.errors.count, "error")} prohibited this user from being saved:"
|
|
@@ -162,24 +199,35 @@ access user: [:show, :index], message: "You shall not pass"
|
|
|
162
199
|
- if @user.new_record? || params[:passwd]
|
|
163
200
|
.field
|
|
164
201
|
= f.label :password
|
|
165
|
-
= f.
|
|
202
|
+
= f.password_field :password
|
|
166
203
|
.field
|
|
167
204
|
= f.label :password_confirmation
|
|
168
|
-
= f.
|
|
205
|
+
= f.password_field :password_confirmation
|
|
169
206
|
.field
|
|
170
207
|
= f.label :role
|
|
171
208
|
= f.select :role, @user.available_roles
|
|
172
209
|
.actions = f.submit
|
|
173
210
|
```
|
|
211
|
+
Development
|
|
212
|
+
-------
|
|
213
|
+
|
|
214
|
+
bundle install
|
|
215
|
+
bundle exec rake test
|
|
216
|
+
|
|
217
|
+
The suite boots a small Rails application in memory rather than carrying a
|
|
218
|
+
dummy app. To run it against a specific Rails version:
|
|
219
|
+
|
|
220
|
+
BUNDLE_GEMFILE=gemfiles/rails_7_1.gemfile bundle exec rake test
|
|
221
|
+
|
|
174
222
|
Credits
|
|
175
223
|
-------
|
|
176
224
|
|
|
177
|
-
PeterGate is written and
|
|
225
|
+
PeterGate is written and maintained by Isaac Sloan and friends.
|
|
178
226
|
|
|
179
227
|
|
|
180
228
|
## Contributing
|
|
181
229
|
|
|
182
|
-
1. Fork it ( https://github.com/
|
|
230
|
+
1. Fork it ( https://github.com/elorest/petergate/fork )
|
|
183
231
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
184
232
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
185
233
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/Rakefile
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
require "bundler/gem_tasks"
|
|
2
|
-
require
|
|
2
|
+
require "rake/testtask"
|
|
3
3
|
|
|
4
4
|
Rake::TestTask.new(:test) do |t|
|
|
5
|
-
t.
|
|
5
|
+
t.libs << "lib"
|
|
6
|
+
t.libs << "test"
|
|
7
|
+
t.pattern = "test/**/*_test.rb"
|
|
6
8
|
t.verbose = false
|
|
9
|
+
t.warning = false
|
|
7
10
|
end
|
|
8
11
|
|
|
9
12
|
task default: :test
|
|
@@ -5,7 +5,6 @@ module Petergate
|
|
|
5
5
|
class InstallGenerator < Rails::Generators::Base
|
|
6
6
|
include Rails::Generators::Migration
|
|
7
7
|
source_root File.expand_path("../templates", __FILE__)
|
|
8
|
-
class_option :orm
|
|
9
8
|
|
|
10
9
|
desc "Sets up rails project for Petergate Authorizations"
|
|
11
10
|
def self.next_migration_number(path)
|
|
@@ -63,7 +63,7 @@ module Petergate
|
|
|
63
63
|
|
|
64
64
|
def self.included(base)
|
|
65
65
|
base.extend(ClassMethods)
|
|
66
|
-
base.helper_method :logged_in?, :forbidden!, :unauthorized!
|
|
66
|
+
base.helper_method :logged_in?, :forbidden!, :unauthorized! if base.respond_to?(:helper_method)
|
|
67
67
|
end
|
|
68
68
|
|
|
69
69
|
def parse_permission_rules(rules)
|
|
@@ -106,7 +106,16 @@ module Petergate
|
|
|
106
106
|
defined?(self.class.controller_message) ? self.class.controller_message : 'Permission Denied'
|
|
107
107
|
end
|
|
108
108
|
|
|
109
|
+
# ActionController::API does not include ActionController::MimeResponds,
|
|
110
|
+
# so `respond_to` is unavailable there. API controllers get a bare status
|
|
111
|
+
# code instead of an HTML redirect, which is what an API caller expects.
|
|
112
|
+
def negotiates_formats?
|
|
113
|
+
respond_to?(:respond_to)
|
|
114
|
+
end
|
|
115
|
+
|
|
109
116
|
def unauthorized!
|
|
117
|
+
return head(:unauthorized) unless negotiates_formats?
|
|
118
|
+
|
|
110
119
|
respond_to do |format|
|
|
111
120
|
format.any(:js, :json, :xml) do
|
|
112
121
|
head(:unauthorized)
|
|
@@ -118,13 +127,23 @@ module Petergate
|
|
|
118
127
|
end
|
|
119
128
|
|
|
120
129
|
def forbidden!(msg = nil)
|
|
130
|
+
return head(:forbidden) unless negotiates_formats?
|
|
131
|
+
|
|
121
132
|
respond_to do |format|
|
|
122
133
|
format.any(:js, :json, :xml) do
|
|
123
134
|
head(:forbidden)
|
|
124
135
|
end
|
|
125
136
|
format.html do
|
|
126
|
-
|
|
127
|
-
|
|
137
|
+
notice = msg || request.headers['msg'] || custom_message
|
|
138
|
+
|
|
139
|
+
# The Referer is deliberately not consulted. The original line read
|
|
140
|
+
# request.headers['Referrer'] -- a misspelling of the HTTP header --
|
|
141
|
+
# so it was always nil and this always resolved to the signed-in
|
|
142
|
+
# destination. Honouring the real header now would change where
|
|
143
|
+
# every existing app sends a refused user, and would hand the
|
|
144
|
+
# redirect target to the caller.
|
|
145
|
+
destination = current_user.present? ? after_sign_in_path_for(current_user) : root_path
|
|
146
|
+
redirect_to destination, notice: notice
|
|
128
147
|
end
|
|
129
148
|
end
|
|
130
149
|
end
|
|
@@ -132,6 +151,14 @@ module Petergate
|
|
|
132
151
|
end
|
|
133
152
|
end
|
|
134
153
|
|
|
135
|
-
|
|
154
|
+
# Hook in lazily rather than reopening ActionController::Base at require time:
|
|
155
|
+
# eager reopening forces ActionPack to load during boot, and it misses API
|
|
156
|
+
# controllers entirely.
|
|
157
|
+
#
|
|
158
|
+
# :action_controller rather than the newer :action_controller_base and
|
|
159
|
+
# :action_controller_api pair. Rails runs this one for both Base and API, and
|
|
160
|
+
# it predates the other two (added in 5.2) -- so on an older Rails the pair
|
|
161
|
+
# would simply never fire and petergate would silently stop working.
|
|
162
|
+
ActiveSupport.on_load(:action_controller) do
|
|
136
163
|
include Petergate::ActionController::Base
|
|
137
164
|
end
|
|
@@ -6,9 +6,29 @@ module Petergate
|
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
module ClassMethods
|
|
9
|
+
# True when a class this one inherits from has already been through
|
|
10
|
+
# petergate. Only the superclass chain is walked: an included module
|
|
11
|
+
# carrying its own ROLES is somebody else's constant, not a sign that
|
|
12
|
+
# this model is already configured.
|
|
13
|
+
def petergate_configured_by_ancestor?
|
|
14
|
+
klass = superclass
|
|
15
|
+
|
|
16
|
+
while klass && klass != ::ActiveRecord::Base && klass != ::Object
|
|
17
|
+
return true if klass.const_defined?(:ROLES, false)
|
|
18
|
+
klass = klass.superclass
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
false
|
|
22
|
+
end
|
|
23
|
+
|
|
9
24
|
def petergate(roles: [:admin], multiple: true)
|
|
25
|
+
# A subclass shares everything its parent configured -- roles, scopes
|
|
26
|
+
# and callbacks. Running again would define scopes for roles the model
|
|
27
|
+
# can never hold and register a second after_initialize.
|
|
28
|
+
return if petergate_configured_by_ancestor?
|
|
29
|
+
|
|
10
30
|
if multiple
|
|
11
|
-
serialize :roles
|
|
31
|
+
serialize :roles, coder: YAML
|
|
12
32
|
after_initialize do
|
|
13
33
|
self[:roles] ||= [:user]
|
|
14
34
|
end
|
|
@@ -19,7 +39,8 @@ module Petergate
|
|
|
19
39
|
end
|
|
20
40
|
|
|
21
41
|
instance_eval do
|
|
22
|
-
|
|
42
|
+
# Configuring the same model twice keeps the first set of roles.
|
|
43
|
+
const_set('ROLES', (roles + [:user]).uniq.map(&:to_sym)) unless const_defined?(:ROLES, false)
|
|
23
44
|
|
|
24
45
|
if multiple
|
|
25
46
|
roles.each do |role|
|
|
@@ -39,7 +60,7 @@ module Petergate
|
|
|
39
60
|
|
|
40
61
|
if multiple
|
|
41
62
|
def roles=(v)
|
|
42
|
-
self[:roles] = (Array(v).map(&:to_sym).select{|r| r.size > 0 && available_roles.include?(r)} + [:user]).uniq
|
|
63
|
+
self[:roles] = (Array(v).compact.map(&:to_sym).select{|r| r.size > 0 && available_roles.include?(r)} + [:user]).uniq
|
|
43
64
|
end
|
|
44
65
|
else
|
|
45
66
|
def roles=(v)
|
|
@@ -48,8 +69,8 @@ module Petergate
|
|
|
48
69
|
v
|
|
49
70
|
when "Array"
|
|
50
71
|
v.first
|
|
51
|
-
end
|
|
52
|
-
self[:roles] = available_roles.include?(r) ? r : :user
|
|
72
|
+
end&.to_sym
|
|
73
|
+
self[:roles] = available_roles.include?(r) ? r : :user
|
|
53
74
|
end
|
|
54
75
|
end
|
|
55
76
|
|
|
@@ -82,6 +103,8 @@ module Petergate
|
|
|
82
103
|
end
|
|
83
104
|
end
|
|
84
105
|
|
|
85
|
-
|
|
106
|
+
# Hook in lazily so ActiveRecord::Base is not forced to load during boot,
|
|
107
|
+
# before the app has finished applying its own `config.active_record` settings.
|
|
108
|
+
ActiveSupport.on_load(:active_record) do
|
|
86
109
|
include Petergate::ActiveRecord::Base
|
|
87
110
|
end
|
data/lib/petergate/version.rb
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
<% end -%>
|
|
1
|
+
<%# 422 is written numerically on purpose. Rack 2.2 knows only
|
|
2
|
+
:unprocessable_entity and Rack 3.2 only :unprocessable_content, and this
|
|
3
|
+
template has to serve apps on either. -%>
|
|
5
4
|
<% module_namespacing do -%>
|
|
6
5
|
class <%= controller_class_name %>Controller < ApplicationController
|
|
7
|
-
before_action :set_<%= singular_table_name %>, only: [
|
|
6
|
+
before_action :set_<%= singular_table_name %>, only: %i[ show edit update destroy ]
|
|
8
7
|
access all: [:index, :show, :new, :edit, :create, :update, :destroy], user: :all
|
|
9
8
|
|
|
10
9
|
# GET <%= route_url %>
|
|
@@ -32,23 +31,23 @@ class <%= controller_class_name %>Controller < ApplicationController
|
|
|
32
31
|
if @<%= orm_instance.save %>
|
|
33
32
|
redirect_to @<%= singular_table_name %>, notice: <%= "'#{human_name} was successfully created.'" %>
|
|
34
33
|
else
|
|
35
|
-
render :new
|
|
34
|
+
render :new, status: 422
|
|
36
35
|
end
|
|
37
36
|
end
|
|
38
37
|
|
|
39
38
|
# PATCH/PUT <%= route_url %>/1
|
|
40
39
|
def update
|
|
41
40
|
if @<%= orm_instance.update("#{singular_table_name}_params") %>
|
|
42
|
-
redirect_to @<%= singular_table_name %>, notice: <%= "'#{human_name} was successfully updated.'"
|
|
41
|
+
redirect_to @<%= singular_table_name %>, notice: <%= "'#{human_name} was successfully updated.'" %>, status: :see_other
|
|
43
42
|
else
|
|
44
|
-
render :edit
|
|
43
|
+
render :edit, status: 422
|
|
45
44
|
end
|
|
46
45
|
end
|
|
47
46
|
|
|
48
47
|
# DELETE <%= route_url %>/1
|
|
49
48
|
def destroy
|
|
50
49
|
@<%= orm_instance.destroy %>
|
|
51
|
-
redirect_to <%= index_helper %>
|
|
50
|
+
redirect_to <%= index_helper %>_path, notice: <%= "'#{human_name} was successfully destroyed.'" %>, status: :see_other
|
|
52
51
|
end
|
|
53
52
|
|
|
54
53
|
private
|
|
@@ -57,10 +56,10 @@ class <%= controller_class_name %>Controller < ApplicationController
|
|
|
57
56
|
@<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
|
|
58
57
|
end
|
|
59
58
|
|
|
60
|
-
# Only allow a
|
|
59
|
+
# Only allow a list of trusted parameters through.
|
|
61
60
|
def <%= "#{singular_table_name}_params" %>
|
|
62
61
|
<%- if attributes_names.empty? -%>
|
|
63
|
-
params
|
|
62
|
+
params.fetch(:<%= singular_table_name %>, {})
|
|
64
63
|
<%- else -%>
|
|
65
64
|
params.require(:<%= singular_table_name %>).permit(<%= attributes_names.map { |name| ":#{name}" }.join(', ') %>)
|
|
66
65
|
<%- end -%>
|
data/petergate.gemspec
CHANGED
|
@@ -10,15 +10,38 @@ Gem::Specification.new do |spec|
|
|
|
10
10
|
spec.email = ["isaac@isaacsloan.com"]
|
|
11
11
|
spec.summary = %q{Authorization system allowing verbose easy read controller syntax.}
|
|
12
12
|
spec.description = %q{If you like the straight forward and effective nature of Strong Parameters and suspect that CanCan might be overkill for your project then you'll love Petergate's easy to use and read action and content based authorizations.}
|
|
13
|
-
spec.homepage = "https://github.com/
|
|
13
|
+
spec.homepage = "https://github.com/elorest/petergate"
|
|
14
14
|
spec.license = "MIT"
|
|
15
|
+
spec.metadata = {
|
|
16
|
+
"source_code_uri" => "https://github.com/elorest/petergate",
|
|
17
|
+
"bug_tracker_uri" => "https://github.com/elorest/petergate/issues",
|
|
18
|
+
}
|
|
15
19
|
|
|
16
|
-
|
|
20
|
+
# assets/ holds the README's images, which the README loads from GitHub. They
|
|
21
|
+
# are 350K of PNG that no runtime code touches, so they stay out of the gem --
|
|
22
|
+
# they only shipped at all because moving them out of dummy/, which was
|
|
23
|
+
# excluded here, put them on the default path.
|
|
24
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |p| p.start_with?("test/", "gemfiles/", ".github/", "assets/") }
|
|
17
25
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
18
26
|
spec.require_paths = ["lib"]
|
|
19
27
|
spec.post_install_message = "NOTICE: As of version 1.5.0, the :admin role has been changed to :root_admin."
|
|
20
28
|
|
|
21
29
|
spec.add_development_dependency "bundler", "> 1.7"
|
|
22
|
-
spec.add_development_dependency "rake", "
|
|
23
|
-
|
|
30
|
+
spec.add_development_dependency "rake", ">= 12.3"
|
|
31
|
+
|
|
32
|
+
# petergate reopens ActionController (actionpack), calls String#pluralize
|
|
33
|
+
# (activesupport), and subclasses Rails::Railtie (railties), so all three are
|
|
34
|
+
# real runtime dependencies -- not just activerecord.
|
|
35
|
+
#
|
|
36
|
+
# 6.1 is the real floor, not a conservative one. `serialize :roles, coder:
|
|
37
|
+
# YAML` needs a serialize that accepts keywords: 6.1 and 7.0 swallow the
|
|
38
|
+
# unknown one and fall through to YAMLColumn.new(:roles, Object), and 7.1
|
|
39
|
+
# added coder: for real. On 6.0 and earlier the signature is
|
|
40
|
+
# serialize(attr_name, class_name_or_coder = Object) with no **options, so
|
|
41
|
+
# Ruby binds the hash to the positional argument and the model raises
|
|
42
|
+
# NoMethodError on load. CI covers 7.1 through 8.1.
|
|
43
|
+
spec.add_dependency "activerecord", ">= 6.1"
|
|
44
|
+
spec.add_dependency "actionpack", ">= 6.1"
|
|
45
|
+
spec.add_dependency "activesupport", ">= 6.1"
|
|
46
|
+
spec.add_dependency "railties", ">= 6.1"
|
|
24
47
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: petergate
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Isaac Sloan
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: bundler
|
|
@@ -28,30 +27,72 @@ dependencies:
|
|
|
28
27
|
name: rake
|
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
|
30
29
|
requirements:
|
|
31
|
-
- - "
|
|
30
|
+
- - ">="
|
|
32
31
|
- !ruby/object:Gem::Version
|
|
33
32
|
version: '12.3'
|
|
34
33
|
type: :development
|
|
35
34
|
prerelease: false
|
|
36
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
36
|
requirements:
|
|
38
|
-
- - "
|
|
37
|
+
- - ">="
|
|
39
38
|
- !ruby/object:Gem::Version
|
|
40
39
|
version: '12.3'
|
|
41
40
|
- !ruby/object:Gem::Dependency
|
|
42
41
|
name: activerecord
|
|
43
42
|
requirement: !ruby/object:Gem::Requirement
|
|
44
43
|
requirements:
|
|
45
|
-
- - "
|
|
44
|
+
- - ">="
|
|
46
45
|
- !ruby/object:Gem::Version
|
|
47
|
-
version:
|
|
46
|
+
version: '6.1'
|
|
48
47
|
type: :runtime
|
|
49
48
|
prerelease: false
|
|
50
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
50
|
requirements:
|
|
52
|
-
- - "
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '6.1'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: actionpack
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '6.1'
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '6.1'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: activesupport
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '6.1'
|
|
75
|
+
type: :runtime
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '6.1'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: railties
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - ">="
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '6.1'
|
|
89
|
+
type: :runtime
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - ">="
|
|
53
94
|
- !ruby/object:Gem::Version
|
|
54
|
-
version:
|
|
95
|
+
version: '6.1'
|
|
55
96
|
description: If you like the straight forward and effective nature of Strong Parameters
|
|
56
97
|
and suspect that CanCan might be overkill for your project then you'll love Petergate's
|
|
57
98
|
easy to use and read action and content based authorizations.
|
|
@@ -63,7 +104,6 @@ extra_rdoc_files: []
|
|
|
63
104
|
files:
|
|
64
105
|
- ".gitignore"
|
|
65
106
|
- ".ruby-version"
|
|
66
|
-
- ".travis.yml"
|
|
67
107
|
- Gemfile
|
|
68
108
|
- LICENSE.txt
|
|
69
109
|
- README.md
|
|
@@ -77,10 +117,12 @@ files:
|
|
|
77
117
|
- lib/petergate/version.rb
|
|
78
118
|
- lib/templates/rails/scaffold_controller/controller.rb
|
|
79
119
|
- petergate.gemspec
|
|
80
|
-
homepage: https://github.com/
|
|
120
|
+
homepage: https://github.com/elorest/petergate
|
|
81
121
|
licenses:
|
|
82
122
|
- MIT
|
|
83
|
-
metadata:
|
|
123
|
+
metadata:
|
|
124
|
+
source_code_uri: https://github.com/elorest/petergate
|
|
125
|
+
bug_tracker_uri: https://github.com/elorest/petergate/issues
|
|
84
126
|
post_install_message: 'NOTICE: As of version 1.5.0, the :admin role has been changed
|
|
85
127
|
to :root_admin.'
|
|
86
128
|
rdoc_options: []
|
|
@@ -97,8 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
97
139
|
- !ruby/object:Gem::Version
|
|
98
140
|
version: '0'
|
|
99
141
|
requirements: []
|
|
100
|
-
rubygems_version: 3.
|
|
101
|
-
signing_key:
|
|
142
|
+
rubygems_version: 3.6.9
|
|
102
143
|
specification_version: 4
|
|
103
144
|
summary: Authorization system allowing verbose easy read controller syntax.
|
|
104
145
|
test_files: []
|