Passed
Push — master ( e6ce91...429907 )
by MusikAnimal
04:46
created

DefaultController   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 240
Duplicated Lines 0 %

Test Coverage

Coverage 40.35%

Importance

Changes 0
Metric Value
eloc 77
dl 0
loc 240
ccs 23
cts 57
cp 0.4035
rs 10
c 0
b 0
f 0
wmc 19

11 Methods

Rating   Name   Duplication   Size   Complexity  
A loginAction() 0 16 2
A getOauthClient() 0 20 2
A configAction() 0 21 4
A oauthCallbackAction() 0 26 2
A indexAction() 0 4 1
A getIndexRoute() 0 3 1
A wikify() 0 4 1
A assessmentsConfigApiAction() 0 12 1
A projectAssessmentsApiAction() 0 5 1
A namespacesApiAction() 0 8 1
A normalizeProjectApiAction() 0 7 1
1
<?php
2
/**
3
 * This file contains only the DefaultController class.
4
 */
5
6
namespace AppBundle\Controller;
7
8
use MediaWiki\OAuthClient\Client;
9
use MediaWiki\OAuthClient\ClientConfig;
10
use MediaWiki\OAuthClient\Consumer;
11
use MediaWiki\OAuthClient\Exception;
12
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
13
use Symfony\Component\HttpFoundation\JsonResponse;
14
use Symfony\Component\HttpFoundation\RedirectResponse;
15
use Symfony\Component\HttpFoundation\Request;
16
use Symfony\Component\HttpFoundation\Response;
17
use Symfony\Component\HttpFoundation\Session\Session;
18
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
19
use Xtools\Edit;
20
use Xtools\ProjectRepository;
21
22
/**
23
 * The DefaultController handles the homepage, about pages, and user authentication.
24
 */
25
class DefaultController extends XtoolsController
26
{
27
    /** @var Client The Oauth HTTP client. */
28
    protected $oauthClient;
29
30
    /**
31
     * Required to be defined by XtoolsController, though here it is unused.
32
     * @return string
33
     * @codeCoverageIgnore
34
     */
35
    public function getIndexRoute()
36
    {
37
        return 'homepage';
38
    }
39
40
    /**
41
     * Display the homepage.
42
     * @Route("/", name="homepage")
43
     * @Route("/index.php", name="homepageIndexPhp")
44
     */
45 1
    public function indexAction()
46
    {
47 1
        return $this->render('default/index.html.twig', [
48 1
            'xtPage' => 'home',
49
        ]);
50
    }
51
52
    /**
53
     * Diplay XTools' about page.
54
     * @Route("/about", name="aboutPage")
55
     * @Route("/info.php", name="info")
56
     */
57 1
    public function aboutAction()
58
    {
59 1
        return $this->render('default/about.html.twig', [
60 1
            'xtPage' => 'about',
61
        ]);
62
    }
63
64
    /**
65
     * Display some configuration details, when in development mode.
66
     * @Route("/config", name="configPage")
67
     * @codeCoverageIgnore
68
     */
69
    public function configAction()
70
    {
71
72
        if ($this->container->getParameter('kernel.environment') !== 'dev') {
73
            throw new NotFoundHttpException();
74
        }
75
76
        $params = $this->container->getParameterBag()->all();
0 ignored issues
show
Bug introduced by
The method getParameterBag() does not exist on Symfony\Component\Depend...tion\ContainerInterface. Did you maybe mean getParameter()? ( Ignorable by Annotation )

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

76
        $params = $this->container->/** @scrutinizer ignore-call */ getParameterBag()->all();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
77
78
        foreach ($params as $key => $value) {
79
            if (strpos($key, 'password') !== false) {
80
                $params[$key] = '<REDACTED>';
81
            }
82
        }
83
84
        // replace this example code with whatever you need
85
        return $this->render('default/config.html.twig', [
86
            'xtTitle' => 'Config',
87
            'xtPageTitle' => 'Config',
88
            'xtPage' => 'index',
89
            'dump' => print_r($params, true),
90
        ]);
91
    }
92
93
    /**
94
     * Redirect to the default project (or Meta) for Oauth authentication.
95
     * @Route("/login", name="login")
96
     * @return RedirectResponse
97
     * @throws Exception If initialization fails.
98
     */
99
    public function loginAction()
100
    {
101
        try {
102
            list( $next, $token ) = $this->getOauthClient()->initiate();
103
        } catch (Exception $oauthException) {
104
            throw $oauthException;
105
            // @TODO Make this work.
106
            //$this->addFlash('error', $oauthException->getMessage());
107
            //return $this->redirectToRoute('homepage');
108
        }
109
110
        // Save the request token to the session.
111
        /** @var Session $session */
112
        $session = $this->get('session');
113
        $session->set('oauth_request_token', $token);
114
        return new RedirectResponse($next);
115
    }
116
117
    /**
118
     * Receive authentication credentials back from the Oauth wiki.
119
     * @Route("/oauth_callback", name="oauth_callback")
120
     * @Route("/oauthredirector.php", name="old_oauth_callback")
121
     * @param Request $request The HTTP request.
122
     * @return RedirectResponse
123
     */
124 1
    public function oauthCallbackAction(Request $request)
125
    {
126
        // Give up if the required GET params don't exist.
127 1
        if (!$request->get('oauth_verifier')) {
128 1
            throw $this->createNotFoundException('No OAuth verifier given.');
129
        }
130
131
        /** @var Session $session */
132
        $session = $this->get('session');
133
134
        // Complete authentication.
135
        $client = $this->getOauthClient();
136
        $token = $session->get('oauth_request_token');
137
        $verifier = $request->get('oauth_verifier');
138
        $accessToken = $client->complete($token, $verifier);
139
140
        // Store access token, and remove request token.
141
        $session->set('oauth_access_token', $accessToken);
142
        $session->remove('oauth_request_token');
143
144
        // Store user identity.
145
        $ident = $client->identify($accessToken);
146
        $session->set('logged_in_user', $ident);
147
148
        // Send back to homepage.
149
        return $this->redirectToRoute('homepage');
150
    }
151
152
    /**
153
     * Get an OAuth client, configured to the default project.
154
     * (This shouldn't really be in this class, but oh well.)
155
     * @return Client
156
     * @codeCoverageIgnore
157
     */
158
    protected function getOauthClient()
159
    {
160
        if ($this->oauthClient instanceof Client) {
0 ignored issues
show
introduced by
$this->oauthClient is always a sub-type of MediaWiki\OAuthClient\Client. If $this->oauthClient can have other possible types, add them to src/AppBundle/Controller/DefaultController.php:27.
Loading history...
161
            return $this->oauthClient;
162
        }
163
        $defaultProject = ProjectRepository::getProject(
164
            $this->getParameter('oauth_project'),
165
            $this->container
166
        );
167
        $endpoint = $defaultProject->getUrl(false)
168
                    . $defaultProject->getScript()
169
                    . '?title=Special:OAuth';
170
        $conf = new ClientConfig($endpoint);
171
        $consumerKey = $this->getParameter('oauth_key');
172
        $consumerSecret =  $this->getParameter('oauth_secret');
173
        $conf->setConsumer(new Consumer($consumerKey, $consumerSecret));
174
        $this->oauthClient = new Client($conf);
175
        // Callback URL is hardcoded in the consumer registration.
176
        $this->oauthClient->setCallback('oob');
177
        return $this->oauthClient;
178
    }
179
180
    /**
181
     * Log out the user and return to the homepage.
182
     * @Route("/logout", name="logout")
183
     */
184 1
    public function logoutAction()
185
    {
186 1
        $this->get('session')->invalidate();
187 1
        return $this->redirectToRoute('homepage');
188
    }
189
190
    /************************ API endpoints ************************/
191
192
    /**
193
     * Get domain name, URL, and API URL of the given project.
194
     * @Route("/api/project/normalize/{project}", name="ProjectApiNormalize")
195
     * @return JsonResponse
196
     */
197
    public function normalizeProjectApiAction()
198
    {
199
        return $this->getFormattedApiResponse([
200
            'domain' => $this->project->getDomain(),
201
            'url' => $this->project->getUrl(),
202
            'api' => $this->project->getApiUrl(),
203
            'database' => $this->project->getDatabaseName(),
204
        ]);
205
    }
206
207
    /**
208
     * Get all namespaces of the given project. This endpoint also does the same thing
209
     * as the /project/normalize endpoint, returning other basic info about the project.
210
     * @Route("/api/project/namespaces/{project}", name="ProjectApiNamespaces")
211
     * @return JsonResponse
212
     */
213 1
    public function namespacesApiAction()
214
    {
215 1
        return $this->getFormattedApiResponse([
216 1
            'domain' => $this->project->getDomain(),
217 1
            'url' => $this->project->getUrl(),
218 1
            'api' => $this->project->getApiUrl(),
219 1
            'database' => $this->project->getDatabaseName(),
220 1
            'namespaces' => $this->project->getNamespaces(),
221
        ]);
222
    }
223
224
    /**
225
     * Get assessment data for a given project.
226
     * @Route("/api/project/assessments/{project}", name="ProjectApiAssessments")
227
     * @return JsonResponse
228
     */
229 1
    public function projectAssessmentsApiAction()
230
    {
231 1
        return $this->getFormattedApiResponse([
232 1
            'project' => $this->project->getDomain(),
233 1
            'assessments' => $this->project->getPageAssessments()->getConfig(),
234
        ]);
235
    }
236
237
    /**
238
     * Get assessment data for all projects.
239
     * @Route("/api/project/assessments", name="ApiAssessmentsConfig")
240
     * @return JsonResponse
241
     */
242
    public function assessmentsConfigApiAction()
243
    {
244
        // Here there is no Project, so we don't use XtoolsController::getFormattedApiResponse().
245
        $response = new JsonResponse();
246
        $response->setEncodingOptions(JSON_NUMERIC_CHECK);
247
        $response->setStatusCode(Response::HTTP_OK);
248
        $response->setData([
249
            'projects' => array_keys($this->container->getParameter('assessments')),
250
            'config' => $this->container->getParameter('assessments'),
251
        ]);
252
253
        return $response;
254
    }
255
256
    /**
257
     * Transform given wikitext to HTML using the XTools parser. Wikitext must be passed in as the query 'wikitext'.
258
     * @Route("/api/project/parser/{project}")
259
     * @return string Safe HTML.
260
     */
261
    public function wikify()
262
    {
263
        return new JsonResponse(
264
            Edit::wikifyString($this->request->query->get('wikitext'), $this->project)
265
        );
266
    }
267
}
268