Controller::index()   C
last analyzed

Complexity

Conditions 11
Paths 194

Size

Total Lines 67
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 11
eloc 37
c 2
b 0
f 0
nc 194
nop 1
dl 0
loc 67
rs 6.5333

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Riddler7\Oauth2GraphQL;
4
5
use Exception;
6
use SilverStripe\Control\Director;
0 ignored issues
show
Bug introduced by
The type SilverStripe\Control\Director 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...
7
use SilverStripe\Core\Config\Config;
0 ignored issues
show
Bug introduced by
The type SilverStripe\Core\Config\Config 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...
8
use SilverStripe\Control\HTTPRequest;
0 ignored issues
show
Bug introduced by
The type SilverStripe\Control\HTTPRequest 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...
9
use SilverStripe\Control\HTTPResponse;
0 ignored issues
show
Bug introduced by
The type SilverStripe\Control\HTTPResponse 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...
10
use SilverStripe\GraphQL\Controller as GraphQLController;
0 ignored issues
show
Bug introduced by
The type SilverStripe\GraphQL\Controller 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...
11
use SilverStripe\GraphQL\Manager;
0 ignored issues
show
Bug introduced by
The type SilverStripe\GraphQL\Manager 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...
12
use SilverStripe\Versioned\Versioned;
0 ignored issues
show
Bug introduced by
The type SilverStripe\Versioned\Versioned 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...
13
14
class Controller extends GraphQLController
15
{
16
    private static $cors = [
0 ignored issues
show
introduced by
The private property $cors is not used, and could be removed.
Loading history...
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
introduced by
$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
            $errorCode = $exception->getCode();
66
67
            // check for an http error, if we have one, return it straight away with correct http status code
68
            if ($errorCode >= 400 || $errorCode <= 599) {
69
                $result = [
70
                    'errors' => ['message' => $exception->getMessage(), 'code' => $exception->getCode()]
71
                ];
72
73
                $response = $this->addCorsHeaders($request, new HTTPResponse(json_encode($result), $exception->getCode()));
74
                return $response->addHeader('Content-Type', 'application/json');
75
            }
76
77
            $error = ['message' => $exception->getMessage()];
78
79
            if (Director::isDev()) {
80
                $error['code'] = $exception->getCode();
81
                $error['file'] = $exception->getFile();
82
                $error['line'] = $exception->getLine();
83
                $error['trace'] = $exception->getTrace();
84
            }
85
86
            $result = [
87
                'errors' => [$error]
88
            ];
89
        }
90
91
        $response = $this->addCorsHeaders($request, new HTTPResponse(json_encode($result)));
92
        return $response->addHeader('Content-Type', 'application/json');
93
    }
94
95
    /**
96
     * Update default to add Allow-Credentials
97
     *
98
     * @param HTTPRequest  $request
99
     * @param HTTPResponse $response
100
     *
101
     * @return HTTPResponse
102
     */
103
    public function addCorsHeaders(HTTPRequest $request, HTTPResponse $response)
104
    {
105
        $response = parent::addCorsHeaders($request, $response);
106
107
        $corsConfig = Config::inst()->get(static::class, 'cors');
108
109
        if ($corsConfig['Enabled']) {
110
            $response->addHeader('Access-Control-Allow-Credentials', $corsConfig['Allow-Credentials']);
111
        }
112
113
        return $response;
114
    }
115
116
    /**
117
     * Add contexts provided by oauth.
118
     *
119
     * @param HTTPRequest $request
120
     * @param Manager    $manager
121
     */
122
    protected function addOauthContexts(HTTPRequest $request, Manager $manager)
123
    {
124
        if (!empty($request->getHeader('oauth_scopes'))) {
125
            // split comma list into an array for easier consumption
126
            $manager->addContext('oauthScopes', $request->getHeader('oauth_scopes'));
127
        }
128
129
        if (!empty($request->getHeader('oauth_client_id'))) {
130
            $manager->addContext('oauthClientIdentifier', $request->getHeader('oauth_client_id'));
131
132
            // request must have an oauth client
133
        } else {
134
            throw new Exception('A valid client is required', 403);
135
        }
136
    }
137
138
    /**
139
     * Use static for config.
140
     *
141
     * @param HTTPRequest $request
142
     *
143
     * @return HTTPResponse
144
     */
145
    protected function handleOptions(HTTPRequest $request)
146
    {
147
        $response = HTTPResponse::create();
148
        $corsConfig = Config::inst()->get(static::class, 'cors');
149
        if ($corsConfig['Enabled']) {
150
            // CORS config is enabled and the request is an OPTIONS pre-flight.
151
            // Process the CORS config and add appropriate headers.
152
            $this->addCorsHeaders($request, $response);
153
        } else {
154
            // CORS is disabled but we have received an OPTIONS request.  This is not a valid request method in this
155
            // situation.  Return a 405 Method Not Allowed response.
156
            $this->httpError(405, "Method Not Allowed");
157
        }
158
        return $response;
159
    }
160
161
    /**
162
     * Prevent error when there is no member. It is up to resolvers to determine whether login is required.
163
     *
164
     * @param HTTPRequest $request
165
     *
166
     * @return \SilverStripe\Security\Member
0 ignored issues
show
Bug introduced by
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...
167
     * @throws \SilverStripe\ORM\ValidationException
168
     */
169
    protected function getRequestUser(HTTPRequest $request)
170
    {
171
        // if permissions required, pass off to parent to enforce member
172
        if ($request->param('Permissions')) {
173
            return parent::getRequestUser($request);
174
        }
175
176
        $authenticator = $this->getAuthHandler()->getAuthenticator($request);
177
178
        return $authenticator ? $authenticator->authenticate($request) : null;
179
    }
180
}
181