Passed
Pull Request — master (#83)
by Robbie
02:06
created

SessionStore::create()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 2
nop 1
dl 0
loc 16
rs 10
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
A SessionStore::getMember() 0 3 1
1
<?php declare(strict_types=1);
2
3
namespace SilverStripe\MFA\Store;
4
5
use SilverStripe\Control\HTTPRequest;
6
use SilverStripe\MFA\Extension\MemberExtension;
7
use SilverStripe\ORM\DataObject;
8
use SilverStripe\Security\Member;
9
10
/**
11
 * This class provides an interface to store data in session during an MFA process. This is implemented as a measure to
12
 * prevent bleeding state between individual MFA auth types
13
 *
14
 * @package SilverStripe\MFA
15
 */
16
class SessionStore implements StoreInterface
17
{
18
    const SESSION_KEY = 'MFASessionStore';
19
20
    /**
21
     * The member that is currently going through the MFA process
22
     *
23
     * @var Member
24
     */
25
    protected $member;
26
27
    /**
28
     * A string representing the current authentication method that is underway
29
     *
30
     * @var string
31
     */
32
    protected $method;
33
34
    /**
35
     * Any state that the current authentication method needs to retain while it is underway
36
     *
37
     * @var array
38
     */
39
    protected $state = [];
40
41
    /**
42
     * Attempt to create a store from the given request getting any existing state from the session of the request
43
     *
44
     * {@inheritdoc}
45
     */
46
    public function __construct(HTTPRequest $request = null)
47
    {
48
        $state = $request ? $request->getSession()->get(static::SESSION_KEY) : null;
49
50
        if ($state && $state['member']) {
51
            /** @var Member $member */
52
            $member = DataObject::get_by_id(Member::class, $state['member']);
53
54
            $this->setMember($member);
55
            $this->setMethod($state['method']);
56
            $this->setState($state['state']);
57
        }
58
    }
59
60
    /**
61
     * @return Member&MemberExtension|null
62
     */
63
    public function getMember(): ?Member
64
    {
65
        return $this->member;
66
    }
67
68
    /**
69
     * @param Member $member
70
     * @return $this
71
     */
72
    public function setMember(Member $member): StoreInterface
73
    {
74
        // Early return if there's no change
75
        if ($this->member && $this->member->ID === $member->ID) {
76
            return $this;
77
        }
78
79
        // If the member has changed we should null out the method that's underway and the state of it
80
        $this->resetMethod();
81
82
        $this->member = $member;
83
84
        return $this;
85
    }
86
87
    /**
88
     * @return string|null
89
     */
90
    public function getMethod(): ?string
91
    {
92
        return $this->method;
93
    }
94
95
    /**
96
     * @param string $method
97
     * @return $this
98
     */
99
    public function setMethod($method): StoreInterface
100
    {
101
        $this->method = $method;
102
103
        return $this;
104
    }
105
106
    public function getState(): array
107
    {
108
        return $this->state;
109
    }
110
111
    public function setState(array $state): StoreInterface
112
    {
113
        $this->state = $state;
114
115
        return $this;
116
    }
117
118
    /**
119
     * Save this store into the session of the given request
120
     *
121
     * {@inheritdoc}
122
     */
123
    public function save(HTTPRequest $request): StoreInterface
124
    {
125
        $request->getSession()->set(static::SESSION_KEY, $this->build());
126
127
        return $this;
128
    }
129
130
    /**
131
     * Clear any stored values for the given request
132
     *
133
     * {@inheritdoc}
134
     */
135
    public static function clear(HTTPRequest $request): void
136
    {
137
        $request->getSession()->clear(static::SESSION_KEY);
138
    }
139
140
    protected function resetMethod(): StoreInterface
141
    {
142
        $this->setMethod(null)->setState([]);
143
144
        return $this;
145
    }
146
147
    protected function build(): array
148
    {
149
        return [
150
            'member' => $this->getMember() ? $this->getMember()->ID : null,
151
            'method' => $this->getMethod(),
152
            'state' => $this->getState(),
153
        ];
154
    }
155
}
156