bullet_train-roles 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/bullet_train/roles/version.rb +1 -1
- data/lib/models/role.rb +13 -23
- data/lib/roles/permit.rb +0 -8
- data/lib/roles/support.rb +21 -8
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 51bbbee558714e45bdff2dadf3735cf8a2fce88d7e7e3a8144880c245bb8e384
|
4
|
+
data.tar.gz: 419402bc1f7560bc932c202275091456e4a68ddd271ddf7382df57b7f4b21b1f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 30bfee959c7c45e7dda23c7d4f71fa44a1efc9499e3bd5244e48e55895ff88e21fc26ade42def3591661c0aef1796762edae9a05625b1145822c5eb3a71cfc43
|
7
|
+
data.tar.gz: 6da43045a530531c8910f4c456f7c5b7211ac90f9cce69d05fc7a7456fedb664d099a951d0c5fdd131f4daa8f0784ac36add7837bfcc7760ff5193c22191c21c
|
data/lib/models/role.rb
CHANGED
@@ -21,17 +21,12 @@ class Role < ActiveYaml::Base
|
|
21
21
|
|
22
22
|
def self.includes(role_or_key)
|
23
23
|
role_key = role_or_key.is_a?(Role) ? role_or_key.key : role_or_key
|
24
|
-
|
25
24
|
role = Role.find_by_key(role_key)
|
26
|
-
|
27
25
|
return Role.all.select(&:assignable?) if role.default?
|
28
|
-
|
29
26
|
result = []
|
30
|
-
|
31
27
|
all.each do |role|
|
32
28
|
result << role if role.includes.include?(role_key)
|
33
29
|
end
|
34
|
-
|
35
30
|
result
|
36
31
|
end
|
37
32
|
|
@@ -49,6 +44,10 @@ class Role < ActiveYaml::Base
|
|
49
44
|
key
|
50
45
|
end
|
51
46
|
|
47
|
+
def to_s
|
48
|
+
key
|
49
|
+
end
|
50
|
+
|
52
51
|
def included_by
|
53
52
|
Role.includes(self)
|
54
53
|
end
|
@@ -69,20 +68,15 @@ class Role < ActiveYaml::Base
|
|
69
68
|
|
70
69
|
def included_roles
|
71
70
|
default_roles = []
|
72
|
-
|
73
71
|
default_roles << Role.default unless default?
|
74
|
-
|
75
72
|
(default_roles + includes.map { |included_key| Role.find_by_key(included_key) }).uniq.compact
|
76
73
|
end
|
77
74
|
|
78
75
|
def manageable_by?(role_or_roles)
|
79
76
|
return true if default?
|
80
|
-
|
81
77
|
roles = role_or_roles.is_a?(Array) ? role_or_roles : [role_or_roles]
|
82
|
-
|
83
78
|
roles.each do |role|
|
84
79
|
return true if role.manageable_roles.include?(key)
|
85
|
-
|
86
80
|
role.included_roles.each do |included_role|
|
87
81
|
return true if manageable_by?([included_role])
|
88
82
|
end
|
@@ -151,42 +145,38 @@ class Role < ActiveYaml::Base
|
|
151
145
|
|
152
146
|
def actions
|
153
147
|
return @actions if @actions
|
154
|
-
|
155
148
|
actions = (@ability_data["actions"] if @ability_data.is_a?(Hash)) || @ability_data
|
156
|
-
|
157
149
|
actions = [actions] unless actions.is_a?(Array)
|
158
|
-
|
159
150
|
@actions = actions.map!(&:to_sym)
|
160
151
|
end
|
161
152
|
|
162
153
|
def possible_parent_associations
|
163
154
|
ary = @parent.to_s.split("::").map(&:underscore)
|
164
|
-
|
165
155
|
possibilities = []
|
166
156
|
current = nil
|
167
|
-
|
168
157
|
until ary.empty?
|
169
158
|
current = "#{ary.pop}#{"_" unless current.nil?}#{current}"
|
170
159
|
possibilities << current
|
171
160
|
end
|
172
|
-
|
173
161
|
possibilities.map(&:to_sym)
|
174
162
|
end
|
175
163
|
|
176
164
|
def condition
|
177
165
|
return @condition if @condition
|
178
|
-
|
179
166
|
return nil unless @parent_ids
|
180
|
-
|
181
167
|
if @model == @parent
|
182
168
|
return @condition = {id: @parent_ids}
|
183
169
|
end
|
184
|
-
|
185
|
-
parent_association = possible_parent_associations.find { |association| @model.method_defined? association }
|
186
|
-
|
170
|
+
parent_association = possible_parent_associations.find { |association| @model.method_defined?(association) || @model.method_defined?("#{association}_id") }
|
187
171
|
return nil unless parent_association.present?
|
188
|
-
|
189
|
-
|
172
|
+
# If possible, use the team_id attribute because it saves us having to join all the way back to the sorce parent model
|
173
|
+
# In some scenarios this may be quicker, or if the parent model is in a different database shard, it may not even
|
174
|
+
# be possible to do the join
|
175
|
+
if @model.method_defined?("#{parent_association}_id")
|
176
|
+
@condition = {"#{parent_association}_id".to_sym => @parent_ids}
|
177
|
+
else
|
178
|
+
@condition = {parent_association => {id: @parent_ids}}
|
179
|
+
end
|
190
180
|
end
|
191
181
|
end
|
192
182
|
end
|
data/lib/roles/permit.rb
CHANGED
@@ -8,23 +8,18 @@ module Roles
|
|
8
8
|
|
9
9
|
# When changing permissions during development, you may also want to do this on each request:
|
10
10
|
# User.update_all ability_cache: nil if Rails.env.development?
|
11
|
-
|
12
11
|
output = []
|
13
12
|
added_roles = Set.new
|
14
|
-
|
15
13
|
user.send(through).map(&:roles).flatten.uniq.each do |role|
|
16
14
|
unless added_roles.include?(role)
|
17
15
|
output << "########### ROLE: #{role.key}"
|
18
|
-
|
19
16
|
output += add_abilities_for(role, user, through, parent)
|
20
|
-
|
21
17
|
added_roles << role
|
22
18
|
end
|
23
19
|
|
24
20
|
role.included_roles.each do |included_role|
|
25
21
|
unless added_roles.include?(included_role)
|
26
22
|
output << "############# INCLUDED ROLE: #{included_role.key}"
|
27
|
-
|
28
23
|
output += add_abilities_for(included_role, user, through, parent)
|
29
24
|
end
|
30
25
|
end
|
@@ -40,17 +35,14 @@ module Roles
|
|
40
35
|
|
41
36
|
def add_abilities_for(role, user, through, parent)
|
42
37
|
output = []
|
43
|
-
|
44
38
|
role.ability_generator(user, through, parent) do |ag|
|
45
39
|
if ag.valid?
|
46
40
|
output << "can #{ag.actions}, #{ag.model}, #{ag.condition}"
|
47
|
-
|
48
41
|
can(ag.actions, ag.model, ag.condition)
|
49
42
|
else
|
50
43
|
output << "# #{ag.model} does not respond to #{parent} so we're not going to add an ability for the #{through} context"
|
51
44
|
end
|
52
45
|
end
|
53
|
-
|
54
46
|
output
|
55
47
|
end
|
56
48
|
end
|
data/lib/roles/support.rb
CHANGED
@@ -13,16 +13,13 @@ module Roles
|
|
13
13
|
|
14
14
|
def assignable_roles
|
15
15
|
return Role.assignable if @allowed_roles.nil?
|
16
|
-
|
17
16
|
Role.assignable.select { |role| @allowed_roles.include?(role.key.to_sym) }
|
18
17
|
end
|
19
18
|
|
20
19
|
# Note default_role is an ActiveRecord core class method so we need to use something else here
|
21
20
|
def default_roles
|
22
21
|
default_role = Role.default
|
23
|
-
|
24
22
|
return [default_role] if @allowed_roles.nil?
|
25
|
-
|
26
23
|
@allowed_roles.include?(default_role.key.to_sym) ? [default_role] : []
|
27
24
|
end
|
28
25
|
end
|
@@ -30,11 +27,7 @@ module Roles
|
|
30
27
|
included do
|
31
28
|
validate :validate_roles
|
32
29
|
|
33
|
-
# This query will return
|
34
|
-
# For example, if you do with_roles(editor) it will return admin users if the admin role includes the editor role
|
35
|
-
scope :with_roles, ->(roles) { where("#{table_name}.role_ids ?| array[:keys]", keys: roles.map(&:key_plus_included_by_keys).flatten.uniq.map(&:to_s)) }
|
36
|
-
|
37
|
-
# This query will return roles that include the given role. See with_roles above for details
|
30
|
+
# This query will return roles that include the given role. See self.with_roles below for details
|
38
31
|
scope :with_role, ->(role) { role.nil? ? all : with_roles([role]) }
|
39
32
|
scope :viewers, -> { where("#{table_name}.role_ids = ?", [].to_json) }
|
40
33
|
scope :editors, -> { with_role(Role.find_by_key("editor")) }
|
@@ -43,6 +36,26 @@ module Roles
|
|
43
36
|
after_save :invalidate_cache
|
44
37
|
after_destroy :invalidate_cache
|
45
38
|
|
39
|
+
# This query will return records that have a role "included" in a different role they have.
|
40
|
+
# For example, if you do with_roles(editor) it will return admin users if the admin role includes the editor role
|
41
|
+
def self.with_roles(roles)
|
42
|
+
# Mysql and postgres have different syntax for searching json or jsonb columns so we need different queries depending on the database
|
43
|
+
ActiveRecord::Base.connection.adapter_name.downcase.include?("mysql") ? with_roles_mysql(roles) : with_roles_postgres(roles)
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.with_roles_mysql(roles)
|
47
|
+
queries = []
|
48
|
+
roles.map(&:key_plus_included_by_keys).flatten.uniq.map(&:to_s).each do |role|
|
49
|
+
queries << "JSON_CONTAINS(#{table_name}.role_ids, '\"#{role}\"')"
|
50
|
+
end
|
51
|
+
query = queries.join(" OR ")
|
52
|
+
where(query)
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.with_roles_postgres(roles)
|
56
|
+
where("#{table_name}.role_ids ?| array[:keys]", keys: roles.map(&:key_plus_included_by_keys).flatten.uniq.map(&:to_s))
|
57
|
+
end
|
58
|
+
|
46
59
|
def validate_roles
|
47
60
|
self.role_ids = role_ids&.select(&:present?) || []
|
48
61
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bullet_train-roles
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Prabin Poudel
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2022-02-
|
12
|
+
date: 2022-02-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: byebug
|