Passed
Push — master ( 5cdc85...37718d )
by Morris
38:53 queued 21:57
created

OC_User::isIncognitoMode()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Aldo "xoen" Giambelluca <[email protected]>
6
 * @author Andreas Fischer <[email protected]>
7
 * @author Arthur Schiwon <[email protected]>
8
 * @author Bart Visscher <[email protected]>
9
 * @author Bartek Przybylski <[email protected]>
10
 * @author Björn Schießle <[email protected]>
11
 * @author Christoph Wurst <[email protected]>
12
 * @author Georg Ehrke <[email protected]>
13
 * @author Jakob Sack <[email protected]>
14
 * @author Jörn Friedrich Dreyer <[email protected]>
15
 * @author Lukas Reschke <[email protected]>
16
 * @author Morris Jobke <[email protected]>
17
 * @author Robin Appelman <[email protected]>
18
 * @author Robin McCorkell <[email protected]>
19
 * @author Roeland Jago Douma <[email protected]>
20
 * @author shkdee <[email protected]>
21
 * @author Thomas Müller <[email protected]>
22
 * @author Tom Needham <[email protected]>
23
 * @author Vincent Petry <[email protected]>
24
 *
25
 * @license AGPL-3.0
26
 *
27
 * This code is free software: you can redistribute it and/or modify
28
 * it under the terms of the GNU Affero General Public License, version 3,
29
 * as published by the Free Software Foundation.
30
 *
31
 * This program is distributed in the hope that it will be useful,
32
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
33
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34
 * GNU Affero General Public License for more details.
35
 *
36
 * You should have received a copy of the GNU Affero General Public License, version 3,
37
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
38
 *
39
 */
40
41
use OCP\ILogger;
42
43
/**
44
 * This class provides wrapper methods for user management. Multiple backends are
45
 * supported. User management operations are delegated to the configured backend for
46
 * execution.
47
 *
48
 * Note that &run is deprecated and won't work anymore.
49
 *
50
 * Hooks provided:
51
 *   pre_createUser(&run, uid, password)
52
 *   post_createUser(uid, password)
53
 *   pre_deleteUser(&run, uid)
54
 *   post_deleteUser(uid)
55
 *   pre_setPassword(&run, uid, password, recoveryPassword)
56
 *   post_setPassword(uid, password, recoveryPassword)
57
 *   pre_login(&run, uid, password)
58
 *   post_login(uid)
59
 *   logout()
60
 */
61
class OC_User {
62
63
	private static $_usedBackends = array();
64
65
	private static $_setupedBackends = array();
66
67
	// bool, stores if a user want to access a resource anonymously, e.g if they open a public link
68
	private static $incognitoMode = false;
69
70
	/**
71
	 * Adds the backend to the list of used backends
72
	 *
73
	 * @param string|\OCP\UserInterface $backend default: database The backend to use for user management
74
	 * @return bool
75
	 *
76
	 * Set the User Authentication Module
77
	 * @suppress PhanDeprecatedFunction
78
	 */
79
	public static function useBackend($backend = 'database') {
80
		if ($backend instanceof \OCP\UserInterface) {
81
			self::$_usedBackends[get_class($backend)] = $backend;
82
			\OC::$server->getUserManager()->registerBackend($backend);
83
		} else {
84
			// You'll never know what happens
85
			if (null === $backend OR !is_string($backend)) {
0 ignored issues
show
introduced by
The condition is_string($backend) is always true.
Loading history...
86
				$backend = 'database';
87
			}
88
89
			// Load backend
90
			switch ($backend) {
91
				case 'database':
92
				case 'mysql':
93
				case 'sqlite':
94
					\OCP\Util::writeLog('core', 'Adding user backend ' . $backend . '.', ILogger::DEBUG);
0 ignored issues
show
Deprecated Code introduced by
The function OCP\Util::writeLog() has been deprecated: 13.0.0 use log of \OCP\ILogger ( Ignorable by Annotation )

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

94
					/** @scrutinizer ignore-deprecated */ \OCP\Util::writeLog('core', 'Adding user backend ' . $backend . '.', ILogger::DEBUG);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
95
					self::$_usedBackends[$backend] = new \OC\User\Database();
96
					\OC::$server->getUserManager()->registerBackend(self::$_usedBackends[$backend]);
97
					break;
98
				case 'dummy':
99
					self::$_usedBackends[$backend] = new \Test\Util\User\Dummy();
0 ignored issues
show
Bug introduced by
The type Test\Util\User\Dummy was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
100
					\OC::$server->getUserManager()->registerBackend(self::$_usedBackends[$backend]);
101
					break;
102
				default:
103
					\OCP\Util::writeLog('core', 'Adding default user backend ' . $backend . '.', ILogger::DEBUG);
0 ignored issues
show
Deprecated Code introduced by
The function OCP\Util::writeLog() has been deprecated: 13.0.0 use log of \OCP\ILogger ( Ignorable by Annotation )

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

103
					/** @scrutinizer ignore-deprecated */ \OCP\Util::writeLog('core', 'Adding default user backend ' . $backend . '.', ILogger::DEBUG);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
104
					$className = 'OC_USER_' . strtoupper($backend);
105
					self::$_usedBackends[$backend] = new $className();
106
					\OC::$server->getUserManager()->registerBackend(self::$_usedBackends[$backend]);
107
					break;
108
			}
109
		}
110
		return true;
111
	}
112
113
	/**
114
	 * remove all used backends
115
	 */
116
	public static function clearBackends() {
117
		self::$_usedBackends = array();
118
		\OC::$server->getUserManager()->clearBackends();
119
	}
120
121
	/**
122
	 * setup the configured backends in config.php
123
	 * @suppress PhanDeprecatedFunction
124
	 */
125
	public static function setupBackends() {
126
		OC_App::loadApps(['prelogin']);
127
		$backends = \OC::$server->getSystemConfig()->getValue('user_backends', []);
128
		if (isset($backends['default']) && !$backends['default']) {
129
			// clear default backends
130
			self::clearBackends();
131
		}
132
		foreach ($backends as $i => $config) {
133
			if (!is_array($config)) {
134
				continue;
135
			}
136
			$class = $config['class'];
137
			$arguments = $config['arguments'];
138
			if (class_exists($class)) {
139
				if (array_search($i, self::$_setupedBackends) === false) {
140
					// make a reflection object
141
					$reflectionObj = new ReflectionClass($class);
142
143
					// use Reflection to create a new instance, using the $args
144
					$backend = $reflectionObj->newInstanceArgs($arguments);
145
					self::useBackend($backend);
146
					self::$_setupedBackends[] = $i;
147
				} else {
148
					\OCP\Util::writeLog('core', 'User backend ' . $class . ' already initialized.', ILogger::DEBUG);
0 ignored issues
show
Deprecated Code introduced by
The function OCP\Util::writeLog() has been deprecated: 13.0.0 use log of \OCP\ILogger ( Ignorable by Annotation )

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

148
					/** @scrutinizer ignore-deprecated */ \OCP\Util::writeLog('core', 'User backend ' . $class . ' already initialized.', ILogger::DEBUG);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
149
				}
150
			} else {
151
				\OCP\Util::writeLog('core', 'User backend ' . $class . ' not found.', ILogger::ERROR);
0 ignored issues
show
Deprecated Code introduced by
The function OCP\Util::writeLog() has been deprecated: 13.0.0 use log of \OCP\ILogger ( Ignorable by Annotation )

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

151
				/** @scrutinizer ignore-deprecated */ \OCP\Util::writeLog('core', 'User backend ' . $class . ' not found.', ILogger::ERROR);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
152
			}
153
		}
154
	}
155
156
	/**
157
	 * Try to login a user, assuming authentication
158
	 * has already happened (e.g. via Single Sign On).
159
	 *
160
	 * Log in a user and regenerate a new session.
161
	 *
162
	 * @param \OCP\Authentication\IApacheBackend $backend
163
	 * @return bool
164
	 */
165
	public static function loginWithApache(\OCP\Authentication\IApacheBackend $backend) {
166
167
		$uid = $backend->getCurrentUserId();
168
		$run = true;
169
		OC_Hook::emit("OC_User", "pre_login", array("run" => &$run, "uid" => $uid, 'backend' => $backend));
170
171
		if ($uid) {
172
			if (self::getUser() !== $uid) {
173
				self::setUserId($uid);
174
				$userSession = \OC::$server->getUserSession();
175
				$userSession->setLoginName($uid);
176
				$request = OC::$server->getRequest();
177
				$userSession->createSessionToken($request, $uid, $uid);
178
				// setup the filesystem
179
				OC_Util::setupFS($uid);
180
				// first call the post_login hooks, the login-process needs to be
181
				// completed before we can safely create the users folder.
182
				// For example encryption needs to initialize the users keys first
183
				// before we can create the user folder with the skeleton files
184
				OC_Hook::emit("OC_User", "post_login", array("uid" => $uid, 'password' => ''));
185
				//trigger creation of user home and /files folder
186
				\OC::$server->getUserFolder($uid);
187
			}
188
			return true;
189
		}
190
		return false;
191
	}
192
193
	/**
194
	 * Verify with Apache whether user is authenticated.
195
	 *
196
	 * @return boolean|null
197
	 *          true: authenticated
198
	 *          false: not authenticated
199
	 *          null: not handled / no backend available
200
	 */
201
	public static function handleApacheAuth() {
202
		$backend = self::findFirstActiveUsedBackend();
203
		if ($backend) {
204
			OC_App::loadApps();
205
206
			//setup extra user backends
207
			self::setupBackends();
208
			\OC::$server->getUserSession()->unsetMagicInCookie();
209
210
			return self::loginWithApache($backend);
211
		}
212
213
		return null;
214
	}
215
216
217
	/**
218
	 * Sets user id for session and triggers emit
219
	 *
220
	 * @param string $uid
221
	 */
222
	public static function setUserId($uid) {
223
		$userSession = \OC::$server->getUserSession();
224
		$userManager = \OC::$server->getUserManager();
225
		if ($user = $userManager->get($uid)) {
226
			$userSession->setUser($user);
227
		} else {
228
			\OC::$server->getSession()->set('user_id', $uid);
229
		}
230
	}
231
232
	/**
233
	 * Check if the user is logged in, considers also the HTTP basic credentials
234
	 *
235
	 * @deprecated use \OC::$server->getUserSession()->isLoggedIn()
236
	 * @return bool
237
	 */
238
	public static function isLoggedIn() {
239
		return \OC::$server->getUserSession()->isLoggedIn();
240
	}
241
242
	/**
243
	 * set incognito mode, e.g. if a user wants to open a public link
244
	 *
245
	 * @param bool $status
246
	 */
247
	public static function setIncognitoMode($status) {
248
		self::$incognitoMode = $status;
249
	}
250
251
	/**
252
	 * get incognito mode status
253
	 *
254
	 * @return bool
255
	 */
256
	public static function isIncognitoMode() {
257
		return self::$incognitoMode;
258
	}
259
260
	/**
261
	 * Returns the current logout URL valid for the currently logged-in user
262
	 *
263
	 * @param \OCP\IURLGenerator $urlGenerator
264
	 * @return string
265
	 */
266
	public static function getLogoutUrl(\OCP\IURLGenerator $urlGenerator) {
267
		$backend = self::findFirstActiveUsedBackend();
268
		if ($backend) {
269
			return $backend->getLogoutUrl();
270
		}
271
272
		$logoutUrl = $urlGenerator->linkToRouteAbsolute(
273
			'core.login.logout',
274
			[
275
				'requesttoken' => \OCP\Util::callRegister(),
276
			]
277
		);
278
279
		return $logoutUrl;
280
	}
281
282
	/**
283
	 * Check if the user is an admin user
284
	 *
285
	 * @param string $uid uid of the admin
286
	 * @return bool
287
	 */
288
	public static function isAdminUser($uid) {
289
		$group = \OC::$server->getGroupManager()->get('admin');
290
		$user = \OC::$server->getUserManager()->get($uid);
291
		if ($group && $user && $group->inGroup($user) && self::$incognitoMode === false) {
292
			return true;
293
		}
294
		return false;
295
	}
296
297
298
	/**
299
	 * get the user id of the user currently logged in.
300
	 *
301
	 * @return string|bool uid or false
302
	 */
303
	public static function getUser() {
304
		$uid = \OC::$server->getSession() ? \OC::$server->getSession()->get('user_id') : null;
305
		if (!is_null($uid) && self::$incognitoMode === false) {
306
			return $uid;
307
		} else {
308
			return false;
309
		}
310
	}
311
312
	/**
313
	 * get the display name of the user currently logged in.
314
	 *
315
	 * @param string $uid
316
	 * @return string|bool uid or false
317
	 * @deprecated 8.1.0 fetch \OCP\IUser (has getDisplayName()) by using method
318
	 *                   get() of \OCP\IUserManager - \OC::$server->getUserManager()
319
	 */
320
	public static function getDisplayName($uid = null) {
321
		if ($uid) {
322
			$user = \OC::$server->getUserManager()->get($uid);
323
			if ($user) {
324
				return $user->getDisplayName();
325
			} else {
326
				return $uid;
327
			}
328
		} else {
329
			$user = \OC::$server->getUserSession()->getUser();
330
			if ($user) {
0 ignored issues
show
introduced by
$user is of type OC\User\User, thus it always evaluated to true.
Loading history...
331
				return $user->getDisplayName();
332
			} else {
333
				return false;
334
			}
335
		}
336
	}
337
338
	/**
339
	 * Set password
340
	 *
341
	 * @param string $uid The username
342
	 * @param string $password The new password
343
	 * @param string $recoveryPassword for the encryption app to reset encryption keys
344
	 * @return bool
345
	 *
346
	 * Change the password of a user
347
	 */
348
	public static function setPassword($uid, $password, $recoveryPassword = null) {
349
		$user = \OC::$server->getUserManager()->get($uid);
350
		if ($user) {
351
			return $user->setPassword($password, $recoveryPassword);
352
		} else {
353
			return false;
354
		}
355
	}
356
357
	/**
358
	 * @param string $uid The username
359
	 * @return string
360
	 *
361
	 * returns the path to the users home directory
362
	 * @deprecated Use \OC::$server->getUserManager->getHome()
363
	 */
364
	public static function getHome($uid) {
365
		$user = \OC::$server->getUserManager()->get($uid);
366
		if ($user) {
367
			return $user->getHome();
368
		} else {
369
			return \OC::$server->getSystemConfig()->getValue('datadirectory', OC::$SERVERROOT . '/data') . '/' . $uid;
370
		}
371
	}
372
373
	/**
374
	 * Get a list of all users display name
375
	 *
376
	 * @param string $search
377
	 * @param int $limit
378
	 * @param int $offset
379
	 * @return array associative array with all display names (value) and corresponding uids (key)
380
	 *
381
	 * Get a list of all display names and user ids.
382
	 * @deprecated Use \OC::$server->getUserManager->searchDisplayName($search, $limit, $offset) instead.
383
	 */
384
	public static function getDisplayNames($search = '', $limit = null, $offset = null) {
385
		$displayNames = array();
386
		$users = \OC::$server->getUserManager()->searchDisplayName($search, $limit, $offset);
387
		foreach ($users as $user) {
388
			$displayNames[$user->getUID()] = $user->getDisplayName();
389
		}
390
		return $displayNames;
391
	}
392
393
	/**
394
	 * Returns the first active backend from self::$_usedBackends.
395
	 *
396
	 * @return OCP\Authentication\IApacheBackend|null if no backend active, otherwise OCP\Authentication\IApacheBackend
397
	 */
398
	private static function findFirstActiveUsedBackend() {
399
		foreach (self::$_usedBackends as $backend) {
400
			if ($backend instanceof OCP\Authentication\IApacheBackend) {
401
				if ($backend->isSessionActive()) {
402
					return $backend;
403
				}
404
			}
405
		}
406
407
		return null;
408
	}
409
}
410