Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
75 / 75
100.00% covered (success)
100.00%
13 / 13
CRAP
100.00% covered (success)
100.00%
1 / 1
AccountSettingsProvider
100.00% covered (success)
100.00%
75 / 75
100.00% covered (success)
100.00%
13 / 13
38
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSettings
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 getPhoneNumber
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 hasSignatureFile
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getConfig
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
4
 getConfigFilters
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 getConfigSorting
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
 getUserConfigByKey
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getUserConfigJsonByKey
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
4
 getUserConfigIdDocsFilters
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
4
 getUserConfigCrlFilters
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
5
 getUserConfigCrlSort
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
5
 getUserConfigIdDocsSort
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
5
1<?php
2
3declare(strict_types=1);
4
5/**
6 * SPDX-FileCopyrightText: 2025 LibreCode coop and contributors
7 * SPDX-License-Identifier: AGPL-3.0-or-later
8 */
9
10namespace OCA\Libresign\Service\File;
11
12use OCA\Libresign\AppInfo\Application;
13use OCA\Libresign\Service\AccountCertificateService;
14use OCA\Libresign\Service\IdDocsPolicyService;
15use OCA\Libresign\Service\Policy\PolicyAuthorizationService;
16use OCA\Libresign\Service\Validation\IdentityDocumentValidator;
17use OCP\Accounts\IAccountManager;
18use OCP\Config\IUserConfig;
19use OCP\IGroupManager;
20use OCP\IUser;
21
22/** @psalm-import-type LibresignAccountCapabilitySettings from \OCA\Libresign\ResponseDefinitions */
23class AccountSettingsProvider {
24    public function __construct(
25        private IAccountManager $accountManager,
26        private IdDocsPolicyService $idDocsPolicyService,
27        private AccountCertificateService $accountCertificateService,
28        private IUserConfig $userConfig,
29        private IGroupManager $groupManager,
30        private PolicyAuthorizationService $policyAuthorizationService,
31        private IdentityDocumentValidator $identityDocumentValidator,
32    ) {
33    }
34
35    /** @psalm-return LibresignAccountCapabilitySettings */
36    public function getSettings(?IUser $user = null): array {
37        $canApproveIdDocs = $this->idDocsPolicyService->userCanApproveValidationDocuments($user, false);
38
39        return [
40            'canRequestSign' => $canApproveIdDocs,
41            'hasSignatureFile' => $this->hasSignatureFile($user),
42            'isApprover' => $canApproveIdDocs,
43        ];
44    }
45
46    public function getPhoneNumber(?IUser $user): string {
47        if (!$user) {
48            return '';
49        }
50        $userAccount = $this->accountManager->getAccount($user);
51        return $userAccount->getProperty(IAccountManager::PROPERTY_PHONE)->getValue();
52    }
53
54    public function hasSignatureFile(?IUser $user = null): bool {
55        return $this->accountCertificateService->hasSignatureFile($user);
56    }
57
58    /**
59     * @return array<string, mixed>
60     */
61    public function getConfig(?IUser $user = null): array {
62        $info['identificationDocumentsFlow'] = $this->idDocsPolicyService->isIdentificationDocumentsEnabled($user);
63        $info['hasSignatureFile'] = $this->hasSignatureFile($user);
64        $info['phoneNumber'] = $this->getPhoneNumber($user);
65        $info['isApprover'] = $this->identityDocumentValidator->userCanApproveValidationDocuments($user, false);
66        $info['id_docs_filters'] = $this->getUserConfigIdDocsFilters($user);
67        $info['id_docs_sort'] = $this->getUserConfigIdDocsSort($user);
68        $info['crl_filters'] = $this->getUserConfigCrlFilters($user);
69        $info['crl_sort'] = $this->getUserConfigCrlSort($user);
70        $info['files_list_grid_view'] = $this->getUserConfigByKey('files_list_grid_view', $user) === '1';
71        $info['files_list_signer_identify_tab'] = $this->getUserConfigByKey('files_list_signer_identify_tab', $user);
72        $info['files_list_sorting_mode'] = $this->getUserConfigByKey('files_list_sorting_mode', $user) ?: 'name';
73        $info['files_list_sorting_direction'] = $this->getUserConfigByKey('files_list_sorting_direction', $user) ?: 'asc';
74        $info['policy_workbench_catalog_compact_view'] = $this->getUserConfigByKey('policy_workbench_catalog_compact_view', $user) === '1';
75        $info['policy_workbench_catalog_collapsed'] = $this->getUserConfigByKey('policy_workbench_catalog_collapsed', $user) === '1';
76        $info['policy_workbench_category_collapsed_state'] = $this->getUserConfigJsonByKey('policy_workbench_category_collapsed_state', $user);
77        $info['warn_without_visible_signature_fields'] = $this->getUserConfigByKey('warn_without_visible_signature_fields', $user) !== '0';
78        $info['can_manage_group_policies'] = $this->policyAuthorizationService->canUserManageGroupPolicies($user);
79        $info['manageable_policy_group_ids'] = $this->policyAuthorizationService->getManageablePolicyGroupIds($user);
80
81        return array_filter($info, static fn (mixed $value): bool => $value !== null && $value !== '');
82    }
83
84    public function getConfigFilters(?IUser $user = null): array {
85        $info['files_list_filter_modified'] = $this->getUserConfigByKey('files_list_filter_modified', $user);
86        $info['files_list_filter_status'] = $this->getUserConfigByKey('files_list_filter_status', $user);
87
88        return $info;
89    }
90
91    public function getConfigSorting(?IUser $user = null): array {
92        $info['files_list_sorting_mode'] = $this->getUserConfigByKey('files_list_sorting_mode', $user) ?: 'name';
93        $info['files_list_sorting_direction'] = $this->getUserConfigByKey('files_list_sorting_direction', $user) ?: 'asc';
94
95        return $info;
96    }
97
98    private function getUserConfigByKey(string $key, ?IUser $user = null): string {
99        if (!$user) {
100            return '';
101        }
102        return $this->userConfig->getValueString($user->getUID(), Application::APP_ID, $key);
103    }
104
105    /**
106     * @return array<string, mixed>|null
107     */
108    private function getUserConfigJsonByKey(string $key, ?IUser $user = null): ?array {
109        if (!$user) {
110            return null;
111        }
112
113        $value = $this->userConfig->getValueString($user->getUID(), Application::APP_ID, $key, '');
114        if (empty($value)) {
115            return null;
116        }
117
118        $decoded = json_decode($value, true);
119        return is_array($decoded) ? $decoded : null;
120    }
121
122    private function getUserConfigIdDocsFilters(?IUser $user = null): array {
123        if (!$user) {
124            return [];
125        }
126
127        $value = $this->userConfig->getValueString($user->getUID(), Application::APP_ID, 'id_docs_filters', '');
128        if (empty($value)) {
129            return [];
130        }
131
132        $decoded = json_decode($value, true);
133        return is_array($decoded) ? $decoded : [];
134    }
135
136    private function getUserConfigCrlFilters(?IUser $user = null): array {
137        if (!$user || !$this->groupManager->isAdmin($user->getUID())) {
138            return [];
139        }
140
141        $value = $this->userConfig->getValueString($user->getUID(), Application::APP_ID, 'crl_filters', '');
142        if (empty($value)) {
143            return [];
144        }
145
146        $decoded = json_decode($value, true);
147        return is_array($decoded) ? $decoded : [];
148    }
149
150    private function getUserConfigCrlSort(?IUser $user): array {
151        if (!$user || !$this->groupManager->isAdmin($user->getUID())) {
152            return ['sortBy' => 'revoked_at', 'sortOrder' => 'DESC'];
153        }
154
155        $value = $this->userConfig->getValueString($user->getUID(), Application::APP_ID, 'crl_sort', '');
156        if (empty($value)) {
157            return ['sortBy' => 'revoked_at', 'sortOrder' => 'DESC'];
158        }
159
160        $decoded = json_decode($value, true);
161        return is_array($decoded) ? $decoded : ['sortBy' => 'revoked_at', 'sortOrder' => 'DESC'];
162    }
163
164    private function getUserConfigIdDocsSort(?IUser $user): array {
165        if (!$user || !$this->identityDocumentValidator->userCanApproveValidationDocuments($user, false)) {
166            return ['sortBy' => null, 'sortOrder' => null];
167        }
168
169        $value = $this->userConfig->getValueString($user->getUID(), Application::APP_ID, 'id_docs_sort', '');
170        if (empty($value)) {
171            return ['sortBy' => null, 'sortOrder' => null];
172        }
173
174        $decoded = json_decode($value, true);
175        return is_array($decoded) ? $decoded : ['sortBy' => null, 'sortOrder' => null];
176    }
177}