Passed
Push — devel-3.0 ( ca620b...2581df )
by Rubén
03:02
created

TrackService::getById()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * sysPass
4
 *
5
 * @author    nuxsmin
6
 * @link      https://syspass.org
7
 * @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
8
 *
9
 * This file is part of sysPass.
10
 *
11
 * sysPass is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU General Public License as published by
13
 * the Free Software Foundation, either version 3 of the License, or
14
 * (at your option) any later version.
15
 *
16
 * sysPass is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License
22
 *  along with sysPass.  If not, see <http://www.gnu.org/licenses/>.
23
 */
24
25
namespace SP\Services\Track;
26
27
use SP\Core\Events\Event;
28
use SP\Core\Events\EventMessage;
29
use SP\DataModel\ItemSearchData;
30
use SP\DataModel\TrackData;
31
use SP\Http\Request;
32
use SP\Repositories\NoSuchItemException;
33
use SP\Repositories\Track\TrackRepository;
34
use SP\Repositories\Track\TrackRequest;
35
use SP\Services\Service;
36
use SP\Services\ServiceException;
37
38
/**
39
 * Class TrackService
40
 *
41
 * @package SP\Services
42
 */
43
final class TrackService extends Service
44
{
45
    /**
46
     * Tiempo para contador de intentos
47
     */
48
    const TIME_TRACKING = 600;
49
    const TIME_TRACKING_MAX_ATTEMPTS = 10;
50
    const TIME_SLEEP = 0.5;
51
52
    /**
53
     * @var TrackRepository
54
     */
55
    protected $trackRepository;
56
    /**
57
     * @var Request
58
     */
59
    protected $request;
60
61
    /**
62
     * @param string $source
63
     *
64
     * @return TrackRequest
65
     * @throws \SP\Core\Exceptions\InvalidArgumentException
66
     */
67
    public function getTrackRequest($source)
68
    {
69
        $trackRequest = new TrackRequest();
70
        $trackRequest->time = time() - self::TIME_TRACKING;
71
        $trackRequest->setTrackIp($this->request->getClientAddress());
0 ignored issues
show
Bug introduced by
It seems like $this->request->getClientAddress() can also be of type array; however, parameter $address of SP\Repositories\Track\TrackRequest::setTrackIp() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

71
        $trackRequest->setTrackIp(/** @scrutinizer ignore-type */ $this->request->getClientAddress());
Loading history...
72
        $trackRequest->source = $source;
73
74
        return $trackRequest;
75
    }
76
77
    /**
78
     * @param $id int
79
     *
80
     * @throws \SP\Core\Exceptions\QueryException
81
     * @throws \SP\Core\Exceptions\ConstraintException
82
     * @throws NoSuchItemException
83
     */
84
    public function delete($id)
85
    {
86
        if ($this->trackRepository->delete($id) === 0) {
87
            throw new NoSuchItemException(__u('Track no encontrado'));
88
        }
89
    }
90
91
    /**
92
     * @param $id int
93
     *
94
     * @throws \SP\Core\Exceptions\QueryException
95
     * @throws \SP\Core\Exceptions\ConstraintException
96
     * @throws NoSuchItemException
97
     */
98
    public function unlock($id)
99
    {
100
        if ($this->trackRepository->unlock($id) === 0) {
101
            throw new NoSuchItemException(__u('Track no encontrado'));
102
        }
103
    }
104
105
    /**
106
     * @return bool
107
     * @throws \SP\Core\Exceptions\ConstraintException
108
     * @throws \SP\Core\Exceptions\QueryException
109
     */
110
    public function clear()
111
    {
112
        return $this->trackRepository->clear();
113
    }
114
115
    /**
116
     * @param $id int
117
     *
118
     * @return TrackData
119
     * @throws \SP\Core\Exceptions\ConstraintException
120
     * @throws \SP\Core\Exceptions\QueryException
121
     * @throws NoSuchItemException
122
     */
123
    public function getById($id)
124
    {
125
        $result = $this->trackRepository->getById($id);
126
127
        if ($result->getNumRows() === 0) {
128
            throw new NoSuchItemException(__u('Track no encontrado'));
129
        }
130
131
        return $result->getData();
132
    }
133
134
    /**
135
     * @return TrackData[]
136
     * @throws \SP\Core\Exceptions\ConstraintException
137
     * @throws \SP\Core\Exceptions\QueryException
138
     */
139
    public function getAll()
140
    {
141
        return $this->trackRepository->getAll()->getDataAsArray();
142
    }
143
144
    /**
145
     * Comprobar los intentos de login
146
     *
147
     * @param TrackRequest $trackRequest
148
     *
149
     * @return bool True if delay is performed, false otherwise
150
     * @throws \Exception
151
     */
152
    public function checkTracking(TrackRequest $trackRequest)
153
    {
154
        try {
155
            $attempts = $this->getTracksForClientFromTime($trackRequest);
156
157
            if ($attempts >= self::TIME_TRACKING_MAX_ATTEMPTS) {
158
                $delaySeconds = self::TIME_SLEEP * $attempts;
159
160
                $this->eventDispatcher->notifyEvent('track.delay',
161
                    new Event($this, EventMessage::factory()
162
                        ->addDescription(sprintf(__('Intentos excedidos (%d/%d)'), $attempts, self::TIME_TRACKING_MAX_ATTEMPTS))
163
                        ->addDetail(__u('Segundos'), $delaySeconds))
164
                );
165
166
                logger('Tracking delay: ' . $delaySeconds . 's');
167
168
                sleep($delaySeconds);
0 ignored issues
show
Bug introduced by
$delaySeconds of type double is incompatible with the type integer expected by parameter $seconds of sleep(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

168
                sleep(/** @scrutinizer ignore-type */ $delaySeconds);
Loading history...
169
170
                return true;
171
            }
172
        } catch (\Exception $e) {
173
            processException($e);
174
175
            throw $e;
176
        }
177
178
        return false;
179
    }
180
181
    /**
182
     * Devuelve los tracks de un cliente desde un tiempo y origen determinados
183
     *
184
     * @param TrackRequest $trackRequest
185
     *
186
     * @return int
187
     * @throws \SP\Core\Exceptions\ConstraintException
188
     * @throws \SP\Core\Exceptions\QueryException
189
     */
190
    public function getTracksForClientFromTime(TrackRequest $trackRequest)
191
    {
192
        return $this->trackRepository->getTracksForClientFromTime($trackRequest)->getNumRows();
193
    }
194
195
    /**
196
     * @param TrackRequest $trackRequest
197
     *
198
     * @return int
199
     * @throws ServiceException
200
     * @throws \SP\Core\Exceptions\ConstraintException
201
     * @throws \SP\Core\Exceptions\QueryException
202
     */
203
    public function add(TrackRequest $trackRequest)
204
    {
205
        if ($trackRequest->getIpv4() === null
0 ignored issues
show
introduced by
The condition $trackRequest->getIpv4() === null is always false.
Loading history...
206
            && $trackRequest->getIpv6() === null
207
        ) {
208
            throw new ServiceException(__u('Dirección IP no establecida'));
209
        }
210
211
        $result = $this->trackRepository->add($trackRequest);
212
213
        $this->eventDispatcher->notifyEvent('track.add',
214
            new Event($this, EventMessage::factory()
215
                ->addDescription($this->request->getClientAddress(true)))
0 ignored issues
show
Bug introduced by
It seems like $this->request->getClientAddress(true) can also be of type array; however, parameter $description of SP\Core\Events\EventMessage::addDescription() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

215
                ->addDescription(/** @scrutinizer ignore-type */ $this->request->getClientAddress(true)))
Loading history...
216
        );
217
218
        return $result;
219
    }
220
221
    /**
222
     * @param ItemSearchData $itemSearchData
223
     *
224
     * @return \SP\Storage\Database\QueryResult
225
     * @throws \SP\Core\Exceptions\ConstraintException
226
     * @throws \SP\Core\Exceptions\QueryException
227
     */
228
    public function search(ItemSearchData $itemSearchData)
229
    {
230
        return $this->trackRepository->search($itemSearchData);
231
    }
232
233
    /**
234
     * @throws \Psr\Container\ContainerExceptionInterface
235
     * @throws \Psr\Container\NotFoundExceptionInterface
236
     */
237
    protected function initialize()
238
    {
239
        $this->trackRepository = $this->dic->get(TrackRepository::class);
240
        $this->request = $this->dic->get(Request::class);
241
    }
242
}