mikras_utils 0.1.1 → 0.3.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: 3edb2b02216445f08fca3238457e20448bcb24c1dc27238ba4429dcc6814f25f
4
- data.tar.gz: e8265ca5326412c5a793f5f056f7908c8c1e0e08945f8e309cd2cbad5347bc2e
3
+ metadata.gz: '039c1d561f66158183511f72a09ce9b76b3de0c7110d8e6aadce11b338985209'
4
+ data.tar.gz: dae3de2a17dd845f6a350ec3b63636e97ff2b565a75d40bd47e429abe5654668
5
5
  SHA512:
6
- metadata.gz: 7eb69399a73f5a046b3ebcb9a356246ddf0b4dfbb72b13c141e2021d0f01750df3778a74c529e75e3e412925b4079038cdee7f767708410ee25e6ed14f48b1b4
7
- data.tar.gz: 1db226b915c8ac98a5efbcde084e50d7547763489f07dbf4e6ee7291adaa5d4d69bd1ba921233fc3cf51a0a9d8671de61f8cc12f1159a830a5461b01cde45363
6
+ metadata.gz: 4651ae8fc80806930718c561c94ae10547d80654802cb88f19020b020871d5de73cd4b736ad98755f63333f8262c44a438ab6134d87d9f51989d68e5ed1bee43
7
+ data.tar.gz: 05a47f398922d45c61e3746c28a5fae17a334e38c9a7eb4a35dbdd4764d4d86dcd57b293fa14b6600e80da5f54b26a65aada13e3679ed56aa670107b457e4ebf
data/exe/mkacl CHANGED
@@ -22,7 +22,7 @@ SPEC = %(
22
22
  pollution)
23
23
 
24
24
  ROLES
25
- The following roles are recognized: RES, LA, TA, KON, AKK, CLA, CTA, ELA,
25
+ The following roles are recognized: RLA, LA, TA, KON, AKK, CLA, CTA, ELA,
26
26
  and ETA
27
27
 
28
28
  Sagsys also defines the ADM role that is excluded because it is now a RBAC
@@ -35,7 +35,7 @@ SPEC = %(
35
35
 
36
36
  -g,generate=LIST
37
37
  Generate only the given modules. LIST is a comma-separated list of
38
- modules. The following modules are currently aavailable: id_functions,
38
+ modules. The following modules are currently available: id_functions,
39
39
  insert_triggers, rules, acl_functions, and role_functions
40
40
 
41
41
  -W,no-warn
@@ -68,8 +68,8 @@ module MkAcl
68
68
  _domain_id integer;
69
69
  _acls integer[]; -- per-rule ACLs
70
70
  _acl_select integer[][]; -- per-action ACLs
71
- _acl_update integer[][];
72
- _acl_delete integer[][];
71
+ _acl_update integer[][]; --
72
+ _acl_delete integer[][]; --
73
73
  begin
74
74
  ).align
75
75
  indent {
@@ -216,7 +216,7 @@ module MkAcl
216
216
  where schema_name = '#{app_schema}'
217
217
  )).group_by(&:table_name)
218
218
 
219
- for domain in %w(case event)
219
+ for domain in MkAcl::DOMAINS
220
220
  domain_id_field = "#{domain}_id"
221
221
  signature = "#{acl_schema}.#{domain_id_field}_of(_r record)"
222
222
  puts %(
@@ -233,22 +233,22 @@ module MkAcl
233
233
  ).align
234
234
  indent {
235
235
  indent {
236
-
237
-
238
236
  for table in spec.tables
239
237
  next if domain == "event" && table.domain == "case"
240
- # puts "------------------------"
241
- # p table.name
242
- # p links.keys
238
+ next if domain == "visit" && table.domain == "event"
243
239
  link = links[table.name]&.first or next
244
240
  if table.name == "cases"
245
241
  puts "when '#{table.uid}' then return _r.id;"
246
242
  elsif domain == "event" && table.name == "events"
247
243
  puts "when '#{table.uid}' then return _r.id;"
244
+ elsif domain == "visit" && table.name == "visits"
245
+ puts "when '#{table.uid}' then return _r.id;"
248
246
  elsif link.ref_table_name == "cases"
249
247
  puts "when '#{table.uid}' then return _r.#{link.column_name};"
250
248
  elsif link.ref_table_name == "events" && table.domain == "event"
251
249
  puts "when '#{table.uid}' then return _r.#{link.column_name};"
250
+ elsif link.ref_table_name == "visits" && table.domain == "visit"
251
+ puts "when '#{table.uid}' then return _r.#{link.column_name};"
252
252
  else
253
253
  ref_record = spec[link.ref_table_name]&.record_name or next
254
254
  id_of_function = "#{acl_schema}.#{domain_id_field}_of_#{ref_record}"
@@ -276,9 +276,8 @@ module MkAcl
276
276
  declare
277
277
  _id integer;
278
278
  begin
279
- select coalesce(acl_portal.event_id_of(_r), acl_portal.case_id_of(_r))
279
+ select coalesce(acl_portal.visit_id_of(_r), acl_portal.event_id_of(_r), acl_portal.case_id_of(_r))
280
280
  into _id;
281
-
282
281
  return _id;
283
282
  end;
284
283
  $$ language plpgsql
@@ -11,59 +11,128 @@ module MkAcl
11
11
  end
12
12
 
13
13
  def generate
14
- generate_role_functions
14
+ generate_user_role_functions
15
+ generate_current_role_functions
15
16
  end
16
17
 
17
18
  def self.generate(generator) self.new(generator).generate end
18
-
19
+
19
20
  private
20
- def generate_role_functions
21
+ def generate_user_role_functions
21
22
  # TODO: Test. Then combine with per-table methods
22
- signature = "public.current_is_role(_case_id integer, _roles text[])"
23
+ signature = "#{acl_schema}.user_is_role(_user_id integer, _domain_id integer, _roles text[])"
23
24
  puts %(
25
+ -- Return true if the user possess one or more of the given roles on the
26
+ -- domain record (cases, events, visits) with the given ID
27
+ --
24
28
  drop function if exists #{signature} cascade;
25
29
  create function #{signature} returns boolean as $$
26
- select exists(
30
+ select exists (
27
31
  select
28
32
  from #{app_schema}.case_roles cr
29
33
  join #{app_schema}.case_role_users cru on cru.case_role_id = cr.id
30
- where cr.case_id = _case_id
31
- and cru.user_id = public.current_user_id()
34
+ where cr.case_id = _domain_id
35
+ and cru.user_id = _user_id
36
+ and cr.kind = any(_roles)
37
+
38
+ union
39
+
40
+ select
41
+ from #{app_schema}.event_roles cr
42
+ join #{app_schema}.event_role_users cru on cru.event_role_id = cr.id
43
+ where cr.event_id = _domain_id
44
+ and cru.user_id = _user_id
32
45
  and cr.kind = any(_roles)
46
+
47
+ union
48
+
49
+ select
50
+ from #{app_schema}.visit_roles cr
51
+ join #{app_schema}.visit_role_users cru on cru.visit_role_id = cr.id
52
+ where cr.visit_id = _domain_id
53
+ and cru.user_id = _user_id
54
+ and cr.kind = any(_roles)
55
+
33
56
  );
34
57
  $$ language sql
35
58
  security definer;
36
59
  ).align
37
60
  puts
38
61
 
39
- signature = "public.current_is_role(_case_id integer, role text)"
62
+ signature = "#{acl_schema}.user_is_role(_user_id integer, _domain_id integer, role text)"
63
+ puts %(
64
+ -- Return true if the user has the given role on the domain record
65
+ -- (cases, events, visits). Note that this function overloads the multi-role
66
+ -- version
67
+ --
68
+ drop function if exists #{signature} cascade;
69
+ create function #{signature} returns boolean as $$
70
+ select #{acl_schema}.user_is_role(_user_id, _domain_id, array[role]);
71
+ $$ language sql
72
+ security definer;
73
+ ).align
74
+ puts
75
+
76
+ for domain, roles in DOMAINS.zip([CASE_ROLES, EVENT_ROLES, VISIT_ROLES])
77
+ for role in roles
78
+ signature = "#{acl_schema}.user_is_#{role.downcase}(_user_id integer, _domain_id integer)"
79
+ puts %(
80
+ -- Return true if the user possess the '#{role}' role
81
+ --
82
+ drop function if exists #{signature} cascade;
83
+ create function #{signature} returns boolean as $$
84
+ select #{acl_schema}.user_is_role(_user_id, _domain_id, '#{role}');
85
+ $$ language sql
86
+ security definer;
87
+ ).align
88
+ puts
89
+ end
90
+ end
91
+ end
92
+
93
+ def generate_current_role_functions
94
+ # TODO: Test. Then combine with per-table methods
95
+ signature = "public.current_is_role(_domain_id integer, _roles text[])"
96
+ puts %(
97
+ -- Return true if the current user possess one or more of the given roles on the
98
+ -- domain record (cases, events, visits) with the given ID
99
+ --
100
+ drop function if exists #{signature} cascade;
101
+ create function #{signature} returns boolean as $$
102
+ select #{acl_schema}.user_is_role(public.current_user_id(), _domain_id, _roles);
103
+ $$ language sql
104
+ security definer;
105
+ ).align
106
+ puts
107
+
108
+ signature = "public.current_is_role(_domain_id integer, _role text)"
40
109
  puts %(
110
+ -- Return true if the current user possess the given role on the domain record
111
+ -- (cases, events, visits). Note that this function overloads the multi-role
112
+ -- version
113
+ --
41
114
  drop function if exists #{signature} cascade;
42
115
  create function #{signature} returns boolean as $$
43
- select public.current_is_role(_case_id, array[role]);
116
+ select #{acl_schema}.user_is_role(public.current_user_id(), _domain_id, array[_role]);
44
117
  $$ language sql
45
118
  security definer;
46
119
  ).align
47
120
  puts
48
121
 
49
- for role in MkAcl::ROLES
50
- name = role.downcase
51
- signature = "public.current_is_#{name}(_case_id integer)"
52
- puts %(
53
- drop function if exists #{signature} cascade;
54
- create function #{signature} returns boolean as $$
55
- select exists(
56
- select
57
- from #{app_schema}.case_roles cr
58
- join #{app_schema}.case_role_users cru on cru.case_role_id = cr.id
59
- where cr.case_id = _case_id
60
- and cru.user_id = public.current_user_id()
61
- and cr.kind = '#{role}'
62
- );
63
- $$ language sql
64
- security definer;
65
- ).align
66
- puts
122
+ for domain, roles in DOMAINS.zip([CASE_ROLES, EVENT_ROLES, VISIT_ROLES])
123
+ for role in roles
124
+ signature = "public.current_is_#{role.downcase}(_domain_id integer)"
125
+ puts %(
126
+ -- Return true if the current user possess the '#{role}' role
127
+ --
128
+ drop function if exists #{signature} cascade;
129
+ create function #{signature} returns boolean as $$
130
+ select #{acl_schema}.user_is_role(public.current_user_id(), _domain_id, '#{role}');
131
+ $$ language sql
132
+ security definer;
133
+ ).align
134
+ puts
135
+ end
67
136
  end
68
137
  end
69
138
  end
@@ -6,7 +6,7 @@ module MkAcl
6
6
  # problem is that a record that fails the rule check is silently ignored
7
7
  # which is probably not what you want
8
8
  #
9
- # The roles matches a acl_* array against a role action entry in the spec
9
+ # The roles matches an acl_* array against a role action entry in the spec
10
10
  # file. The acl_* arrays are themselves array of role ids. Each subarray is
11
11
  # indexed using the order in the acl.spec file
12
12
  #
@@ -14,7 +14,7 @@ module MkAcl
14
14
  def parse_spec
15
15
  hash = YAML.load(IO.read(file), symbolize_names: true)
16
16
 
17
- schema = hash.delete(:schema) or raise ArgumentError, "Can't find 'schema' declaration"
17
+ schema = hash.delete(:schema) or raise ArgumentError, "Can't find 'schema' declaration in #{file}"
18
18
  app_schema = schema[:app] or raise ArgumentError, "Can't find 'schema.app' attribute"
19
19
  acl_schema = schema[:acl] or raise ArgumentError, "Can't find 'schema.acl' attribute"
20
20
  spec = Spec.new(file, app_schema, acl_schema)
@@ -9,7 +9,14 @@ require 'prick-inflector'
9
9
  module MkAcl
10
10
  class ParseError < RuntimeError; end
11
11
 
12
- ROLES = %w(LA TA KON AKK)
12
+ DOMAINS = %w(case event visit)
13
+ DOMAIN_TABLES = DOMAINS.map { "#{_1}s" }
14
+
15
+ CASE_ROLES = %w(LA TA KON AKK RLA CLA CTA)
16
+ EVENT_ROLES = %w(ELA ETA)
17
+ VISIT_ROLES = %w(VLA VTA)
18
+
19
+ ROLES = CASE_ROLES + EVENT_ROLES + VISIT_ROLES
13
20
  end
14
21
 
15
22
  require_relative 'mkacl/spec.rb'
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MikrasUtils
4
- VERSION = "0.1.1"
4
+ VERSION = "0.3.0"
5
5
  end
data/tests/acl.fox CHANGED
@@ -35,7 +35,7 @@ cases
35
35
  name: case3
36
36
 
37
37
  role_kinds
38
- - kind: RES
38
+ - kind: RLA
39
39
  acl: true
40
40
  ordinal: 1
41
41
  - kind: LA
@@ -62,7 +62,7 @@ role_kinds
62
62
  ordinal: 9
63
63
 
64
64
  case_role_templates
65
- - role: RES
65
+ - role: RLA
66
66
  - role: LA
67
67
  - role: TA
68
68
  - role: CLA
@@ -73,7 +73,7 @@ case_role_templates
73
73
  case_roles
74
74
  - &case1_res
75
75
  case: *case1
76
- role: RES
76
+ role: RLA
77
77
  - &case1_la
78
78
  case: *case1
79
79
  role: LA
@@ -95,7 +95,7 @@ case_roles
95
95
 
96
96
  - &case2_res
97
97
  case: *case2
98
- role: RES
98
+ role: RLA
99
99
  - &case2_la
100
100
  case: *case2
101
101
  role: LA
@@ -117,7 +117,7 @@ case_roles
117
117
 
118
118
  - &case3_res
119
119
  case: *case3
120
- role: RES
120
+ role: RLA
121
121
  - &case3_la
122
122
  case: *case3
123
123
  role: LA
data/tests/acl.spec CHANGED
@@ -16,7 +16,7 @@ cases:
16
16
  select: internal TA KON AKK
17
17
  update:
18
18
  - role: admin
19
- - role: RES CLA
19
+ - role: RLA CLA
20
20
  exclude: serial ident name
21
21
  delete: admin
22
22
 
@@ -2,7 +2,6 @@
2
2
 
3
3
  set search_path to app_portal;
4
4
 
5
- /*
6
5
 
7
6
  -- Union of case_roles and event_roles
8
7
  drop view if exists acl_portal.domain_roles cascade;
@@ -24,6 +23,7 @@ create view acl_portal.domain_roles as
24
23
  app_portal.event_roles
25
24
  ;
26
25
 
26
+ /*
27
27
  -- Union of case_role_users and event_users
28
28
  drop view if exists acl_portal.domain_users cascade;
29
29
  create view acl_portal.domain_users as
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.1
4
+ version: 0.3.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: 2024-07-08 00:00:00.000000000 Z
11
+ date: 2024-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pg_conn