2013-05-28 21:46:57 +00:00
< ? php
/**
2016-07-21 15:07:57 +00:00
* @ copyright Copyright ( c ) 2016 , ownCloud , Inc .
*
2016-05-26 17:56:05 +00:00
* @ author Arthur Schiwon < blizzz @ arthur - schiwon . de >
2015-03-26 10:44:34 +00:00
* @ author Bart Visscher < bartv @ thisnet . nl >
2016-05-26 17:56:05 +00:00
* @ author Björn Schießle < bjoern @ schiessle . org >
2020-03-31 08:49:10 +00:00
* @ author Christoph Wurst < christoph @ winzerhof - wurst . at >
2017-11-06 14:56:42 +00:00
* @ author Joas Schilling < coding @ schilljs . com >
2021-06-04 19:52:51 +00:00
* @ author John Molakvoæ < skjnldsv @ protonmail . com >
2016-03-01 16:25:15 +00:00
* @ author Jörn Friedrich Dreyer < jfd @ butonic . de >
2020-04-29 09:57:22 +00:00
* @ author Julius Härtl < jus @ bitgrid . net >
2019-12-03 18:57:53 +00:00
* @ author Leon Klingele < leon @ struktur . de >
2016-05-26 17:56:05 +00:00
* @ author Lukas Reschke < lukas @ statuscode . ch >
2015-03-26 10:44:34 +00:00
* @ author Morris Jobke < hey @ morrisjobke . de >
2016-07-21 16:13:36 +00:00
* @ author Robin Appelman < robin @ icewind . nl >
2019-12-03 18:57:53 +00:00
* @ author Roeland Jago Douma < roeland @ famdouma . nl >
2015-03-26 10:44:34 +00:00
* @ author Thomas Müller < thomas . mueller @ tmit . eu >
*
* @ license AGPL - 3.0
*
* This code is free software : you can redistribute it and / or modify
* it under the terms of the GNU Affero General Public License , version 3 ,
* as published by the Free Software Foundation .
*
* This program 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 , version 3 ,
2019-12-03 18:57:53 +00:00
* along with this program . If not , see < http :// www . gnu . org / licenses />
2015-03-26 10:44:34 +00:00
*
2013-05-28 21:46:57 +00:00
*/
namespace OC\User ;
2021-09-01 12:04:57 +00:00
use InvalidArgumentException ;
2017-05-15 11:30:52 +00:00
use OC\Accounts\AccountManager ;
2020-03-13 13:16:43 +00:00
use OC\Avatar\AvatarManager ;
2013-05-28 21:46:57 +00:00
use OC\Hooks\Emitter ;
2016-02-09 16:16:43 +00:00
use OC_Helper ;
2021-09-01 12:04:57 +00:00
use OCP\Accounts\IAccountManager ;
2023-08-29 22:30:52 +00:00
use OCP\Comments\ICommentsManager ;
2020-07-07 19:17:25 +00:00
use OCP\EventDispatcher\IEventDispatcher ;
use OCP\Group\Events\BeforeUserRemovedEvent ;
use OCP\Group\Events\UserRemovedEvent ;
2015-11-25 20:44:36 +00:00
use OCP\IAvatarManager ;
2019-11-22 19:52:10 +00:00
use OCP\IConfig ;
2024-09-10 20:50:16 +00:00
use OCP\IDBConnection ;
use OCP\IGroupManager ;
2015-11-25 20:44:36 +00:00
use OCP\IImage ;
2015-11-30 12:57:54 +00:00
use OCP\IURLGenerator ;
2014-07-09 13:32:33 +00:00
use OCP\IUser ;
2019-11-22 19:52:10 +00:00
use OCP\IUserBackend ;
2024-09-10 20:50:16 +00:00
use OCP\Notification\IManager as INotificationManager ;
2023-11-23 09:22:34 +00:00
use OCP\User\Backend\IGetHomeBackend ;
use OCP\User\Backend\IProvideAvatarBackend ;
use OCP\User\Backend\IProvideEnabledStateBackend ;
use OCP\User\Backend\ISetDisplayNameBackend ;
use OCP\User\Backend\ISetPasswordBackend ;
2023-07-25 19:45:07 +00:00
use OCP\User\Events\BeforePasswordUpdatedEvent ;
2020-11-23 22:59:50 +00:00
use OCP\User\Events\BeforeUserDeletedEvent ;
2023-07-25 19:45:07 +00:00
use OCP\User\Events\PasswordUpdatedEvent ;
use OCP\User\Events\UserChangedEvent ;
2020-11-23 22:59:50 +00:00
use OCP\User\Events\UserDeletedEvent ;
2020-09-17 13:06:50 +00:00
use OCP\User\GetQuotaEvent ;
2016-01-14 13:28:03 +00:00
use OCP\UserInterface ;
2024-09-10 20:50:16 +00:00
use Psr\Log\LoggerInterface ;
2023-05-02 06:59:46 +00:00
use function json_decode ;
use function json_encode ;
2013-05-28 21:46:57 +00:00
2014-07-09 13:32:33 +00:00
class User implements IUser {
2023-05-02 06:59:46 +00:00
private const CONFIG_KEY_MANAGERS = 'manager' ;
2024-09-10 20:50:16 +00:00
private IConfig $config ;
private IURLGenerator $urlGenerator ;
2021-09-01 12:04:57 +00:00
/** @var IAccountManager */
protected $accountManager ;
2013-05-28 21:46:57 +00:00
2021-03-04 13:49:58 +00:00
/** @var string|null */
2013-05-28 21:46:57 +00:00
private $displayName ;
2022-02-25 23:34:17 +00:00
/** @var bool|null */
2013-05-28 21:46:57 +00:00
private $enabled ;
2024-09-10 20:50:16 +00:00
/** @var Emitter|Manager|null */
2013-05-28 21:46:57 +00:00
private $emitter ;
2019-02-22 12:07:26 +00:00
/** @var string */
2013-12-11 15:22:26 +00:00
private $home ;
2022-02-25 23:34:17 +00:00
/** @var int|null */
2014-05-21 16:03:37 +00:00
private $lastLogin ;
2015-11-25 20:44:36 +00:00
/** @var IAvatarManager */
private $avatarManager ;
2024-09-10 20:50:16 +00:00
public function __construct (
private string $uid ,
private ? UserInterface $backend ,
private IEventDispatcher $dispatcher ,
$emitter = null ,
? IConfig $config = null ,
$urlGenerator = null ,
) {
2013-05-28 21:46:57 +00:00
$this -> emitter = $emitter ;
2024-09-10 20:50:16 +00:00
$this -> config = $config ? ? \OCP\Server :: get ( IConfig :: class );
$this -> urlGenerator = $urlGenerator ? ? \OCP\Server :: get ( IURLGenerator :: class );
2013-05-28 21:46:57 +00:00
}
/**
2013-06-03 11:33:56 +00:00
* get the user id
*
2013-05-28 21:46:57 +00:00
* @ return string
*/
public function getUID () {
return $this -> uid ;
}
/**
2015-12-02 13:25:07 +00:00
* get the display name for the user , if no specific display name is set it will fallback to the user id
2013-06-03 11:33:56 +00:00
*
2013-05-28 21:46:57 +00:00
* @ return string
*/
public function getDisplayName () {
2021-03-04 13:49:58 +00:00
if ( $this -> displayName === null ) {
2014-10-15 12:05:18 +00:00
$displayName = '' ;
2019-02-22 12:07:26 +00:00
if ( $this -> backend && $this -> backend -> implementsActions ( Backend :: GET_DISPLAYNAME )) {
2014-10-15 12:05:18 +00:00
// get display name and strip whitespace from the beginning and end of it
$backendDisplayName = $this -> backend -> getDisplayName ( $this -> uid );
if ( is_string ( $backendDisplayName )) {
$displayName = trim ( $backendDisplayName );
}
}
if ( ! empty ( $displayName )) {
$this -> displayName = $displayName ;
2014-02-21 21:53:31 +00:00
} else {
$this -> displayName = $this -> uid ;
}
}
2013-05-28 21:46:57 +00:00
return $this -> displayName ;
}
/**
2013-06-03 11:33:56 +00:00
* set the displayname for the user
*
2013-05-28 21:46:57 +00:00
* @ param string $displayName
* @ return bool
2022-08-19 20:02:57 +00:00
*
* @ since 25.0 . 0 Throw InvalidArgumentException
* @ throws \InvalidArgumentException
2013-05-28 21:46:57 +00:00
*/
public function setDisplayName ( $displayName ) {
2014-10-15 12:05:18 +00:00
$displayName = trim ( $displayName );
2019-03-06 12:07:41 +00:00
$oldDisplayName = $this -> getDisplayName ();
2019-03-06 12:10:18 +00:00
if ( $this -> backend -> implementsActions ( Backend :: SET_DISPLAYNAME ) && ! empty ( $displayName ) && $displayName !== $oldDisplayName ) {
2022-05-13 10:59:51 +00:00
/** @var ISetDisplayNameBackend $backend */
$backend = $this -> backend ;
$result = $backend -> setDisplayName ( $this -> uid , $displayName );
2016-01-18 20:01:16 +00:00
if ( $result ) {
$this -> displayName = $displayName ;
2019-03-06 12:07:41 +00:00
$this -> triggerChange ( 'displayName' , $displayName , $oldDisplayName );
2016-01-18 20:01:16 +00:00
}
2013-06-03 11:39:34 +00:00
return $result !== false ;
2013-05-28 21:46:57 +00:00
}
2019-04-11 07:49:21 +00:00
return false ;
2013-05-28 21:46:57 +00:00
}
2016-01-18 19:27:43 +00:00
/**
2021-09-01 12:04:57 +00:00
* @ inheritDoc
2016-01-18 19:27:43 +00:00
*/
public function setEMailAddress ( $mailAddress ) {
2021-09-01 12:04:57 +00:00
$this -> setSystemEMailAddress ( $mailAddress );
}
/**
* @ inheritDoc
*/
public function setSystemEMailAddress ( string $mailAddress ) : void {
$oldMailAddress = $this -> getSystemEMailAddress ();
if ( $mailAddress === '' ) {
$this -> config -> deleteUserValue ( $this -> uid , 'settings' , 'email' );
} else {
$this -> config -> setUserValue ( $this -> uid , 'settings' , 'email' , $mailAddress );
}
$primaryAddress = $this -> getPrimaryEMailAddress ();
if ( $primaryAddress === $mailAddress ) {
// on match no dedicated primary settings is necessary
$this -> setPrimaryEMailAddress ( '' );
}
2022-09-06 08:58:01 +00:00
if ( $oldMailAddress !== strtolower ( $mailAddress )) {
2017-06-01 09:23:46 +00:00
$this -> triggerChange ( 'eMailAddress' , $mailAddress , $oldMailAddress );
}
2016-01-18 19:27:43 +00:00
}
2021-09-01 12:04:57 +00:00
/**
* @ inheritDoc
*/
public function setPrimaryEMailAddress ( string $mailAddress ) : void {
if ( $mailAddress === '' ) {
$this -> config -> deleteUserValue ( $this -> uid , 'settings' , 'primary_email' );
return ;
}
$this -> ensureAccountManager ();
$account = $this -> accountManager -> getAccount ( $this );
$property = $account -> getPropertyCollection ( IAccountManager :: COLLECTION_EMAIL )
-> getPropertyByValue ( $mailAddress );
if ( $property === null || $property -> getLocallyVerified () !== IAccountManager :: VERIFIED ) {
throw new InvalidArgumentException ( 'Only verified emails can be set as primary' );
}
$this -> config -> setUserValue ( $this -> uid , 'settings' , 'primary_email' , $mailAddress );
}
private function ensureAccountManager () {
if ( ! $this -> accountManager instanceof IAccountManager ) {
$this -> accountManager = \OC :: $server -> get ( IAccountManager :: class );
}
}
2014-05-21 16:03:37 +00:00
/**
* returns the timestamp of the user ' s last login or 0 if the user did never
* login
*
* @ return int
*/
public function getLastLogin () {
2022-02-25 23:34:17 +00:00
if ( $this -> lastLogin === null ) {
$this -> lastLogin = ( int ) $this -> config -> getUserValue ( $this -> uid , 'login' , 'lastLogin' , 0 );
}
return ( int ) $this -> lastLogin ;
2014-05-21 16:03:37 +00:00
}
/**
* updates the timestamp of the most recent login of this user
*/
public function updateLastLoginTimestamp () {
2022-07-20 14:43:42 +00:00
$previousLogin = $this -> getLastLogin ();
$now = time ();
$firstTimeLogin = $previousLogin === 0 ;
if ( $now - $previousLogin > 60 ) {
$this -> lastLogin = time ();
$this -> config -> setUserValue (
$this -> uid , 'login' , 'lastLogin' , ( string ) $this -> lastLogin );
}
2016-09-23 15:21:07 +00:00
return $firstTimeLogin ;
2014-05-21 16:03:37 +00:00
}
2013-05-28 21:46:57 +00:00
/**
2013-06-03 11:33:56 +00:00
* Delete the user
*
2013-05-28 21:46:57 +00:00
* @ return bool
*/
public function delete () {
2024-09-10 20:50:16 +00:00
if ( $this -> backend === null ) {
\OCP\Server :: get ( LoggerInterface :: class ) -> error ( 'Cannot delete user: No backend set' );
return false ;
}
2013-05-28 21:46:57 +00:00
if ( $this -> emitter ) {
2020-11-23 22:59:50 +00:00
/** @deprecated 21.0.0 use BeforeUserDeletedEvent event with the IEventDispatcher instead */
2020-03-26 08:30:18 +00:00
$this -> emitter -> emit ( '\OC\User' , 'preDelete' , [ $this ]);
2013-05-28 21:46:57 +00:00
}
2020-11-23 22:59:50 +00:00
$this -> dispatcher -> dispatchTyped ( new BeforeUserDeletedEvent ( $this ));
2014-12-04 13:15:55 +00:00
2024-09-10 20:50:16 +00:00
// Set delete flag on the user - this is needed to ensure that the user data is removed if there happen any exception in the backend
// because we can not restore the user meaning we could not rollback to any stable state otherwise.
$this -> config -> setUserValue ( $this -> uid , 'core' , 'deleted' , 'true' );
// We also need to backup the home path as this can not be reconstructed later if the original backend uses custom home paths
2024-09-11 17:33:53 +00:00
$this -> config -> setUserValue ( $this -> uid , 'core' , 'deleted.home-path' , $this -> getHome ());
2016-09-28 11:59:50 +00:00
2024-09-10 20:50:16 +00:00
// Try to delete the user on the backend
$result = $this -> backend -> deleteUser ( $this -> uid );
if ( $result === false ) {
// The deletion was aborted or something else happened, we are in a defined state, so remove the delete flag
$this -> config -> deleteUserValue ( $this -> uid , 'core' , 'deleted' );
return false ;
}
2020-03-13 13:16:43 +00:00
2024-09-10 20:50:16 +00:00
// We have to delete the user from all groups
$groupManager = \OCP\Server :: get ( IGroupManager :: class );
foreach ( $groupManager -> getUserGroupIds ( $this ) as $groupId ) {
$group = $groupManager -> get ( $groupId );
if ( $group ) {
$this -> dispatcher -> dispatchTyped ( new BeforeUserRemovedEvent ( $group , $this ));
$group -> removeUser ( $this );
$this -> dispatcher -> dispatchTyped ( new UserRemovedEvent ( $group , $this ));
}
}
2014-12-04 13:15:55 +00:00
2024-09-10 20:50:16 +00:00
$commentsManager = \OCP\Server :: get ( ICommentsManager :: class );
$commentsManager -> deleteReferencesOfActor ( 'users' , $this -> uid );
$commentsManager -> deleteReadMarksFromUser ( $this );
$avatarManager = \OCP\Server :: get ( AvatarManager :: class );
$avatarManager -> deleteUserAvatar ( $this -> uid );
$notificationManager = \OCP\Server :: get ( INotificationManager :: class );
$notification = $notificationManager -> createNotification ();
$notification -> setUser ( $this -> uid );
$notificationManager -> markProcessed ( $notification );
$accountManager = \OCP\Server :: get ( AccountManager :: class );
$accountManager -> deleteUser ( $this );
$database = \OCP\Server :: get ( IDBConnection :: class );
try {
// We need to create a transaction to make sure we are in a defined state
// because if all user values are removed also the flag is gone, but if an exception happens (e.g. database lost connection on the set operation)
// exactly here we are in an undefined state as the data is still present but the user does not exist on the system anymore.
$database -> beginTransaction ();
// Remove all user settings
$this -> config -> deleteAllUserValues ( $this -> uid );
// But again set flag that this user is about to be deleted
$this -> config -> setUserValue ( $this -> uid , 'core' , 'deleted' , 'true' );
2024-09-11 17:33:53 +00:00
$this -> config -> setUserValue ( $this -> uid , 'core' , 'deleted.home-path' , $this -> getHome ());
2024-09-10 20:50:16 +00:00
// Commit the transaction so we are in a defined state: either the preferences are removed or an exception occurred but the delete flag is still present
$database -> commit ();
} catch ( \Throwable $e ) {
$database -> rollback ();
throw $e ;
}
2017-05-15 11:30:52 +00:00
2024-09-11 17:33:53 +00:00
if ( $this -> emitter !== null ) {
2024-09-10 20:50:16 +00:00
/** @deprecated 21.0.0 use UserDeletedEvent event with the IEventDispatcher instead */
$this -> emitter -> emit ( '\OC\User' , 'postDelete' , [ $this ]);
2013-05-28 21:46:57 +00:00
}
2024-09-10 20:50:16 +00:00
$this -> dispatcher -> dispatchTyped ( new UserDeletedEvent ( $this ));
// Finally we can unset the delete flag and all other states
$this -> config -> deleteAllUserValues ( $this -> uid );
return true ;
2013-05-28 21:46:57 +00:00
}
/**
2013-06-03 11:33:56 +00:00
* Set the password of the user
*
2013-05-28 21:46:57 +00:00
* @ param string $password
* @ param string $recoveryPassword for the encryption app to reset encryption keys
* @ return bool
*/
2014-07-24 10:50:39 +00:00
public function setPassword ( $password , $recoveryPassword = null ) {
2023-07-25 19:45:07 +00:00
$this -> dispatcher -> dispatchTyped ( new BeforePasswordUpdatedEvent ( $this , $password , $recoveryPassword ));
2013-06-06 11:30:18 +00:00
if ( $this -> emitter ) {
2020-03-26 08:30:18 +00:00
$this -> emitter -> emit ( '\OC\User' , 'preSetPassword' , [ $this , $password , $recoveryPassword ]);
2013-06-06 11:30:18 +00:00
}
2016-08-11 07:52:02 +00:00
if ( $this -> backend -> implementsActions ( Backend :: SET_PASSWORD )) {
2022-05-13 10:59:51 +00:00
/** @var ISetPasswordBackend $backend */
$backend = $this -> backend ;
$result = $backend -> setPassword ( $this -> uid , $password );
2022-05-05 09:21:20 +00:00
if ( $result !== false ) {
2023-07-25 19:45:07 +00:00
$this -> dispatcher -> dispatchTyped ( new PasswordUpdatedEvent ( $this , $password , $recoveryPassword ));
2022-05-05 09:21:20 +00:00
if ( $this -> emitter ) {
$this -> emitter -> emit ( '\OC\User' , 'postSetPassword' , [ $this , $password , $recoveryPassword ]);
}
2013-05-28 21:46:57 +00:00
}
2022-05-05 09:21:20 +00:00
2013-05-28 21:46:57 +00:00
return ! ( $result === false );
} else {
return false ;
}
}
/**
* get the users home folder to mount
*
* @ return string
*/
public function getHome () {
2013-12-11 15:22:26 +00:00
if ( ! $this -> home ) {
2022-05-13 10:59:51 +00:00
/** @psalm-suppress UndefinedInterfaceMethod Once we get rid of the legacy implementsActions, psalm won't complain anymore */
if (( $this -> backend instanceof IGetHomeBackend || $this -> backend -> implementsActions ( Backend :: GET_HOME )) && $home = $this -> backend -> getHome ( $this -> uid )) {
2013-12-11 15:22:26 +00:00
$this -> home = $home ;
2013-12-12 11:57:25 +00:00
} else {
2024-09-10 20:50:16 +00:00
$this -> home = $this -> config -> getSystemValueString ( 'datadirectory' , \OC :: $SERVERROOT . '/data' ) . '/' . $this -> uid ;
2013-12-11 15:22:26 +00:00
}
2013-05-28 21:46:57 +00:00
}
2013-12-11 15:22:26 +00:00
return $this -> home ;
2013-05-28 21:46:57 +00:00
}
Expose backend type via REST API
This change will expose the user backend via the REST API which is a pre-requisite for https://github.com/owncloud/core/issues/12620.
For example:
````json
[{"name":"9707A09E-CA9A-4ABE-A66A-3F632F16C409","displayname":"Document Conversion User Account","groups":[],"subadmin":[],"quota":"default","storageLocation":"\/Users\/lreschke\/Programming\/core\/data\/9707A09E-CA9A-4ABE-A66A-3F632F16C409","lastLogin":0,"backend":"OCA\\user_ldap\\USER_LDAP"},{"name":"ED86733E-745C-4E4D-90CB-278A9737DB3C","displayname":"Hacker","groups":[],"subadmin":[],"quota":"default","storageLocation":"\/Users\/lreschke\/Programming\/core\/data\/ED86733E-745C-4E4D-90CB-278A9737DB3C","lastLogin":0,"backend":"OCA\\user_ldap\\USER_LDAP"},{"name":"71CDF45B-E125-450D-983C-D9192F36EC88","displayname":"admin","groups":[],"subadmin":[],"quota":"default","storageLocation":"\/Users\/lreschke\/Programming\/core\/data\/71CDF45B-E125-450D-983C-D9192F36EC88","lastLogin":0,"backend":"OCA\\user_ldap\\USER_LDAP"},{"name":"admin","displayname":"admin","groups":["admin"],"subadmin":[],"quota":"default","storageLocation":"\/Users\/lreschke\/Programming\/core\/data\/admin","lastLogin":"1418057287","backend":"OC_User_Database"},{"name":"test","displayname":"test","groups":[],"subadmin":[],"quota":"default","storageLocation":"\/Users\/lreschke\/Programming\/core\/data\/test","lastLogin":0,"backend":"OC_User_Database"}]
```
2014-12-08 21:38:54 +00:00
/**
* Get the name of the backend class the user is connected with
*
* @ return string
*/
public function getBackendClassName () {
2020-04-10 12:19:56 +00:00
if ( $this -> backend instanceof IUserBackend ) {
2014-12-12 16:25:03 +00:00
return $this -> backend -> getBackendName ();
}
Expose backend type via REST API
This change will expose the user backend via the REST API which is a pre-requisite for https://github.com/owncloud/core/issues/12620.
For example:
````json
[{"name":"9707A09E-CA9A-4ABE-A66A-3F632F16C409","displayname":"Document Conversion User Account","groups":[],"subadmin":[],"quota":"default","storageLocation":"\/Users\/lreschke\/Programming\/core\/data\/9707A09E-CA9A-4ABE-A66A-3F632F16C409","lastLogin":0,"backend":"OCA\\user_ldap\\USER_LDAP"},{"name":"ED86733E-745C-4E4D-90CB-278A9737DB3C","displayname":"Hacker","groups":[],"subadmin":[],"quota":"default","storageLocation":"\/Users\/lreschke\/Programming\/core\/data\/ED86733E-745C-4E4D-90CB-278A9737DB3C","lastLogin":0,"backend":"OCA\\user_ldap\\USER_LDAP"},{"name":"71CDF45B-E125-450D-983C-D9192F36EC88","displayname":"admin","groups":[],"subadmin":[],"quota":"default","storageLocation":"\/Users\/lreschke\/Programming\/core\/data\/71CDF45B-E125-450D-983C-D9192F36EC88","lastLogin":0,"backend":"OCA\\user_ldap\\USER_LDAP"},{"name":"admin","displayname":"admin","groups":["admin"],"subadmin":[],"quota":"default","storageLocation":"\/Users\/lreschke\/Programming\/core\/data\/admin","lastLogin":"1418057287","backend":"OC_User_Database"},{"name":"test","displayname":"test","groups":[],"subadmin":[],"quota":"default","storageLocation":"\/Users\/lreschke\/Programming\/core\/data\/test","lastLogin":0,"backend":"OC_User_Database"}]
```
2014-12-08 21:38:54 +00:00
return get_class ( $this -> backend );
}
2022-05-13 10:59:51 +00:00
public function getBackend () : ? UserInterface {
2018-10-11 19:55:42 +00:00
return $this -> backend ;
}
2013-11-22 12:24:11 +00:00
/**
2022-05-13 10:59:51 +00:00
* Check if the backend allows the user to change his avatar on Personal page
2013-11-22 12:24:11 +00:00
*
* @ return bool
*/
public function canChangeAvatar () {
2022-05-13 10:59:51 +00:00
if ( $this -> backend instanceof IProvideAvatarBackend || $this -> backend -> implementsActions ( Backend :: PROVIDE_AVATAR )) {
/** @var IProvideAvatarBackend $backend */
$backend = $this -> backend ;
return $backend -> canChangeAvatar ( $this -> uid );
2013-11-22 12:24:11 +00:00
}
return true ;
}
2013-05-28 21:46:57 +00:00
/**
2013-06-03 11:33:56 +00:00
* check if the backend supports changing passwords
*
2013-05-28 21:46:57 +00:00
* @ return bool
*/
public function canChangePassword () {
2016-08-11 07:52:02 +00:00
return $this -> backend -> implementsActions ( Backend :: SET_PASSWORD );
2013-05-28 21:46:57 +00:00
}
/**
2013-06-03 11:33:56 +00:00
* check if the backend supports changing display names
*
2013-05-28 21:46:57 +00:00
* @ return bool
*/
public function canChangeDisplayName () {
2023-05-04 18:14:49 +00:00
if ( ! $this -> config -> getSystemValueBool ( 'allow_user_to_change_display_name' , true )) {
2013-12-16 13:22:25 +00:00
return false ;
}
2016-08-11 07:52:02 +00:00
return $this -> backend -> implementsActions ( Backend :: SET_DISPLAYNAME );
2013-05-28 21:46:57 +00:00
}
/**
2013-06-03 11:33:56 +00:00
* check if the user is enabled
*
2013-05-28 21:46:57 +00:00
* @ return bool
*/
public function isEnabled () {
2022-10-05 15:13:33 +00:00
$queryDatabaseValue = function () : bool {
if ( $this -> enabled === null ) {
$enabled = $this -> config -> getUserValue ( $this -> uid , 'core' , 'enabled' , 'true' );
$this -> enabled = $enabled === 'true' ;
}
2023-06-20 13:10:39 +00:00
return $this -> enabled ;
2022-10-05 15:13:33 +00:00
};
if ( $this -> backend instanceof IProvideEnabledStateBackend ) {
return $this -> backend -> isUserEnabled ( $this -> uid , $queryDatabaseValue );
} else {
return $queryDatabaseValue ();
2022-02-25 23:34:17 +00:00
}
2013-05-28 21:46:57 +00:00
}
/**
2013-06-03 11:33:56 +00:00
* set the enabled status for the user
*
2022-10-05 15:13:33 +00:00
* @ return void
2013-05-28 21:46:57 +00:00
*/
2018-04-06 18:19:52 +00:00
public function setEnabled ( bool $enabled = true ) {
2017-04-25 15:11:57 +00:00
$oldStatus = $this -> isEnabled ();
2022-10-05 15:13:33 +00:00
$setDatabaseValue = function ( bool $enabled ) : void {
2018-04-06 18:19:52 +00:00
$this -> config -> setUserValue ( $this -> uid , 'core' , 'enabled' , $enabled ? 'true' : 'false' );
2022-10-05 15:13:33 +00:00
$this -> enabled = $enabled ;
};
if ( $this -> backend instanceof IProvideEnabledStateBackend ) {
$queryDatabaseValue = function () : bool {
if ( $this -> enabled === null ) {
$enabled = $this -> config -> getUserValue ( $this -> uid , 'core' , 'enabled' , 'true' );
$this -> enabled = $enabled === 'true' ;
}
2023-06-20 13:10:39 +00:00
return $this -> enabled ;
2022-10-05 15:13:33 +00:00
};
2023-06-20 13:10:39 +00:00
$enabled = $this -> backend -> setUserEnabled ( $this -> uid , $enabled , $queryDatabaseValue , $setDatabaseValue );
2023-05-23 15:18:19 +00:00
if ( $oldStatus !== $enabled ) {
$this -> triggerChange ( 'enabled' , $enabled , $oldStatus );
}
} elseif ( $oldStatus !== $enabled ) {
2022-10-05 15:13:33 +00:00
$setDatabaseValue ( $enabled );
$this -> triggerChange ( 'enabled' , $enabled , $oldStatus );
2017-04-25 15:11:57 +00:00
}
2013-05-28 21:46:57 +00:00
}
2015-11-24 22:28:24 +00:00
/**
* get the users email address
*
* @ return string | null
* @ since 9.0 . 0
*/
public function getEMailAddress () {
2021-09-01 12:04:57 +00:00
return $this -> getPrimaryEMailAddress () ? ? $this -> getSystemEMailAddress ();
}
/**
* @ inheritDoc
*/
public function getSystemEMailAddress () : ? string {
2015-12-01 11:05:40 +00:00
return $this -> config -> getUserValue ( $this -> uid , 'settings' , 'email' , null );
2015-11-24 22:28:24 +00:00
}
2015-11-25 20:44:36 +00:00
2021-09-01 12:04:57 +00:00
/**
* @ inheritDoc
*/
public function getPrimaryEMailAddress () : ? string {
return $this -> config -> getUserValue ( $this -> uid , 'settings' , 'primary_email' , null );
}
2016-02-09 16:16:43 +00:00
/**
* get the users ' quota
*
* @ return string
* @ since 9.0 . 0
*/
public function getQuota () {
2020-09-17 13:06:50 +00:00
// allow apps to modify the user quota by hooking into the event
$event = new GetQuotaEvent ( $this );
$this -> dispatcher -> dispatchTyped ( $event );
$overwriteQuota = $event -> getQuota ();
if ( $overwriteQuota ) {
$quota = $overwriteQuota ;
} else {
$quota = $this -> config -> getUserValue ( $this -> uid , 'files' , 'quota' , 'default' );
}
2020-04-10 12:19:56 +00:00
if ( $quota === 'default' ) {
2016-02-09 16:16:43 +00:00
$quota = $this -> config -> getAppValue ( 'files' , 'default_quota' , 'none' );
2021-07-29 11:04:41 +00:00
// if unlimited quota is not allowed => avoid getting 'unlimited' as default_quota fallback value
// use the first preset instead
$allowUnlimitedQuota = $this -> config -> getAppValue ( 'files' , 'allow_unlimited_quota' , '1' ) === '1' ;
if ( ! $allowUnlimitedQuota ) {
$presets = $this -> config -> getAppValue ( 'files' , 'quota_preset' , '1 GB, 5 GB, 10 GB' );
$presets = array_filter ( array_map ( 'trim' , explode ( ',' , $presets )));
$quotaPreset = array_values ( array_diff ( $presets , [ 'default' , 'none' ]));
if ( count ( $quotaPreset ) > 0 ) {
$quota = $this -> config -> getAppValue ( 'files' , 'default_quota' , $quotaPreset [ 0 ]);
}
}
2016-02-09 16:16:43 +00:00
}
return $quota ;
}
/**
* set the users ' quota
*
* @ param string $quota
* @ return void
2023-01-23 11:24:53 +00:00
* @ throws InvalidArgumentException
2016-02-09 16:16:43 +00:00
* @ since 9.0 . 0
*/
public function setQuota ( $quota ) {
2017-06-01 09:23:46 +00:00
$oldQuota = $this -> config -> getUserValue ( $this -> uid , 'files' , 'quota' , '' );
2020-04-10 12:19:56 +00:00
if ( $quota !== 'none' and $quota !== 'default' ) {
2023-01-23 11:24:53 +00:00
$bytesQuota = OC_Helper :: computerFileSize ( $quota );
if ( $bytesQuota === false ) {
throw new InvalidArgumentException ( 'Failed to set quota to invalid value ' . $quota );
}
$quota = OC_Helper :: humanFileSize ( $bytesQuota );
2016-02-09 16:16:43 +00:00
}
2020-04-10 12:19:56 +00:00
if ( $quota !== $oldQuota ) {
2019-03-06 12:07:41 +00:00
$this -> config -> setUserValue ( $this -> uid , 'files' , 'quota' , $quota );
2019-04-11 07:49:21 +00:00
$this -> triggerChange ( 'quota' , $quota , $oldQuota );
2017-06-01 09:23:46 +00:00
}
2023-02-16 07:43:14 +00:00
\OC_Helper :: clearStorageInfo ( '/' . $this -> uid . '/files' );
2016-02-09 16:16:43 +00:00
}
2023-05-02 06:59:46 +00:00
public function getManagerUids () : array {
$encodedUids = $this -> config -> getUserValue (
$this -> uid ,
'settings' ,
self :: CONFIG_KEY_MANAGERS ,
'[]'
);
return json_decode ( $encodedUids , false , 512 , JSON_THROW_ON_ERROR );
}
public function setManagerUids ( array $uids ) : void {
$oldUids = $this -> getManagerUids ();
$this -> config -> setUserValue (
$this -> uid ,
'settings' ,
self :: CONFIG_KEY_MANAGERS ,
json_encode ( $uids , JSON_THROW_ON_ERROR )
);
$this -> triggerChange ( 'managers' , $uids , $oldUids );
}
2015-11-25 20:44:36 +00:00
/**
* get the avatar image if it exists
*
* @ param int $size
* @ return IImage | null
* @ since 9.0 . 0
*/
public function getAvatarImage ( $size ) {
2015-12-02 13:25:07 +00:00
// delay the initialization
if ( is_null ( $this -> avatarManager )) {
2023-08-29 22:33:36 +00:00
$this -> avatarManager = \OC :: $server -> get ( IAvatarManager :: class );
2015-12-02 13:25:07 +00:00
}
2015-11-25 20:44:36 +00:00
$avatar = $this -> avatarManager -> getAvatar ( $this -> uid );
2023-05-26 08:03:58 +00:00
$image = $avatar -> get ( $size );
2015-11-25 20:44:36 +00:00
if ( $image ) {
return $image ;
}
return null ;
}
2015-11-30 12:57:54 +00:00
/**
* get the federation cloud id
*
* @ return string
* @ since 9.0 . 0
*/
public function getCloudId () {
$uid = $this -> getUID ();
2022-09-01 12:32:14 +00:00
$server = rtrim ( $this -> urlGenerator -> getAbsoluteURL ( '/' ), '/' );
2023-07-07 01:24:20 +00:00
if ( str_ends_with ( $server , '/index.php' )) {
2022-08-31 19:33:09 +00:00
$server = substr ( $server , 0 , - 10 );
}
2022-09-01 12:32:14 +00:00
$server = $this -> removeProtocolFromUrl ( $server );
2021-07-13 10:39:56 +00:00
return $uid . '@' . $server ;
2015-11-30 12:57:54 +00:00
}
2022-06-08 08:38:20 +00:00
private function removeProtocolFromUrl ( string $url ) : string {
2023-05-15 11:47:19 +00:00
if ( str_starts_with ( $url , 'https://' )) {
2015-11-30 12:57:54 +00:00
return substr ( $url , strlen ( 'https://' ));
}
return $url ;
}
2016-01-18 19:27:43 +00:00
2017-04-13 10:34:02 +00:00
public function triggerChange ( $feature , $value = null , $oldValue = null ) {
2023-07-25 19:45:07 +00:00
$this -> dispatcher -> dispatchTyped ( new UserChangedEvent ( $this , $feature , $value , $oldValue ));
2016-01-22 10:34:49 +00:00
if ( $this -> emitter ) {
2020-03-26 08:30:18 +00:00
$this -> emitter -> emit ( '\OC\User' , 'changeUser' , [ $this , $feature , $value , $oldValue ]);
2016-01-22 10:34:49 +00:00
}
}
2013-05-28 21:46:57 +00:00
}