lex-governance 0.2.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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3189a600f236fa9cc937e52c9c5591b62e8c99468d061b9eb4fdc69c3ee26d04
|
|
4
|
+
data.tar.gz: 1d55e9b3727a66c33e7414a19719c5326387abe784ca8a1d88e52e73ac1f2778
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bd0099e5d6c31ede525c9fdb9856d70101bba628b7ffa99acdd863c81d3cd5549ce57c2ec35a668329b07886e6b17919fe3b871fd962bd83f669ffff4557348d
|
|
7
|
+
data.tar.gz: 8f894c7e5624de924d69a1eb3a30c0fd21bab6d8d1eacb20a1e042a6c699c4f97ccb2bb2f8c333c28bf6d44a8c6f4cd828fabfcb522a60c9d599810078b03088
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module Governance
|
|
6
|
+
module Helpers
|
|
7
|
+
module Authority
|
|
8
|
+
AUTHORITY_REQUIRED = {
|
|
9
|
+
%w[active paused] => :owner_or_manager,
|
|
10
|
+
%w[paused active] => :owner_or_manager,
|
|
11
|
+
%w[active retired] => :owner_or_manager
|
|
12
|
+
}.freeze
|
|
13
|
+
|
|
14
|
+
module_function
|
|
15
|
+
|
|
16
|
+
def check_authority(principal_id:, from_state:, to_state:, worker_owner: nil, **)
|
|
17
|
+
required = authority_for(from_state, to_state)
|
|
18
|
+
return { allowed: true, reason: :no_authority_required } unless required
|
|
19
|
+
return { allowed: true, reason: :system_principal } if principal_id == 'system'
|
|
20
|
+
return { allowed: false, reason: :authority_required, required: required } if principal_id.nil?
|
|
21
|
+
|
|
22
|
+
case required
|
|
23
|
+
when :owner_or_manager
|
|
24
|
+
if principal_id == worker_owner
|
|
25
|
+
{ allowed: true, reason: :owner_match }
|
|
26
|
+
else
|
|
27
|
+
{ allowed: false, reason: :authority_required, required: required,
|
|
28
|
+
principal_id: principal_id, worker_owner: worker_owner }
|
|
29
|
+
end
|
|
30
|
+
else
|
|
31
|
+
{ allowed: false, reason: :authority_required, required: required }
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def authority_for(from_state, to_state)
|
|
36
|
+
AUTHORITY_REQUIRED[[from_state, to_state]]
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module Governance
|
|
6
|
+
module Helpers
|
|
7
|
+
module Council
|
|
8
|
+
module_function
|
|
9
|
+
|
|
10
|
+
def council_approved?(worker_id:, from_state:, to_state:, **)
|
|
11
|
+
return { allowed: true, reason: :audit_not_loaded } unless defined?(Legion::Extensions::Audit::Runners::ApprovalQueue)
|
|
12
|
+
|
|
13
|
+
record = find_approved_record(worker_id: worker_id, from_state: from_state, to_state: to_state)
|
|
14
|
+
if record
|
|
15
|
+
{ allowed: true, reason: :council_approved, approval_id: record[:id] }
|
|
16
|
+
else
|
|
17
|
+
{ allowed: false, reason: :council_approval_required,
|
|
18
|
+
worker_id: worker_id, from_state: from_state, to_state: to_state }
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def submit_approval(worker_id:, from_state:, to_state:, requester_id:, **)
|
|
23
|
+
unless defined?(Legion::Extensions::Audit::Runners::ApprovalQueue)
|
|
24
|
+
return { success: false, reason: :audit_not_loaded }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
Legion::Extensions::Audit::Runners::ApprovalQueue.submit(
|
|
28
|
+
approval_type: 'lifecycle_transition',
|
|
29
|
+
payload: { worker_id: worker_id, from_state: from_state, to_state: to_state },
|
|
30
|
+
requester_id: requester_id
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def find_approved_record(**)
|
|
35
|
+
nil
|
|
36
|
+
rescue StandardError
|
|
37
|
+
nil
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -5,6 +5,23 @@ module Legion
|
|
|
5
5
|
module Governance
|
|
6
6
|
module Runners
|
|
7
7
|
module Governance
|
|
8
|
+
def review_transition(worker_id:, from_state:, to_state:, principal_id: nil, worker_owner: nil, **)
|
|
9
|
+
return { allowed: true, skipped: true } unless governance_enabled?
|
|
10
|
+
|
|
11
|
+
results = []
|
|
12
|
+
results << check_airb_approval(worker_id: worker_id)
|
|
13
|
+
results << check_council_approval(worker_id: worker_id, from_state: from_state, to_state: to_state)
|
|
14
|
+
results << check_authority_level(principal_id: principal_id, from_state: from_state, to_state: to_state,
|
|
15
|
+
worker_owner: worker_owner)
|
|
16
|
+
|
|
17
|
+
blocked = results.reject { |r| r[:allowed] }
|
|
18
|
+
return { allowed: true, checks: results } if blocked.empty?
|
|
19
|
+
|
|
20
|
+
auto = try_auto_submit(blocked, worker_id: worker_id, from_state: from_state, to_state: to_state,
|
|
21
|
+
requester_id: principal_id || 'system')
|
|
22
|
+
{ allowed: false, reasons: blocked.map { |r| r[:reason] }, checks: results, auto_submitted: auto }
|
|
23
|
+
end
|
|
24
|
+
|
|
8
25
|
def check_airb_approval(worker_id:, **)
|
|
9
26
|
require_relative '../helpers/airb'
|
|
10
27
|
record = Helpers::Airb.fetch(worker_id: worker_id)
|
|
@@ -21,6 +38,72 @@ module Legion
|
|
|
21
38
|
reason: allowed ? :airb_cleared : :airb_blocked
|
|
22
39
|
}
|
|
23
40
|
end
|
|
41
|
+
|
|
42
|
+
def check_council_approval(worker_id:, from_state:, to_state:, **)
|
|
43
|
+
require_relative '../helpers/council'
|
|
44
|
+
required = council_required?(from_state, to_state)
|
|
45
|
+
return { allowed: true, reason: :no_council_required } unless required
|
|
46
|
+
|
|
47
|
+
Helpers::Council.council_approved?(worker_id: worker_id, from_state: from_state, to_state: to_state)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def check_authority_level(principal_id:, from_state:, to_state:, worker_owner: nil, **)
|
|
51
|
+
require_relative '../helpers/authority'
|
|
52
|
+
Helpers::Authority.check_authority(
|
|
53
|
+
principal_id: principal_id, from_state: from_state, to_state: to_state,
|
|
54
|
+
worker_owner: worker_owner
|
|
55
|
+
)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def governance_enabled?
|
|
59
|
+
gov = Legion::Settings[:governance]
|
|
60
|
+
return false if gov.is_a?(Hash) && gov.key?(:enabled) && gov[:enabled] == false
|
|
61
|
+
|
|
62
|
+
if Legion::Settings.dig(:governance, :bypass_in_dev) && Legion::Settings.respond_to?(:dev_mode?) && Legion::Settings.dev_mode?
|
|
63
|
+
return false
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
true
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def auto_submit?
|
|
70
|
+
gov = Legion::Settings[:governance]
|
|
71
|
+
return true unless gov.is_a?(Hash) && gov.key?(:auto_submit_approval)
|
|
72
|
+
|
|
73
|
+
gov[:auto_submit_approval]
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def council_required_transitions
|
|
77
|
+
Legion::Settings.dig(:governance, :council, :required_transitions)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
|
|
82
|
+
def try_auto_submit(blocked, worker_id:, from_state:, to_state:, requester_id:)
|
|
83
|
+
return false unless auto_submit? && blocked.any? { |r| r[:reason] == :council_approval_required }
|
|
84
|
+
|
|
85
|
+
require_relative '../helpers/council'
|
|
86
|
+
Helpers::Council.submit_approval(worker_id: worker_id, from_state: from_state, to_state: to_state,
|
|
87
|
+
requester_id: requester_id)
|
|
88
|
+
true
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def council_required?(from_state, to_state)
|
|
92
|
+
custom = council_required_transitions
|
|
93
|
+
if custom
|
|
94
|
+
custom.any? { |pair| pair == [from_state, to_state] }
|
|
95
|
+
else
|
|
96
|
+
governance_required_defaults.key?([from_state, to_state])
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def governance_required_defaults
|
|
101
|
+
if defined?(Legion::DigitalWorker::Lifecycle::GOVERNANCE_REQUIRED)
|
|
102
|
+
Legion::DigitalWorker::Lifecycle::GOVERNANCE_REQUIRED
|
|
103
|
+
else
|
|
104
|
+
{ %w[retired terminated] => :council_approval, %w[active terminated] => :council_approval }
|
|
105
|
+
end
|
|
106
|
+
end
|
|
24
107
|
end
|
|
25
108
|
end
|
|
26
109
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lex-governance
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Esity
|
|
@@ -18,6 +18,8 @@ extra_rdoc_files: []
|
|
|
18
18
|
files:
|
|
19
19
|
- lib/legion/extensions/governance.rb
|
|
20
20
|
- lib/legion/extensions/governance/helpers/airb.rb
|
|
21
|
+
- lib/legion/extensions/governance/helpers/authority.rb
|
|
22
|
+
- lib/legion/extensions/governance/helpers/council.rb
|
|
21
23
|
- lib/legion/extensions/governance/runners/governance.rb
|
|
22
24
|
- lib/legion/extensions/governance/version.rb
|
|
23
25
|
homepage: https://github.com/LegionIO
|