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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +3 -1
  3. data/README.md +46 -23
  4. data/i_am_i_can.gemspec +3 -2
  5. data/lib/generators/i_am_i_can/setup_generator.rb +53 -16
  6. data/lib/generators/i_am_i_can/templates/initializers/i_am_i_can.erb +8 -0
  7. data/lib/generators/i_am_i_can/templates/migrations/i_am_i_can.erb +78 -0
  8. data/lib/generators/i_am_i_can/templates/models/permission.erb +9 -2
  9. data/lib/generators/i_am_i_can/templates/models/role.erb +15 -4
  10. data/lib/generators/i_am_i_can/templates/models/role_group.erb +12 -5
  11. data/lib/i_am_i_can/configs/config.rb +32 -0
  12. data/lib/i_am_i_can/configs/configs.rb +29 -0
  13. data/lib/i_am_i_can/configurable.rb +28 -0
  14. data/lib/i_am_i_can/dynamic_generate.rb +95 -0
  15. data/lib/i_am_i_can/permission/assignment.rb +3 -18
  16. data/lib/i_am_i_can/permission/definition.rb +1 -21
  17. data/lib/i_am_i_can/permission/helpers.rb +35 -8
  18. data/lib/i_am_i_can/permission.rb +50 -50
  19. data/lib/i_am_i_can/reflection.rb +25 -0
  20. data/lib/i_am_i_can/resource.rb +29 -0
  21. data/lib/i_am_i_can/role/assignment.rb +2 -16
  22. data/lib/i_am_i_can/role/definition.rb +4 -46
  23. data/lib/i_am_i_can/role/helpers.rb +43 -5
  24. data/lib/i_am_i_can/role.rb +17 -0
  25. data/lib/i_am_i_can/subject/permission_querying.rb +4 -4
  26. data/lib/i_am_i_can/subject.rb +24 -0
  27. data/lib/i_am_i_can/version.rb +1 -1
  28. data/lib/i_am_i_can.rb +52 -35
  29. metadata +32 -12
  30. data/lib/generators/i_am_i_can/templates/migrations/add_to_subject.erb +0 -5
  31. data/lib/generators/i_am_i_can/templates/migrations/permission.erb +0 -15
  32. data/lib/generators/i_am_i_can/templates/migrations/role.erb +0 -13
  33. data/lib/generators/i_am_i_can/templates/migrations/role_group.erb +0 -14
  34. 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: config.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: config.auto_define_before
25
- raise Error, "Permission Assignment: local role `#{name}` was not defined" unless config.subject_model.defined_local_roles.key?(self.name.to_sym)
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 which(name:, **conditions)
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 config.strict_mode && fail_msg
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 config.permission_model.exists?(pred, obj)
15
- config.permission_model.create!(pred: pred, **deconstruct_obj(obj), **options)
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
- config.permission_model.naming(pred, obj)
19
+ i_am_i_can.permission_model.naming(pred, obj)
20
20
  end
21
21
 
22
22
  def deconstruct_obj(obj)
23
- config.permission_model.deconstruct_obj(obj)
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
- config.subject_model.defined_local_roles[role_name.to_sym]&.[](:permissions) || []
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 || config.strict_mode) && fail_msg
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
- config.permission_model.matched?(pms_name, in: plist[:in])
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
- def matched?(pms_name = nil, pred: nil, obj: nil, **options)
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
- def deconstruct_obj(obj)
21
- return { } unless obj
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
- if obj.is_a?(String) || obj.is_a?(Symbol)
24
- { obj_type: obj }
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
- def exists?(pred, obj)
33
- super(pred: pred, **deconstruct_obj(obj))
34
- end
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
- def self.extended(kls)
37
- kls.include InstanceMethods
38
- end
39
- end
25
+ def deconstruct_obj(obj)
26
+ return { } unless obj
40
27
 
41
- # === End of ClassMethods ===
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
- module Permission::InstanceMethods
44
- # like: manage_User_1
45
- def name
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
- def assign_to role: nil, group: nil
52
- obj = if role
53
- role.is_a?(Symbol) ? ii_config.role_model.find(name: role) : role
54
- else
55
- group.is_a?(Symbol) ? ii_config.role_group_model.find(name: role) : group
56
- end
57
- obj.have_permission self.pred, obj: self.obj
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
- alias is_assigned_to assign_to
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
- # :user, User, user
63
- def obj
64
- return obj_type.constantize.find(obj_id) if obj_id.present?
65
- obj_type[/[A-Z]/] ? obj_type.constantize : obj_type.to_sym
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: ii_config.auto_define_before, save: ii_config.default_save
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: ii_config.default_save
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: ii_config.default_save, which_can: [ ], obj: nil
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
- ii_config.role_model.which(name: name).can *preds, obj: obj, auto_define_before: true, strict_mode: true if which_can.present?
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 ii_config.role_model.exists?(name: by_name)
39
- ii_config.role_group_model.find_or_create_by!(name: by_name).members_add(members)
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 ii_config.role_model.exists?(name: name) || ii_config.role_group_model&.exists?(name: name)
7
- ii_config.role_model.create!(name: name, **options)
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 ii_config.strict_mode && fail_msg
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 ii_config.strict_mode && fail_msg
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?(ii_config.role_model)
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
- ii_config.permission_model.matched?(pred: pred, obj: obj, in: permissions_of_local_roles)
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
- ii_config.permission_model.matched?(pred: pred, obj: obj, in: permissions_of_stored_roles)
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 || ii_config.without_group
53
- ii_config.permission_model.matched?(pred: pred, obj: obj, in: permissions_of_role_groups)
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
@@ -1,3 +1,3 @@
1
1
  module IAmICan
2
- VERSION = '3.0.0pre'
2
+ VERSION = '3.0.0'
3
3
  end