Passed
Pull Request — master (#124)
by Arman
06:03 queued 02:57
created

Csrf::deleteToken()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Quantum PHP Framework
5
 *
6
 * An open source software development framework for PHP
7
 *
8
 * @package Quantum
9
 * @author Arman Ag. <[email protected]>
10
 * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org)
11
 * @link http://quantum.softberg.org/
12
 * @since 2.9.0
13
 */
14
15
namespace Quantum\Libraries\Csrf;
16
17
use Quantum\Exceptions\DatabaseException;
18
use Quantum\Exceptions\CryptorException;
19
use Quantum\Exceptions\SessionException;
20
use Quantum\Exceptions\ConfigException;
21
use Quantum\Exceptions\CsrfException;
22
use Quantum\Exceptions\LangException;
23
use Quantum\Exceptions\DiException;
24
use Quantum\Libraries\Session\Session;
25
use Quantum\Libraries\Hasher\Hasher;
26
use ReflectionException;
27
28
/**
29
 * Class Csrf
30
 * @package Quantum\Libraries\Csrf
31
 */
32
class Csrf
33
{
34
    /**
35
     * Request methods to validate against
36
     */
37
    const METHODS = ['POST', 'PUT', 'PATCH', 'DELETE'];
38
39
    /**
40
     * Csrf token key
41
     */
42
    const TOKEN_KEY = 'csrf-token';
43
44
    /**
45
     * @var Csrf
46
     */
47
    private static $instance;
48
49
    /**
50
     * @var Session
51
     */
52
    private $storage;
53
54
    /**
55
     * @var Hasher
56
     */
57
    private $hasher;
58
59
    /**
60
     * @throws ConfigException
61
     * @throws SessionException
62
     * @throws LangException
63
     * @throws ReflectionException
64
     * @throws DiException
65
     * @throws DatabaseException
66
     */
67
    private function __construct()
68
    {
69
        $this->storage = session();
70
        $this->hasher = new Hasher();
71
    }
72
73
    /**
74
     * Csrf instance
75
     * @return Csrf
76
     */
77
    public static function getInstance(): Csrf
78
    {
79
        if (self::$instance === null) {
80
            self::$instance = new self();
81
        }
82
83
        return self::$instance;
84
    }
85
86
    /**
87
     * Generates the CSRF token or returns the previously generated one
88
     * @param string $key
89
     * @return string|null
90
     * @throws CryptorException
91
     */
92
    public function generateToken(string $key): ?string
93
    {
94
        if (!$this->storage->has(self::TOKEN_KEY)) {
95
            $this->storage->set(self::TOKEN_KEY, $this->hasher->hash($key));
96
        }
97
98
        return $this->storage->get(self::TOKEN_KEY);
99
    }
100
101
    /**
102
     * Checks the token
103
     * @param string|null $token
104
     * @return bool
105
     * @throws CryptorException
106
     * @throws CsrfException
107
     */
108
    public function checkToken(?string $token): bool
109
    {
110
        if (!$token) {
111
            throw CsrfException::tokenNotFound();
112
        }
113
114
        if ($this->storage->get(self::TOKEN_KEY) !== $token) {
115
            throw CsrfException::tokenNotMatched();
116
        }
117
118
        $this->storage->delete(self::TOKEN_KEY);
119
120
        return true;
121
    }
122
}
123