Failed Conditions
Push — issue#666 ( 82e9d5...91903a )
by Guilherme
08:00
created

AuthorizationCode::setSessionStateStorage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
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 OAuth2\OpenID\Storage\AuthorizationCodeInterface;
14
use LoginCidadao\OpenIDBundle\Storage\SessionState;
15
use Doctrine\ORM\EntityManager;
16
17
class AuthorizationCode implements AuthorizationCodeInterface
18
{
19
    /** @var EntityManager */
20
    private $em;
21
22
    /** @var SessionState */
23
    private $sessionStateStorage;
24
25
    public function __construct(EntityManager $EntityManager)
26
    {
27
        $this->em = $EntityManager;
28
    }
29
30
    /**
31
     * Fetch authorization code data (probably the most common grant type).
32
     *
33
     * Retrieve the stored data for the given authorization code.
34
     *
35
     * Required for OAuth2::GRANT_TYPE_AUTH_CODE.
36
     *
37
     * @param $code
38
     * Authorization code to be check with.
39
     *
40
     * @return
41
     * An associative array as below, and NULL if the code is invalid
42
     * @code
43
     * return array(
44
     *     "client_id"    => CLIENT_ID,      // REQUIRED Stored client identifier
45
     *     "user_id"      => USER_ID,        // REQUIRED Stored user identifier
46
     *     "expires"      => EXPIRES,        // REQUIRED Stored expiration in unix timestamp
47
     *     "redirect_uri" => REDIRECT_URI,   // REQUIRED Stored redirect URI
48
     *     "scope"        => SCOPE,          // OPTIONAL Stored scope values in space-separated string
49
     * );
50
     * @endcode
51
     *
52
     * @see http://tools.ietf.org/html/rfc6749#section-4.1
53
     *
54
     * @ingroup oauth2_section_4
55
     */
56
    public function getAuthorizationCode($code)
57
    {
58
        // Get Code
59
        $code = $this->em->getRepository('LoginCidadaoOAuthBundle:AuthCode')
60
            ->findOneBy(array('token' => $code));
61
62
        if (!$code) {
63
            return null;
64
        }
65
66
        if ($code instanceof \LoginCidadao\OAuthBundle\Entity\AuthCode) {
67
            $response = array(
68
                'client_id' => $code->getClient()->getClientId(),
69
                'user_id' => $code->getUser()->getId(),
0 ignored issues
show
Bug introduced by
The method getId() does not exist on Symfony\Component\Security\Core\User\UserInterface. It seems like you code against a sub-type of Symfony\Component\Security\Core\User\UserInterface such as HWI\Bundle\OAuthBundle\Tests\Fixtures\User or FOS\OAuthServerBundle\Te...\TestBundle\Entity\User or FOS\UserBundle\Model\UserInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

69
                'user_id' => $code->getUser()->/** @scrutinizer ignore-call */ getId(),
Loading history...
70
                'expires' => $code->getExpiresAt(),
71
                'redirect_uri' => $code->getRedirectUri(),
72
                'scope' => $code->getScope()
73
            );
74
            if ($code->getIdToken()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $code->getIdToken() of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
75
                $response['id_token'] = $code->getIdToken();
76
            }
77
            if ($code->getSessionId()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $code->getSessionId() of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
78
                $response['session_id'] = $code->getSessionId();
79
            }
80
            return $response;
81
        }
82
    }
83
84
    /**
85
     * Take the provided authorization code values and store them somewhere.
86
     *
87
     * This function should be the storage counterpart to getAuthCode().
88
     *
89
     * If storage fails for some reason, we're not currently checking for
90
     * any sort of success/failure, so you should bail out of the script
91
     * and provide a descriptive fail message.
92
     *
93
     * Required for OAuth2::GRANT_TYPE_AUTH_CODE.
94
     *
95
     * @param $code
96
     * Authorization code to be stored.
97
     * @param $client_id
98
     * Client identifier to be stored.
99
     * @param $user_id
100
     * User identifier to be stored.
101
     * @param string $redirect_uri
102
     *                             Redirect URI(s) to be stored in a space-separated string.
103
     * @param int    $expires
104
     *                             Expiration to be stored as a Unix timestamp.
105
     * @param string $scope
106
     *                             (optional) Scopes to be stored in space-separated string.
107
     *
108
     * @ingroup oauth2_section_4
109
     */
110
    public function setAuthorizationCode($code, $client_id, $user_id,
111
                                            $redirect_uri, $expires, $scope = null,
112
                                            $id_token = null)
113
    {
114
        $id     = explode('_', $client_id);
115
        $client = $this->em->getRepository('LoginCidadaoOAuthBundle:Client')
116
            ->find($id[0]);
117
118
        if ($user_id === null) {
119
            $user = null;
120
        } else {
121
            $user = $this->em->getRepository('LoginCidadaoCoreBundle:Person')
122
                ->find($user_id);
123
        }
124
125
        if (!$client) {
126
            throw new \Exception('Unknown client identifier');
127
        }
128
129
        $authorizationCode = new \LoginCidadao\OAuthBundle\Entity\AuthCode();
130
        $authorizationCode->setToken($code);
131
        $authorizationCode->setClient($client);
132
        $authorizationCode->setUser($user);
133
        $authorizationCode->setRedirectUri($redirect_uri);
134
        $authorizationCode->setExpiresAt($expires);
135
        $authorizationCode->setScope($scope);
136
        $authorizationCode->setIdToken($id_token);
137
        $authorizationCode->setSessionId($this->sessionStateStorage->getSessionId());
138
139
        $this->em->persist($authorizationCode);
140
        $this->em->flush();
141
    }
142
143
    /**
144
     * once an Authorization Code is used, it must be exipired
145
     *
146
     * @see http://tools.ietf.org/html/rfc6749#section-4.1.2
147
     *
148
     *    The client MUST NOT use the authorization code
149
     *    more than once.  If an authorization code is used more than
150
     *    once, the authorization server MUST deny the request and SHOULD
151
     *    revoke (when possible) all tokens previously issued based on
152
     *    that authorization code
153
     *
154
     */
155
    public function expireAuthorizationCode($code)
156
    {
157
        $code = $this->em->getRepository('LoginCidadaoOAuthBundle:AuthCode')
158
            ->findOneBy(array('token' => $code));
159
        $this->em->remove($code);
160
        $this->em->flush();
161
    }
162
163
    public function setSessionStateStorage(SessionState $sessionStateStorage)
164
    {
165
        $this->sessionStateStorage = $sessionStateStorage;
166
    }
167
}
168