Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
98.08% covered (success)
98.08%
51 / 52
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
ConfettiPolicy
98.08% covered (success)
98.08%
51 / 52
50.00% covered (danger)
50.00%
1 / 2
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
97.96% covered (success)
97.96%
48 / 49
0.00% covered (danger)
0.00%
0 / 1
11
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\Confetti;
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 ConfettiPolicy implements IPolicyDefinitionProvider {
20    public const KEY = 'show_confetti_after_signing';
21    public const SYSTEM_APP_CONFIG_KEY = self::KEY;
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: true,
36                allowedValues: [
37                    false,
38                    true,
39                ],
40                normalizer: static fn (mixed $rawValue): bool => filter_var($rawValue, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) ?? false,
41                appConfigKey: self::SYSTEM_APP_CONFIG_KEY,
42                supportsRequestOverride: true,
43                requestLifecycle: PolicySpec::LIFECYCLE_RUNTIME,
44                supportedScopes: [
45                    PolicySpec::SCOPE_SYSTEM,
46                    PolicySpec::SCOPE_GROUP,
47                    PolicySpec::SCOPE_USER,
48                ],
49                groupPolicyManager: static function (PolicyContext $context, ?PolicyLayer $systemPolicy, array $groupLayers): bool {
50                    $actorRole = $context->getActorRole();
51
52                    if ($actorRole->canManageSystemPolicies) {
53                        return true;
54                    }
55
56                    if (!$actorRole->canManageGroupPolicies) {
57                        return false;
58                    }
59
60                    if ($actorRole->manageableGroupCount < 1) {
61                        return false;
62                    }
63
64                    if (DelegationLayerHelper::hasExplicitGlobalDelegation($systemPolicy)) {
65                        return true;
66                    }
67
68                    return DelegationLayerHelper::hasSystemCreatedGroupDelegation($groupLayers);
69                },
70                systemCreatedGroupRuleEditor: static function (PolicyContext $context, ?PolicyLayer $systemPolicy, PolicyLayer $existingPolicy): bool {
71                    $actorRole = $context->getActorRole();
72
73                    if ($actorRole->canManageSystemPolicies) {
74                        return true;
75                    }
76
77                    if (!$actorRole->canManageGroupPolicies) {
78                        return false;
79                    }
80
81                    if (!$existingPolicy->isVisibleToChild()) {
82                        return false;
83                    }
84
85                    if (!$existingPolicy->isAllowChildOverride()) {
86                        return false;
87                    }
88
89                    if ($existingPolicy->getValue() === null) {
90                        return false;
91                    }
92
93                    if (DelegationLayerHelper::hasExplicitGlobalDelegation($systemPolicy)) {
94                        return true;
95                    }
96
97                    return $existingPolicy->isCreatedBySystemAdmin();
98                },
99                supportsGroupAdminDelegation: true,
100            ),
101            default => throw new \InvalidArgumentException('Unknown policy key: ' . PolicyKeyNormalizer::normalize($policyKey)),
102        };
103    }
104
105}