Completed
Pull Request — master (#15)
by Oguzhan
02:25
created

AuthenticatorTest::supportsPreAuthToken()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 8
Ratio 100 %

Importance

Changes 0
Metric Value
dl 8
loc 8
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 0
1
<?php
2
/*
3
 * This file is part of the KleijnWeb\JwtBundle package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
namespace KleijnWeb\JwtBundle\Tests\Authenticator;
9
10
use KleijnWeb\JwtBundle\Authenticator\Authenticator;
11
use KleijnWeb\JwtBundle\Authenticator\JwtKey;
12
use KleijnWeb\JwtBundle\Authenticator\JwtToken;
13
use KleijnWeb\JwtBundle\User\UserInterface;
14
use Symfony\Component\HttpFoundation\Request;
15
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
16
use Symfony\Component\Security\Core\User\User;
17
18
/**
19
 * @author John Kleijn <[email protected]>
20
 */
21
class AuthenticatorTest extends \PHPUnit_Framework_TestCase
22
{
23
    // @codingStandardsIgnoreStart
24
25
    /**
26
     * Created using jwt.io
27
     */
28
    const TEST_TOKEN = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImtleU9uZSJ9.eyJwcm4iOiJqb2huIiwiaXNzIjoiaHR0cDovL2FwaS5zZXJ2ZXIxLmNvbS9vYXV0aDIvdG9rZW4ifQ._jXjAWMzwwG1v5N3ZOEUoLGSINtmwLsvQdfYkYAcWiY';
29
30
    const JKEY_CLASS = 'KleijnWeb\JwtBundle\Authenticator\JwtKey';
31
32
    /**
33
     * @var array
34
     */
35
    private static $keyConfig = [
36
        'keyOne' =>
37
            [
38
                'issuer' => 'http://api.server1.com/oauth2/token',
39
                'secret' => 'A Pre-Shared Key',
40
                'type'   => 'HS256',
41
            ],
42
        'keyTwo' =>
43
            [
44
                'issuer' => 'http://api.server2.com/oauth2/token',
45
                'type'   => 'RS256',
46
                'secret' => 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0F',
47
            ],
48
    ];
49
50
    // @codingStandardsIgnoreEnd
51
52
    /**
53
     * @var JwtKey[]
54
     */
55
    private $keys = [];
56
57
    protected function setUp()
58
    {
59
        foreach (self::$keyConfig as $keyId => $config) {
60
            $config['kid']      = $keyId;
61
            $this->keys[$keyId] = new JwtKey($config);
62
        }
63
    }
64
65
    /**
66
     * @test
67
     */
68
    public function getGetKeysUsingIndexesInConfig()
69
    {
70
        $authenticator = new Authenticator($this->keys);
71
72
        $this->assertInstanceOf(self::JKEY_CLASS, $authenticator->getKeyById('keyOne'));
73
        $this->assertInstanceOf(self::JKEY_CLASS, $authenticator->getKeyById('keyTwo'));
74
    }
75
76
    /**
77
     * @test
78
     */
79
    public function willGetSingleKeyWhenKeyIdIsNull()
80
    {
81
        $config = $this->keys;
82
        unset($config['keyTwo']);
83
84
        $authenticator = new Authenticator($config);
85
86
        $this->assertInstanceOf(self::JKEY_CLASS, $authenticator->getKeyById(null));
87
    }
88
89
    /**
90
     * @test
91
     * @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationException
92
     */
93
    public function willFailWhenTryingToGetKeyWithoutIdWhenThereAreMoreThanOne()
94
    {
95
        $authenticator = new Authenticator($this->keys);
96
97
        $this->assertInstanceOf(self::JKEY_CLASS, $authenticator->getKeyById(null));
98
    }
99
100
    /**
101
     * @test
102
     * @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationException
103
     */
104
    public function willFailWhenTryingToGetUnknownKey()
105
    {
106
        $authenticator = new Authenticator($this->keys);
107
108
        $this->assertInstanceOf(self::JKEY_CLASS, $authenticator->getKeyById('blah'));
109
    }
110
111
    /**
112
     * @test
113
     */
114
    public function authenticateTokenWillSetUserFetchedFromUserProviderOnToken()
115
    {
116
        $jwtToken      = $this->createToken(['sub' => 'john']);
117
        $authenticator = new Authenticator($this->keys);
118
        $anonToken     = new PreAuthenticatedToken('foo', $jwtToken, 'myprovider');
119
120
        $userProvider = $this->getMockBuilder(
121
            'Symfony\Component\Security\Core\User\UserProviderInterface'
122
        )->getMockForAbstractClass();
123
124
        $userProvider->expects($this->once())
125
            ->method('loadUserByUsername')
126
            ->with('john')
127
            ->willReturn(new User('john', 'hi there'));
128
129
        $authenticator->authenticateToken($anonToken, $userProvider, 'myprovider');
130
    }
131
132
    /**
133
     * @test
134
     * @expectedException \UnexpectedValueException
135
     */
136
    public function authenticateTokenWillFailIfCredentialsAreNotJwtToken()
137
    {
138
        $authenticator = new Authenticator($this->keys);
139
        $anonToken     = new PreAuthenticatedToken('foo', ['sub' => 'john'], 'myprovider');
140
141
        $userProvider = $this->getMockBuilder(
142
            'Symfony\Component\Security\Core\User\UserProviderInterface'
143
        )->getMockForAbstractClass();
144
145
        $authenticator->authenticateToken($anonToken, $userProvider, 'myprovider');
146
    }
147
148
    /**
149
     * @test
150
     */
151
    public function supportsPreAuthToken()
152
    {
153
        $authenticator = new Authenticator($this->keys);
154
155
        $securityToken = new PreAuthenticatedToken('foo', 'bar', 'myprovider');
156
        $actual        = $authenticator->supportsToken($securityToken, 'myprovider');
157
        $this->assertTrue($actual);
158
    }
159
160
    /**
161
     * @test
162
     * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
163
     */
164
    public function willFailWhenApiKeyNotFoundInHeader()
165
    {
166
        $authenticator = new Authenticator($this->keys);
167
        $request       = new Request();
168
        $authenticator->createToken($request, 'myprovider');
169
    }
170
171
    /**
172
     * @test
173
     */
174
    public function canGetAnonTokenWithClaims()
175
    {
176
        $authenticator = new Authenticator($this->keys);
177
        $request       = new Request();
178
        $request->headers->set('Authorization', 'Bearer ' . self::TEST_TOKEN);
179
        $token = $authenticator->createToken($request, 'myprovider');
180
181
        $expected = new JwtToken(self::TEST_TOKEN);
182
        $this->assertEquals($expected, $token->getCredentials());
183
    }
184
185
    /**
186
     * @test
187
     */
188
    public function willAddRolesFromAudienceClaimsInToken()
189
    {
190
        $authenticator = new Authenticator($this->keys);
191
        $token         = $this->createToken(['sub' => 'john', 'aud' => 'guests']);
192
        $anonToken     = new PreAuthenticatedToken('foo', $token, 'myprovider');
193
194
        $user          = $this->getMockBuilder(
195
            'KleijnWeb\JwtBundle\User\UserInterface'
196
        )->getMockForAbstractClass();
197
198
        $userProvider = $this->getMockBuilder(
199
            'Symfony\Component\Security\Core\User\UserProviderInterface'
200
        )->getMockForAbstractClass();
201
202
        $userProvider->expects($this->once())
203
            ->method('loadUserByUsername')
204
            ->willReturn($user);
205
206
        $user->expects($this->once())
207
            ->method('addRole')
208
            ->with('guests');
209
210
        $user->expects($this->once())
211
            ->method('getRoles')
212
            ->willReturn(['guests']);
213
214
        $authenticator->authenticateToken($anonToken, $userProvider, 'myprovider');
215
    }
216
217
    /**
218
     * @test
219
     */
220
    public function willAddMultipleRolesFromAudienceClaimsInToken()
221
    {$authenticator = new Authenticator($this->keys);
222
        $token         = $this->createToken(['sub' => 'john', 'aud' => ['guests', 'users' ]]);
223
        $anonToken     = new PreAuthenticatedToken('foo', $token, 'myprovider');
224
225
        $user          = $this->getMockBuilder(
226
            'KleijnWeb\JwtBundle\User\UserInterface'
227
        )->getMockForAbstractClass();
228
229
        $userProvider = $this->getMockBuilder(
230
            'Symfony\Component\Security\Core\User\UserProviderInterface'
231
        )->getMockForAbstractClass();
232
233
        $userProvider->expects($this->once())
234
            ->method('loadUserByUsername')
235
            ->willReturn($user);
236
237
        $user->expects($this->exactly(2))
238
            ->method('addRole');
239
240
        $user->expects($this->once())
241
            ->method('getRoles')git 
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_STRING
Loading history...
242
            ->willReturn(['guests', 'users']);
243
244
        $authenticator->authenticateToken($anonToken, $userProvider, 'myprovider');
245
    }
246
247
    /**
248
     * @param array $claims
249
     *
250
     * @return JwtToken
251
     */
252
    private function createToken(array $claims)
253
    {
254
        return new JwtToken([
255
            'header' => [
256
                'alg' => 'HS256',
257
                'typ' => 'JWT',
258
                'kid' => 'keyOne'
259
            ],
260
            'claims' => $claims,
261
            'secret' => 'secret'
262
        ]);
263
    }
264
}
265