• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

LibreSign / libresign / 19861782503

02 Dec 2025 02:18PM UTC coverage: 40.755%. First build
19861782503

Pull #5919

github

web-flow
Merge 3045734d7 into 9adaadaec
Pull Request #5919: fix: document not visible after account creation

0 of 8 new or added lines in 1 file covered. (0.0%)

4977 of 12212 relevant lines covered (40.75%)

3.98 hits per line

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

24.06
/lib/Service/AccountService.php
1
<?php
2

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

9
namespace OCA\Libresign\Service;
10

11
use InvalidArgumentException;
12
use OC\Files\Filesystem;
13
use OCA\Libresign\AppInfo\Application;
14
use OCA\Libresign\Db\AccountFileMapper;
15
use OCA\Libresign\Db\File as FileEntity;
16
use OCA\Libresign\Db\FileMapper;
17
use OCA\Libresign\Db\FileTypeMapper;
18
use OCA\Libresign\Db\IdentifyMethodMapper;
19
use OCA\Libresign\Db\SignRequest;
20
use OCA\Libresign\Db\SignRequestMapper;
21
use OCA\Libresign\Db\UserElement;
22
use OCA\Libresign\Db\UserElementMapper;
23
use OCA\Libresign\Exception\InvalidPasswordException;
24
use OCA\Libresign\Exception\LibresignException;
25
use OCA\Libresign\Handler\CertificateEngine\CertificateEngineFactory;
26
use OCA\Libresign\Handler\SignEngine\Pkcs12Handler;
27
use OCA\Libresign\Helper\ValidateHelper;
28
use OCA\Settings\Mailer\NewUserMailHelper;
29
use OCP\Accounts\IAccountManager;
30
use OCP\AppFramework\Db\DoesNotExistException;
31
use OCP\AppFramework\Utility\ITimeFactory;
32
use OCP\Files\Config\IMountProviderCollection;
33
use OCP\Files\File;
34
use OCP\Files\IMimeTypeDetector;
35
use OCP\Files\IRootFolder;
36
use OCP\Files\NotFoundException;
37
use OCP\Http\Client\IClientService;
38
use OCP\IAppConfig;
39
use OCP\IConfig;
40
use OCP\IGroupManager;
41
use OCP\IL10N;
42
use OCP\IURLGenerator;
43
use OCP\IUser;
44
use OCP\IUserManager;
45
use Sabre\DAV\UUIDUtil;
46
use Throwable;
47

48
class AccountService {
49
        private ?SignRequest $signRequest = null;
50
        private ?\OCA\Libresign\Db\File $fileData = null;
51
        private \OCP\Files\File $fileToSign;
52

53
        public function __construct(
54
                private IL10N $l10n,
55
                private SignRequestMapper $signRequestMapper,
56
                private IUserManager $userManager,
57
                private IAccountManager $accountManager,
58
                private IRootFolder $root,
59
                private IMimeTypeDetector $mimeTypeDetector,
60
                private FileMapper $fileMapper,
61
                private FileTypeMapper $fileTypeMapper,
62
                private AccountFileMapper $accountFileMapper,
63
                private SignFileService $signFileService,
64
                private RequestSignatureService $requestSignatureService,
65
                private CertificateEngineFactory $certificateEngineFactory,
66
                private IConfig $config,
67
                private IAppConfig $appConfig,
68
                private IMountProviderCollection $mountProviderCollection,
69
                private NewUserMailHelper $newUserMail,
70
                private IdentifyMethodService $identifyMethodService,
71
                private IdentifyMethodMapper $identifyMethodMapper,
72
                private ValidateHelper $validateHelper,
73
                private IURLGenerator $urlGenerator,
74
                private Pkcs12Handler $pkcs12Handler,
75
                private IGroupManager $groupManager,
76
                private AccountFileService $accountFileService,
77
                private SignerElementsService $signerElementsService,
78
                private UserElementMapper $userElementMapper,
79
                private FolderService $folderService,
80
                private IClientService $clientService,
81
                private ITimeFactory $timeFactory,
82
        ) {
83
        }
41✔
84

85
        public function validateCreateToSign(array $data): void {
86
                if (!UUIDUtil::validateUUID($data['uuid'])) {
1✔
87
                        throw new LibresignException($this->l10n->t('Invalid UUID'), 1);
1✔
88
                }
89
                try {
90
                        $signRequest = $this->getSignRequestByUuid($data['uuid']);
×
91
                } catch (\Throwable) {
×
92
                        throw new LibresignException($this->l10n->t('UUID not found'), 1);
×
93
                }
94
                $identifyMethods = $this->identifyMethodService->getIdentifyMethodsFromSignRequestId($signRequest->getId());
×
95
                if (!array_key_exists('identify', $data['user'])) {
×
96
                        throw new LibresignException($this->l10n->t('Invalid identification method'), 1);
×
97
                }
98
                foreach ($data['user']['identify'] as $method => $value) {
×
99
                        if (!array_key_exists($method, $identifyMethods)) {
×
100
                                throw new LibresignException($this->l10n->t('Invalid identification method'), 1);
×
101
                        }
102
                        foreach ($identifyMethods[$method] as $identifyMethod) {
×
103
                                $identifyMethod->validateToCreateAccount($value);
×
104
                        }
105
                }
106
                if (empty($data['password'])) {
×
107
                        throw new LibresignException($this->l10n->t('Password is mandatory'), 1);
×
108
                }
109
                $file = $this->getFileByUuid($data['uuid']);
×
110
                if (empty($file['fileToSign'])) {
×
111
                        throw new LibresignException($this->l10n->t('File not found'));
×
112
                }
113
        }
114

115
        public function getFileByUuid(string $uuid): array {
116
                $signRequest = $this->getSignRequestByUuid($uuid);
×
117
                if (!$this->fileData instanceof \OCA\Libresign\Db\File) {
×
118
                        $this->fileData = $this->fileMapper->getById($signRequest->getFileId());
×
119

120
                        $nodeId = $this->fileData->getNodeId();
×
121

122
                        $fileToSign = $this->root->getUserFolder($this->fileData->getUserId())->getFirstNodeById($nodeId);
×
123
                        if ($fileToSign) {
×
124
                                $this->fileToSign = $fileToSign;
×
125
                        }
126
                }
127
                return [
×
128
                        'fileData' => $this->fileData,
×
129
                        'fileToSign' => $this->fileToSign
×
130
                ];
×
131
        }
132

133
        public function validateCertificateData(array $data): void {
134
                if (array_key_exists('email', $data['user']) && empty($data['user']['email'])) {
4✔
135
                        throw new LibresignException($this->l10n->t('You must have an email. You can define the email in your profile.'), 1);
1✔
136
                }
137
                if (!empty($data['user']['email']) && !filter_var($data['user']['email'], FILTER_VALIDATE_EMAIL)) {
3✔
138
                        throw new LibresignException($this->l10n->t('Invalid email'), 1);
1✔
139
                }
140
                if (empty($data['signPassword'])) {
2✔
141
                        throw new LibresignException($this->l10n->t('Password to sign is mandatory'), 1);
1✔
142
                }
143
        }
144

145
        public function validateAccountFiles(array $files, IUser $user): void {
146
                foreach ($files as $fileIndex => $file) {
5✔
147
                        $this->validateAccountFile($fileIndex, $file, $user);
5✔
148
                }
149
        }
150

151
        private function validateAccountFile(int $fileIndex, array $file, IUser $user): void {
152
                $profileFileTypes = $this->fileTypeMapper->getTypes();
5✔
153
                if (!array_key_exists($file['type'], $profileFileTypes)) {
5✔
154
                        throw new LibresignException(json_encode([
2✔
155
                                'type' => 'danger',
2✔
156
                                'file' => $fileIndex,
2✔
157
                                'message' => $this->l10n->t('Invalid file type.')
2✔
158
                        ]));
2✔
159
                }
160

161
                try {
162
                        $this->validateHelper->validateFileTypeExists($file['type']);
3✔
163
                        $this->validateHelper->validateNewFile($file, ValidateHelper::TYPE_ACCOUNT_DOCUMENT, $user);
3✔
164
                        $this->validateHelper->validateUserHasNoFileWithThisType($user->getUID(), $file['type']);
3✔
165
                } catch (\Exception $e) {
×
166
                        throw new LibresignException(json_encode([
×
167
                                'type' => 'danger',
×
168
                                'file' => $fileIndex,
×
169
                                'message' => $e->getMessage()
×
170
                        ]));
×
171
                }
172
        }
173

174
        /**
175
         * Get signRequest by Uuid
176
         */
177
        public function getSignRequestByUuid(string $uuid): SignRequest {
178
                if (!$this->signRequest instanceof SignRequest) {
1✔
179
                        $this->signRequest = $this->signRequestMapper->getByUuid($uuid);
1✔
180
                }
181
                return $this->signRequest;
1✔
182
        }
183

184
        public function createToSign(string $uuid, string $email, string $password, ?string $signPassword): void {
185
                $signRequest = $this->getSignRequestByUuid($uuid);
1✔
186

187
                $newUser = $this->userManager->createUser($email, $password);
1✔
188
                $newUser->setDisplayName($signRequest->getDisplayName());
1✔
189
                $newUser->setSystemEMailAddress($email);
1✔
190

191
                // Update identify method from email to account after user creation
192
                $identifyMethods = $this->identifyMethodService->getIdentifyMethodsFromSignRequestId($signRequest->getId());
1✔
193
                foreach ($identifyMethods as $name => $methods) {
1✔
194
                        if ($name === IdentifyMethodService::IDENTIFY_EMAIL) {
×
195
                                foreach ($methods as $identifyMethod) {
×
196
                                        $entity = $identifyMethod->getEntity();
×
197
                                        if ($entity->getIdentifierValue() === $email) {
×
198
                                                $entity->setIdentifierKey(IdentifyMethodService::IDENTIFY_ACCOUNT);
×
199
                                                $entity->setIdentifierValue($newUser->getUID());
×
200
                                                $this->identifyMethodMapper->update($entity);
×
201
                                        }
202
                                }
203
                        }
204
                }
205

206
                if ($this->config->getAppValue('core', 'newUser.sendEmail', 'yes') === 'yes') {
1✔
207
                        try {
208
                                $emailTemplate = $this->newUserMail->generateTemplate($newUser, false);
1✔
209
                                $this->newUserMail->sendMail($newUser, $emailTemplate);
1✔
210
                        } catch (\Exception) {
1✔
211
                                throw new LibresignException('Unable to send the invitation', 1);
1✔
212
                        }
213
                }
214

215
                if ($signPassword) {
×
216
                        $certificate = $this->pkcs12Handler->generateCertificate(
×
217
                                [
×
218
                                        'host' => $newUser->getPrimaryEMailAddress(),
×
219
                                        'uid' => 'account:' . $newUser->getUID(),
×
220
                                        'name' => $newUser->getDisplayName()
×
221
                                ],
×
222
                                $signPassword,
×
223
                                $newUser->getDisplayName()
×
224
                        );
×
225
                        $this->pkcs12Handler->savePfx($newUser->getPrimaryEMailAddress(), $certificate);
×
226
                }
227
        }
228

229
        public function getCertificateEngineName(): string {
230
                return $this->certificateEngineFactory->getEngine()->getName();
×
231
        }
232

233
        /**
234
         * @return array[]
235
         */
236
        public function getConfig(?IUser $user = null): array {
237
                $info['identificationDocumentsFlow'] = $this->appConfig->getValueBool(Application::APP_ID, 'identification_documents', false);
×
238
                $info['hasSignatureFile'] = $this->hasSignatureFile($user);
×
239
                $info['phoneNumber'] = $this->getPhoneNumber($user);
×
240
                $info['isApprover'] = $this->validateHelper->userCanApproveValidationDocuments($user, false);
×
241
                $info['grid_view'] = $this->getUserConfigGridView($user);
×
242

NEW
243
                if ($user && $this->groupManager->isAdmin($user->getUID())) {
×
NEW
244
                        $info = array_filter(array_merge($info, [
×
NEW
245
                                'crl_filters' => $this->getUserConfigCrlFilters($user),
×
NEW
246
                                'crl_sort' => $this->getUserConfigCrlSort($user),
×
NEW
247
                        ]));
×
248
                }
249

NEW
250
                return $info;
×
251
        }
252

253

254

255
        private function getPhoneNumber(?IUser $user): string {
NEW
256
                if (!$user) {
×
NEW
257
                        return '';
×
258
                }
259
                $userAccount = $this->accountManager->getAccount($user);
×
260
                return $userAccount->getProperty(IAccountManager::PROPERTY_PHONE)->getValue();
×
261
        }
262

263
        public function hasSignatureFile(?IUser $user = null): bool {
264
                if (!$user) {
4✔
265
                        return false;
×
266
                }
267
                try {
268
                        $this->pkcs12Handler->getPfxOfCurrentSigner($user->getUID());
4✔
269
                        return true;
×
270
                } catch (LibresignException) {
4✔
271
                        return false;
4✔
272
                }
273
        }
274

275
        private function getUserConfigGridView(?IUser $user = null): bool {
276
                if (!$user) {
×
277
                        return false;
×
278
                }
279

280
                return $this->config->getUserValue($user->getUID(), Application::APP_ID, 'grid_view', false) === '1';
×
281
        }
282

283
        private function getUserConfigCrlFilters(?IUser $user = null): array {
284
                if (!$user) {
×
285
                        return [];
×
286
                }
287

288
                $value = $this->config->getUserValue($user->getUID(), Application::APP_ID, 'crl_filters', '');
×
289
                if (empty($value)) {
×
290
                        return [];
×
291
                }
292

293
                $decoded = json_decode($value, true);
×
294
                return is_array($decoded) ? $decoded : [];
×
295
        }
296

297
        private function getUserConfigCrlSort(?IUser $user = null): array {
298
                if (!$user) {
×
299
                        return ['sortBy' => 'revoked_at', 'sortOrder' => 'DESC'];
×
300
                }
301

302
                $value = $this->config->getUserValue($user->getUID(), Application::APP_ID, 'crl_sort', '');
×
303
                if (empty($value)) {
×
304
                        return ['sortBy' => 'revoked_at', 'sortOrder' => 'DESC'];
×
305
                }
306

307
                $decoded = json_decode($value, true);
×
308
                return is_array($decoded) ? $decoded : ['sortBy' => 'revoked_at', 'sortOrder' => 'DESC'];
×
309
        }
310

311
        /**
312
         * Get PDF node by UUID
313
         *
314
         * @psalm-suppress MixedReturnStatement
315
         * @throws Throwable
316
         * @return \OCP\Files\File
317
         */
318
        public function getPdfByUuid(string $uuid): File {
319
                $fileData = $this->fileMapper->getByUuid($uuid);
2✔
320

321
                if (in_array($fileData->getStatus(), [FileEntity::STATUS_PARTIAL_SIGNED, FileEntity::STATUS_SIGNED])) {
2✔
322
                        $nodeId = $fileData->getSignedNodeId();
2✔
323
                } else {
324
                        $nodeId = $fileData->getNodeId();
×
325
                }
326
                $file = $this->root->getUserFolder($fileData->getUserId())->getFirstNodeById($nodeId);
2✔
327
                if (!$file instanceof File) {
2✔
328
                        throw new DoesNotExistException('Not found');
×
329
                }
330
                return $file;
2✔
331
        }
332

333
        public function getFileByNodeId(int $nodeId): File {
334
                try {
335
                        return $this->folderService->getFileById($nodeId);
×
336
                } catch (NotFoundException) {
×
337
                        throw new DoesNotExistException('Not found');
×
338
                }
339
        }
340

341
        public function canRequestSign(?IUser $user = null): bool {
342
                if (!$user) {
8✔
343
                        return false;
1✔
344
                }
345
                $authorized = $this->appConfig->getValueArray(Application::APP_ID, 'groups_request_sign', ['admin']);
7✔
346
                if (empty($authorized)) {
7✔
347
                        return false;
1✔
348
                }
349
                $userGroups = $this->groupManager->getUserGroupIds($user);
6✔
350
                if (!array_intersect($userGroups, $authorized)) {
6✔
351
                        return false;
3✔
352
                }
353
                return true;
3✔
354
        }
355

356
        public function getSettings(?IUser $user = null): array {
357
                $return['canRequestSign'] = $this->canRequestSign($user);
4✔
358
                $return['hasSignatureFile'] = $this->hasSignatureFile($user);
4✔
359
                return $return;
4✔
360
        }
361

362
        public function addFilesToAccount(array $files, IUser $user): void {
363
                $this->validateAccountFiles($files, $user);
3✔
364
                foreach ($files as $fileData) {
2✔
365
                        $dataToSave = $fileData;
2✔
366
                        $dataToSave['userManager'] = $user;
2✔
367
                        $dataToSave['name'] = $fileData['name'] ?? $fileData['type'];
2✔
368
                        $file = $this->requestSignatureService->saveFile($dataToSave);
2✔
369

370
                        $this->accountFileService->addFile($file, $user, $fileData['type']);
2✔
371
                }
372
        }
373

374
        public function deleteFileFromAccount(int $nodeId, IUser $user): void {
375
                $this->validateHelper->validateAccountFileIsOwnedByUser($nodeId, $user->getUID());
×
376
                $accountFile = $this->accountFileMapper->getByUserIdAndNodeId($user->getUID(), $nodeId);
×
377
                $this->accountFileService->deleteFile($accountFile->getFileId(), $user->getUID());
×
378
        }
379

380
        public function saveVisibleElements(array $elements, string $sessionId, ?IUser $user): void {
381
                foreach ($elements as $element) {
×
382
                        $this->saveVisibleElement($element, $sessionId, $user);
×
383
                }
384
        }
385

386
        public function saveVisibleElement(array $data, string $sessionId, ?IUser $user): void {
387
                if (isset($data['elementId'])) {
×
388
                        $this->updateFileOfVisibleElement($data);
×
389
                        $this->updateDataOfVisibleElement($data);
×
390
                } elseif ($user instanceof IUser) {
×
391
                        $file = $this->saveFileOfVisibleElementUsingUser($data, $user);
×
392
                        $this->insertVisibleElement($data, $user, $file);
×
393
                } else {
394
                        $file = $this->saveFileOfVisibleElementUsingSession($data, $sessionId);
×
395
                }
396
        }
397

398
        private function updateFileOfVisibleElement(array $data): void {
399
                if (!isset($data['file'])) {
×
400
                        return;
×
401
                }
402
                $userElement = $this->userElementMapper->findOne(['id' => $data['elementId']]);
×
403
                $file = $this->folderService->getFileById($userElement->getFileId());
×
404
                $file->putContent($this->getFileRaw($data));
×
405
        }
406

407
        private function updateDataOfVisibleElement(array $data): void {
408
                if (!isset($data['starred'])) {
×
409
                        return;
×
410
                }
411
                $userElement = $this->userElementMapper->findOne(['id' => $data['elementId']]);
×
412
                $userElement->setStarred($data['starred'] ? 1 : 0);
×
413
                $this->userElementMapper->update($userElement);
×
414
        }
415

416
        private function saveFileOfVisibleElementUsingUser(array $data, IUser $user): File {
417
                $rootSignatureFolder = $this->folderService->getFolder();
×
418
                $folderName = $this->folderService->getFolderName($data, $user);
×
419
                $folderToFile = $rootSignatureFolder->newFolder($folderName);
×
420
                return $folderToFile->newFile(UUIDUtil::getUUID() . '.png', $this->getFileRaw($data));
×
421
        }
422

423
        private function saveFileOfVisibleElementUsingSession(array $data, string $sessionId): File {
424
                if (!empty($data['nodeId'])) {
×
425
                        return $this->updateFileOfVisibleElementUsingSession($data, $sessionId);
×
426
                }
427
                return $this->createFileOfVisibleElementUsingSession($data, $sessionId);
×
428
        }
429

430
        private function updateFileOfVisibleElementUsingSession(array $data, string $sessionId): File {
431
                $fileList = $this->signerElementsService->getElementsFromSession();
×
432
                $element = array_filter($fileList, fn (File $element) => $element->getId() === $data['nodeId']);
×
433
                $element = current($element);
×
434
                if (!$element instanceof File) {
×
435
                        throw new \Exception($this->l10n->t('File not found'));
×
436
                }
437
                $element->putContent($this->getFileRaw($data));
×
438
                return $element;
×
439
        }
440

441
        private function createFileOfVisibleElementUsingSession(array $data, string $sessionId): File {
442
                $rootSignatureFolder = $this->folderService->getFolder();
×
443
                $folderName = $sessionId;
×
444
                $folderToFile = $rootSignatureFolder->newFolder($folderName);
×
445
                $filename = implode(
×
446
                        '_',
×
447
                        [
×
448
                                $data['type'],
×
449
                                $this->timeFactory->getDateTime()->getTimestamp(),
×
450
                        ]
×
451
                ) . '.png';
×
452
                return $folderToFile->newFile($filename, $this->getFileRaw($data));
×
453
        }
454

455
        private function insertVisibleElement(array $data, IUser $user, File $file): void {
456
                $userElement = new UserElement();
×
457
                $userElement->setType($data['type']);
×
458
                $userElement->setFileId($file->getId());
×
459
                $userElement->setUserId($user->getUID());
×
460
                $userElement->setStarred(isset($data['starred']) && $data['starred'] ? 1 : 0);
×
461
                $userElement->setCreatedAt($this->timeFactory->getDateTime());
×
462
                $this->userElementMapper->insert($userElement);
×
463
        }
464

465
        private function getFileRaw(array $data): string {
466
                if (!empty($data['file']['url'])) {
×
467
                        if (!filter_var($data['file']['url'], FILTER_VALIDATE_URL)) {
×
468
                                throw new \Exception($this->l10n->t('Invalid URL file'));
×
469
                        }
470
                        $response = $this->clientService->newClient()->get($data['file']['url']);
×
471
                        $contentType = $response->getHeader('Content-Type');
×
472
                        if ($contentType !== 'image/png') {
×
473
                                throw new \Exception($this->l10n->t('Visible element file must be png.'));
×
474
                        }
475
                        $content = (string)$response->getBody();
×
476
                        if (empty($content)) {
×
477
                                throw new \Exception($this->l10n->t('Empty file'));
×
478
                        }
479
                        $this->validateHelper->validateBase64($content, ValidateHelper::TYPE_VISIBLE_ELEMENT_USER);
×
480
                        return $content;
×
481
                }
482
                $this->validateHelper->validateBase64($data['file']['base64'], ValidateHelper::TYPE_VISIBLE_ELEMENT_USER);
×
483
                $withMime = explode(',', (string)$data['file']['base64']);
×
484
                if (count($withMime) === 2) {
×
485
                        $content = base64_decode($withMime[1]);
×
486
                } else {
487
                        $content = base64_decode((string)$data['file']['base64']);
×
488
                }
489
                if (!$content) {
×
490
                        return '';
×
491
                }
492
                return $content;
×
493
        }
494

495
        public function deleteSignatureElement(?IUser $user, string $sessionId, int $nodeId): void {
496
                if ($user instanceof IUser) {
×
497
                        $element = $this->userElementMapper->findOne([
×
498
                                'file_id' => $nodeId,
×
499
                                'user_id' => $user->getUID(),
×
500
                        ]);
×
501
                        $this->userElementMapper->delete($element);
×
502
                        try {
503
                                $file = $this->folderService->getFileById($element->getFileId());
×
504
                                $file->delete();
×
505
                        } catch (NotFoundException) {
×
506
                        }
507
                } else {
508
                        $rootSignatureFolder = $this->folderService->getFolder();
×
509
                        $folderName = $sessionId;
×
510
                        $rootSignatureFolder->delete($folderName);
×
511
                }
512
        }
513

514
        /**
515
         * @throws LibresignException at savePfx
516
         * @throws InvalidArgumentException
517
         */
518
        public function uploadPfx(array $file, IUser $user): void {
519
                if (
520
                        $file['error'] !== 0
×
521
                        || !is_uploaded_file($file['tmp_name'])
×
522
                        || Filesystem::isFileBlacklisted($file['tmp_name'])
×
523
                ) {
524
                        // TRANSLATORS Error when the uploaded certificate file is not valid
525
                        throw new InvalidArgumentException($this->l10n->t('Invalid file provided. Need to be a .pfx file.'));
×
526
                }
527
                if ($file['size'] > 10 * 1024) {
×
528
                        // TRANSLATORS Error when the certificate file is bigger than normal
529
                        throw new InvalidArgumentException($this->l10n->t('File is too big'));
×
530
                }
531
                $content = file_get_contents($file['tmp_name']);
×
532
                $mimetype = $this->mimeTypeDetector->detectString($content);
×
533
                if ($mimetype !== 'application/octet-stream') {
×
534
                        // TRANSLATORS Error when the mimetype of uploaded file is not valid
535
                        throw new InvalidArgumentException($this->l10n->t('Invalid file provided. Need to be a .pfx file.'));
×
536
                }
537
                $extension = strtolower(pathinfo((string)$file['name'], PATHINFO_EXTENSION));
×
538
                if ($extension !== 'pfx') {
×
539
                        // TRANSLATORS Error when the certificate file is not a pfx file
540
                        throw new InvalidArgumentException($this->l10n->t('Invalid file provided. Need to be a .pfx file.'));
×
541
                }
542
                unlink($file['tmp_name']);
×
543
                $this->pkcs12Handler->savePfx($user->getUID(), $content);
×
544
        }
545

546
        public function deletePfx(IUser $user): void {
547
                $this->pkcs12Handler->deletePfx($user->getUID());
×
548
        }
549

550
        /**
551
         * @throws LibresignException when have not a certificate file
552
         */
553
        public function updatePfxPassword(IUser $user, string $current, string $new): void {
554
                try {
555
                        $pfx = $this->pkcs12Handler->updatePassword($user->getUID(), $current, $new);
×
556
                } catch (InvalidPasswordException) {
×
557
                        throw new LibresignException($this->l10n->t('Invalid user or password'));
×
558
                }
559
        }
560

561
        /**
562
         * @throws LibresignException when have not a certificate file
563
         */
564
        public function readPfxData(IUser $user, string $password): array {
565
                try {
566
                        return $this->pkcs12Handler
×
567
                                ->setCertificate($this->pkcs12Handler->getPfxOfCurrentSigner($user->getUID()))
×
568
                                ->setPassword($password)
×
569
                                ->readCertificate();
×
570
                } catch (InvalidPasswordException) {
×
571
                        throw new LibresignException($this->l10n->t('Invalid user or password'));
×
572
                }
573
        }
574
}
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