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

LibreSign / libresign / 25449810140

06 May 2026 05:08PM UTC coverage: 56.831%. First build
25449810140

Pull #7661

github

web-flow
Merge 8533c1232 into 5705a0e39
Pull Request #7661: refactor: use default DataResponse success constructor in id docs

1 of 2 new or added lines in 1 file covered. (50.0%)

10728 of 18877 relevant lines covered (56.83%)

6.97 hits per line

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

33.33
/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\Service\IdDocsService;
16
use OCA\Libresign\Service\SignFileService;
17
use OCP\AppFramework\Http;
18
use OCP\AppFramework\Http\Attribute\AnonRateLimit;
19
use OCP\AppFramework\Http\Attribute\ApiRoute;
20
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
21
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
22
use OCP\AppFramework\Http\Attribute\PublicPage;
23
use OCP\AppFramework\Http\DataResponse;
24
use OCP\IL10N;
25
use OCP\IRequest;
26
use OCP\IUserSession;
27
use Psr\Log\LoggerInterface;
28

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

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

99
        /**
100
         * Delete file from account
101
         *
102
         * @param int $nodeId the nodeId of file to be delete
103
         * @param string|null $uuid Sign request UUID for unauthenticated access
104
         *
105
         * @return DataResponse<Http::STATUS_OK, array<empty>, array{}>|DataResponse<Http::STATUS_UNAUTHORIZED, LibresignMessagesResponse, array{}>
106
         *
107
         * 200: File deleted with success
108
         * 401: Failure to delete file from account
109
         */
110
        #[PublicPage]
111
        #[AnonRateLimit(limit: 30, period: 60)]
112
        #[NoAdminRequired]
113
        #[NoCSRFRequired]
114
        #[RequireSignRequestUuid(skipIfAuthenticated: true)]
115
        #[ApiRoute(verb: 'DELETE', url: '/api/{apiVersion}/id-docs/{nodeId}', requirements: ['apiVersion' => '(v1)'])]
116
        public function delete(int $nodeId, ?string $uuid = null): DataResponse {
117
                try {
118
                        if ($user = $this->userSession->getUser()) {
×
119
                                $this->idDocsService->deleteIdDoc($nodeId, $user);
×
120
                        } elseif ($signRequest = $this->getSignRequestEntity()) {
×
121
                                $this->idDocsService->deleteIdDocBySignRequest($nodeId, $signRequest);
×
122
                        } else {
123
                                throw new Exception('Invalid data');
×
124
                        }
NEW
125
                        return new DataResponse();
×
126
                } catch (\Exception $exception) {
×
127
                        return new DataResponse(
×
128
                                [
×
129
                                        'messages' => [
×
130
                                                $exception->getMessage(),
×
131
                                        ],
×
132
                                ],
×
133
                                Http::STATUS_UNAUTHORIZED,
×
134
                        );
×
135
                }
136
        }
137

138
        /**
139
         * List files of unauthenticated account
140
         *
141
         * @param string|null $userId User ID to filter by
142
         * @param int|null $signRequestId Sign request ID to filter by
143
         * @param int|null $page the number of page to return
144
         * @param int|null $length Total of elements to return
145
         * @return DataResponse<Http::STATUS_OK, LibresignIdDocsListResponse, array{}>|DataResponse<Http::STATUS_NOT_FOUND, LibresignMessageResponse, array{}>
146
         *
147
         * 200: Certificate saved with success
148
         * 404: No file provided or other problem with provided file
149
         */
150
        #[PublicPage]
151
        #[AnonRateLimit(limit: 30, period: 60)]
152
        #[NoCSRFRequired]
153
        #[RequireSignRequestUuid(skipIfAuthenticated: true)]
154
        #[ApiRoute(verb: 'GET', url: '/api/{apiVersion}/id-docs', requirements: ['apiVersion' => '(v1)'])]
155
        public function listOfUnauthenticatedSigner(
156
                ?string $userId = null,
157
                ?int $signRequestId = null,
158
                ?int $page = null,
159
                ?int $length = null,
160
        ): DataResponse {
161
                try {
162
                        if ($user = $this->userSession->getUser()) {
×
163
                                $userId = $user->getUID();
×
164
                        } elseif ($signRequest = $this->getSignRequestEntity()) {
×
165
                                $signRequestId = $signRequest->getId();
×
166
                        } elseif (!$userId && !$signRequestId) {
×
167
                                throw new Exception('Invalid data');
×
168
                        }
169

170
                        $filter = array_filter([
×
171
                                'userId' => $userId,
×
172
                                'signRequestId' => $signRequestId,
×
173
                        ], static fn ($var) => $var !== null);
×
174

175
                        $return = $this->idDocsService->list($filter, $page, $length);
×
176
                        return new DataResponse($return, Http::STATUS_OK);
×
177
                } catch (\Throwable $th) {
×
178
                        return new DataResponse(
×
179
                                [
×
180
                                        'message' => $th->getMessage()
×
181
                                ],
×
182
                                Http::STATUS_NOT_FOUND
×
183
                        );
×
184
                }
185
        }
186

187
        /**
188
         * List files that need to be approved
189
         *
190
         * @param string|null $userId User ID to filter by
191
         * @param int|null $signRequestId Sign request ID to filter by
192
         * @param int|null $page the number of page to return
193
         * @param int|null $length Total of elements to return
194
         * @param string|null $sortBy Sort field (e.g., 'owner', 'file_type', 'status')
195
         * @param string|null $sortOrder Sort order (ASC or DESC)
196
         * @return DataResponse<Http::STATUS_OK, LibresignIdDocsApprovalListResponse, array{}>|DataResponse<Http::STATUS_NOT_FOUND, LibresignMessageResponse, array{}>
197
         *
198
         * 200: OK
199
         * 404: Account not found
200
         */
201
        #[NoAdminRequired]
202
        #[NoCSRFRequired]
203
        #[ApiRoute(verb: 'GET', url: '/api/{apiVersion}/id-docs/approval/list', requirements: ['apiVersion' => '(v1)'])]
204
        public function listToApproval(
205
                ?string $userId = null,
206
                ?int $signRequestId = null,
207
                ?int $page = null,
208
                ?int $length = null,
209
                ?string $sortBy = null,
210
                ?string $sortOrder = null,
211
        ): DataResponse {
212
                try {
213
                        $this->validateHelper->userCanApproveValidationDocuments($this->userSession->getUser());
1✔
214
                        $filter = array_filter([
1✔
215
                                'userId' => $userId,
1✔
216
                                'signRequestId' => $signRequestId,
1✔
217
                        ], static fn ($var) => $var !== null);
1✔
218
                        $sort = [];
1✔
219
                        if ($sortBy !== null) {
1✔
220
                                $sort[$sortBy] = $sortOrder ?? 'DESC';
×
221
                        }
222
                        $return = $this->idDocsService->list($filter, $page, $length, $sort);
1✔
223
                        return new DataResponse($return, Http::STATUS_OK);
1✔
224
                } catch (\Throwable $th) {
×
225
                        return new DataResponse(
×
226
                                [
×
227
                                        'message' => $th->getMessage()
×
228
                                ],
×
229
                                Http::STATUS_NOT_FOUND
×
230
                        );
×
231
                }
232
        }
233
}
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