Completed
Pull Request — develop (#816)
by Kristijan
07:28
created

ResourceController::getAccessTokenData()   C

Complexity

Conditions 8
Paths 13

Size

Total Lines 30
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 30
rs 5.3846
c 0
b 0
f 0
cc 8
eloc 16
nc 13
nop 2
1
<?php
2
3
namespace OAuth2\Controller;
4
5
use OAuth2\TokenType\TokenTypeInterface;
6
use OAuth2\Storage\AccessTokenInterface;
7
use OAuth2\ScopeInterface;
8
use OAuth2\RequestInterface;
9
use OAuth2\ResponseInterface;
10
use OAuth2\Scope;
11
12
/**
13
 * @see OAuth2\Controller\ResourceControllerInterface
14
 */
15
class ResourceController implements ResourceControllerInterface
16
{
17
    private $token;
18
19
    protected $tokenType;
20
    protected $tokenStorage;
21
    protected $config;
22
    protected $scopeUtil;
23
24
    public function __construct(TokenTypeInterface $tokenType, AccessTokenInterface $tokenStorage, $config = array(), ScopeInterface $scopeUtil = null)
25
    {
26
        $this->tokenType = $tokenType;
27
        $this->tokenStorage = $tokenStorage;
28
29
        $this->config = array_merge(array(
30
            'www_realm' => 'Service',
31
        ), $config);
32
33
        if (is_null($scopeUtil)) {
34
            $scopeUtil = new Scope();
35
        }
36
        $this->scopeUtil = $scopeUtil;
37
    }
38
39
    public function verifyResourceRequest(RequestInterface $request, ResponseInterface $response, $scope = null)
40
    {
41
        $token = $this->getAccessTokenData($request, $response);
42
43
        // Check if we have token data
44
        if (is_null($token)) {
45
            return false;
46
        }
47
48
        /**
49
         * Check scope, if provided
50
         * If token doesn't have a scope, it's null/empty, or it's insufficient, then throw 403
51
         * @see http://tools.ietf.org/html/rfc6750#section-3.1
52
         */
53
        if ($scope && (!isset($token["scope"]) || !$token["scope"] || !$this->scopeUtil->checkScope($scope, $token["scope"]))) {
54
            $response->setError(403, 'insufficient_scope', 'The request requires higher privileges than provided by the access token');
55
            $response->addHttpHeaders(array(
56
                'WWW-Authenticate' => sprintf('%s realm="%s", scope="%s", error="%s", error_description="%s"',
57
                    $this->tokenType->getTokenType(),
58
                    $this->config['www_realm'],
59
                    $scope,
60
                    $response->getParameter('error'),
61
                    $response->getParameter('error_description')
62
                )
63
            ));
64
65
            return false;
66
        }
67
68
        // allow retrieval of the token
69
        $this->token = $token;
70
71
        return (bool) $token;
72
    }
73
74
    public function getAccessTokenData(RequestInterface $request, ResponseInterface $response)
75
    {
76
        // Get the token parameter
77
        if ($token_param = $this->tokenType->getAccessTokenParameter($request, $response)) {
78
            // Get the stored token data (from the implementing subclass)
79
            // Check we have a well formed token
80
            // Check token expiration (expires is a mandatory paramter)
81
            if (!$token = $this->tokenStorage->getAccessToken($token_param)) {
82
                $response->setError(401, 'invalid_token', 'The access token provided is invalid');
83
            } elseif (!isset($token["expires"]) || !isset($token["client_id"])) {
84
                $response->setError(401, 'malformed_token', 'Malformed token (missing "expires")');
85
            } elseif (time() > $token["expires"]) {
86
                $response->setError(401, 'expired_token', 'The access token provided has expired');
87
            } else {
88
                return $token;
89
            }
90
        }
91
92
        $authHeader = sprintf('%s realm="%s"', $this->tokenType->getTokenType(), $this->config['www_realm']);
93
94
        if ($error = $response->getParameter('error')) {
95
            $authHeader = sprintf('%s, error="%s"', $authHeader, $error);
96
            if ($error_description = $response->getParameter('error_description')) {
97
                $authHeader = sprintf('%s, error_description="%s"', $authHeader, $error_description);
98
            }
99
        }
100
101
        $response->addHttpHeaders(array('WWW-Authenticate' => $authHeader));
102
103
        return null;
104
    }
105
106
    // convenience method to allow retrieval of the token
107
    public function getToken()
108
    {
109
        return $this->token;
110
    }
111
}
112