SecurityBundleTest   A
last analyzed

Complexity

Total Complexity 6

Size/Duplication

Total Lines 123
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 6
eloc 69
c 0
b 0
f 0
dl 0
loc 123
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A anApiRequestIsReceivedButTheTokenDoesNotHaveTheRequiredScope() 0 23 1
A anApiRequestIsReceivedButTheTokenTypeIsNotAllowed() 0 23 1
A aValidApiRequestIsReceivedAndTheAccessTokenResolverIsUsed() 0 23 1
A anApiRequestIsReceivedWithAnUnsupportedTokenType() 0 7 1
A anApiRequestWithoutAccessTokenIsReceived() 0 7 1
A anApiRequestIsReceivedButTheTokenDoesNotExist() 0 10 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * The MIT License (MIT)
7
 *
8
 * Copyright (c) 2014-2019 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\SecurityBundle\Tests\Functional\Security;
15
16
use OAuth2Framework\Component\Core\AccessToken\AccessTokenId;
17
use OAuth2Framework\Component\Core\Client\ClientId;
18
use OAuth2Framework\Component\Core\DataBag\DataBag;
19
use OAuth2Framework\Component\Core\ResourceServer\ResourceServerId;
20
use OAuth2Framework\Component\Core\UserAccount\UserAccountId;
21
use OAuth2Framework\SecurityBundle\Tests\Functional\AccessToken;
22
use OAuth2Framework\SecurityBundle\Tests\TestBundle\Service\AccessTokenHandler;
23
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
24
25
/**
26
 * @group Firewall
27
 *
28
 * @internal
29
 */
30
class SecurityBundleTest extends WebTestCase
31
{
32
    /**
33
     * @test
34
     */
35
    public function anApiRequestWithoutAccessTokenIsReceived()
36
    {
37
        $client = static::createClient();
38
        $client->request('GET', '/api/hello/World');
39
        $response = $client->getResponse();
40
        static::assertEquals(200, $response->getStatusCode());
41
        static::assertEquals('{"name":"World","message":"Hello World!"}', $response->getContent());
42
    }
43
44
    /**
45
     * @test
46
     */
47
    public function anApiRequestIsReceivedWithAnUnsupportedTokenType()
48
    {
49
        $client = static::createClient();
50
        $client->request('GET', '/api/hello/World', [], [], ['HTTPS' => 'on', 'HTTP_AUTHORIZATION' => 'POP UNKNOWN_ACCESS_TOKEN_ID']);
51
        $response = $client->getResponse();
52
        static::assertEquals(200, $response->getStatusCode());
53
        static::assertEquals('{"name":"World","message":"Hello World!"}', $response->getContent());
54
    }
55
56
    /**
57
     * @test
58
     */
59
    public function anApiRequestIsReceivedButTheTokenDoesNotExist()
60
    {
61
        $client = static::createClient();
62
        $client->request('GET', '/api/hello/World', [], [], ['HTTPS' => 'on', 'HTTP_AUTHORIZATION' => 'Bearer UNKNOWN_ACCESS_TOKEN_ID']);
63
        $response = $client->getResponse();
64
65
        static::assertEquals(401, $response->getStatusCode());
66
        static::assertEquals('', $response->getContent());
67
        static::assertTrue($response->headers->has('www-authenticate'));
68
        static::assertEquals('Bearer realm="Protected API",error="access_denied",error_description="OAuth2 authentication required. Invalid access token."', $response->headers->get('www-authenticate'));
69
    }
70
71
    /**
72
     * @test
73
     */
74
    public function anApiRequestIsReceivedButTheTokenDoesNotHaveTheRequiredScope()
75
    {
76
        $client = static::createClient();
77
        /** @var AccessTokenHandler $accessTokenHandler */
78
        $accessTokenHandler = $client->getContainer()->get(AccessTokenHandler::class);
79
        $accessToken = new AccessToken(
80
            new AccessTokenId('ACCESS_TOKEN_WITH_INSUFFICIENT_SCOPE'),
81
            new ClientId('CLIENT_ID'),
82
            new UserAccountId('USER_ACCOUNT_ID'),
83
            new \DateTimeImmutable('now +1 hour'),
84
            new DataBag([
85
                'token_type' => 'Bearer',
86
                'scope' => 'openid',
87
            ]),
88
            new DataBag([]),
89
            new ResourceServerId('RESOURCE_SERVER_ID')
90
        );
91
        $accessTokenHandler->save($accessToken);
92
93
        $client->request('GET', '/api/hello-profile', [], [], ['HTTPS' => 'on', 'HTTP_AUTHORIZATION' => 'Bearer ACCESS_TOKEN_WITH_INSUFFICIENT_SCOPE']);
94
        $response = $client->getResponse();
95
        static::assertEquals(403, $response->getStatusCode());
96
        static::assertEquals('{"scope":"profile openid","error":"access_denied","error_description":"Insufficient scope. The required scope is \"profile openid\""}', $response->getContent());
97
    }
98
99
    /**
100
     * @test
101
     */
102
    public function anApiRequestIsReceivedButTheTokenTypeIsNotAllowed()
103
    {
104
        $client = static::createClient();
105
        /** @var AccessTokenHandler $accessTokenHandler */
106
        $accessTokenHandler = $client->getContainer()->get(AccessTokenHandler::class);
107
        $accessToken = new AccessToken(
108
            new AccessTokenId('ACCESS_TOKEN_WITH_BAD_TOKEN_TYPE'),
109
            new ClientId('CLIENT_ID'),
110
            new UserAccountId('USER_ACCOUNT_ID'),
111
            new \DateTimeImmutable('now +1 hour'),
112
            new DataBag([
113
                'token_type' => 'Bearer',
114
                'scope' => 'openid',
115
            ]),
116
            new DataBag([]),
117
            new ResourceServerId('RESOURCE_SERVER_ID')
118
        );
119
        $accessTokenHandler->save($accessToken);
120
121
        $client->request('GET', '/api/hello-token', [], [], ['HTTPS' => 'on', 'HTTP_AUTHORIZATION' => 'Bearer ACCESS_TOKEN_WITH_BAD_TOKEN_TYPE']);
122
        $response = $client->getResponse();
123
        static::assertEquals(403, $response->getStatusCode());
124
        static::assertEquals('{"error":"access_denied","error_description":"Token type \"Bearer\" not allowed. Please use \"MAC\""}', $response->getContent());
125
    }
126
127
    /**
128
     * @test
129
     */
130
    public function aValidApiRequestIsReceivedAndTheAccessTokenResolverIsUsed()
131
    {
132
        $client = static::createClient();
133
        /** @var AccessTokenHandler $accessTokenHandler */
134
        $accessTokenHandler = $client->getContainer()->get(AccessTokenHandler::class);
135
        $accessToken = new AccessToken(
136
            new AccessTokenId('VALID_ACCESS_TOKEN'),
137
            new ClientId('CLIENT_ID'),
138
            new UserAccountId('USER_ACCOUNT_ID'),
139
            new \DateTimeImmutable('now +1 hour'),
140
            new DataBag([
141
                'token_type' => 'Bearer',
142
                'scope' => 'openid',
143
            ]),
144
            new DataBag([]),
145
            new ResourceServerId('RESOURCE_SERVER_ID')
146
        );
147
        $accessTokenHandler->save($accessToken);
148
149
        $client->request('GET', '/api/hello-resolver', [], [], ['HTTPS' => 'on', 'HTTP_AUTHORIZATION' => 'Bearer VALID_ACCESS_TOKEN']);
150
        $response = $client->getResponse();
151
        static::assertEquals(200, $response->getStatusCode());
152
        static::assertEquals(\Safe\json_encode($accessToken), $response->getContent());
153
    }
154
}
155