ExpirationHelper   A
last analyzed

Complexity

Total Complexity 6

Size/Duplication

Total Lines 52
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 20
dl 0
loc 52
rs 10
c 2
b 0
f 0
wmc 6

2 Methods

Rating   Name   Duplication   Size   Complexity  
A isExpired() 0 30 4
A __construct() 0 18 2
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Copyright 2023 SURFnet bv
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 *     http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20
21
namespace Surfnet\StepupGateway\GatewayBundle\Sso2fa\DateTime;
22
23
use DateTime as CoreDateTime;
24
use Surfnet\StepupBundle\DateTime\DateTime;
25
use Surfnet\StepupGateway\GatewayBundle\Sso2fa\Exception\InvalidAuthenticationTimeException;
26
use Surfnet\StepupGateway\GatewayBundle\Sso2fa\ValueObject\CookieValueInterface;
27
use TypeError;
28
29
class ExpirationHelper implements ExpirationHelperInterface
30
{
31
    public function __construct(
32
        /**
33
         * The SSO on 2FA cookie lifetime in seconds
34
         * See: config/openconext/parameters.yaml sso_cookie_lifetime
35
         */
36
        private int $cookieLifetime,
37
        /**
38
         * The period in seconds that we still acknowledge the
39
         * cookie even tho the expiration was reached. This accounts
40
         * for server time/sync differences that may occur.
41
         */
42
        private int $gracePeriod,
43
        private ?CoreDateTime $now = null
44
    ) {
45
        if ($now === null) {
46
            $now = DateTime::now();
47
        }
48
        $this->now = $now;
49
    }
50
51
    public function isExpired(CookieValueInterface $cookieValue): bool
52
    {
53
        try {
54
            $authenticationTimestamp = $cookieValue->authenticationTime();
55
        } catch (TypeError $error) {
56
            throw new InvalidAuthenticationTimeException(
57
                'The authentication time contained a non-int value',
58
                0,
59
                $error
60
            );
61
        }
62
63
        if ($authenticationTimestamp < 0) {
64
            throw new InvalidAuthenticationTimeException(
65
                'The authentication time is from before the Unix timestamp epoch'
66
            );
67
        }
68
69
        if ($authenticationTimestamp > $this->now->getTimestamp()) {
0 ignored issues
show
Bug introduced by
The method getTimestamp() does not exist on null. ( Ignorable by Annotation )

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

69
        if ($authenticationTimestamp > $this->now->/** @scrutinizer ignore-call */ getTimestamp()) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
70
            throw new InvalidAuthenticationTimeException(
71
                'The authentication time is from the future, which indicates the clock settings ' .
72
                'are incorrect, or the time in the cookie value was tampered with.'
73
            );
74
        }
75
76
        $expirationTimestamp = $authenticationTimestamp + $this->cookieLifetime + $this->gracePeriod;
77
        $currentTimestamp = $this->now->getTimestamp();
78
79
        // Is the current time greater than the expiration time?
80
        return $currentTimestamp > $expirationTimestamp;
81
    }
82
}
83