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

applyAuthorizationCodeRevokedEvent()   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\AuthorizationCodeGrant;
15
16
use OAuth2Framework\Component\AuthorizationCodeGrant\Event as AuthorizationCodeEvent;
17
use OAuth2Framework\Component\Core\Client\ClientId;
18
use OAuth2Framework\Component\Core\DataBag\DataBag;
19
use OAuth2Framework\Component\Core\Domain\DomainObject;
20
use OAuth2Framework\Component\Core\Event\Event;
21
use OAuth2Framework\Component\Core\ResourceServer\ResourceServerId;
22
use OAuth2Framework\Component\Core\Token\Token;
23
use OAuth2Framework\Component\Core\Token\TokenId;
24
use OAuth2Framework\Component\Core\UserAccount\UserAccountId;
25
26
class AuthorizationCode extends Token
27
{
28
    /**
29
     * @var AuthorizationCodeId
30
     */
31
    private $authorizationCodeId = null;
32
33
    /**
34
     * @var array
35
     */
36
    private $queryParameters = [];
37
38
    /**
39
     * @var string
40
     */
41
    private $redirectUri = null;
42
43
    /**
44
     * @var bool
45
     */
46
    private $used = false;
47
48
    /**
49
     * @return AuthorizationCode
50
     */
51
    public static function createEmpty(): self
52
    {
53
        return new self();
54
    }
55
56
    /**
57
     * {@inheritdoc}
58
     */
59
    public static function getSchema(): string
60
    {
61
        return 'https://oauth2-framework.spomky-labs.com/schemas/model/authorization-code/1.0/schema';
62
    }
63
64
    /**
65
     * @param AuthorizationCodeId $authorizationCodeId
66
     * @param ClientId            $clientId
67
     * @param UserAccountId       $userAccountId
68
     * @param array               $queryParameters
69
     * @param string              $redirectUri
70
     * @param \DateTimeImmutable  $expiresAt
71
     * @param DataBag             $parameters
72
     * @param DataBag             $metadatas
73
     * @param ResourceServerId    $resourceServerId
74
     *
75
     * @return AuthorizationCode
76
     */
77
    public function create(AuthorizationCodeId $authorizationCodeId, ClientId $clientId, UserAccountId $userAccountId, array $queryParameters, string $redirectUri, \DateTimeImmutable $expiresAt, DataBag $parameters, DataBag $metadatas, ? ResourceServerId $resourceServerId)
78
    {
79
        $clone = clone $this;
80
        $clone->authorizationCodeId = $authorizationCodeId;
81
        $clone->clientId = $clientId;
82
        $clone->resourceOwnerId = $userAccountId;
83
        $clone->queryParameters = $queryParameters;
84
        $clone->redirectUri = $redirectUri;
85
        $clone->authorizationCodeId = $authorizationCodeId;
86
        $clone->expiresAt = $expiresAt;
87
        $clone->parameters = $parameters;
88
        $clone->metadatas = $metadatas;
89
        $clone->expiresAt = $expiresAt;
90
        $clone->resourceServerId = $resourceServerId;
91
92
        $event = AuthorizationCodeEvent\AuthorizationCodeCreatedEvent::create($authorizationCodeId, $clientId, $userAccountId, $queryParameters, $redirectUri, $expiresAt, $parameters, $metadatas, $resourceServerId);
93
        $clone->record($event);
94
95
        return $clone;
96
    }
97
98
    /**
99
     * {@inheritdoc}
100
     */
101
    public function getTokenId(): TokenId
102
    {
103
        if (null === $this->authorizationCodeId) {
104
            throw new \RuntimeException('Authorization code not initialized.');
105
        }
106
107
        return $this->authorizationCodeId;
108
    }
109
110
    /**
111
     * @return array
112
     */
113
    public function getQueryParameters(): array
114
    {
115
        return $this->queryParameters;
116
    }
117
118
    /**
119
     * @return bool
120
     */
121
    public function isUsed(): bool
122
    {
123
        return $this->used;
124
    }
125
126
    /**
127
     * @return AuthorizationCode
128
     */
129
    public function markAsUsed(): self
130
    {
131
        if (true === $this->used) {
132
            return $this;
133
        }
134
        $clone = clone $this;
135
        $clone->used = true;
136
        $event = AuthorizationCodeEvent\AuthorizationCodeMarkedAsUsedEvent::create($clone->getTokenId());
137
        $clone->record($event);
138
139
        return $clone;
140
    }
141
142
    /**
143
     * @return AuthorizationCode
144
     */
145
    public function markAsRevoked(): self
146
    {
147
        $clone = clone $this;
148
        $clone->revoked = true;
149
        $event = AuthorizationCodeEvent\AuthorizationCodeRevokedEvent::create($clone->getTokenId());
150
        $clone->record($event);
151
152
        return $clone;
153
    }
154
155
    /**
156
     * @return array
157
     */
158
    public function getQueryParams(): array
159
    {
160
        return $this->queryParameters;
161
    }
162
163
    /**
164
     * @param string $key
165
     *
166
     * @return mixed
167
     */
168
    public function getQueryParam(string $key)
169
    {
170
        if ($this->hasQueryParams($key)) {
171
            throw new \RuntimeException(sprintf('Query parameter with key "%s" does not exist.', $key));
172
        }
173
174
        return $this->queryParameters[$key];
175
    }
176
177
    /**
178
     * @param string $key
179
     *
180
     * @return bool
181
     */
182
    public function hasQueryParams(string $key): bool
183
    {
184
        return array_key_exists($key, $this->getQueryParams());
185
    }
186
187
    /**
188
     * @return string
189
     */
190
    public function getRedirectUri(): string
191
    {
192
        if (null === $this->authorizationCodeId) {
193
            throw new \RuntimeException('Authorization code not initialized.');
194
        }
195
196
        return $this->redirectUri;
197
    }
198
199
    /**
200
     * @return array
201
     */
202
    public function toArray(): array
203
    {
204
        return [
205
            'code' => $this->getTokenId()->getValue(),
206
        ];
207
    }
208
209
    /**
210
     * {@inheritdoc}
211
     */
212
    public static function createFromJson(\stdClass $json): DomainObject
213
    {
214
        $authorizationCodeId = AuthorizationCodeId::create($json->auth_code_id);
215
        $queryParameters = (array) $json->query_parameters;
216
        $redirectUri = $json->redirect_uri;
217
        $resourceServerId = null !== $json->resource_server_id ? ResourceServerId::create($json->resource_server_id) : null;
218
        $used = $json->is_used;
219
220
        $expiresAt = \DateTimeImmutable::createFromFormat('U', (string) $json->expires_at);
221
        $clientId = ClientId::create($json->client_id);
222
        $parameters = DataBag::create((array) $json->parameters);
223
        $metadatas = DataBag::create((array) $json->metadatas);
224
        $revoked = $json->is_revoked;
225
        $resourceOwnerClass = $json->resource_owner_class;
226
        $resourceOwnerId = $resourceOwnerClass::create($json->resource_owner_id);
227
228
        $authorizationCode = new self();
229
        $authorizationCode->authorizationCodeId = $authorizationCodeId;
230
        $authorizationCode->queryParameters = $queryParameters;
231
        $authorizationCode->redirectUri = $redirectUri;
232
        $authorizationCode->used = $used;
233
        $authorizationCode->resourceServerId = $resourceServerId;
234
235
        $authorizationCode->expiresAt = $expiresAt;
236
        $authorizationCode->clientId = $clientId;
237
        $authorizationCode->parameters = $parameters;
238
        $authorizationCode->metadatas = $metadatas;
239
        $authorizationCode->revoked = $revoked;
240
        $authorizationCode->resourceOwnerId = $resourceOwnerId;
241
242
        return $authorizationCode;
243
    }
244
245
    /**
246
     * {@inheritdoc}
247
     */
248
    public function jsonSerialize()
249
    {
250
        $data = parent::jsonSerialize() + [
251
                'auth_code_id' => $this->getTokenId()->getValue(),
252
                'query_parameters' => (object) $this->getQueryParameters(),
253
                'redirect_uri' => $this->getRedirectUri(),
254
                'is_used' => $this->isUsed(),
255
            ];
256
257
        return $data;
258
    }
259
260
    /**
261
     * @param Event $event
262
     *
263
     * @return AuthorizationCode
264
     */
265
    public function apply(Event $event): self
266
    {
267
        $map = $this->getEventMap();
268
        if (!array_key_exists($event->getType(), $map)) {
269
            throw new \RuntimeException('Unsupported event.');
270
        }
271
        if (null !== $this->authorizationCodeId && $this->authorizationCodeId->getValue() !== $event->getDomainId()->getValue()) {
272
            throw new \RuntimeException('Event not applicable for this authorization code.');
273
        }
274
        $method = $map[$event->getType()];
275
276
        return $this->$method($event);
277
    }
278
279
    /**
280
     * @return array
281
     */
282
    private function getEventMap(): array
283
    {
284
        return [
285
            AuthorizationCodeEvent\AuthorizationCodeCreatedEvent::class => 'applyAuthorizationCodeCreatedEvent',
286
            AuthorizationCodeEvent\AuthorizationCodeMarkedAsUsedEvent::class => 'applyAuthorizationCodeMarkedAsUsedEvent',
287
            AuthorizationCodeEvent\AuthorizationCodeRevokedEvent::class => 'applyAuthorizationCodeRevokedEvent',
288
        ];
289
    }
290
291
    /**
292
     * @param AuthorizationCodeEvent\AuthorizationCodeCreatedEvent $event
293
     *
294
     * @return AuthorizationCode
295
     */
296
    protected function applyAuthorizationCodeCreatedEvent(AuthorizationCodeEvent\AuthorizationCodeCreatedEvent $event): self
297
    {
298
        $clone = clone $this;
299
        $clone->authorizationCodeId = $event->getAuthorizationCodeId();
300
        $clone->clientId = $event->getClientId();
301
        $clone->resourceOwnerId = $event->getUserAccountId();
302
        $clone->queryParameters = $event->getQueryParameters();
303
        $clone->redirectUri = $event->getRedirectUri();
304
        $clone->expiresAt = $event->getExpiresAt();
305
        $clone->parameters = $event->getParameters();
306
        $clone->metadatas = $event->getMetadatas();
307
        $clone->expiresAt = $event->getExpiresAt();
308
        $clone->resourceServerId = $event->getResourceServerId();
309
310
        return $clone;
311
    }
312
313
    /**
314
     * @param AuthorizationCodeEvent\AuthorizationCodeMarkedAsUsedEvent $event
315
     *
316
     * @return AuthorizationCode
317
     */
318
    protected function applyAuthorizationCodeMarkedAsUsedEvent(AuthorizationCodeEvent\AuthorizationCodeMarkedAsUsedEvent $event): self
319
    {
320
        $clone = clone $this;
321
        $clone->used = true;
322
323
        return $clone;
324
    }
325
326
    /**
327
     * @param AuthorizationCodeEvent\AuthorizationCodeRevokedEvent $event
328
     *
329
     * @return AuthorizationCode
330
     */
331
    protected function applyAuthorizationCodeRevokedEvent(AuthorizationCodeEvent\AuthorizationCodeRevokedEvent $event): self
332
    {
333
        $clone = clone $this;
334
        $clone->revoked = true;
335
336
        return $clone;
337
    }
338
}
339