action_permission 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +165 -0
- data/Rakefile +1 -0
- data/action_permission.gemspec +25 -0
- data/lib/action_permission/base.rb +71 -0
- data/lib/action_permission/controller.rb +56 -0
- data/lib/action_permission/dispatch.rb +96 -0
- data/lib/action_permission/railtie.rb +21 -0
- data/lib/action_permission/version.rb +3 -0
- data/lib/action_permission.rb +4 -0
- data/lib/generators/action_permission/install/USAGE +3 -0
- data/lib/generators/action_permission/install/install_generator.rb +37 -0
- data/lib/generators/action_permission/install/templates/application.rb +32 -0
- data/lib/generators/action_permission/permission/USAGE +2 -0
- data/lib/generators/action_permission/permission/permission_generator.rb +14 -0
- data/lib/generators/action_permission/permission/templates/permission.rb +45 -0
- data/lib/generators/rails/USAGE +16 -0
- data/lib/generators/rails/action_permission_controller_generator.rb +17 -0
- data/lib/generators/rails/templates/controller.rb +98 -0
- data/spec/base_spec.rb +108 -0
- data/spec/controller_spec.rb +101 -0
- data/spec/dispatch_spec.rb +164 -0
- data/spec/spec_helper.rb +43 -0
- metadata +148 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2d598921d73d8ca53edf5154616e27108e9b9ef7
|
4
|
+
data.tar.gz: baaba6a7c5792c1f22433c768ab391cdec09cc0a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9de568d75f1b7871776526e385f35b5fa06e613cc78f745fcf7682b21f63e8ecab21639795572293c9a45f0a65429f1ebfb237da25231e55f6e9c2bdef9d9a89
|
7
|
+
data.tar.gz: 2cc23db2ada4942dde384df738c93168c69c4255b12e8a174dc4434bbef6048f59d3dbac791606a303387077402716718fb8ea43168faafe0bc039e9aecd1c99
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Matt Duffy
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
__NOTICE: The gem as it stands is not production-ready.__
|
2
|
+
_See [issues](https://github.com/mttdffy/action_permission/issues) for details_
|
3
|
+
|
4
|
+
----
|
5
|
+
|
6
|
+
# ActionPermission
|
7
|
+
|
8
|
+
A permission structure for defining both action-based and attribute-based permissions for rails 3+ applications.
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
gem 'action_permission'
|
16
|
+
```
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
```sh
|
21
|
+
$ bundle
|
22
|
+
$ rails generate action_permission:install
|
23
|
+
```
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
ActionPermission assumes you have the concept of user roles. This can be any field of any name. It's core action is to load permissions for the controller handling the request, determine the user's access level, and call a method on the permission object that corresponds to that level. A permission file might look like this:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
class BookPermission < ApplicationPermission
|
31
|
+
|
32
|
+
def params
|
33
|
+
[:name, :author, :isbn, :page_count, :price]
|
34
|
+
end
|
35
|
+
|
36
|
+
def guest
|
37
|
+
allow [:index, :show]
|
38
|
+
end
|
39
|
+
|
40
|
+
def user
|
41
|
+
allow [:index, :show, :new]
|
42
|
+
allow [:create, :edit, :update, :destroy] do |user|
|
43
|
+
@membership.id == user.id
|
44
|
+
end
|
45
|
+
allow_params except: [:price]
|
46
|
+
end
|
47
|
+
|
48
|
+
def admin
|
49
|
+
allow_rest_actions
|
50
|
+
allow_params
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
```
|
55
|
+
|
56
|
+
- the `params` method can be used to define attributes allowed to be modified by that user level in addition to their allowed actions.
|
57
|
+
- the `@membership` attribute is set on initialization based on the method handed to `authorize_with` in your `ApplicationController` (See 'Setup' below)
|
58
|
+
|
59
|
+
|
60
|
+
## Setup
|
61
|
+
|
62
|
+
```sh
|
63
|
+
$ rails generate action_permission:install
|
64
|
+
```
|
65
|
+
|
66
|
+
This generator will creating the `app/permissions` directory along with a `application_perimission.rb` file.
|
67
|
+
|
68
|
+
Permissions should be placed in the `app/permissions` directory. Each permission will typically extend from `ApplicationPermission`, allowing you to set default permissions for each role.
|
69
|
+
|
70
|
+
Additionally, the install generator will add some boilerplate code into your `ApplicationController` for setting up your application to work properly with ActionPermission.
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
#app/controllers/application_controller.rb
|
74
|
+
|
75
|
+
authorize_with :current_user
|
76
|
+
before_action :check_permission
|
77
|
+
|
78
|
+
def current_user
|
79
|
+
@current_user ||= session[:user_id] ? User.find(session[:user_id]) : User.new
|
80
|
+
end
|
81
|
+
|
82
|
+
def check_permission
|
83
|
+
unless authorized?
|
84
|
+
#do something when user does not have permission to access page
|
85
|
+
# Flash[:warn] = "You do not have permission to access this page."
|
86
|
+
# redirect_to root_url
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
```
|
91
|
+
|
92
|
+
This is a basic implementation that you can change and modify to work with your application's user role structure.
|
93
|
+
|
94
|
+
Ultimately, ActionPermission looks to receive a string representing the name of the role/level of current user. It requires you to define a method on your `ApplicationController` to call when loading permissions. This method should return an object that can repond to a `#identify` method. `identify` method should return a string value of the current user's role
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
# app/models/user.rb
|
98
|
+
class User < ActiveRecord::Base
|
99
|
+
|
100
|
+
# assume User#role exists as a string representation
|
101
|
+
# of what role that user is
|
102
|
+
|
103
|
+
def identify
|
104
|
+
role || "guest"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
```
|
109
|
+
|
110
|
+
Alternatively, you can overwrite `ActionPermission::Base#load` in the `ApplicationPermission` class to define your own way of determining a method to call.
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
class ApplicationPermission < ActionPermission::Base
|
114
|
+
|
115
|
+
def load(user)
|
116
|
+
@membership = user
|
117
|
+
send @membership.role
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
```
|
123
|
+
|
124
|
+
Once you have it setup, your controller has access to an `authorized?` method which will tell you if the current user has permission to access the current action
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
# app/controllers/application_controller.rb
|
128
|
+
ApplicationController < ActionController::Base
|
129
|
+
|
130
|
+
before_action :check_permissions
|
131
|
+
|
132
|
+
def check_permissions
|
133
|
+
unless authorized?
|
134
|
+
flash[:warn] = "You do not have permission to access this page"
|
135
|
+
rediect_to root_url
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
```
|
140
|
+
|
141
|
+
## Generators
|
142
|
+
|
143
|
+
rails g action_permission:install
|
144
|
+
|
145
|
+
This will add the base application_permission.rb file as well as add some boilerplate code to the application controller
|
146
|
+
|
147
|
+
rails g action_permission:permission CONTROLLER [attribute, attribute, ...]
|
148
|
+
|
149
|
+
rails g action_permission:permission users username name email role password_digest
|
150
|
+
|
151
|
+
This will generate a permission file for the supplied controller. YOu can pass in attributes to auto populate the params method for that permission object. In the future this will be added onto the scaffolding generator so you don't have to run this seperately
|
152
|
+
|
153
|
+
## Contributors
|
154
|
+
|
155
|
+
- [Matt Duffy](https://github.com/mttdffy)
|
156
|
+
- [Brian McElaney](https://github.com/mcelaney)
|
157
|
+
- [Mark Platt](https://github.com/mrkplt)
|
158
|
+
|
159
|
+
## Contributing
|
160
|
+
|
161
|
+
1. Fork it
|
162
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
163
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
164
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
165
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'action_permission/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "action_permission"
|
8
|
+
spec.version = ActionPermission::VERSION
|
9
|
+
spec.authors = ["Matt Duffy", "Brian McElaney", "Mark Platt"]
|
10
|
+
spec.email = ["matt@mttdffy.com", "", ""]
|
11
|
+
spec.summary = "Controller-based action and attribute permissions"
|
12
|
+
spec.homepage = "https://github.com/mttdffy/action_permission"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files`.split($/)
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_dependency "rails", "~> 4"
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec", "~> 2"
|
24
|
+
spec.add_development_dependency "activerecord-nulldb-adapter"
|
25
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module ActionPermission
|
2
|
+
|
3
|
+
class Base
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
def match_with source,to
|
8
|
+
Array(to).each do |role|
|
9
|
+
alias_method role, source
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_accessor :membership
|
16
|
+
attr_reader :allowed_params, :allowed_actions
|
17
|
+
|
18
|
+
def initialize(membership)
|
19
|
+
load membership
|
20
|
+
end
|
21
|
+
|
22
|
+
def load(membership)
|
23
|
+
@membership = membership
|
24
|
+
role = @membership.identify
|
25
|
+
if role && respond_to?(role)
|
26
|
+
send(role)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def allow?(action, resource = nil)
|
31
|
+
allowed = @allowed_actions[action.to_s] if @allowed_actions
|
32
|
+
allowed && (allowed == true || resource && allowed.call(resource))
|
33
|
+
end
|
34
|
+
|
35
|
+
def allow(actions, &block)
|
36
|
+
@allowed_actions ||= {}
|
37
|
+
Array(actions).each do |action|
|
38
|
+
@allowed_actions[action.to_s] = block || true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def allow_rest_actions(&block)
|
43
|
+
allow [:index, :new, :create, :show, :edit, :update, :destroy], &block
|
44
|
+
end
|
45
|
+
|
46
|
+
def params
|
47
|
+
[]
|
48
|
+
end
|
49
|
+
|
50
|
+
def allow_params options=nil
|
51
|
+
@allowed_params ||= []
|
52
|
+
|
53
|
+
if options
|
54
|
+
@allowed_params = allow_params_with_options options
|
55
|
+
else
|
56
|
+
@allowed_params = Array(params)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def allow_params_with_options options
|
63
|
+
alt_params = params
|
64
|
+
alt_params = Array(options[:only]) if options[:only]
|
65
|
+
Array(options[:except]).each {|e| alt_params.delete e } if options[:except]
|
66
|
+
alt_params
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'active_support/core_ext/object'
|
2
|
+
require 'active_support/dependencies'
|
3
|
+
require 'abstract_controller/helpers'
|
4
|
+
|
5
|
+
module ActionPermission
|
6
|
+
|
7
|
+
module Controller
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
include AbstractController::Helpers
|
10
|
+
|
11
|
+
included do
|
12
|
+
delegate :allow?, to: :current_permission
|
13
|
+
delegate :allow_param?, to: :current_permission
|
14
|
+
delegate :allowed_params_for, to: :current_permission
|
15
|
+
helper_method :allow?
|
16
|
+
helper_method :allow_param?
|
17
|
+
helper_method :current_permission
|
18
|
+
end
|
19
|
+
|
20
|
+
module ClassMethods
|
21
|
+
|
22
|
+
def authorize_with authorizer
|
23
|
+
helper_method authorizer
|
24
|
+
@@permission_authorizer = authorizer
|
25
|
+
end
|
26
|
+
|
27
|
+
def permission_authorizer
|
28
|
+
@@permission_authorizer
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
def current_resource
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
|
37
|
+
def current_permission
|
38
|
+
@current_permission ||= ActionPermission::Dispatch.new(permission_authorizer)
|
39
|
+
end
|
40
|
+
|
41
|
+
def authorized?
|
42
|
+
current_permission.allow?(params[:controller], params[:action], current_resource)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def permission_authorizer
|
48
|
+
send self.class.permission_authorizer
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
ActionController::Base.send :include, ActionPermission::Controller if ENV['RAILS']
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'active_support/hash_with_indifferent_access'
|
2
|
+
require 'active_support/inflector'
|
3
|
+
|
4
|
+
module ActionPermission
|
5
|
+
|
6
|
+
class Dispatch
|
7
|
+
attr_accessor :membership, :permissions
|
8
|
+
|
9
|
+
def initialize(membership)
|
10
|
+
@membership = membership
|
11
|
+
@permissions = HashWithIndifferentAccess.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def allow?(controller, action, resource = nil)
|
15
|
+
current_permission = load_permission controller
|
16
|
+
|
17
|
+
if resource
|
18
|
+
current_permission.allow?(action, resource)
|
19
|
+
else !resource
|
20
|
+
current_permission.allow?(action)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# 'book/review', params #=> controller == 'books/reviews'
|
25
|
+
# 'book/review', params, 'reviews' #=> controller == 'reviews'
|
26
|
+
def allowed_params_for(resource, params, controller=nil)
|
27
|
+
controller = set_controller(resource, controller)
|
28
|
+
resource = set_resource(resource)
|
29
|
+
|
30
|
+
current_permission = load_permission(controller)
|
31
|
+
|
32
|
+
if current_permission && current_permission.allowed_params
|
33
|
+
params.require(resource).permit *current_permission.allowed_params
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def allow_param?(resource, attribute)
|
38
|
+
current_permission = load_permission resource.to_s.pluralize
|
39
|
+
|
40
|
+
if current_permission && current_permission.allowed_params
|
41
|
+
current_permission.allowed_params.include? attribute
|
42
|
+
else
|
43
|
+
false
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def set_controller(resource, controller)
|
50
|
+
if controller
|
51
|
+
case controller
|
52
|
+
when String, Symbol
|
53
|
+
controller.to_s.pluralize
|
54
|
+
else
|
55
|
+
(controller.is_a?(Class) ? controller : controller.class).
|
56
|
+
name.underscore.gsub('_controller', '')
|
57
|
+
end
|
58
|
+
else
|
59
|
+
case resource
|
60
|
+
when String, Symbol
|
61
|
+
resource.to_s
|
62
|
+
else
|
63
|
+
(resource.is_a?(Class) ? resource : resource.class).
|
64
|
+
name.underscore
|
65
|
+
end.
|
66
|
+
split('/').map(&:pluralize).join('/')
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def set_resource(resource)
|
71
|
+
case resource
|
72
|
+
when String, Symbol
|
73
|
+
resource.to_s.parameterize("_")
|
74
|
+
else
|
75
|
+
(resource.is_a?(Class) ? resource : resource.class).model_name.param_key
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def load_permission(controller)
|
80
|
+
klass = get_class_name(controller)
|
81
|
+
# grab the permissions for this controller from cache or register it if missing
|
82
|
+
@permissions[controller] ||= register_permission(controller, klass)
|
83
|
+
end
|
84
|
+
|
85
|
+
def get_class_name(controller)
|
86
|
+
controller = controller.to_s
|
87
|
+
return (controller.pluralize + "_permissions").classify.constantize
|
88
|
+
end
|
89
|
+
|
90
|
+
def register_permission(controller, klass)
|
91
|
+
@permissions[controller] = klass.new(@membership)
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rails/railtie'
|
2
|
+
|
3
|
+
module ActionPermission
|
4
|
+
class Railtie < ::Rails::Railtie
|
5
|
+
if config.respond_to?(:app_generators)
|
6
|
+
config.app_generators.scaffold_controller = :action_permission_controller
|
7
|
+
else
|
8
|
+
config.generators.scaffold_controller = :action_permission_controller
|
9
|
+
end
|
10
|
+
|
11
|
+
# initializer 'activeservice.autoload', :before => :set_autoload_paths do |app|
|
12
|
+
# app.config.autoload_paths << (app.config.root + '/app/permissions')
|
13
|
+
# end
|
14
|
+
|
15
|
+
# initializer "strong_parameters.config", :before => "action_controller.set_configs" do |app|
|
16
|
+
# ActionController::Parameters.action_on_unpermitted_parameters = app.config.action_controller.delete(:action_on_unpermitted_parameters) do
|
17
|
+
# (Rails.env.test? || Rails.env.development?) ? :log : false
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'rails/generators/base'
|
2
|
+
|
3
|
+
module ActionPermission
|
4
|
+
module Generators
|
5
|
+
|
6
|
+
class InstallGenerator < Rails::Generators::Base
|
7
|
+
p "creating permissions directory"
|
8
|
+
source_root File.expand_path("../templates", __FILE__)
|
9
|
+
|
10
|
+
def copy_application_file
|
11
|
+
copy_file "application.rb", "app/permissions/application_permission.rb"
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_controller_setup
|
15
|
+
line = /class ApplicationController \< ActionController\:\:Base\n/
|
16
|
+
inject_into_file 'app/controllers/application_controller.rb', after: line do <<-'RUBY'
|
17
|
+
authorize_with :current_user
|
18
|
+
before_action :check_permission
|
19
|
+
|
20
|
+
def current_user
|
21
|
+
@current_user ||= session[:user_id] ? User.find(session[:user_id]) : User.new
|
22
|
+
end
|
23
|
+
|
24
|
+
def check_permission
|
25
|
+
unless authorized?
|
26
|
+
#do something when user does not have permission to access page
|
27
|
+
# Flash[:warn] = "You do not have permission to access this page."
|
28
|
+
# redirect_to root_url
|
29
|
+
end
|
30
|
+
end
|
31
|
+
RUBY
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class ApplicationPermission < ActionPermission::Base
|
2
|
+
|
3
|
+
# Your base permission file
|
4
|
+
# You can use this file to set default permissions
|
5
|
+
# or overwrite the #load method to manually determine which
|
6
|
+
# methods of a permission file are called for each user role
|
7
|
+
|
8
|
+
# example overwrite method
|
9
|
+
# def load(user)
|
10
|
+
# @membership = user
|
11
|
+
# send (@membership.role) || "guest"
|
12
|
+
# end
|
13
|
+
|
14
|
+
# default permissions
|
15
|
+
|
16
|
+
# def guest
|
17
|
+
# allow [:show]
|
18
|
+
# end
|
19
|
+
|
20
|
+
# def user
|
21
|
+
# allow_rest_actions do |user|
|
22
|
+
# @membership.id == user.id
|
23
|
+
# end
|
24
|
+
# allow_params
|
25
|
+
# end
|
26
|
+
|
27
|
+
# def admin
|
28
|
+
# allow_rest_actions
|
29
|
+
# allow_params
|
30
|
+
# end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rails/generators/named_base'
|
2
|
+
|
3
|
+
module ActionPermission
|
4
|
+
module Generators
|
5
|
+
class PermissionGenerator < Rails::Generators::NamedBase
|
6
|
+
argument :attributes, type: :array, default: [], banner: "field field"
|
7
|
+
source_root File.expand_path("../templates", __FILE__)
|
8
|
+
|
9
|
+
def create_permission_file
|
10
|
+
template "permission.rb", "app/permissions/#{file_name}_permission.rb"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
<% module_namespacing do -%>
|
2
|
+
class <%= class_name %>Permission < ApplicationPermission
|
3
|
+
|
4
|
+
# defines parameters for requests coming to associated object/controlelr
|
5
|
+
# typically defines all attributes and uses except option to exclude
|
6
|
+
# params on a per-role basis
|
7
|
+
def params
|
8
|
+
[<%= attributes.map {|a| ":#{a.name}" }.sort.join(', ') %>]
|
9
|
+
end
|
10
|
+
|
11
|
+
# define methods for each of your user roles here
|
12
|
+
|
13
|
+
# allow [:actions]
|
14
|
+
# defines routes allowed for that role
|
15
|
+
# an optional block can be passed to allow to check
|
16
|
+
# things like ownership.
|
17
|
+
|
18
|
+
# allow_params
|
19
|
+
# options: [:except, :only]
|
20
|
+
# define params user role can change
|
21
|
+
# no options gives access to all of #params
|
22
|
+
# except excludes any listed
|
23
|
+
# only overwrites params array
|
24
|
+
|
25
|
+
# @membership is available as the object returned from
|
26
|
+
# method passed to ActionPermission::Controller#authorize_with
|
27
|
+
|
28
|
+
def guest
|
29
|
+
allow [:show]
|
30
|
+
end
|
31
|
+
|
32
|
+
def user
|
33
|
+
allow_rest_actions do |user|
|
34
|
+
@membership.id == user.id
|
35
|
+
end
|
36
|
+
allow_params except: [:id]
|
37
|
+
end
|
38
|
+
|
39
|
+
def admin
|
40
|
+
allow_rest_actions
|
41
|
+
allow_params
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
<% end -%>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Description:
|
2
|
+
Stubs out a scaffolded controller and its views. Different from rails
|
3
|
+
scaffold_controller, it uses strong_parameters to whitelist permissible
|
4
|
+
attributes in a private method.
|
5
|
+
Pass the model name, either CamelCased or under_scored. The controller
|
6
|
+
name is retrieved as a pluralized version of the model name.
|
7
|
+
|
8
|
+
With ActionPermission, it replaces the default strong_parameters
|
9
|
+
call with a call to allowed_params_for that loads the permission file
|
10
|
+
to determined whitelisted parameters
|
11
|
+
|
12
|
+
To create a controller within a module, specify the model name as a
|
13
|
+
path like 'parent_module/controller_name'.
|
14
|
+
|
15
|
+
This generates a controller class in app/controllers and invokes helper,
|
16
|
+
template engine and test framework generators.
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rails/version'
|
2
|
+
require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator'
|
3
|
+
|
4
|
+
module Rails
|
5
|
+
module Generators
|
6
|
+
class ActionPermissionControllerGenerator < ScaffoldControllerGenerator
|
7
|
+
argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
|
8
|
+
source_root File.expand_path("../templates", __FILE__)
|
9
|
+
|
10
|
+
if ::Rails::VERSION::STRING < '3.1'
|
11
|
+
def module_namespacing
|
12
|
+
yield if block_given?
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|