Completed
Push — feature/controller ( 5a6415...9e7a26 )
by René
07:43 queued 05:40
created

Cookie::getTokenString()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 22
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6
Metric Value
dl 0
loc 22
ccs 0
cts 9
cp 0
rs 9.2
cc 2
eloc 9
nc 2
nop 0
crap 6
1
<?php
2
declare(strict_types = 1);
3
4
namespace Zortje\MVC\Storage\Cookie;
5
6
use Lcobucci\JWT\Builder;
7
use Lcobucci\JWT\Claim;
8
use Lcobucci\JWT\Parser;
9
use Lcobucci\JWT\Signer\Hmac\Sha256;
10
use Lcobucci\JWT\ValidationData;
11
use Zortje\MVC\Configuration\Configuration;
12
use Zortje\MVC\Storage\Cookie\Exception\CookieUndefinedIndexException;
13
14
/**
15
 * Class Cookie
16
 *
17
 * @package Zortje\MVC\Storage
18
 */
19
class Cookie
20
{
21
22
    const ISSUER = 'zortje/mvc';
23
24
    /**
25
     * @var Configuration
26
     */
27
    protected $configuration;
28
29
    /**
30
     * @var string[] Internal cookie values
31
     */
32
    protected $values = [];
33
34
    /**
35
     * Cookie constructor.
36
     *
37
     * @param Configuration $configuration Configuration
38
     * @param string        $token         JWT string
39
     */
40 1
    public function __construct(Configuration $configuration, string $token = '')
41
    {
42 1
        $this->configuration = $configuration;
43 1
        $this->values        = $this->parseAndValidateToken($token);
44 1
    }
45
46
    /**
47
     * Set value in cookie
48
     *
49
     * @param string $key   Cookie key
50
     * @param string $value Cookie value
51
     */
52 2
    public function set(string $key, string $value)
53
    {
54 2
        $this->values[$key] = $value;
55 2
    }
56
57
    /**
58
     * Get value from cookie
59
     *
60
     * @param string $key Cookie key
61
     *
62
     * @return string Cookie value
63
     *
64
     * @throws CookieUndefinedIndexException
65
     */
66 1
    public function get(string $key): string
67
    {
68 1
        if (isset($this->values[$key]) === false) {
69
            throw new CookieUndefinedIndexException([$key]);
70
        }
71
72 1
        return $this->values[$key];
73
    }
74
75
    /**
76
     * @return string JWT string
77
     */
78
    public function getTokenString(): string
79
    {
80
        /**
81
         * Build Token
82
         */
83
        $builder = (new Builder());
84
        $builder->setIssuer(self::ISSUER);
85
        $builder->setExpiration((new \DateTime($this->configuration->get('Cookie.TTL')))->getTimestamp());
86
87
        foreach ($this->values as $key => $value) {
88
            $builder->set($key, $value);
89
        }
90
91
        /**
92
         * Sign and generate new token
93
         */
94
        $builder->sign(new Sha256(), $this->configuration->get('Cookie.Signer.Key'));
95
96
        $token = $builder->getToken();
97
98
        return (string)$token;
99
    }
100
101
    protected function parseAndValidateToken(string $token)
102
    {
103
        try {
104
            $token = (new Parser())->parse($token);
105
106
            // @todo How to test: It will use the current time to validate (iat, nbf and exp)
107
            $data = new ValidationData();
108
            $data->setIssuer(self::ISSUER);
109
110
            $values = [];
111
112
            if ($token->validate($data) && $token->verify(new Sha256(), $this->configuration->get('Cookie.Signer.Key'))) {
113
                /**
114
                 * @var Claim $claim
115
                 */
116
                $ignored = array_fill_keys(['iss', 'exp'], true);
117
118
                foreach ($token->getClaims() as $claim) {
119
                    if (isset($ignored[$claim->getName()])) {
120
                        continue;
121
                    }
122
123
                    $values[$claim->getName()] = $claim->getValue();
124
                }
125
            }
126
127
            return $values;
128
        } catch (\InvalidArgumentException $e) {
129
            return [];
130
        }
131
    }
132
}
133