mikras_utils 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.ruby-version +1 -0
- data/Gemfile +10 -0
- data/README.md +31 -0
- data/Rakefile +8 -0
- data/acl-build +5 -0
- data/build +11 -0
- data/exe/mikras_utils +5 -0
- data/exe/mkacl +59 -0
- data/lib/mikras_utils/mkacl/analyzer.rb +46 -0
- data/lib/mikras_utils/mkacl/generator.rb +55 -0
- data/lib/mikras_utils/mkacl/generators/acl_functions.rb +208 -0
- data/lib/mikras_utils/mkacl/generators/id_functions.rb +262 -0
- data/lib/mikras_utils/mkacl/generators/insert_triggers.rb +267 -0
- data/lib/mikras_utils/mkacl/generators/role_functions.rb +72 -0
- data/lib/mikras_utils/mkacl/generators/rules.rb +80 -0
- data/lib/mikras_utils/mkacl/parser.rb +73 -0
- data/lib/mikras_utils/mkacl/spec.rb +154 -0
- data/lib/mikras_utils/mkacl.rb +18 -0
- data/lib/mikras_utils/version.rb +5 -0
- data/lib/mikras_utils.rb +6 -0
- data/sig/mikras_utils.rbs +4 -0
- data/tests/acl.fox +312 -0
- data/tests/acl.spec +135 -0
- data/tests/acl.sql +132 -0
- data/tests/acl_portal-functions.sql +94 -0
- data/tests/acl_portal-tables.sql +23 -0
- data/tests/acl_portal-views.sql +73 -0
- data/tests/agg.sql +25 -0
- data/tests/app.sql +48 -0
- data/tests/app_portal-tables.sql +138 -0
- data/tests/app_portal-triggers.sql +23 -0
- data/tests/app_portal-views.sql +203 -0
- data/tests/auth.sql +12 -0
- data/tests/auth.users.sql +5 -0
- data/tests/build +7 -0
- data/tests/final-functions.sql +28 -0
- data/tests/fox.sql +158 -0
- data/tests/initial-functions.sql +6 -0
- data/tests/meta.sql +197 -0
- data/tests/reflections.yml +5 -0
- data/tests/schemas.sql +25 -0
- data/tests/setup.sql +8 -0
- data/tests/sys_portal.sql +172 -0
- metadata +145 -0
@@ -0,0 +1,73 @@
|
|
1
|
+
|
2
|
+
module MkAcl
|
3
|
+
class Parser
|
4
|
+
attr_reader :file
|
5
|
+
|
6
|
+
def initialize(file) @file = file end
|
7
|
+
def parse() parse_spec end
|
8
|
+
def self.parse(file) Parser.new(file).parse end
|
9
|
+
|
10
|
+
private
|
11
|
+
def error(*msg) raise ParseError, *msg end
|
12
|
+
def norm_array(value) value.is_a?(Array) ? value : value&.split end
|
13
|
+
|
14
|
+
def parse_spec
|
15
|
+
hash = YAML.load(IO.read(file), symbolize_names: true)
|
16
|
+
|
17
|
+
schema = hash.delete(:schema) or raise ArgumentError, "Can't find 'schema' declaration"
|
18
|
+
app_schema = schema[:app] or raise ArgumentError, "Can't find 'schema.app' attribute"
|
19
|
+
acl_schema = schema[:acl] or raise ArgumentError, "Can't find 'schema.acl' attribute"
|
20
|
+
spec = Spec.new(file, app_schema, acl_schema)
|
21
|
+
parse_tables(spec, hash)
|
22
|
+
spec
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse_tables(spec, tables)
|
26
|
+
for table_name, actions in tables
|
27
|
+
table = Table.new(spec, table_name, actions.delete(:domain))
|
28
|
+
parse_actions(table, actions)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def parse_actions(table, actions)
|
33
|
+
for action_name, rules in actions
|
34
|
+
constrain?(action_name, :insert, :select, :update, :delete) or error "Illegal action '#{action_name}'"
|
35
|
+
constrain?(rules, String, Array, Hash) or error "Illegal value for #{action} action '#{rules}'"
|
36
|
+
action = Action.new(table, action_name)
|
37
|
+
|
38
|
+
# Normalize rules
|
39
|
+
case rules
|
40
|
+
when Hash
|
41
|
+
rules = [rules]
|
42
|
+
when String
|
43
|
+
rules = [{ role: rules }]
|
44
|
+
end
|
45
|
+
|
46
|
+
parse_rules(action, rules)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def parse_rules(action, rules)
|
51
|
+
index = 0
|
52
|
+
for entry in rules
|
53
|
+
rule = Rule.new(action, index += 1)
|
54
|
+
|
55
|
+
for key, value in entry
|
56
|
+
case key
|
57
|
+
when :role; rule.roles = norm_array(value)
|
58
|
+
when :using; rule.using = value
|
59
|
+
when :check; rule.check = value
|
60
|
+
when :include; rule.include = norm_array(value)
|
61
|
+
when :exclude; rule.exclude = norm_array(value)
|
62
|
+
else
|
63
|
+
raise ArgumentError, "Illegal field '#{key}' in #{action.table}.#{action}"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
!action.rules.empty? or
|
68
|
+
error "At least one rule is required in #{action.table}.#{action}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
@@ -0,0 +1,154 @@
|
|
1
|
+
|
2
|
+
module MkAcl
|
3
|
+
class Spec
|
4
|
+
attr_reader :file # Only for informational purposes
|
5
|
+
attr_reader :app_schema
|
6
|
+
attr_reader :acl_schema
|
7
|
+
attr_reader :tables
|
8
|
+
|
9
|
+
forward_to :@table_hash, :[], :key?, :keys, :values
|
10
|
+
|
11
|
+
def initialize(file, app_schema, acl_schema)
|
12
|
+
@file = file
|
13
|
+
@app_schema = app_schema
|
14
|
+
@acl_schema = acl_schema
|
15
|
+
@tables = []
|
16
|
+
@table_hash = {}
|
17
|
+
end
|
18
|
+
|
19
|
+
def dump
|
20
|
+
puts "Schema"
|
21
|
+
indent {
|
22
|
+
puts "app_schema: #{app_schema}"
|
23
|
+
puts "acl_schema: #{acl_schema}"
|
24
|
+
puts
|
25
|
+
tables.map(&:dump)
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def attach_table(table)
|
31
|
+
@tables << table
|
32
|
+
@table_hash[table.name] = table
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class Table
|
37
|
+
attr_reader :spec
|
38
|
+
attr_accessor :parents # Parent TableSpec objects. Initialized by the analyzer
|
39
|
+
attr_reader :uid # SCHEMA.TABLE name
|
40
|
+
attr_reader :name
|
41
|
+
attr_reader :record_name # Associated record name. Used in function names
|
42
|
+
attr_accessor :domain # Security domain - either 'case' or 'event'. Initialized by the analyzer
|
43
|
+
|
44
|
+
# Action objects
|
45
|
+
def insert = @actions["insert"]
|
46
|
+
def select = @actions["select"]
|
47
|
+
def update = @actions["update"]
|
48
|
+
def delete = @actions["delete"]
|
49
|
+
|
50
|
+
# Hash from action name to action object
|
51
|
+
attr_reader :actions
|
52
|
+
|
53
|
+
def initialize(spec, name, domain)
|
54
|
+
@spec = spec
|
55
|
+
@parents = []
|
56
|
+
@name = name.to_s
|
57
|
+
@uid = "#{@spec.app_schema}.#{@name}"
|
58
|
+
@record_name = Prick::Inflector.singularize(@name)
|
59
|
+
@domain = domain
|
60
|
+
@actions = {}
|
61
|
+
@spec.send :attach_table, self
|
62
|
+
for action_name in %w(insert select update delete)
|
63
|
+
attach_action(Action.new(self, action_name))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def to_s() = name
|
68
|
+
def inspect() "<<#{name}>>" end
|
69
|
+
|
70
|
+
def dump
|
71
|
+
puts "#{name}:"
|
72
|
+
indent {
|
73
|
+
puts "domain: #{domain}" if domain
|
74
|
+
puts "parents: #{parents.inspect}"
|
75
|
+
for action_name in %w(insert select update delete)
|
76
|
+
actions[action_name]&.dump
|
77
|
+
end
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
def attach_action(action)
|
83
|
+
@actions[action.name] = action
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class Action
|
88
|
+
attr_reader :table
|
89
|
+
attr_reader :name
|
90
|
+
attr_reader :rules
|
91
|
+
|
92
|
+
def initialize(table, name)
|
93
|
+
@table = table
|
94
|
+
@name = name.to_s
|
95
|
+
@rules = []
|
96
|
+
@table.send :attach_action, self
|
97
|
+
end
|
98
|
+
|
99
|
+
def fields() @include + @exclude.map { "-#{_1}" } end
|
100
|
+
|
101
|
+
def to_s() name end
|
102
|
+
|
103
|
+
def dump
|
104
|
+
if rules.empty?
|
105
|
+
puts "#{name}: []"
|
106
|
+
else
|
107
|
+
puts name
|
108
|
+
indent {
|
109
|
+
for rule in rules
|
110
|
+
print "- "
|
111
|
+
indent(bol: false) { rule.dump }
|
112
|
+
end
|
113
|
+
}
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
def attach_rule(rule)
|
119
|
+
@rules << rule
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
class Rule
|
124
|
+
attr_reader :action
|
125
|
+
forward_to :action, :table, :name
|
126
|
+
attr_reader :index
|
127
|
+
attr_accessor :roles
|
128
|
+
attr_accessor :using # Goes into the postgres policy
|
129
|
+
attr_accessor :check # Goes into the postgres trigger
|
130
|
+
attr_accessor :include
|
131
|
+
attr_accessor :exclude
|
132
|
+
|
133
|
+
def auth_roles() @auth_roles ||= roles.select { _1 == _1.downcase } end
|
134
|
+
def case_roles() @case_roles ||= roles.select { _1 == _1.upcase } end
|
135
|
+
|
136
|
+
def initialize(action, index)
|
137
|
+
@action = action
|
138
|
+
@index = index
|
139
|
+
@roles, @check, @include, @exclude = [], nil, [], []
|
140
|
+
action.send :attach_rule, self
|
141
|
+
end
|
142
|
+
|
143
|
+
def fields() @include + @exclude.map { "-#{_1}" } end
|
144
|
+
|
145
|
+
def dump
|
146
|
+
puts "index: #{index}"
|
147
|
+
puts "roles: #{roles.join(' ')}"
|
148
|
+
puts "check: #{check}" if check
|
149
|
+
puts "include: #{include.join(' ')}" if !include.empty?
|
150
|
+
puts "exclude: #{exclude.join(' ')}" if !exclude.empty?
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
require 'pg_conn'
|
3
|
+
require 'indented_io'
|
4
|
+
require 'string-text'
|
5
|
+
require 'forward_to'; include ForwardTo
|
6
|
+
require 'constrain'; include Constrain
|
7
|
+
require 'prick-inflector'
|
8
|
+
|
9
|
+
module MkAcl
|
10
|
+
class ParseError < RuntimeError; end
|
11
|
+
|
12
|
+
ROLES = %w(LA TA KON AKK)
|
13
|
+
end
|
14
|
+
|
15
|
+
require_relative 'mkacl/spec.rb'
|
16
|
+
require_relative 'mkacl/parser.rb'
|
17
|
+
require_relative 'mkacl/analyzer.rb'
|
18
|
+
require_relative 'mkacl/generator.rb'
|
data/lib/mikras_utils.rb
ADDED
data/tests/acl.fox
ADDED
@@ -0,0 +1,312 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
auth.roles
|
4
|
+
- &internal
|
5
|
+
rolename: internal
|
6
|
+
- &hdj
|
7
|
+
rolename: hdj
|
8
|
+
- &bkn
|
9
|
+
rolename: bkn
|
10
|
+
- &hr
|
11
|
+
rolename: hr
|
12
|
+
- &ta
|
13
|
+
rolename: ta
|
14
|
+
- &kon1
|
15
|
+
rolename: kon1
|
16
|
+
- &akk1
|
17
|
+
rolename: akk1
|
18
|
+
- &kon2
|
19
|
+
rolename: kon2
|
20
|
+
- &akk2
|
21
|
+
rolename: akk2
|
22
|
+
- &kon3
|
23
|
+
rolename: kon3
|
24
|
+
- &akk3
|
25
|
+
rolename: akk3
|
26
|
+
|
27
|
+
@schema app_portal
|
28
|
+
|
29
|
+
cases
|
30
|
+
- &case1
|
31
|
+
name: case1
|
32
|
+
- &case2
|
33
|
+
name: case2
|
34
|
+
- &case3
|
35
|
+
name: case3
|
36
|
+
|
37
|
+
role_kinds
|
38
|
+
- kind: RES
|
39
|
+
acl: true
|
40
|
+
ordinal: 1
|
41
|
+
- kind: LA
|
42
|
+
ordinal: 2
|
43
|
+
- kind: TA
|
44
|
+
ordinal: 3
|
45
|
+
- kind: KON
|
46
|
+
acl: true
|
47
|
+
ordinal: 4
|
48
|
+
- kind: AKK
|
49
|
+
acl: true
|
50
|
+
ordinal: 5
|
51
|
+
- kind: ELA
|
52
|
+
acl: true
|
53
|
+
ordinal: 6
|
54
|
+
- kind: CLA
|
55
|
+
acl: true
|
56
|
+
ordinal: 7
|
57
|
+
- kind: ETA
|
58
|
+
acl: true
|
59
|
+
ordinal: 8
|
60
|
+
- kind: CTA
|
61
|
+
acl: true
|
62
|
+
ordinal: 9
|
63
|
+
|
64
|
+
case_role_templates
|
65
|
+
- role: RES
|
66
|
+
- role: LA
|
67
|
+
- role: TA
|
68
|
+
- role: CLA
|
69
|
+
- role: CTA
|
70
|
+
- role: KON
|
71
|
+
- role: AKK
|
72
|
+
|
73
|
+
case_roles
|
74
|
+
- &case1_res
|
75
|
+
case: *case1
|
76
|
+
role: RES
|
77
|
+
- &case1_la
|
78
|
+
case: *case1
|
79
|
+
role: LA
|
80
|
+
- &case1_ta
|
81
|
+
case: *case1
|
82
|
+
role: TA
|
83
|
+
- &case1_cla
|
84
|
+
case: *case1
|
85
|
+
role: CLA
|
86
|
+
- &case1_cta
|
87
|
+
case: *case1
|
88
|
+
role: CTA
|
89
|
+
- &case1_kon
|
90
|
+
case: *case1
|
91
|
+
role: KON
|
92
|
+
- &case1_akk
|
93
|
+
case: *case1
|
94
|
+
role: AKK
|
95
|
+
|
96
|
+
- &case2_res
|
97
|
+
case: *case2
|
98
|
+
role: RES
|
99
|
+
- &case2_la
|
100
|
+
case: *case2
|
101
|
+
role: LA
|
102
|
+
- &case2_ta
|
103
|
+
case: *case2
|
104
|
+
role: TA
|
105
|
+
- &case2_Cla
|
106
|
+
case: *case2
|
107
|
+
role: CLA
|
108
|
+
- &case2_cta
|
109
|
+
case: *case2
|
110
|
+
role: CTA
|
111
|
+
- &case2_kon
|
112
|
+
case: *case2
|
113
|
+
role: KON
|
114
|
+
- &case2_akk
|
115
|
+
case: *case2
|
116
|
+
role: AKK
|
117
|
+
|
118
|
+
- &case3_res
|
119
|
+
case: *case3
|
120
|
+
role: RES
|
121
|
+
- &case3_la
|
122
|
+
case: *case3
|
123
|
+
role: LA
|
124
|
+
- &case3_ta
|
125
|
+
case: *case3
|
126
|
+
role: TA
|
127
|
+
- &case3_cla
|
128
|
+
case: *case3
|
129
|
+
role: CLA
|
130
|
+
- &case3_cta
|
131
|
+
case: *case3
|
132
|
+
role: CTA
|
133
|
+
- &case3_kon
|
134
|
+
case: *case3
|
135
|
+
role: KON
|
136
|
+
- &case3_akk
|
137
|
+
case: *case3
|
138
|
+
role: AKK
|
139
|
+
|
140
|
+
case_users
|
141
|
+
- case_role: *case1_res
|
142
|
+
user: *hdj
|
143
|
+
- case_role: *case1_la
|
144
|
+
user: *hdj
|
145
|
+
- case_role: *case1_ta
|
146
|
+
user: *bkn
|
147
|
+
- case_role: *case1_kon
|
148
|
+
user: *kon1
|
149
|
+
- case_role: *case1_akk
|
150
|
+
user: *akk1
|
151
|
+
|
152
|
+
- case_role: *case2_res
|
153
|
+
user: *hdj
|
154
|
+
- case_role: *case2_la
|
155
|
+
user: *hdj
|
156
|
+
- case_role: *case2_la
|
157
|
+
user: *hr
|
158
|
+
- case_role: *case2_ta
|
159
|
+
user: *ta
|
160
|
+
- case_role: *case2_kon
|
161
|
+
user: *kon2
|
162
|
+
- case_role: *case2_akk
|
163
|
+
user: *akk2
|
164
|
+
|
165
|
+
- case_role: *case3_res
|
166
|
+
user: *hdj
|
167
|
+
- case_role: *case3_la
|
168
|
+
user: *hdj
|
169
|
+
- case_role: *case3_ta
|
170
|
+
user: *bkn
|
171
|
+
- case_role: *case3_ta
|
172
|
+
user: *ta
|
173
|
+
- case_role: *case3_kon
|
174
|
+
user: *kon3
|
175
|
+
|
176
|
+
events
|
177
|
+
- &event11
|
178
|
+
case: *case1
|
179
|
+
name: e11
|
180
|
+
closed: true
|
181
|
+
- &event12
|
182
|
+
case: *case1
|
183
|
+
name: e12
|
184
|
+
closed: false
|
185
|
+
- &event13
|
186
|
+
case: *case1
|
187
|
+
name: e13
|
188
|
+
closed: false
|
189
|
+
- &event21
|
190
|
+
case: *case2
|
191
|
+
name: e21
|
192
|
+
closed: false
|
193
|
+
|
194
|
+
event_role_templates
|
195
|
+
- role: ELA
|
196
|
+
- role: ETA
|
197
|
+
|
198
|
+
event_roles
|
199
|
+
- &event_role11_ela
|
200
|
+
event: *event11
|
201
|
+
role: ELA
|
202
|
+
- &event_role11_eta
|
203
|
+
event: *event11
|
204
|
+
role: ETA
|
205
|
+
- &event_role11_kon
|
206
|
+
event: *event11
|
207
|
+
role: KON
|
208
|
+
- &event_role11_akk
|
209
|
+
event: *event11
|
210
|
+
role: AKK
|
211
|
+
|
212
|
+
- &event_role12_ela
|
213
|
+
event: *event12
|
214
|
+
role: ELA
|
215
|
+
- &event_role12_eta
|
216
|
+
event: *event12
|
217
|
+
role: ETA
|
218
|
+
- &event_role12_kon
|
219
|
+
event: *event12
|
220
|
+
role: KON
|
221
|
+
- &event_role12_akk
|
222
|
+
event: *event12
|
223
|
+
role: AKK
|
224
|
+
|
225
|
+
- &event_role13_ela
|
226
|
+
event: *event13
|
227
|
+
role: ELA
|
228
|
+
- &event_role13_eta
|
229
|
+
event: *event13
|
230
|
+
role: ETA
|
231
|
+
- &event_role13_kon
|
232
|
+
event: *event13
|
233
|
+
role: KON
|
234
|
+
- &event_role13_akk
|
235
|
+
event: *event13
|
236
|
+
role: AKK
|
237
|
+
|
238
|
+
- &event_role21_ela
|
239
|
+
event: *event21
|
240
|
+
role: ELA
|
241
|
+
- &event_role21_eta
|
242
|
+
event: *event21
|
243
|
+
role: ETA
|
244
|
+
- &event_role21_kon
|
245
|
+
event: *event21
|
246
|
+
role: KON
|
247
|
+
- &event_role21_akk
|
248
|
+
event: *event21
|
249
|
+
role: AKK
|
250
|
+
|
251
|
+
event_users
|
252
|
+
- event_role: *event_role11_ela
|
253
|
+
user: *hdj
|
254
|
+
- event_role: *event_role12_eta
|
255
|
+
user: *ta # No longer assciated with the case
|
256
|
+
- event_role: *event_role11_kon
|
257
|
+
user: *kon1
|
258
|
+
- event_role: *event_role11_akk
|
259
|
+
user: *akk1
|
260
|
+
|
261
|
+
# No TA on this event
|
262
|
+
- event_role: *event_role12_ela
|
263
|
+
user: *hdj
|
264
|
+
- event_role: *event_role12_kon
|
265
|
+
user: *kon1
|
266
|
+
- event_role: *event_role12_akk
|
267
|
+
user: *akk1
|
268
|
+
|
269
|
+
# Two TAs on this event
|
270
|
+
- event_role: *event_role13_ela
|
271
|
+
user: *hdj
|
272
|
+
- event_role: *event_role13_eta
|
273
|
+
user: *ta
|
274
|
+
- event_role: *event_role13_eta
|
275
|
+
user: *bkn
|
276
|
+
- event_role: *event_role13_kon
|
277
|
+
user: *kon1
|
278
|
+
- event_role: *event_role13_akk
|
279
|
+
user: *akk1
|
280
|
+
|
281
|
+
# Event-specific LA
|
282
|
+
- event_role: *event_role21_ela
|
283
|
+
user: *hr
|
284
|
+
- event_role: *event_role21_eta
|
285
|
+
user: *ta
|
286
|
+
- event_role: *event_role21_kon
|
287
|
+
user: *kon3
|
288
|
+
- event_role: *event_role21_akk
|
289
|
+
user: *akk3
|
290
|
+
|
291
|
+
visits
|
292
|
+
- &visit131
|
293
|
+
event: *event13
|
294
|
+
name: "visit 1 of event 3 of case 1"
|
295
|
+
- &visit132
|
296
|
+
event: *event13
|
297
|
+
name: "visit 2 of event 3 of case 1"
|
298
|
+
- &visit211
|
299
|
+
event: *event21
|
300
|
+
name: "visit 1 of event 1 of case 2"
|
301
|
+
|
302
|
+
noncompliances
|
303
|
+
- &nc1311
|
304
|
+
visit: *visit131
|
305
|
+
name: "NC 1 of visit 1 of event 3 of case 1"
|
306
|
+
- &nc1312
|
307
|
+
visit: *visit131
|
308
|
+
name: "NC 2 of visit 1 of event 3 of case 1"
|
309
|
+
- &nc2111
|
310
|
+
visit: *visit131
|
311
|
+
name: "NC 1 of visit 1 of event 1 of case 2"
|
312
|
+
|
data/tests/acl.spec
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
|
2
|
+
schema:
|
3
|
+
app: app_portal
|
4
|
+
acl: acl_portal
|
5
|
+
|
6
|
+
#
|
7
|
+
# CASES AND ROLES
|
8
|
+
#
|
9
|
+
# insert, update, and delete are not used for many tables because data are
|
10
|
+
# loaded from sagsys databases without policy checks and without triggers
|
11
|
+
#
|
12
|
+
|
13
|
+
cases:
|
14
|
+
domain: case
|
15
|
+
insert: admin
|
16
|
+
select: internal TA KON AKK
|
17
|
+
update:
|
18
|
+
- role: admin
|
19
|
+
- role: RES CLA
|
20
|
+
exclude: serial ident name
|
21
|
+
delete: admin
|
22
|
+
|
23
|
+
case_roles: # TODO: RBAC
|
24
|
+
select: internal KON AKK
|
25
|
+
|
26
|
+
case_users:
|
27
|
+
insert: CLA admin
|
28
|
+
select: internal
|
29
|
+
delete: CLA admin
|
30
|
+
|
31
|
+
#
|
32
|
+
# EVENTS AND VISITS
|
33
|
+
#
|
34
|
+
|
35
|
+
events:
|
36
|
+
domain: event
|
37
|
+
insert: CLA
|
38
|
+
select: internal ETA KON AKK
|
39
|
+
update:
|
40
|
+
role: CLA ELA
|
41
|
+
include: kind
|
42
|
+
delete: CLA ELA
|
43
|
+
|
44
|
+
event_roles:
|
45
|
+
select: internal ETA KON AKK
|
46
|
+
|
47
|
+
event_users:
|
48
|
+
# insert: CLA ELA
|
49
|
+
# insert:
|
50
|
+
# role: CLA ELA
|
51
|
+
# call: acl_portal.insert_event_user(NEW.event_id, NEW.role, NEW.user_id) # In instead-of trigger
|
52
|
+
# delete
|
53
|
+
# role: CLA ELA
|
54
|
+
# call: acl_portal.delete_event_user(OLD.event_id, OLD.user_id) # In instead-of trigger
|
55
|
+
|
56
|
+
select: internal ETA KON AKK
|
57
|
+
|
58
|
+
visits:
|
59
|
+
insert: CLA ELA
|
60
|
+
select: internal ETA KON AKK
|
61
|
+
update:
|
62
|
+
role: CLA ELA
|
63
|
+
include: notes closed progress progress_description visit_at mat_received_at reported_at deadline_at
|
64
|
+
delete: CLA ELA
|
65
|
+
|
66
|
+
noncompliances:
|
67
|
+
insert:
|
68
|
+
- role: CLA ELA
|
69
|
+
- role: ETA
|
70
|
+
check: true # FIXME Example
|
71
|
+
select:
|
72
|
+
- role: internal CTA
|
73
|
+
- role: KON AKK
|
74
|
+
using: true # FIXME Example
|
75
|
+
update: CLA ELA ETA KON AKK # FLS managed by trigger
|
76
|
+
delete: CLA ELA ETA KON AKK # FLS managed by trigger
|
77
|
+
|
78
|
+
noncompliance_uploads:
|
79
|
+
insert: CLA ELA ETA KON AKK
|
80
|
+
select: internal ETA KON AKK
|
81
|
+
update:
|
82
|
+
- role: CLA ELA
|
83
|
+
include: description visible
|
84
|
+
- role: ETA KON AKK
|
85
|
+
include: description
|
86
|
+
delete:
|
87
|
+
- role: CLA ELA
|
88
|
+
- role: ETA KON AKK
|
89
|
+
using: uploaded_by_id = current_user_id()
|
90
|
+
|
91
|
+
bookings:
|
92
|
+
insert: CLA ELA
|
93
|
+
select: internal ETA KON AKK
|
94
|
+
update: CLA ELA
|
95
|
+
delete: CLA ELA
|
96
|
+
|
97
|
+
user_bookings:
|
98
|
+
insert: CLA ELA
|
99
|
+
select: internal KON AKK
|
100
|
+
update:
|
101
|
+
- role: CLA ELA
|
102
|
+
- role: ETA KON AKK
|
103
|
+
using: user_id = current_user_id()
|
104
|
+
include: mask note locked
|
105
|
+
delete: CLA ELA
|
106
|
+
|
107
|
+
#
|
108
|
+
# METHOD LINES
|
109
|
+
#
|
110
|
+
|
111
|
+
#method_lines:
|
112
|
+
# insert: CLA AKK KON
|
113
|
+
# select: CLA CTA KON AKK internal
|
114
|
+
# update: CLA KON AKK
|
115
|
+
# delete: CLA KON AKK
|
116
|
+
#
|
117
|
+
#buckets:
|
118
|
+
# insert: CLA
|
119
|
+
# select: CLA CTA KON AKK internal
|
120
|
+
# update: CLA
|
121
|
+
# delete: CLA
|
122
|
+
#
|
123
|
+
#bucket_kinds:
|
124
|
+
# select: CLA CTA KON AKK internal
|
125
|
+
#
|
126
|
+
#bucket_method_lines:
|
127
|
+
# insert: CLA
|
128
|
+
# select: CLA CTA KON AKK internal
|
129
|
+
# update: CLA
|
130
|
+
# delete: CLA
|
131
|
+
|
132
|
+
|
133
|
+
|
134
|
+
|
135
|
+
|