i_am_i_can 2.1.0 → 3.0.0pre
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Build Status](https://travis-ci.org/zhandao/i_am_i_can.svg?branch=master)](https://travis-ci.org/zhandao/i_am_i_can)
|
4
4
|
[![Maintainability](https://api.codeclimate.com/v1/badges/27b664da01b6cc7180e3/maintainability)](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
|