Failed Conditions
Push — master ( 4fec28...cca42a )
by Florent
04:20
created

AuthorizationCode::getAuthorizationCodeId()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 0
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 AuthorizationCodeId
112
     */
113
    public function getAuthorizationCodeId(): AuthorizationCodeId
114
    {
115
        $id = $this->getTokenId();
116
        if (!$id instanceof AuthorizationCodeId) {
117
            throw new \RuntimeException('Authorization code not initialized.');
118
        }
119
120
        return $this->authorizationCodeId;
121
    }
122
123
124
    /**
125
     * @return array
126
     */
127
    public function getQueryParameters(): array
128
    {
129
        return $this->queryParameters;
130
    }
131
132
    /**
133
     * @return bool
134
     */
135
    public function isUsed(): bool
136
    {
137
        return $this->used;
138
    }
139
140
    /**
141
     * @return AuthorizationCode
142
     */
143
    public function markAsUsed(): self
144
    {
145
        if (true === $this->used) {
146
            return $this;
147
        }
148
        $clone = clone $this;
149
        $clone->used = true;
150
        $event = AuthorizationCodeEvent\AuthorizationCodeMarkedAsUsedEvent::create($clone->getTokenId());
151
        $clone->record($event);
152
153
        return $clone;
154
    }
155
156
    /**
157
     * @return AuthorizationCode
158
     */
159
    public function markAsRevoked(): self
160
    {
161
        $clone = clone $this;
162
        $clone->revoked = true;
163
        $event = AuthorizationCodeEvent\AuthorizationCodeRevokedEvent::create($clone->getTokenId());
164
        $clone->record($event);
165
166
        return $clone;
167
    }
168
169
    /**
170
     * @return array
171
     */
172
    public function getQueryParams(): array
173
    {
174
        return $this->queryParameters;
175
    }
176
177
    /**
178
     * @param string $key
179
     *
180
     * @return mixed
181
     */
182
    public function getQueryParam(string $key)
183
    {
184
        if ($this->hasQueryParams($key)) {
185
            throw new \RuntimeException(sprintf('Query parameter with key "%s" does not exist.', $key));
186
        }
187
188
        return $this->queryParameters[$key];
189
    }
190
191
    /**
192
     * @param string $key
193
     *
194
     * @return bool
195
     */
196
    public function hasQueryParams(string $key): bool
197
    {
198
        return array_key_exists($key, $this->getQueryParams());
199
    }
200
201
    /**
202
     * @return string
203
     */
204
    public function getRedirectUri(): string
205
    {
206
        if (null === $this->authorizationCodeId) {
207
            throw new \RuntimeException('Authorization code not initialized.');
208
        }
209
210
        return $this->redirectUri;
211
    }
212
213
    /**
214
     * @return array
215
     */
216
    public function toArray(): array
217
    {
218
        return [
219
            'code' => $this->getTokenId()->getValue(),
220
        ];
221
    }
222
223
    /**
224
     * {@inheritdoc}
225
     */
226
    public static function createFromJson(\stdClass $json): DomainObject
227
    {
228
        $authorizationCodeId = AuthorizationCodeId::create($json->auth_code_id);
229
        $queryParameters = (array) $json->query_parameters;
230
        $redirectUri = $json->redirect_uri;
231
        $resourceServerId = null !== $json->resource_server_id ? ResourceServerId::create($json->resource_server_id) : null;
232
        $used = $json->is_used;
233
234
        $expiresAt = \DateTimeImmutable::createFromFormat('U', (string) $json->expires_at);
235
        $clientId = ClientId::create($json->client_id);
236
        $parameters = DataBag::create((array) $json->parameters);
237
        $metadatas = DataBag::create((array) $json->metadatas);
238
        $revoked = $json->is_revoked;
239
        $resourceOwnerClass = $json->resource_owner_class;
240
        $resourceOwnerId = $resourceOwnerClass::create($json->resource_owner_id);
241
242
        $authorizationCode = new self();
243
        $authorizationCode->authorizationCodeId = $authorizationCodeId;
244
        $authorizationCode->queryParameters = $queryParameters;
245
        $authorizationCode->redirectUri = $redirectUri;
246
        $authorizationCode->used = $used;
247
        $authorizationCode->resourceServerId = $resourceServerId;
248
249
        $authorizationCode->expiresAt = $expiresAt;
250
        $authorizationCode->clientId = $clientId;
251
        $authorizationCode->parameters = $parameters;
252
        $authorizationCode->metadatas = $metadatas;
253
        $authorizationCode->revoked = $revoked;
254
        $authorizationCode->resourceOwnerId = $resourceOwnerId;
255
256
        return $authorizationCode;
257
    }
258
259
    /**
260
     * {@inheritdoc}
261
     */
262
    public function jsonSerialize()
263
    {
264
        $data = parent::jsonSerialize() + [
265
                'auth_code_id' => $this->getTokenId()->getValue(),
266
                'query_parameters' => (object) $this->getQueryParameters(),
267
                'redirect_uri' => $this->getRedirectUri(),
268
                'is_used' => $this->isUsed(),
269
            ];
270
271
        return $data;
272
    }
273
274
    /**
275
     * @param Event $event
276
     *
277
     * @return AuthorizationCode
278
     */
279
    public function apply(Event $event): self
280
    {
281
        $map = $this->getEventMap();
282
        if (!array_key_exists($event->getType(), $map)) {
283
            throw new \RuntimeException('Unsupported event.');
284
        }
285
        if (null !== $this->authorizationCodeId && $this->authorizationCodeId->getValue() !== $event->getDomainId()->getValue()) {
286
            throw new \RuntimeException('Event not applicable for this authorization code.');
287
        }
288
        $method = $map[$event->getType()];
289
290
        return $this->$method($event);
291
    }
292
293
    /**
294
     * @return array
295
     */
296
    private function getEventMap(): array
297
    {
298
        return [
299
            AuthorizationCodeEvent\AuthorizationCodeCreatedEvent::class => 'applyAuthorizationCodeCreatedEvent',
300
            AuthorizationCodeEvent\AuthorizationCodeMarkedAsUsedEvent::class => 'applyAuthorizationCodeMarkedAsUsedEvent',
301
            AuthorizationCodeEvent\AuthorizationCodeRevokedEvent::class => 'applyAuthorizationCodeRevokedEvent',
302
        ];
303
    }
304
305
    /**
306
     * @param AuthorizationCodeEvent\AuthorizationCodeCreatedEvent $event
307
     *
308
     * @return AuthorizationCode
309
     */
310
    protected function applyAuthorizationCodeCreatedEvent(AuthorizationCodeEvent\AuthorizationCodeCreatedEvent $event): self
311
    {
312
        $clone = clone $this;
313
        $clone->authorizationCodeId = $event->getAuthorizationCodeId();
314
        $clone->clientId = $event->getClientId();
315
        $clone->resourceOwnerId = $event->getUserAccountId();
316
        $clone->queryParameters = $event->getQueryParameters();
317
        $clone->redirectUri = $event->getRedirectUri();
318
        $clone->expiresAt = $event->getExpiresAt();
319
        $clone->parameters = $event->getParameters();
320
        $clone->metadatas = $event->getMetadatas();
321
        $clone->expiresAt = $event->getExpiresAt();
322
        $clone->resourceServerId = $event->getResourceServerId();
323
324
        return $clone;
325
    }
326
327
    /**
328
     * @param AuthorizationCodeEvent\AuthorizationCodeMarkedAsUsedEvent $event
329
     *
330
     * @return AuthorizationCode
331
     */
332
    protected function applyAuthorizationCodeMarkedAsUsedEvent(AuthorizationCodeEvent\AuthorizationCodeMarkedAsUsedEvent $event): self
333
    {
334
        $clone = clone $this;
335
        $clone->used = true;
336
337
        return $clone;
338
    }
339
340
    /**
341
     * @param AuthorizationCodeEvent\AuthorizationCodeRevokedEvent $event
342
     *
343
     * @return AuthorizationCode
344
     */
345
    protected function applyAuthorizationCodeRevokedEvent(AuthorizationCodeEvent\AuthorizationCodeRevokedEvent $event): self
346
    {
347
        $clone = clone $this;
348
        $clone->revoked = true;
349
350
        return $clone;
351
    }
352
}
353