i_am_i_can 3.0.0pre → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +3 -1
- data/README.md +46 -23
- data/i_am_i_can.gemspec +3 -2
- data/lib/generators/i_am_i_can/setup_generator.rb +53 -16
- data/lib/generators/i_am_i_can/templates/initializers/i_am_i_can.erb +8 -0
- data/lib/generators/i_am_i_can/templates/migrations/i_am_i_can.erb +78 -0
- data/lib/generators/i_am_i_can/templates/models/permission.erb +9 -2
- data/lib/generators/i_am_i_can/templates/models/role.erb +15 -4
- data/lib/generators/i_am_i_can/templates/models/role_group.erb +12 -5
- data/lib/i_am_i_can/configs/config.rb +32 -0
- data/lib/i_am_i_can/configs/configs.rb +29 -0
- data/lib/i_am_i_can/configurable.rb +28 -0
- data/lib/i_am_i_can/dynamic_generate.rb +95 -0
- data/lib/i_am_i_can/permission/assignment.rb +3 -18
- data/lib/i_am_i_can/permission/definition.rb +1 -21
- data/lib/i_am_i_can/permission/helpers.rb +35 -8
- data/lib/i_am_i_can/permission.rb +50 -50
- data/lib/i_am_i_can/reflection.rb +25 -0
- data/lib/i_am_i_can/resource.rb +29 -0
- data/lib/i_am_i_can/role/assignment.rb +2 -16
- data/lib/i_am_i_can/role/definition.rb +4 -46
- data/lib/i_am_i_can/role/helpers.rb +43 -5
- data/lib/i_am_i_can/role.rb +17 -0
- data/lib/i_am_i_can/subject/permission_querying.rb +4 -4
- data/lib/i_am_i_can/subject.rb +24 -0
- data/lib/i_am_i_can/version.rb +1 -1
- data/lib/i_am_i_can.rb +52 -35
- metadata +32 -12
- data/lib/generators/i_am_i_can/templates/migrations/add_to_subject.erb +0 -5
- data/lib/generators/i_am_i_can/templates/migrations/permission.erb +0 -15
- data/lib/generators/i_am_i_can/templates/migrations/role.erb +0 -13
- data/lib/generators/i_am_i_can/templates/migrations/role_group.erb +0 -14
- data/lib/i_am_i_can/config.rb +0 -14
@@ -6,7 +6,7 @@ module IAmICan
|
|
6
6
|
include Helpers::Ins
|
7
7
|
|
8
8
|
# permission assignment for stored role
|
9
|
-
def can *preds, obj: nil, strict_mode: false, auto_define_before:
|
9
|
+
def can *preds, obj: nil, strict_mode: false, auto_define_before: i_am_i_can.auto_define_before
|
10
10
|
self.class.have_permissions *preds, obj: obj if auto_define_before
|
11
11
|
not_defined_items, covered_items = [ ], [ ]
|
12
12
|
|
@@ -21,8 +21,8 @@ module IAmICan
|
|
21
21
|
|
22
22
|
alias has_permission can
|
23
23
|
|
24
|
-
def temporarily_can *preds, obj: nil, strict_mode: false, auto_define_before:
|
25
|
-
raise Error, "Permission Assignment: local role `#{name}` was not defined" unless
|
24
|
+
def temporarily_can *preds, obj: nil, strict_mode: false, auto_define_before: i_am_i_can.auto_define_before
|
25
|
+
raise Error, "Permission Assignment: local role `#{name}` was not defined" unless i_am_i_can.subject_model.defined_local_roles.key?(self.name.to_sym)
|
26
26
|
self.class.have_permissions *preds, obj: obj, save: false if auto_define_before
|
27
27
|
not_defined_items, covered_items = [ ], [ ]
|
28
28
|
|
@@ -70,21 +70,6 @@ module IAmICan
|
|
70
70
|
end
|
71
71
|
|
72
72
|
alias locally_can? temporarily_can?
|
73
|
-
|
74
|
-
def local_permissions
|
75
|
-
@local_permissions ||= [ ]
|
76
|
-
end
|
77
|
-
|
78
|
-
alias local_permission_names local_permissions
|
79
|
-
|
80
|
-
def stored_permission_names
|
81
|
-
stored_permissions.map(&:name)
|
82
|
-
end
|
83
|
-
|
84
|
-
# TODO: show by hash
|
85
|
-
def permissions
|
86
|
-
local_permission_names + stored_permission_names
|
87
|
-
end
|
88
73
|
end
|
89
74
|
end
|
90
75
|
end
|
@@ -6,11 +6,7 @@ module IAmICan
|
|
6
6
|
module Definition
|
7
7
|
include Helpers::Cls
|
8
8
|
|
9
|
-
def
|
10
|
-
find_by!(name: name, **conditions)
|
11
|
-
end
|
12
|
-
|
13
|
-
def have_permission *preds, obj: nil, desc: nil, save: config.default_save
|
9
|
+
def have_permission *preds, obj: nil, desc: nil, save: i_am_i_can.default_save
|
14
10
|
failed_items = [ ]
|
15
11
|
|
16
12
|
preds.each do |pred|
|
@@ -37,22 +33,6 @@ module IAmICan
|
|
37
33
|
|
38
34
|
alias declare_permissions declare_permission
|
39
35
|
|
40
|
-
def defined_local_permissions
|
41
|
-
@defined_local_permissions ||= { }
|
42
|
-
end
|
43
|
-
|
44
|
-
def defined_stored_pms_names
|
45
|
-
config.permission_model.all.map(&:name)
|
46
|
-
end
|
47
|
-
|
48
|
-
def defined_stored_permissions
|
49
|
-
config.permission_model.all.map { |pms| [ pms.name, pms.desc ] }.to_h
|
50
|
-
end
|
51
|
-
|
52
|
-
def defined_permissions
|
53
|
-
defined_local_permissions.deep_merge(defined_stored_permissions)
|
54
|
-
end
|
55
|
-
|
56
36
|
def self.extended(kls)
|
57
37
|
kls.delegate :defined_permissions, :pms_naming, :deconstruct_obj, :pms_of_defined_local_role, to: kls
|
58
38
|
end
|
@@ -5,26 +5,42 @@ module IAmICan
|
|
5
5
|
def _pms_definition_result(preds, obj, failed_items)
|
6
6
|
prefix = 'Permission Definition Done'
|
7
7
|
fail_msg = prefix + ", but #{failed_items} have been defined" if failed_items.present?
|
8
|
-
raise Error, fail_msg if
|
8
|
+
raise Error, fail_msg if i_am_i_can.strict_mode && fail_msg
|
9
9
|
puts fail_msg || prefix unless ENV['ITEST']
|
10
10
|
prefix.present?
|
11
11
|
end
|
12
12
|
|
13
13
|
def _to_store_permission(pred, obj, **options)
|
14
|
-
return false if
|
15
|
-
|
14
|
+
return false if i_am_i_can.permission_model.exists?(pred, obj)
|
15
|
+
i_am_i_can.permission_model.create!(pred: pred, **deconstruct_obj(obj), **options)
|
16
16
|
end
|
17
17
|
|
18
18
|
def pms_naming(pred, obj)
|
19
|
-
|
19
|
+
i_am_i_can.permission_model.naming(pred, obj)
|
20
20
|
end
|
21
21
|
|
22
22
|
def deconstruct_obj(obj)
|
23
|
-
|
23
|
+
i_am_i_can.permission_model.deconstruct_obj(obj)
|
24
|
+
end
|
25
|
+
|
26
|
+
def defined_local_permissions
|
27
|
+
@defined_local_permissions ||= { }
|
28
|
+
end
|
29
|
+
|
30
|
+
def defined_stored_pms_names
|
31
|
+
i_am_i_can.permission_model.all.map(&:name)
|
32
|
+
end
|
33
|
+
|
34
|
+
def defined_stored_permissions
|
35
|
+
i_am_i_can.permission_model.all.map { |pms| [ pms.name, pms.desc ] }.to_h
|
36
|
+
end
|
37
|
+
|
38
|
+
def defined_permissions
|
39
|
+
defined_local_permissions.deep_merge(defined_stored_permissions)
|
24
40
|
end
|
25
41
|
|
26
42
|
def pms_of_defined_local_role(role_name)
|
27
|
-
|
43
|
+
i_am_i_can.subject_model.defined_local_roles[role_name.to_sym]&.[](:permissions) || []
|
28
44
|
end
|
29
45
|
end
|
30
46
|
|
@@ -34,13 +50,24 @@ module IAmICan
|
|
34
50
|
msg1 = "#{not_defined_items} have not been defined or have been repeatedly assigned" if not_defined_items.present?
|
35
51
|
msg2 = "#{covered_items} have been covered" if covered_items.present?
|
36
52
|
fail_msg = prefix + ', but ' + [msg1, msg2].compact.join(', ') if msg1 || msg2
|
37
|
-
raise Error, fail_msg if (strict_mode ||
|
53
|
+
raise Error, fail_msg if (strict_mode || i_am_i_can.strict_mode) && fail_msg
|
38
54
|
puts fail_msg || prefix unless ENV['ITEST']
|
39
55
|
prefix.present?
|
40
56
|
end
|
41
57
|
|
42
58
|
def pms_matched?(pms_name, plist)
|
43
|
-
|
59
|
+
i_am_i_can.permission_model.matched?(pms_name, in: plist[:in])
|
60
|
+
end
|
61
|
+
|
62
|
+
def local_permissions
|
63
|
+
@local_permissions ||= [ ]
|
64
|
+
end
|
65
|
+
|
66
|
+
alias local_permission_names local_permissions
|
67
|
+
|
68
|
+
# TODO: show by hash
|
69
|
+
def permissions
|
70
|
+
local_permission_names + stored_permission_names
|
44
71
|
end
|
45
72
|
end
|
46
73
|
end
|
@@ -1,68 +1,68 @@
|
|
1
1
|
require 'i_am_i_can/permission/p_array'
|
2
|
+
require 'i_am_i_can/permission/definition'
|
3
|
+
require 'i_am_i_can/permission/assignment'
|
2
4
|
|
3
5
|
module IAmICan
|
4
6
|
module Permission
|
5
|
-
|
6
|
-
PArray.new(options[:in]).matched?(pms_name || naming(pred, obj))
|
7
|
-
end
|
8
|
-
|
9
|
-
def which(pred:, obj: nil, **conditions)
|
10
|
-
find_by!(pred: pred, **deconstruct_obj(obj), **conditions)
|
11
|
-
end
|
12
|
-
|
13
|
-
def naming(pred, obj)
|
14
|
-
obj_type, obj_id = deconstruct_obj(obj).values
|
15
|
-
otp = "_#{obj_type}" if obj_type.present?
|
16
|
-
oid = "_#{obj_id}" if obj_id.present?
|
17
|
-
[pred, otp, oid].join.to_sym
|
18
|
-
end
|
7
|
+
extend ActiveSupport::Concern
|
19
8
|
|
20
|
-
|
21
|
-
|
9
|
+
class_methods do
|
10
|
+
def matched?(pms_name = nil, pred: nil, obj: nil, **options)
|
11
|
+
PArray.new(options[:in]).matched?(pms_name || naming(pred, obj))
|
12
|
+
end
|
22
13
|
|
23
|
-
|
24
|
-
|
25
|
-
elsif obj.respond_to?(:attributes)
|
26
|
-
{ obj_type: obj.class.name, obj_id: obj.id }
|
27
|
-
else
|
28
|
-
{ obj_type: obj.to_s, obj_id: nil }
|
14
|
+
def which(pred:, obj: nil, **conditions)
|
15
|
+
find_by!(pred: pred, **deconstruct_obj(obj), **conditions)
|
29
16
|
end
|
30
|
-
end
|
31
17
|
|
32
|
-
|
33
|
-
|
34
|
-
|
18
|
+
def naming(pred, obj)
|
19
|
+
obj_type, obj_id = deconstruct_obj(obj).values
|
20
|
+
otp = "_#{obj_type}" if obj_type.present?
|
21
|
+
oid = "_#{obj_id}" if obj_id.present?
|
22
|
+
[pred, otp, oid].join.to_sym
|
23
|
+
end
|
35
24
|
|
36
|
-
|
37
|
-
|
38
|
-
end
|
39
|
-
end
|
25
|
+
def deconstruct_obj(obj)
|
26
|
+
return { } unless obj
|
40
27
|
|
41
|
-
|
28
|
+
if obj.is_a?(String) || obj.is_a?(Symbol)
|
29
|
+
{ obj_type: obj }
|
30
|
+
elsif obj.respond_to?(:attributes)
|
31
|
+
{ obj_type: obj.class.name, obj_id: obj.id }
|
32
|
+
else
|
33
|
+
{ obj_type: obj.to_s, obj_id: nil }
|
34
|
+
end
|
35
|
+
end
|
42
36
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
otp = "_#{obj_type}" if obj_type.present?
|
47
|
-
oid = "_#{obj_id}" if obj_id.present?
|
48
|
-
[pred, otp, oid].join.to_sym
|
37
|
+
def exists?(pred, obj)
|
38
|
+
super(pred: pred, **deconstruct_obj(obj))
|
39
|
+
end
|
49
40
|
end
|
50
41
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
end
|
42
|
+
included do
|
43
|
+
# like: manage_User_1
|
44
|
+
def name
|
45
|
+
otp = "_#{obj_type}" if obj_type.present?
|
46
|
+
oid = "_#{obj_id}" if obj_id.present?
|
47
|
+
[pred, otp, oid].join.to_sym
|
48
|
+
end
|
59
49
|
|
60
|
-
|
50
|
+
# def assign_to role: nil, group: nil
|
51
|
+
# obj = if role
|
52
|
+
# role.is_a?(Symbol) ? i_am_i_can.role_model.find(name: role) : role
|
53
|
+
# else
|
54
|
+
# group.is_a?(Symbol) ? i_am_i_can.role_group_model.find(name: role) : group
|
55
|
+
# end
|
56
|
+
# obj.have_permission self.pred, obj: self.obj
|
57
|
+
# end
|
58
|
+
#
|
59
|
+
# alias is_assigned_to assign_to
|
61
60
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
61
|
+
# :user, User, user
|
62
|
+
def obj
|
63
|
+
return obj_type.constantize.find(obj_id) if obj_id.present?
|
64
|
+
obj_type[/[A-Z]/] ? obj_type.constantize : obj_type.to_sym
|
65
|
+
end
|
66
66
|
end
|
67
67
|
end
|
68
68
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module IAmICan
|
2
|
+
module Reflection
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
class_methods do
|
6
|
+
# User._roles => 'stored_roles'
|
7
|
+
%w[ subjects roles role_groups permissions ].each do |k|
|
8
|
+
define_method "_#{k}" do
|
9
|
+
v = instance_variable_get("@_#{k}")
|
10
|
+
return v if v.present?
|
11
|
+
instance_variable_set("@_#{k}", _reflect_of(k.singularize))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
included do
|
17
|
+
# user._roles => Association CollectionProxy, same as: `user.stored_roles`
|
18
|
+
%w[ subjects roles role_groups permissions ].each do |k|
|
19
|
+
define_method "_#{k}" do
|
20
|
+
send(self.class.send("_#{k}")) if self.class.send("_#{k}")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module IAmICan
|
2
|
+
module Resource
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
class_methods do
|
6
|
+
# Book.that_allow(User.all).to(:read)
|
7
|
+
# Book.that_allow(User.last).to(:write)
|
8
|
+
def that_allow(subject)
|
9
|
+
ThatAllow.new(self, subject)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class ThatAllow
|
15
|
+
attr_accessor :records, :subject
|
16
|
+
|
17
|
+
def initialize(records, subject)
|
18
|
+
self.records = records
|
19
|
+
self.subject = subject
|
20
|
+
end
|
21
|
+
|
22
|
+
def to(pred)
|
23
|
+
roles = Configs.take.subject_model._roles
|
24
|
+
permissions = Configs.take.role_model._permissions
|
25
|
+
allowed_ids = subject.send(roles).send(permissions).where(pred: pred, obj_type: records.name).pluck(:obj_id)
|
26
|
+
records.where(id: allowed_ids)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -5,7 +5,7 @@ module IAmICan
|
|
5
5
|
module Assignment
|
6
6
|
include Helpers::Ins
|
7
7
|
|
8
|
-
def becomes_a *roles, which_can: [ ], obj: nil, auto_define_before:
|
8
|
+
def becomes_a *roles, which_can: [ ], obj: nil, auto_define_before: i_am_i_can.auto_define_before, save: i_am_i_can.default_save
|
9
9
|
should_define_role = which_can.present? || auto_define_before
|
10
10
|
self.class.have_roles *roles, which_can: which_can, obj: obj, save: save if should_define_role
|
11
11
|
failed_items = [ ]
|
@@ -36,7 +36,7 @@ module IAmICan
|
|
36
36
|
|
37
37
|
alias locally_is temporarily_is
|
38
38
|
|
39
|
-
def falls_from *roles, saved:
|
39
|
+
def falls_from *roles, saved: i_am_i_can.default_save
|
40
40
|
failed_items = [ ]
|
41
41
|
|
42
42
|
roles.each do |role|
|
@@ -57,20 +57,6 @@ module IAmICan
|
|
57
57
|
alias leaves falls_from
|
58
58
|
alias has_not_role falls_from
|
59
59
|
alias has_not_roles falls_from
|
60
|
-
|
61
|
-
def local_role_names
|
62
|
-
@local_role_names ||= [ ]
|
63
|
-
end
|
64
|
-
|
65
|
-
def local_roles
|
66
|
-
defined_local_roles.slice(*local_role_names)
|
67
|
-
end
|
68
|
-
|
69
|
-
def roles
|
70
|
-
local_role_names + stored_role_names
|
71
|
-
end
|
72
|
-
|
73
|
-
alias role_names roles
|
74
60
|
end
|
75
61
|
end
|
76
62
|
end
|
@@ -5,14 +5,14 @@ module IAmICan
|
|
5
5
|
module Definition
|
6
6
|
include Helpers::Cls
|
7
7
|
|
8
|
-
def have_role *names, desc: nil, save:
|
8
|
+
def have_role *names, desc: nil, save: i_am_i_can.default_save, which_can: [ ], obj: nil
|
9
9
|
failed_items, preds = [ ], which_can
|
10
10
|
|
11
11
|
names.each do |name|
|
12
12
|
description = desc || name.to_s.humanize
|
13
13
|
if save
|
14
14
|
next failed_items << name unless _to_store_role(name, desc: description)
|
15
|
-
|
15
|
+
i_am_i_can.role_model.which(name: name).can *preds, obj: obj, auto_define_before: true, strict_mode: true if which_can.present?
|
16
16
|
else
|
17
17
|
next failed_items << name if defined_local_roles.key?(name)
|
18
18
|
defined_local_roles[name] ||= { desc: description, permissions: [ ] }
|
@@ -35,8 +35,8 @@ module IAmICan
|
|
35
35
|
|
36
36
|
def group_roles *members, by_name:, which_can: [ ], obj: nil
|
37
37
|
raise Error, 'Some of members have not been defined' unless (members - defined_stored_role_names).empty?
|
38
|
-
raise Error, "Given name #{by_name} has been used by a role" if
|
39
|
-
|
38
|
+
raise Error, "Given name #{by_name} has been used by a role" if i_am_i_can.role_model.exists?(name: by_name)
|
39
|
+
i_am_i_can.role_group_model.find_or_create_by!(name: by_name).members_add(members)
|
40
40
|
end
|
41
41
|
|
42
42
|
alias group_role group_roles
|
@@ -50,51 +50,9 @@ module IAmICan
|
|
50
50
|
|
51
51
|
alias has_and_groups_roles have_and_group_roles
|
52
52
|
|
53
|
-
# permission assignment locally for local role
|
54
|
-
# User.local_role_which(name: :admin, can: :fly)
|
55
|
-
# same effect to: UserRole.new(name: :admin).temporarily_can :fly
|
56
|
-
def local_role_which(name:, can:, obj: nil, **options)
|
57
|
-
ii_config.role_model.new(name: name).temporarily_can *Array(can), obj: obj, **options
|
58
|
-
end
|
59
|
-
|
60
53
|
def self.extended(kls)
|
61
54
|
kls.delegate :defined_local_roles, :defined_stored_roles, :defined_roles, to: kls
|
62
55
|
end
|
63
56
|
end
|
64
|
-
|
65
|
-
# === End of MainMethods ===
|
66
|
-
|
67
|
-
module Definition::SecondaryMethods
|
68
|
-
def defined_local_roles
|
69
|
-
@local_roles ||= { }
|
70
|
-
end
|
71
|
-
|
72
|
-
def defined_stored_role_names
|
73
|
-
ii_config.role_model.pluck(:name).map(&:to_sym)
|
74
|
-
end
|
75
|
-
|
76
|
-
def defined_stored_roles
|
77
|
-
ii_config.role_model.all.map { |role| [ role.name.to_sym, role.desc ] }.to_h
|
78
|
-
end
|
79
|
-
|
80
|
-
def defined_roles
|
81
|
-
defined_local_roles.deep_merge(defined_stored_roles)
|
82
|
-
end
|
83
|
-
|
84
|
-
def defined_role_group_names
|
85
|
-
ii_config.role_group_model.pluck(:name).map(&:to_sym)
|
86
|
-
|
87
|
-
end
|
88
|
-
|
89
|
-
def defined_role_groups
|
90
|
-
ii_config.role_group_model.all.map { |group| [ group.name.to_sym, group.member_names.map(&:to_sym) ] }.to_h
|
91
|
-
end
|
92
|
-
|
93
|
-
def members_of_role_group name
|
94
|
-
ii_config.role_group_model.find_by!(name: name).member_names
|
95
|
-
end
|
96
|
-
|
97
|
-
Definition.include self
|
98
|
-
end
|
99
57
|
end
|
100
58
|
end
|
@@ -3,24 +3,48 @@ module IAmICan
|
|
3
3
|
module Helpers
|
4
4
|
module Cls
|
5
5
|
def _to_store_role name, **options
|
6
|
-
return false if
|
7
|
-
|
6
|
+
return false if i_am_i_can.role_model.exists?(name: name) || i_am_i_can.role_group_model&.exists?(name: name)
|
7
|
+
i_am_i_can.role_model.create!(name: name, **options)
|
8
8
|
end
|
9
9
|
|
10
10
|
def _role_definition_result(names, failed_items)
|
11
11
|
prefix = 'Role Definition Done'
|
12
12
|
fail_msg = prefix + ", but name #{failed_items} have been used by other role or group" if failed_items.present?
|
13
|
-
raise Error, fail_msg if
|
13
|
+
raise Error, fail_msg if i_am_i_can.strict_mode && fail_msg
|
14
14
|
puts fail_msg || prefix unless ENV['ITEST']
|
15
15
|
prefix.present?
|
16
16
|
end
|
17
|
+
|
18
|
+
def defined_local_roles
|
19
|
+
@local_roles ||= { }
|
20
|
+
end
|
21
|
+
|
22
|
+
def defined_stored_role_names
|
23
|
+
i_am_i_can.role_model.pluck(:name).map(&:to_sym)
|
24
|
+
end
|
25
|
+
|
26
|
+
def defined_stored_roles
|
27
|
+
i_am_i_can.role_model.all.map { |role| [ role.name.to_sym, role.desc ] }.to_h
|
28
|
+
end
|
29
|
+
|
30
|
+
def defined_roles
|
31
|
+
defined_local_roles.deep_merge(defined_stored_roles)
|
32
|
+
end
|
33
|
+
|
34
|
+
def defined_role_group_names
|
35
|
+
i_am_i_can.role_group_model.pluck(:name).map(&:to_sym)
|
36
|
+
end
|
37
|
+
|
38
|
+
def defined_role_groups
|
39
|
+
i_am_i_can.role_group_model.all.map { |group| [ group.name.to_sym, group.member_names.map(&:to_sym).sort ] }.to_h
|
40
|
+
end
|
17
41
|
end
|
18
42
|
|
19
43
|
module Ins
|
20
44
|
def _role_assignment_result(names, failed_items)
|
21
45
|
prefix = 'Role Assignment Done'
|
22
46
|
fail_msg = prefix + ", but #{failed_items} have not been defined or have been repeatedly assigned" if failed_items.present?
|
23
|
-
raise Error, fail_msg if
|
47
|
+
raise Error, fail_msg if i_am_i_can.strict_mode && fail_msg
|
24
48
|
puts fail_msg || prefix unless ENV['ITEST']
|
25
49
|
prefix.present?
|
26
50
|
end
|
@@ -28,10 +52,24 @@ module IAmICan
|
|
28
52
|
def __role
|
29
53
|
proc do |role|
|
30
54
|
next role.to_sym if role.is_a?(String) || role.is_a?(Symbol)
|
31
|
-
next role.name if role.is_a?(
|
55
|
+
next role.name if role.is_a?(i_am_i_can.role_model)
|
32
56
|
# raise error
|
33
57
|
end
|
34
58
|
end
|
59
|
+
|
60
|
+
def local_role_names
|
61
|
+
@local_role_names ||= [ ]
|
62
|
+
end
|
63
|
+
|
64
|
+
def local_roles
|
65
|
+
defined_local_roles.slice(*local_role_names)
|
66
|
+
end
|
67
|
+
|
68
|
+
def roles
|
69
|
+
local_role_names + stored_role_names
|
70
|
+
end
|
71
|
+
|
72
|
+
alias role_names roles
|
35
73
|
end
|
36
74
|
end
|
37
75
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'i_am_i_can/role/definition'
|
2
|
+
require 'i_am_i_can/role/assignment'
|
3
|
+
|
4
|
+
module IAmICan
|
5
|
+
module Role
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
class_methods do
|
9
|
+
def which(name:, **conditions)
|
10
|
+
find_by!(name: name, **conditions)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
included do
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -39,18 +39,18 @@ module IAmICan
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def temporarily_can? pred, obj
|
42
|
-
|
42
|
+
i_am_i_can.permission_model.matched?(pred: pred, obj: obj, in: permissions_of_local_roles)
|
43
43
|
end
|
44
44
|
|
45
45
|
alias locally_can? temporarily_can?
|
46
46
|
|
47
47
|
def stored_can? pred, obj
|
48
|
-
|
48
|
+
i_am_i_can.permission_model.matched?(pred: pred, obj: obj, in: permissions_of_stored_roles)
|
49
49
|
end
|
50
50
|
|
51
51
|
def group_can? pred, obj, without_group = false
|
52
|
-
return false if without_group ||
|
53
|
-
|
52
|
+
return false if without_group || i_am_i_can.without_group
|
53
|
+
i_am_i_can.permission_model.matched?(pred: pred, obj: obj, in: permissions_of_role_groups)
|
54
54
|
end
|
55
55
|
|
56
56
|
def permissions_of_stored_roles
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'i_am_i_can/subject/role_querying'
|
2
|
+
require 'i_am_i_can/subject/permission_querying'
|
3
|
+
|
4
|
+
module IAmICan
|
5
|
+
module Subject
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
class_methods do
|
9
|
+
# permission assignment locally for local role
|
10
|
+
# User.local_role_which(name: :admin, can: :fly)
|
11
|
+
# same effect to: UserRole.new(name: :admin).temporarily_can :fly
|
12
|
+
def local_role_which(name:, can:, obj: nil, **options)
|
13
|
+
i_am_i_can.role_model.new(name: name).temporarily_can *Array(can), obj: obj, **options
|
14
|
+
end
|
15
|
+
|
16
|
+
def members_of_role_group name
|
17
|
+
i_am_i_can.role_group_model.find_by!(name: name).member_names.sort
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
included do
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/i_am_i_can/version.rb
CHANGED