Passed
Push — master ( 5193bc...d3ccde )
by Marcel
02:52
created

OutputController::evaluateCanFilter()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 5
nc 2
nop 4
dl 0
loc 11
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 2021 Marcel Scherello
10
 */
11
12
namespace OCA\Analytics\Controller;
13
14
use OCA\Analytics\DataSession;
15
use OCA\Analytics\Service\DatasetService;
16
use OCA\Analytics\Service\ShareService;
17
use OCA\Analytics\Service\ThresholdService;
18
use OCP\AppFramework\Controller;
19
use OCP\AppFramework\Http;
20
use OCP\AppFramework\Http\DataResponse;
21
use OCP\AppFramework\Http\NotFoundResponse;
22
use OCP\Files\IRootFolder;
23
use OCP\Files\NotFoundException;
24
use OCP\ILogger;
25
use OCP\IRequest;
26
27
class OutputController extends Controller
28
{
29
    private $logger;
30
    private $DatasetService;
31
    private $rootFolder;
32
    private $userId;
33
    private $DataSession;
34
    private $ShareService;
35
    private $DatasourceController;
36
    private $StorageController;
37
    private $ThresholdService;
38
39
    public function __construct(
40
        string $AppName,
41
        IRequest $request,
42
        $userId,
43
        ILogger $logger,
44
        IRootFolder $rootFolder,
45
        DatasetService $DatasetService,
46
        ShareService $ShareService,
47
        DataSession $DataSession,
48
        DatasourceController $DatasourceController,
49
        StorageController $StorageController,
50
        ThresholdService $ThresholdService
51
    )
52
    {
53
        parent::__construct($AppName, $request);
54
        $this->userId = $userId;
55
        $this->logger = $logger;
56
        $this->DatasetService = $DatasetService;
57
        $this->rootFolder = $rootFolder;
58
        $this->DataSession = $DataSession;
59
        $this->ShareService = $ShareService;
60
        $this->DatasourceController = $DatasourceController;
61
        $this->StorageController = $StorageController;
62
        $this->ThresholdService = $ThresholdService;
63
    }
64
65
    /**
66
     * get the data when requested from internal page
67
     *
68
     * @NoAdminRequired
69
     * @param int $datasetId
70
     * @param $filteroptions
71
     * @param $dataoptions
72
     * @return DataResponse|NotFoundResponse
73
     * @throws NotFoundException
74
     */
75
    public function read(int $datasetId, $filteroptions, $dataoptions, $chartoptions)
76
    {
77
        $datasetMetadata = $this->DatasetService->getOwnDataset($datasetId);
78
        if (empty($datasetMetadata)) $datasetMetadata = $this->ShareService->getSharedDataset($datasetId);
79
80
        if (!empty($datasetMetadata)) {
81
            $datasetMetadata = $this->evaluateCanFilter($datasetMetadata, $filteroptions, $dataoptions, $chartoptions);
82
            $result = $this->getData($datasetMetadata);
83
84
            $response = new DataResponse($result, HTTP::STATUS_OK);
85
            //$response->setETag(md5('123'));
86
            return $response;
87
        } else {
88
            return new NotFoundResponse();
89
        }
90
    }
91
92
    /**
93
     * Get the data from backend;
94
     * pre-evaluation of valid datasetId within read & readPublic is trusted here
95
     *
96
     * @NoAdminRequired
97
     * @param $datasetMetadata
98
     * @return array|NotFoundException
99
     * @throws NotFoundException
100
     */
101
    private function getData($datasetMetadata)
102
    {
103
        $datasourceId = (int)$datasetMetadata['type'];
104
105
        if ($datasourceId === DatasourceController::DATASET_TYPE_INTERNAL_DB) {
106
            $result = $this->StorageController->read($datasetMetadata);
107
        } else {
108
            $option = array();
109
            // before 3.1.0, the options were in another format. as of 3.1.0 the standard option array is used
110
            if ($datasetMetadata['link'][0] !== '{') {
111
                $option['link'] = $datasetMetadata['link'];
112
            } else {
113
                $option = json_decode($datasetMetadata['link'], true);
114
            }
115
            $option['user_id'] = $datasetMetadata['user_id'];
116
117
            $result = $this->DatasourceController->read($datasourceId, $datasetMetadata);
118
            //unset($result['error']);
119
        }
120
121
        $result['thresholds'] = $this->ThresholdService->read($datasetMetadata['id']);
122
123
        unset($datasetMetadata['parent']
124
            , $datasetMetadata['user_id']
125
            , $datasetMetadata['link']
126
            , $datasetMetadata['dimension1']
127
            , $datasetMetadata['dimension2']
128
            , $datasetMetadata['dimension3']
129
            , $datasetMetadata['value']
130
            , $datasetMetadata['password']
131
        );
132
        $result['options'] = $datasetMetadata;
133
134
        return $result;
135
    }
136
137
    /**
138
     * get the data when requested from public page
139
     *
140
     * @NoAdminRequired
141
     * @PublicPage
142
     * @UseSession
143
     * @param $token
144
     * @param $filteroptions
145
     * @param $dataoptions
146
     * @return DataResponse|NotFoundResponse
147
     * @throws NotFoundException
148
     */
149
    public function readPublic($token, $filteroptions, $dataoptions, $chartoptions)
150
    {
151
        $share = $this->ShareService->getDatasetByToken($token);
152
        if (empty($share)) {
153
            // Dataset not shared or wrong token
154
            return new NotFoundResponse();
155
        } else {
156
            if ($share['password'] !== null) {
157
                $password = $this->DataSession->getPasswordForShare($token);
158
                $passwordVerification = $this->ShareService->verifyPassword($password, $share['password']);
159
                if ($passwordVerification === false) {
160
                    return new NotFoundResponse();
161
                }
162
            }
163
            $share = $this->evaluateCanFilter($share, $filteroptions, $dataoptions, $chartoptions);
164
            $result = $this->getData($share);
165
            return new DataResponse($result);
166
        }
167
    }
168
169
    /**
170
     * evaluate if the user did filter in the report and if he is allowed to filter (shared reports)
171
     *
172
     * @param $metadata
173
     * @param $filteroptions
174
     * @param $dataoptions
175
     * @return mixed
176
     */
177
    private function evaluateCanFilter($metadata, $filteroptions, $dataoptions, $chartoptions)
178
    {
179
        // send current user filteroptions to the datarequest
180
        // only if the report has update-permissions
181
        // if nothing is changed by the user, the filter which is stored for the report, will be used
182
        if ($filteroptions and $filteroptions !== '' and $metadata['permissions'] === \OCP\Constants::PERMISSION_UPDATE) {
183
            $metadata['filteroptions'] = $filteroptions;
184
            $metadata['dataoptions'] = $dataoptions;
185
            $metadata['chartoptions'] = $chartoptions;
186
        }
187
        return $metadata;
188
    }
189
}