mikras_utils 0.2.0 → 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: 3a66c5d0dcdafd3fb71c101b1cb02d5acb3ebe464418c070ed98c9e192301a45
4
- data.tar.gz: 6bf90eead1cf7fd35b8a5082bae1a68cc6aec3a8ef158f025d6f3643c49f0f8f
3
+ metadata.gz: '039c1d561f66158183511f72a09ce9b76b3de0c7110d8e6aadce11b338985209'
4
+ data.tar.gz: dae3de2a17dd845f6a350ec3b63636e97ff2b565a75d40bd47e429abe5654668
5
5
  SHA512:
6
- metadata.gz: 8339a0a8a6f4180aa26b3f1430ce722d3f399d45b9875e59dfa0ace4086dcd9db82dc8b8b2c66596b52391e4140e0475bfb033b29470ee71cc2de000c138b0c1
7
- data.tar.gz: 525550b69df7f1151f6f617c4cf9b9f5f034501cff135d2de268ed2d76c7e393f57b8aa3cf68f8e768d03dfd04669cea9c81536891c0c73b645f4e00493eeaf8
6
+ metadata.gz: 4651ae8fc80806930718c561c94ae10547d80654802cb88f19020b020871d5de73cd4b736ad98755f63333f8262c44a438ab6134d87d9f51989d68e5ed1bee43
7
+ data.tar.gz: 05a47f398922d45c61e3746c28a5fae17a334e38c9a7eb4a35dbdd4764d4d86dcd57b293fa14b6600e80da5f54b26a65aada13e3679ed56aa670107b457e4ebf
@@ -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(RLA LA TA KON AKK CLA CTA ELA ETA)
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.2.0"
4
+ VERSION = "0.3.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.2.0
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