bullet_train-roles 0.1.4 → 0.1.7
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/.circleci/config.yml +126 -49
- data/Gemfile.lock +4 -1
- data/README.md +3 -2
- data/lib/bullet_train/roles/version.rb +1 -1
- data/lib/models/role.rb +30 -28
- data/lib/roles/permit.rb +5 -13
- data/lib/roles/support.rb +22 -9
- data/lib/roles/user.rb +2 -3
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 95cb748cf7f1d4cb6b3ba9a28c6d7b3d7e8bab30cd1d76eb925e52ebc48741a7
|
4
|
+
data.tar.gz: 8d1a5d66b9febbae5985105932f9d4f751f0e806386bb6ec9b98ff73c240e3fc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9eed70dbba4e17e025885df2d7a1ce920afadfa1da90ad20194916c13d4cfeedd5f979efaf71c1609a4f9474b8b5783c31ef7477cfcd078227726a81252d8e09
|
7
|
+
data.tar.gz: 43c8ed5b1db7d28f49aa171cca36eb675f95eeb37542f7dcb264691c35f55aaf2c18109b35604f8f5add5ae2142f2eba9834bddfb5e38f51aa532a79fa0d20f3
|
data/.circleci/config.yml
CHANGED
@@ -1,86 +1,124 @@
|
|
1
1
|
version: 2.1
|
2
2
|
orbs:
|
3
3
|
ruby: circleci/ruby@0.1.2
|
4
|
-
|
4
|
+
browser-tools: circleci/browser-tools@1.1
|
5
5
|
aliases:
|
6
6
|
- &restore_bundler_cache
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
name: Restore Bundler cache
|
8
|
+
keys:
|
9
|
+
- gem-cache-v1-{{ .Branch }}-{{ checksum "Gemfile.lock" }}
|
10
|
+
- gem-cache-v1-{{ .Branch }}-
|
11
|
+
- gem-cache-v1-
|
12
12
|
- &restore_yarn_cache
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
name: Restore Yarn cache
|
14
|
+
keys:
|
15
|
+
- yarn-packages-v1-{{ .Branch }}-{{ checksum "yarn.lock" }}
|
16
|
+
- yarn-packages-v1-{{ .Branch }}-
|
17
|
+
- yarn-packages-
|
18
18
|
- &save_bundle_cache
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
name: Save Bundle cache
|
20
|
+
key: gem-cache-v1-{{ .Branch }}-{{ checksum "Gemfile.lock" }}
|
21
|
+
paths:
|
22
|
+
- vendor/bundle
|
23
23
|
- &save_yarn_cache
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
name: Save Yarn cache
|
25
|
+
key: yarn-packages-v1-{{ .Branch }}-{{ checksum "yarn.lock" }}
|
26
|
+
paths:
|
27
|
+
- node_modules
|
28
|
+
- &ruby_node_browsers_docker_image
|
29
|
+
- image: cimg/ruby:3.1.2-browsers
|
30
|
+
environment:
|
31
|
+
PGHOST: localhost
|
32
|
+
PGUSER: untitled_application
|
33
|
+
RAILS_ENV: test
|
34
|
+
- &postgres_docker_image
|
35
|
+
- image: circleci/postgres
|
36
|
+
environment:
|
37
|
+
POSTGRES_HOST_AUTH_METHOD: trust
|
38
|
+
POSTGRES_DB: untitled_application_test
|
39
|
+
POSTGRES_USER: untitled_application
|
40
|
+
- &wait_for_docker
|
41
|
+
# We run this because the DB might not be available for a while due to a race condition.
|
42
|
+
run: dockerize -wait tcp://localhost:5432 -timeout 1m
|
29
43
|
jobs:
|
30
|
-
'
|
44
|
+
'Local Minitest':
|
45
|
+
docker:
|
46
|
+
- <<: *ruby_node_browsers_docker_image
|
47
|
+
- <<: *postgres_docker_image
|
48
|
+
- image: circleci/redis
|
49
|
+
executor: ruby/default
|
50
|
+
steps:
|
51
|
+
- browser-tools/install-browser-tools
|
52
|
+
- checkout
|
53
|
+
|
54
|
+
# Install dependencies
|
55
|
+
- run: "bundle install"
|
56
|
+
- run: "bundle clean --force"
|
57
|
+
- run: "yarn install"
|
58
|
+
- *wait_for_docker
|
59
|
+
- run:
|
60
|
+
name: Run unit tests
|
61
|
+
command: bundle exec rails test
|
62
|
+
|
63
|
+
'Local Standard Ruby':
|
31
64
|
docker:
|
32
|
-
|
33
|
-
- image: circleci/ruby:3.0.2-node-browsers
|
65
|
+
- <<: *ruby_node_browsers_docker_image
|
34
66
|
steps:
|
35
67
|
- checkout
|
36
68
|
|
37
|
-
#
|
38
|
-
|
39
|
-
- restore_cache: *
|
69
|
+
# TODO Figure out how to make these work for `tmp/starter`
|
70
|
+
# # Restore dependency caches
|
71
|
+
# - restore_cache: *restore_bundler_cache
|
72
|
+
# - restore_cache: *restore_yarn_cache
|
40
73
|
|
41
74
|
# Install dependencies
|
42
75
|
- ruby/bundle-install
|
43
76
|
- run: bundle clean --force
|
44
77
|
- run: yarn install
|
45
78
|
|
46
|
-
# Save dependency caches
|
47
|
-
# We only do this as part of this job, because it's time consuming and we don't want it to slow down test runners.
|
48
|
-
- save_cache: *save_bundle_cache
|
49
|
-
- save_cache: *save_yarn_cache
|
79
|
+
# # Save dependency caches
|
80
|
+
# # We only do this as part of this job, because it's time consuming and we don't want it to slow down test runners.
|
81
|
+
# - save_cache: *save_bundle_cache
|
82
|
+
# - save_cache: *save_yarn_cache
|
50
83
|
|
51
84
|
- run:
|
52
85
|
name: Check Standard Ruby
|
53
86
|
command: bundle exec standardrb
|
54
87
|
|
55
|
-
'Minitest':
|
88
|
+
'Starter Repo Minitest':
|
56
89
|
docker:
|
57
|
-
-
|
58
|
-
|
59
|
-
|
60
|
-
PGUSER: bullet_train
|
61
|
-
RAILS_ENV: test
|
62
|
-
- image: circleci/postgres
|
63
|
-
environment:
|
64
|
-
POSTGRES_HOST_AUTH_METHOD: trust
|
65
|
-
POSTGRES_DB: bullet_train_test
|
66
|
-
POSTGRES_USER: bullet_train
|
90
|
+
- <<: *ruby_node_browsers_docker_image
|
91
|
+
- <<: *postgres_docker_image
|
92
|
+
- image: circleci/redis
|
67
93
|
executor: ruby/default
|
68
94
|
parallelism: 16
|
69
95
|
steps:
|
96
|
+
- browser-tools/install-browser-tools
|
70
97
|
- checkout
|
71
|
-
-
|
72
|
-
|
98
|
+
- run: "git clone https://github.com/bullet-train-co/bullet_train.git tmp/starter"
|
99
|
+
|
100
|
+
- run:
|
101
|
+
name: Link starter repository to the Ruby gem being tested.
|
102
|
+
command: "grep -v 'gem \"bullet_train-roles\"' tmp/starter/Gemfile > tmp/starter/Gemfile.tmp && mv tmp/starter/Gemfile.tmp tmp/starter/Gemfile && echo 'gem \"bullet_train-roles\", path: \"../..\"' >> tmp/starter/Gemfile"
|
103
|
+
|
104
|
+
# TODO Figure out how to make these work for `tmp/starter`
|
105
|
+
# - restore_cache: *restore_bundler_cache
|
106
|
+
# - restore_cache: *restore_yarn_cache
|
73
107
|
|
74
108
|
# Install dependencies
|
75
|
-
-
|
76
|
-
- run: bundle clean --force
|
109
|
+
- run: "cd tmp/starter && bundle install"
|
110
|
+
- run: "cd tmp/starter && bundle clean --force"
|
111
|
+
- run: "cd tmp/starter && bundle exec rake bt:link"
|
112
|
+
- run: "cd tmp/starter && yarn install"
|
113
|
+
- run: "cd tmp/starter && yarn build"
|
114
|
+
- run: "cd tmp/starter && yarn build:css"
|
77
115
|
|
78
|
-
|
79
|
-
- run: dockerize -wait tcp://localhost:5432 -timeout 1m
|
116
|
+
- *wait_for_docker
|
80
117
|
|
81
118
|
- run:
|
82
119
|
name: Run tests with Knapsack Pro
|
83
120
|
command: |
|
121
|
+
cd tmp/starter
|
84
122
|
export RAILS_ENV=test
|
85
123
|
bundle exec rails "knapsack_pro:queue:minitest[--verbose]"
|
86
124
|
environment:
|
@@ -102,9 +140,48 @@ jobs:
|
|
102
140
|
# - store_test_results:
|
103
141
|
# path: test/reports
|
104
142
|
|
143
|
+
'Starter Repo Minitest for Super Scaffolding':
|
144
|
+
docker:
|
145
|
+
- <<: *ruby_node_browsers_docker_image
|
146
|
+
- <<: *postgres_docker_image
|
147
|
+
- image: circleci/redis
|
148
|
+
executor: ruby/default
|
149
|
+
steps:
|
150
|
+
- browser-tools/install-browser-tools
|
151
|
+
- checkout
|
152
|
+
- run: "git clone https://github.com/bullet-train-co/bullet_train.git tmp/starter"
|
153
|
+
|
154
|
+
- run:
|
155
|
+
name: Link starter repository to the Ruby gem being tested.
|
156
|
+
command: "grep -v 'gem \"bullet_train-roles\"' tmp/starter/Gemfile > tmp/starter/Gemfile.tmp && mv tmp/starter/Gemfile.tmp tmp/starter/Gemfile && echo 'gem \"bullet_train-roles\", path: \"../..\"' >> tmp/starter/Gemfile"
|
157
|
+
|
158
|
+
# TODO Figure out how to make these work for `tmp/starter`
|
159
|
+
# # Restore dependency caches
|
160
|
+
# - restore_cache: *restore_bundler_cache
|
161
|
+
# - restore_cache: *restore_yarn_cache
|
162
|
+
|
163
|
+
# Install dependencies
|
164
|
+
- run: "cd tmp/starter && bundle install"
|
165
|
+
- run: "cd tmp/starter && bundle clean --force"
|
166
|
+
- run: "cd tmp/starter && bundle exec rake bt:link"
|
167
|
+
- run: "cd tmp/starter && yarn install"
|
168
|
+
- run: "cd tmp/starter && yarn build"
|
169
|
+
- run: "cd tmp/starter && yarn build:css"
|
170
|
+
|
171
|
+
- *wait_for_docker
|
172
|
+
|
173
|
+
- run:
|
174
|
+
name: 'Setup Super Scaffolding System Test'
|
175
|
+
command: "cd tmp/starter && bundle exec test/bin/setup-super-scaffolding-system-test"
|
176
|
+
- run:
|
177
|
+
name: 'Run Super Scaffolding Test'
|
178
|
+
command: "cd tmp/starter && bundle exec rails test test/system/super_scaffolding_test.rb"
|
179
|
+
|
105
180
|
workflows:
|
106
181
|
version: 2
|
107
182
|
build:
|
108
183
|
jobs:
|
109
|
-
- '
|
110
|
-
- '
|
184
|
+
- 'Local Minitest'
|
185
|
+
- 'Local Standard Ruby'
|
186
|
+
- 'Starter Repo Minitest'
|
187
|
+
- 'Starter Repo Minitest for Super Scaffolding'
|
data/Gemfile.lock
CHANGED
@@ -9,7 +9,7 @@ GIT
|
|
9
9
|
PATH
|
10
10
|
remote: .
|
11
11
|
specs:
|
12
|
-
bullet_train-roles (0.1.
|
12
|
+
bullet_train-roles (0.1.7)
|
13
13
|
active_hash
|
14
14
|
activesupport
|
15
15
|
cancancan
|
@@ -106,6 +106,8 @@ GEM
|
|
106
106
|
nio4r (2.5.8)
|
107
107
|
nokogiri (1.12.5-arm64-darwin)
|
108
108
|
racc (~> 1.4)
|
109
|
+
nokogiri (1.12.5-x86_64-darwin)
|
110
|
+
racc (~> 1.4)
|
109
111
|
parallel (1.21.0)
|
110
112
|
parser (3.0.3.2)
|
111
113
|
ast (~> 2.4.1)
|
@@ -174,6 +176,7 @@ GEM
|
|
174
176
|
PLATFORMS
|
175
177
|
arm64-darwin-20
|
176
178
|
arm64-darwin-21
|
179
|
+
x86_64-darwin-21
|
177
180
|
|
178
181
|
DEPENDENCIES
|
179
182
|
active_hash!
|
data/README.md
CHANGED
@@ -68,7 +68,7 @@ editor:
|
|
68
68
|
manageable_roles:
|
69
69
|
- editor
|
70
70
|
models:
|
71
|
-
Project:
|
71
|
+
Project: crud
|
72
72
|
|
73
73
|
billing:
|
74
74
|
manageable_roles:
|
@@ -98,7 +98,8 @@ The following things are true given the example configuration above:
|
|
98
98
|
- By default, users on a team are read-only participants.
|
99
99
|
- Users with the `editor` role:
|
100
100
|
- can give other users the `editor` role.
|
101
|
-
- can
|
101
|
+
- can perform crud actions on project (create, read, update and destroy).
|
102
|
+
- cannot perform any custom controller actions the projects controller responds to
|
102
103
|
- Users with the `billing` role:
|
103
104
|
- can give other users the `billing` role.
|
104
105
|
- can create and update billing subscriptions.
|
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
|
@@ -95,9 +89,9 @@ class Role < ActiveYaml::Base
|
|
95
89
|
!default?
|
96
90
|
end
|
97
91
|
|
98
|
-
def ability_generator(user, through, parent)
|
92
|
+
def ability_generator(user, through, parent, intermediary)
|
99
93
|
models.each do |model_name, _|
|
100
|
-
ag = AbilityGenerator.new(self, model_name, user, through, parent)
|
94
|
+
ag = AbilityGenerator.new(self, model_name, user, through, parent, intermediary)
|
101
95
|
yield(ag)
|
102
96
|
end
|
103
97
|
end
|
@@ -131,7 +125,7 @@ class Role < ActiveYaml::Base
|
|
131
125
|
class AbilityGenerator
|
132
126
|
attr_reader :model
|
133
127
|
|
134
|
-
def initialize(role, model_name, user, through, parent_name)
|
128
|
+
def initialize(role, model_name, user, through, parent_name, intermediary = nil)
|
135
129
|
begin
|
136
130
|
@model = model_name.constantize
|
137
131
|
rescue NameError
|
@@ -143,6 +137,8 @@ class Role < ActiveYaml::Base
|
|
143
137
|
@through = through
|
144
138
|
@parent = user.send(through).reflect_on_association(parent_name)&.klass
|
145
139
|
@parent_ids = user.parent_ids_for(@role, @through, parent_name) if @parent
|
140
|
+
@intermediary = intermediary
|
141
|
+
@intermediary_class = @model.reflect_on_association(intermediary)&.class_name&.constantize if @intermediary.present?
|
146
142
|
end
|
147
143
|
|
148
144
|
def valid?
|
@@ -151,42 +147,48 @@ class Role < ActiveYaml::Base
|
|
151
147
|
|
152
148
|
def actions
|
153
149
|
return @actions if @actions
|
150
|
+
@actions = (@ability_data["actions"] if @ability_data.is_a?(Hash)) || @ability_data
|
151
|
+
# crud is a special value that we substitute for the 4 crud actions
|
152
|
+
# This is instead of :manage which covers all 4 actions _and_ any extra actions the controller may respond to
|
153
|
+
@actions = crud_actions if @actions.to_s.downcase == "crud"
|
154
|
+
@actions = [actions] unless actions.is_a?(Array)
|
155
|
+
@actions.map!(&:to_sym)
|
156
|
+
end
|
154
157
|
|
155
|
-
|
156
|
-
|
157
|
-
actions = [actions] unless actions.is_a?(Array)
|
158
|
-
|
159
|
-
@actions = actions.map!(&:to_sym)
|
158
|
+
def crud_actions
|
159
|
+
[:create, :read, :update, :destroy]
|
160
160
|
end
|
161
161
|
|
162
162
|
def possible_parent_associations
|
163
163
|
ary = @parent.to_s.split("::").map(&:underscore)
|
164
|
-
|
165
164
|
possibilities = []
|
166
165
|
current = nil
|
167
|
-
|
168
166
|
until ary.empty?
|
169
167
|
current = "#{ary.pop}#{"_" unless current.nil?}#{current}"
|
170
168
|
possibilities << current
|
171
169
|
end
|
172
|
-
|
173
170
|
possibilities.map(&:to_sym)
|
174
171
|
end
|
175
172
|
|
176
173
|
def condition
|
177
174
|
return @condition if @condition
|
178
|
-
|
179
175
|
return nil unless @parent_ids
|
180
|
-
|
181
176
|
if @model == @parent
|
182
177
|
return @condition = {id: @parent_ids}
|
183
178
|
end
|
184
|
-
|
185
|
-
parent_association = possible_parent_associations.find { |association| @model.method_defined? association }
|
186
|
-
|
179
|
+
parent_association = possible_parent_associations.find { |association| @model.method_defined?(association) || @model.method_defined?("#{association}_id") }
|
187
180
|
return nil unless parent_association.present?
|
188
|
-
|
189
|
-
|
181
|
+
# If possible, use the team_id attribute because it saves us having to join all the way back to the source parent model
|
182
|
+
# In some scenarios this may be quicker, or if the parent model is in a different database shard, it may not even
|
183
|
+
# be possible to do the join
|
184
|
+
parent_with_id = "#{parent_association}_id"
|
185
|
+
@condition = if @model.column_names.include?(parent_with_id)
|
186
|
+
{parent_with_id.to_sym => @parent_ids}
|
187
|
+
elsif @intermediary.present? && @model.method_defined?(@intermediary) && @intermediary_class&.column_names&.include?(parent_with_id)
|
188
|
+
{@intermediary.to_sym => {parent_with_id.to_sym => @parent_ids}}
|
189
|
+
else
|
190
|
+
{parent_association => {id: @parent_ids}}
|
191
|
+
end
|
190
192
|
end
|
191
193
|
end
|
192
194
|
end
|
data/lib/roles/permit.rb
CHANGED
@@ -2,30 +2,25 @@
|
|
2
2
|
|
3
3
|
module Roles
|
4
4
|
module Permit
|
5
|
-
def permit(user, through:, parent:, debug: false)
|
5
|
+
def permit(user, through:, parent:, debug: false, intermediary: nil)
|
6
6
|
# Without this, you need to restart the server each time you make changes to the config/models/role.yml file
|
7
7
|
Role.reload(true) if Rails.env.development?
|
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
|
-
output += add_abilities_for(role, user, through, parent)
|
20
|
-
|
16
|
+
output += add_abilities_for(role, user, through, parent, intermediary)
|
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
|
-
output += add_abilities_for(included_role, user, through, parent)
|
23
|
+
output += add_abilities_for(included_role, user, through, parent, intermediary)
|
29
24
|
end
|
30
25
|
end
|
31
26
|
end
|
@@ -38,19 +33,16 @@ module Roles
|
|
38
33
|
end
|
39
34
|
end
|
40
35
|
|
41
|
-
def add_abilities_for(role, user, through, parent)
|
36
|
+
def add_abilities_for(role, user, through, parent, intermediary)
|
42
37
|
output = []
|
43
|
-
|
44
|
-
role.ability_generator(user, through, parent) do |ag|
|
38
|
+
role.ability_generator(user, through, parent, intermediary) 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
|
|
@@ -58,7 +71,7 @@ module Roles
|
|
58
71
|
end
|
59
72
|
|
60
73
|
def roles=(roles)
|
61
|
-
|
74
|
+
update(role_ids: roles.map(&:key))
|
62
75
|
end
|
63
76
|
|
64
77
|
def assignable_roles
|
data/lib/roles/user.rb
CHANGED
@@ -9,17 +9,16 @@ module Roles
|
|
9
9
|
included do
|
10
10
|
def parent_ids_for(role, through, parent)
|
11
11
|
parent_id_column = "#{parent}_id"
|
12
|
-
key = "#{role.key}_#{through}_#{parent_id_column}s"
|
12
|
+
# key = "#{role.key}_#{through}_#{parent_id_column}s"
|
13
13
|
# TODO Maybe we should make ability caching a default feature of the gem?
|
14
14
|
# If we do that, we would just make it check whether `ability_cache` exists.
|
15
15
|
# return ability_cache[key] if ability_cache && ability_cache[key]
|
16
16
|
role = nil if role.default?
|
17
|
-
|
17
|
+
send(through).with_role(role).distinct.pluck(parent_id_column)
|
18
18
|
# TODO Maybe we should make ability caching a default feature of the gem?
|
19
19
|
# current_cache = ability_cache || {}
|
20
20
|
# current_cache[key] = value
|
21
21
|
# update_column :ability_cache, current_cache
|
22
|
-
value
|
23
22
|
end
|
24
23
|
end
|
25
24
|
end
|
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.7
|
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-
|
12
|
+
date: 2022-04-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: byebug
|
@@ -215,7 +215,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
215
215
|
- !ruby/object:Gem::Version
|
216
216
|
version: '0'
|
217
217
|
requirements: []
|
218
|
-
rubygems_version: 3.
|
218
|
+
rubygems_version: 3.3.0
|
219
219
|
signing_key:
|
220
220
|
specification_version: 4
|
221
221
|
summary: Yaml-backed ApplicationHash for CanCan Roles
|