Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
92.31% covered (success)
92.31%
48 / 52
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
IdentificationDocumentsPolicy
92.31% covered (success)
92.31%
48 / 52
50.00% covered (danger)
50.00%
1 / 2
16.12
0.00% covered (danger)
0.00%
0 / 1
 keys
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 get
91.84% covered (success)
91.84%
45 / 49
0.00% covered (danger)
0.00%
0 / 1
15.12
1<?php
2
3declare(strict_types=1);
4/**
5 * SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
6 * SPDX-License-Identifier: AGPL-3.0-or-later
7 */
8
9namespace OCA\Libresign\Service\Policy\Provider\IdentificationDocuments;
10
11use OCA\Libresign\Service\Policy\Contract\IPolicyDefinition;
12use OCA\Libresign\Service\Policy\Contract\IPolicyDefinitionProvider;
13use OCA\Libresign\Service\Policy\Model\PolicyContext;
14use OCA\Libresign\Service\Policy\Model\PolicyLayer;
15use OCA\Libresign\Service\Policy\Model\PolicySpec;
16use OCA\Libresign\Service\Policy\Provider\Helper\DelegationLayerHelper;
17use OCA\Libresign\Service\Policy\Provider\Helper\PolicyKeyNormalizer;
18
19final class IdentificationDocumentsPolicy implements IPolicyDefinitionProvider {
20    public const KEY = 'identification_documents';
21    public const SYSTEM_APP_CONFIG_KEY = 'identification_documents';
22
23    #[\Override]
24    public function keys(): array {
25        return [
26            self::KEY,
27        ];
28    }
29
30    #[\Override]
31    public function get(string|\BackedEnum $policyKey): IPolicyDefinition {
32        return match (PolicyKeyNormalizer::normalize($policyKey)) {
33            self::KEY => new PolicySpec(
34                key: self::KEY,
35                defaultSystemValue: [
36                    'enabled' => false,
37                    'approvers' => ['admin'],
38                ],
39                allowedValues: static fn (): array => [],
40                normalizer: static fn (mixed $rawValue): array => \OCA\Libresign\Service\Policy\Provider\IdentificationDocuments\IdentificationDocumentsPolicyValue::normalize($rawValue, false),
41                validator: static function (mixed $value): void {
42                    if (!is_array($value)) {
43                        throw new \InvalidArgumentException('Invalid value for ' . self::KEY);
44                    }
45                    if (!array_key_exists('enabled', $value)) {
46                        throw new \InvalidArgumentException('Missing "enabled" key in ' . self::KEY);
47                    }
48                    if (!array_key_exists('approvers', $value)) {
49                        throw new \InvalidArgumentException('Missing "approvers" key in ' . self::KEY);
50                    }
51                    if (!is_array($value['approvers'])) {
52                        throw new \InvalidArgumentException('Approvers must be an array');
53                    }
54                },
55                appConfigKey: self::SYSTEM_APP_CONFIG_KEY,
56                supportsRequestOverride: true,
57                requestLifecycle: PolicySpec::LIFECYCLE_REQUEST_SNAPSHOT,
58                groupPolicyManager: static function (PolicyContext $context, ?PolicyLayer $systemPolicy, array $groupLayers): bool {
59                    $actorRole = $context->getActorRole();
60                    if ($actorRole->canManageSystemPolicies) {
61                        return true;
62                    }
63
64                    if (!$actorRole->canManageGroupPolicies) {
65                        return false;
66                    }
67
68                    if ($actorRole->manageableGroupCount < 1) {
69                        return false;
70                    }
71
72                    return DelegationLayerHelper::hasExplicitGlobalDelegation($systemPolicy)
73                        || DelegationLayerHelper::hasSystemCreatedGroupDelegation($groupLayers);
74                },
75                systemCreatedGroupRuleEditor: static function (PolicyContext $context, ?PolicyLayer $systemPolicy, PolicyLayer $existingPolicy): bool {
76                    $actorRole = $context->getActorRole();
77                    if ($actorRole->canManageSystemPolicies) {
78                        return true;
79                    }
80
81                    if (!$actorRole->canManageGroupPolicies) {
82                        return false;
83                    }
84
85                    if (!$existingPolicy->isVisibleToChild() || !$existingPolicy->isAllowChildOverride() || $existingPolicy->getValue() === null) {
86                        return false;
87                    }
88
89                    if (DelegationLayerHelper::hasExplicitGlobalDelegation($systemPolicy)) {
90                        return true;
91                    }
92
93                    return $existingPolicy->isCreatedBySystemAdmin();
94                },
95                supportsGroupAdminDelegation: true,
96            ),
97            default => throw new \InvalidArgumentException('Unknown policy key: ' . PolicyKeyNormalizer::normalize($policyKey)),
98        };
99    }
100
101}