Passed
Push — master ( 6fe14f...44c396 )
by Marcel
03:09 queued 13s
created

ShareService::deleteByUser()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Analytics
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the LICENSE.md file.
7
 *
8
 * @author Marcel Scherello <[email protected]>
9
 * @copyright 2019-2022 Marcel Scherello
10
 */
11
12
namespace OCA\Analytics\Service;
13
14
use OCA\Analytics\Activity\ActivityManager;
15
use OCA\Analytics\Db\ShareMapper;
16
use OCA\Analytics\Db\ReportMapper;
17
use OCP\DB\Exception;
18
use OCP\IGroupManager;
19
use OCP\IUserManager;
20
use OCP\IUserSession;
21
use OCP\Security\ISecureRandom;
22
use Psr\Log\LoggerInterface;
23
24
class ShareService
25
{
26
    const SHARE_TYPE_USER = 0;
27
    const SHARE_TYPE_GROUP = 1;
28
    const SHARE_TYPE_USERGROUP = 2; // obsolete
29
    const SHARE_TYPE_LINK = 3;
30
    const SHARE_TYPE_ROOM = 10;
31
32
    /** @var IUserSession */
33
    private $userSession;
34
    /** @var LoggerInterface */
35
    private $logger;
36
    /** @var ShareMapper */
37
    private $ShareMapper;
38
    private $ReportMapper;
39
    private $secureRandom;
40
    private $ActivityManager;
41
    /** @var IGroupManager */
42
    private $groupManager;
43
    /** @var IUserManager */
44
    private $userManager;
45
    private $VariableService;
46
47
    public function __construct(
48
        IUserSession $userSession,
49
        LoggerInterface $logger,
50
        ShareMapper $ShareMapper,
51
        ReportMapper $ReportMapper,
52
        ActivityManager $ActivityManager,
53
        IGroupManager $groupManager,
54
        ISecureRandom $secureRandom,
55
        IUserManager $userManager,
56
        VariableService $VariableService
57
    )
58
    {
59
        $this->userSession = $userSession;
60
        $this->logger = $logger;
61
        $this->ShareMapper = $ShareMapper;
62
        $this->ReportMapper = $ReportMapper;
63
        $this->secureRandom = $secureRandom;
64
        $this->groupManager = $groupManager;
65
        $this->ActivityManager = $ActivityManager;
66
        $this->userManager = $userManager;
67
        $this->VariableService = $VariableService;
68
    }
69
70
    /**
71
     * create a new share
72
     *
73
     * @param $reportId
74
     * @param $type
75
     * @param $user
76
     * @return bool
77
     * @throws \OCP\DB\Exception
78
     */
79
    public function create($reportId, $type, $user)
80
    {
81
        $token = null;
82
        if ((int)$type === self::SHARE_TYPE_LINK) {
83
            $token = $this->generateToken();
84
        }
85
        $this->ShareMapper->createShare($reportId, $type, $user, $token);
86
        $this->ActivityManager->triggerEvent($reportId, ActivityManager::OBJECT_REPORT, ActivityManager::SUBJECT_REPORT_SHARE);
87
        return true;
88
    }
89
90
    /**
91
     * get all shares for a report
92
     *
93
     * @param $reportId
94
     * @return array
95
     * @throws Exception
96
     */
97
    public function read($reportId)
98
    {
99
100
        $shares = $this->ShareMapper->getShares($reportId);
101
        foreach ($shares as $key => $share) {
102
            if ((int)$share['type'] === self::SHARE_TYPE_USER) {
103
                if (!$this->userManager->userExists($share['uid_owner'])) {
104
                    $this->ShareMapper->deleteShare($share['id']);
105
                    unset($shares[$key]);
106
                    continue;
107
                }
108
                $shares[$key]['displayName'] = $this->userManager->get($share['uid_owner'])->getDisplayName();
109
            }
110
            $shares[$key]['pass'] = $share['pass'] !== null;
111
        }
112
        return $shares;
113
    }
114
115
    /**
116
     * get all report by token
117
     *
118
     * @param $token
119
     * @return array
120
     */
121
    public function getReportByToken($token)
122
    {
123
        $reportId = $this->ShareMapper->getReportByToken($token);
124
        return $this->VariableService->replaceTextVariables($reportId);
125
    }
126
127
    /**
128
     * verify password hahes
129
     *
130
     * @param $password
131
     * @param $sharePassword
132
     * @return bool
133
     */
134
    public function verifyPassword($password, $sharePassword)
135
    {
136
        return password_verify($password, $sharePassword);
137
    }
138
139
    /**
140
     * get all reports shared with user
141
     *
142
     * @throws Exception
143
     */
144
    public function getSharedReports()
145
    {
146
        $sharedReports = $this->ShareMapper->getAllSharedReports();
147
        $groupsOfUser = $this->groupManager->getUserGroups($this->userSession->getUser());
148
        $reports = array();
149
150
        foreach ($sharedReports as $sharedReport) {
151
            // shared with a group?
152
            if ($sharedReport['shareType'] === self::SHARE_TYPE_GROUP) {
153
                // is the current user part of this group?
154
                if (array_key_exists($sharedReport['shareUid_owner'], $groupsOfUser)) {
155
                    // was the report not yet added to the result?
156
                    if (!in_array($sharedReport["id"], array_column($reports, "id"))) {
157
                        unset($sharedReport['shareType']);
158
                        unset($sharedReport['shareUid_owner']);
159
                        $sharedReport['isShare'] = self::SHARE_TYPE_GROUP;
160
                        $reports[] = $sharedReport;
161
                    }
162
                }
163
            // shared with a user directly?
164
            } elseif ($sharedReport['shareType'] === self::SHARE_TYPE_USER) {
165
                // current user matching?
166
                if ($this->userSession->getUser()->getUID() === $sharedReport['shareUid_owner']) {
167
                    // was the report not yet added to the result?
168
                    if (!in_array($sharedReport["id"], array_column($reports, "id"))) {
169
                        unset($sharedReport['shareType']);
170
                        unset($sharedReport['shareUid_owner']);
171
                        $sharedReport['isShare'] = self::SHARE_TYPE_USER;
172
                        $reports[] = $sharedReport;
173
                    }
174
                }
175
            }
176
        }
177
178
        foreach ($reports as $report) {
179
            // if it is a shared group, get all reports below
180
            if ($report['type'] === ReportService::REPORT_TYPE_GROUP) {
181
                $subreport = $this->ReportMapper->getReportsByGroup($report['id']);
182
                $subreport = array_map(function($report) {
183
                    $report['isShare'] = self::SHARE_TYPE_GROUP;
184
                    return $report;
185
                }, $subreport);
186
187
                $reports = array_merge($reports, $subreport);
188
            }
189
        }
190
        return $reports;
191
    }
192
193
    /**
194
     * get metadata of a report, shared with current user
195
     * used to check if user is allowed to execute current report
196
     *
197
     * @param $reportId
198
     * @return array
199
     * @throws Exception
200
     */
201
    public function getSharedReport($reportId)
202
    {
203
        $sharedReport = $this->getSharedReports();
204
        if (in_array($reportId, array_column($sharedReport, "id"))) {
205
            $key = array_search($reportId, array_column($sharedReport, 'id'));
206
            return $sharedReport[$key];
207
        } else {
208
            return [];
209
        }
210
    }
211
212
    /**
213
     * Delete an own share (sharee or receiver)
214
     *
215
     * @param $shareId
216
     * @return bool
217
     * @throws Exception
218
     */
219
    public function delete($shareId)
220
    {
221
        $this->ShareMapper->deleteShare($shareId);
222
        return true;
223
    }
224
225
    /**
226
     * delete all shares for a report
227
     *
228
     * @param $reportId
229
     * @return bool
230
     */
231
    public function deleteShareByReport($reportId)
232
    {
233
        return $this->ShareMapper->deleteShareByReport($reportId);
234
    }
235
236
    /**
237
     * delete all shares when a share-receiving-user is deleted
238
     *
239
     * @param $userId
240
     * @return bool
241
     */
242
    public function deleteByUser($userId)
243
    {
244
        return $this->ShareMapper->deleteByUser($userId);
245
    }
246
247
    /**
248
     * update/set share password
249
     *
250
     * @param $shareId
251
     * @param string|null $password
252
     * @param string|null $canEdit
253
     * @param string|null $domain
254
     * @return bool
255
     */
256
    public function update($shareId, $password = null, $canEdit = null, $domain = null)
257
    {
258
        if ($password !== null) {
259
            $password = password_hash($password, PASSWORD_DEFAULT);
260
            return $this->ShareMapper->updateSharePassword($shareId, $password);
261
        }
262
        if ($domain !== null) {
263
            return $this->ShareMapper->updateShareDomain($shareId, $domain);
264
        }
265
        if ($canEdit !== null) {
266
            $canEdit === true ? $canEdit = \OCP\Constants::PERMISSION_UPDATE : $canEdit = \OCP\Constants::PERMISSION_READ;
0 ignored issues
show
introduced by
The condition $canEdit === true is always false.
Loading history...
267
            return $this->ShareMapper->updateSharePermissions($shareId, $canEdit);
268
        }
269
    }
270
271
    /**
272
     * generate to token used to authenticate federated shares
273
     *
274
     * @return string
275
     */
276
    private function generateToken()
277
    {
278
        $token = $this->secureRandom->generate(
279
            15,
280
            ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS);
281
        return $token;
282
    }
283
}