This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Copyright (c) Enalean, 2012 - 2015. All Rights Reserved. |
||
4 | * |
||
5 | * This file is a part of Tuleap. |
||
6 | * |
||
7 | * Tuleap is free software; you can redistribute it and/or modify |
||
8 | * it under the terms of the GNU General Public License as published by |
||
9 | * the Free Software Foundation; either version 2 of the License, or |
||
10 | * (at your option) any later version. |
||
11 | * |
||
12 | * Tuleap is distributed in the hope that it will be useful, |
||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
15 | * GNU General Public License for more details. |
||
16 | * |
||
17 | * You should have received a copy of the GNU General Public License |
||
18 | * along with Tuleap. If not, see <http://www.gnu.org/licenses/>. |
||
19 | */ |
||
20 | |||
21 | require_once 'common/plugin/Plugin.class.php'; |
||
22 | |||
23 | /** |
||
24 | * Routes HTTP (and maybe SOAP ?) requests to the appropriate controllers |
||
25 | * (e.g. PlanningController, MilestoneController...). |
||
26 | * |
||
27 | * See AgileDashboardRouter::route() |
||
28 | * |
||
29 | * TODO: Layout management should be extracted and moved to controllers or views. |
||
30 | */ |
||
31 | class AgileDashboardRouter { |
||
32 | |||
33 | /** |
||
34 | * @var Plugin |
||
35 | */ |
||
36 | private $plugin; |
||
37 | |||
38 | /** |
||
39 | * @param Service |
||
40 | */ |
||
41 | private $service; |
||
42 | |||
43 | /** |
||
44 | * @var Planning_MilestoneFactory |
||
45 | */ |
||
46 | private $milestone_factory; |
||
47 | |||
48 | /** |
||
49 | * @var PlanningFactory |
||
50 | */ |
||
51 | private $planning_factory; |
||
52 | |||
53 | /** |
||
54 | * @var Planning_ShortAccessFactory |
||
55 | */ |
||
56 | private $planning_shortaccess_factory; |
||
57 | |||
58 | /** |
||
59 | * @var Planning_MilestoneControllerFactory |
||
60 | */ |
||
61 | private $milestone_controller_factory; |
||
62 | |||
63 | /** |
||
64 | * @var ProjectManager |
||
65 | */ |
||
66 | private $project_manager; |
||
67 | |||
68 | /** |
||
69 | * @var AgileDashboard_XMLFullStructureExporter |
||
70 | */ |
||
71 | private $xml_exporter; |
||
72 | |||
73 | /** @var AgileDashboard_KanbanManager */ |
||
74 | private $kanban_manager; |
||
75 | |||
76 | /** @var AgileDashboard_ConfigurationManager */ |
||
77 | private $config_manager; |
||
78 | |||
79 | /** @var AgileDashboard_KanbanFactory */ |
||
80 | private $kanban_factory; |
||
81 | |||
82 | /** @var PlanningPermissionsManager */ |
||
83 | private $planning_permissions_manager; |
||
84 | |||
85 | /** @var AgileDashboard_HierarchyChecker */ |
||
86 | private $hierarchy_checker; |
||
87 | |||
88 | public function __construct( |
||
89 | Plugin $plugin, |
||
90 | Planning_MilestoneFactory $milestone_factory, |
||
91 | PlanningFactory $planning_factory, |
||
92 | Planning_ShortAccessFactory $planning_shortaccess_factory, |
||
93 | Planning_MilestoneControllerFactory $milestone_controller_factory, |
||
94 | ProjectManager $project_manager, |
||
95 | AgileDashboard_XMLFullStructureExporter $xml_exporter, |
||
96 | AgileDashboard_KanbanManager $kanban_manager, |
||
97 | AgileDashboard_ConfigurationManager $config_manager, |
||
98 | AgileDashboard_KanbanFactory $kanban_factory, |
||
99 | PlanningPermissionsManager $planning_permissions_manager, |
||
100 | AgileDashboard_HierarchyChecker $hierarchy_checker |
||
101 | ) { |
||
102 | $this->plugin = $plugin; |
||
103 | $this->milestone_factory = $milestone_factory; |
||
104 | $this->planning_factory = $planning_factory; |
||
105 | $this->planning_shortaccess_factory = $planning_shortaccess_factory; |
||
106 | $this->milestone_controller_factory = $milestone_controller_factory; |
||
107 | $this->project_manager = $project_manager; |
||
108 | $this->xml_exporter = $xml_exporter; |
||
109 | $this->kanban_manager = $kanban_manager; |
||
110 | $this->config_manager = $config_manager; |
||
111 | $this->kanban_factory = $kanban_factory; |
||
112 | $this->planning_permissions_manager = $planning_permissions_manager; |
||
113 | $this->hierarchy_checker = $hierarchy_checker; |
||
114 | } |
||
115 | |||
116 | /** |
||
117 | * Routes the given request to the appropriate controller. |
||
118 | * |
||
119 | * TODO: |
||
120 | * - Use a 'resource' parameter to deduce the controller (e.g. someurl/?resource=planning&id=2 ) |
||
121 | * - Pass $request to action methods |
||
122 | * |
||
123 | * @param Codendi_Request $request |
||
124 | */ |
||
125 | public function route(Codendi_Request $request) { |
||
126 | $planning_controller = $this->buildPlanningController($request); |
||
127 | $agile_dashboard_xml_controller = new AgileDashboard_XMLController( |
||
128 | $request, |
||
129 | $this->planning_factory, |
||
130 | $this->milestone_factory, |
||
131 | $this->plugin->getThemePath(), |
||
132 | $this->kanban_factory |
||
133 | ); |
||
134 | |||
135 | switch($request->get('action')) { |
||
136 | case 'show': |
||
137 | $this->routeShowPlanning($request); |
||
138 | break; |
||
139 | case 'show-top': |
||
140 | $this->routeShowTopPlanning($request, $planning_controller); |
||
141 | break; |
||
142 | case 'new': |
||
143 | $this->renderAction($planning_controller, 'new_', $request); |
||
144 | break; |
||
145 | case 'import-form': |
||
146 | $this->renderAction($planning_controller, 'importForm', $request); |
||
147 | break; |
||
148 | case 'export-to-file': |
||
149 | $this->executeAction($planning_controller, 'exportToFile'); |
||
150 | break; |
||
151 | case 'create': |
||
152 | $this->executeAction($planning_controller, 'create'); |
||
153 | break; |
||
154 | case 'edit': |
||
155 | $this->renderAction($planning_controller, 'edit', $request); |
||
156 | break; |
||
157 | case 'update': |
||
158 | $this->executeAction($planning_controller, 'update'); |
||
159 | break; |
||
160 | case 'delete': |
||
161 | $this->executeAction($planning_controller, 'delete'); |
||
162 | break; |
||
163 | case 'admin': |
||
164 | if ($this->userIsAdmin($request)) { |
||
165 | if ($request->get('pane') === 'kanban') { |
||
166 | $this->renderAction($this->buildController($request), 'adminKanban', $request); |
||
167 | } else { |
||
168 | $this->renderAction($this->buildController($request), 'adminScrum', $request); |
||
169 | } |
||
170 | } else { |
||
171 | $this->renderAction($planning_controller, 'index', $request); |
||
172 | } |
||
173 | break; |
||
174 | case 'export': |
||
175 | $this->executeAction($agile_dashboard_xml_controller, 'export'); |
||
176 | break; |
||
177 | case 'import': |
||
178 | $this->executeAction($agile_dashboard_xml_controller, 'import'); |
||
179 | break; |
||
180 | case 'submilestonedata' : |
||
181 | $milestone_controller = $this->milestone_controller_factory->getMilestoneController($request); |
||
182 | $this->executeAction($milestone_controller, 'submilestonedata'); |
||
183 | break; |
||
184 | case 'get-more-milestones': |
||
185 | $this->executeAction($planning_controller, 'getMoreMilestones'); |
||
186 | break; |
||
187 | case 'solve-inconsistencies': |
||
188 | $milestone_controller = $this->milestone_controller_factory->getMilestoneController($request); |
||
189 | $this->executeAction($milestone_controller, 'solveInconsistencies'); |
||
190 | break; |
||
191 | case 'updateConfiguration': |
||
192 | $this->executeAction($this->buildController($request), 'updateConfiguration'); |
||
193 | break; |
||
194 | case 'createKanban': |
||
195 | $this->executeAction($this->buildController($request), 'createKanban'); |
||
196 | break; |
||
197 | case 'showKanban': |
||
198 | $header_options = array( |
||
199 | 'body_class' => array('agiledashboard_kanban'), |
||
200 | Layout::INCLUDE_FAT_COMBINED => false, |
||
201 | ); |
||
202 | $this->renderAction($this->buildController($request), 'showKanban', $request, array(), $header_options); |
||
203 | break; |
||
204 | case 'index': |
||
205 | default: |
||
206 | $header_options = array( |
||
207 | 'body_class' => array('agiledashboard_homepage') |
||
208 | ); |
||
209 | $this->renderAction($planning_controller, 'index', $request, array(), $header_options); |
||
210 | } |
||
211 | } |
||
212 | |||
213 | /** |
||
214 | * Returns the page title according to the current controller action name. |
||
215 | * |
||
216 | * TODO: |
||
217 | * - Use a layout template, and move title retrieval to the appropriate presenters. |
||
218 | * |
||
219 | * @param string $action_name The controller action name (e.g. index, show...). |
||
220 | * |
||
221 | * @return string |
||
222 | */ |
||
223 | private function getHeaderTitle($action_name) { |
||
224 | $header_title = array( |
||
225 | 'index' => $GLOBALS['Language']->getText('plugin_agiledashboard', 'service_lbl_key'), |
||
226 | 'exportToFile' => $GLOBALS['Language']->getText('plugin_agiledashboard', 'service_lbl_key'), |
||
227 | 'adminScrum' => $GLOBALS['Language']->getText('plugin_agiledashboard', 'AdminScrum'), |
||
228 | 'adminKanban' => $GLOBALS['Language']->getText('plugin_agiledashboard', 'AdminKanban'), |
||
229 | 'new_' => $GLOBALS['Language']->getText('plugin_agiledashboard', 'planning_new'), |
||
230 | 'importForm' => $GLOBALS['Language']->getText('plugin_agiledashboard', 'planning_new'), |
||
231 | 'edit' => $GLOBALS['Language']->getText('plugin_agiledashboard', 'planning_edit'), |
||
232 | 'show' => $GLOBALS['Language']->getText('plugin_agiledashboard', 'planning_show'), |
||
233 | 'showTop' => $GLOBALS['Language']->getText('plugin_agiledashboard', 'planning_show'), |
||
234 | 'showKanban' => $GLOBALS['Language']->getText('plugin_agiledashboard', 'kanban_show') |
||
235 | ); |
||
236 | |||
237 | return $header_title[$action_name]; |
||
238 | } |
||
239 | |||
240 | /** |
||
241 | * Retrieves the Agile Dashboard Service instance matching the request group id. |
||
242 | * |
||
243 | * @param Codendi_Request $request |
||
244 | * |
||
245 | * @return Service |
||
246 | */ |
||
247 | private function getService(Codendi_Request $request) { |
||
248 | if ($this->service == null) { |
||
249 | $project = $request->getProject(); |
||
250 | $this->service = $project->getService('plugin_agiledashboard'); |
||
251 | } |
||
252 | return $this->service; |
||
253 | } |
||
254 | |||
255 | /** |
||
256 | * Renders the top banner + navigation for all Agile Dashboard pages. |
||
257 | * |
||
258 | * @param MVC2_Controller $controller The controller instance |
||
259 | * @param Codendi_Request $request The request |
||
260 | * @param string $title The page title |
||
261 | */ |
||
262 | private function displayHeader(MVC2_Controller $controller, |
||
263 | Codendi_Request $request, |
||
264 | $title, |
||
265 | array $header_options = array()) { |
||
266 | $service = $this->getService($request); |
||
267 | if (! $service) { |
||
268 | exit_error( |
||
269 | $GLOBALS['Language']->getText('global', 'error'), |
||
270 | $GLOBALS['Language']->getText( |
||
271 | 'project_service', |
||
272 | 'service_not_used', |
||
273 | $GLOBALS['Language']->getText('plugin_agiledashboard', 'service_lbl_key')) |
||
274 | ); |
||
275 | } |
||
276 | |||
277 | $toolbar = array(); |
||
278 | $breadcrumbs = $controller->getBreadcrumbs($this->plugin->getPluginPath()); |
||
279 | if ($this->userIsAdmin($request)) { |
||
280 | $toolbar[] = array( |
||
281 | 'title' => $GLOBALS['Language']->getText('global', 'Admin'), |
||
282 | 'url' => AGILEDASHBOARD_BASE_URL .'/?'. http_build_query(array( |
||
283 | 'group_id' => $request->get('group_id'), |
||
284 | 'action' => 'admin', |
||
285 | )) |
||
286 | ); |
||
287 | } |
||
288 | $service->displayHeader($title, $breadcrumbs->getCrumbs(), $toolbar, $header_options); |
||
289 | } |
||
290 | |||
291 | private function userIsAdmin(Codendi_Request $request) { |
||
292 | return $request->getProject()->userIsAdmin($request->getCurrentUser()); |
||
0 ignored issues
–
show
|
|||
293 | } |
||
294 | |||
295 | /** |
||
296 | * Renders the bottom footer for all Agile Dashboard pages. |
||
297 | * |
||
298 | * @param Codendi_Request $request |
||
299 | */ |
||
300 | private function displayFooter(Codendi_Request $request) { |
||
301 | $this->getService($request)->displayFooter(); |
||
302 | } |
||
303 | |||
304 | /** |
||
305 | * Builds a new Planning_Controller instance. |
||
306 | * |
||
307 | * @param Codendi_Request $request |
||
308 | * |
||
309 | * @return Planning_Controller |
||
310 | */ |
||
311 | protected function buildPlanningController(Codendi_Request $request) { |
||
312 | return new Planning_Controller( |
||
313 | $request, |
||
314 | $this->planning_factory, |
||
315 | $this->planning_shortaccess_factory, |
||
316 | $this->milestone_factory, |
||
317 | $this->project_manager, |
||
318 | $this->xml_exporter, |
||
319 | $this->plugin->getThemePath(), |
||
320 | $this->plugin->getPluginPath(), |
||
321 | $this->kanban_manager, |
||
322 | $this->config_manager, |
||
323 | $this->kanban_factory, |
||
324 | $this->planning_permissions_manager, |
||
325 | $this->hierarchy_checker |
||
326 | ); |
||
327 | } |
||
328 | |||
329 | protected function buildController(Codendi_Request $request) { |
||
330 | return new AgileDashboard_Controller( |
||
331 | $request, |
||
332 | $this->planning_factory, |
||
333 | $this->kanban_manager, |
||
334 | $this->kanban_factory, |
||
335 | $this->config_manager, |
||
336 | TrackerFactory::instance(), |
||
337 | new AgileDashboard_PermissionsManager(), |
||
338 | $this->hierarchy_checker |
||
339 | ); |
||
340 | } |
||
341 | |||
342 | /** |
||
343 | * Renders the given controller action, with page header/footer. |
||
344 | * |
||
345 | * @param MVC2_Controller $controller The controller instance. |
||
346 | * @param string $action_name The controller action name (e.g. index, show...). |
||
347 | * @param Codendi_Request $request The request |
||
348 | * @param array $args Arguments to pass to the controller action method. |
||
349 | */ |
||
350 | protected function renderAction(MVC2_Controller $controller, |
||
351 | $action_name, |
||
352 | Codendi_Request $request, |
||
353 | array $args = array(), |
||
354 | array $header_options = array()) { |
||
355 | $content = $this->executeAction($controller, $action_name, $args); |
||
356 | $header_options = array_merge($header_options, $controller->getHeaderOptions()); |
||
357 | |||
358 | $this->displayHeader($controller, $request, $this->getHeaderTitle($action_name), $header_options); |
||
359 | echo $content; |
||
360 | $this->displayFooter($request); |
||
361 | } |
||
362 | |||
363 | /** |
||
364 | * Executes the given controller action, without rendering page header/footer. |
||
365 | * Useful for actions ending with a redirection instead of page rendering. |
||
366 | * |
||
367 | * @param MVC2_Controller $controller The controller instance. |
||
368 | * @param string $action_name The controller action name (e.g. index, show...). |
||
369 | * @param array $args Arguments to pass to the controller action method. |
||
370 | */ |
||
371 | protected function executeAction(MVC2_Controller $controller, |
||
372 | $action_name, |
||
373 | array $args = array()) { |
||
374 | |||
375 | return call_user_func_array(array($controller, $action_name), $args); |
||
376 | } |
||
377 | |||
378 | /** |
||
379 | * Routes some milestone-related requests. |
||
380 | * |
||
381 | * TODO: |
||
382 | * - merge into AgileDashboardRouter::route() |
||
383 | * |
||
384 | * @param Codendi_Request $request |
||
385 | */ |
||
386 | public function routeShowPlanning(Codendi_Request $request) { |
||
387 | $aid = $request->getValidated('aid', 'int', 0); |
||
388 | switch ($aid) { |
||
389 | case -1: |
||
390 | $controller = new Planning_ArtifactCreationController($this->planning_factory, $request); |
||
391 | $this->executeAction($controller, 'createArtifact'); |
||
392 | break; |
||
393 | case 0: |
||
394 | $controller = new Planning_MilestoneSelectorController($request, $this->milestone_factory); |
||
395 | $this->executeAction($controller, 'show'); |
||
396 | /* no break */ |
||
397 | default: |
||
398 | $controller = $this->milestone_controller_factory->getMilestoneController($request); |
||
399 | $action_arguments = array(); |
||
400 | $this->renderAction($controller, 'show', $request, $action_arguments, array('body_class' => array('agiledashboard_planning'))); |
||
401 | } |
||
402 | } |
||
403 | |||
404 | public function routeShowTopPlanning(Codendi_Request $request, $default_controller) { |
||
405 | $user = $request->getCurrentUser(); |
||
406 | if (! $user) { |
||
407 | $this->renderAction($default_controller, 'index', $request); |
||
408 | } |
||
409 | |||
410 | $service = $this->getService($request); |
||
411 | if (! $service) { |
||
412 | exit_error( |
||
413 | $GLOBALS['Language']->getText('global', 'error'), |
||
414 | $GLOBALS['Language']->getText( |
||
415 | 'project_service', |
||
416 | 'service_not_used', |
||
417 | $GLOBALS['Language']->getText('plugin_agiledashboard', 'service_lbl_key')) |
||
418 | ); |
||
419 | } |
||
420 | |||
421 | $toolbar = array(); |
||
422 | if ($this->userIsAdmin($request)) { |
||
423 | $toolbar[] = array( |
||
424 | 'title' => $GLOBALS['Language']->getText('global', 'Admin'), |
||
425 | 'url' => AGILEDASHBOARD_BASE_URL .'/?'. http_build_query(array( |
||
426 | 'group_id' => $request->get('group_id'), |
||
427 | 'action' => 'admin', |
||
428 | )) |
||
429 | ); |
||
430 | } |
||
431 | |||
432 | $no_breadcrumbs = new BreadCrumb_NoCrumb(); |
||
433 | $controller = $this->milestone_controller_factory->getVirtualTopMilestoneController($request); |
||
434 | $header_options = array_merge( |
||
435 | array('body_class' => array('agiledashboard_planning')), |
||
436 | $controller->getHeaderOptions() |
||
437 | ); |
||
438 | |||
439 | $top_planning_rendered = $this->executeAction($controller, 'showTop', array()); |
||
440 | $service->displayHeader($this->getHeaderTitle('showTop'), $no_breadcrumbs, $toolbar, $header_options); |
||
441 | echo $top_planning_rendered; |
||
442 | $this->displayFooter($request); |
||
443 | } |
||
444 | } |
||
445 |
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.