i_am_i_can 3.0.0pre → 3.0.0
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.
- 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