bullet_train-roles 0.1.4 → 0.1.5
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 +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
|