mikras_utils 0.14.1 → 0.16.0
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/mikras_utils/mkacl/analyzer.rb +13 -0
- data/lib/mikras_utils/mkacl/generators/seeds.rb +37 -4
- data/lib/mikras_utils/mkacl/parser.rb +9 -27
- data/lib/mikras_utils/mkacl/spec.rb +85 -25
- data/lib/mikras_utils/version.rb +1 -1
- 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: 4fe12ca731ca5946497ff1c82d4d31f00b383dc467588581a8af123347e961d9
|
4
|
+
data.tar.gz: f703327b44103dcd3d0cb0e5b87f5ac87322d48a9756a23ed1ca14fd19cac580
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5bd1d52942bf6493256aecf50776fe0c77d86e47566fd049d858d8439d027ec2f99dfffeb0973cb14f70747c6862cdb52f73b2c610037a63b7d413478f445c30
|
7
|
+
data.tar.gz: df3cac1ea3ce8b620db3417304798e53e5ac5efe6773d8cf88f3d9e765669293aff97277f4f77ef6f314e41d4f113a22a53c322422d67bef7693302ac64fd394
|
@@ -86,6 +86,19 @@ module MkAcl
|
|
86
86
|
# Resolve domains
|
87
87
|
spec.tables.select(&:acl).each { |t| resolve_domain(t) }
|
88
88
|
|
89
|
+
# Function defaults
|
90
|
+
rules = spec.tables.map { |table| table.actions.values.map { |action| action.rules } }.flatten
|
91
|
+
rules.each { |rule|
|
92
|
+
if rule.mutation && !%w(attach detach).include?(rule.action)
|
93
|
+
if !rule.function
|
94
|
+
rule.function = DEFAULT_FUNCTION
|
95
|
+
end
|
96
|
+
else # rule.mutation.nil?
|
97
|
+
# do nothing
|
98
|
+
end
|
99
|
+
}
|
100
|
+
|
101
|
+
|
89
102
|
spec
|
90
103
|
end
|
91
104
|
|
@@ -54,6 +54,7 @@ module MkAcl
|
|
54
54
|
|
55
55
|
table.actions.values.each { |action|
|
56
56
|
puts %(
|
57
|
+
-- #{action.name.upcase}
|
57
58
|
insert into acl_portal.acl_actions (acl_table_id, kind)
|
58
59
|
values (:table_id, '#{action.name.upcase}')
|
59
60
|
returning id as "action_id"
|
@@ -62,11 +63,11 @@ module MkAcl
|
|
62
63
|
puts
|
63
64
|
|
64
65
|
action.rules.each { |rule|
|
65
|
-
fields = %w(roles filter assert mutation fields tables ordinal)
|
66
|
+
fields = %w(roles filter assert mutation function fields tables ordinal)
|
66
67
|
values = fields.map { |field| conn.quote_value(rule.send(field.to_sym), elem_type: :text) }
|
67
68
|
puts %(
|
68
69
|
insert into acl_portal.acl_rules (
|
69
|
-
acl_action_id, roles, filter, assert, function_name, fields, tables, ordinal)
|
70
|
+
acl_action_id, roles, filter, assert, mutation_name, function_name, fields, tables, ordinal)
|
70
71
|
values (:action_id, #{values.join(', ')})
|
71
72
|
returning id as "rule_id"
|
72
73
|
\\gset
|
@@ -75,11 +76,12 @@ module MkAcl
|
|
75
76
|
|
76
77
|
rule.stamps.each { |stamp|
|
77
78
|
puts %(
|
78
|
-
insert into acl_portal.acl_stamps (acl_rule_id, watch, stamp)
|
79
|
+
insert into acl_portal.acl_stamps (acl_rule_id, watch, stamp, value)
|
79
80
|
values (
|
80
81
|
:rule_id,
|
81
82
|
#{conn.quote_value(stamp.watch)},
|
82
|
-
#{conn.quote_value(stamp.stamp)}
|
83
|
+
#{conn.quote_value(stamp.stamp)},
|
84
|
+
#{conn.quote_value(stamp.value)}
|
83
85
|
);
|
84
86
|
).align
|
85
87
|
}
|
@@ -87,7 +89,11 @@ module MkAcl
|
|
87
89
|
}
|
88
90
|
end
|
89
91
|
|
92
|
+
# Patch-up acl_tables
|
90
93
|
puts %(
|
94
|
+
--
|
95
|
+
-- ASSIGN TABLE PARENT ID
|
96
|
+
--
|
91
97
|
update acl_portal.acl_tables sub
|
92
98
|
set parent_id = (
|
93
99
|
select id
|
@@ -97,6 +103,33 @@ module MkAcl
|
|
97
103
|
);
|
98
104
|
).align
|
99
105
|
puts
|
106
|
+
|
107
|
+
# Patch-up acl_stamps
|
108
|
+
puts %(
|
109
|
+
--
|
110
|
+
-- ASSIGN STAMP TYPE AND VALUE
|
111
|
+
--
|
112
|
+
update acl_portal.acl_stamps s
|
113
|
+
set type = c.column_type,
|
114
|
+
value = coalesce(
|
115
|
+
s.value,
|
116
|
+
case c.column_type
|
117
|
+
when 'int' then 'public.current_role_id()'
|
118
|
+
when 'time' then 'now()'
|
119
|
+
end
|
120
|
+
)
|
121
|
+
from
|
122
|
+
acl_portal.acl_rules r
|
123
|
+
join acl_portal.acl_actions a on a.id = r.acl_action_id
|
124
|
+
join acl_portal.acl_tables t on t.id = a.acl_table_id
|
125
|
+
join meta.columns c
|
126
|
+
on c.schema_name = t.schema_name
|
127
|
+
and c.table_name = t.table_name
|
128
|
+
where
|
129
|
+
r.id = s.acl_rule_id
|
130
|
+
and c.column_name = s.stamp
|
131
|
+
;
|
132
|
+
).align
|
100
133
|
end
|
101
134
|
end
|
102
135
|
end
|
@@ -88,6 +88,7 @@ module MkAcl
|
|
88
88
|
when :filter; rule.filter = norm_value(value)
|
89
89
|
when :assert; rule.assert = norm_value(value)
|
90
90
|
when :mutation; rule.mutation = value.nil? ? nil : norm_value(value)
|
91
|
+
when :function; rule.function = value.nil? ? nil : norm_value(value)
|
91
92
|
when :fields; rule.fields = value.nil? ? nil : norm_array(value)
|
92
93
|
when :tables; rule.tables = norm_array(value)
|
93
94
|
else
|
@@ -103,12 +104,9 @@ module MkAcl
|
|
103
104
|
def parse_stamps(rule, stamps)
|
104
105
|
constrain rule, Rule
|
105
106
|
constrain stamps, String, Hash, Array
|
106
|
-
# constrain stamps, String, Hash[watch: NilClass | String | [String], stamp: String | [String]]
|
107
107
|
|
108
108
|
# Normalize stamps
|
109
|
-
stamps = Array(stamps)
|
110
|
-
|
111
|
-
stamps.map! { |stamp|
|
109
|
+
stamps = Array(stamps).map! { |stamp|
|
112
110
|
case stamp
|
113
111
|
when Hash; stamp
|
114
112
|
when String; { stamp: stamp }
|
@@ -120,32 +118,16 @@ module MkAcl
|
|
120
118
|
# Check fields and create stamp
|
121
119
|
stamps.each { |stamp|
|
122
120
|
# Check fields
|
123
|
-
diff = stamp.keys - [:watch, :stamp]
|
121
|
+
diff = stamp.keys - [:watch, :stamp, :value]
|
124
122
|
diff.empty? or raise "Illegal field '#{diff.first}' in #{rule.name} rule in table #{rule.table.name}"
|
125
|
-
|
123
|
+
(stamp[:watch]&.split || [nil]).map { |watch_field|
|
124
|
+
stamp[:stamp].split.map { |stamp_field|
|
125
|
+
Stamp.new(rule, watch_field, stamp_field, stamp[:value])
|
126
|
+
}
|
127
|
+
}
|
128
|
+
StampExpr.new(rule, stamp[:watch]&.split, stamp[:stamp].split, stamp[:value])
|
126
129
|
}
|
127
130
|
end
|
128
131
|
end
|
129
132
|
end
|
130
133
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
@@ -1,6 +1,6 @@
|
|
1
1
|
|
2
2
|
module MkAcl
|
3
|
-
|
3
|
+
DEFAULT_FUNCTION = "app_portal.mutate"
|
4
4
|
ACTIONS = %w(insert select update delete attach detach)
|
5
5
|
|
6
6
|
class Spec
|
@@ -175,13 +175,9 @@ module MkAcl
|
|
175
175
|
end
|
176
176
|
end
|
177
177
|
|
178
|
-
def dump(header =
|
179
|
-
|
180
|
-
|
181
|
-
indent { dump_body }
|
182
|
-
else
|
183
|
-
dump_body
|
184
|
-
end
|
178
|
+
def dump(header = name)
|
179
|
+
puts "#{header || name}:"
|
180
|
+
indent { dump_body }
|
185
181
|
end
|
186
182
|
|
187
183
|
private
|
@@ -195,13 +191,31 @@ module MkAcl
|
|
195
191
|
|
196
192
|
attr_reader :action
|
197
193
|
forward_to :action, :table, :name
|
198
|
-
|
199
|
-
|
200
|
-
attr_accessor :
|
201
|
-
|
202
|
-
|
203
|
-
attr_accessor :
|
194
|
+
|
195
|
+
# Roles that this rule applies to
|
196
|
+
attr_accessor :roles
|
197
|
+
|
198
|
+
# Goes into the postgres policy, may be nil
|
199
|
+
attr_accessor :filter
|
200
|
+
|
201
|
+
# Goes into the postgres trigger, may be nil
|
202
|
+
attr_accessor :assert
|
203
|
+
|
204
|
+
# Mutation function, may be nil. Default create/update/delete_RECORD except
|
205
|
+
# select/attach/detach
|
206
|
+
attr_accessor :mutation
|
207
|
+
|
208
|
+
# Implementation function, may be nil. Default 'app_portal.mutate()' except attach/detach
|
209
|
+
attr_accessor :function
|
210
|
+
|
211
|
+
# Only used for insert and update, nil otherwise
|
212
|
+
attr_accessor :fields
|
213
|
+
|
214
|
+
# Only used for attach and detach, nil otherwise
|
215
|
+
attr_accessor :tables
|
216
|
+
|
204
217
|
attr_accessor :stamps
|
218
|
+
attr_accessor :stamp_exprs
|
205
219
|
attr_reader :ordinal
|
206
220
|
|
207
221
|
# admin, internal, etc.
|
@@ -216,63 +230,109 @@ module MkAcl
|
|
216
230
|
@roles = []
|
217
231
|
@filter = nil
|
218
232
|
@assert = nil
|
219
|
-
|
233
|
+
# @mutation = (action.name == "select" ? nil : "#{action}_#{table.record_name}")
|
234
|
+
@mutation = default_mutation
|
235
|
+
@function = nil #(action.name == "select" ? nil : DEFAULT_MUTATION)
|
220
236
|
@fields = %w(insert update).include?(action.name) ? [] : nil
|
221
237
|
@tables = %w(attach detach).include?(action.name) ? [] : nil
|
222
238
|
@stamps = []
|
239
|
+
@stamp_exprs = []
|
223
240
|
|
224
241
|
action.send :attach_rule, self
|
225
242
|
end
|
226
243
|
|
227
244
|
def dump
|
228
245
|
puts "roles: #{roles.join(' ')}"
|
246
|
+
puts "tables: #{tables.join(' ')}" if tables && !tables.empty?
|
229
247
|
puts "filter: #{filter}" if filter
|
230
248
|
puts "assert: #{assert}" if assert
|
231
|
-
|
249
|
+
if %w(insert update delete).include?(action.name)
|
250
|
+
puts "mutation: #{mutation || 'nil'}" \
|
251
|
+
if name != 'select' && (mutation.nil? || mutation != default_mutation)
|
252
|
+
puts "function: #{function || 'nil'}" if name != 'select' && function != DEFAULT_FUNCTION
|
253
|
+
else
|
254
|
+
puts "function: #{function}" if function
|
255
|
+
end
|
232
256
|
puts "fields: #{fields.join(' ')}" if fields && !fields.empty?
|
233
|
-
puts "tables: #{tables.join(' ')}" if tables && !tables.empty?
|
234
257
|
|
235
|
-
if
|
236
|
-
|
237
|
-
elsif
|
258
|
+
if stamp_exprs.size == 1
|
259
|
+
stamp_exprs.first.dump
|
260
|
+
elsif stamp_exprs.size > 1
|
238
261
|
puts "stamps:"
|
239
262
|
indent {
|
240
|
-
for
|
263
|
+
for stamp_expr in stamp_exprs
|
241
264
|
print "- "
|
242
|
-
indent(bol: false) {
|
265
|
+
indent(bol: false) { stamp_expr.dump }
|
243
266
|
end
|
244
267
|
}
|
245
268
|
end
|
246
269
|
|
247
270
|
puts "ordinal: #{ordinal}"
|
248
271
|
end
|
272
|
+
|
249
273
|
private
|
274
|
+
def default_mutation
|
275
|
+
%w(insert update delete).include?(action.name) ? "#{action.name}_#{table.record_name}" : nil
|
276
|
+
end
|
277
|
+
|
250
278
|
def attach_stamp(stamp)
|
251
279
|
@stamps << stamp
|
252
280
|
end
|
281
|
+
|
282
|
+
def attach_stamp_expr(stamp_expr)
|
283
|
+
@stamp_exprs << stamp_expr
|
284
|
+
end
|
253
285
|
end
|
254
286
|
|
255
287
|
class Stamp
|
256
288
|
attr_reader :rule
|
289
|
+
|
257
290
|
forward_to :rule, :table, :name
|
258
291
|
|
259
292
|
attr_accessor :watch
|
260
293
|
attr_accessor :stamp
|
294
|
+
attr_accessor :value
|
261
295
|
|
262
|
-
def initialize(rule, watch
|
296
|
+
def initialize(rule, watch, stamp, value)
|
263
297
|
constrain rule, Rule
|
298
|
+
constrain watch, String, nil
|
299
|
+
constrain stamp, String
|
264
300
|
@rule = rule
|
265
|
-
@watch, @stamp = watch, stamp
|
301
|
+
@watch, @stamp, @value = watch, stamp, value
|
266
302
|
rule.send :attach_stamp, self
|
267
303
|
end
|
268
304
|
|
305
|
+
def to_s() = watch ? "#{watch}->#{stamp}" : stamp
|
306
|
+
|
307
|
+
def dump
|
308
|
+
puts "watch: #{watch}" if watch
|
309
|
+
puts "stamp: #{stamp}" if stamp
|
310
|
+
puts "value: #{value}" if value
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
class StampExpr # For debug. Express the structure of stamp syntax
|
315
|
+
attr_reader :rule
|
316
|
+
forward_to :rule, :table, :name
|
317
|
+
|
318
|
+
attr_accessor :watch # [String]
|
319
|
+
attr_accessor :stamp # [String]
|
320
|
+
attr_accessor :value
|
321
|
+
|
322
|
+
def initialize(rule, watch, stamp, value)
|
323
|
+
constrain rule, Rule
|
324
|
+
@rule = rule
|
325
|
+
@watch, @stamp, @value = watch, stamp, value
|
326
|
+
rule.send :attach_stamp_expr, self
|
327
|
+
end
|
328
|
+
|
269
329
|
def to_s() = watch
|
270
330
|
|
271
331
|
def dump
|
272
332
|
puts "watch: #{watch.join(" ")}" if watch
|
273
333
|
puts "stamp: #{stamp.join(" ")}" if stamp
|
334
|
+
puts "value: #{value}" if value
|
274
335
|
end
|
275
336
|
end
|
276
|
-
|
277
337
|
end
|
278
338
|
|
data/lib/mikras_utils/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mikras_utils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.16.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Claus Rasmussen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-03-
|
11
|
+
date: 2025-03-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pg_conn
|