Failed Conditions
Push — ng ( 280307...a36945 )
by Florent
03:55
created

findClientIdAndCredentials()   C

Complexity

Conditions 7
Paths 6

Size

Total Lines 25
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 16
nc 6
nop 3
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\ClientAuthentication;
15
16
use OAuth2Framework\Component\Core\Client\Client;
17
use OAuth2Framework\Component\Core\Client\ClientId;
18
use OAuth2Framework\Component\Core\Exception\OAuth2Exception;
19
use Psr\Http\Message\ServerRequestInterface;
20
21
class AuthenticationMethodManager
22
{
23
    /**
24
     * @var AuthenticationMethod[]
25
     */
26
    private $methods = [];
27
28
    /**
29
     * @var string[]
30
     */
31
    private $names = [];
32
33
    /**
34
     * @param AuthenticationMethod $method
35
     *
36
     * @return AuthenticationMethodManager
37
     */
38
    public function add(AuthenticationMethod $method): self
39
    {
40
        $class = get_class($method);
41
        $this->methods[$class] = $method;
42
        foreach ($method->getSupportedMethods() as $name) {
43
            $this->names[$name] = $class;
44
        }
45
46
        return $this;
47
    }
48
49
    /**
50
     * @return string[]
51
     */
52
    public function list(): array
53
    {
54
        return array_keys($this->names);
55
    }
56
57
    /**
58
     * @param string $name
59
     *
60
     * @return bool
61
     */
62
    public function has(string $name): bool
63
    {
64
        return array_key_exists($name, $this->names);
65
    }
66
67
    /**
68
     * @param string $name
69
     *
70
     * @throws \InvalidArgumentException
71
     *
72
     * @return AuthenticationMethod
73
     */
74
    public function get(string $name): AuthenticationMethod
75
    {
76
        if (!$this->has($name)) {
77
            throw new \InvalidArgumentException(sprintf('The token endpoint authentication method "%s" is not supported. Please use one of the following values: %s', $name, implode(', ', $this->list())));
78
        }
79
        $class = $this->names[$name];
80
81
        return $this->methods[$class];
82
    }
83
84
    /**
85
     * @return AuthenticationMethod[]
86
     */
87
    public function all(): array
88
    {
89
        return array_values($this->methods);
90
    }
91
92
    /**
93
     * @param ServerRequestInterface $request
94
     * @param AuthenticationMethod   $authenticationMethod
0 ignored issues
show
Documentation introduced by
Should the type for parameter $authenticationMethod not be null|AuthenticationMethod?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
95
     * @param mixed                  $clientCredentials    The client credentials found in the request
96
     *
97
     * @throws OAuth2Exception
98
     *
99
     * @return null|ClientId
100
     */
101
    public function findClientIdAndCredentials(ServerRequestInterface $request, AuthenticationMethod &$authenticationMethod = null, &$clientCredentials = null)
102
    {
103
        $clientId = null;
104
        $clientCredentials = null;
105
        foreach ($this->methods as $method) {
106
            $tempClientId = $method->findClientIdAndCredentials($request, $clientCredentials);
107
            if (null === $tempClientId) {
108
                continue;
109
            }
110
            if (null === $clientId) {
111
                $clientId = $tempClientId;
112
                $authenticationMethod = $method;
113
114
                continue;
115
            }
116
            if (!$method instanceof None && !$authenticationMethod instanceof None) {
117
                throw new OAuth2Exception(400, OAuth2Exception::ERROR_INVALID_REQUEST, 'Only one authentication method may be used to authenticate the client.');
118
            }
119
            if (!$method instanceof None) {
120
                $authenticationMethod = $method;
121
            }
122
        }
123
124
        return $clientId;
125
    }
126
127
    /**
128
     * @param ServerRequestInterface $request
129
     * @param Client                 $client
130
     * @param AuthenticationMethod   $authenticationMethod
131
     * @param mixed                  $clientCredentials
132
     *
133
     * @return bool
134
     */
135
    public function isClientAuthenticated(ServerRequestInterface $request, Client $client, AuthenticationMethod $authenticationMethod, $clientCredentials): bool
136
    {
137
        if (in_array($client->get('token_endpoint_auth_method'), $authenticationMethod->getSupportedMethods())) {
138
            if (false === $client->areClientCredentialsExpired()) {
139
                return $authenticationMethod->isClientAuthenticated($client, $clientCredentials, $request);
140
            }
141
        }
142
143
        return false;
144
    }
145
146
    /**
147
     * @return string[]
148
     */
149
    public function getSchemesParameters(): array
150
    {
151
        $schemes = [];
152
        foreach ($this->all() as $method) {
153
            $schemes = array_merge(
154
                $schemes,
155
                $method->getSchemesParameters()
156
            );
157
        }
158
159
        return $schemes;
160
    }
161
}
162