Completed
Pull Request — master (#28003)
by Piotr
11:34
created

AccountModuleMiddleware::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 4
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Jörn Friedrich Dreyer <[email protected]>
4
 *
5
 * @copyright Copyright (c) 2018, ownCloud GmbH
6
 * @license AGPL-3.0
7
 *
8
 * This code is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License, version 3,
10
 * as published by the Free Software Foundation.
11
 *
12
 * This program 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 Affero General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Affero General Public License, version 3,
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
19
 *
20
 */
21
22
namespace OC\Core\Middleware;
23
24
use Exception;
25
use OC\Authentication\AccountModule\Manager;
26
use OC\Authentication\Exceptions\AccountCheckException;
27
use OC\Core\Controller\LoginController;
28
use OCP\AppFramework\Controller;
29
use OCP\AppFramework\Http;
30
use OCP\AppFramework\Middleware;
31
use OCP\AppFramework\Utility\IControllerMethodReflector;
32
use OCP\Authentication\IAccountModuleController;
33
use OCP\ILogger;
34
use OCP\IUserSession;
35
36
/**
37
 * Class AccountModuleMiddleware
38
 *
39
 * Apps can register IAccountModules in their info.xml. These IAccountModules
40
 * will be checked on every request. So the check() call should be cheap.
41
 *
42
 * @package OC\Core\Middleware
43
 */
44
class AccountModuleMiddleware extends Middleware {
45
46
	/** @var ILogger */
47
	private $logger;
48
49
	/** @var Manager */
50
	private $manager;
51
52
	/** @var IUserSession */
53
	private $session;
54
55
	/** @var IControllerMethodReflector */
56
	private $reflector;
57
58
	/**
59
	 * @param ILogger $logger
60
	 * @param Manager $manager
61
	 * @param IUserSession $session
62
	 * @param IControllerMethodReflector $reflector
63
	 */
64
	public function __construct(
65
		ILogger $logger,
66
		Manager $manager,
67
		IUserSession $session,
68
		IControllerMethodReflector $reflector
69
	) {
70
		$this->logger = $logger;
71
		$this->manager = $manager;
72
		$this->session = $session;
73
		$this->reflector = $reflector;
74
	}
75
76
	/**
77
	 * @param Controller $controller
78
	 * @param string $methodName
79
	 * @throws AccountCheckException
80
	 */
81
	public function beforeController($controller, $methodName) {
82
		if ($this->reflector->hasAnnotation('PublicPage')) {
83
			// Don't block public pages
84
			return;
85
		}
86
87
		if ($controller instanceof LoginController && $methodName === 'logout') {
88
			// Don't block the logout page
89
			return;
90
		}
91
92
		if ($controller instanceof IAccountModuleController) {
93
			// Don't block any IAccountModuleController controllers
94
			return;
95
		}
96
97
		if ($this->session->isLoggedIn()) {
98
			$user = $this->session->getUser();
99
			if ($user === null) {
100
				throw new \UnexpectedValueException('User isLoggedIn but session does not contain user');
101
			}
102
			$this->manager->check($user);
103
		}
104
	}
105
106
	/**
107
	 * @param Controller $controller
108
	 * @param string $methodName
109
	 * @param Exception $exception
110
	 * @return Http\Response
111
	 * @throws Exception
112
	 */
113
	public function afterException($controller, $methodName, Exception $exception) {
114
		if ($exception instanceof AccountCheckException) {
115
			$this->logger->debug('IAccountModule check failed: {message}, {code}', [
116
				'app'=>__METHOD__,
117
				'message' => $exception->getMessage(),
118
				'code' => $exception->getCode()
119
			]);
120
			return $exception->getRedirectResponse();
121
		}
122
		throw $exception;
123
	}
124
}
125