i_am_i_can 2.1.0 → 3.0.0pre
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 +5 -5
- data/.github/issue_template.md +15 -0
- data/.github/pull_request_template.md +8 -0
- data/Gemfile.lock +7 -4
- data/README.md +1 -1
- data/i_am_i_can.gemspec +1 -1
- data/lib/generators/i_am_i_can/setup_generator.rb +2 -2
- data/lib/i_am_i_can/permission/definition.rb +2 -2
- data/lib/i_am_i_can/permission/helpers.rb +5 -3
- data/lib/i_am_i_can/permission.rb +3 -3
- data/lib/i_am_i_can/role/assignment.rb +1 -1
- data/lib/i_am_i_can/role/helpers.rb +14 -4
- data/lib/i_am_i_can/version.rb +1 -1
- data/lib/i_am_i_can.rb +11 -13
- metadata +9 -8
- data/lib/i_am_i_can/has_an_array_of.rb +0 -75
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8a7c648cdb9a60d42ca538e28735070ef9644325
|
4
|
+
data.tar.gz: 4a5ee5a0a56967049baeeddafc944fe6fc548479
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f684f54b656c925ff293706fec374eee0592b7ad91df3502e4fa031255f17f96cac95c22c8ee9e0426786453539ec6d26400b6fb8c9afe11d10dfa1b306d4343
|
7
|
+
data.tar.gz: a855e8ebc30a47548b42be4f43ef07d4ec90816418369962e9562b3e773e878c7a2c748501911c41f77d891cd4f85562ec5491a7dec7c44e699510954c8c9bba
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
i_am_i_can (
|
4
|
+
i_am_i_can (3.0.0pre)
|
5
5
|
activerecord
|
6
6
|
activesupport
|
7
7
|
railties
|
@@ -35,6 +35,7 @@ GEM
|
|
35
35
|
tzinfo (~> 1.1)
|
36
36
|
arel (9.0.0)
|
37
37
|
builder (3.2.3)
|
38
|
+
coderay (1.1.2)
|
38
39
|
concurrent-ruby (1.0.5)
|
39
40
|
crass (1.0.4)
|
40
41
|
database_cleaner (1.7.0)
|
@@ -52,7 +53,9 @@ GEM
|
|
52
53
|
minitest (5.11.3)
|
53
54
|
nokogiri (1.8.4)
|
54
55
|
mini_portile2 (~> 2.3.0)
|
55
|
-
|
56
|
+
pry (0.11.3)
|
57
|
+
coderay (~> 1.1.0)
|
58
|
+
method_source (~> 0.9.0)
|
56
59
|
rack (2.0.5)
|
57
60
|
rack-test (1.1.0)
|
58
61
|
rack (>= 1.0, < 3)
|
@@ -106,11 +109,11 @@ DEPENDENCIES
|
|
106
109
|
bundler (~> 1.16)
|
107
110
|
database_cleaner
|
108
111
|
i_am_i_can!
|
109
|
-
|
112
|
+
pry
|
110
113
|
rake (~> 10.0)
|
111
114
|
rspec (~> 3.0)
|
112
115
|
rspec-rails
|
113
116
|
simplecov
|
114
117
|
|
115
118
|
BUNDLED WITH
|
116
|
-
1.16.
|
119
|
+
1.16.6
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# IAmICan
|
1
|
+
# IAmICan
|
2
2
|
|
3
3
|
[](https://travis-ci.org/zhandao/i_am_i_can)
|
4
4
|
[](https://codeclimate.com/github/zhandao/i_am_i_can/maintainability)
|
data/i_am_i_can.gemspec
CHANGED
@@ -26,8 +26,8 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.add_development_dependency "rspec", "~> 3.0"
|
27
27
|
spec.add_development_dependency 'rspec-rails'
|
28
28
|
spec.add_development_dependency 'database_cleaner'
|
29
|
-
spec.add_development_dependency 'pg'
|
30
29
|
spec.add_development_dependency 'simplecov'
|
30
|
+
spec.add_development_dependency 'pry'
|
31
31
|
|
32
32
|
|
33
33
|
spec.add_dependency 'activerecord'
|
@@ -44,8 +44,8 @@ module IAmICan
|
|
44
44
|
|
45
45
|
def tip
|
46
46
|
options = ' ' + @ii_opts.to_s[2..-2].gsub('=>', ': ').gsub(', :', ', ') if @ii_opts.keys.present?
|
47
|
-
puts 'Please add this line to your subject model:'.
|
48
|
-
puts " act_as_i_am_i_can#{options}".
|
47
|
+
puts 'Please add this line to your subject model:'.green
|
48
|
+
puts " act_as_i_am_i_can#{options}".green
|
49
49
|
end
|
50
50
|
|
51
51
|
def self.next_migration_number(dirname)
|
@@ -6,8 +6,8 @@ module IAmICan
|
|
6
6
|
module Definition
|
7
7
|
include Helpers::Cls
|
8
8
|
|
9
|
-
def which(name
|
10
|
-
find_by!(name: name)
|
9
|
+
def which(name:, **conditions)
|
10
|
+
find_by!(name: name, **conditions)
|
11
11
|
end
|
12
12
|
|
13
13
|
def have_permission *preds, obj: nil, desc: nil, save: config.default_save
|
@@ -6,7 +6,8 @@ module IAmICan
|
|
6
6
|
prefix = 'Permission Definition Done'
|
7
7
|
fail_msg = prefix + ", but #{failed_items} have been defined" if failed_items.present?
|
8
8
|
raise Error, fail_msg if config.strict_mode && fail_msg
|
9
|
-
fail_msg
|
9
|
+
puts fail_msg || prefix unless ENV['ITEST']
|
10
|
+
prefix.present?
|
10
11
|
end
|
11
12
|
|
12
13
|
def _to_store_permission(pred, obj, **options)
|
@@ -30,11 +31,12 @@ module IAmICan
|
|
30
31
|
module Ins
|
31
32
|
def _pms_assignment_result(preds, obj, not_defined_items, covered_items = nil, strict_mode = false)
|
32
33
|
prefix = 'Permission Assignment Done'
|
33
|
-
msg1 = "#{not_defined_items} have not been defined" if not_defined_items.present?
|
34
|
+
msg1 = "#{not_defined_items} have not been defined or have been repeatedly assigned" if not_defined_items.present?
|
34
35
|
msg2 = "#{covered_items} have been covered" if covered_items.present?
|
35
36
|
fail_msg = prefix + ', but ' + [msg1, msg2].compact.join(', ') if msg1 || msg2
|
36
37
|
raise Error, fail_msg if (strict_mode || config.strict_mode) && fail_msg
|
37
|
-
fail_msg
|
38
|
+
puts fail_msg || prefix unless ENV['ITEST']
|
39
|
+
prefix.present?
|
38
40
|
end
|
39
41
|
|
40
42
|
def pms_matched?(pms_name, plist)
|
@@ -6,8 +6,8 @@ module IAmICan
|
|
6
6
|
PArray.new(options[:in]).matched?(pms_name || naming(pred, obj))
|
7
7
|
end
|
8
8
|
|
9
|
-
def which(pred:, obj: nil)
|
10
|
-
find_by!(pred: pred, **deconstruct_obj(obj))
|
9
|
+
def which(pred:, obj: nil, **conditions)
|
10
|
+
find_by!(pred: pred, **deconstruct_obj(obj), **conditions)
|
11
11
|
end
|
12
12
|
|
13
13
|
def naming(pred, obj)
|
@@ -25,7 +25,7 @@ module IAmICan
|
|
25
25
|
elsif obj.respond_to?(:attributes)
|
26
26
|
{ obj_type: obj.class.name, obj_id: obj.id }
|
27
27
|
else
|
28
|
-
{ obj_type: obj.to_s }
|
28
|
+
{ obj_type: obj.to_s, obj_id: nil }
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -10,7 +10,7 @@ module IAmICan
|
|
10
10
|
self.class.have_roles *roles, which_can: which_can, obj: obj, save: save if should_define_role
|
11
11
|
failed_items = [ ]
|
12
12
|
|
13
|
-
roles.each do |role|
|
13
|
+
roles.map(&__role).each do |role|
|
14
14
|
if save
|
15
15
|
failed_items << role unless stored_roles_add(role)
|
16
16
|
else
|
@@ -3,7 +3,7 @@ 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
|
6
|
+
return false if ii_config.role_model.exists?(name: name) || ii_config.role_group_model&.exists?(name: name)
|
7
7
|
ii_config.role_model.create!(name: name, **options)
|
8
8
|
end
|
9
9
|
|
@@ -11,16 +11,26 @@ module IAmICan
|
|
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
13
|
raise Error, fail_msg if ii_config.strict_mode && fail_msg
|
14
|
-
fail_msg
|
14
|
+
puts fail_msg || prefix unless ENV['ITEST']
|
15
|
+
prefix.present?
|
15
16
|
end
|
16
17
|
end
|
17
18
|
|
18
19
|
module Ins
|
19
20
|
def _role_assignment_result(names, failed_items)
|
20
21
|
prefix = 'Role Assignment Done'
|
21
|
-
fail_msg = prefix + ", but #{failed_items} have not been defined" if failed_items.present?
|
22
|
+
fail_msg = prefix + ", but #{failed_items} have not been defined or have been repeatedly assigned" if failed_items.present?
|
22
23
|
raise Error, fail_msg if ii_config.strict_mode && fail_msg
|
23
|
-
fail_msg
|
24
|
+
puts fail_msg || prefix unless ENV['ITEST']
|
25
|
+
prefix.present?
|
26
|
+
end
|
27
|
+
|
28
|
+
def __role
|
29
|
+
proc do |role|
|
30
|
+
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)
|
32
|
+
# raise error
|
33
|
+
end
|
24
34
|
end
|
25
35
|
end
|
26
36
|
end
|
data/lib/i_am_i_can/version.rb
CHANGED
data/lib/i_am_i_can.rb
CHANGED
@@ -3,7 +3,6 @@ require 'active_support/core_ext/object/inclusion'
|
|
3
3
|
require 'active_support/core_ext/hash/deep_merge'
|
4
4
|
|
5
5
|
require 'i_am_i_can/version'
|
6
|
-
require 'i_am_i_can/has_an_array_of'
|
7
6
|
require 'i_am_i_can/config'
|
8
7
|
require 'i_am_i_can/role/definition'
|
9
8
|
require 'i_am_i_can/role/assignment'
|
@@ -14,8 +13,6 @@ require 'i_am_i_can/subject/role_querying'
|
|
14
13
|
require 'i_am_i_can/subject/permission_querying'
|
15
14
|
|
16
15
|
module IAmICan
|
17
|
-
include HasAnArrayOf
|
18
|
-
|
19
16
|
def act_as_i_am_i_can role_model: "#{name}Role".constantize,
|
20
17
|
role_group_model: ("#{name}RoleGroup".constantize rescue nil),
|
21
18
|
permission_model: "#{name}Permission".constantize, **options
|
@@ -40,17 +37,18 @@ module IAmICan
|
|
40
37
|
role_group_model&.extend IAmICan::Permission::Definition
|
41
38
|
role_group_model&.include IAmICan::Permission::Assignment
|
42
39
|
self.include IAmICan::Subject::PermissionQuerying
|
40
|
+
end
|
41
|
+
|
42
|
+
def act_as_role
|
43
|
+
#
|
44
|
+
end
|
45
|
+
|
46
|
+
def act_as_role_group
|
47
|
+
#
|
48
|
+
end
|
43
49
|
|
44
|
-
|
45
|
-
|
46
|
-
located_by: :name,
|
47
|
-
prefix: :stored,
|
48
|
-
cache_expires_in: options[:cache_expires_in] || 15.minutes
|
49
|
-
}
|
50
|
-
self.has_an_array_of :roles, model: role_model.name, for_related_name: name.underscore, **opts
|
51
|
-
role_group_model&.has_an_array_of :members, model: role_model.name, for_related_name: 'role_group', **opts.except(:prefix)
|
52
|
-
role_model.has_an_array_of :permissions, model: permission_model.name, for_related_name: 'role', **opts.except(:attrs, :located_by)
|
53
|
-
role_group_model&.has_an_array_of :permissions, model: permission_model.name, for_related_name: 'role_group', **opts.except(:attrs, :located_by)
|
50
|
+
def act_as_permission
|
51
|
+
#
|
54
52
|
end
|
55
53
|
|
56
54
|
class Error < StandardError; end
|
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
|
+
version: 3.0.0pre
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- zhandao
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-10-
|
11
|
+
date: 2018-10-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -81,7 +81,7 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: simplecov
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - ">="
|
@@ -95,7 +95,7 @@ dependencies:
|
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: pry
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - ">="
|
@@ -158,6 +158,8 @@ executables: []
|
|
158
158
|
extensions: []
|
159
159
|
extra_rdoc_files: []
|
160
160
|
files:
|
161
|
+
- ".github/issue_template.md"
|
162
|
+
- ".github/pull_request_template.md"
|
161
163
|
- ".gitignore"
|
162
164
|
- ".rspec"
|
163
165
|
- ".travis.yml"
|
@@ -181,7 +183,6 @@ files:
|
|
181
183
|
- lib/generators/i_am_i_can/templates/models/role_group.erb
|
182
184
|
- lib/i_am_i_can.rb
|
183
185
|
- lib/i_am_i_can/config.rb
|
184
|
-
- lib/i_am_i_can/has_an_array_of.rb
|
185
186
|
- lib/i_am_i_can/permission.rb
|
186
187
|
- lib/i_am_i_can/permission/assignment.rb
|
187
188
|
- lib/i_am_i_can/permission/definition.rb
|
@@ -208,12 +209,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
208
209
|
version: '0'
|
209
210
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
210
211
|
requirements:
|
211
|
-
- - "
|
212
|
+
- - ">"
|
212
213
|
- !ruby/object:Gem::Version
|
213
|
-
version:
|
214
|
+
version: 1.3.1
|
214
215
|
requirements: []
|
215
216
|
rubyforge_project:
|
216
|
-
rubygems_version: 2.
|
217
|
+
rubygems_version: 2.6.12
|
217
218
|
signing_key:
|
218
219
|
specification_version: 4
|
219
220
|
summary: Concise and Natural DSL for `Subject - Role(Role Group) - Permission` Management.
|
@@ -1,75 +0,0 @@
|
|
1
|
-
module IAmICan
|
2
|
-
module HasAnArrayOf
|
3
|
-
def has_an_array_of obj, model: nil, field: nil,
|
4
|
-
prefix: nil, attrs: [ ], located_by: nil, cache_expires_in: nil, for_related_name: nil
|
5
|
-
obj_model = model.constantize || obj.to_s.singularize.camelize.constantize
|
6
|
-
field = field || :"#{obj.to_s.singularize}_ids"
|
7
|
-
prefix = "#{prefix}_" if prefix
|
8
|
-
|
9
|
-
# User.where(..).stored_roles
|
10
|
-
define_singleton_method "#{prefix}#{obj}" do
|
11
|
-
obj_ids = self.all.map(&field).flatten.uniq
|
12
|
-
obj_model.where(id: obj_ids)
|
13
|
-
end
|
14
|
-
|
15
|
-
# user.stored_roles
|
16
|
-
define_method "#{prefix}#{obj}" do
|
17
|
-
obj_model.where(id: send(field))
|
18
|
-
end
|
19
|
-
|
20
|
-
# cached_stored_roles
|
21
|
-
define_method "cached_#{prefix}#{obj}" do |**options|
|
22
|
-
Rails.cache.fetch("#{self.class.name}/#{id}/#{obj}", expires_in: cache_expires_in, **options) do
|
23
|
-
obj_model.where(id: send(field))
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
# stored_roles_add
|
28
|
-
define_method "#{prefix}#{obj}_add" do |locate_vals = nil, check_size: nil, **condition|
|
29
|
-
condition = { located_by => locate_vals } if locate_vals
|
30
|
-
obj_ids = obj_model.where(condition)&.pluck(:id)
|
31
|
-
# will return false if it does nothing
|
32
|
-
return false if obj_ids.blank? || (check_size && obj_ids != check_size)
|
33
|
-
(send(field).concat(obj_ids)).uniq!
|
34
|
-
save!
|
35
|
-
end
|
36
|
-
|
37
|
-
# stored_roles_rmv
|
38
|
-
define_method "#{prefix}#{obj}_rmv" do |locate_vals = nil, check_size: nil, **condition|
|
39
|
-
condition = { located_by => locate_vals } if locate_vals
|
40
|
-
obj_ids = obj_model.where(condition)&.pluck(:id)
|
41
|
-
# will return false if it does nothing
|
42
|
-
return false if obj_ids.blank? || (check_size && obj_ids != check_size)
|
43
|
-
send("#{field}=", send(field) - obj_ids)
|
44
|
-
save!
|
45
|
-
end
|
46
|
-
|
47
|
-
attrs.each do |(attr_name, attr_type)|
|
48
|
-
# User.where(..).stored_role_names
|
49
|
-
define_singleton_method "#{prefix}#{obj.to_s.singularize}_#{attr_name.to_s.pluralize}" do
|
50
|
-
res = send("#{prefix}#{obj}").pluck(attr_name)
|
51
|
-
attr_type ? res.map(&attr_type) : res
|
52
|
-
end
|
53
|
-
|
54
|
-
# user.stored_role_names
|
55
|
-
define_method "#{prefix}#{obj.to_s.singularize}_#{attr_name.to_s.pluralize}" do
|
56
|
-
res = send("#{prefix}#{obj}").pluck(attr_name)
|
57
|
-
attr_type ? res.map(&attr_type) : res
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
# === actions for object model ===
|
62
|
-
obj_model.class_exec(for_related_name, self, field) do |subject_name, subject_model, related_field|
|
63
|
-
# roles.related_users
|
64
|
-
define_singleton_method "related_#{(subject_name || subject_model.name).underscore.pluralize}" do
|
65
|
-
subject_model.where("#{related_field} @> ARRAY[?]::integer[]", ids)
|
66
|
-
end
|
67
|
-
|
68
|
-
# role.related_users
|
69
|
-
define_method "related_#{(subject_name || subject_model.name).underscore.pluralize}" do
|
70
|
-
subject_model.where("? = ANY (#{related_field})", self.id)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|