permissify 0.0.1
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.
- data/CHANGELOG.rdoc +4 -0
- data/Gemfile +52 -0
- data/LICENSE +21 -0
- data/README.rdoc +134 -0
- data/Rakefile +18 -0
- data/init.rb +1 -0
- data/lib/generators/permissify/ability/USAGE +3 -0
- data/lib/generators/permissify/ability/ability_generator.rb +11 -0
- data/lib/generators/permissify/ability/template/ability.rb +31 -0
- data/lib/generators/permissify/product/USAGE +3 -0
- data/lib/generators/permissify/role/USAGE +3 -0
- data/lib/generators/permissify/role/role_generator.rb +16 -0
- data/lib/generators/permissify/role/template/role.rb +66 -0
- data/lib/permissify/aggregate.rb +79 -0
- data/lib/permissify/model.rb +26 -0
- data/lib/permissify/model_class.rb +34 -0
- data/lib/permissify.rb +3 -0
- metadata +114 -0
data/CHANGELOG.rdoc
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# source 'https://rubygems.org'
|
2
|
+
#
|
3
|
+
# gem 'rails', '3.2.3'
|
4
|
+
#
|
5
|
+
# # Bundle edge Rails instead:
|
6
|
+
# # gem 'rails', :git => 'git://github.com/rails/rails.git'
|
7
|
+
#
|
8
|
+
# gem 'mysql'
|
9
|
+
#
|
10
|
+
# gem 'json'
|
11
|
+
#
|
12
|
+
# # Gems used only for assets and not required
|
13
|
+
# # in production environments by default.
|
14
|
+
# group :assets do
|
15
|
+
# gem 'sass-rails', '~> 3.2.3'
|
16
|
+
# gem 'coffee-rails', '~> 3.2.1'
|
17
|
+
#
|
18
|
+
# # See https://github.com/sstephenson/execjs#readme for more supported runtimes
|
19
|
+
# # gem 'therubyracer', :platform => :ruby
|
20
|
+
#
|
21
|
+
# gem 'uglifier', '>= 1.0.3'
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# gem 'jquery-rails'
|
25
|
+
#
|
26
|
+
# # To use ActiveModel has_secure_password
|
27
|
+
# # gem 'bcrypt-ruby', '~> 3.0.0'
|
28
|
+
#
|
29
|
+
# # To use Jbuilder templates for JSON
|
30
|
+
# # gem 'jbuilder'
|
31
|
+
#
|
32
|
+
# # Use unicorn as the app server
|
33
|
+
# # gem 'unicorn'
|
34
|
+
#
|
35
|
+
# # Deploy with Capistrano
|
36
|
+
# # gem 'capistrano'
|
37
|
+
#
|
38
|
+
# # To use debugger
|
39
|
+
# # gem 'ruby-debug'
|
40
|
+
#
|
41
|
+
# gem 'authlogic', '>= 3.1.0'
|
42
|
+
|
43
|
+
source "http://rubygems.org"
|
44
|
+
|
45
|
+
# gem "sqlite3"
|
46
|
+
# TODO : any activerecord version dependency?
|
47
|
+
# gem "activerecord", '~> 3.0.9', :require => "active_record"
|
48
|
+
gem "activerecord", :require => "active_record"
|
49
|
+
# gem "with_model", "~> 0.2.5"
|
50
|
+
# gem "meta_where"
|
51
|
+
|
52
|
+
gemspec
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2012 Frederick Fix
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
data/README.rdoc
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
= Permissify
|
2
|
+
|
3
|
+
Based on/inspired by CanCan {<img src="https://secure.travis-ci.org/ryanb/cancan.png" />}[http://travis-ci.org/ryanb/cancan]
|
4
|
+
|
5
|
+
Wiki[https://github.com/rickfix/permissify/wiki] | RDocs[http://rdoc.info/projects/rickfix/permissify]
|
6
|
+
|
7
|
+
Permissify is an authorization library for Ruby on Rails which restricts what resources a given model (i.e. user) is, or combination of models (user and merchant) are, allowed to access.
|
8
|
+
|
9
|
+
Abilities are defined in a single location (the +Ability+ class).
|
10
|
+
|
11
|
+
If you wish to permissify users with a set of roles... your roles class is permissified and you specify (through seeds, administration or some other mechanism) permissions to each ability.
|
12
|
+
|
13
|
+
Permissify expects a user to have many and belong to roles.
|
14
|
+
The following interfaces must be supported...
|
15
|
+
|
16
|
+
|
17
|
+
In the system which this gem was extracted, users where assigned many roles and businesses where are assigned many products (or, more accurately, product bundles). In views, access to ability-restricted navigation was typically affected by checking, (example is for merchant user admin) 'allowed_to?(:view, :merchant_user_admin)'. Under the hood, at least one of the user's roles must have permission to view merchant user admin AND at least one of the merchant's products must also have permission to view merchant user admin. Remember those Venn diagrams from 4th grade? Permissify is performing unions and intersections for you. It also allows you to specify if a particular abiltiy is only governed by a single model (role or product or ...).
|
18
|
+
|
19
|
+
|
20
|
+
== Installation
|
21
|
+
|
22
|
+
In <b>Rails 3</b>, add this to your Gemfile and run the +bundle+ command.
|
23
|
+
|
24
|
+
gem "permissify"
|
25
|
+
|
26
|
+
In <b>Rails 2</b>, add this to your environment.rb file.
|
27
|
+
|
28
|
+
config.gem "permissify"
|
29
|
+
|
30
|
+
|
31
|
+
== Getting Started
|
32
|
+
|
33
|
+
Permissify expects a +current_user+ method to exist in the controller. First, set up some authentication (such as Authlogic[https://github.com/binarylogic/authlogic] or Devise[https://github.com/plataformatec/devise]). See {Changing Defaults}[https://github.com/rickfix/permissify/wiki/changing-defaults] if you need different behavior.
|
34
|
+
|
35
|
+
|
36
|
+
=== 1. Define Abilities
|
37
|
+
|
38
|
+
User permissions are defined in an +Ability+ class. Permissify x.y includes a Rails 3 generator for creating this class.
|
39
|
+
|
40
|
+
rails g permissify:ability
|
41
|
+
|
42
|
+
In Rails 2.3, just add a new class in `app/models/ability.rb` with the folowing contents:
|
43
|
+
|
44
|
+
class Ability
|
45
|
+
include Permissify::Ability
|
46
|
+
|
47
|
+
def initialize(user)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
See {Defining Abilities}[https://github.com/rickfix/permissify/wiki/defining-abilities] for details.
|
52
|
+
|
53
|
+
|
54
|
+
=== 2. Check Abilities & Authorization
|
55
|
+
|
56
|
+
The current user's permissions can then be checked using the <tt>can?</tt> and <tt>cannot?</tt> methods in the view and controller.
|
57
|
+
|
58
|
+
<% if can? :update, @article %>
|
59
|
+
<%= link_to "Edit", edit_article_path(@article) %>
|
60
|
+
<% end %>
|
61
|
+
|
62
|
+
See {Checking Abilities}[https://github.com/rickfix/permissify/wiki/checking-abilities] for more information
|
63
|
+
|
64
|
+
The <tt>authorize!</tt> method in the controller will raise an exception if the user is not able to perform the given action.
|
65
|
+
|
66
|
+
def show
|
67
|
+
@article = Article.find(params[:id])
|
68
|
+
authorize! :read, @article
|
69
|
+
end
|
70
|
+
|
71
|
+
Setting this for every action can be tedious, therefore the +load_and_authorize_resource+ method is provided to automatically authorize all actions in a RESTful style resource controller. It will use a before filter to load the resource into an instance variable and authorize it for every action.
|
72
|
+
|
73
|
+
class ArticlesController < ApplicationController
|
74
|
+
load_and_authorize_resource
|
75
|
+
|
76
|
+
def show
|
77
|
+
# @article is already loaded and authorized
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
See {Authorizing Controller Actions}[https://github.com/rickfix/permissify/wiki/authorizing-controller-actions] for more information.
|
82
|
+
|
83
|
+
|
84
|
+
=== 3. Handle Unauthorized Access
|
85
|
+
|
86
|
+
If the user authorization fails, a <tt>Permissify::AccessDenied</tt> exception will be raised. You can catch this and modify its behavior in the +ApplicationController+.
|
87
|
+
|
88
|
+
class ApplicationController < ActionController::Base
|
89
|
+
rescue_from Permissify::AccessDenied do |exception|
|
90
|
+
redirect_to root_url, :alert => exception.message
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
See {Exception Handling}[https://github.com/rickfix/permissify/wiki/exception-handling] for more information.
|
95
|
+
|
96
|
+
|
97
|
+
=== 4. Lock It Down
|
98
|
+
|
99
|
+
If you want to ensure authorization happens on every action in your application, add +check_authorization+ to your ApplicationController.
|
100
|
+
|
101
|
+
class ApplicationController < ActionController::Base
|
102
|
+
check_authorization
|
103
|
+
end
|
104
|
+
|
105
|
+
This will raise an exception if authorization is not performed in an action. If you want to skip this add +skip_authorization_check+ to a controller subclass. See {Ensure Authorization}[https://github.com/rickfix/permissify/wiki/Ensure-Authorization] for more information.
|
106
|
+
|
107
|
+
|
108
|
+
== Wiki Docs
|
109
|
+
|
110
|
+
* {Upgrading to 1.6}[https://github.com/rickfix/permissify/wiki/Upgrading-to-1.6]
|
111
|
+
* {Defining Abilities}[https://github.com/rickfix/permissify/wiki/Defining-Abilities]
|
112
|
+
* {Checking Abilities}[https://github.com/rickfix/permissify/wiki/Checking-Abilities]
|
113
|
+
* {Authorizing Controller Actions}[https://github.com/rickfix/permissify/wiki/Authorizing-Controller-Actions]
|
114
|
+
* {Exception Handling}[https://github.com/rickfix/permissify/wiki/Exception-Handling]
|
115
|
+
* {Changing Defaults}[https://github.com/rickfix/permissify/wiki/Changing-Defaults]
|
116
|
+
* {See more}[https://github.com/rickfix/permissify/wiki]
|
117
|
+
|
118
|
+
|
119
|
+
== Project Status
|
120
|
+
|
121
|
+
Unfortunately I have not had time to actively work on this project recently. If you find a critical issue where it does not work as documented please {ping me on twitter}[http://twitter.com/rbates] and I'll take a look.
|
122
|
+
|
123
|
+
|
124
|
+
== Questions or Problems?
|
125
|
+
|
126
|
+
If you have any issues with Permissify which you cannot find the solution to in the documentation[https://github.com/rickfix/permissify/wiki], please add an {issue on GitHub}[https://github.com/rickfix/permissify/issues] or fork the project and send a pull request.
|
127
|
+
|
128
|
+
To get the specs running you should call +bundle+ and then +rake+. See the {spec/README}[https://github.com/rickfix/permissify/blob/master/spec/README.rdoc] for more information.
|
129
|
+
|
130
|
+
|
131
|
+
== Special Thanks
|
132
|
+
|
133
|
+
Permissify was inspired by declarative_authorization[https://github.com/stffn/declarative_authorization/] and aegis[https://github.com/makandra/aegis]. Also many thanks to the Permissify contributors[https://github.com/rickfix/permissify/contributors]. See the CHANGELOG[https://github.com/rickfix/permissify/blob/master/CHANGELOG.rdoc] for the full list.
|
134
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
|
5
|
+
desc "Run RSpec"
|
6
|
+
RSpec::Core::RakeTask.new do |t|
|
7
|
+
t.verbose = false
|
8
|
+
end
|
9
|
+
|
10
|
+
desc "Run specs for all adapters"
|
11
|
+
task :spec_all do
|
12
|
+
%w[active_record].each do |model_adapter|
|
13
|
+
puts "MODEL_ADAPTER = #{model_adapter}"
|
14
|
+
system "rake spec MODEL_ADAPTER=#{model_adapter}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
task :default => :spec
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'permissify'
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# TODO : talk about how this could be an active record, but just needs to support a set of interfaces (all, all_for, others?)
|
2
|
+
class Ability
|
3
|
+
class << self
|
4
|
+
include SystemFixtures::Abilities
|
5
|
+
@@abilities = []
|
6
|
+
|
7
|
+
def all; seed if @@abilities.empty?; @@abilities; end
|
8
|
+
|
9
|
+
def all_for(applicability_types)
|
10
|
+
applicability_types = [applicability_types] if applicability_types.kind_of?(String)
|
11
|
+
all.select{|a| (a[:applicability] & applicability_types) == applicability_types}
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_permissions_hash(view_only_categories=[], remove_categories=[], applicability_types = 'Role')
|
15
|
+
@@permissions = {}
|
16
|
+
all_for(applicability_types).each{|permission| @@permissions[permission[:key]] = {'0' => '1'}}
|
17
|
+
view_only_categories.each{|category| view_only(category)}
|
18
|
+
remove_categories.each{|category| remove(category)}
|
19
|
+
@@permissions
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
def view_only(category); %w(create update delete).each{|action| @@permissions.delete("#{category}_#{action}")}; end
|
24
|
+
def remove(permission_prefix); @@permissions.keys.each{|key| @@permissions.delete(key) if key.starts_with?(permission_prefix)}; end
|
25
|
+
def add(key, category, section, action, applicability, number_of_values, position, default_values, admin_expression='', category_allows = :multiple)
|
26
|
+
@@abilities << { :key => key, :category => category, :section => section, :action => action,
|
27
|
+
:applicability => applicability, :number_of_values => number_of_values, :position => position,
|
28
|
+
:default_values => default_values, :administration_expression => admin_expression, :category_allows => category_allows}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Permissify
|
2
|
+
module Generators
|
3
|
+
class RoleGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path('../template', __FILE__)
|
5
|
+
|
6
|
+
def generate_ability
|
7
|
+
copy_file "role.rb", "app/models/role.rb"
|
8
|
+
# also make the following?
|
9
|
+
# d app/models/system_fixtures
|
10
|
+
# f app/models/system_fixtures/roles.rb
|
11
|
+
# d app/models/permissions
|
12
|
+
# f app/models/permissions/roles.rb
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
class Role < ActiveRecord::Base
|
2
|
+
DOMAIN_TYPES = %w(Admin Dealer Corporate Brand Merchant)
|
3
|
+
include Permissions::Model
|
4
|
+
# is_paranoid
|
5
|
+
has_and_belongs_to_many :users, :order => "userable_type ASC"
|
6
|
+
# default_scope :conditions => {:deleted_at => nil}, :order => "roles.name"
|
7
|
+
validates_presence_of :name, :domain_type
|
8
|
+
validates_uniqueness_of :name
|
9
|
+
before_create :initialize_permissions
|
10
|
+
before_validation :initialize_non_permission_values
|
11
|
+
serialize :permissions
|
12
|
+
serialize :can_manage_roles
|
13
|
+
after_save :propagate_managed_by
|
14
|
+
|
15
|
+
class << self
|
16
|
+
include Permissions::ModelClass
|
17
|
+
include SystemFixtures::Roles
|
18
|
+
def super_user; locate(1, 'super user'); end
|
19
|
+
def system_admin; locate(2, 'system admin'); end
|
20
|
+
def dealer_admin; locate(3, 'dealer admin'); end
|
21
|
+
def corporate_admin; locate(4, 'corporate admin'); end
|
22
|
+
def brand_admin; locate(5, 'brand admin'); end
|
23
|
+
def merchant_admin; locate(6, 'merchant admin'); end
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize_non_permission_values
|
27
|
+
establish_from_permissions_model.nil? ? default_non_permissions_values : copy_non_permissions_values
|
28
|
+
end
|
29
|
+
|
30
|
+
def default_non_permissions_values
|
31
|
+
self.can_manage_roles ||= []
|
32
|
+
self.domain_type = DOMAIN_TYPES.last if self.domain_type.blank?
|
33
|
+
self.name = self.name.gsub("'","")
|
34
|
+
end
|
35
|
+
|
36
|
+
def copy_non_permissions_values
|
37
|
+
self.domain_type = self.from_permissions_model.domain_type
|
38
|
+
self.managed_by = self.from_permissions_model.managed_by
|
39
|
+
self.can_manage_roles = self.from_permissions_model.can_manage_roles
|
40
|
+
end
|
41
|
+
|
42
|
+
def manages_roles
|
43
|
+
return [] if quoted_role_names.blank?
|
44
|
+
self.class.find(:all, :conditions => ["name in (#{quoted_role_names})"], :order => :name)
|
45
|
+
end
|
46
|
+
|
47
|
+
def remove(permissions_list); permissions_list.each{|permission| self.permissions.delete(permission)}; save; end
|
48
|
+
|
49
|
+
def quoted_role_names; self.can_manage_roles.collect{|n| "'#{n}'"}.join(', ') rescue []; end
|
50
|
+
|
51
|
+
def managed_by=(role_name_list); @managed_by = role_name_list; end
|
52
|
+
def managed_by
|
53
|
+
@managed_by ||= Role.all.select{|r| r.can_manage_roles.include?(self.name)}.collect(&:name)
|
54
|
+
end
|
55
|
+
|
56
|
+
def propagate_managed_by
|
57
|
+
Role.all.each{ |r| r.update_manages_roles(managed_by.include?(r.name), self.name) } unless @managed_by.nil?
|
58
|
+
end
|
59
|
+
|
60
|
+
def update_manages_roles(manages_role_name, role_name)
|
61
|
+
old = self.manages_roles
|
62
|
+
old = [] if old.blank?
|
63
|
+
new_value = manages_role_name ? old | [role_name] : old - [role_name]
|
64
|
+
update_attribute(:can_manage_roles, new_value) if old != new_value
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Permissions::Aggregate
|
2
|
+
attr_accessor :abilities
|
3
|
+
|
4
|
+
def permissions_union # [integer values].max
|
5
|
+
@union ||= construct_union
|
6
|
+
end
|
7
|
+
|
8
|
+
def construct_union
|
9
|
+
union = {}
|
10
|
+
self.send(permissions_association).collect(&:permissions).each do |permissions_hash|
|
11
|
+
permissions_hash.each do |key, descriptor|
|
12
|
+
descriptor ||= {'0' => false}
|
13
|
+
if union[key].nil?
|
14
|
+
union[key] = descriptor
|
15
|
+
else
|
16
|
+
arbitrate(union, descriptor, key, :max)
|
17
|
+
end
|
18
|
+
union[key]['0'] = (union[key]['0'] == '1' || descriptor['0'] == '1')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
union
|
22
|
+
end
|
23
|
+
|
24
|
+
def permissions_intersection(product_permissions) # [integer values].min
|
25
|
+
return @intersection if @intersection
|
26
|
+
@intersection = {}
|
27
|
+
permissions_union
|
28
|
+
|
29
|
+
Ability.all_for(%w(Product Role)).each do |ability|
|
30
|
+
key = ability[:key]
|
31
|
+
descriptor = @union[key]
|
32
|
+
product_descriptor = product_permissions[key]
|
33
|
+
if permissable?(descriptor) && permissable?(product_descriptor)
|
34
|
+
@intersection[key] = descriptor
|
35
|
+
arbitrate(@intersection, product_descriptor, key, :min)
|
36
|
+
else
|
37
|
+
@intersection[key] = null_permission
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
include_permissions_unless_common_to_role_and_product('Product', product_permissions)
|
42
|
+
include_permissions_unless_common_to_role_and_product('Role', @union)
|
43
|
+
@intersection
|
44
|
+
end
|
45
|
+
|
46
|
+
def permissable?(descriptor); descriptor && (descriptor['0'] == true || descriptor['0'] == '1'); end
|
47
|
+
def subscribed_to?(feature); allowed_to?('on', feature); end
|
48
|
+
def allowed_to?(action, feature); (permissions_union["#{feature}_#{action}"]['0'] == true rescue false); end
|
49
|
+
|
50
|
+
def include_permissions_unless_common_to_role_and_product(applicability_type, applicable_permissions)
|
51
|
+
Ability.all_for(applicability_type).each do |ability|
|
52
|
+
key = ability[:key]
|
53
|
+
descriptor = applicable_permissions[key]
|
54
|
+
unless @intersection.has_key?(key)
|
55
|
+
if permissable?(descriptor)
|
56
|
+
descriptor['0'] = true
|
57
|
+
@intersection[key] = descriptor
|
58
|
+
arbitrate(@intersection, descriptor, key, :min)
|
59
|
+
else
|
60
|
+
@intersection[key] = null_permission
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
def arbitrate(aggregation, other_descriptor, key, min_or_max) # assuming all permission 'args' are integers stored as strings
|
68
|
+
1.upto(other_descriptor.size-1) do |i|
|
69
|
+
is = i.to_s; aggregation[key][is] = [aggregation[key][is].to_i, other_descriptor[is].to_i].send(min_or_max) # .to_s ?
|
70
|
+
end
|
71
|
+
end
|
72
|
+
def null_permission; {'0' => false, '1' => 0}; end
|
73
|
+
|
74
|
+
def permissions_association # kinda icky
|
75
|
+
klass = self.respond_to?(:product_tiers) ? self.class : Business
|
76
|
+
@permissions_association ||= {User => :roles, klass => :product_tiers}[self.class]
|
77
|
+
@permissions_association ||= :permission_objects
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Permissions::Model
|
2
|
+
attr_accessor :from, :from_permissions_model
|
3
|
+
|
4
|
+
def establish_from_permissions_model
|
5
|
+
self.from_permissions_model ||= self.from.nil? ? nil : self.class.find(self.from)
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize_permissions
|
9
|
+
self.permissions ||= self.from.nil? ? {} : establish_from_permissions_model.permissions
|
10
|
+
end
|
11
|
+
|
12
|
+
def allows?(ability_key) ; logger.debug(ability_key.inspect.to_s);
|
13
|
+
allowed = self.permissions[ability_key];
|
14
|
+
allowed && allowed['0'];
|
15
|
+
end
|
16
|
+
def remove_permissions(keys)
|
17
|
+
keys = [keys] if keys.class == String
|
18
|
+
keys.each{ |k| self.permissions[k] = nil}
|
19
|
+
self.save
|
20
|
+
end
|
21
|
+
def update_permissions(new_or_updated_permissions)
|
22
|
+
self.permissions = self.permissions.merge(new_or_updated_permissions)
|
23
|
+
self.save
|
24
|
+
end
|
25
|
+
def underscored_name_symbol; self.class.underscored_name_symbol(self.name); end
|
26
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Permissions::ModelClass
|
2
|
+
def retire_permissions_objects(retire_sql)
|
3
|
+
ActiveRecord::Base.connection.execute retire_sql
|
4
|
+
end
|
5
|
+
|
6
|
+
def create_seeds(table_name, seed_specifications)
|
7
|
+
@model_class_seed_specifications = seed_specifications
|
8
|
+
seed_specifications.each do |id, name|
|
9
|
+
permissions_model = locate(id, name)
|
10
|
+
permissions_model.permissions = send("#{underscored_name_symbol(name)}_permissions")
|
11
|
+
permissions_model.save
|
12
|
+
end
|
13
|
+
ActiveRecord::Base.connection.execute "ALTER TABLE #{table_name} AUTO_INCREMENT = 101;"
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_with_id(table, id, name)
|
17
|
+
permissions = send("#{underscored_name_symbol(name)}_permissions")
|
18
|
+
permissions_model = new
|
19
|
+
permissions_model.name = name
|
20
|
+
permissions_model.permissions = permissions
|
21
|
+
permissions_model.save
|
22
|
+
ActiveRecord::Base.connection.execute "UPDATE #{table}s SET id=#{id} WHERE id=#{permissions_model.id};"
|
23
|
+
find(id)
|
24
|
+
end
|
25
|
+
|
26
|
+
def locate(id, name)
|
27
|
+
model_with_id = find_by_id(id)
|
28
|
+
model_with_id ||= send("create_#{underscored_name_symbol(name)}")
|
29
|
+
end
|
30
|
+
|
31
|
+
def underscored_name_symbol(name)
|
32
|
+
name.to_s.downcase.gsub('-','_').gsub(':','').gsub(' ',' ').gsub(' ','_')
|
33
|
+
end
|
34
|
+
end
|
data/lib/permissify.rb
ADDED
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: permissify
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Frederick Fix
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-05-29 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 23
|
29
|
+
segments:
|
30
|
+
- 2
|
31
|
+
- 6
|
32
|
+
- 0
|
33
|
+
version: 2.6.0
|
34
|
+
type: :development
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rails
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 21
|
45
|
+
segments:
|
46
|
+
- 3
|
47
|
+
- 0
|
48
|
+
- 9
|
49
|
+
version: 3.0.9
|
50
|
+
type: :development
|
51
|
+
version_requirements: *id002
|
52
|
+
description: Not so simple authorization solution for Rails.
|
53
|
+
email: rickfix80004@gmail.com
|
54
|
+
executables: []
|
55
|
+
|
56
|
+
extensions: []
|
57
|
+
|
58
|
+
extra_rdoc_files: []
|
59
|
+
|
60
|
+
files:
|
61
|
+
- lib/generators/permissify/ability/ability_generator.rb
|
62
|
+
- lib/generators/permissify/ability/template/ability.rb
|
63
|
+
- lib/generators/permissify/ability/USAGE
|
64
|
+
- lib/generators/permissify/product/USAGE
|
65
|
+
- lib/generators/permissify/role/role_generator.rb
|
66
|
+
- lib/generators/permissify/role/template/role.rb
|
67
|
+
- lib/generators/permissify/role/USAGE
|
68
|
+
- lib/permissify/aggregate.rb
|
69
|
+
- lib/permissify/model.rb
|
70
|
+
- lib/permissify/model_class.rb
|
71
|
+
- lib/permissify.rb
|
72
|
+
- CHANGELOG.rdoc
|
73
|
+
- Gemfile
|
74
|
+
- LICENSE
|
75
|
+
- Rakefile
|
76
|
+
- README.rdoc
|
77
|
+
- init.rb
|
78
|
+
homepage: http://github.com/rickfix/permissify
|
79
|
+
licenses: []
|
80
|
+
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options: []
|
83
|
+
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
hash: 3
|
92
|
+
segments:
|
93
|
+
- 0
|
94
|
+
version: "0"
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
|
+
none: false
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
hash: 19
|
101
|
+
segments:
|
102
|
+
- 1
|
103
|
+
- 3
|
104
|
+
- 4
|
105
|
+
version: 1.3.4
|
106
|
+
requirements: []
|
107
|
+
|
108
|
+
rubyforge_project: permissify
|
109
|
+
rubygems_version: 1.8.24
|
110
|
+
signing_key:
|
111
|
+
specification_version: 3
|
112
|
+
summary: Not so simple authorization solution for Rails.
|
113
|
+
test_files: []
|
114
|
+
|