• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In
Build has been canceled!

LibreSign / libresign / 19118950120

05 Nov 2025 10:58PM UTC coverage: 39.847%. First build
19118950120

Pull #5754

github

web-flow
Merge adfafab73 into 681cce019
Pull Request #5754: feat: preserve previous root cert

86 of 120 new or added lines in 10 files covered. (71.67%)

4633 of 11627 relevant lines covered (39.85%)

3.06 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.74
/lib/Service/CaIdentifierService.php
1
<?php
2

3
declare(strict_types=1);
4
/**
5
 * SPDX-FileCopyrightText: 2025 LibreCode coop and contributors
6
 * SPDX-License-Identifier: AGPL-3.0-or-later
7
 */
8

9
namespace OCA\Libresign\Service;
10

11
use OCA\Libresign\AppInfo\Application;
12
use OCP\IAppConfig;
13
use OCP\Security\ISecureRandom;
14

15
class CaIdentifierService {
16
        private const ENGINE_TYPES = [
17
                'openssl' => 'o',
18
                'cfssl' => 'c',
19
        ];
20

21
        public function __construct(
22
                private IAppConfig $appConfig,
23
        ) {
24
        }
65✔
25

26
        private function getInstanceId(): string {
27
                $instanceId = $this->appConfig->getValueString(Application::APP_ID, 'instance_id', '');
11✔
28
                if (strlen($instanceId) === 10) {
11✔
NEW
29
                        return $instanceId;
×
30
                }
31
                $instanceId = \OC::$server->get(ISecureRandom::class)->generate(10, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_DIGITS);
11✔
32
                $this->appConfig->setValueString(Application::APP_ID, 'instance_id', $instanceId);
11✔
33
                return $instanceId;
11✔
34
        }
35

36
        public function generateCaId(string $engineName): string {
37
                $instanceId = $this->getInstanceId();
11✔
38

39
                $generation = $this->getNextGeneration();
11✔
40

41
                $caId = sprintf(
11✔
42
                        'libresign-ca-id:%s_g:%d_e:%s',
11✔
43
                        $instanceId,
11✔
44
                        $generation,
11✔
45
                        self::ENGINE_TYPES[$engineName] ?? throw new \InvalidArgumentException("Invalid engine name: $engineName"),
11✔
46
                );
11✔
47
                $this->appConfig->setValueString(Application::APP_ID, 'ca_id', $caId);
11✔
48
                return $caId;
11✔
49
        }
50

51
        public function getCaId(): string {
52
                $caId = $this->appConfig->getValueString(Application::APP_ID, 'ca_id');
9✔
53
                return $caId;
9✔
54
        }
55

56
        public function isValidCaId(string $caId, string $instanceId): bool {
57
                $enginePattern = '[' . implode('', array_values(self::ENGINE_TYPES)) . ']';
6✔
58

59
                $newPattern = '/^libresign-ca-id:' . preg_quote($instanceId, '/') . '_g:\d+_e:' . $enginePattern . '$/';
6✔
60
                if (preg_match($newPattern, $caId)) {
6✔
61
                        return true;
3✔
62
                }
63
                return false;
3✔
64
        }
65

66
        public function generatePkiDirectoryName(string $caId): string {
67
                $parsed = $this->parseCaId($caId);
10✔
68
                return 'pki/' . $parsed['instanceId'] . '_' . $parsed['generation'] . '_' . $parsed['engineName'];
10✔
69
        }
70

71
        private function parseCaId(string $caId): array {
72
                $pattern = '/^libresign-ca-id:(?P<instanceId>[a-z0-9]+)_g:(?P<generation>\d+)_e:(?P<engineType>[' . implode('', array_values(self::ENGINE_TYPES)) . '])$/';
10✔
73
                if (!preg_match($pattern, $caId, $matches)) {
10✔
NEW
74
                        throw new \InvalidArgumentException('Invalid CA ID format');
×
75
                }
76
                $parsed['engineName'] = array_search($matches['engineType'], self::ENGINE_TYPES, true);
10✔
77
                $parsed['instanceId'] = $matches['instanceId'];
10✔
78
                $parsed['generation'] = (int)$matches['generation'];
10✔
79
                $parsed['engineType'] = $matches['engineType'];
10✔
80
                return $parsed;
10✔
81
        }
82

83
        private function getNextGeneration(): int {
84
                $currentNumber = $this->appConfig->getValueInt(Application::APP_ID, 'ca_generation_counter', 0);
11✔
85
                $nextNumber = $currentNumber + 1;
11✔
86
                $this->appConfig->setValueInt(Application::APP_ID, 'ca_generation_counter', $nextNumber);
11✔
87

88
                return $nextNumber;
11✔
89
        }
90
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc