cantango 0.9.4 → 0.9.4.1
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|