Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
23.58% covered (danger)
23.58%
25 / 106
50.00% covered (danger)
50.00%
3 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
IdentifyMethodMapper
23.58% covered (danger)
23.58%
25 / 106
50.00% covered (danger)
50.00%
3 / 6
145.95
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getIdentifyMethodsFromSignRequestId
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
3
 getIdentifyMethodsFromSignRequestIds
26.67% covered (danger)
26.67%
4 / 15
0.00% covered (danger)
0.00%
0 / 1
10.31
 neutralizeDeletedUser
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
20
 deleteBySignRequestId
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 searchByIdentifierValue
0.00% covered (danger)
0.00%
0 / 50
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3declare(strict_types=1);
4/**
5 * SPDX-FileCopyrightText: 2020-2024 LibreCode coop and contributors
6 * SPDX-License-Identifier: AGPL-3.0-or-later
7 */
8
9namespace OCA\Libresign\Db;
10
11use OCP\AppFramework\Db\QBMapper;
12use OCP\Comments\ICommentsManager;
13use OCP\DB\QueryBuilder\IQueryBuilder;
14use OCP\IDBConnection;
15
16/**
17 * @template-extends QBMapper<IdentifyMethod>
18 */
19class IdentifyMethodMapper extends QBMapper {
20    /**
21     * @var IdentifyMethod[][]
22     */
23    private array $methodsBySignRequest = [];
24    public function __construct(IDBConnection $db) {
25        parent::__construct($db, 'libresign_identify_method');
26    }
27
28    /**
29     * @return IdentifyMethod[]
30     */
31    public function getIdentifyMethodsFromSignRequestId(int $signRequestId): array {
32        if (!empty($this->methodsBySignRequest[$signRequestId])) {
33            return $this->methodsBySignRequest[$signRequestId];
34        }
35        $qb = $this->db->getQueryBuilder();
36        $qb->select('im.*')
37            ->from('libresign_identify_method', 'im')
38            ->where(
39                $qb->expr()->eq('im.sign_request_id', $qb->createNamedParameter($signRequestId, IQueryBuilder::PARAM_INT))
40            );
41        $cursor = $qb->executeQuery();
42        $this->methodsBySignRequest[$signRequestId] = [];
43        while ($row = $cursor->fetch()) {
44            /** @var IdentifyMethod */
45            $this->methodsBySignRequest[$signRequestId][] = $this->mapRowToEntity($row);
46        }
47        return $this->methodsBySignRequest[$signRequestId];
48    }
49
50    /**
51     * @param int[] $signRequestIds
52     * @return array<int, IdentifyMethod[]>
53     */
54    public function getIdentifyMethodsFromSignRequestIds(array $signRequestIds): array {
55        if (empty($signRequestIds)) {
56            return [];
57        }
58
59        $missing = array_diff($signRequestIds, array_keys($this->methodsBySignRequest));
60
61        if (!empty($missing)) {
62            $qb = $this->db->getQueryBuilder();
63            $qb->select('im.*')
64                ->from('libresign_identify_method', 'im')
65                ->where($qb->expr()->in('im.sign_request_id', $qb->createNamedParameter($missing, IQueryBuilder::PARAM_INT_ARRAY)));
66
67            $cursor = $qb->executeQuery();
68            while ($row = $cursor->fetch()) {
69                $entity = $this->mapRowToEntity($row);
70                $signRequestId = $entity->getSignRequestId();
71                $this->methodsBySignRequest[$signRequestId][] = $entity;
72            }
73            $cursor->closeCursor();
74        }
75
76        return array_map(fn ($id) => $this->methodsBySignRequest[$id] ?? [], $signRequestIds);
77    }
78
79    public function neutralizeDeletedUser(string $userId, string $displayName): void {
80        $update = $this->db->getQueryBuilder();
81        $qb = $this->db->getQueryBuilder();
82        $qb->select('im.id')
83            ->addSelect('im.metadata')
84            ->from('libresign_identify_method', 'im')
85            ->where($qb->expr()->in('im.identifier_key', $qb->createNamedParameter(['account', 'email'], IQueryBuilder::PARAM_STR_ARRAY), IQueryBuilder::PARAM_STR_ARRAY))
86            ->andWhere($qb->expr()->eq('im.identifier_value', $qb->createNamedParameter($userId)));
87        $cursor = $qb->executeQuery();
88        while ($row = $cursor->fetch()) {
89            if (is_string($row['metadata']) && !empty($row['metadata'])) {
90                $row['metadata'] = json_decode($row['metadata'], true);
91            }
92            $row['metadata']['deleted_account'] = [
93                'account' => $userId,
94                'display_name' => $displayName,
95            ];
96            $update->update('libresign_identify_method')
97                ->set('identifier_value', $update->createNamedParameter(ICommentsManager::DELETED_USER))
98                ->set('metadata', $update->createNamedParameter($row['metadata'], IQueryBuilder::PARAM_JSON))
99                ->where($update->expr()->eq('id', $update->createNamedParameter($row['id'])));
100            $update->executeStatement();
101        }
102    }
103
104    public function deleteBySignRequestId(int $signRequestId): void {
105        $qb = $this->db->getQueryBuilder();
106        $qb->delete('libresign_identify_method')
107            ->where(
108                $qb->expr()->eq('sign_request_id', $qb->createNamedParameter($signRequestId, IQueryBuilder::PARAM_INT))
109            )
110            ->executeStatement();
111        unset($this->methodsBySignRequest[$signRequestId]);
112    }
113
114    /**
115     * @return array<string, string>[]
116     */
117    public function searchByIdentifierValue(string $search, string $userId, string $method, int $limit = 20, int $offset = 0): array {
118        $qb = $this->db->getQueryBuilder();
119
120        $latestQb = $this->db->getQueryBuilder();
121        $latestQb->select('im2.identifier_key')
122            ->addSelect('im2.identifier_value')
123            ->selectAlias($latestQb->func()->max('sr2.created_at'), 'created_at')
124            ->from('libresign_identify_method', 'im2')
125            ->join('im2', 'libresign_sign_request', 'sr2',
126                $latestQb->expr()->eq('sr2.id', 'im2.sign_request_id')
127            )
128            ->join('im2', 'libresign_file', 'f2',
129                $latestQb->expr()->eq('f2.id', 'sr2.file_id')
130            )
131            ->where($latestQb->expr()->eq('f2.user_id', $latestQb->createNamedParameter($userId)));
132        if (!empty($method)) {
133            $latestQb->andWhere($latestQb->expr()->eq('im2.identifier_key', $latestQb->createNamedParameter($method)));
134        }
135        $latestQb->andWhere(
136            $latestQb->expr()->orX(
137                $latestQb->expr()->iLike(
138                    'im2.identifier_value',
139                    $latestQb->createNamedParameter('%' . $this->db->escapeLikeParameter($search) . '%')
140                ),
141                $latestQb->expr()->iLike(
142                    'sr2.display_name',
143                    $latestQb->createNamedParameter('%' . $this->db->escapeLikeParameter($search) . '%')
144                )
145            )
146        )
147            ->groupBy('im2.identifier_key')
148            ->addGroupBy('im2.identifier_value');
149
150        foreach ($latestQb->getParameters() as $name => $value) {
151            $qb->setParameter($name, $value);
152        }
153
154        $qb->select('im.identifier_key', 'im.identifier_value', 'sr.display_name')
155            ->from('libresign_identify_method', 'im')
156            ->join('im', $qb->createFunction('(' . $latestQb->getSQL() . ')'), 'latest',
157                $qb->expr()->andX(
158                    $qb->expr()->eq('latest.identifier_key', 'im.identifier_key'),
159                    $qb->expr()->eq('latest.identifier_value', 'im.identifier_value')
160                )
161            )
162            ->join('im', 'libresign_sign_request', 'sr',
163                $qb->expr()->eq('sr.id', 'im.sign_request_id'),
164            )
165            ->where($qb->expr()->neq('im.identifier_value', $qb->createNamedParameter('deleted_users')))
166            ->setMaxResults($limit)
167            ->setFirstResult($offset);
168
169        $cursor = $qb->executeQuery();
170        $return = [];
171        while ($row = $cursor->fetch()) {
172            $return[] = $row;
173        }
174        return $return;
175    }
176}