cantango 0.9.4 → 0.9.4.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/README.textile +5 -2
- data/VERSION +1 -1
- data/cantango.gemspec +6 -2
- data/lib/cantango/configuration/models.rb +5 -2
- data/lib/cantango/configuration/models/actions.rb +26 -0
- data/lib/cantango/configuration/permit_registry.rb +8 -9
- data/lib/cantango/configuration/permits.rb +23 -4
- data/lib/cantango/model.rb +1 -1
- data/lib/cantango/model/actions.rb +45 -0
- data/lib/cantango/permit_engine.rb +4 -12
- data/lib/cantango/permit_engine/finder.rb +6 -2
- data/lib/cantango/permits/executor.rb +2 -8
- data/lib/cantango/permits/permit.rb +16 -0
- data/lib/cantango/permits/role_group_permit.rb +4 -0
- data/lib/cantango/permits/role_group_permit/builder.rb +4 -5
- data/lib/cantango/permits/role_permit.rb +4 -0
- data/lib/cantango/permits/role_permit/builder.rb +4 -3
- data/lib/cantango/rails/helpers/rest_helper.rb +23 -0
- data/spec/cantango/model/actions_spec.rb +85 -0
- data/spec/cantango/permit_engine/builder/role_group_permits_spec.rb +4 -0
- data/spec/cantango/permit_engine/finder_spec.rb +9 -2
- data/spec/cantango/permit_engine/role_group_permit_spec.rb +2 -2
- data/spec/cantango/permits/custom_permit_spec.rb +78 -0
- metadata +37 -33
data/README.textile
CHANGED
@@ -35,15 +35,18 @@ Run bundler in a terminal/console from the folder of your Gemfile (root folder o
|
|
35
35
|
|
36
36
|
@$ bundle@
|
37
37
|
|
38
|
-
h2. Update Nov
|
38
|
+
h2. Update Nov 3, 2011
|
39
39
|
|
40
|
-
Version 0.9.4 has been released with the following featuring and improvements:
|
40
|
+
Version 0.9.4.1 has been released with the following featuring and improvements:
|
41
41
|
|
42
42
|
* Redesign of Cache and Ability execution
|
43
43
|
* Caching at the individual engine level that can be switched (configured) on/off
|
44
44
|
* Individual caching for each type of Permit in the Permit engine
|
45
45
|
* Each engine return a set of rules which are merged into one rule set for that particular execution mode
|
46
46
|
* Caching for the new User AC engine
|
47
|
+
* Ability to register your own Permit base classes simply by subclassing CanTango::Permit!
|
48
|
+
* This is useful if you want to go beyond the built in types, see the @custom_permit_spec.rb@ for an example
|
49
|
+
* Some bug fixes
|
47
50
|
|
48
51
|
The :user_ac engine is a port of the Permission system from the _Rails in Action_ book.
|
49
52
|
With this engine a user can have many permissions defined, where each such permission is a persisted Permission model instance that describes a 'can' action on a specific type of object.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.9.4
|
1
|
+
0.9.4.1
|
data/cantango.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{cantango}
|
8
|
-
s.version = "0.9.4"
|
8
|
+
s.version = "0.9.4.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = [%q{Kristian Mandrup}, %q{Stanislaw Pankevich}]
|
12
|
-
s.date = %q{2011-11-
|
12
|
+
s.date = %q{2011-11-03}
|
13
13
|
s.description = %q{Define your permission rules as role- or role group specific permits.
|
14
14
|
Integrates well with multiple Devise user acounts.
|
15
15
|
Includes rules caching.
|
@@ -91,6 +91,7 @@ Store permissions in yaml file or key-value store}
|
|
91
91
|
"lib/cantango/configuration/guest.rb",
|
92
92
|
"lib/cantango/configuration/hash_registry.rb",
|
93
93
|
"lib/cantango/configuration/models.rb",
|
94
|
+
"lib/cantango/configuration/models/actions.rb",
|
94
95
|
"lib/cantango/configuration/models/active_record.rb",
|
95
96
|
"lib/cantango/configuration/models/data_mapper.rb",
|
96
97
|
"lib/cantango/configuration/models/generic.rb",
|
@@ -117,6 +118,7 @@ Store permissions in yaml file or key-value store}
|
|
117
118
|
"lib/cantango/helpers/debug.rb",
|
118
119
|
"lib/cantango/helpers/role_methods.rb",
|
119
120
|
"lib/cantango/model.rb",
|
121
|
+
"lib/cantango/model/actions.rb",
|
120
122
|
"lib/cantango/model/filter.rb",
|
121
123
|
"lib/cantango/model/scope.rb",
|
122
124
|
"lib/cantango/permission_engine.rb",
|
@@ -360,6 +362,7 @@ Store permissions in yaml file or key-value store}
|
|
360
362
|
"spec/cantango/configuration/user_spec.rb",
|
361
363
|
"spec/cantango/configuration_spec.rb",
|
362
364
|
"spec/cantango/license/save_license_spec.rb",
|
365
|
+
"spec/cantango/model/actions_spec.rb",
|
363
366
|
"spec/cantango/model/filter_spec.rb",
|
364
367
|
"spec/cantango/model/scope_spec.rb",
|
365
368
|
"spec/cantango/models/items.rb",
|
@@ -397,6 +400,7 @@ Store permissions in yaml file or key-value store}
|
|
397
400
|
"spec/cantango/permit_engine/user_permit_spec.rb",
|
398
401
|
"spec/cantango/permit_engine_cached_spec.rb",
|
399
402
|
"spec/cantango/permit_engine_spec.rb",
|
403
|
+
"spec/cantango/permits/custom_permit_spec.rb",
|
400
404
|
"spec/cantango/permits/executor_cached_spec.rb",
|
401
405
|
"spec/cantango/permits/executor_spec.rb",
|
402
406
|
"spec/cantango/permits/macros_spec.rb",
|
@@ -2,10 +2,15 @@ module CanTango
|
|
2
2
|
class Configuration
|
3
3
|
class Models
|
4
4
|
autoload_modules :Generic, :ActiveRecord, :DataMapper, :MongoMapper, :Mongoid
|
5
|
+
autoload_modules :Actions
|
5
6
|
|
6
7
|
include Singleton
|
7
8
|
include ClassExt
|
8
9
|
|
10
|
+
def actions
|
11
|
+
@actions ||= HashRegistry.new
|
12
|
+
end
|
13
|
+
|
9
14
|
def by_reg_exp reg_exp
|
10
15
|
raise "Must be a Regular Expression like: /xyz/ was #{reg_exp.inspect}" if !reg_exp.kind_of? Regexp
|
11
16
|
|
@@ -43,8 +48,6 @@ module CanTango
|
|
43
48
|
|
44
49
|
private
|
45
50
|
|
46
|
-
|
47
|
-
|
48
51
|
def adapter_for orm
|
49
52
|
"CanTango::Configuration::Models::#{orm.to_s.camlize}".constantize.new
|
50
53
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module CanTango
|
2
|
+
class Configuration
|
3
|
+
class Models
|
4
|
+
class Actions
|
5
|
+
attr_reader :collection, :member
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@collection = []
|
9
|
+
@member = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def actions_for type
|
13
|
+
send(type.to_sym) || []
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_member action
|
17
|
+
@member << action.to_sym
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_collection action
|
21
|
+
@collection << action.to_sym
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -1,24 +1,23 @@
|
|
1
1
|
module CanTango
|
2
2
|
class Configuration
|
3
3
|
class PermitRegistry
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
}
|
4
|
+
def get permit
|
5
|
+
raise ArgumentError, "Not an available permit" if !CanTango.config.permits.available_types.include? permit
|
6
|
+
inst_var_name = "@#{permit}"
|
7
|
+
instance_variable_set(inst_var_name, HashRegistry.new) if !instance_variable_get(inst_var_name)
|
8
|
+
instance_variable_get(inst_var_name)
|
10
9
|
end
|
11
10
|
|
12
|
-
def registered_for type, name = nil
|
11
|
+
def registered_for type, name = nil
|
13
12
|
name ? registered_by(type)[name.to_s] : registered_by(type)
|
14
13
|
end
|
15
14
|
|
16
15
|
def registered_by type
|
17
|
-
|
16
|
+
get(type).registered
|
18
17
|
end
|
19
18
|
|
20
19
|
def all
|
21
|
-
[
|
20
|
+
(CanTango.config.permits.available_types - [:special]).map{|p| send(p) if respond_to?(p)}
|
22
21
|
end
|
23
22
|
|
24
23
|
def show_all
|
@@ -2,6 +2,7 @@ module CanTango
|
|
2
2
|
class Configuration
|
3
3
|
class Permits < PermitRegistry
|
4
4
|
include Singleton
|
5
|
+
include CanTango::Helpers::Debug
|
5
6
|
|
6
7
|
attr_reader :accounts
|
7
8
|
attr_writer :enabled_types
|
@@ -11,8 +12,25 @@ module CanTango
|
|
11
12
|
end
|
12
13
|
alias_method :enabled, :enabled_types
|
13
14
|
|
15
|
+
def available_permits
|
16
|
+
@available_permits ||= default_permits
|
17
|
+
end
|
18
|
+
|
14
19
|
def available_types
|
15
|
-
|
20
|
+
available_permits.keys
|
21
|
+
end
|
22
|
+
|
23
|
+
def available_classes
|
24
|
+
available_permits.values.compact
|
25
|
+
end
|
26
|
+
|
27
|
+
def default_permits
|
28
|
+
{ :user => CanTango::Permits::UserPermit,
|
29
|
+
:account => CanTango::Permits::AccountPermit,
|
30
|
+
:role => CanTango::Permits::RolePermit,
|
31
|
+
:role_group => CanTango::Permits::RoleGroupPermit,
|
32
|
+
:special => nil
|
33
|
+
}
|
16
34
|
end
|
17
35
|
|
18
36
|
def disable_types *types
|
@@ -61,9 +79,10 @@ module CanTango
|
|
61
79
|
|
62
80
|
def register_permit_class(permit_name, permit_clazz, permit_type, account_name)
|
63
81
|
registry = account_name ? self.send(account_name.to_sym) : self
|
64
|
-
|
65
|
-
|
66
|
-
|
82
|
+
debug "Registering #{permit_type} permit: #{permit_name} of class #{permit_clazz}"
|
83
|
+
|
84
|
+
registry.get(permit_type)[permit_name] = permit_clazz
|
85
|
+
debug registry.get(permit_type).inspect
|
67
86
|
end
|
68
87
|
|
69
88
|
def allowed candidate, actions, subjects, *extra_args
|
data/lib/cantango/model.rb
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
module CanTango::Model
|
2
|
+
module Actions
|
3
|
+
def self.included(base)
|
4
|
+
register base
|
5
|
+
base.extend ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.register clazz
|
9
|
+
model_actions[clazz.to_s.underscore.to_sym] = CanTango::Configuration::Models::Actions.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.register_member_actions clazz, *actions
|
13
|
+
actions.flatten.each do |action|
|
14
|
+
model_actions[clazz].add_member action.to_sym
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.register_collection_actions clazz, *actions
|
19
|
+
actions.flatten.each do |action|
|
20
|
+
model_actions[clazz].add_collection action.to_sym
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.model_actions
|
25
|
+
CanTango.config.models.actions
|
26
|
+
end
|
27
|
+
|
28
|
+
module ClassMethods
|
29
|
+
def tango_actions *actions
|
30
|
+
action_clazz = self.name.underscore.to_sym
|
31
|
+
options = actions.extract_options!
|
32
|
+
clazz = CanTango::Model::Actions
|
33
|
+
case options[:as]
|
34
|
+
when :member
|
35
|
+
clazz.register_member_actions action_clazz, *actions
|
36
|
+
when :collection
|
37
|
+
clazz.register_collection_actions action_clazz, *actions
|
38
|
+
else
|
39
|
+
raise ArgumentError, "You must specify a :to option as the last argument, of either :member or :collection"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -65,18 +65,10 @@ module CanTango
|
|
65
65
|
end
|
66
66
|
|
67
67
|
def key_method_names
|
68
|
-
permits.keys.map
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
case type
|
73
|
-
when :role
|
74
|
-
roles_list_meth
|
75
|
-
when :role_group
|
76
|
-
role_groups_list_meth
|
77
|
-
else
|
78
|
-
nil
|
79
|
-
end
|
68
|
+
permits.keys.map do |permit|
|
69
|
+
permit_class = CanTango.config.permits.available_permits[permit]
|
70
|
+
permit_class.hash_key
|
71
|
+
end.compact
|
80
72
|
end
|
81
73
|
end
|
82
74
|
end
|
@@ -32,14 +32,18 @@ module CanTango
|
|
32
32
|
|
33
33
|
# TODO: User/Account cases should be handled somehow following is just interim measure
|
34
34
|
def account_permit
|
35
|
-
return nil if !user_account.class
|
35
|
+
return nil if !registered_account? user_account.class
|
36
36
|
found = account_permits_by(type)[name]
|
37
|
-
|
37
|
+
debug account_permit_msg(found)
|
38
38
|
found
|
39
39
|
rescue
|
40
40
|
nil
|
41
41
|
end
|
42
42
|
|
43
|
+
def registered_account? account
|
44
|
+
CanTango.config.user_accounts.registered_class? account
|
45
|
+
end
|
46
|
+
|
43
47
|
def account_permit_msg found
|
44
48
|
found.nil? ? "no account permits found for #{name}" : "account permits registered for name: #{name} -> #{found}"
|
45
49
|
end
|
@@ -43,14 +43,8 @@ module CanTango
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def key_method_names
|
46
|
-
|
47
|
-
|
48
|
-
[roles_list_meth]
|
49
|
-
when :role_group
|
50
|
-
[role_groups_list_meth]
|
51
|
-
else
|
52
|
-
[]
|
53
|
-
end
|
46
|
+
permit_class = CanTango.config.permits.available_permits[permit_type]
|
47
|
+
permit_class.hash_key ? [permit_class.hash_key] : []
|
54
48
|
end
|
55
49
|
end
|
56
50
|
end
|
@@ -18,11 +18,27 @@ module CanTango
|
|
18
18
|
|
19
19
|
delegate :cached?, :options, :subject, :user, :user_account, :to => :ability
|
20
20
|
|
21
|
+
def self.inherited(subclass)
|
22
|
+
register subclass.name.split('::').last.sub(/Permit$/, '').underscore.to_sym, subclass
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.register permit, subclass
|
26
|
+
available_permits[permit] = subclass
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.available_permits
|
30
|
+
CanTango.config.permits.available_permits
|
31
|
+
end
|
32
|
+
|
21
33
|
# creates the permit
|
22
34
|
def initialize ability
|
23
35
|
@ability = ability
|
24
36
|
end
|
25
37
|
|
38
|
+
def hash_key
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
|
26
42
|
def permit_type
|
27
43
|
self.class.type
|
28
44
|
end
|
@@ -1,23 +1,22 @@
|
|
1
1
|
module CanTango
|
2
2
|
module Permits
|
3
3
|
class RoleGroupPermit < CanTango::Permit
|
4
|
-
|
5
4
|
class Builder < CanTango::PermitEngine::Builder::Base
|
6
|
-
|
7
|
-
|
5
|
+
include CanTango::Helpers::Debug
|
8
6
|
# builds a list of Permits for each role group of the current ability user (or account)
|
9
7
|
# @return [Array<RoleGroupPermit::Base>] the role group permits built for this ability
|
10
8
|
def build
|
11
9
|
matching_permits = matching_role_groups(roles).inject([]) do |permits, role_group|
|
12
|
-
|
10
|
+
debug "Building RoleGroupPermit for #{role_group}"
|
13
11
|
(permits << create_permit(role_group)) if valid?(role_group)
|
14
12
|
permits
|
15
13
|
end.compact
|
16
14
|
|
17
15
|
if matching_permits.empty?
|
18
|
-
|
16
|
+
debug "Not building any RoleGroupPermits since no role groups could be found that are relevant for the permission candidate"
|
19
17
|
return []
|
20
18
|
end
|
19
|
+
matching_permits
|
21
20
|
end
|
22
21
|
|
23
22
|
def name
|
@@ -2,15 +2,17 @@ module CanTango
|
|
2
2
|
module Permits
|
3
3
|
class RolePermit < CanTango::Permit
|
4
4
|
class Builder < CanTango::PermitEngine::Builder::Base
|
5
|
+
include CanTango::Helpers::Debug
|
6
|
+
|
5
7
|
# builds a list of Permits for each role of the current ability user (or account)
|
6
8
|
# @return [Array<RoleGroupPermit::Base>] the role permits built for this ability
|
7
9
|
def build
|
8
10
|
if roles.empty?
|
9
|
-
|
11
|
+
debug "Not building any RolePermit"
|
10
12
|
return [] if roles.empty?
|
11
13
|
end
|
12
14
|
roles.inject([]) do |permits, role|
|
13
|
-
|
15
|
+
debug "Building RolePermit for #{role}"
|
14
16
|
(permits << create_permit(role)) if valid?(role.to_sym)
|
15
17
|
permits
|
16
18
|
end.compact
|
@@ -29,7 +31,6 @@ module CanTango
|
|
29
31
|
def filter role
|
30
32
|
CanTango::Filters::RoleFilter.new role
|
31
33
|
end
|
32
|
-
|
33
34
|
end
|
34
35
|
end
|
35
36
|
end
|
@@ -1,4 +1,27 @@
|
|
1
1
|
module CanTango::Rails::Helpers::RestHelper
|
2
|
+
CanTango.config.models.actions.each_pair do |model, actions|
|
3
|
+
actions.actions_for :member do |member_action|
|
4
|
+
class_eval %{
|
5
|
+
def #{member_action}_#{model.to_s.underscore}_path obj, options = {}
|
6
|
+
return unless can_perform_action?(user_type, :#{member_action}, obj)
|
7
|
+
# use i18n translation on label
|
8
|
+
link_to t(".#{member_action}"), rest_obj_action(obj, :#{member_action}, options)
|
9
|
+
end
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
actions.actions_for :collection do |collection_action|
|
14
|
+
class_eval %{
|
15
|
+
def #{collection_action}_#{model.to_s.underscore}_path obj, options = {}
|
16
|
+
clazz = obj.kind_of?(Class) ? obj : obj.class
|
17
|
+
return unless can_perform_action?(user_type, :#{collection_action}, clazz)
|
18
|
+
# use i18n translation on label
|
19
|
+
link_to t(".#{collection_action}"), send(action_method clazz, :#{collection_action}, options)
|
20
|
+
end
|
21
|
+
}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
2
25
|
CanTango.config.models.available_models.each do |model|
|
3
26
|
class_eval %{
|
4
27
|
def delete_#{model.to_s.underscore}_path obj, options = {}
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'cantango'
|
3
|
+
require 'simple_roles'
|
4
|
+
require 'fixtures/models'
|
5
|
+
require 'cantango/api/current_users'
|
6
|
+
require 'cantango/api/current_user_accounts'
|
7
|
+
|
8
|
+
class User
|
9
|
+
tango_user
|
10
|
+
|
11
|
+
include_and_extend SimpleRoles
|
12
|
+
end
|
13
|
+
|
14
|
+
class Admin < User
|
15
|
+
tango_user
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
CanTango.configure do |config|
|
20
|
+
config.cache_engine.set :off
|
21
|
+
config.permit_engine.set :on
|
22
|
+
end
|
23
|
+
|
24
|
+
class Context
|
25
|
+
include CanTango::Api::User::Ability
|
26
|
+
|
27
|
+
include_and_extend ::CurrentUsers
|
28
|
+
include_and_extend ::CurrentUserAccounts
|
29
|
+
end
|
30
|
+
|
31
|
+
class UserRolePermit < CanTango::RolePermit
|
32
|
+
def initialize ability
|
33
|
+
super
|
34
|
+
end
|
35
|
+
|
36
|
+
def permit_rules
|
37
|
+
can :edit, Project
|
38
|
+
cannot :publish, Project
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class AdminRolePermit < CanTango::RolePermit
|
43
|
+
def initialize ability
|
44
|
+
super
|
45
|
+
end
|
46
|
+
|
47
|
+
def permit_rules
|
48
|
+
can :create, Project
|
49
|
+
can :show, Project
|
50
|
+
|
51
|
+
can :publish, Project
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class Project
|
56
|
+
include CanTango::Model::Actions
|
57
|
+
|
58
|
+
tango_actions :search, :as => :collection
|
59
|
+
|
60
|
+
tango_actions :publish, :tag, :as => :member
|
61
|
+
end
|
62
|
+
|
63
|
+
describe CanTango::Model::Filter do
|
64
|
+
let(:context) { Context.new }
|
65
|
+
|
66
|
+
subject { CanTango.config.models.actions }
|
67
|
+
|
68
|
+
describe '#tango_actions' do
|
69
|
+
|
70
|
+
describe 'registered model actions' do
|
71
|
+
it 'should have registered :search as a collection action' do
|
72
|
+
subject[:project].actions_for(:collection).should include(:search)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'should have registered :publish as a member action' do
|
76
|
+
subject[:project].actions_for(:member).should include(:publish)
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should have registered :tag as a member action' do
|
80
|
+
subject[:project].actions_for(:member).should include(:publish)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
@@ -1,6 +1,14 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'fixtures/models'
|
3
3
|
|
4
|
+
class UserAccount
|
5
|
+
tango_account
|
6
|
+
end
|
7
|
+
|
8
|
+
class AdminAccount
|
9
|
+
tango_account
|
10
|
+
end
|
11
|
+
|
4
12
|
module AdminAccountPermits
|
5
13
|
class EditorRolePermit < CanTango::RolePermit
|
6
14
|
end
|
@@ -71,7 +79,6 @@ def setup
|
|
71
79
|
end
|
72
80
|
|
73
81
|
describe CanTango::Permits::RolePermit::Finder do
|
74
|
-
|
75
82
|
setup
|
76
83
|
|
77
84
|
context "Account" do
|
@@ -90,7 +97,7 @@ describe CanTango::Permits::RolePermit::Finder do
|
|
90
97
|
finder.permit_class.should == "EditorRolePermit"
|
91
98
|
end
|
92
99
|
end
|
93
|
-
|
100
|
+
|
94
101
|
describe '#get_permit' do
|
95
102
|
it 'should return the AdminAccount::EditorRolePermit' do
|
96
103
|
finder.get_permit.should == AdminAccountPermits::EditorRolePermit
|
@@ -34,10 +34,10 @@ describe CanTango::Permits::RoleGroupPermit do
|
|
34
34
|
describe 'attributes' do
|
35
35
|
it "should be the permit for the :admins group" do
|
36
36
|
permit.role_group.should == :admins
|
37
|
-
end
|
37
|
+
end
|
38
38
|
|
39
39
|
it "should have an ability" do
|
40
40
|
permit.ability.should be_a(CanTango::Ability)
|
41
|
-
end
|
41
|
+
end
|
42
42
|
end
|
43
43
|
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# registering a custom permit
|
2
|
+
#
|
3
|
+
|
4
|
+
require 'rspec'
|
5
|
+
require 'cantango'
|
6
|
+
# require 'simple_roles'
|
7
|
+
require 'fixtures/models'
|
8
|
+
require 'cantango/rspec'
|
9
|
+
|
10
|
+
class MembershipPermit < CanTango::Permit
|
11
|
+
class Builder
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
class Finder
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.inherited(base_clazz)
|
20
|
+
CanTango.config.permits.register_permit_class membership_name(base_clazz), base_clazz, type, account_name(base_clazz)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.type
|
24
|
+
:membership
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.membership_name clazz
|
28
|
+
clazz.name.demodulize.gsub(/(.*)(MembershipPermit)/, '\1').underscore.to_sym
|
29
|
+
end
|
30
|
+
|
31
|
+
def permit_name
|
32
|
+
self.class.membership_name self.class
|
33
|
+
end
|
34
|
+
alias_method :membership_name, :permit_name
|
35
|
+
|
36
|
+
# creates the permit
|
37
|
+
# @param [Permits::Ability] the ability
|
38
|
+
# @param [Hash] the options
|
39
|
+
def initialize ability
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
43
|
+
# In a specific Role based Permit you can use
|
44
|
+
# def permit? user, options = {}
|
45
|
+
# ... permission logic follows
|
46
|
+
#
|
47
|
+
# This will call the Permit::Base#permit? instance method (the method below)
|
48
|
+
# It will only return true if the user matches the role of the Permit class and the
|
49
|
+
#
|
50
|
+
# If these confitions are not met, it will return false and thus the outer permit
|
51
|
+
# will not run the permission logic to follow
|
52
|
+
#
|
53
|
+
# Normally super for #permit? should not be called except for this case,
|
54
|
+
# or if subclassing another Permit than Permit::Base
|
55
|
+
#
|
56
|
+
def permit?
|
57
|
+
super
|
58
|
+
end
|
59
|
+
|
60
|
+
def valid_for? subject
|
61
|
+
subject.memberships.include? membership_name
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe 'Custom Permit registration - Membership' do
|
66
|
+
it 'should register :membership as available permit' do
|
67
|
+
CanTango.config.permits.available_permits[:membership].should == MembershipPermit
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should register :membership as available permit type' do
|
71
|
+
CanTango.config.permits.available_types.should include(:membership)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should register MmembershipPermit as available permit class' do
|
75
|
+
CanTango.config.permits.available_classes.should include(MembershipPermit)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cantango
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.4
|
4
|
+
version: 0.9.4.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2011-11-
|
13
|
+
date: 2011-11-03 00:00:00.000000000Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rails
|
17
|
-
requirement: &
|
17
|
+
requirement: &70209186980320 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ! '>='
|
@@ -22,10 +22,10 @@ dependencies:
|
|
22
22
|
version: 3.0.1
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *70209186980320
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: cancan
|
28
|
-
requirement: &
|
28
|
+
requirement: &70209186979560 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - ! '>='
|
@@ -33,10 +33,10 @@ dependencies:
|
|
33
33
|
version: '1.4'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *70209186979560
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: sugar-high
|
39
|
-
requirement: &
|
39
|
+
requirement: &70209186978580 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
42
|
- - ! '>='
|
@@ -44,10 +44,10 @@ dependencies:
|
|
44
44
|
version: 0.6.0
|
45
45
|
type: :runtime
|
46
46
|
prerelease: false
|
47
|
-
version_requirements: *
|
47
|
+
version_requirements: *70209186978580
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: sweetloader
|
50
|
-
requirement: &
|
50
|
+
requirement: &70209186967700 !ruby/object:Gem::Requirement
|
51
51
|
none: false
|
52
52
|
requirements:
|
53
53
|
- - ~>
|
@@ -55,10 +55,10 @@ dependencies:
|
|
55
55
|
version: 0.1.0
|
56
56
|
type: :runtime
|
57
57
|
prerelease: false
|
58
|
-
version_requirements: *
|
58
|
+
version_requirements: *70209186967700
|
59
59
|
- !ruby/object:Gem::Dependency
|
60
60
|
name: hashie
|
61
|
-
requirement: &
|
61
|
+
requirement: &70209186965280 !ruby/object:Gem::Requirement
|
62
62
|
none: false
|
63
63
|
requirements:
|
64
64
|
- - ! '>='
|
@@ -66,10 +66,10 @@ dependencies:
|
|
66
66
|
version: '0.4'
|
67
67
|
type: :runtime
|
68
68
|
prerelease: false
|
69
|
-
version_requirements: *
|
69
|
+
version_requirements: *70209186965280
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
71
|
name: rspec-rails
|
72
|
-
requirement: &
|
72
|
+
requirement: &70209186963200 !ruby/object:Gem::Requirement
|
73
73
|
none: false
|
74
74
|
requirements:
|
75
75
|
- - ! '>='
|
@@ -77,10 +77,10 @@ dependencies:
|
|
77
77
|
version: 2.6.1
|
78
78
|
type: :development
|
79
79
|
prerelease: false
|
80
|
-
version_requirements: *
|
80
|
+
version_requirements: *70209186963200
|
81
81
|
- !ruby/object:Gem::Dependency
|
82
82
|
name: forgery
|
83
|
-
requirement: &
|
83
|
+
requirement: &70209186962020 !ruby/object:Gem::Requirement
|
84
84
|
none: false
|
85
85
|
requirements:
|
86
86
|
- - ! '>='
|
@@ -88,10 +88,10 @@ dependencies:
|
|
88
88
|
version: '0.3'
|
89
89
|
type: :development
|
90
90
|
prerelease: false
|
91
|
-
version_requirements: *
|
91
|
+
version_requirements: *70209186962020
|
92
92
|
- !ruby/object:Gem::Dependency
|
93
93
|
name: factory_girl
|
94
|
-
requirement: &
|
94
|
+
requirement: &70209186959280 !ruby/object:Gem::Requirement
|
95
95
|
none: false
|
96
96
|
requirements:
|
97
97
|
- - ! '>='
|
@@ -99,10 +99,10 @@ dependencies:
|
|
99
99
|
version: '0'
|
100
100
|
type: :development
|
101
101
|
prerelease: false
|
102
|
-
version_requirements: *
|
102
|
+
version_requirements: *70209186959280
|
103
103
|
- !ruby/object:Gem::Dependency
|
104
104
|
name: sqlite3
|
105
|
-
requirement: &
|
105
|
+
requirement: &70209186956860 !ruby/object:Gem::Requirement
|
106
106
|
none: false
|
107
107
|
requirements:
|
108
108
|
- - ! '>='
|
@@ -110,10 +110,10 @@ dependencies:
|
|
110
110
|
version: '0'
|
111
111
|
type: :development
|
112
112
|
prerelease: false
|
113
|
-
version_requirements: *
|
113
|
+
version_requirements: *70209186956860
|
114
114
|
- !ruby/object:Gem::Dependency
|
115
115
|
name: sourcify
|
116
|
-
requirement: &
|
116
|
+
requirement: &70209186956080 !ruby/object:Gem::Requirement
|
117
117
|
none: false
|
118
118
|
requirements:
|
119
119
|
- - ! '>='
|
@@ -121,10 +121,10 @@ dependencies:
|
|
121
121
|
version: '0'
|
122
122
|
type: :development
|
123
123
|
prerelease: false
|
124
|
-
version_requirements: *
|
124
|
+
version_requirements: *70209186956080
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: dkastner-moneta
|
127
|
-
requirement: &
|
127
|
+
requirement: &70209186955040 !ruby/object:Gem::Requirement
|
128
128
|
none: false
|
129
129
|
requirements:
|
130
130
|
- - ! '>='
|
@@ -132,10 +132,10 @@ dependencies:
|
|
132
132
|
version: '1.0'
|
133
133
|
type: :development
|
134
134
|
prerelease: false
|
135
|
-
version_requirements: *
|
135
|
+
version_requirements: *70209186955040
|
136
136
|
- !ruby/object:Gem::Dependency
|
137
137
|
name: rspec
|
138
|
-
requirement: &
|
138
|
+
requirement: &70209186953320 !ruby/object:Gem::Requirement
|
139
139
|
none: false
|
140
140
|
requirements:
|
141
141
|
- - ! '>='
|
@@ -143,10 +143,10 @@ dependencies:
|
|
143
143
|
version: 2.4.0
|
144
144
|
type: :development
|
145
145
|
prerelease: false
|
146
|
-
version_requirements: *
|
146
|
+
version_requirements: *70209186953320
|
147
147
|
- !ruby/object:Gem::Dependency
|
148
148
|
name: jeweler
|
149
|
-
requirement: &
|
149
|
+
requirement: &70209186931540 !ruby/object:Gem::Requirement
|
150
150
|
none: false
|
151
151
|
requirements:
|
152
152
|
- - ! '>='
|
@@ -154,10 +154,10 @@ dependencies:
|
|
154
154
|
version: 1.6.4
|
155
155
|
type: :development
|
156
156
|
prerelease: false
|
157
|
-
version_requirements: *
|
157
|
+
version_requirements: *70209186931540
|
158
158
|
- !ruby/object:Gem::Dependency
|
159
159
|
name: bundler
|
160
|
-
requirement: &
|
160
|
+
requirement: &70209186930560 !ruby/object:Gem::Requirement
|
161
161
|
none: false
|
162
162
|
requirements:
|
163
163
|
- - ! '>='
|
@@ -165,10 +165,10 @@ dependencies:
|
|
165
165
|
version: 1.0.1
|
166
166
|
type: :development
|
167
167
|
prerelease: false
|
168
|
-
version_requirements: *
|
168
|
+
version_requirements: *70209186930560
|
169
169
|
- !ruby/object:Gem::Dependency
|
170
170
|
name: rdoc
|
171
|
-
requirement: &
|
171
|
+
requirement: &70209186928720 !ruby/object:Gem::Requirement
|
172
172
|
none: false
|
173
173
|
requirements:
|
174
174
|
- - ! '>='
|
@@ -176,7 +176,7 @@ dependencies:
|
|
176
176
|
version: '0'
|
177
177
|
type: :development
|
178
178
|
prerelease: false
|
179
|
-
version_requirements: *
|
179
|
+
version_requirements: *70209186928720
|
180
180
|
description: ! 'Define your permission rules as role- or role group specific permits.
|
181
181
|
|
182
182
|
Integrates well with multiple Devise user acounts.
|
@@ -262,6 +262,7 @@ files:
|
|
262
262
|
- lib/cantango/configuration/guest.rb
|
263
263
|
- lib/cantango/configuration/hash_registry.rb
|
264
264
|
- lib/cantango/configuration/models.rb
|
265
|
+
- lib/cantango/configuration/models/actions.rb
|
265
266
|
- lib/cantango/configuration/models/active_record.rb
|
266
267
|
- lib/cantango/configuration/models/data_mapper.rb
|
267
268
|
- lib/cantango/configuration/models/generic.rb
|
@@ -288,6 +289,7 @@ files:
|
|
288
289
|
- lib/cantango/helpers/debug.rb
|
289
290
|
- lib/cantango/helpers/role_methods.rb
|
290
291
|
- lib/cantango/model.rb
|
292
|
+
- lib/cantango/model/actions.rb
|
291
293
|
- lib/cantango/model/filter.rb
|
292
294
|
- lib/cantango/model/scope.rb
|
293
295
|
- lib/cantango/permission_engine.rb
|
@@ -531,6 +533,7 @@ files:
|
|
531
533
|
- spec/cantango/configuration/user_spec.rb
|
532
534
|
- spec/cantango/configuration_spec.rb
|
533
535
|
- spec/cantango/license/save_license_spec.rb
|
536
|
+
- spec/cantango/model/actions_spec.rb
|
534
537
|
- spec/cantango/model/filter_spec.rb
|
535
538
|
- spec/cantango/model/scope_spec.rb
|
536
539
|
- spec/cantango/models/items.rb
|
@@ -568,6 +571,7 @@ files:
|
|
568
571
|
- spec/cantango/permit_engine/user_permit_spec.rb
|
569
572
|
- spec/cantango/permit_engine_cached_spec.rb
|
570
573
|
- spec/cantango/permit_engine_spec.rb
|
574
|
+
- spec/cantango/permits/custom_permit_spec.rb
|
571
575
|
- spec/cantango/permits/executor_cached_spec.rb
|
572
576
|
- spec/cantango/permits/executor_spec.rb
|
573
577
|
- spec/cantango/permits/macros_spec.rb
|
@@ -868,7 +872,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
868
872
|
version: '0'
|
869
873
|
segments:
|
870
874
|
- 0
|
871
|
-
hash: -
|
875
|
+
hash: -2565050033249570748
|
872
876
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
873
877
|
none: false
|
874
878
|
requirements:
|