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

LibreSign / libresign / 19867129312

02 Dec 2025 05:10PM UTC coverage: 41.519%. First build
19867129312

Pull #4464

github

web-flow
Merge 4521e389d into 198609762
Pull Request #4464: refactor: attach document

85 of 242 new or added lines in 14 files covered. (35.12%)

5099 of 12281 relevant lines covered (41.52%)

4.18 hits per line

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

32.2
/lib/Controller/IdDocsController.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\Controller;
10

11
use Exception;
12
use OCA\Libresign\AppInfo\Application;
13
use OCA\Libresign\Helper\ValidateHelper;
14
use OCA\Libresign\Middleware\Attribute\RequireSignRequestUuid;
15
use OCA\Libresign\ResponseDefinitions;
16
use OCA\Libresign\Service\IdDocsService;
17
use OCA\Libresign\Service\SignFileService;
18
use OCP\AppFramework\Http;
19
use OCP\AppFramework\Http\Attribute\AnonRateLimit;
20
use OCP\AppFramework\Http\Attribute\ApiRoute;
21
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
22
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
23
use OCP\AppFramework\Http\Attribute\PublicPage;
24
use OCP\AppFramework\Http\DataResponse;
25
use OCP\IL10N;
26
use OCP\IRequest;
27
use OCP\IUserSession;
28
use Psr\Log\LoggerInterface;
29

30
/**
31
 * @psalm-import-type LibresignIdDocs from ResponseDefinitions
32
 * @psalm-import-type LibresignPagination from ResponseDefinitions
33
 * @psalm-import-type LibresignFile from ResponseDefinitions
34
 */
35
class IdDocsController extends AEnvironmentAwareController implements ISignatureUuid {
36
        use LibresignTrait;
37
        public function __construct(
38
                IRequest $request,
39
                protected SignFileService $signFileService,
40
                protected IL10N $l10n,
41
                protected IdDocsService $idDocsService,
42
                protected IUserSession $userSession,
43
                protected ValidateHelper $validateHelper,
44
                protected LoggerInterface $logger,
45
        ) {
46
                parent::__construct(Application::APP_ID, $request);
3✔
47
        }
48

49
        /**
50
         * Add identification documents to user profile
51
         *
52
         * @param LibresignIdDocs[] $files The list of files to add to profile
53
         * @return DataResponse<Http::STATUS_OK, array<empty>, array{}>|DataResponse<Http::STATUS_UNAUTHORIZED, array{file: ?int, type: 'info'|'warning'|'danger', message: string}, array{}>
54
         *
55
         * 200: Certificate saved with success
56
         * 401: No file provided or other problem with provided file
57
         */
58
        #[PublicPage]
59
        #[AnonRateLimit(limit: 30, period: 60)]
60
        #[NoAdminRequired]
61
        #[NoCSRFRequired]
62
        #[RequireSignRequestUuid(skipIfAuthenticated: true)]
63
        #[ApiRoute(verb: 'POST', url: '/api/{apiVersion}/id-docs', requirements: ['apiVersion' => '(v1)'])]
64
        public function addFiles(array $files): DataResponse {
65
                try {
66
                        if ($user = $this->userSession->getUser()) {
2✔
67
                                $this->idDocsService->addIdDocs($files, $user);
2✔
NEW
68
                        } elseif ($signRequest = $this->getSignRequestEntity()) {
×
NEW
69
                                $this->idDocsService->addFilesToDocumentFolder($files, $signRequest);
×
70
                        } else {
NEW
71
                                throw new Exception('Invalid data');
×
72
                        }
73
                        return new DataResponse([], Http::STATUS_OK);
1✔
74
                } catch (\Exception $exception) {
1✔
75
                        $exceptionData = json_decode($exception->getMessage());
1✔
76
                        if (isset($exceptionData->file)) {
1✔
77
                                $message = [
1✔
78
                                        'file' => $exceptionData->file,
1✔
79
                                        'type' => $exceptionData->type,
1✔
80
                                        'message' => $exceptionData->message
1✔
81
                                ];
1✔
82
                        } else {
NEW
83
                                $message = [
×
NEW
84
                                        'file' => null,
×
NEW
85
                                        'type' => null,
×
NEW
86
                                        'message' => $exception->getMessage()
×
NEW
87
                                ];
×
88
                        }
89
                        return new DataResponse(
1✔
90
                                $message,
1✔
91
                                Http::STATUS_UNAUTHORIZED
1✔
92
                        );
1✔
93
                }
94
        }
95

96
        /**
97
         * Delete file from account
98
         *
99
         * @param int $nodeId the nodeId of file to be delete
100
         *
101
         * @return DataResponse<Http::STATUS_OK, array<empty>, array{}>|DataResponse<Http::STATUS_UNAUTHORIZED, array{messages: string[]}, array{}>
102
         *
103
         * 200: File deleted with success
104
         * 401: Failure to delete file from account
105
         */
106
        #[NoAdminRequired]
107
        #[NoCSRFRequired]
108
        #[ApiRoute(verb: 'DELETE', url: '/api/{apiVersion}/id-docs', requirements: ['apiVersion' => '(v1)'])]
109
        public function deleteFile(int $nodeId): DataResponse {
110
                try {
NEW
111
                        $this->idDocsService->deleteIdDoc($nodeId, $this->userSession->getUser());
×
NEW
112
                        return new DataResponse([], Http::STATUS_OK);
×
NEW
113
                } catch (\Exception $exception) {
×
NEW
114
                        return new DataResponse(
×
NEW
115
                                [
×
NEW
116
                                        'messages' => [
×
NEW
117
                                                $exception->getMessage(),
×
NEW
118
                                        ],
×
NEW
119
                                ],
×
NEW
120
                                Http::STATUS_UNAUTHORIZED,
×
NEW
121
                        );
×
122
                }
123
        }
124

125
        /**
126
         * List files of unauthenticated account
127
         *
128
         * @param array<string, mixed> $filter Filter params
129
         * @param int|null $page the number of page to return
130
         * @param int|null $length Total of elements to return
131
         * @return DataResponse<Http::STATUS_OK, array{pagination: LibresignPagination, data: LibresignFile[]}, array{}>|DataResponse<Http::STATUS_NOT_FOUND, array{message: string}, array{}>
132
         *
133
         * 200: Certificate saved with success
134
         * 404: No file provided or other problem with provided file
135
         */
136
        #[PublicPage]
137
        #[AnonRateLimit(limit: 30, period: 60)]
138
        #[NoCSRFRequired]
139
        #[RequireSignRequestUuid(skipIfAuthenticated: true)]
140
        #[ApiRoute(verb: 'GET', url: '/api/{apiVersion}/id-docs', requirements: ['apiVersion' => '(v1)'])]
141
        public function listOfUnauthenticatedSigner(array $filter = [], ?int $page = null, ?int $length = null): DataResponse {
142
                try {
NEW
143
                        if ($user = $this->userSession->getUser()) {
×
NEW
144
                                $filter['userId'] = $user->getUID();
×
NEW
145
                        } elseif ($signRequest = $this->getSignRequestEntity()) {
×
NEW
146
                                $filter['signRequestId'] = $signRequest->getId();
×
147
                        } else {
NEW
148
                                throw new Exception('Invalid data');
×
149
                        }
150

NEW
151
                        $return = $this->idDocsService->list($filter, $page, $length);
×
NEW
152
                        return new DataResponse($return, Http::STATUS_OK);
×
NEW
153
                } catch (\Throwable $th) {
×
NEW
154
                        return new DataResponse(
×
NEW
155
                                [
×
NEW
156
                                        'message' => $th->getMessage()
×
NEW
157
                                ],
×
NEW
158
                                Http::STATUS_NOT_FOUND
×
NEW
159
                        );
×
160
                }
161
        }
162

163
        /**
164
         * List files that need to be approved
165
         *
166
         * @param array<string, mixed> $filter Filter params
167
         * @param int|null $page the number of page to return
168
         * @param int|null $length Total of elements to return
169
         * @return DataResponse<Http::STATUS_OK, array{pagination: LibresignPagination, data: ?LibresignFile[]}, array{}>|DataResponse<Http::STATUS_NOT_FOUND, array{message: string}, array{}>
170
         *
171
         * 200: OK
172
         * 404: Account not found
173
         */
174
        #[NoAdminRequired]
175
        #[NoCSRFRequired]
176
        #[ApiRoute(verb: 'GET', url: '/api/{apiVersion}/id-docs/approval/list', requirements: ['apiVersion' => '(v1)'])]
177
        public function listToApproval(array $filter = [], ?int $page = null, ?int $length = null): DataResponse {
178
                try {
179
                        $this->validateHelper->userCanApproveValidationDocuments($this->userSession->getUser());
1✔
180
                        $return = $this->idDocsService->list($filter, $page, $length);
1✔
181
                        return new DataResponse($return, Http::STATUS_OK);
1✔
NEW
182
                } catch (\Throwable $th) {
×
NEW
183
                        return new DataResponse(
×
NEW
184
                                [
×
NEW
185
                                        'message' => $th->getMessage()
×
NEW
186
                                ],
×
NEW
187
                                Http::STATUS_NOT_FOUND
×
NEW
188
                        );
×
189
                }
190
        }
191
}
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