GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — 3.x ( 283ce0...550ea0 )
by Jindřich
12s queued 10s
created

User::parseDate()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3.0987

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 1
dl 0
loc 17
ccs 7
cts 9
cp 0.7778
crap 3.0987
rs 9.7
c 0
b 0
f 0
1
<?php
2
declare(strict_types = 1);
3
4
namespace Skaut\Skautis;
5
6
use DateTimeImmutable;
7
use DateTimeZone;
8
use Skaut\Skautis\SessionAdapter\AdapterInterface;
9
use Skaut\Skautis\Wsdl\WebServiceName;
10
use Skaut\Skautis\Wsdl\WsdlManager;
11
12
/**
13
 * @author Petr Morávek <[email protected]>
14
 */
15
class User
16
{
17
18
    public const ID_LOGIN = 'ID_Login';
19
    public const ID_ROLE = 'ID_Role';
20
    public const ID_UNIT = 'ID_Unit';
21
    public const LOGOUT_DATE = 'LOGOUT_Date';
22
    private const AUTH_CONFIRMED = 'AUTH_Confirmed';
23
    private const SESSION_ID = 'skautis_user_data';
24
25
    /**
26
     * @var WsdlManager
27
     */
28
    private $wsdlManager;
29
30
    /**
31
     * @var AdapterInterface|null
32
     */
33
    private $session;
34
35
    /**
36
     * Informace o přihlášení uživatele
37
     *
38
     * @var array<string, mixed>
39
     */
40
    protected $loginData = [];
41
42
    /**
43
     * @param WsdlManager $wsdlManager
44
     * @param AdapterInterface|null $session
45
     */
46 7
    public function __construct(WsdlManager $wsdlManager, AdapterInterface $session = null)
47
    {
48 7
        $this->wsdlManager = $wsdlManager;
49 7
        $this->session = $session;
50
51 7
        if ($session !== null && $session->has(self::SESSION_ID)) {
52
            $this->loginData = (array)$session->get(self::SESSION_ID);
53
        }
54 7
    }
55
56 6
    public function getLoginId(): ?string
57
    {
58 6
        return $this->loginData[self::ID_LOGIN] ?? null;
59
    }
60
61 2
    public function getRoleId(): ?int
62
    {
63 2
        return $this->loginData[self::ID_ROLE] ?? null;
64
    }
65
66 2
    public function getUnitId(): ?int
67
    {
68 2
        return $this->loginData[self::ID_UNIT] ?? null;
69
    }
70
71
    /**
72
     * Vrací datum a čas automatického odhlášení ze skautISu
73
     */
74 3
    public function getLogoutDate(): ?DateTimeImmutable
75
    {
76 3
        return $this->loginData[self::LOGOUT_DATE] ?? null;
77
    }
78
79
    /**+
80
     * Hromadné nastavení po přihlášení
81
     */
82 3
    public function setLoginData(
83
      string $loginId,
84
      ?int $roleId = null,
85
      ?int $unitId = null,
86
      ?DateTimeImmutable $logoutDate = null
87
    ): self {
88 3
        $this->loginData = [];
89
90 3
        return $this->updateLoginData($loginId, $roleId, $unitId, $logoutDate);
91
    }
92
93
    /**
94
     * Hromadná změna údajů, bez vymazání stávajících
95
     */
96 3
    public function updateLoginData(
97
      ?string $loginId = null,
98
      ?int $roleId = null,
99
      ?int $unitId = null,
100
      ?DateTimeImmutable $logoutDate = null
101
    ): self {
102 3
        if ($loginId !== null) {
103 3
            $this->loginData[self::ID_LOGIN] = $loginId;
104
        }
105
106 3
        if ($roleId !== null) {
107 3
            $this->loginData[self::ID_ROLE] = $roleId;
108
        }
109
110 3
        if ($unitId !== null) {
111 3
            $this->loginData[self::ID_UNIT] = $unitId;
112
        }
113
114 3
        if ($logoutDate !== null) {
115 3
            $this->loginData[self::LOGOUT_DATE] = $logoutDate;
116
        }
117
118 3
        $this->saveToSession();
119
120 3
        return $this;
121
    }
122
123
    /**
124
     * Hromadný reset dat po odhlášení
125
     */
126 1
    public function resetLoginData(): self
127
    {
128 1
        $this->loginData = [];
129 1
        $this->saveToSession();
130
131 1
        return $this;
132
    }
133
134
    /**
135
     * Kontoluje, jestli je přihlášení platné.
136
     * Pro správné fungování je nezbytně nutné, aby byl na serveru nastaven správný čas.
137
     *
138
     * @param bool $hardCheck vynutí kontrolu přihlášení na serveru
139
     */
140 3
    public function isLoggedIn(bool $hardCheck = false): bool
141
    {
142 3
        if (empty($this->loginData[self::ID_LOGIN])) {
143 2
            return false;
144
        }
145
146 1
        if ($hardCheck || !$this->isAuthConfirmed()) {
147 1
            $this->confirmAuth();
148
        }
149
150 1
        if ($this->getLogoutDate() === null) {
151
          return false;
152
        }
153
154 1
        return $this->isAuthConfirmed() && $this->getLogoutDate()->getTimestamp() > time();
155
    }
156
157
    /**
158
     * Bylo potvrzeno přihlášení dotazem na skautIS?
159
     */
160 1
    protected function isAuthConfirmed(): bool
161
    {
162 1
        return !empty($this->loginData[self::AUTH_CONFIRMED]);
163
    }
164
165 1
    protected function setAuthConfirmed(bool $isConfirmed): void
166
    {
167 1
        $this->loginData[self::AUTH_CONFIRMED] = $isConfirmed;
168 1
        $this->saveToSession();
169 1
    }
170
171
  /**
172
   * Potvrdí (a prodlouží) přihlášení dotazem na skautIS.
173
   *
174
   * @throws \Exception Pokud se authentikace nepovede
175
   */
176 1
    protected function confirmAuth(): void
177
    {
178
        try {
179 1
          $logoutTimeUpdated = $this->updateLogoutTime();
180 1
          if(!$logoutTimeUpdated) {
181
              throw new \RuntimeException('Updating logout time failed');
182
            }
183 1
            $this->setAuthConfirmed(true);
184
        } catch (\Exception $e) {
185
            $this->setAuthConfirmed(false);
186
            throw $e;
187
        }
188 1
    }
189
190
    /**
191
     * Prodloužení přihlášení o 30 min
192
     *
193
     * @throws UnexpectedValueException pokud se nepodaří naparsovat datum
194
     */
195 1
    public function updateLogoutTime(): bool
196
    {
197 1
        $loginId = $this->getLoginId();
198 1
        if ($loginId === null) {
199
            // Nemáme token, uživatel není přihlášen a není, co prodlužovat
200
            return false;
201
        }
202
203 1
        $result = $this->wsdlManager->getWebService(WebServiceName::USER_MANAGEMENT, $loginId)->LoginUpdateRefresh(['ID' => $loginId]);
204
205 1
        $logoutDate = $this->parseDate($result->DateLogout);
206 1
        $this->loginData[self::LOGOUT_DATE] = $logoutDate;
207
208 1
        $this->saveToSession();
209
210 1
        return true;
211
    }
212
213
    /**
214
     * Uloží nastavení do session
215
     */
216 3
    protected function saveToSession(): void
217
    {
218 3
        if ($this->session !== null) {
219
            $this->session->set(self::SESSION_ID, $this->loginData);
220
        }
221 3
    }
222
223 1
    private function parseDate(string $dateText): DateTimeImmutable {
224
      //skautIS vrací sekundy včetně desetinné části
225 1
      $dateTextWithoutDecimals = preg_replace('/\.(\d*)$/', '', $dateText);
226
227 1
      if (!is_string($dateTextWithoutDecimals)) {
228
        throw new UnexpectedValueException("Could not parse date '$dateText'.");
229
      }
230
231 1
      $tz = new DateTimeZone('Europe/Prague');
232 1
      $dateTime =  DateTimeImmutable::createFromFormat('Y-m-d\TH:i:s', $dateTextWithoutDecimals, $tz);
233
234 1
      if ($dateTime === false) {
235
        throw new UnexpectedValueException("Could not parse date '$dateText'.");
236
      }
237
238 1
      return $dateTime;
239
    }
240
}
241