bullet_train-roles 0.1.6 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +126 -49
- data/Gemfile.lock +1 -1
- data/README.md +3 -2
- data/lib/bullet_train/roles/version.rb +1 -1
- data/lib/models/role.rb +22 -12
- data/lib/roles/permit.rb +5 -5
- data/lib/roles/support.rb +1 -1
- data/lib/roles/user.rb +2 -3
- 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: 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
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
@@ -89,9 +89,9 @@ class Role < ActiveYaml::Base
|
|
89
89
|
!default?
|
90
90
|
end
|
91
91
|
|
92
|
-
def ability_generator(user, through, parent)
|
92
|
+
def ability_generator(user, through, parent, intermediary)
|
93
93
|
models.each do |model_name, _|
|
94
|
-
ag = AbilityGenerator.new(self, model_name, user, through, parent)
|
94
|
+
ag = AbilityGenerator.new(self, model_name, user, through, parent, intermediary)
|
95
95
|
yield(ag)
|
96
96
|
end
|
97
97
|
end
|
@@ -125,7 +125,7 @@ class Role < ActiveYaml::Base
|
|
125
125
|
class AbilityGenerator
|
126
126
|
attr_reader :model
|
127
127
|
|
128
|
-
def initialize(role, model_name, user, through, parent_name)
|
128
|
+
def initialize(role, model_name, user, through, parent_name, intermediary = nil)
|
129
129
|
begin
|
130
130
|
@model = model_name.constantize
|
131
131
|
rescue NameError
|
@@ -137,6 +137,8 @@ class Role < ActiveYaml::Base
|
|
137
137
|
@through = through
|
138
138
|
@parent = user.send(through).reflect_on_association(parent_name)&.klass
|
139
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?
|
140
142
|
end
|
141
143
|
|
142
144
|
def valid?
|
@@ -145,9 +147,16 @@ class Role < ActiveYaml::Base
|
|
145
147
|
|
146
148
|
def actions
|
147
149
|
return @actions if @actions
|
148
|
-
actions = (@ability_data["actions"] if @ability_data.is_a?(Hash)) || @ability_data
|
149
|
-
|
150
|
-
|
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
|
157
|
+
|
158
|
+
def crud_actions
|
159
|
+
[:create, :read, :update, :destroy]
|
151
160
|
end
|
152
161
|
|
153
162
|
def possible_parent_associations
|
@@ -169,15 +178,16 @@ class Role < ActiveYaml::Base
|
|
169
178
|
end
|
170
179
|
parent_association = possible_parent_associations.find { |association| @model.method_defined?(association) || @model.method_defined?("#{association}_id") }
|
171
180
|
return nil unless parent_association.present?
|
172
|
-
# If possible, use the team_id attribute because it saves us having to join all the way back to the
|
181
|
+
# If possible, use the team_id attribute because it saves us having to join all the way back to the source parent model
|
173
182
|
# In some scenarios this may be quicker, or if the parent model is in a different database shard, it may not even
|
174
183
|
# be possible to do the join
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
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}}
|
179
189
|
else
|
180
|
-
|
190
|
+
{parent_association => {id: @parent_ids}}
|
181
191
|
end
|
182
192
|
end
|
183
193
|
end
|
data/lib/roles/permit.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
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
|
|
@@ -13,14 +13,14 @@ module Roles
|
|
13
13
|
user.send(through).map(&:roles).flatten.uniq.each do |role|
|
14
14
|
unless added_roles.include?(role)
|
15
15
|
output << "########### ROLE: #{role.key}"
|
16
|
-
output += add_abilities_for(role, user, through, parent)
|
16
|
+
output += add_abilities_for(role, user, through, parent, intermediary)
|
17
17
|
added_roles << role
|
18
18
|
end
|
19
19
|
|
20
20
|
role.included_roles.each do |included_role|
|
21
21
|
unless added_roles.include?(included_role)
|
22
22
|
output << "############# INCLUDED ROLE: #{included_role.key}"
|
23
|
-
output += add_abilities_for(included_role, user, through, parent)
|
23
|
+
output += add_abilities_for(included_role, user, through, parent, intermediary)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -33,9 +33,9 @@ module Roles
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
def add_abilities_for(role, user, through, parent)
|
36
|
+
def add_abilities_for(role, user, through, parent, intermediary)
|
37
37
|
output = []
|
38
|
-
role.ability_generator(user, through, parent) do |ag|
|
38
|
+
role.ability_generator(user, through, parent, intermediary) do |ag|
|
39
39
|
if ag.valid?
|
40
40
|
output << "can #{ag.actions}, #{ag.model}, #{ag.condition}"
|
41
41
|
can(ag.actions, ag.model, ag.condition)
|
data/lib/roles/support.rb
CHANGED
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
|