Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
35 / 35
100.00% covered (success)
100.00%
6 / 6
CRAP
100.00% covered (success)
100.00%
1 / 1
WorkerConfigPolicy
100.00% covered (success)
100.00%
35 / 35
100.00% covered (success)
100.00%
6 / 6
10
100.00% covered (success)
100.00%
1 / 1
 keys
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
1
 defaultValue
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 normalizeValue
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
5
 encodeDefault
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 encodeNormalized
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
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\Worker;
10
11use OCA\Libresign\Service\Policy\Contract\IPolicyDefinition;
12use OCA\Libresign\Service\Policy\Contract\IPolicyDefinitionProvider;
13use OCA\Libresign\Service\Policy\Model\PolicySpec;
14
15final class WorkerConfigPolicy implements IPolicyDefinitionProvider {
16    public const KEY = 'worker_config';
17    public const SYSTEM_APP_CONFIG_KEY = 'worker_config';
18
19    private const DEFAULT_WORKER_TYPE = 'local';
20    private const DEFAULT_PARALLEL_WORKERS = 4;
21    private const MIN_PARALLEL_WORKERS = 1;
22    private const MAX_PARALLEL_WORKERS = 32;
23
24    #[\Override]
25    public function keys(): array {
26        return [self::KEY];
27    }
28
29    #[\Override]
30    public function get(string|\BackedEnum $policyKey): IPolicyDefinition {
31        return new PolicySpec(
32            key: self::KEY,
33            defaultSystemValue: $this->encodeDefault(),
34            allowedValues: [],
35            normalizer: fn (mixed $rawValue): string => $this->encodeNormalized($rawValue),
36            appConfigKey: self::SYSTEM_APP_CONFIG_KEY,
37            supportsUserPreference: false,
38            supportsRequestOverride: false,
39            requestLifecycle: PolicySpec::LIFECYCLE_RUNTIME,
40            supportedScopes: [PolicySpec::SCOPE_SYSTEM],
41            helper: true,
42            parentPolicyKey: SigningModePolicy::KEY_SIGNING_MODE,
43        );
44    }
45
46    /**
47     * @return array{worker_type: string, parallel_workers: int}
48     */
49    public function defaultValue(): array {
50        return [
51            'worker_type' => self::DEFAULT_WORKER_TYPE,
52            'parallel_workers' => self::DEFAULT_PARALLEL_WORKERS,
53        ];
54    }
55
56    /**
57     * @return array{worker_type: string, parallel_workers: int}
58     */
59    public function normalizeValue(mixed $rawValue): array {
60        if (is_string($rawValue)) {
61            $decoded = json_decode($rawValue, true);
62            if (is_array($decoded)) {
63                $rawValue = $decoded;
64            }
65        }
66
67        if (!is_array($rawValue)) {
68            return $this->defaultValue();
69        }
70
71        $workerType = (string)($rawValue['worker_type'] ?? self::DEFAULT_WORKER_TYPE);
72        if (!in_array($workerType, ['local', 'external'], true)) {
73            $workerType = self::DEFAULT_WORKER_TYPE;
74        }
75
76        $parallelWorkers = (int)($rawValue['parallel_workers'] ?? self::DEFAULT_PARALLEL_WORKERS);
77        $parallelWorkers = max(self::MIN_PARALLEL_WORKERS, min(self::MAX_PARALLEL_WORKERS, $parallelWorkers));
78
79        return [
80            'worker_type' => $workerType,
81            'parallel_workers' => $parallelWorkers,
82        ];
83    }
84
85    private function encodeDefault(): string {
86        return json_encode($this->defaultValue(), JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES);
87    }
88
89    private function encodeNormalized(mixed $rawValue): string {
90        return json_encode($this->normalizeValue($rawValue), JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES);
91    }
92
93}