i_am_i_can 4.0.0 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +48 -6
- data/lib/generators/i_am_i_can/templates/models/permission.erb +1 -1
- data/lib/generators/i_am_i_can/templates/models/role.erb +2 -4
- data/lib/generators/i_am_i_can/templates/models/role_group.erb +3 -3
- data/lib/i_am_i_can/helpers/dynamic.rb +11 -13
- data/lib/i_am_i_can/permission/assignment.rb +15 -6
- data/lib/i_am_i_can/role/assignment.rb +17 -7
- data/lib/i_am_i_can/role/grouping.rb +6 -0
- data/lib/i_am_i_can/role.rb +2 -4
- data/lib/i_am_i_can/role_group/definition.rb +1 -1
- data/lib/i_am_i_can/subject.rb +1 -0
- data/lib/i_am_i_can/support/association_class_methods.rb +2 -2
- data/lib/i_am_i_can/support/reflection.rb +1 -1
- data/lib/i_am_i_can/version.rb +1 -1
- data/lib/i_am_i_can.rb +5 -4
- metadata +3 -3
- data/lib/i_am_i_can/role_group/assignment.rb +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5c54e75b43df8cbfb0e8acd30cb0fc40e0aeda0
|
4
|
+
data.tar.gz: 5a0a6c5198cdb76ca0a251b99d7320cc2a081854
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 00ed26e8fe4e750241e92eda7d5acb084bc3a733f654af380e61f052c8723c62e5f8b82ef9e1907466caf02a8f7a2cc6c2d30fd44a20848b60965e53333e65f1
|
7
|
+
data.tar.gz: f6d4a8bbab40bfe9017f38a0f7acc63aa5784743e279a15c4b26611bab9ee8f39d1c58e572de1f48b9acfc36d464454869be057354329dad5119bc14d5bde1a3
|
data/README.md
CHANGED
@@ -58,8 +58,9 @@ Resource.that_allow(user, to: :manage) # => ActiveRecord_Relation[]
|
|
58
58
|
- [About role group](#about-role-group)
|
59
59
|
- [Three steps to use this gem](#three-steps-to-use-this-gem)
|
60
60
|
- [Two Concepts of this gem](#two-concepts-of-this-gem)
|
61
|
+
- [How it work?](#how-it-work)
|
61
62
|
|
62
|
-
2. [Installation
|
63
|
+
2. [Installation and Setup](#installation-and-setup)
|
63
64
|
|
64
65
|
3. [Usage](#usage)
|
65
66
|
- [Config Options](#config-options)
|
@@ -133,9 +134,20 @@ Resource.that_allow(user, to: :manage) # => ActiveRecord_Relation[]
|
|
133
134
|
1. Stored (save in database) TODO
|
134
135
|
2. Temporary (save in instance variable) TODO
|
135
136
|
|
137
|
+
### How it work?
|
138
|
+
|
139
|
+
Very simple. Really simple. Sooooo Simple.
|
140
|
+
|
141
|
+
1. To define something, you actually `create` records.
|
142
|
+
[see here](https://github.com/zhandao/i_am_i_can/blob/master/lib/i_am_i_can/helpers/dynamic.rb#L92)
|
143
|
+
2. To assign something, you actually call one of the activerecord association methods.
|
144
|
+
[see here](https://github.com/zhandao/i_am_i_can/blob/master/lib/i_am_i_can/helpers/dynamic.rb#L67)
|
145
|
+
2. To query something, you actually call the querying interfaces of activerecord.
|
146
|
+
[see here](https://github.com/zhandao/i_am_i_can/tree/master/lib/i_am_i_can/subject)
|
147
|
+
|
136
148
|
[Feature List: needs you](https://github.com/zhandao/i_am_i_can/issues/2)
|
137
149
|
|
138
|
-
## Installation
|
150
|
+
## Installation and Setup
|
139
151
|
|
140
152
|
1. Add this line to your application's Gemfile and then `bundle`:
|
141
153
|
|
@@ -251,7 +263,13 @@ UserRoleGroup.which(name: :vip).members.names # => %i[vip1 vip2 vip3]
|
|
251
263
|
3. `is_not_a` / `has_not_role` / `has_not_roles`
|
252
264
|
4. `will_not_be`
|
253
265
|
2. `is_not_a_temporary`
|
254
|
-
4.
|
266
|
+
4. replacement assignment by calling: `is_only_a`, alias `currently_is`.
|
267
|
+
(makes the role collection contain only the supplied roles, by adding and deleting as appropriate)
|
268
|
+
5. callbacks - before / after / around:
|
269
|
+
1. `role_assign`: assignment
|
270
|
+
2. `cancel_role_assign`: cancel assignment
|
271
|
+
3. `role_update`:
|
272
|
+
6. helpers:
|
255
273
|
1. relation with stored role, defaults to `stored_roles`.
|
256
274
|
2. `temporary_roles` and `valid_temporary_roles`
|
257
275
|
3. `roles`
|
@@ -287,6 +305,12 @@ is_not_a_temporary *roles
|
|
287
305
|
he.falls_from :admin # => 'Role Assignment Done' or error message
|
288
306
|
he.is_not_a_temporary :coder # => 'Role Assignment Done' or error message
|
289
307
|
he.roles # => []
|
308
|
+
|
309
|
+
# === Replacement Assignment ===
|
310
|
+
# method signature
|
311
|
+
is_only_a *roles
|
312
|
+
# examples
|
313
|
+
he.is_only_a :role1, :role2
|
290
314
|
```
|
291
315
|
|
292
316
|
#### D. [Role / Group Querying](https://github.com/zhandao/i_am_i_can/blob/master/lib/i_am_i_can/subject/role_querying.rb)
|
@@ -347,6 +371,12 @@ UserPermission.count # => 1 + 2
|
|
347
371
|
1. caller: role / role group instance, like `UserRole.which(name: :admin)`
|
348
372
|
2. assignment by calling `can`. alias `has_permission`
|
349
373
|
3. cancel assignment by calling `cannot`. alias `is_not_allowed_to`
|
374
|
+
4. replacement assignment by calling: `can_only`,.
|
375
|
+
(makes the permission collection contain only the supplied permissions, by adding and deleting as appropriate)
|
376
|
+
5. callbacks - before / after / around:
|
377
|
+
1. `permission_assign`: assignment
|
378
|
+
2. `cancel_permission_assign`: cancel assignment
|
379
|
+
3. `permission_update`: replacement assignment
|
350
380
|
4. helpers:
|
351
381
|
1. relation with stored permission, defaults to `permissions`.
|
352
382
|
|
@@ -359,11 +389,23 @@ UserRole.have_permission :fly
|
|
359
389
|
|
360
390
|
# === Assignment ===
|
361
391
|
# method signature
|
362
|
-
can *actions, resource: nil, obj: resource,
|
392
|
+
can *actions, resource: nil, obj: resource, # you can use `resource` or `obj`
|
363
393
|
_d: config.auto_definition, auto_definition: _d
|
364
394
|
# examples
|
365
395
|
role.can :fly # => 'Permission Assignment Done' or error message
|
366
396
|
role.permissions # => [<#UserPermission id: ..>]
|
397
|
+
|
398
|
+
# === Cancel Assignment ===
|
399
|
+
# method signature
|
400
|
+
cannot *actions, resource: nil, obj: resource
|
401
|
+
# examples
|
402
|
+
role.cannot :fly
|
403
|
+
|
404
|
+
# === Replacement Assignment ===
|
405
|
+
# method signature
|
406
|
+
can_only *actions, resource: nil, obj: resource
|
407
|
+
# examples
|
408
|
+
role.can_only :run
|
367
409
|
```
|
368
410
|
|
369
411
|
#### G. [Permission Querying](https://github.com/zhandao/i_am_i_can/blob/master/lib/i_am_i_can/subject/role_querying.rb)
|
@@ -397,8 +439,8 @@ he.can? :perform, obj: :magic
|
|
397
439
|
he.cannot? :perform, :magic
|
398
440
|
he.can! :perform, :magic
|
399
441
|
|
400
|
-
he.can_each? %i[fly jump] # return false if he can not `fly` or `jump`
|
401
|
-
he.can_one_of! %i[fly jump] # return true if he can `fly` or `jump`
|
442
|
+
he.can_each? %i[ fly jump ] # return false if he can not `fly` or `jump`
|
443
|
+
he.can_one_of! %i[ fly jump ] # return true if he can `fly` or `jump`
|
402
444
|
```
|
403
445
|
|
404
446
|
#### H. Shortcut Combinations - which_can
|
@@ -5,7 +5,7 @@ class <%= permission_c %> < ActiveRecord::Base
|
|
5
5
|
has_and_belongs_to_many :related_role_groups,
|
6
6
|
join_table: '<%= group_pms_tb %>', foreign_key: :<%= group_u %>_id, class_name: '<%= group_c %>', association_foreign_key: :<%= permission_u %>_id
|
7
7
|
<% end %>
|
8
|
-
belongs_to :
|
8
|
+
belongs_to :resource, polymorphic: true
|
9
9
|
|
10
10
|
acts_as_permission
|
11
11
|
end
|
@@ -2,17 +2,15 @@ class <%= role_c %> < ActiveRecord::Base
|
|
2
2
|
has_and_belongs_to_many :related_users,
|
3
3
|
join_table: '<%= subj_role_tb %>', foreign_key: :<%= name_u %>_id, class_name: '<%= name_c %>', association_foreign_key: :<%= role_u %>_id
|
4
4
|
<% unless @ii_opts[:without_group] %>
|
5
|
-
has_and_belongs_to_many :
|
5
|
+
has_and_belongs_to_many :related_groups,
|
6
6
|
join_table: '<%= group_role_tb %>', foreign_key: :<%= group_u %>_id, class_name: '<%= group_c %>', association_foreign_key: :<%= role_u %>_id
|
7
7
|
<% end %>
|
8
8
|
has_and_belongs_to_many :permissions,
|
9
9
|
join_table: '<%= role_pms_tb %>', foreign_key: :<%= permission_u %>_id, class_name: '<%= permission_c %>', association_foreign_key: :<%= role_u %>_id
|
10
10
|
|
11
|
-
has_many_temporary_permissions
|
12
|
-
|
13
11
|
acts_as_role
|
14
12
|
|
15
|
-
# default_scope {
|
13
|
+
# default_scope { with_permissions }
|
16
14
|
end
|
17
15
|
|
18
16
|
__END__
|
@@ -5,11 +5,11 @@ class RoleGroup < ActiveRecord::Base
|
|
5
5
|
has_and_belongs_to_many :members,
|
6
6
|
join_table: '<%= group_role_tb %>', foreign_key: :<%= role_u %>_id, class_name: '<%= role_c %>', association_foreign_key: :<%= group_u %>_id
|
7
7
|
|
8
|
-
has_many_temporary_permissions
|
9
|
-
|
10
8
|
acts_as_role_group
|
11
9
|
|
12
|
-
# default_scope { with_members
|
10
|
+
# default_scope { with_members) }
|
11
|
+
|
12
|
+
# default_scope { with_permissions) }
|
13
13
|
end
|
14
14
|
|
15
15
|
__END__
|
@@ -53,23 +53,21 @@ module IAmICan
|
|
53
53
|
# You call the proc below by given contents [:role], then:
|
54
54
|
#
|
55
55
|
proc { |contents| contents.each do |content|
|
56
|
-
content_cls = i_am_i_can.send("#{content}_class")
|
56
|
+
content_cls = i_am_i_can.send("#{content}_class") rescue next
|
57
57
|
_plural = '_' + content.to_s.pluralize
|
58
|
+
__plural = send("_#{_plural}")
|
58
59
|
|
59
60
|
# _stored_roles_exec
|
60
61
|
# Add / Remove (by passing action :cancel) roles to a user instance
|
61
|
-
define_method "_#{_reflect_of(content)}_exec" do |action = :
|
62
|
-
collection = send(_plural)
|
63
|
-
|
64
|
-
# Role.where(name: [...]).where.not(id: roles.ids)
|
65
|
-
query_result = content_cls.constantize.where(conditions).where.not(id: collection.ids)
|
66
|
-
elsif conditions.present? && action == :cancel
|
67
|
-
# Role.where(id: roles.ids, name: [...])
|
68
|
-
query_result = content_cls.constantize.where(id: collection.ids, **conditions)
|
69
|
-
end
|
62
|
+
define_method "_#{_reflect_of(content)}_exec" do |action = :assign, instances = [ ], **conditions|
|
63
|
+
collection, objects = send(_plural), [ ]
|
64
|
+
records = conditions.present? ? content_cls.constantize.where(conditions) : [ ]
|
70
65
|
|
71
|
-
|
72
|
-
|
66
|
+
case action
|
67
|
+
when :assign then collection << objects = (records + instances).uniq - collection
|
68
|
+
when :cancel then collection.destroy objects = (records + instances).uniq & collection
|
69
|
+
when :replace then send("#{__plural}=", objects = (records + instances).uniq) # collection=
|
70
|
+
end
|
73
71
|
objects
|
74
72
|
end
|
75
73
|
#
|
@@ -86,7 +84,7 @@ module IAmICan
|
|
86
84
|
# You call the proc below by given contents [:role], then:
|
87
85
|
#
|
88
86
|
proc { |contents| contents.each do |content|
|
89
|
-
content_cls = i_am_i_can.send("#{content}_class")
|
87
|
+
content_cls = i_am_i_can.send("#{content}_class") rescue next
|
90
88
|
_plural = '_' + content.to_s.pluralize
|
91
89
|
|
92
90
|
# _create_roles
|
@@ -1,22 +1,31 @@
|
|
1
1
|
module IAmICan
|
2
2
|
module Permission
|
3
3
|
module Assignment
|
4
|
-
def can *actions,
|
5
|
-
resource: nil, obj: resource,
|
4
|
+
def can *actions, resource: nil, obj: resource,
|
6
5
|
_d: i_am_i_can.auto_definition, auto_definition: _d
|
7
6
|
self.class.have_permissions *actions, obj: obj if auto_definition
|
8
|
-
|
7
|
+
run_callbacks(:permission_assign) do
|
8
|
+
_permissions_assignment(actions, obj)
|
9
|
+
end
|
9
10
|
end
|
10
11
|
|
11
12
|
alias has_permission can
|
12
13
|
|
13
|
-
def cannot *actions, obj:
|
14
|
-
|
14
|
+
def cannot *actions, resource: nil, obj: resource
|
15
|
+
run_callbacks(:cancel_permission_assign) do
|
16
|
+
_permissions_assignment(:cancel, actions, obj)
|
17
|
+
end
|
15
18
|
end
|
16
19
|
|
17
20
|
alias is_not_allowed_to cannot
|
18
21
|
|
19
|
-
def
|
22
|
+
def can_only *actions, resource: nil, obj: resource
|
23
|
+
run_callbacks(:permission_update) do
|
24
|
+
_permissions_assignment(:replace, actions, obj)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def _permissions_assignment(action = :assign, actions, obj)
|
20
29
|
permissions = actions.product(Array[obj]).map { |(p, o)| { action: p, **deconstruct_obj(o) } }
|
21
30
|
assignment = _stored_permissions_exec(action,
|
22
31
|
permissions.reduce({ }) { |a, b| a.merge(b) { |_, x, y| [x, y] } })
|
@@ -6,26 +6,36 @@ module IAmICan
|
|
6
6
|
auto_definition: _d || which_can.present?,
|
7
7
|
save: true
|
8
8
|
self.class.have_roles *roles, which_can: which_can, obj: obj if auto_definition
|
9
|
-
|
9
|
+
run_callbacks(:role_assign) do
|
10
|
+
_roles_assignment(roles, save)
|
11
|
+
end
|
10
12
|
end
|
11
13
|
|
12
|
-
%i[ is is_a is_a_role is_roles has_role has_roles role_is role_are ].each { |aname| alias_method aname, :becomes_a }
|
13
|
-
|
14
14
|
def is_a_temporary *roles, **options
|
15
15
|
becomes_a *roles, save: false, **options
|
16
16
|
end
|
17
17
|
|
18
18
|
def falls_from *roles, saved: true
|
19
|
-
|
19
|
+
run_callbacks(:cancel_role_assign) do
|
20
|
+
_roles_assignment(:cancel, roles, saved)
|
21
|
+
end
|
20
22
|
end
|
21
23
|
|
22
|
-
%i[ is_not_a will_not_be removes_role leaves has_not_role has_not_roles ].each { |aname| alias_method aname, :falls_from }
|
23
|
-
|
24
24
|
def is_not_a_temporary *roles
|
25
25
|
falls_from *roles, saved: false
|
26
26
|
end
|
27
27
|
|
28
|
-
def
|
28
|
+
def is_only_a *roles
|
29
|
+
run_callbacks(:role_update) do
|
30
|
+
_roles_assignment(:replace, roles, true)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
%i[ is is_a is_a_role is_roles has_role has_roles role_is role_are ].each { |aname| alias_method aname, :becomes_a }
|
35
|
+
%i[ is_not_a will_not_be removes_role leaves has_not_role has_not_roles ].each { |aname| alias_method aname, :falls_from }
|
36
|
+
%i[ currently_is_a ].each { |aname| alias_method aname, :is_only_a }
|
37
|
+
|
38
|
+
def _roles_assignment(action = :assign, roles, save)
|
29
39
|
instances, names = Role.extract(roles, i_am_i_can)
|
30
40
|
if save
|
31
41
|
assignment = _stored_roles_exec(action, instances, name: names)
|
data/lib/i_am_i_can/role.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'i_am_i_can/role/definition'
|
2
2
|
require 'i_am_i_can/role/assignment'
|
3
|
+
require 'i_am_i_can/role/grouping'
|
3
4
|
require 'i_am_i_can/role_group/definition'
|
4
|
-
require 'i_am_i_can/role_group/assignment'
|
5
5
|
|
6
6
|
module IAmICan
|
7
7
|
module Role
|
@@ -18,9 +18,7 @@ module IAmICan
|
|
18
18
|
end
|
19
19
|
|
20
20
|
included do
|
21
|
-
|
22
|
-
# super.symbolize_keys
|
23
|
-
# end
|
21
|
+
define_model_callbacks :permission_assign, :cancel_permission_assign, :permission_update
|
24
22
|
|
25
23
|
# `can? :manage, User` / `can? :manage, obj: User`
|
26
24
|
def can? action, o = nil, obj: o
|
@@ -4,7 +4,7 @@ module IAmICan
|
|
4
4
|
def group_roles *members, by_name:, which_can: [ ], obj: nil
|
5
5
|
group = (i = i_am_i_can).role_group_model.where(name: by_name).first_or_create
|
6
6
|
instances, names = Role.extract(members, i)
|
7
|
-
assignment = group._members_exec(:
|
7
|
+
assignment = group._members_exec(:assign, instances, name: names)
|
8
8
|
ResultOf.members assignment, i, given: [instances, names]
|
9
9
|
end
|
10
10
|
|
data/lib/i_am_i_can/subject.rb
CHANGED
@@ -35,8 +35,8 @@ module IAmICan
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
define_method :_temporary_roles_exec do |action = :
|
39
|
-
send('_temporary_roles_' + (action == :
|
38
|
+
define_method :_temporary_roles_exec do |action = :assign, names|
|
39
|
+
send('_temporary_roles_' + (action == :assign ? 'add' : 'rmv'), names)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
data/lib/i_am_i_can/version.rb
CHANGED
data/lib/i_am_i_can.rb
CHANGED
@@ -15,7 +15,7 @@ require 'i_am_i_can/resource'
|
|
15
15
|
|
16
16
|
module IAmICan
|
17
17
|
def acts_as_subject
|
18
|
-
i_am_i_can
|
18
|
+
i_am_i_can&.act = :subject
|
19
19
|
include Subject
|
20
20
|
|
21
21
|
extend Role::Definition
|
@@ -32,7 +32,7 @@ module IAmICan
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def acts_as_role
|
35
|
-
i_am_i_can
|
35
|
+
i_am_i_can&.act = :role
|
36
36
|
include Role
|
37
37
|
|
38
38
|
extend Permission::Definition
|
@@ -49,10 +49,11 @@ module IAmICan
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def acts_as_role_group
|
52
|
-
i_am_i_can
|
52
|
+
i_am_i_can&.act = :role_group
|
53
53
|
include Role
|
54
54
|
# include RoleGroup
|
55
55
|
|
56
|
+
include Role::Grouping
|
56
57
|
extend Permission::Definition
|
57
58
|
include Permission::Assignment
|
58
59
|
|
@@ -67,7 +68,7 @@ module IAmICan
|
|
67
68
|
end
|
68
69
|
|
69
70
|
def acts_as_permission
|
70
|
-
i_am_i_can
|
71
|
+
i_am_i_can&.act = :permission
|
71
72
|
include Permission
|
72
73
|
|
73
74
|
include Reflection
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: i_am_i_can
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- zhandao
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-12-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -204,7 +204,7 @@ files:
|
|
204
204
|
- lib/i_am_i_can/role.rb
|
205
205
|
- lib/i_am_i_can/role/assignment.rb
|
206
206
|
- lib/i_am_i_can/role/definition.rb
|
207
|
-
- lib/i_am_i_can/
|
207
|
+
- lib/i_am_i_can/role/grouping.rb
|
208
208
|
- lib/i_am_i_can/role_group/definition.rb
|
209
209
|
- lib/i_am_i_can/subject.rb
|
210
210
|
- lib/i_am_i_can/subject/permission_querying.rb
|