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