Failed Conditions
Push — issue#702 ( 91bd46...0b5bf0 )
by Guilherme
19:37 queued 12:15
created

ClientCredentials::getClient()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 24
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 13
nc 4
nop 1
dl 0
loc 24
ccs 13
cts 13
cp 1
crap 3
rs 8.9713
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of the login-cidadao project or it's bundles.
4
 *
5
 * (c) Guilherme Donato <guilhermednt on github>
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 LoginCidadao\OpenIDBundle\Storage;
12
13
use Doctrine\ORM\EntityManagerInterface;
14
use LoginCidadao\OAuthBundle\Entity\Client;
15
use LoginCidadao\OAuthBundle\Entity\ClientRepository;
16
use LoginCidadao\OAuthBundle\Model\ClientInterface;
17
use LoginCidadao\RemoteClaimsBundle\Entity\RemoteClaim;
18
use LoginCidadao\RemoteClaimsBundle\Entity\RemoteClaimRepository;
19
use LoginCidadao\RemoteClaimsBundle\Model\RemoteClaimInterface;
20
use OAuth2\ServerBundle\Storage\ClientCredentials as BaseClass;
21
22
class ClientCredentials extends BaseClass
23
{
24
    private $em;
25
26 10
    public function __construct(EntityManagerInterface $EntityManager)
27
    {
28 10
        $this->em = $EntityManager;
29 10
    }
30
31
    /**
32
     * Make sure that the client credentials is valid.
33
     *
34
     * @param $client_id
35
     * Client identifier to be check with.
36
     * @param $client_secret
37
     * (optional) If a secret is required, check that they've given the right one.
38
     *
39
     * @return TRUE if the client credentials are valid, and MUST return FALSE if it isn't.
40
     * @endcode
41
     *
42
     * @see http://tools.ietf.org/html/rfc6749#section-3.1
43
     *
44
     * @ingroup oauth2_section_3
45
     */
46 3
    public function checkClientCredentials($client_id, $client_secret = null)
47
    {
48 3
        $client = $this->getClient($client_id);
49
50
        // If client exists check secret
51 3
        if ($client) {
52 2
            return $client->getClientSecret() === $client_secret;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $client->getClien...et() === $client_secret returns the type boolean which is incompatible with the documented return type true.
Loading history...
53
        }
54
55 1
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type true.
Loading history...
56
    }
57
58
    /**
59
     * Get client details corresponding client_id.
60
     *
61
     * OAuth says we should store request URIs for each registered client.
62
     * Implement this function to grab the stored URI for a given client id.
63
     *
64
     * @param $client_id
65
     * Client identifier to be check with.
66
     *
67
     * @return array
68
     *               Client details. The only mandatory key in the array is "redirect_uri".
69
     *               This function MUST return FALSE if the given client does not exist or is
70
     *               invalid. "redirect_uri" can be space-delimited to allow for multiple valid uris.
71
     * @code
72
     *               return array(
73
     *               "redirect_uri" => REDIRECT_URI,      // REQUIRED redirect_uri registered for the client
74
     *               "client_id"    => CLIENT_ID,         // OPTIONAL the client id
75
     *               "grant_types"  => GRANT_TYPES,       // OPTIONAL an array of restricted grant types
76
     *               );
77
     * @endcode
78
     *
79
     * @ingroup oauth2_section_4
80
     */
81 2
    public function getClientDetails($client_id)
82
    {
83 2
        $client = $this->getClient($client_id);
84
85 2
        if (!$client) {
86 1
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type array.
Loading history...
87
        }
88
89
        return [
90 1
            'redirect_uri' => implode(' ', $client->getRedirectUris()),
91 1
            'client_id' => $client->getPublicId(),
92 1
            'grant_types' => $client->getAllowedGrantTypes(),
93
        ];
94
    }
95
96
    /**
97
     * Determine if the client is a "public" client, and therefore
98
     * does not require passing credentials for certain grant types
99
     *
100
     * @param $client_id
101
     * Client identifier to be check with.
102
     *
103
     * @return TRUE if the client is public, and FALSE if it isn't.
104
     * @endcode
105
     *
106
     * @see http://tools.ietf.org/html/rfc6749#section-2.3
107
     * @see https://github.com/bshaffer/oauth2-server-php/issues/257
108
     *
109
     * @ingroup oauth2_section_2
110
     */
111 2
    public function isPublicClient($client_id)
112
    {
113 2
        $client = $this->getClient($client_id);
114
115 2
        if (!$client) {
116 1
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type true.
Loading history...
117
        }
118
119 1
        $secret = $client->getClientSecret();
120
121 1
        return empty($secret);
0 ignored issues
show
Bug Best Practice introduced by
The expression return empty($secret) returns the type boolean which is incompatible with the documented return type true.
Loading history...
122
    }
123
124
    /**
125
     * Get the scope associated with this client
126
     *
127
     * @return string the space-delineated scope list for the specified client_id
128
     */
129 3
    public function getClientScope($client_id)
130
    {
131
        /** @var Client $client */
132 3
        $client = $this->getClient($client_id);
133
134 3
        if (!$client instanceof ClientInterface) {
0 ignored issues
show
introduced by
$client is always a sub-type of LoginCidadao\OAuthBundle\Model\ClientInterface. If $client can have other possible types, add them to src/LoginCidadao/OpenIDB...e/ClientCredentials.php:131.
Loading history...
135 1
            return false;
136
        }
137
138
        /*
139
         * TODO: performance issue: if there are too many Remote Claims listing all of them might be an issue
140
         */
141 2
        $remoteClaims = $this->getRemoteClaimsTags($this->getAllRemoteClaims());
142 2
        $allowedScopes = array_merge($client->getAllowedScopes(), $remoteClaims);
143
144 2
        return implode(' ', $allowedScopes);
145
    }
146
147
    /**
148
     * @param $client_id mixed
149
     * @return ClientInterface|null
150
     */
151 10
    private function getClient($client_id)
152
    {
153 10
        $randomId = null;
154 10
        if (strstr($client_id, '_') !== false) {
155 8
            $parts = explode('_', $client_id);
156 8
            $client_id = $parts[0];
157 8
            $randomId = $parts[1];
158
        }
159
160
        /** @var ClientRepository $repo */
161 10
        $repo = $this->em->getRepository('LoginCidadaoOAuthBundle:Client');
162
163 10
        if ($randomId) {
164
            /** @var ClientInterface|null $client */
165 8
            $client = $repo->findOneBy([
166 8
                'id' => $client_id,
167 8
                'randomId' => $randomId,
168
            ]);
169
        } else {
170
            /** @var ClientInterface|null $client */
171 2
            $client = $repo->find($client_id);
172
        }
173
174 10
        return $client;
175
    }
176
177
    /**
178
     * @return array|RemoteClaimInterface[]
179
     */
180 2
    private function getAllRemoteClaims()
181
    {
182
        /** @var RemoteClaimRepository $repo */
183 2
        $repo = $this->em->getRepository('LoginCidadaoRemoteClaimsBundle:RemoteClaim');
184
185 2
        $remoteClaims = $repo->findAll();
186
187 2
        return $remoteClaims;
188
    }
189
190 2
    private function getRemoteClaimsTags(array $remoteClaims)
191
    {
192 2
        if (count($remoteClaims) > 0) {
193 1
            return array_map(function (RemoteClaimInterface $claim) {
194 1
                return $claim->getName();
195 1
            }, $remoteClaims);
196
        }
197
198 1
        return [];
199
    }
200
}
201