Passed
Push — master ( 98569b...e6a2e6 )
by Conrad
01:23
created

src/Controller.php (2 issues)

1
<?php
2
3
namespace Riddler7\Oauth2GraphQL;
4
5
use League\Flysystem\Exception;
6
use SilverStripe\Control\Director;
7
use SilverStripe\Core\Config\Config;
8
use SilverStripe\Control\HTTPRequest;
9
use SilverStripe\Control\HTTPResponse;
10
use SilverStripe\GraphQL\Controller as GraphQLController;
11
use SilverStripe\GraphQL\Manager;
12
use SilverStripe\Versioned\Versioned;
13
14
class Controller extends GraphQLController
15
{
16
    private static $cors = [
17
        'Allow-Credentials' => ''
18
    ];
19
20
    /**
21
     * Handles requests to the index action (e.g. /graphql)
22
     *
23
     * @param HTTPRequest $request
24
     * @return HTTPResponse
25
     */
26
    public function index(HTTPRequest $request)
27
    {
28
        $stage = $request->param('Stage');
29
        if ($stage && in_array($stage, [Versioned::DRAFT, Versioned::LIVE])) {
30
            Versioned::set_stage($stage);
31
        }
32
        // Check for a possible CORS preflight request and handle if necessary
33
        // Refer issue 66:  https://github.com/silverstripe/silverstripe-graphql/issues/66
34
        if ($request->httpMethod() === 'OPTIONS') {
35
            return $this->handleOptions($request);
36
        }
37
38
        // Main query handling
39
        try {
40
            $manager = $this->getManager();
41
            $manager->addContext('token', $this->getToken());
42
            $method = null;
43
            if ($request->isGET()) {
44
                $method = 'GET';
45
            } elseif ($request->isPOST()) {
46
                $method = 'POST';
47
            }
48
            $manager->addContext('httpMethod', $method);
49
50
            // Check and validate user for this request
51
            $member = $this->getRequestUser($request);
52
53
            if ($member) {
0 ignored issues
show
$member is of type SilverStripe\Security\Member, thus it always evaluated to true.
Loading history...
54
                $manager->setMember($member);
55
            }
56
57
            $this->addOauthContexts($request, $manager);
58
59
            // Parse input
60
            list($query, $variables) = $this->getRequestQueryVariables($request);
61
62
            // Run query
63
            $result = $manager->query($query, $variables);
64
        } catch (Exception $exception) {
65
            $error = ['message' => $exception->getMessage()];
66
67
            if (Director::isDev()) {
68
                $error['code'] = $exception->getCode();
69
                $error['file'] = $exception->getFile();
70
                $error['line'] = $exception->getLine();
71
                $error['trace'] = $exception->getTrace();
72
            }
73
74
            $result = [
75
                'errors' => [$error]
76
            ];
77
        }
78
79
        $response = $this->addCorsHeaders($request, new HTTPResponse(json_encode($result)));
80
        return $response->addHeader('Content-Type', 'application/json');
81
    }
82
83
    /**
84
     * Update default to add Allow-Credentials
85
     *
86
     * @param HTTPRequest  $request
87
     * @param HTTPResponse $response
88
     *
89
     * @return HTTPResponse
90
     */
91
    public function addCorsHeaders(HTTPRequest $request, HTTPResponse $response)
92
    {
93
        $response = parent::addCorsHeaders($request, $response);
94
95
        $corsConfig = Config::inst()->get(static::class, 'cors');
96
97
        if ($corsConfig['Enabled']) {
98
            $response->addHeader('Access-Control-Allow-Credentials', $corsConfig['Allow-Credentials']);
99
        }
100
101
        return $response;
102
    }
103
104
    /**
105
     * Add contexts provided by oauth.
106
     *
107
     * @param HTTPRequest $request
108
     * @param Manager    $manager
109
     */
110
    protected function addOauthContexts(HTTPRequest $request, Manager $manager)
111
    {
112
        if (!empty($request->getHeader('oauth_scopes'))) {
113
            // split comma list into an array for easier consumption
114
            $manager->addContext('oauthScopes', $request->getHeader('oauth_scopes'));
115
        }
116
117
        if (!empty($request->getHeader('oauth_client_id'))) {
118
            $manager->addContext('oauthClientIdentifier', $request->getHeader('oauth_client_id'));
119
        }
120
    }
121
122
    /**
123
     * Use static for config.
124
     *
125
     * @param HTTPRequest $request
126
     *
127
     * @return HTTPResponse
128
     */
129
    protected function handleOptions(HTTPRequest $request)
130
    {
131
        $response = HTTPResponse::create();
132
        $corsConfig = Config::inst()->get(static::class, 'cors');
133
        if ($corsConfig['Enabled']) {
134
            // CORS config is enabled and the request is an OPTIONS pre-flight.
135
            // Process the CORS config and add appropriate headers.
136
            $this->addCorsHeaders($request, $response);
137
        } else {
138
            // CORS is disabled but we have received an OPTIONS request.  This is not a valid request method in this
139
            // situation.  Return a 405 Method Not Allowed response.
140
            $this->httpError(405, "Method Not Allowed");
141
        }
142
        return $response;
143
    }
144
145
    /**
146
     * Prevent error when there is no member. It is up to resolvers to determine whether login is required.
147
     *
148
     * @param HTTPRequest $request
149
     *
150
     * @return \SilverStripe\Security\Member
0 ignored issues
show
The type SilverStripe\Security\Member was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
151
     * @throws \SilverStripe\ORM\ValidationException
152
     */
153
    protected function getRequestUser(HTTPRequest $request)
154
    {
155
        // if permissions required, pass off to parent to enforce member
156
        if ($request->param('Permissions')) {
157
            return parent::getRequestUser($request);
158
        }
159
160
        return $this->getAuthHandler()->getAuthenticator()->authenticate($request);
161
    }
162
163
}
164