Completed
Push — master ( 8a3809...a85fa0 )
by Michał
03:13
created

Credentials   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 87
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 3
dl 0
loc 87
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 3
A getSecret() 0 4 1
B matches() 0 24 6
A unserialize() 0 7 1
A toArray() 0 7 1
1
<?php namespace nyx\auth;
2
3
// External dependencies
4
use nyx\core;
5
use nyx\diagnostics;
6
7
/**
8
 * Credentials
9
 *
10
 * @package     Nyx\Auth
11
 * @version     0.1.0
12
 * @author      Michal Chojnacki <[email protected]>
13
 * @copyright   2012-2017 Nyx Dev Team
14
 * @link        https://github.com/unyx/nyx
15
 */
16
class Credentials extends Token implements interfaces\Credentials
17
{
18
    /**
19
     * The traits of a Credentials instance.
20
     */
21
    use core\traits\Serializable;
22
23
    /**
24
     * @var string|interfaces\Credentials                   The secret associated with the underlying identifier.
25
     */
26
    protected $secret;
27
28
    /**
29
     * {@inheritDoc}
30
     *
31
     * @param   string|interfaces\Credentials   $secret     The secret associated with the underlying identifier.
32
     * @throws  \InvalidArgumentException                   When a secret of an invalid type is given.
33
     */
34
    public function __construct(string $id, $secret)
35
    {
36
        parent::__construct($id);
37
38
        if (!is_string($secret) && !$secret instanceof interfaces\Credentials) {
39
            throw new \InvalidArgumentException("The [secret] must be either a string or an instance of ".interfaces\Credentials::class.", got [".diagnostics\Debug::getTypeName($secret)."] instead.");
40
        }
41
42
        $this->secret = $secret;
43
    }
44
45
    /**
46
     * {@inheritDoc}
47
     */
48
    public function getSecret()
49
    {
50
        return $this->secret;
51
    }
52
53
    /**
54
     * {@inheritDoc}
55
     */
56
    public function matches(interfaces\Token $that) : bool
57
    {
58
        // The interface assumes Token comparisons but we need data from our own, stricter interface.
59
        // @todo Loosen the Token interface to allow mixed types for the matches() method?
60
        if (!$that instanceof interfaces\Credentials) {
61
            return false;
62
        }
63
64
        // $that's secret will be required more than once so let's reduce calls.
65
        $otherSecret = $that->getSecret();
66
67
        // In the case of nested Credentials we are going to need to check for equality of the underlying data.
68
        // If only one of the secrets is a Credentials instance, then the control structure will proceed to the
69
        // next block and catch that with the identity comparison (returning false there).
70
        if ($this->secret instanceof interfaces\Credentials && $otherSecret instanceof interfaces\Credentials) {
71
            if (!$this->secret->matches($otherSecret)) {
72
                return false;
73
            }
74
        } elseif ($this->secret !== $otherSecret) {
75
            return false;
76
        }
77
78
        return parent::matches($that);
79
    }
80
81
    /**
82
     * {@inheritDoc}
83
     */
84
    public function unserialize($data)
85
    {
86
        $data = unserialize($data);
87
88
        $this->id     = $data['id'];
89
        $this->secret = $data['secret'];
90
    }
91
92
    /**
93
     * {@inheritDoc}
94
     */
95
    public function toArray() : array
96
    {
97
        return [
98
            'id'     => $this->id,
99
            'secret' => $this->secret
100
        ];
101
    }
102
}
103