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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a7a7d9d893a73103e2159bfbc3ec2d0ff48fc644dec46bff98e35173d98bcff0
4
- data.tar.gz: 872e5596dead57f495e4b7f903a5607063a4efd2e46b7716414fdfd0c6688e34
3
+ metadata.gz: 4fe12ca731ca5946497ff1c82d4d31f00b383dc467588581a8af123347e961d9
4
+ data.tar.gz: f703327b44103dcd3d0cb0e5b87f5ac87322d48a9756a23ed1ca14fd19cac580
5
5
  SHA512:
6
- metadata.gz: 198336a960602043f627077526bbdb1962ea32709aa9d82cecd6b244bdc64a59034db125f429c11fe51b19037e5d08141077f7b8d9145924169f06ebb9eb4daf
7
- data.tar.gz: ace4fdcf35f66b9be6ee8e4ecdac0e0a70f6fdd4d9e79468bfbb39819a5a7c554f1be6ca4c73a7280139c0de1ad9e814c2eba90029d4482600c2ddf8fd8f937e
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
- Stamp.new(rule, stamp[:watch]&.split, stamp[:stamp].split)
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
- DEFAULT_MUTATION = "app_portal.mutate"
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 = nil)
179
- if header
180
- header = "#{header || name}:"
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
- attr_accessor :roles # Roles that this rule applies to
199
- attr_accessor :filter # Goes into the postgres policy, may be nil
200
- attr_accessor :assert # Goes into the postgres trigger, may be nil
201
- attr_accessor :mutation # Mutation function to use, may be nil. Default app_portal.mutate() except attach/detach
202
- attr_accessor :fields # Only used for insert and update, nil otherwise
203
- attr_accessor :tables # Only used for attach and detach, nil otherwise
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
- @mutation = (action.name == "select" ? nil : DEFAULT_MUTATION)
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
- puts "mutation: #{mutation || 'nil'}" if !mutation.nil? && mutation != DEFAULT_MUTATION
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 stamps.size == 1
236
- stamps.first.dump
237
- elsif stamps.size > 1
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 stamp in stamps
263
+ for stamp_expr in stamp_exprs
241
264
  print "- "
242
- indent(bol: false) { stamp.dump }
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 = nil, stamp)
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
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MikrasUtils
4
- VERSION = "0.14.1"
4
+ VERSION = "0.16.0"
5
5
  end
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.14.1
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-21 00:00:00.000000000 Z
11
+ date: 2025-03-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg_conn