mikras_utils 0.1.0 → 0.1.1
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/exe/mkacl +19 -7
- data/lib/mikras_utils/mkacl/analyzer.rb +30 -4
- data/lib/mikras_utils/mkacl/generators/id_functions.rb +98 -69
- data/lib/mikras_utils/mkacl/spec.rb +12 -2
- data/lib/mikras_utils/version.rb +1 -1
- data/tests/acl.fox +1 -1
- data/tests/acl.spec +1 -1
- data/tests/acl.sql +2 -2
- data/tests/acl_portal-tables.sql +1 -1
- data/tests/acl_portal-views.sql +1 -1
- data/tests/app_portal-tables.sql +1 -1
- data/tests/app_portal-triggers.sql +2 -2
- data/tests/app_portal-views.sql +11 -6
- data/tests/fox.sql +2 -2
- data/tests/sys_portal.sql +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: 3edb2b02216445f08fca3238457e20448bcb24c1dc27238ba4429dcc6814f25f
|
4
|
+
data.tar.gz: e8265ca5326412c5a793f5f056f7908c8c1e0e08945f8e309cd2cbad5347bc2e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7eb69399a73f5a046b3ebcb9a356246ddf0b4dfbb72b13c141e2021d0f01750df3778a74c529e75e3e412925b4079038cdee7f767708410ee25e6ed14f48b1b4
|
7
|
+
data.tar.gz: 1db226b915c8ac98a5efbcde084e50d7547763489f07dbf4e6ee7291adaa5d4d69bd1ba921233fc3cf51a0a9d8671de61f8cc12f1159a830a5461b01cde45363
|
data/exe/mkacl
CHANGED
@@ -22,9 +22,12 @@ SPEC = %(
|
|
22
22
|
pollution)
|
23
23
|
|
24
24
|
ROLES
|
25
|
-
The following roles are recognized: LA, TA, KON, AKK
|
26
|
-
|
27
|
-
|
25
|
+
The following roles are recognized: RES, LA, TA, KON, AKK, CLA, CTA, ELA,
|
26
|
+
and ETA
|
27
|
+
|
28
|
+
Sagsys also defines the ADM role that is excluded because it is now a RBAC
|
29
|
+
fole, and PUP and NON that are excluded because they are not implemented in
|
30
|
+
Mikras
|
28
31
|
|
29
32
|
OPTIONS
|
30
33
|
-i,interactive
|
@@ -34,6 +37,10 @@ SPEC = %(
|
|
34
37
|
Generate only the given modules. LIST is a comma-separated list of
|
35
38
|
modules. The following modules are currently aavailable: id_functions,
|
36
39
|
insert_triggers, rules, acl_functions, and role_functions
|
40
|
+
|
41
|
+
-W,no-warn
|
42
|
+
Do not emit warnings about tables in the application schema that are not
|
43
|
+
defined in the spec file
|
37
44
|
)
|
38
45
|
|
39
46
|
require 'yaml'
|
@@ -48,12 +55,17 @@ username ||= database || ENV['PRICK_USERNAME']
|
|
48
55
|
database ||= ENV['PRICK_DATABASE']
|
49
56
|
conn = PgConn.new database, username
|
50
57
|
|
58
|
+
if opts.generate?
|
59
|
+
modules = opts.generate.split(',').map(&:to_sym)
|
60
|
+
modules.each { |m| MkAcl::Generator::MODULES.include?(m) or ShellOpts.error("Unknown module - #{m}") }
|
61
|
+
else
|
62
|
+
modules = MkAcl::Generator::MODULES
|
63
|
+
end
|
64
|
+
|
51
65
|
spec = MkAcl::Parser.parse(file)
|
52
|
-
MkAcl::Analyzer.analyze(spec, conn)
|
66
|
+
MkAcl::Analyzer.analyze(spec, conn, warn: !opts.no_warn?)
|
53
67
|
#spec.dump
|
54
|
-
#puts
|
55
68
|
#exit
|
56
|
-
|
57
|
-
modules = opts.generate? ? opts.generate.split(',').map(&:to_sym) : MkAcl::Generator::MODULES
|
58
69
|
MkAcl::Generator.generate(spec, conn, modules, interactive: opts.interactive?)
|
59
70
|
|
71
|
+
|
@@ -4,9 +4,14 @@ module MkAcl
|
|
4
4
|
attr_reader :spec
|
5
5
|
attr_reader :conn
|
6
6
|
|
7
|
-
|
7
|
+
# Tables in the application schema that are not defined in the SPEC file
|
8
|
+
def uncovered_tables = @uncovered_tables.to_a
|
9
|
+
|
10
|
+
def initialize(spec, conn, warn: true)
|
8
11
|
@spec = spec
|
9
12
|
@conn = conn
|
13
|
+
@warn = warn
|
14
|
+
@uncovered_tables = Set.new
|
10
15
|
end
|
11
16
|
|
12
17
|
def analyze
|
@@ -17,15 +22,32 @@ module MkAcl
|
|
17
22
|
schema_name || '.' || table_name,
|
18
23
|
ref_schema_name || '.' || ref_table_name
|
19
24
|
from meta.links
|
25
|
+
where schema_name = '#{spec.app_schema}'
|
26
|
+
and ref_schema_name = '#{spec.app_schema}'
|
20
27
|
)
|
21
28
|
|
22
29
|
# Link up tables
|
23
30
|
for child_table_name, parent_table_name, child_table_uid, parent_table_uid in links
|
31
|
+
if !spec.key?(child_table_name)
|
32
|
+
@uncovered_tables << child_table_name
|
33
|
+
next
|
34
|
+
elsif !spec.key?(parent_table_name)
|
35
|
+
@uncovered_tables << parent_table_name
|
36
|
+
next
|
37
|
+
end
|
38
|
+
|
24
39
|
spec[child_table_name].parents << spec[parent_table_name] if spec[parent_table_name]
|
25
40
|
end
|
26
41
|
|
42
|
+
# if warn && !@uncovered_tables.empty?
|
43
|
+
# puts "Warning: Uncovered tables"
|
44
|
+
# indent { puts uncovered_tables }
|
45
|
+
# end
|
46
|
+
|
27
47
|
# Assign domains
|
28
|
-
spec.tables.each { |table|
|
48
|
+
spec.tables.each { |table|
|
49
|
+
resolve_domain(table)
|
50
|
+
}
|
29
51
|
|
30
52
|
# Check that no table has more than one parent. FIXME
|
31
53
|
spec.tables.each { |table|
|
@@ -35,11 +57,15 @@ module MkAcl
|
|
35
57
|
spec
|
36
58
|
end
|
37
59
|
|
38
|
-
def self.analyze(spec, conn) self.new(spec, conn).analyze end
|
60
|
+
def self.analyze(spec, conn, **opts) self.new(spec, conn, **opts).analyze end
|
39
61
|
|
40
62
|
private
|
63
|
+
def find_tables
|
64
|
+
|
65
|
+
end
|
66
|
+
|
41
67
|
def resolve_domain(table)
|
42
|
-
table.domain ||= resolve_domain(table.parents.first)
|
68
|
+
table.domain ||= table.parents.first && resolve_domain(table.parents.first)
|
43
69
|
end
|
44
70
|
end
|
45
71
|
end
|
@@ -7,11 +7,32 @@ module MkAcl
|
|
7
7
|
attr_reader :generator
|
8
8
|
forward_to :generator, :conn, :spec, :app_schema, :acl_schema
|
9
9
|
|
10
|
+
# Map from domain table to list of [table, path, links] tuples. The
|
11
|
+
# entries describes the SQL link chain from the table to the given domain
|
12
|
+
# table (cases or events)
|
13
|
+
attr_reader :chains
|
14
|
+
|
10
15
|
def initialize(generator)
|
11
16
|
@generator = generator
|
17
|
+
@chains = {}
|
12
18
|
end
|
13
19
|
|
20
|
+
# TODO: ACL checks so that a user can't get IDs of other users' records
|
14
21
|
def generate
|
22
|
+
# Find chains
|
23
|
+
@chains = conn.multimap %(
|
24
|
+
select
|
25
|
+
dst_table_name as "key",
|
26
|
+
src_table_name as "table_name",
|
27
|
+
path as "tables",
|
28
|
+
links
|
29
|
+
from
|
30
|
+
meta.chains
|
31
|
+
where src_schema_name = '#{app_schema}'
|
32
|
+
and dst_schema_name = '#{app_schema}'
|
33
|
+
and dst_table_name in ('cases', 'events')
|
34
|
+
)
|
35
|
+
|
15
36
|
generate_per_table_id_functions
|
16
37
|
generate_general_id_functions
|
17
38
|
generate_general_id_of_record_functions
|
@@ -20,33 +41,42 @@ module MkAcl
|
|
20
41
|
def self.generate(generator) self.new(generator).generate end
|
21
42
|
|
22
43
|
private
|
23
|
-
|
24
|
-
|
25
|
-
|
44
|
+
# # SQL sequence of spec file tables
|
45
|
+
# def table_seq() @table_seq ||= spec.tables.map(&:uid).join(', ') end
|
46
|
+
|
47
|
+
# Generate a set of per-table functions that returns the associated
|
48
|
+
# case_id/event_id for the given record. The Functions are generated for
|
49
|
+
# each table in the spec file
|
26
50
|
#
|
27
|
-
#
|
28
|
-
# event_id_of_noncompliance(id integer)
|
29
|
-
# domain_id_of_noncompliance(id integer)
|
51
|
+
# The geneated functions are
|
30
52
|
#
|
31
|
-
#
|
32
|
-
#
|
53
|
+
# case_id_of_RECORD(id integer)
|
54
|
+
# event_id_of_RECORD(id integer)
|
55
|
+
# domain_id_of_RECORD(id integer)
|
56
|
+
#
|
57
|
+
# and the record variants
|
33
58
|
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
59
|
+
# case_id_of_RECORD(r record)
|
60
|
+
# event_id_of_RECORD(r record)
|
61
|
+
# domain_id_of_RECORD(r record)
|
37
62
|
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
63
|
+
# 'RECORD' is substituted with the record name of a table. Record names
|
64
|
+
# are the singular name of a table. TODO: Make it plural again
|
65
|
+
#
|
66
|
+
# The domain functions returns event_id if related to an event and
|
67
|
+
# case_id if not. It is meant to return the most specialized domin id for
|
68
|
+
# a record. TODO Is it used?
|
69
|
+
#
|
70
|
+
# Returns null if not found. Note that the record has to exists because
|
71
|
+
# we access it to read the foreign keys
|
43
72
|
#
|
44
|
-
# IDEA: Make the implementations also take a record type instead of an
|
45
|
-
# id. This is useful in triggers because we already have the first record
|
46
|
-
# in the acl chain
|
47
73
|
def generate_per_table_id_functions
|
74
|
+
# Generate functions by domain
|
48
75
|
for domain in %w(case event)
|
49
|
-
|
76
|
+
|
77
|
+
# Create the identity functions first. The identity functions are
|
78
|
+
# case_id_of_case() and event_id_of_event(). This makes some stuff
|
79
|
+
# easier later on
|
50
80
|
table = "#{domain}s"
|
51
81
|
id_field = "#{domain}_id"
|
52
82
|
signature = "#{acl_schema}.#{id_field}_of_#{domain}(_id integer)"
|
@@ -54,24 +84,14 @@ module MkAcl
|
|
54
84
|
drop function if exists #{signature} cascade;
|
55
85
|
create function #{signature} returns integer as $$
|
56
86
|
select _id;
|
57
|
-
$$ language sql
|
87
|
+
$$ language sql
|
88
|
+
set search_path to ''; -- intentionally empty
|
58
89
|
).align
|
59
90
|
puts
|
60
91
|
|
61
|
-
# Create
|
62
|
-
|
63
|
-
|
64
|
-
start_table as "table_uid",
|
65
|
-
path as "tables",
|
66
|
-
links
|
67
|
-
from
|
68
|
-
acl.paths
|
69
|
-
where
|
70
|
-
stop_table = '#{app_schema}.#{table}'
|
71
|
-
)
|
72
|
-
|
73
|
-
for table_uid, tables, links in functions
|
74
|
-
table_name = table_uid.split(".").last
|
92
|
+
# Create functions
|
93
|
+
domain_table = Prick::Inflector.pluralize(domain)
|
94
|
+
for table_name, tables, links in chains[domain_table]
|
75
95
|
record_name = Prick::Inflector.singularize(table_name)
|
76
96
|
id_arg = "_#{id_field}"
|
77
97
|
signature = "#{acl_schema}.#{id_field}_of_#{record_name}(#{id_arg} integer)"
|
@@ -92,25 +112,35 @@ module MkAcl
|
|
92
112
|
}
|
93
113
|
puts ";"
|
94
114
|
}
|
95
|
-
puts
|
115
|
+
puts %(
|
116
|
+
$$ language sql
|
117
|
+
set search_path to ''; -- intentionally empty
|
118
|
+
).align
|
96
119
|
puts
|
97
|
-
|
98
120
|
end
|
99
121
|
end
|
100
122
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
123
|
+
# Tables that references events and cases
|
124
|
+
event_tables = chains['events'].map(&:first)
|
125
|
+
|
126
|
+
# Tables that references only cases
|
127
|
+
case_tables = chains['cases'].map(&:first) - event_tables
|
128
|
+
|
129
|
+
# Create domain functions
|
130
|
+
for domain, tables in { case: case_tables, event: event_tables }
|
131
|
+
for table_name in tables
|
132
|
+
record_name = Prick::Inflector.singularize(table_name)
|
133
|
+
signature = "#{acl_schema}.domain_id_of_#{record_name}(_id integer)"
|
134
|
+
domain_function = "#{acl_schema}.#{domain}_id_of_#{record_name}"
|
135
|
+
puts %(
|
136
|
+
drop function if exists #{signature} cascade;
|
137
|
+
create function #{signature} returns integer as $$
|
138
|
+
select #{domain_function}(_id);
|
139
|
+
$$ language sql
|
140
|
+
set search_path to ''; -- intentionally empty
|
141
|
+
).align
|
142
|
+
puts
|
143
|
+
end
|
114
144
|
end
|
115
145
|
end
|
116
146
|
|
@@ -125,7 +155,7 @@ module MkAcl
|
|
125
155
|
#
|
126
156
|
def generate_general_id_functions
|
127
157
|
for domain in %w(case event)
|
128
|
-
domain_table =
|
158
|
+
domain_table = Prick::Inflector.pluralize(domain)
|
129
159
|
field = "#{domain}_id"
|
130
160
|
signature = "#{acl_schema}.#{field}_of(_table varchar, _id integer)"
|
131
161
|
|
@@ -136,14 +166,8 @@ module MkAcl
|
|
136
166
|
).align
|
137
167
|
indent(2) {
|
138
168
|
puts "case _table"
|
139
|
-
tables = conn.values %(
|
140
|
-
select start_table
|
141
|
-
from acl.paths
|
142
|
-
where stop_table = '#{app_schema}.#{domain}'
|
143
|
-
).align
|
144
169
|
indent {
|
145
|
-
for
|
146
|
-
table_name = table_uid.split(".").last
|
170
|
+
for table_name in chains[domain_table].map(&:first)
|
147
171
|
record_name = Prick::Inflector.singularize(table_name)
|
148
172
|
function_name = "#{field}_of_#{record_name}"
|
149
173
|
puts "when '#{table_name}' then #{acl_schema}.#{function_name}(_id)"
|
@@ -171,12 +195,12 @@ module MkAcl
|
|
171
195
|
|
172
196
|
# General domain-id-of-record functions
|
173
197
|
#
|
174
|
-
# case_id_of(record)
|
175
|
-
# event_id_of(record)
|
176
|
-
# domain_id_of(record)
|
198
|
+
# case_id_of(r record)
|
199
|
+
# event_id_of(r record)
|
200
|
+
# domain_id_of(r record)
|
177
201
|
#
|
178
202
|
# Returns the case or event id associated with the given record. The
|
179
|
-
# record should be an ACL table record
|
203
|
+
# record should be an ACL table record type
|
180
204
|
#
|
181
205
|
# Very useful in before insert triggers because it takes a record (eg.
|
182
206
|
# NEW) instead of an ID
|
@@ -188,9 +212,8 @@ module MkAcl
|
|
188
212
|
column_name,
|
189
213
|
ref_table_name
|
190
214
|
from
|
191
|
-
|
192
|
-
where
|
193
|
-
schema_name = '#{app_schema}'
|
215
|
+
meta.links
|
216
|
+
where schema_name = '#{app_schema}'
|
194
217
|
)).group_by(&:table_name)
|
195
218
|
|
196
219
|
for domain in %w(case event)
|
@@ -210,9 +233,14 @@ module MkAcl
|
|
210
233
|
).align
|
211
234
|
indent {
|
212
235
|
indent {
|
236
|
+
|
237
|
+
|
213
238
|
for table in spec.tables
|
214
239
|
next if domain == "event" && table.domain == "case"
|
215
|
-
|
240
|
+
# puts "------------------------"
|
241
|
+
# p table.name
|
242
|
+
# p links.keys
|
243
|
+
link = links[table.name]&.first or next
|
216
244
|
if table.name == "cases"
|
217
245
|
puts "when '#{table.uid}' then return _r.id;"
|
218
246
|
elsif domain == "event" && table.name == "events"
|
@@ -222,7 +250,7 @@ module MkAcl
|
|
222
250
|
elsif link.ref_table_name == "events" && table.domain == "event"
|
223
251
|
puts "when '#{table.uid}' then return _r.#{link.column_name};"
|
224
252
|
else
|
225
|
-
ref_record = spec[link.ref_table_name]
|
253
|
+
ref_record = spec[link.ref_table_name]&.record_name or next
|
226
254
|
id_of_function = "#{acl_schema}.#{domain_id_field}_of_#{ref_record}"
|
227
255
|
puts "when '#{table.uid}' then return #{id_of_function}(_r.#{link.column_name});"
|
228
256
|
end
|
@@ -235,7 +263,7 @@ module MkAcl
|
|
235
263
|
}
|
236
264
|
puts %(
|
237
265
|
$$ language plpgsql
|
238
|
-
set search_path to '';
|
266
|
+
set search_path to ''; -- intentionally ''
|
239
267
|
).align
|
240
268
|
puts
|
241
269
|
end
|
@@ -253,7 +281,8 @@ module MkAcl
|
|
253
281
|
|
254
282
|
return _id;
|
255
283
|
end;
|
256
|
-
$$ language plpgsql
|
284
|
+
$$ language plpgsql
|
285
|
+
set search_path to ''; -- intentionally ''
|
257
286
|
).align
|
258
287
|
puts
|
259
288
|
end
|
@@ -1,11 +1,21 @@
|
|
1
1
|
|
2
2
|
module MkAcl
|
3
3
|
class Spec
|
4
|
-
|
4
|
+
# Source SPEC file. Only for informational purposes
|
5
|
+
attr_reader :file
|
6
|
+
|
7
|
+
# Application schema that contains the ACL controlled tables
|
5
8
|
attr_reader :app_schema
|
9
|
+
|
10
|
+
# Schema for generated functions to keep the application schema
|
11
|
+
# (relatively) clean
|
6
12
|
attr_reader :acl_schema
|
13
|
+
|
14
|
+
# List of tables. Initialized by Table::initialize through #attach_table
|
7
15
|
attr_reader :tables
|
8
16
|
|
17
|
+
# Spec acts as a hash from table name to Table object. Initialized by
|
18
|
+
# Table::initialize through #attach_table
|
9
19
|
forward_to :@table_hash, :[], :key?, :keys, :values
|
10
20
|
|
11
21
|
def initialize(file, app_schema, acl_schema)
|
@@ -65,7 +75,7 @@ module MkAcl
|
|
65
75
|
end
|
66
76
|
|
67
77
|
def to_s() = name
|
68
|
-
def inspect() "
|
78
|
+
def inspect() "<#{self.class}#name #{name.inspect}>" end
|
69
79
|
|
70
80
|
def dump
|
71
81
|
puts "#{name}:"
|
data/lib/mikras_utils/version.rb
CHANGED
data/tests/acl.fox
CHANGED
data/tests/acl.spec
CHANGED
data/tests/acl.sql
CHANGED
@@ -77,7 +77,7 @@ create view closures as
|
|
77
77
|
|
78
78
|
\echo ACL_CLOSURES
|
79
79
|
--select * from closures;
|
80
|
-
|
80
|
+
/*
|
81
81
|
drop view if exists paths cascade;
|
82
82
|
create view paths as
|
83
83
|
with
|
@@ -129,4 +129,4 @@ create view paths as
|
|
129
129
|
|
130
130
|
\echo ACL_PATHS
|
131
131
|
--select * from paths;
|
132
|
-
|
132
|
+
*/
|
data/tests/acl_portal-tables.sql
CHANGED
@@ -12,7 +12,7 @@ create table acl_portal.attach_acls (
|
|
12
12
|
unique (child_table, child_field, parent_table, parent_id, acls)
|
13
13
|
);
|
14
14
|
|
15
|
-
-- Acts as a materialized view. A user's record is updated whenever
|
15
|
+
-- Acts as a materialized view. A user's record is updated whenever case_role_users
|
16
16
|
-- or event_users are changed
|
17
17
|
drop table if exists acl_portal.user_acls cascade;
|
18
18
|
create table acl_portal.user_acls (
|
data/tests/acl_portal-views.sql
CHANGED
@@ -44,7 +44,7 @@ create view acl_portal.domain_users as
|
|
44
44
|
cr.id as "domain_role_id",
|
45
45
|
cu.user_id,
|
46
46
|
cr.role
|
47
|
-
from app_portal.
|
47
|
+
from app_portal.case_role_users cu
|
48
48
|
join app_portal.case_roles cr on cr.id = cu.case_role_id
|
49
49
|
join app_portal.cases c on c.id = cr.case_id
|
50
50
|
where (not c.closed or cr.role in ('CLA', 'ELA'))
|
data/tests/app_portal-tables.sql
CHANGED
@@ -45,7 +45,7 @@ create table case_roles (
|
|
45
45
|
unique (case_id, "role")
|
46
46
|
);
|
47
47
|
|
48
|
-
create table
|
48
|
+
create table case_role_users (
|
49
49
|
id integer generated by default as identity primary key,
|
50
50
|
case_role_id integer not null references case_roles(id),
|
51
51
|
user_id integer not null references auth.roles(id),
|
@@ -3,7 +3,7 @@
|
|
3
3
|
-- Triggers that maintains acl_portal.user_acls.
|
4
4
|
--
|
5
5
|
|
6
|
-
-- Call acl_portal.update_user_acl on any change to either
|
6
|
+
-- Call acl_portal.update_user_acl on any change to either case_role_users or
|
7
7
|
-- event_users. Note that this function is both cross-table and cross
|
8
8
|
-- insert/delete
|
9
9
|
create function domain_users_aiud() returns trigger as $$
|
@@ -13,7 +13,7 @@ create function domain_users_aiud() returns trigger as $$
|
|
13
13
|
end;
|
14
14
|
$$ language plpgsql;
|
15
15
|
|
16
|
-
create trigger
|
16
|
+
create trigger case_role_users_aiud_trg after insert or update or delete on app_portal.case_role_users
|
17
17
|
for each row execute function domain_users_aiud()
|
18
18
|
;
|
19
19
|
|
data/tests/app_portal-views.sql
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
set search_path to app_portal;
|
4
4
|
|
5
|
+
/*
|
6
|
+
|
5
7
|
-- Union of case_roles and event_roles
|
6
8
|
drop view if exists acl_portal.domain_roles cascade;
|
7
9
|
create view acl_portal.domain_roles as
|
@@ -22,14 +24,14 @@ create view acl_portal.domain_roles as
|
|
22
24
|
app_portal.event_roles
|
23
25
|
;
|
24
26
|
|
25
|
-
-- Union of
|
27
|
+
-- Union of case_role_users and event_users
|
26
28
|
drop view if exists acl_portal.domain_users cascade;
|
27
29
|
create view acl_portal.domain_users as
|
28
30
|
select
|
29
31
|
case_role_id as "domain_role_id",
|
30
32
|
user_id
|
31
33
|
from
|
32
|
-
app_portal.
|
34
|
+
app_portal.case_role_users
|
33
35
|
|
34
36
|
union all
|
35
37
|
|
@@ -39,8 +41,10 @@ create view acl_portal.domain_users as
|
|
39
41
|
from
|
40
42
|
app_portal.event_users
|
41
43
|
;
|
44
|
+
*/
|
42
45
|
|
43
|
-
|
46
|
+
/*
|
47
|
+
-- Combines cases, case_roles, and case_role_users and also computes the virtual CLA
|
44
48
|
-- and CTA roles from the event ELA and ETA roles and assigns the CLA role to
|
45
49
|
-- RES users. Only ACL roles are included
|
46
50
|
drop view if exists case_role_users cascade;
|
@@ -55,7 +59,7 @@ create view case_role_users as
|
|
55
59
|
cr.role
|
56
60
|
from app_portal.role_kinds rk
|
57
61
|
join app_portal.case_roles cr on cr.role = rk.kind
|
58
|
-
join app_portal.
|
62
|
+
join app_portal.case_role_users cu on cu.case_role_id = cr.id
|
59
63
|
where rk.acl
|
60
64
|
),
|
61
65
|
-- RES user is also CLA
|
@@ -95,7 +99,8 @@ create view case_role_users as
|
|
95
99
|
select * from eta_ela_roles
|
96
100
|
order by case_id, user_id -- FIXME: Yt
|
97
101
|
;
|
98
|
-
|
102
|
+
*/
|
103
|
+
/*
|
99
104
|
-- Combines case_role_users with event_roles and event_users. It is the set of
|
100
105
|
-- roles (case or event) that is associated with an event. Users that are no
|
101
106
|
-- longer associated with the case are excluded
|
@@ -200,4 +205,4 @@ create view agg_name.domain_role_users as
|
|
200
205
|
username
|
201
206
|
order by domain_id, username
|
202
207
|
;
|
203
|
-
|
208
|
+
*/
|
data/tests/fox.sql
CHANGED
@@ -15,7 +15,7 @@ insert into acl_portal.attach_acls (parent_table, parent_id, child_table, child_
|
|
15
15
|
select
|
16
16
|
'case_roles' as "parent_table",
|
17
17
|
id as "parent_id",
|
18
|
-
'
|
18
|
+
'case_role_users' as "child_table",
|
19
19
|
'case_role_id' as "child_id",
|
20
20
|
array[2] -- hdj
|
21
21
|
from
|
@@ -28,7 +28,7 @@ insert into acl_portal.attach_acls (parent_table, parent_id, child_table, child_
|
|
28
28
|
delete from auth.users;
|
29
29
|
insert into auth.users select * from auth.roles;
|
30
30
|
|
31
|
-
select acl_portal.update_acls();
|
31
|
+
--select acl_portal.update_acls();
|
32
32
|
select acl_portal.update_user_acls();
|
33
33
|
|
34
34
|
/*
|
data/tests/sys_portal.sql
CHANGED
@@ -60,7 +60,7 @@ create view acl_users as
|
|
60
60
|
cr.id as "role_id"
|
61
61
|
from
|
62
62
|
auth.roles u
|
63
|
-
join app_portal.
|
63
|
+
join app_portal.case_role_users cu on cu.user_id = u.id
|
64
64
|
join app_portal.case_roles cr on cr.id = cu.case_role_id
|
65
65
|
join app_portal.cases c on c.id = cr.case_id
|
66
66
|
where
|
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.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Claus Rasmussen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-07-
|
11
|
+
date: 2024-07-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pg_conn
|