Failed Conditions
Push — master ( c24b3a...b512e9 )
by Florent
14:42
created

applyInitialAccessTokenRevokedEvent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * The MIT License (MIT)
7
 *
8
 * Copyright (c) 2014-2018 Spomky-Labs
9
 *
10
 * This software may be modified and distributed under the terms
11
 * of the MIT license.  See the LICENSE file for details.
12
 */
13
14
namespace OAuth2Framework\Component\ClientRegistrationEndpoint;
15
16
use OAuth2Framework\Component\Core\Domain\DomainObject;
17
use OAuth2Framework\Component\ClientRegistrationEndpoint\Event as InitialAccessTokenEvent;
18
use OAuth2Framework\Component\Core\Event\Event;
19
use OAuth2Framework\Component\Core\UserAccount\UserAccountId;
20
use SimpleBus\Message\Recorder\ContainsRecordedMessages;
21
use SimpleBus\Message\Recorder\PrivateMessageRecorderCapabilities;
22
23
class InitialAccessToken implements ContainsRecordedMessages, DomainObject
24
{
25
    use PrivateMessageRecorderCapabilities;
26
27
    /**
28
     * @var bool
29
     */
30
    private $revoked = false;
31
32
    /**
33
     * @var InitialAccessTokenId|null
34
     */
35
    private $initialAccessTokenId = null;
36
37
    /**
38
     * @var \DateTimeImmutable|null
39
     */
40
    private $expiresAt = null;
41
42
    /**
43
     * @var UserAccountId|null
44
     */
45
    private $userAccountId = null;
46
47
    /**
48
     * @return InitialAccessToken
49
     */
50
    public static function createEmpty(): self
51
    {
52
        return new self();
53
    }
54
55
    /**
56
     * @param InitialAccessTokenId    $initialAccessTokenId
57
     * @param UserAccountId           $userAccountId
58
     * @param \DateTimeImmutable|null $expiresAt
59
     *
60
     * @return InitialAccessToken
61
     */
62
    public function create(InitialAccessTokenId $initialAccessTokenId, UserAccountId $userAccountId, ? \DateTimeImmutable $expiresAt): self
63
    {
64
        $clone = clone $this;
65
        $clone->initialAccessTokenId = $initialAccessTokenId;
66
        $clone->expiresAt = $expiresAt;
67
        $clone->userAccountId = $userAccountId;
68
69
        $event = InitialAccessTokenEvent\InitialAccessTokenCreatedEvent::create($initialAccessTokenId, $userAccountId, $expiresAt);
70
        $clone->record($event);
71
72
        return $clone;
73
    }
74
75
    /**
76
     * @return InitialAccessTokenId
77
     */
78
    public function getTokenId(): InitialAccessTokenId
79
    {
80
        if (null === $this->initialAccessTokenId) {
81
            throw new \LogicException('Initial Access Token not initialized.');
82
        }
83
84
        return $this->initialAccessTokenId;
85
    }
86
87
    /**
88
     * @return UserAccountId
89
     */
90
    public function getUserAccountId(): UserAccountId
91
    {
92
        if (null === $this->userAccountId) {
93
            throw new \LogicException('Initial Access Token not initialized.');
94
        }
95
96
        return $this->userAccountId;
97
    }
98
99
    /**
100
     * @return \DateTimeImmutable|null
101
     */
102
    public function getExpiresAt(): ? \DateTimeImmutable
103
    {
104
        return $this->expiresAt;
105
    }
106
107
    /**
108
     * @return bool
109
     */
110
    public function hasExpired(): bool
111
    {
112
        return $this->expiresAt->getTimestamp() < time();
113
    }
114
115
    /**
116
     * @return bool
117
     */
118
    public function isRevoked(): bool
119
    {
120
        return $this->revoked;
121
    }
122
123
    /**
124
     * @return InitialAccessToken
125
     */
126
    public function markAsRevoked(): self
127
    {
128
        $clone = clone $this;
129
        $clone->revoked = true;
130
        $event = InitialAccessTokenEvent\InitialAccessTokenRevokedEvent::create($clone->getTokenId());
131
        $clone->record($event);
132
133
        return $clone;
134
    }
135
136
    /**
137
     * {@inheritdoc}
138
     */
139
    public static function getSchema(): string
140
    {
141
        return 'https://oauth2-framework.spomky-labs.com/schemas/model/initial-access-token/1.0/schema';
142
    }
143
144
    /**
145
     * {@inheritdoc}
146
     */
147
    public static function createFromJson(\stdClass $json): DomainObject
148
    {
149
        $initialAccessTokenId = InitialAccessTokenId::create($json->initial_access_token_id);
150
        $expiresAt = $json->expires_at ? \DateTimeImmutable::createFromFormat('U', (string) $json->expires_at) : null;
151
        $userAccountId = $json->user_account_id ? UserAccountId::create($json->user_account_id) : null;
152
        $revoked = $json->is_revoked;
153
154
        $initialAccessToken = new self();
155
        $initialAccessToken->initialAccessTokenId = $initialAccessTokenId;
156
        $initialAccessToken->userAccountId = $userAccountId;
157
        $initialAccessToken->expiresAt = $expiresAt;
158
        $initialAccessToken->revoked = $revoked;
159
160
        return $initialAccessToken;
161
    }
162
163
    /**
164
     * {@inheritdoc}
165
     */
166
    public function jsonSerialize()
167
    {
168
        $data = [
169
            '$schema' => $this->getSchema(),
170
            'type' => get_class($this),
171
            'initial_access_token_id' => $this->getTokenId() ? $this->getTokenId()->getValue() : null,
172
            'user_account_id' => $this->getUserAccountId() ? $this->getUserAccountId()->getValue() : null,
173
            'expires_at' => $this->getExpiresAt() ? $this->getExpiresAt()->getTimestamp() : null,
174
            'is_revoked' => $this->isRevoked(),
175
        ];
176
177
        return $data;
178
    }
179
180
    /**
181
     * @param Event $event
182
     *
183
     * @return InitialAccessToken
184
     */
185
    public function apply(Event $event): self
186
    {
187
        $map = $this->getEventMap();
188
        if (!array_key_exists($event->getType(), $map)) {
189
            throw new \InvalidArgumentException('Unsupported event.');
190
        }
191
        if (null !== $this->initialAccessTokenId && $this->initialAccessTokenId->getValue() !== $event->getDomainId()->getValue()) {
192
            throw new \InvalidArgumentException('Event not applicable for this initial access token.');
193
        }
194
        $method = $map[$event->getType()];
195
196
        return $this->$method($event);
197
    }
198
199
    /**
200
     * @return array
201
     */
202
    private function getEventMap(): array
203
    {
204
        return [
205
            InitialAccessTokenEvent\InitialAccessTokenCreatedEvent::class => 'applyInitialAccessTokenCreatedEvent',
206
            InitialAccessTokenEvent\InitialAccessTokenRevokedEvent::class => 'applyInitialAccessTokenRevokedEvent',
207
        ];
208
    }
209
210
    /**
211
     * @param InitialAccessTokenEvent\InitialAccessTokenCreatedEvent $event
212
     *
213
     * @return InitialAccessToken
214
     */
215
    protected function applyInitialAccessTokenCreatedEvent(InitialAccessTokenEvent\InitialAccessTokenCreatedEvent $event): self
216
    {
217
        $clone = clone $this;
218
        $clone->initialAccessTokenId = $event->getInitialAccessTokenId();
219
        $clone->expiresAt = $event->getExpiresAt();
220
        $clone->userAccountId = $event->getUserAccountId();
221
222
        return $clone;
223
    }
224
225
    /**
226
     * @param InitialAccessTokenEvent\InitialAccessTokenRevokedEvent $event
227
     *
228
     * @return InitialAccessToken
229
     */
230
    protected function applyInitialAccessTokenRevokedEvent(InitialAccessTokenEvent\InitialAccessTokenRevokedEvent $event): self
231
    {
232
        $clone = clone $this;
233
        $clone->revoked = true;
234
235
        return $clone;
236
    }
237
}
238