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.

Hash   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 195
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 16
c 1
b 0
f 0
lcom 1
cbo 1
dl 0
loc 195
rs 10

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A __call() 0 4 1
A getHasher() 0 4 1
A hash() 0 7 1
A verify() 0 8 1
A shortHash() 0 4 1
A compare() 0 4 1
A getDataString() 0 8 2
A parseHashOptions() 0 11 2
A setSalt() 0 15 4
A verifyShortHash() 0 7 1
1
<?php
2
/**
3
 * Hash.php
4
 *
5
 * @category    AngryBytes
6
 * @package     Hash
7
 * @copyright   Copyright (c) 2007-2016 Angry Bytes BV (http://www.angrybytes.com)
8
 */
9
10
namespace AngryBytes\Hash;
11
12
use \InvalidArgumentException;
13
14
/**
15
 * A collection of hash generation and comparison methods.
16
 *
17
 * This Hash library must receive a \AngryBytes\HasherInterface compatible
18
 * instance to work with.
19
 *
20
 * Providing a salt is strictly optional, and should not be provided when the
21
 * hasher provides better salt generation methods.
22
 *
23
 * @category    AngryBytes
24
 * @package     Hash
25
 */
26
class Hash
27
{
28
    /**
29
     * Salt for hashing
30
     *
31
     * @var string|null
32
     **/
33
    private $salt;
34
35
    /**
36
     * Hasher
37
     *
38
     * @var HasherInterface
39
     **/
40
    private $hasher;
41
42
    /**
43
     * Constructor
44
     *
45
     * @param  HasherInterface $hasher The hasher to be used
46
     * @param  string|bool     $salt (optional) Omit if the hasher creates its own (better) salt
47
     **/
48
    public function __construct(HasherInterface $hasher, $salt = null)
49
    {
50
        $this->hasher = $hasher;
51
52
        $this->setSalt($salt);
0 ignored issues
show
Bug introduced by
It seems like $salt defined by parameter $salt on line 48 can also be of type boolean; however, AngryBytes\Hash\Hash::setSalt() does only seem to accept string|null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
53
    }
54
55
    /**
56
     * Dynamically pass methods to the active hasher
57
     *
58
     * @param string $method
59
     * @param array $parameters
60
     */
61
    public function __call($method, $parameters)
62
    {
63
        return $this->hasher->$method(...$parameters);
64
    }
65
66
    /**
67
     * Get the hasher to use for the actual hashing
68
     *
69
     * @return HasherInterface
70
     */
71
    public function getHasher()
72
    {
73
        return $this->hasher;
74
    }
75
76
    /**
77
     * Generate a hash
78
     *
79
     * @param mixed $data The data to hash. This can either be a scalar value or a serializable value.
80
     * @param mixed[] $options Additional hasher options (the actual options depend on the registered Hasher)
81
     * @return string
82
     **/
83
    public function hash($data, array $options = [])
84
    {
85
        return $this->hasher->hash(
86
            self::getDataString($data),
87
            $this->parseHashOptions($options)
88
        );
89
    }
90
91
    /**
92
     * Verify if the data matches the hash
93
     *
94
     * @param mixed $data The data to verify against the hash string. This can either be a scalar value or a serializable value.
95
     * @param string $hash
96
     * @param mixed[] $options
97
     * @return bool
98
     */
99
    public function verify($data, $hash, array $options = [])
100
    {
101
        return $this->hasher->verify(
102
            self::getDataString($data),
103
            $hash,
104
            $this->parseHashOptions($options)
105
        );
106
    }
107
108
    /**
109
     * Hash something into a short hash
110
     *
111
     * This is simply a shortened version of hash(), returning a 7 character hash, which should be good
112
     * enough for identification purposes. Therefore it MUST NOT be used for cryptographic purposes or
113
     * password storage but only to create a fast, short string to compare or identify.
114
     *
115
     * It is RECOMMENDED to only use this method with the Hasher\MD5 hasher as hashes
116
     * created by bcrypt/crypt() have a common beginning.
117
     *
118
     * @see Hash::hash()
119
     *
120
     * @param string $data
121
     * @param mixed[] $options
122
     * @return string
123
     */
124
    public function shortHash($data, array $options = [])
125
    {
126
        return substr($this->hash($data, $options), 0, 7);
127
    }
128
129
    /**
130
     * Verify if the data matches the shortHash
131
     *
132
     * @see Hash::shortHash()
133
     *
134
     * @param mixed $data
135
     * @param string $shortHash
136
     * @param mixed[] $options
137
     * @return bool
138
     **/
139
    public function verifyShortHash($data, $shortHash, array $options = [])
140
    {
141
        return self::compare(
142
            $this->shortHash($data, $options),
143
            $shortHash
144
        );
145
    }
146
147
    /**
148
     * Compare two hashes
149
     *
150
     * Uses the time-save `hash_equals()` function to compare 2 hashes.
151
     *
152
     * @param  string $hashA
153
     * @param  string $hashB
154
     * @return bool
155
     **/
156
    public static function compare($hashA, $hashB)
157
    {
158
        return hash_equals($hashA, $hashB);
159
    }
160
161
    /**
162
     * Set the salt
163
     *
164
     * @param  string|null $salt
165
     * @return Hash
166
     */
167
    protected function setSalt($salt)
168
    {
169
        if (is_string($salt) && (strlen($salt) < 20 || strlen($salt) > CRYPT_SALT_LENGTH)) {
170
            // Make sure it's of sufficient length
171
            throw new InvalidArgumentException(sprintf(
172
                'Provided salt "%s" does not match the length requirements. A length between 20 en %d characters is required.',
173
                $salt,
174
                CRYPT_SALT_LENGTH
175
            ));
176
        }
177
178
        $this->salt = $salt;
179
180
        return $this;
181
    }
182
183
    /**
184
     * Get the data as a string
185
     *
186
     * Will serialize non-scalar values
187
     *
188
     * @param mixed $data
189
     * @return string
190
     */
191
    private static function getDataString($data)
192
    {
193
        if (is_scalar($data)) {
194
            return (string) $data;
195
        }
196
197
        return serialize($data);
198
    }
199
200
    /**
201
     * Merge the default and provided hash options
202
     *
203
     * Automatically sets the salt as an option when set in this
204
     * component.
205
     *
206
     * @param mixed[] $options
207
     * @return mixed[]
208
     */
209
    private function parseHashOptions(array $options = [])
210
    {
211
        $defaultOptions = [];
212
213
        // Pass the salt if set
214
        if (!is_null($this->salt)) {
215
            $defaultOptions['salt'] = $this->salt;
216
        }
217
218
        return array_merge($defaultOptions, $options);
219
    }
220
}
221