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

LibreSign / libresign / 19868313373

02 Dec 2025 05:50PM UTC coverage: 41.522%. First build
19868313373

Pull #4464

github

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

89 of 246 new or added lines in 14 files covered. (36.18%)

5103 of 12290 relevant lines covered (41.52%)

4.18 hits per line

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

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

NEW
157
                        $filter = array_filter([
×
NEW
158
                                'userId' => $userId,
×
NEW
159
                                'signRequestId' => $signRequestId,
×
NEW
160
                        ], static fn ($var) => $var !== null);
×
161

NEW
162
                        $return = $this->idDocsService->list($filter, $page, $length);
×
NEW
163
                        return new DataResponse($return, Http::STATUS_OK);
×
NEW
164
                } catch (\Throwable $th) {
×
NEW
165
                        return new DataResponse(
×
NEW
166
                                [
×
NEW
167
                                        'message' => $th->getMessage()
×
NEW
168
                                ],
×
NEW
169
                                Http::STATUS_NOT_FOUND
×
NEW
170
                        );
×
171
                }
172
        }
173

174
        /**
175
         * List files that need to be approved
176
         *
177
         * @param string|null $userId User ID to filter by
178
         * @param int|null $signRequestId Sign request ID to filter by
179
         * @param int|null $page the number of page to return
180
         * @param int|null $length Total of elements to return
181
         * @return DataResponse<Http::STATUS_OK, array{pagination: LibresignPagination, data: ?LibresignFile[]}, array{}>|DataResponse<Http::STATUS_NOT_FOUND, array{message: string}, array{}>
182
         *
183
         * 200: OK
184
         * 404: Account not found
185
         */
186
        #[NoAdminRequired]
187
        #[NoCSRFRequired]
188
        #[ApiRoute(verb: 'GET', url: '/api/{apiVersion}/id-docs/approval/list', requirements: ['apiVersion' => '(v1)'])]
189
        public function listToApproval(
190
                ?string $userId = null,
191
                ?int $signRequestId = null,
192
                ?int $page = null,
193
                ?int $length = null,
194
        ): DataResponse {
195
                try {
196
                        $this->validateHelper->userCanApproveValidationDocuments($this->userSession->getUser());
1✔
197
                        $filter = array_filter([
1✔
198
                                'userId' => $userId,
1✔
199
                                'signRequestId' => $signRequestId,
1✔
200
                        ], static fn ($var) => $var !== null);
1✔
201
                        $return = $this->idDocsService->list($filter, $page, $length);
1✔
202
                        return new DataResponse($return, Http::STATUS_OK);
1✔
NEW
203
                } catch (\Throwable $th) {
×
NEW
204
                        return new DataResponse(
×
NEW
205
                                [
×
NEW
206
                                        'message' => $th->getMessage()
×
NEW
207
                                ],
×
NEW
208
                                Http::STATUS_NOT_FOUND
×
NEW
209
                        );
×
210
                }
211
        }
212
}
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