JWTContext   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 96
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 1 Features 0
Metric Value
wmc 13
eloc 44
c 1
b 1
f 0
dl 0
loc 96
ccs 0
cts 56
cp 0
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A setKernel() 0 3 1
B beforeStep() 0 44 7
A beforeScenario() 0 3 1
A setToken() 0 15 4
1
<?php
2
/*******************************************************************************
3
 *  This file is part of the GraphQL Bundle package.
4
 *
5
 *  (c) YnloUltratech <[email protected]>
6
 *
7
 *  For the full copyright and license information, please view the LICENSE
8
 *  file that was distributed with this source code.
9
 ******************************************************************************/
10
11
namespace Ynlo\GraphQLBundle\Behat\Context;
12
13
use Behat\Behat\Context\Context;
14
use Behat\Behat\Hook\Scope\BeforeStepScope;
15
use Behat\Symfony2Extension\Context\KernelAwareContext;
16
use Symfony\Component\HttpKernel\Kernel;
17
use Symfony\Component\HttpKernel\KernelInterface;
18
use Ynlo\GraphQLBundle\Behat\Authentication\JWT\TokenGeneratorInterface;
19
use Ynlo\GraphQLBundle\Behat\Authentication\UserResolverInterface;
20
use Ynlo\GraphQLBundle\Behat\Client\ClientAwareInterface;
21
use Ynlo\GraphQLBundle\Behat\Client\ClientAwareTrait;
22
use Ynlo\GraphQLBundle\Behat\GraphQLApiExtension;
23
24
/**
25
 * JWT Context
26
 */
27
final class JWTContext implements Context, KernelAwareContext, ClientAwareInterface
28
{
29
    use ClientAwareTrait;
30
31
    /**
32
     * @var Kernel
33
     */
34
    protected $kernel;
35
36
    private static $tokens = [];
37
38
    protected $token;
39
40
    /**
41
     * Sets Kernel instance.
42
     *
43
     * @param KernelInterface $kernel
44
     */
45
    public function setKernel(KernelInterface $kernel)
46
    {
47
        $this->kernel = $kernel;
0 ignored issues
show
Documentation Bug introduced by
$kernel is of type Symfony\Component\HttpKernel\KernelInterface, but the property $kernel was declared to be of type Symfony\Component\HttpKernel\Kernel. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
48
    }
49
50
    /**
51
     * @BeforeScenario
52
     */
53
    public function beforeScenario()
54
    {
55
        $this->token = null;
56
    }
57
58
    /**
59
     * @BeforeStep
60
     */
61
    public function beforeStep(BeforeStepScope $scope)
62
    {
63
        $config = GraphQLApiExtension::getConfig();
64
65
        if ($this->token) {
66
            $this->setToken($this->token);
67
68
            return;
69
        }
70
71
        $tags = $scope->getFeature()->getTags();
72
        $featureUser = null;
73
        foreach ($tags as $tag) {
74
            if (preg_match('/^jwt:/', $tag)) {
75
                $featureUser = preg_replace('/^jwt:/', null, $tag);
76
                break;
77
            }
78
        }
79
80
        if ($featureUser) {
81
            if (isset(self::$tokens[$featureUser])) {
82
                $this->token = self::$tokens[$featureUser];
83
                $this->setToken($this->token);
84
85
                return;
86
            }
87
88
            $resolverClass = $config['authentication']['jwt']['user_resolver'];
89
            $tokenGeneratorClass = $config['authentication']['jwt']['generator'];
90
91
            /** @var UserResolverInterface $resolver */
92
            $resolver = new $resolverClass($this->kernel);
93
            $user = $resolver->findByUsername($featureUser);
94
95
            /** @var TokenGeneratorInterface $tokenGenerator */
96
            $tokenGenerator = new $tokenGeneratorClass($this->kernel);
97
            $this->token = $tokenGenerator->generate($user);
98
99
            if (!$this->token) {
100
                throw new \RuntimeException('Cant resolve a token using given credentials');
101
            }
102
103
            self::$tokens[$featureUser] = $this->token;
104
            $this->setToken($this->token);
105
        }
106
    }
107
108
    protected function setToken($token)
109
    {
110
        $tokenIn = $config['authentication']['jwt']['token_in'] ?? 'header';
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $config seems to never exist and therefore isset should always be false.
Loading history...
111
        $tokenName = $config['authentication']['jwt']['token_name'] ?? 'Authorization';
112
        $tokenTemplate = $config['authentication']['jwt']['token_template'] ?? 'Bearer {token}';
113
114
        if ($token) {
115
            $tokenValue = str_replace('{token}', $token, $tokenTemplate);
116
            switch ($tokenIn) {
117
                case 'header':
118
                    $this->client->setServerParameter(sprintf('HTTP_%s', $tokenName), $tokenValue);
119
                    break;
120
                case 'query':
121
                    $query = http_build_query([$tokenName => $tokenValue], null, '&');
122
                    $this->client->setEndpoint($this->client->getEndpoint().'?'.$query);
123
            }
124
        }
125
    }
126
}
127