Blame view
sources/lib/private/appframework/middleware/security/securitymiddleware.php
5.08 KB
|
31b7f2792
|
1 2 3 4 5 6 |
<?php /** * ownCloud - App Framework * * @author Bernhard Posselt |
|
6d9380f96
|
7 |
* @copyright 2012 Bernhard Posselt <dev@bernhard-posselt.com> |
|
31b7f2792
|
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
* * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE * License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU AFFERO GENERAL PUBLIC LICENSE for more details. * * You should have received a copy of the GNU Affero General Public * License along with this library. If not, see <http://www.gnu.org/licenses/>. * */ namespace OC\AppFramework\Middleware\Security; use OC\AppFramework\Http; |
|
6d9380f96
|
28 29 |
use OC\AppFramework\Utility\ControllerMethodReflector; use OCP\AppFramework\Http\RedirectResponse; |
|
31b7f2792
|
30 31 32 |
use OCP\AppFramework\Middleware; use OCP\AppFramework\Http\Response; use OCP\AppFramework\Http\JSONResponse; |
|
6d9380f96
|
33 34 |
use OCP\INavigationManager; use OCP\IURLGenerator; |
|
31b7f2792
|
35 |
use OCP\IRequest; |
|
6d9380f96
|
36 |
use OCP\ILogger; |
|
31b7f2792
|
37 38 39 40 41 42 43 44 45 |
/**
* Used to do all the authentication and checking stuff for a controller method
* It reads out the annotations of a controller method and checks which if
* security things should be checked and also handles errors in case a security
* check fails
*/
class SecurityMiddleware extends Middleware {
|
|
6d9380f96
|
46 |
private $navigationManager; |
|
31b7f2792
|
47 |
private $request; |
|
6d9380f96
|
48 49 50 51 52 53 |
private $reflector; private $appName; private $urlGenerator; private $logger; private $isLoggedIn; private $isAdminUser; |
|
31b7f2792
|
54 55 |
/** |
|
31b7f2792
|
56 |
* @param IRequest $request |
|
6d9380f96
|
57 58 59 60 61 62 63 |
* @param ControllerMethodReflector $reflector * @param INavigationManager $navigationManager * @param IURLGenerator $urlGenerator * @param ILogger $logger * @param string $appName * @param bool $isLoggedIn * @param bool $isAdminUser |
|
31b7f2792
|
64 |
*/ |
|
6d9380f96
|
65 66 67 68 69 70 71 72 73 |
public function __construct(IRequest $request,
ControllerMethodReflector $reflector,
INavigationManager $navigationManager,
IURLGenerator $urlGenerator,
ILogger $logger,
$appName,
$isLoggedIn,
$isAdminUser){
$this->navigationManager = $navigationManager;
|
|
31b7f2792
|
74 |
$this->request = $request; |
|
6d9380f96
|
75 76 77 78 79 80 |
$this->reflector = $reflector; $this->appName = $appName; $this->urlGenerator = $urlGenerator; $this->logger = $logger; $this->isLoggedIn = $isLoggedIn; $this->isAdminUser = $isAdminUser; |
|
31b7f2792
|
81 82 83 84 85 86 87 |
} /** * This runs all the security checks before a method call. The * security checks are determined by inspecting the controller method * annotations |
|
6d9380f96
|
88 |
* @param string $controller the controllername or string |
|
31b7f2792
|
89 90 91 92 |
* @param string $methodName the name of the method
* @throws SecurityException when a security check fails
*/
public function beforeController($controller, $methodName){
|
|
31b7f2792
|
93 94 |
// this will set the current navigation entry of the app, use this only // for normal HTML requests and not for AJAX requests |
|
6d9380f96
|
95 |
$this->navigationManager->setActiveEntry($this->appName); |
|
31b7f2792
|
96 97 |
// security checks |
|
6d9380f96
|
98 |
$isPublicPage = $this->reflector->hasAnnotation('PublicPage');
|
|
31b7f2792
|
99 |
if(!$isPublicPage) {
|
|
6d9380f96
|
100 |
if(!$this->isLoggedIn) {
|
|
31b7f2792
|
101 102 |
throw new SecurityException('Current user is not logged in', Http::STATUS_UNAUTHORIZED);
}
|
|
6d9380f96
|
103 104 |
if(!$this->reflector->hasAnnotation('NoAdminRequired')) {
if(!$this->isAdminUser) {
|
|
31b7f2792
|
105 106 107 108 |
throw new SecurityException('Logged in user must be an admin', Http::STATUS_FORBIDDEN);
}
}
}
|
|
6d9380f96
|
109 |
if(!$this->reflector->hasAnnotation('NoCSRFRequired')) {
|
|
31b7f2792
|
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
if(!$this->request->passesCSRFCheck()) {
throw new SecurityException('CSRF check failed', Http::STATUS_PRECONDITION_FAILED);
}
}
}
/**
* If an SecurityException is being caught, ajax requests return a JSON error
* response and non ajax requests redirect to the index
* @param Controller $controller the controller that is being called
* @param string $methodName the name of the method that will be called on
* the controller
* @param \Exception $exception the thrown exception
* @throws \Exception the passed in exception if it cant handle it
* @return Response a Response object or null in case that the exception could not be handled
*/
public function afterException($controller, $methodName, \Exception $exception){
if($exception instanceof SecurityException){
if (stripos($this->request->getHeader('Accept'),'html')===false) {
$response = new JSONResponse(
array('message' => $exception->getMessage()),
$exception->getCode()
);
|
|
6d9380f96
|
137 |
$this->logger->debug($exception->getMessage()); |
|
31b7f2792
|
138 139 140 |
} else {
// TODO: replace with link to route
|
|
6d9380f96
|
141 142 143 |
$url = $this->urlGenerator->getAbsoluteURL('index.php');
// add redirect URL to redirect to the previous page after login
$url .= '?redirect_url=' . urlencode($this->request->server['REQUEST_URI']);
|
|
31b7f2792
|
144 |
$response = new RedirectResponse($url); |
|
6d9380f96
|
145 |
$this->logger->debug($exception->getMessage()); |
|
31b7f2792
|
146 147 148 149 150 151 152 153 154 155 |
} return $response; } throw $exception; } } |