petergate 3.0.1 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 03b0b048bf5f3fa47709ea1ee62839a0a4fb793eaa5cd054435a4765f39d5529
4
- data.tar.gz: 6252d26aa0f3009ceb36b7f77070920a58b4f8f16dc7d345c4ed5b8a151efe73
3
+ metadata.gz: 458fdd69a1955dde44434ec3ba661af445de0b754b09b8d61dfd7e959ba33632
4
+ data.tar.gz: 5b99cfc5fb9d622d9b9b47a9777b3fe3bc51bc520b45ee52a29dfdbc633b3c7d
5
5
  SHA512:
6
- metadata.gz: 530ffc1078e0999fef2fd48d0041c8754fd4f7b6e95ed2d55ea187dc4affd1d7257071f28e3997d4b42457b090fe4f94f04ae8049bf5bfe6ec322e9cedfd3447
7
- data.tar.gz: cf64dfce82b8358c162555a5c5bdde118520b4308d09f382c21b9a72a17b805e4a01b665644a6edb9006f17d886dd1a45ed772847b007f1f8dbb6a9cdca2f5af
6
+ metadata.gz: af0027d006aa080fe77ce5467ac3ec036d84d2ad3211caf21d267914fc18b46680ff3722dbc855801b7026bfdeeb420ffc5e53cac10611f78a82d063d2178486
7
+ data.tar.gz: 686f7f73c012fc240a9734599cd2106e35dbe0b0694bff964aab9114fb3f8de9ff78a7a83dfcc57a39c10cce7c124cb05a592a2a5594dbe763cc198d0cc513fb
data/.gitignore CHANGED
@@ -6,8 +6,6 @@ Gemfile.lock
6
6
  /doc/
7
7
  /pkg/
8
8
  /spec/reports/
9
- dummy/log/*
10
- dummy/tmp/*
11
9
  *.sqlite3
12
10
  *.bundle
13
11
  *.so
@@ -16,3 +14,5 @@ dummy/tmp/*
16
14
  mkmf.log
17
15
  *.gem
18
16
  .DS_Store
17
+ /tmp/
18
+ gemfiles/*.lock
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.4.2
1
+ 3.2.0
data/Gemfile CHANGED
@@ -1,43 +1,16 @@
1
- source 'https://rubygems.org'
2
- ruby '3.2.0'
1
+ source "https://rubygems.org"
3
2
 
4
- # Specify your gem's dependencies in petergate.gemspec
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
- [![Petergate](https://github.com/elorest/petergate/blob/master/dummy/public/petergate.png)](https://github.com/elorest/petergate)
1
+ [![Petergate](https://raw.githubusercontent.com/elorest/petergate/master/assets/petergate.png)](https://github.com/elorest/petergate)
2
2
 
3
- [![Build Status](https://travis-ci.org/elorest/petergate.svg)](https://travis-ci.org/dburnsii/petergate)
4
- [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/isaacsloan/petergate?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
3
+ [![CI](https://github.com/elorest/petergate/actions/workflows/ci.yml/badge.svg)](https://github.com/elorest/petergate/actions/workflows/ci.yml)
5
4
  [![Gem Version](https://badge.fury.io/rb/petergate.svg)](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/isaacsloan/petergate) easy to use and read action and content based authorizations."
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
- Make sure your user model is defined in
31
- app/models/user.rb
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/plataformatec/devise) you're in luck, otherwise you'll have to add following methods to your project:
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, :editors) # returns true if user is any of roles passed in as params.
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
- `User.#{role}_editors => #list of editors. Method is created for all roles. Roles [admin, :teacher] will have corresponding methods role_admins, role_teachers, etc.`
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
- # or from an instance
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
- = form_for @user do |f|
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.text_field :password
175
+ = f.password_field :password
139
176
  .field
140
177
  = f.label :password_confirmation
141
- = f.text_field :password_confirmation
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
- = form_for @user do |f|
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.text_field :password
202
+ = f.password_field :password
166
203
  .field
167
204
  = f.label :password_confirmation
168
- = f.text_field :password_confirmation
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 maintaned by Isaac Sloan and friends.
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/isaacsloan/petergate/fork )
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 'rake/testtask'
2
+ require "rake/testtask"
3
3
 
4
4
  Rake::TestTask.new(:test) do |t|
5
- t.pattern = 'dummy/test/**/*_test.rb'
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
- destination = current_user.present? ? request.headers['Referrer'] || after_sign_in_path_for(current_user) : root_path
127
- redirect_to destination, notice: (msg || request.headers['msg'] || custom_message)
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
- class ActionController::Base
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,7 +6,27 @@ 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
31
  serialize :roles, coder: YAML
12
32
  after_initialize do
@@ -19,7 +39,8 @@ module Petergate
19
39
  end
20
40
 
21
41
  instance_eval do
22
- const_set('ROLES', (roles + [:user]).uniq.map(&:to_sym)) unless defined?(User::ROLES)
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.to_sym
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
- class ActiveRecord::Base
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
@@ -1,3 +1,3 @@
1
1
  module Petergate
2
- VERSION = "3.0.1"
2
+ VERSION = "3.1.0"
3
3
  end
@@ -1,10 +1,9 @@
1
- <% if namespaced? -%>
2
- require_dependency "<%= namespaced_file_path %>/application_controller"
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: [:show, :edit, :update, :destroy]
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 %>_url, notice: <%= "'#{human_name} was successfully destroyed.'" %>
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 trusted parameter "white list" through.
59
+ # Only allow a list of trusted parameters through.
61
60
  def <%= "#{singular_table_name}_params" %>
62
61
  <%- if attributes_names.empty? -%>
63
- params[:<%= singular_table_name %>]
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/isaacsloan/petergate"
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
- spec.files = `git ls-files -z`.split("\x0").delete_if{|p| p.include?("dummy/")}
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", "~> 12.3"
23
- spec.add_dependency 'activerecord', "> 4.0.0"
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,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: petergate
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.1
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Isaac Sloan
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-06-20 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: bundler
@@ -27,30 +27,72 @@ dependencies:
27
27
  name: rake
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
- - - "~>"
30
+ - - ">="
31
31
  - !ruby/object:Gem::Version
32
32
  version: '12.3'
33
33
  type: :development
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
- - - "~>"
37
+ - - ">="
38
38
  - !ruby/object:Gem::Version
39
39
  version: '12.3'
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: activerecord
42
42
  requirement: !ruby/object:Gem::Requirement
43
43
  requirements:
44
- - - ">"
44
+ - - ">="
45
45
  - !ruby/object:Gem::Version
46
- version: 4.0.0
46
+ version: '6.1'
47
47
  type: :runtime
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - ">"
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
+ - - ">="
52
94
  - !ruby/object:Gem::Version
53
- version: 4.0.0
95
+ version: '6.1'
54
96
  description: If you like the straight forward and effective nature of Strong Parameters
55
97
  and suspect that CanCan might be overkill for your project then you'll love Petergate's
56
98
  easy to use and read action and content based authorizations.
@@ -62,7 +104,6 @@ extra_rdoc_files: []
62
104
  files:
63
105
  - ".gitignore"
64
106
  - ".ruby-version"
65
- - ".travis.yml"
66
107
  - Gemfile
67
108
  - LICENSE.txt
68
109
  - README.md
@@ -76,10 +117,12 @@ files:
76
117
  - lib/petergate/version.rb
77
118
  - lib/templates/rails/scaffold_controller/controller.rb
78
119
  - petergate.gemspec
79
- homepage: https://github.com/isaacsloan/petergate
120
+ homepage: https://github.com/elorest/petergate
80
121
  licenses:
81
122
  - MIT
82
- metadata: {}
123
+ metadata:
124
+ source_code_uri: https://github.com/elorest/petergate
125
+ bug_tracker_uri: https://github.com/elorest/petergate/issues
83
126
  post_install_message: 'NOTICE: As of version 1.5.0, the :admin role has been changed
84
127
  to :root_admin.'
85
128
  rdoc_options: []
@@ -96,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
139
  - !ruby/object:Gem::Version
97
140
  version: '0'
98
141
  requirements: []
99
- rubygems_version: 3.6.2
142
+ rubygems_version: 3.6.9
100
143
  specification_version: 4
101
144
  summary: Authorization system allowing verbose easy read controller syntax.
102
145
  test_files: []
data/.travis.yml DELETED
@@ -1,5 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - "2.5.1"
4
- before_script: "bundle install && cd dummy && rake db:create && rake db:migrate"
5
- script: "bundle exec rake test"