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

LibreSign / libresign / 21521428053

30 Jan 2026 03:40PM UTC coverage: 47.504%. First build
21521428053

Pull #6647

github

web-flow
Merge 4800f8073 into 9f329c924
Pull Request #6647: feat: use contact and account phone

219 of 253 new or added lines in 9 files covered. (86.56%)

8183 of 17226 relevant lines covered (47.5%)

5.18 hits per line

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

0.0
/lib/Controller/IdentifyController.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\Controller;
10

11
use OCA\Libresign\AppInfo\Application;
12
use OCA\Libresign\Collaboration\Collaborators\AccountPhonePlugin;
13
use OCA\Libresign\Collaboration\Collaborators\ContactPhonePlugin;
14
use OCA\Libresign\Collaboration\Collaborators\ManualPhonePlugin;
15
use OCA\Libresign\Collaboration\Collaborators\SignerPlugin;
16
use OCA\Libresign\Middleware\Attribute\RequireManager;
17
use OCA\Libresign\ResponseDefinitions;
18
use OCA\Libresign\Service\Identify\ResultEnricher;
19
use OCA\Libresign\Service\Identify\ResultFilter;
20
use OCA\Libresign\Service\Identify\ResultFormatter;
21
use OCA\Libresign\Service\Identify\SearchNormalizer;
22
use OCA\Libresign\Service\Identify\SignerSearchContext;
23
use OCA\Libresign\Service\IdentifyMethod\Account;
24
use OCA\Libresign\Service\IdentifyMethod\Email;
25
use OCP\AppFramework\Http;
26
use OCP\AppFramework\Http\Attribute\ApiRoute;
27
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
28
use OCP\AppFramework\Http\DataResponse;
29
use OCP\Collaboration\Collaborators\ISearch;
30
use OCP\IRequest;
31
use OCP\Share\IShare;
32

33
/**
34
 * @psalm-import-type LibresignIdentifyAccount from ResponseDefinitions
35
 */
36
class IdentifyController extends AEnvironmentAwareController {
37
        private const PHONE_METHODS = ['whatsapp', 'sms', 'telegram', 'signal'];
38

39
        public function __construct(
40
                IRequest $request,
41
                private ISearch $collaboratorSearch,
42
                private Email $identifyEmailMethod,
43
                private Account $identifyAccountMethod,
44
                private SearchNormalizer $searchNormalizer,
45
                private SignerSearchContext $signerSearchContext,
46
                private ResultFilter $resultFilter,
47
                private ResultFormatter $resultFormatter,
48
                private ResultEnricher $resultEnricher,
49
        ) {
50
                parent::__construct(Application::APP_ID, $request);
×
51
        }
52

53
        /**
54
         * List possible signers
55
         *
56
         * Used to identify who can sign the document. The return of this endpoint is related with Administration Settiongs > LibreSign > Identify method.
57
         *
58
         * @param string $search search params
59
         * @param string $method filter by method (email, account, sms, signal, telegram, whatsapp, xmpp)
60
         * @param int $page the number of page to return. Default: 1
61
         * @param int $limit Total of elements to return. Default: 25
62
         * @return DataResponse<Http::STATUS_OK, LibresignIdentifyAccount[], array{}>
63
         *
64
         * 200: Certificate saved with success
65
         * 400: No file provided or other problem with provided file
66
         */
67
        #[NoAdminRequired]
68
        #[RequireManager]
69
        #[ApiRoute(verb: 'GET', url: '/api/{apiVersion}/identify-account/search', requirements: ['apiVersion' => '(v1)'])]
70
        public function search(string $search = '', string $method = '', int $page = 1, int $limit = 25): DataResponse {
NEW
71
                $rawSearch = $search;
×
72
                $search = $this->searchNormalizer->normalize($search, $method);
×
73

74
                // Only search for string larger than a minimum length
75
                if (strlen($search) < 1) {
×
76
                        return new DataResponse([]);
×
77
                }
78

NEW
79
                $shareTypes = $this->getShareTypes($method);
×
80
                $offset = $limit * ($page - 1);
×
81

NEW
82
                $this->signerSearchContext->set($method, $search, $rawSearch);
×
NEW
83
                $this->registerPlugin();
×
84
                [$result] = $this->collaboratorSearch->search($search, $shareTypes, false, $limit, $offset);
×
85

86
                // Process results through filters and formatters
87
                $result['exact'] = $this->resultFilter->unify($result['exact']);
×
88
                $result = $this->resultFilter->unify($result);
×
89
                $result = $this->resultFilter->excludeEmpty($result);
×
90

91
                $return = $this->resultFormatter->formatForNcSelect($result);
×
92
                $return = $this->resultEnricher->addHerselfAccount($return, $search);
×
93
                $return = $this->resultEnricher->addHerselfEmail($return, $search);
×
94
                $return = $this->resultFormatter->replaceShareTypeWithMethod($return);
×
95
                $return = $this->resultEnricher->addEmailNotificationPreference($return);
×
96
                $return = $this->resultFilter->excludeNotAllowed($return);
×
97

98
                return new DataResponse($return);
×
99
        }
100

101
        private function registerPlugin(): void {
102

103
                $refObject = new \ReflectionObject($this->collaboratorSearch);
×
104
                $refProperty = $refObject->getProperty('pluginList');
×
105

106
                $plugins = $refProperty->getValue($this->collaboratorSearch);
×
107
                $plugins[SignerPlugin::TYPE_SIGNER] = [SignerPlugin::class];
×
NEW
108
                $plugins[AccountPhonePlugin::TYPE_SIGNER_ACCOUNT_PHONE] = [AccountPhonePlugin::class];
×
NEW
109
                $plugins[ContactPhonePlugin::TYPE_SIGNER_CONTACT_PHONE] = [ContactPhonePlugin::class];
×
NEW
110
                $plugins[ManualPhonePlugin::TYPE_SIGNER_MANUAL_PHONE] = [ManualPhonePlugin::class];
×
111

112
                $refProperty->setValue($this->collaboratorSearch, $plugins);
×
113
        }
114

115
        private function getShareTypes(string $method): array {
NEW
116
                $shareTypes = [];
×
117
                $settings = $this->identifyEmailMethod->getSettings();
×
118
                if ($settings['enabled']) {
×
NEW
119
                        $shareTypes[] = IShare::TYPE_EMAIL;
×
120
                }
121
                $settings = $this->identifyAccountMethod->getSettings();
×
122
                if ($settings['enabled']) {
×
NEW
123
                        $shareTypes[] = IShare::TYPE_USER;
×
124
                }
125

NEW
126
                $shareTypes[] = SignerPlugin::TYPE_SIGNER;
×
NEW
127
                if (in_array($method, self::PHONE_METHODS, true)) {
×
NEW
128
                        $shareTypes[] = AccountPhonePlugin::TYPE_SIGNER_ACCOUNT_PHONE;
×
NEW
129
                        $shareTypes[] = ContactPhonePlugin::TYPE_SIGNER_CONTACT_PHONE;
×
NEW
130
                        $shareTypes[] = ManualPhonePlugin::TYPE_SIGNER_MANUAL_PHONE;
×
131
                }
NEW
132
                return $shareTypes;
×
133
        }
134
}
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