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

AccessToken::markAsRevoked()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 1
eloc 6
nc 1
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\Core\AccessToken;
15
16
use OAuth2Framework\Component\Core\AccessToken\Event as AccessTokenEvent;
17
use OAuth2Framework\Component\Core\Client\ClientId;
18
use OAuth2Framework\Component\Core\DataBag\DataBag;
19
use OAuth2Framework\Component\Core\Event\Event;
20
use OAuth2Framework\Component\Core\ResourceOwner\ResourceOwnerId;
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\Domain\DomainObject;
25
26
class AccessToken extends Token
27
{
28
    /**
29
     * @var AccessTokenId
30
     */
31
    private $accessTokenId = null;
32
33
    /**
34
     * @return AccessToken
35
     */
36
    public static function createEmpty(): self
37
    {
38
        return new self();
39
    }
40
41
    /**
42
     * {@inheritdoc}
43
     */
44
    public static function getSchema(): string
45
    {
46
        return 'https://oauth2-framework.spomky-labs.com/schemas/model/access-token/1.0/schema';
47
    }
48
49
    /**
50
     * @param AccessTokenId         $accessTokenId
51
     * @param ResourceOwnerId       $resourceOwnerId
52
     * @param ClientId              $clientId
53
     * @param DataBag               $parameters
54
     * @param DataBag               $metadatas
55
     * @param \DateTimeImmutable    $expiresAt
56
     * @param ResourceServerId|null $resourceServerId
57
     *
58
     * @return AccessToken
59
     */
60
    public function create(AccessTokenId $accessTokenId, ResourceOwnerId $resourceOwnerId, ClientId $clientId, DataBag $parameters, DataBag $metadatas, \DateTimeImmutable $expiresAt, ? ResourceServerId $resourceServerId)
61
    {
62
        $clone = clone $this;
63
        $clone->accessTokenId = $accessTokenId;
64
        $clone->resourceOwnerId = $resourceOwnerId;
65
        $clone->clientId = $clientId;
66
        $clone->parameters = $parameters;
67
        $clone->metadatas = $metadatas;
68
        $clone->expiresAt = $expiresAt;
69
        $clone->resourceServerId = $resourceServerId;
70
71
        $event = AccessTokenEvent\AccessTokenCreatedEvent::create($accessTokenId, $resourceOwnerId, $clientId, $parameters, $metadatas, $expiresAt, $resourceServerId);
72
        $clone->record($event);
73
74
        return $clone;
75
    }
76
77
    /**
78
     * {@inheritdoc}
79
     */
80
    public function getTokenId(): TokenId
81
    {
82
        if (null === $this->accessTokenId) {
83
            throw new \RuntimeException('Access token not initialized.');
84
        }
85
86
        return $this->accessTokenId;
87
    }
88
89
    /**
90
     * @return AccessToken
91
     */
92
    public function markAsRevoked(): self
93
    {
94
        $clone = clone $this;
95
        $clone->revoked = true;
96
        $event = AccessTokenEvent\AccessTokenRevokedEvent::create($clone->getTokenId());
97
        $clone->record($event);
98
99
        return $clone;
100
    }
101
102
    /**
103
     * {@inheritdoc}
104
     */
105
    public function jsonSerialize()
106
    {
107
        $data = parent::jsonSerialize() + [
108
            'access_token_id' => $this->getTokenId()->getValue(),
109
        ];
110
111
        return $data;
112
    }
113
114
    /**
115
     * {@inheritdoc}
116
     */
117
    public static function createFromJson(\stdClass $json): DomainObject
118
    {
119
        $accessTokenId = AccessTokenId::create($json->access_token_id);
120
        $resourceServerId = null !== $json->resource_server_id ? ResourceServerId::create($json->resource_server_id) : null;
121
122
        $expiresAt = \DateTimeImmutable::createFromFormat('U', (string) $json->expires_at);
123
        $clientId = ClientId::create($json->client_id);
124
        $parameters = DataBag::create((array) $json->parameters);
125
        $metadatas = DataBag::create((array) $json->metadatas);
126
        $revoked = $json->is_revoked;
127
        $resourceOwnerClass = $json->resource_owner_class;
128
        if (!method_exists($resourceOwnerClass, 'create')) {
129
            throw new \InvalidArgumentException('Invalid resource owner.');
130
        }
131
        $resourceOwnerId = $resourceOwnerClass::create($json->resource_owner_id);
132
133
        $accessToken = new self();
134
        $accessToken->accessTokenId = $accessTokenId;
135
        $accessToken->resourceServerId = $resourceServerId;
136
137
        $accessToken->expiresAt = $expiresAt;
138
        $accessToken->clientId = $clientId;
139
        $accessToken->parameters = $parameters;
140
        $accessToken->metadatas = $metadatas;
141
        $accessToken->revoked = $revoked;
142
        $accessToken->resourceOwnerId = $resourceOwnerId;
143
144
        return $accessToken;
145
    }
146
147
    /**
148
     * @return array
149
     */
150
    public function getResponseData(): array
151
    {
152
        $data = $this->getParameters()->all();
153
        $data['access_token'] = $this->getTokenId()->getValue();
154
        $data['expires_in'] = $this->getExpiresIn();
155
156
        return $data;
157
    }
158
159
    /**
160
     * @param Event $event
161
     *
162
     * @return AccessToken
163
     */
164
    public function apply(Event $event): self
165
    {
166
        $map = $this->getEventMap();
167
        if (!array_key_exists($event->getType(), $map)) {
168
            throw new \InvalidArgumentException('Unsupported event.');
169
        }
170
        if (null !== $this->clientId && $this->accessTokenId->getValue() !== $event->getDomainId()->getValue()) {
171
            throw new \InvalidArgumentException('Event not applicable for this access token.');
172
        }
173
        $method = $map[$event->getType()];
174
175
        return $this->$method($event);
176
    }
177
178
    /**
179
     * @return array
180
     */
181
    private function getEventMap(): array
182
    {
183
        return [
184
            AccessTokenEvent\AccessTokenCreatedEvent::class => 'applyAccessTokenCreatedEvent',
185
            AccessTokenEvent\AccessTokenRevokedEvent::class => 'applyAccessTokenRevokedEvent',
186
        ];
187
    }
188
189
    /**
190
     * @param AccessTokenEvent\AccessTokenCreatedEvent $event
191
     *
192
     * @return AccessToken
193
     */
194
    protected function applyAccessTokenCreatedEvent(AccessTokenEvent\AccessTokenCreatedEvent $event): self
195
    {
196
        $clone = clone $this;
197
        $clone->accessTokenId = $event->getAccessTokenId();
198
        $clone->resourceOwnerId = $event->getResourceOwnerId();
199
        $clone->clientId = $event->getClientId();
200
        $clone->parameters = $event->getParameters();
201
        $clone->metadatas = $event->getMetadatas();
202
        $clone->expiresAt = $event->getExpiresAt();
203
        $clone->resourceServerId = $event->getResourceServerId();
204
205
        return $clone;
206
    }
207
208
    /**
209
     * @return AccessToken
210
     */
211
    protected function applyAccessTokenRevokedEvent(): self
212
    {
213
        $clone = clone $this;
214
        $clone->revoked = true;
215
216
        return $clone;
217
    }
218
}
219