Completed
Push — master ( 2bf15e...34716f )
by Morris
24:46 queued 11:25
created

TwoFactorChallengeController::getLogoutAttribute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
/**
4
 * @copyright Copyright (c) 2016, ownCloud, Inc.
5
 *
6
 * @author Christoph Wurst <[email protected]>
7
 * @author Joas Schilling <[email protected]>
8
 *
9
 * @license AGPL-3.0
10
 *
11
 * This code is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License, version 3,
13
 * as published by the Free Software Foundation.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU Affero General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Affero General Public License, version 3,
21
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
22
 *
23
 */
24
25
namespace OC\Core\Controller;
26
27
use OC\Authentication\TwoFactorAuth\Manager;
28
use OC_User;
29
use OC_Util;
30
use OCP\AppFramework\Controller;
31
use OCP\AppFramework\Http\RedirectResponse;
32
use OCP\AppFramework\Http\TemplateResponse;
33
use OCP\Authentication\TwoFactorAuth\IProvidesCustomCSP;
34
use OCP\Authentication\TwoFactorAuth\TwoFactorException;
35
use OCP\IRequest;
36
use OCP\ISession;
37
use OCP\IURLGenerator;
38
use OCP\IUserSession;
39
40
class TwoFactorChallengeController extends Controller {
41
42
	/** @var Manager */
43
	private $twoFactorManager;
44
45
	/** @var IUserSession */
46
	private $userSession;
47
48
	/** @var ISession */
49
	private $session;
50
51
	/** @var IURLGenerator */
52
	private $urlGenerator;
53
54
	/**
55
	 * @param string $appName
56
	 * @param IRequest $request
57
	 * @param Manager $twoFactorManager
58
	 * @param IUserSession $userSession
59
	 * @param ISession $session
60
	 * @param IURLGenerator $urlGenerator
61
	 */
62
	public function __construct($appName, IRequest $request, Manager $twoFactorManager, IUserSession $userSession,
63
		ISession $session, IURLGenerator $urlGenerator) {
64
		parent::__construct($appName, $request);
65
		$this->twoFactorManager = $twoFactorManager;
66
		$this->userSession = $userSession;
67
		$this->session = $session;
68
		$this->urlGenerator = $urlGenerator;
69
	}
70
71
	/**
72
	 * @return string
73
	 */
74
	protected function getLogoutUrl() {
75
		return OC_User::getLogoutUrl($this->urlGenerator);
76
	}
77
78
	/**
79
	 * @NoAdminRequired
80
	 * @NoCSRFRequired
81
	 *
82
	 * @param string $redirect_url
83
	 * @return TemplateResponse
84
	 */
85
	public function selectChallenge($redirect_url) {
86
		$user = $this->userSession->getUser();
87
		$providers = $this->twoFactorManager->getProviders($user);
0 ignored issues
show
Bug introduced by
It seems like $user defined by $this->userSession->getUser() on line 86 can be null; however, OC\Authentication\TwoFac...Manager::getProviders() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
88
		$backupProvider = $this->twoFactorManager->getBackupProvider($user);
0 ignored issues
show
Bug introduced by
It seems like $user defined by $this->userSession->getUser() on line 86 can be null; however, OC\Authentication\TwoFac...er::getBackupProvider() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
89
90
		$data = [
91
			'providers' => $providers,
92
			'backupProvider' => $backupProvider,
93
			'redirect_url' => $redirect_url,
94
			'logout_url' => $this->getLogoutUrl(),
95
		];
96
		return new TemplateResponse($this->appName, 'twofactorselectchallenge', $data, 'guest');
97
	}
98
99
	/**
100
	 * @NoAdminRequired
101
	 * @NoCSRFRequired
102
	 * @UseSession
103
	 *
104
	 * @param string $challengeProviderId
105
	 * @param string $redirect_url
106
	 * @return TemplateResponse|RedirectResponse
107
	 */
108
	public function showChallenge($challengeProviderId, $redirect_url) {
109
		$user = $this->userSession->getUser();
110
		$provider = $this->twoFactorManager->getProvider($user, $challengeProviderId);
0 ignored issues
show
Bug introduced by
It seems like $user defined by $this->userSession->getUser() on line 109 can be null; however, OC\Authentication\TwoFac...\Manager::getProvider() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
111
		if (is_null($provider)) {
112
			return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
113
		}
114
115
		$backupProvider = $this->twoFactorManager->getBackupProvider($user);
0 ignored issues
show
Bug introduced by
It seems like $user defined by $this->userSession->getUser() on line 109 can be null; however, OC\Authentication\TwoFac...er::getBackupProvider() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
116
		if (!is_null($backupProvider) && $backupProvider->getId() === $provider->getId()) {
117
			// Don't show the backup provider link if we're already showing that provider's challenge
118
			$backupProvider = null;
119
		}
120
121
		$errorMessage = '';
122
		$error = false;
123
		if ($this->session->exists('two_factor_auth_error')) {
124
			$this->session->remove('two_factor_auth_error');
125
			$error = true;
126
			$errorMessage = $this->session->get("two_factor_auth_error_message");
127
			$this->session->remove('two_factor_auth_error_message');
128
		}
129
		$tmpl = $provider->getTemplate($user);
0 ignored issues
show
Bug introduced by
It seems like $user defined by $this->userSession->getUser() on line 109 can be null; however, OCP\Authentication\TwoFa...Provider::getTemplate() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
130
		$tmpl->assign('redirect_url', $redirect_url);
131
		$data = [
132
			'error' => $error,
133
			'error_message' => $errorMessage,
134
			'provider' => $provider,
135
			'backupProvider' => $backupProvider,
136
			'logout_url' => $this->getLogoutUrl(),
137
			'redirect_url' => $redirect_url,
138
			'template' => $tmpl->fetchPage(),
139
		];
140
		$response = new TemplateResponse($this->appName, 'twofactorshowchallenge', $data, 'guest');
141
		if ($provider instanceof IProvidesCustomCSP) {
142
			$response->setContentSecurityPolicy($provider->getCSP());
143
		}
144
		return $response;
145
	}
146
147
	/**
148
	 * @NoAdminRequired
149
	 * @NoCSRFRequired
150
	 * @UseSession
151
	 *
152
	 * @UserRateThrottle(limit=5, period=100)
153
	 *
154
	 * @param string $challengeProviderId
155
	 * @param string $challenge
156
	 * @param string $redirect_url
157
	 * @return RedirectResponse
158
	 */
159
	public function solveChallenge($challengeProviderId, $challenge, $redirect_url = null) {
160
		$user = $this->userSession->getUser();
161
		$provider = $this->twoFactorManager->getProvider($user, $challengeProviderId);
0 ignored issues
show
Bug introduced by
It seems like $user defined by $this->userSession->getUser() on line 160 can be null; however, OC\Authentication\TwoFac...\Manager::getProvider() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
162
		if (is_null($provider)) {
163
			return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
164
		}
165
166
		try {
167
			if ($this->twoFactorManager->verifyChallenge($challengeProviderId, $user, $challenge)) {
0 ignored issues
show
Bug introduced by
It seems like $user defined by $this->userSession->getUser() on line 160 can be null; however, OC\Authentication\TwoFac...ager::verifyChallenge() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
168
				if (!is_null($redirect_url)) {
169
					return new RedirectResponse($this->urlGenerator->getAbsoluteURL(urldecode($redirect_url)));
170
				}
171
				return new RedirectResponse(OC_Util::getDefaultPageUrl());
172
			}
173
		} catch (TwoFactorException $e) {
174
			/*
175
			 * The 2FA App threw an TwoFactorException. Now we display more
176
			 * information to the user. The exception text is stored in the
177
			 * session to be used in showChallenge()
178
			 */
179
			$this->session->set('two_factor_auth_error_message', $e->getMessage());
180
		}
181
182
		$this->session->set('two_factor_auth_error', true);
183
		return new RedirectResponse($this->urlGenerator->linkToRoute('core.TwoFactorChallenge.showChallenge', [
184
			'challengeProviderId' => $provider->getId(),
185
			'redirect_url' => $redirect_url,
186
		]));
187
	}
188
189
}
190