Passed
Pull Request — develop (#295)
by Peter
04:30
created

CookieHelper::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
nc 1
nop 3
dl 0
loc 8
rs 10
c 1
b 0
f 0
1
<?php declare(strict_types=1);
2
3
/**
4
 * Copyright 2022 SURFnet bv
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
0 ignored issues
show
Coding Style introduced by
PHP version not specified
Loading history...
Coding Style introduced by
Missing @category tag in file comment
Loading history...
Coding Style introduced by
Missing @package tag in file comment
Loading history...
Coding Style introduced by
Missing @author tag in file comment
Loading history...
Coding Style introduced by
Missing @license tag in file comment
Loading history...
Coding Style introduced by
Missing @link tag in file comment
Loading history...
18
19
namespace Surfnet\StepupGateway\GatewayBundle\Sso2fa\Http;
20
21
use Psr\Log\LoggerInterface;
22
use Surfnet\StepupGateway\GatewayBundle\Sso2fa\Crypto\CryptoHelperInterface;
23
use Surfnet\StepupGateway\GatewayBundle\Sso2fa\Exception\CookieNotFoundException;
24
use Surfnet\StepupGateway\GatewayBundle\Sso2fa\ValueObject\Configuration;
25
use Surfnet\StepupGateway\GatewayBundle\Sso2fa\ValueObject\CookieValueInterface;
26
use Symfony\Component\HttpFoundation\Cookie;
27
use Symfony\Component\HttpFoundation\Request;
28
use Symfony\Component\HttpFoundation\Response;
29
30
class CookieHelper implements CookieHelperInterface
0 ignored issues
show
Coding Style introduced by
Missing doc comment for class CookieHelper
Loading history...
31
{
32
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
33
     * @var Configuration
34
     */
35
    private $configuration;
0 ignored issues
show
Coding Style introduced by
Private member variable "configuration" must be prefixed with an underscore
Loading history...
36
37
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
38
     * @var CryptoHelperInterface
39
     */
40
    private $encryptionHelper;
0 ignored issues
show
Coding Style introduced by
Private member variable "encryptionHelper" must be prefixed with an underscore
Loading history...
41
42
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
43
     * @var LoggerInterface
44
     */
45
    private $logger;
0 ignored issues
show
Coding Style introduced by
Private member variable "logger" must be prefixed with an underscore
Loading history...
46
47
    public function __construct(
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function __construct()
Loading history...
48
        Configuration $configuration,
49
        CryptoHelperInterface $encryptionHelper,
50
        LoggerInterface $logger
51
    ) {
52
        $this->configuration = $configuration;
53
        $this->encryptionHelper = $encryptionHelper;
54
        $this->logger = $logger;
55
    }
56
57
    public function write(Response $response, CookieValueInterface $value): void
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function write()
Loading history...
58
    {
59
        // The CookieValue is encrypted
60
        $encryptedCookieValue = $this->encryptionHelper->encrypt($value);
61
        $fingerprint = $this->hashFingerprint($encryptedCookieValue);
62
        $this->logger->notice(sprintf('Writing a SSO on 2FA cookie with fingerprint %s', $fingerprint));
63
        // Create a Symfony HttpFoundation cookie object
64
        $cookie = $this->createCookieWithValue($encryptedCookieValue);
65
        // Which is added to the response headers
66
        $response->headers->setCookie($cookie);
67
    }
68
69
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $request should have a doc-comment as per coding-style.
Loading history...
70
     * Retrieve the current cookie from the Request if it exists.
71
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
72
    public function read(Request $request): CookieValueInterface
73
    {
74
        if (!$request->cookies || !$request->cookies->has($this->configuration->getName())) {
75
            throw new CookieNotFoundException();
76
        }
77
        $cookie = $request->cookies->get($this->configuration->getName());
78
        $fingerprint = $this->hashFingerprint($cookie);
79
        $this->logger->notice(sprintf('Reading a SSO on 2FA cookie with fingerprint %s', $fingerprint));
80
        return $this->encryptionHelper->decrypt($cookie);
81
    }
82
83
    public function fingerprint(Request $request): string
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function fingerprint()
Loading history...
84
    {
85
        if (!$request->cookies || !$request->cookies->has($this->configuration->getName())) {
86
            throw new CookieNotFoundException();
87
        }
88
        $cookie = $request->cookies->get($this->configuration->getName());
89
        return $this->hashFingerprint($cookie);
90
    }
91
92
    private function createCookieWithValue($value): Cookie
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function createCookieWithValue()
Loading history...
Coding Style introduced by
Private method name "CookieHelper::createCookieWithValue" must be prefixed with an underscore
Loading history...
93
    {
94
        return new Cookie(
95
            $this->configuration->getName(),
96
            $value,
97
            $this->configuration->isPersistent() ? $this->getTimestamp($this->configuration->getLifetime()): 0,
98
            '/',
99
            null,
100
            true,
101
            true,
102
            false,
103
            Cookie::SAMESITE_STRICT
104
        );
105
    }
106
107
    private function hashFingerprint(string $encryptedCookieValue): string
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function hashFingerprint()
Loading history...
Coding Style introduced by
Private method name "CookieHelper::hashFingerprint" must be prefixed with an underscore
Loading history...
108
    {
109
        return hash('sha256', $encryptedCookieValue);
110
    }
111
112
    private function getTimestamp(int $expiresInSeconds): int
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function getTimestamp()
Loading history...
Coding Style introduced by
Private method name "CookieHelper::getTimestamp" must be prefixed with an underscore
Loading history...
113
    {
114
        $currentTimestamp = time();
115
        return $currentTimestamp + $expiresInSeconds;
116
    }
117
}
118