Completed
Pull Request — master (#1234)
by Blizzz
33:32 queued 09:32
created
settings/templates/users/part.grouplist.php 1 patch
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -28,33 +28,33 @@
 block discarded – undo
28 28
 	</li>
29 29
 
30 30
 	<!-- The Admin Group -->
31
-	<?php foreach($_["adminGroup"] as $adminGroup): ?>
32
-		<li data-gid="admin" data-usercount="<?php if($adminGroup['usercount'] > 0) { p($adminGroup['usercount']); } ?>" class="isgroup">
31
+	<?php foreach ($_["adminGroup"] as $adminGroup): ?>
32
+		<li data-gid="admin" data-usercount="<?php if ($adminGroup['usercount'] > 0) { p($adminGroup['usercount']); } ?>" class="isgroup">
33 33
 			<a href="#"><span class="groupname"><?php p($l->t('Admins')); ?></span></a>
34 34
 			<span class="utils">
35
-				<span class="usercount"><?php if($adminGroup['usercount'] > 0) { p($adminGroup['usercount']); } ?></span>
35
+				<span class="usercount"><?php if ($adminGroup['usercount'] > 0) { p($adminGroup['usercount']); } ?></span>
36 36
 			</span>
37 37
 		</li>
38 38
 	<?php endforeach; ?>
39 39
 
40 40
 	<!-- Disabled Users -->
41 41
 	<?php $disabledUsersGroup = $_["disabledUsersGroup"] ?>
42
-	<li data-gid="_disabledUsers" data-usercount="<?php if($disabledUsersGroup['usercount'] > 0) { p($disabledUsersGroup['usercount']); } ?>" class="isgroup">
42
+	<li data-gid="_disabledUsers" data-usercount="<?php if ($disabledUsersGroup['usercount'] > 0) { p($disabledUsersGroup['usercount']); } ?>" class="isgroup">
43 43
 		<a href="#"><span class="groupname"><?php p($l->t('Disabled')); ?></span></a>
44 44
 		<span class="utils">
45
-			<span class="usercount"><?php if($disabledUsersGroup['usercount'] > 0) { p($disabledUsersGroup['usercount']); } ?></span>
45
+			<span class="usercount"><?php if ($disabledUsersGroup['usercount'] > 0) { p($disabledUsersGroup['usercount']); } ?></span>
46 46
 		</span>
47 47
 	</li>
48 48
 
49 49
 	<!--List of Groups-->
50
-	<?php foreach($_["groups"] as $group): ?>
50
+	<?php foreach ($_["groups"] as $group): ?>
51 51
 		<li data-gid="<?php p($group['name']) ?>" data-usercount="<?php p($group['usercount']) ?>" class="isgroup">
52 52
 			<a href="#" class="dorename">
53 53
 				<span class="groupname"><?php p($group['name']); ?></span>
54 54
 			</a>
55 55
 			<span class="utils">
56
-				<span class="usercount"><?php if($group['usercount'] > 0) { p($group['usercount']); } ?></span>
57
-				<?php if($_['isAdmin']): ?>
56
+				<span class="usercount"><?php if ($group['usercount'] > 0) { p($group['usercount']); } ?></span>
57
+				<?php if ($_['isAdmin']): ?>
58 58
 				<a href="#" class="action delete" original-title="<?php p($l->t('Delete'))?>">
59 59
 					<img src="<?php print_unescaped(image_path('core', 'actions/delete.svg')) ?>" />
60 60
 				</a>
Please login to merge, or discard this patch.
settings/routes.php 1 patch
Indentation   +52 added lines, -52 removed lines patch added patch discarded remove patch
@@ -36,77 +36,77 @@
 block discarded – undo
36 36
 
37 37
 $application = new Application();
38 38
 $application->registerRoutes($this, [
39
-	'resources' => [
40
-		'users' => ['url' => '/settings/users/users'],
41
-		'AuthSettings' => ['url' => '/settings/personal/authtokens'],
42
-	],
43
-	'routes' => [
44
-		['name' => 'MailSettings#setMailSettings', 'url' => '/settings/admin/mailsettings', 'verb' => 'POST'],
45
-		['name' => 'MailSettings#storeCredentials', 'url' => '/settings/admin/mailsettings/credentials', 'verb' => 'POST'],
46
-		['name' => 'MailSettings#sendTestMail', 'url' => '/settings/admin/mailtest', 'verb' => 'POST'],
47
-		['name' => 'Encryption#startMigration', 'url' => '/settings/admin/startmigration', 'verb' => 'POST'],
48
-		['name' => 'AppSettings#listCategories', 'url' => '/settings/apps/categories', 'verb' => 'GET'],
49
-		['name' => 'AppSettings#viewApps', 'url' => '/settings/apps', 'verb' => 'GET'],
50
-		['name' => 'AppSettings#listApps', 'url' => '/settings/apps/list', 'verb' => 'GET'],
51
-		['name' => 'SecuritySettings#trustedDomains', 'url' => '/settings/admin/security/trustedDomains', 'verb' => 'POST'],
52
-		['name' => 'Users#setDisplayName', 'url' => '/settings/users/{username}/displayName', 'verb' => 'POST'],
53
-		['name' => 'Users#setEMailAddress', 'url' => '/settings/users/{id}/mailAddress', 'verb' => 'PUT'],
54
-		['name' => 'Users#setUserSettings', 'url' => '/settings/users/{username}/settings', 'verb' => 'PUT'],
55
-		['name' => 'Users#setEnabled', 'url' => '/settings/users/{id}/setEnabled', 'verb' => 'POST'],
56
-		['name' => 'Users#stats', 'url' => '/settings/users/stats', 'verb' => 'GET'],
57
-		['name' => 'LogSettings#setLogLevel', 'url' => '/settings/admin/log/level', 'verb' => 'POST'],
58
-		['name' => 'LogSettings#getEntries', 'url' => '/settings/admin/log/entries', 'verb' => 'GET'],
59
-		['name' => 'LogSettings#download', 'url' => '/settings/admin/log/download', 'verb' => 'GET'],
60
-		['name' => 'CheckSetup#check', 'url' => '/settings/ajax/checksetup', 'verb' => 'GET'],
61
-		['name' => 'CheckSetup#getFailedIntegrityCheckFiles', 'url' => '/settings/integrity/failed', 'verb' => 'GET'],
62
-		['name' => 'CheckSetup#rescanFailedIntegrityCheck', 'url' => '/settings/integrity/rescan', 'verb' => 'GET'],
63
-		['name' => 'Certificate#addPersonalRootCertificate', 'url' => '/settings/personal/certificate', 'verb' => 'POST'],
64
-		['name' => 'Certificate#removePersonalRootCertificate', 'url' => '/settings/personal/certificate/{certificateIdentifier}', 'verb' => 'DELETE'],
65
-		['name' => 'Certificate#addSystemRootCertificate', 'url' => '/settings/admin/certificate', 'verb' => 'POST'],
66
-		['name' => 'Certificate#removeSystemRootCertificate', 'url' => '/settings/admin/certificate/{certificateIdentifier}', 'verb' => 'DELETE'],
67
-		['name' => 'AdminSettings#index', 'url' => '/settings/admin/{section}', 'verb' => 'GET', 'defaults' => ['section' => 'server']],
68
-		['name' => 'AdminSettings#form', 'url' => '/settings/admin/{section}', 'verb' => 'GET'],
69
-		['name' => 'ChangePassword#changePersonalPassword', 'url' => '/settings/personal/changepassword', 'verb' => 'POST'],
70
-		['name' => 'ChangePassword#changeUserPassword', 'url' => '/settings/users/changepassword', 'verb' => 'POST'],
71
-		['name' => 'Personal#setLanguage', 'url' => '/settings/ajax/setlanguage.php', 'verb' => 'POST'],
72
-		['name' => 'Groups#index', 'url' => '/settings/users/groups', 'verb' => 'GET'],
73
-		['name' => 'Groups#show', 'url' => '/settings/users/groups/{id}', 'requirements' => ['id' => '[^?]*'], 'verb' => 'GET'],
74
-		['name' => 'Groups#create', 'url' => '/settings/users/groups', 'verb' => 'POST'],
75
-		['name' => 'Groups#update', 'url' => '/settings/users/groups/{id}', 'requirements' => ['id' => '[^?]*'], 'verb' => 'PUT'],
76
-		['name' => 'Groups#destroy', 'url' => '/settings/users/groups/{id}', 'requirements' => ['id' => '[^?]*'], 'verb' => 'DELETE'],
77
-	]
39
+    'resources' => [
40
+        'users' => ['url' => '/settings/users/users'],
41
+        'AuthSettings' => ['url' => '/settings/personal/authtokens'],
42
+    ],
43
+    'routes' => [
44
+        ['name' => 'MailSettings#setMailSettings', 'url' => '/settings/admin/mailsettings', 'verb' => 'POST'],
45
+        ['name' => 'MailSettings#storeCredentials', 'url' => '/settings/admin/mailsettings/credentials', 'verb' => 'POST'],
46
+        ['name' => 'MailSettings#sendTestMail', 'url' => '/settings/admin/mailtest', 'verb' => 'POST'],
47
+        ['name' => 'Encryption#startMigration', 'url' => '/settings/admin/startmigration', 'verb' => 'POST'],
48
+        ['name' => 'AppSettings#listCategories', 'url' => '/settings/apps/categories', 'verb' => 'GET'],
49
+        ['name' => 'AppSettings#viewApps', 'url' => '/settings/apps', 'verb' => 'GET'],
50
+        ['name' => 'AppSettings#listApps', 'url' => '/settings/apps/list', 'verb' => 'GET'],
51
+        ['name' => 'SecuritySettings#trustedDomains', 'url' => '/settings/admin/security/trustedDomains', 'verb' => 'POST'],
52
+        ['name' => 'Users#setDisplayName', 'url' => '/settings/users/{username}/displayName', 'verb' => 'POST'],
53
+        ['name' => 'Users#setEMailAddress', 'url' => '/settings/users/{id}/mailAddress', 'verb' => 'PUT'],
54
+        ['name' => 'Users#setUserSettings', 'url' => '/settings/users/{username}/settings', 'verb' => 'PUT'],
55
+        ['name' => 'Users#setEnabled', 'url' => '/settings/users/{id}/setEnabled', 'verb' => 'POST'],
56
+        ['name' => 'Users#stats', 'url' => '/settings/users/stats', 'verb' => 'GET'],
57
+        ['name' => 'LogSettings#setLogLevel', 'url' => '/settings/admin/log/level', 'verb' => 'POST'],
58
+        ['name' => 'LogSettings#getEntries', 'url' => '/settings/admin/log/entries', 'verb' => 'GET'],
59
+        ['name' => 'LogSettings#download', 'url' => '/settings/admin/log/download', 'verb' => 'GET'],
60
+        ['name' => 'CheckSetup#check', 'url' => '/settings/ajax/checksetup', 'verb' => 'GET'],
61
+        ['name' => 'CheckSetup#getFailedIntegrityCheckFiles', 'url' => '/settings/integrity/failed', 'verb' => 'GET'],
62
+        ['name' => 'CheckSetup#rescanFailedIntegrityCheck', 'url' => '/settings/integrity/rescan', 'verb' => 'GET'],
63
+        ['name' => 'Certificate#addPersonalRootCertificate', 'url' => '/settings/personal/certificate', 'verb' => 'POST'],
64
+        ['name' => 'Certificate#removePersonalRootCertificate', 'url' => '/settings/personal/certificate/{certificateIdentifier}', 'verb' => 'DELETE'],
65
+        ['name' => 'Certificate#addSystemRootCertificate', 'url' => '/settings/admin/certificate', 'verb' => 'POST'],
66
+        ['name' => 'Certificate#removeSystemRootCertificate', 'url' => '/settings/admin/certificate/{certificateIdentifier}', 'verb' => 'DELETE'],
67
+        ['name' => 'AdminSettings#index', 'url' => '/settings/admin/{section}', 'verb' => 'GET', 'defaults' => ['section' => 'server']],
68
+        ['name' => 'AdminSettings#form', 'url' => '/settings/admin/{section}', 'verb' => 'GET'],
69
+        ['name' => 'ChangePassword#changePersonalPassword', 'url' => '/settings/personal/changepassword', 'verb' => 'POST'],
70
+        ['name' => 'ChangePassword#changeUserPassword', 'url' => '/settings/users/changepassword', 'verb' => 'POST'],
71
+        ['name' => 'Personal#setLanguage', 'url' => '/settings/ajax/setlanguage.php', 'verb' => 'POST'],
72
+        ['name' => 'Groups#index', 'url' => '/settings/users/groups', 'verb' => 'GET'],
73
+        ['name' => 'Groups#show', 'url' => '/settings/users/groups/{id}', 'requirements' => ['id' => '[^?]*'], 'verb' => 'GET'],
74
+        ['name' => 'Groups#create', 'url' => '/settings/users/groups', 'verb' => 'POST'],
75
+        ['name' => 'Groups#update', 'url' => '/settings/users/groups/{id}', 'requirements' => ['id' => '[^?]*'], 'verb' => 'PUT'],
76
+        ['name' => 'Groups#destroy', 'url' => '/settings/users/groups/{id}', 'requirements' => ['id' => '[^?]*'], 'verb' => 'DELETE'],
77
+    ]
78 78
 ]);
79 79
 
80 80
 /** @var $this \OCP\Route\IRouter */
81 81
 
82 82
 // Settings pages
83 83
 $this->create('settings_help', '/settings/help')
84
-	->actionInclude('settings/help.php');
84
+    ->actionInclude('settings/help.php');
85 85
 $this->create('settings_personal', '/settings/personal')
86
-	->actionInclude('settings/personal.php');
86
+    ->actionInclude('settings/personal.php');
87 87
 $this->create('settings_users', '/settings/users')
88
-	->actionInclude('settings/users.php');
88
+    ->actionInclude('settings/users.php');
89 89
 // Settings ajax actions
90 90
 // users
91 91
 $this->create('settings_ajax_setquota', '/settings/ajax/setquota.php')
92
-	->actionInclude('settings/ajax/setquota.php');
92
+    ->actionInclude('settings/ajax/setquota.php');
93 93
 $this->create('settings_ajax_togglegroups', '/settings/ajax/togglegroups.php')
94
-	->actionInclude('settings/ajax/togglegroups.php');
94
+    ->actionInclude('settings/ajax/togglegroups.php');
95 95
 $this->create('settings_ajax_togglesubadmins', '/settings/ajax/togglesubadmins.php')
96
-	->actionInclude('settings/ajax/togglesubadmins.php');
96
+    ->actionInclude('settings/ajax/togglesubadmins.php');
97 97
 $this->create('settings_ajax_changegorupname', '/settings/ajax/changegroupname.php')
98
-	->actionInclude('settings/ajax/changegroupname.php');
98
+    ->actionInclude('settings/ajax/changegroupname.php');
99 99
 // apps
100 100
 $this->create('settings_ajax_enableapp', '/settings/ajax/enableapp.php')
101
-	->actionInclude('settings/ajax/enableapp.php');
101
+    ->actionInclude('settings/ajax/enableapp.php');
102 102
 $this->create('settings_ajax_disableapp', '/settings/ajax/disableapp.php')
103
-	->actionInclude('settings/ajax/disableapp.php');
103
+    ->actionInclude('settings/ajax/disableapp.php');
104 104
 $this->create('settings_ajax_updateapp', '/settings/ajax/updateapp.php')
105
-	->actionInclude('settings/ajax/updateapp.php');
105
+    ->actionInclude('settings/ajax/updateapp.php');
106 106
 $this->create('settings_ajax_uninstallapp', '/settings/ajax/uninstallapp.php')
107
-	->actionInclude('settings/ajax/uninstallapp.php');
107
+    ->actionInclude('settings/ajax/uninstallapp.php');
108 108
 $this->create('settings_ajax_navigationdetect', '/settings/ajax/navigationdetect.php')
109
-	->actionInclude('settings/ajax/navigationdetect.php');
109
+    ->actionInclude('settings/ajax/navigationdetect.php');
110 110
 // admin
111 111
 $this->create('settings_ajax_excludegroups', '/settings/ajax/excludegroups.php')
112
-	->actionInclude('settings/ajax/excludegroups.php');
112
+    ->actionInclude('settings/ajax/excludegroups.php');
Please login to merge, or discard this patch.
lib/public/IUserManager.php 1 patch
Indentation   +131 added lines, -131 removed lines patch added patch discarded remove patch
@@ -41,135 +41,135 @@
 block discarded – undo
41 41
  * @since 8.0.0
42 42
  */
43 43
 interface IUserManager {
44
-		/**
45
-	 * register a user backend
46
-	 *
47
-	 * @param \OCP\UserInterface $backend
48
-	 * @since 8.0.0
49
-	 */
50
-	public function registerBackend($backend);
51
-
52
-	/**
53
-	 * Get the active backends
54
-	 * @return \OCP\UserInterface[]
55
-	 * @since 8.0.0
56
-	 */
57
-	public function getBackends();
58
-
59
-	/**
60
-	 * remove a user backend
61
-	 *
62
-	 * @param \OCP\UserInterface $backend
63
-	 * @since 8.0.0
64
-	 */
65
-	public function removeBackend($backend);
66
-
67
-	/**
68
-	 * remove all user backends
69
-	 * @since 8.0.0
70
-	 */
71
-	public function clearBackends() ;
72
-
73
-	/**
74
-	 * get a user by user id
75
-	 *
76
-	 * @param string $uid
77
-	 * @return \OCP\IUser|null Either the user or null if the specified user does not exist
78
-	 * @since 8.0.0
79
-	 */
80
-	public function get($uid);
81
-
82
-	/**
83
-	 * check if a user exists
84
-	 *
85
-	 * @param string $uid
86
-	 * @return bool
87
-	 * @since 8.0.0
88
-	 */
89
-	public function userExists($uid);
90
-
91
-	/**
92
-	 * Check if the password is valid for the user
93
-	 *
94
-	 * @param string $loginName
95
-	 * @param string $password
96
-	 * @return mixed the User object on success, false otherwise
97
-	 * @since 8.0.0
98
-	 */
99
-	public function checkPassword($loginName, $password);
100
-
101
-	/**
102
-	 * search by user id
103
-	 *
104
-	 * @param string $pattern
105
-	 * @param int $limit
106
-	 * @param int $offset
107
-	 * @return \OCP\IUser[]
108
-	 * @since 8.0.0
109
-	 */
110
-	public function search($pattern, $limit = null, $offset = null);
111
-
112
-	/**
113
-	 * search by displayName
114
-	 *
115
-	 * @param string $pattern
116
-	 * @param int $limit
117
-	 * @param int $offset
118
-	 * @return \OCP\IUser[]
119
-	 * @since 8.0.0
120
-	 */
121
-	public function searchDisplayName($pattern, $limit = null, $offset = null);
122
-
123
-	/**
124
-	 * @param string $uid
125
-	 * @param string $password
126
-	 * @throws \Exception
127
-	 * @return bool|\OCP\IUser the created user of false
128
-	 * @since 8.0.0
129
-	 */
130
-	public function createUser($uid, $password);
131
-
132
-	/**
133
-	 * returns how many users per backend exist (if supported by backend)
134
-	 *
135
-	 * @return array an array of backend class as key and count number as value
136
-	 * @since 8.0.0
137
-	 */
138
-	public function countUsers();
139
-
140
-	/**
141
-	 * @param \Closure $callback
142
-	 * @param string $search
143
-	 * @since 9.0.0
144
-	 */
145
-	public function callForAllUsers(\Closure $callback, $search = '');
146
-
147
-	/**
148
-	 * returns how many users have logged in once
149
-	 *
150
-	 * @return int
151
-	 * @since 11.0.0
152
-	 */
153
-	public function countDisabledUsers();
154
-
155
-	/**
156
-	 * returns how many users have logged in once
157
-	 *
158
-	 * @return int
159
-	 * @since 11.0.0
160
-	 */
161
-	public function countSeenUsers();
162
-
163
-	/**
164
-	 * @param \Closure $callback
165
-	 * @since 11.0.0
166
-	 */
167
-	public function callForSeenUsers(\Closure $callback);
168
-
169
-	/**
170
-	 * @param string $email
171
-	 * @return IUser[]
172
-	 * @since 9.1.0
173
-	 */
174
-	public function getByEmail($email);
44
+        /**
45
+         * register a user backend
46
+         *
47
+         * @param \OCP\UserInterface $backend
48
+         * @since 8.0.0
49
+         */
50
+    public function registerBackend($backend);
51
+
52
+    /**
53
+     * Get the active backends
54
+     * @return \OCP\UserInterface[]
55
+     * @since 8.0.0
56
+     */
57
+    public function getBackends();
58
+
59
+    /**
60
+     * remove a user backend
61
+     *
62
+     * @param \OCP\UserInterface $backend
63
+     * @since 8.0.0
64
+     */
65
+    public function removeBackend($backend);
66
+
67
+    /**
68
+     * remove all user backends
69
+     * @since 8.0.0
70
+     */
71
+    public function clearBackends() ;
72
+
73
+    /**
74
+     * get a user by user id
75
+     *
76
+     * @param string $uid
77
+     * @return \OCP\IUser|null Either the user or null if the specified user does not exist
78
+     * @since 8.0.0
79
+     */
80
+    public function get($uid);
81
+
82
+    /**
83
+     * check if a user exists
84
+     *
85
+     * @param string $uid
86
+     * @return bool
87
+     * @since 8.0.0
88
+     */
89
+    public function userExists($uid);
90
+
91
+    /**
92
+     * Check if the password is valid for the user
93
+     *
94
+     * @param string $loginName
95
+     * @param string $password
96
+     * @return mixed the User object on success, false otherwise
97
+     * @since 8.0.0
98
+     */
99
+    public function checkPassword($loginName, $password);
100
+
101
+    /**
102
+     * search by user id
103
+     *
104
+     * @param string $pattern
105
+     * @param int $limit
106
+     * @param int $offset
107
+     * @return \OCP\IUser[]
108
+     * @since 8.0.0
109
+     */
110
+    public function search($pattern, $limit = null, $offset = null);
111
+
112
+    /**
113
+     * search by displayName
114
+     *
115
+     * @param string $pattern
116
+     * @param int $limit
117
+     * @param int $offset
118
+     * @return \OCP\IUser[]
119
+     * @since 8.0.0
120
+     */
121
+    public function searchDisplayName($pattern, $limit = null, $offset = null);
122
+
123
+    /**
124
+     * @param string $uid
125
+     * @param string $password
126
+     * @throws \Exception
127
+     * @return bool|\OCP\IUser the created user of false
128
+     * @since 8.0.0
129
+     */
130
+    public function createUser($uid, $password);
131
+
132
+    /**
133
+     * returns how many users per backend exist (if supported by backend)
134
+     *
135
+     * @return array an array of backend class as key and count number as value
136
+     * @since 8.0.0
137
+     */
138
+    public function countUsers();
139
+
140
+    /**
141
+     * @param \Closure $callback
142
+     * @param string $search
143
+     * @since 9.0.0
144
+     */
145
+    public function callForAllUsers(\Closure $callback, $search = '');
146
+
147
+    /**
148
+     * returns how many users have logged in once
149
+     *
150
+     * @return int
151
+     * @since 11.0.0
152
+     */
153
+    public function countDisabledUsers();
154
+
155
+    /**
156
+     * returns how many users have logged in once
157
+     *
158
+     * @return int
159
+     * @since 11.0.0
160
+     */
161
+    public function countSeenUsers();
162
+
163
+    /**
164
+     * @param \Closure $callback
165
+     * @since 11.0.0
166
+     */
167
+    public function callForSeenUsers(\Closure $callback);
168
+
169
+    /**
170
+     * @param string $email
171
+     * @return IUser[]
172
+     * @since 9.1.0
173
+     */
174
+    public function getByEmail($email);
175 175
 }
Please login to merge, or discard this patch.
lib/private/User/Manager.php 2 patches
Indentation   +458 added lines, -458 removed lines patch added patch discarded remove patch
@@ -54,462 +54,462 @@
 block discarded – undo
54 54
  * @package OC\User
55 55
  */
56 56
 class Manager extends PublicEmitter implements IUserManager {
57
-	/**
58
-	 * @var \OCP\UserInterface[] $backends
59
-	 */
60
-	private $backends = array();
61
-
62
-	/**
63
-	 * @var \OC\User\User[] $cachedUsers
64
-	 */
65
-	private $cachedUsers = array();
66
-
67
-	/**
68
-	 * @var \OCP\IConfig $config
69
-	 */
70
-	private $config;
71
-
72
-	/**
73
-	 * @param \OCP\IConfig $config
74
-	 */
75
-	public function __construct(IConfig $config) {
76
-		$this->config = $config;
77
-		$cachedUsers = &$this->cachedUsers;
78
-		$this->listen('\OC\User', 'postDelete', function ($user) use (&$cachedUsers) {
79
-			/** @var \OC\User\User $user */
80
-			unset($cachedUsers[$user->getUID()]);
81
-		});
82
-	}
83
-
84
-	/**
85
-	 * Get the active backends
86
-	 * @return \OCP\UserInterface[]
87
-	 */
88
-	public function getBackends() {
89
-		return $this->backends;
90
-	}
91
-
92
-	/**
93
-	 * register a user backend
94
-	 *
95
-	 * @param \OCP\UserInterface $backend
96
-	 */
97
-	public function registerBackend($backend) {
98
-		$this->backends[] = $backend;
99
-	}
100
-
101
-	/**
102
-	 * remove a user backend
103
-	 *
104
-	 * @param \OCP\UserInterface $backend
105
-	 */
106
-	public function removeBackend($backend) {
107
-		$this->cachedUsers = array();
108
-		if (($i = array_search($backend, $this->backends)) !== false) {
109
-			unset($this->backends[$i]);
110
-		}
111
-	}
112
-
113
-	/**
114
-	 * remove all user backends
115
-	 */
116
-	public function clearBackends() {
117
-		$this->cachedUsers = array();
118
-		$this->backends = array();
119
-	}
120
-
121
-	/**
122
-	 * get a user by user id
123
-	 *
124
-	 * @param string $uid
125
-	 * @return \OC\User\User|null Either the user or null if the specified user does not exist
126
-	 */
127
-	public function get($uid) {
128
-		if (isset($this->cachedUsers[$uid])) { //check the cache first to prevent having to loop over the backends
129
-			return $this->cachedUsers[$uid];
130
-		}
131
-		foreach ($this->backends as $backend) {
132
-			if ($backend->userExists($uid)) {
133
-				return $this->getUserObject($uid, $backend);
134
-			}
135
-		}
136
-		return null;
137
-	}
138
-
139
-	/**
140
-	 * get or construct the user object
141
-	 *
142
-	 * @param string $uid
143
-	 * @param \OCP\UserInterface $backend
144
-	 * @param bool $cacheUser If false the newly created user object will not be cached
145
-	 * @return \OC\User\User
146
-	 */
147
-	protected function getUserObject($uid, $backend, $cacheUser = true) {
148
-		if (isset($this->cachedUsers[$uid])) {
149
-			return $this->cachedUsers[$uid];
150
-		}
151
-
152
-		if (method_exists($backend, 'loginName2UserName')) {
153
-			$loginName = $backend->loginName2UserName($uid);
154
-			if ($loginName !== false) {
155
-				$uid = $loginName;
156
-			}
157
-			if (isset($this->cachedUsers[$uid])) {
158
-				return $this->cachedUsers[$uid];
159
-			}
160
-		}
161
-
162
-		$user = new User($uid, $backend, $this, $this->config);
163
-		if ($cacheUser) {
164
-			$this->cachedUsers[$uid] = $user;
165
-		}
166
-		return $user;
167
-	}
168
-
169
-	/**
170
-	 * check if a user exists
171
-	 *
172
-	 * @param string $uid
173
-	 * @return bool
174
-	 */
175
-	public function userExists($uid) {
176
-		$user = $this->get($uid);
177
-		return ($user !== null);
178
-	}
179
-
180
-	/**
181
-	 * Check if the password is valid for the user
182
-	 *
183
-	 * @param string $loginName
184
-	 * @param string $password
185
-	 * @return mixed the User object on success, false otherwise
186
-	 */
187
-	public function checkPassword($loginName, $password) {
188
-		$result = $this->checkPasswordNoLogging($loginName, $password);
189
-
190
-		if ($result === false) {
191
-			\OC::$server->getLogger()->warning('Login failed: \''. $loginName .'\' (Remote IP: \''. \OC::$server->getRequest()->getRemoteAddress(). '\')', ['app' => 'core']);
192
-		}
193
-
194
-		return $result;
195
-	}
196
-
197
-	/**
198
-	 * Check if the password is valid for the user
199
-	 *
200
-	 * @internal
201
-	 * @param string $loginName
202
-	 * @param string $password
203
-	 * @return mixed the User object on success, false otherwise
204
-	 */
205
-	public function checkPasswordNoLogging($loginName, $password) {
206
-		$loginName = str_replace("\0", '', $loginName);
207
-		$password = str_replace("\0", '', $password);
208
-
209
-		foreach ($this->backends as $backend) {
210
-			if ($backend->implementsActions(Backend::CHECK_PASSWORD)) {
211
-				$uid = $backend->checkPassword($loginName, $password);
212
-				if ($uid !== false) {
213
-					return $this->getUserObject($uid, $backend);
214
-				}
215
-			}
216
-		}
217
-
218
-		return false;
219
-	}
220
-
221
-	/**
222
-	 * search by user id
223
-	 *
224
-	 * @param string $pattern
225
-	 * @param int $limit
226
-	 * @param int $offset
227
-	 * @return \OC\User\User[]
228
-	 */
229
-	public function search($pattern, $limit = null, $offset = null) {
230
-		$users = array();
231
-		foreach ($this->backends as $backend) {
232
-			$backendUsers = $backend->getUsers($pattern, $limit, $offset);
233
-			if (is_array($backendUsers)) {
234
-				foreach ($backendUsers as $uid) {
235
-					$users[$uid] = $this->getUserObject($uid, $backend);
236
-				}
237
-			}
238
-		}
239
-
240
-		uasort($users, function ($a, $b) {
241
-			/**
242
-			 * @var \OC\User\User $a
243
-			 * @var \OC\User\User $b
244
-			 */
245
-			return strcmp($a->getUID(), $b->getUID());
246
-		});
247
-		return $users;
248
-	}
249
-
250
-	/**
251
-	 * search by displayName
252
-	 *
253
-	 * @param string $pattern
254
-	 * @param int $limit
255
-	 * @param int $offset
256
-	 * @return \OC\User\User[]
257
-	 */
258
-	public function searchDisplayName($pattern, $limit = null, $offset = null) {
259
-		$users = array();
260
-		foreach ($this->backends as $backend) {
261
-			$backendUsers = $backend->getDisplayNames($pattern, $limit, $offset);
262
-			if (is_array($backendUsers)) {
263
-				foreach ($backendUsers as $uid => $displayName) {
264
-					$users[] = $this->getUserObject($uid, $backend);
265
-				}
266
-			}
267
-		}
268
-
269
-		usort($users, function ($a, $b) {
270
-			/**
271
-			 * @var \OC\User\User $a
272
-			 * @var \OC\User\User $b
273
-			 */
274
-			return strcmp(strtolower($a->getDisplayName()), strtolower($b->getDisplayName()));
275
-		});
276
-		return $users;
277
-	}
278
-
279
-	/**
280
-	 * @param string $uid
281
-	 * @param string $password
282
-	 * @throws \Exception
283
-	 * @return bool|\OC\User\User the created user or false
284
-	 */
285
-	public function createUser($uid, $password) {
286
-		$l = \OC::$server->getL10N('lib');
287
-		// Check the name for bad characters
288
-		// Allowed are: "a-z", "A-Z", "0-9" and "_.@-'"
289
-		if (preg_match('/[^a-zA-Z0-9 _\.@\-\']/', $uid)) {
290
-			throw new \Exception($l->t('Only the following characters are allowed in a username:'
291
-				. ' "a-z", "A-Z", "0-9", and "_.@-\'"'));
292
-		}
293
-		// No empty username
294
-		if (trim($uid) == '') {
295
-			throw new \Exception($l->t('A valid username must be provided'));
296
-		}
297
-		// No whitespace at the beginning or at the end
298
-		if (trim($uid) !== $uid) {
299
-			throw new \Exception($l->t('Username contains whitespace at the beginning or at the end'));
300
-		}
301
-		// Username only consists of 1 or 2 dots (directory traversal)
302
-		if ($uid === '.' || $uid === '..') {
303
-			throw new \Exception($l->t('Username must not consist of dots only'));
304
-		}
305
-		// No empty password
306
-		if (trim($password) == '') {
307
-			throw new \Exception($l->t('A valid password must be provided'));
308
-		}
309
-
310
-		// Check if user already exists
311
-		if ($this->userExists($uid)) {
312
-			throw new \Exception($l->t('The username is already being used'));
313
-		}
314
-
315
-		$this->emit('\OC\User', 'preCreateUser', array($uid, $password));
316
-		foreach ($this->backends as $backend) {
317
-			if ($backend->implementsActions(Backend::CREATE_USER)) {
318
-				$backend->createUser($uid, $password);
319
-				$user = $this->getUserObject($uid, $backend);
320
-				$this->emit('\OC\User', 'postCreateUser', array($user, $password));
321
-				return $user;
322
-			}
323
-		}
324
-		return false;
325
-	}
326
-
327
-	/**
328
-	 * returns how many users per backend exist (if supported by backend)
329
-	 *
330
-	 * @param boolean $hasLoggedIn when true only users that have a lastLogin
331
-	 *                entry in the preferences table will be affected
332
-	 * @return array|int an array of backend class as key and count number as value
333
-	 *                if $hasLoggedIn is true only an int is returned
334
-	 */
335
-	public function countUsers($hasLoggedIn = false) {
336
-		if ($hasLoggedIn) {
337
-			return $this->countSeenUsers();
338
-		}
339
-		$userCountStatistics = [];
340
-		foreach ($this->backends as $backend) {
341
-			if ($backend->implementsActions(Backend::COUNT_USERS)) {
342
-				$backendUsers = $backend->countUsers();
343
-				if($backendUsers !== false) {
344
-					if($backend instanceof IUserBackend) {
345
-						$name = $backend->getBackendName();
346
-					} else {
347
-						$name = get_class($backend);
348
-					}
349
-					if(isset($userCountStatistics[$name])) {
350
-						$userCountStatistics[$name] += $backendUsers;
351
-					} else {
352
-						$userCountStatistics[$name] = $backendUsers;
353
-					}
354
-				}
355
-			}
356
-		}
357
-		return $userCountStatistics;
358
-	}
359
-
360
-	/**
361
-	 * The callback is executed for each user on each backend.
362
-	 * If the callback returns false no further users will be retrieved.
363
-	 *
364
-	 * @param \Closure $callback
365
-	 * @param string $search
366
-	 * @param boolean $onlySeen when true only users that have a lastLogin entry
367
-	 *                in the preferences table will be affected
368
-	 * @since 9.0.0
369
-	 */
370
-	public function callForAllUsers(\Closure $callback, $search = '', $onlySeen = false) {
371
-		if ($onlySeen) {
372
-			$this->callForSeenUsers($callback);
373
-		} else {
374
-			foreach ($this->getBackends() as $backend) {
375
-				$limit = 500;
376
-				$offset = 0;
377
-				do {
378
-					$users = $backend->getUsers($search, $limit, $offset);
379
-					foreach ($users as $uid) {
380
-						if (!$backend->userExists($uid)) {
381
-							continue;
382
-						}
383
-						$user = $this->getUserObject($uid, $backend, false);
384
-						$return = $callback($user);
385
-						if ($return === false) {
386
-							break;
387
-						}
388
-					}
389
-					$offset += $limit;
390
-				} while (count($users) >= $limit);
391
-			}
392
-		}
393
-	}
394
-
395
-	/**
396
-	 * returns how many users have logged in once
397
-	 *
398
-	 * @return int
399
-	 * @since 12.0.0
400
-	 */
401
-	public function countDisabledUsers() {
402
-		$queryBuilder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
403
-		$queryBuilder->select($queryBuilder->createFunction('COUNT(*)'))
404
-			->from('preferences')
405
-			->where($queryBuilder->expr()->eq('appid', $queryBuilder->createNamedParameter('core')))
406
-			->andWhere($queryBuilder->expr()->eq('configkey', $queryBuilder->createNamedParameter('enabled')))
407
-			->andWhere($queryBuilder->expr()->eq('configvalue', $queryBuilder->createNamedParameter('false')));
408
-
409
-		$query = $queryBuilder->execute();
410
-
411
-		$result = (int)$query->fetchColumn();
412
-		$query->closeCursor();
413
-
414
-		return $result;
415
-	}
416
-
417
-	/**
418
-	 * returns how many users have logged in once
419
-	 *
420
-	 * @return int
421
-	 * @since 11.0.0
422
-	 */
423
-	public function countSeenUsers() {
424
-		$queryBuilder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
425
-		$queryBuilder->select($queryBuilder->createFunction('COUNT(*)'))
426
-			->from('preferences')
427
-			->where($queryBuilder->expr()->eq('appid', $queryBuilder->createNamedParameter('login')))
428
-			->andWhere($queryBuilder->expr()->eq('configkey', $queryBuilder->createNamedParameter('lastLogin')))
429
-			->andWhere($queryBuilder->expr()->isNotNull('configvalue'));
430
-
431
-		$query = $queryBuilder->execute();
432
-
433
-		$result = (int)$query->fetchColumn();
434
-		$query->closeCursor();
435
-
436
-		return $result;
437
-	}
438
-
439
-	/**
440
-	 * @param \Closure $callback
441
-	 * @since 11.0.0
442
-	 */
443
-	public function callForSeenUsers(\Closure $callback) {
444
-		$limit = 1000;
445
-		$offset = 0;
446
-		do {
447
-			$userIds = $this->getSeenUserIds($limit, $offset);
448
-			$offset += $limit;
449
-			foreach ($userIds as $userId) {
450
-				foreach ($this->backends as $backend) {
451
-					if ($backend->userExists($userId)) {
452
-						$user = $this->getUserObject($userId, $backend, false);
453
-						$return = $callback($user);
454
-						if ($return === false) {
455
-							return;
456
-						}
457
-					}
458
-				}
459
-			}
460
-		} while (count($userIds) >= $limit);
461
-	}
462
-
463
-	/**
464
-	 * Getting all userIds that have a listLogin value requires checking the
465
-	 * value in php because on oracle you cannot use a clob in a where clause,
466
-	 * preventing us from doing a not null or length(value) > 0 check.
467
-	 * 
468
-	 * @param int $limit
469
-	 * @param int $offset
470
-	 * @return string[] with user ids
471
-	 */
472
-	private function getSeenUserIds($limit = null, $offset = null) {
473
-		$queryBuilder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
474
-		$queryBuilder->select(['userid'])
475
-			->from('preferences')
476
-			->where($queryBuilder->expr()->eq(
477
-				'appid', $queryBuilder->createNamedParameter('login'))
478
-			)
479
-			->andWhere($queryBuilder->expr()->eq(
480
-				'configkey', $queryBuilder->createNamedParameter('lastLogin'))
481
-			)
482
-			->andWhere($queryBuilder->expr()->isNotNull('configvalue')
483
-			);
484
-
485
-		if ($limit !== null) {
486
-			$queryBuilder->setMaxResults($limit);
487
-		}
488
-		if ($offset !== null) {
489
-			$queryBuilder->setFirstResult($offset);
490
-		}
491
-		$query = $queryBuilder->execute();
492
-		$result = [];
493
-
494
-		while ($row = $query->fetch()) {
495
-			$result[] = $row['userid'];
496
-		}
497
-
498
-		$query->closeCursor();
499
-
500
-		return $result;
501
-	}
502
-
503
-	/**
504
-	 * @param string $email
505
-	 * @return IUser[]
506
-	 * @since 9.1.0
507
-	 */
508
-	public function getByEmail($email) {
509
-		$userIds = $this->config->getUsersForUserValue('settings', 'email', $email);
510
-
511
-		return array_map(function($uid) {
512
-			return $this->get($uid);
513
-		}, $userIds);
514
-	}
57
+    /**
58
+     * @var \OCP\UserInterface[] $backends
59
+     */
60
+    private $backends = array();
61
+
62
+    /**
63
+     * @var \OC\User\User[] $cachedUsers
64
+     */
65
+    private $cachedUsers = array();
66
+
67
+    /**
68
+     * @var \OCP\IConfig $config
69
+     */
70
+    private $config;
71
+
72
+    /**
73
+     * @param \OCP\IConfig $config
74
+     */
75
+    public function __construct(IConfig $config) {
76
+        $this->config = $config;
77
+        $cachedUsers = &$this->cachedUsers;
78
+        $this->listen('\OC\User', 'postDelete', function ($user) use (&$cachedUsers) {
79
+            /** @var \OC\User\User $user */
80
+            unset($cachedUsers[$user->getUID()]);
81
+        });
82
+    }
83
+
84
+    /**
85
+     * Get the active backends
86
+     * @return \OCP\UserInterface[]
87
+     */
88
+    public function getBackends() {
89
+        return $this->backends;
90
+    }
91
+
92
+    /**
93
+     * register a user backend
94
+     *
95
+     * @param \OCP\UserInterface $backend
96
+     */
97
+    public function registerBackend($backend) {
98
+        $this->backends[] = $backend;
99
+    }
100
+
101
+    /**
102
+     * remove a user backend
103
+     *
104
+     * @param \OCP\UserInterface $backend
105
+     */
106
+    public function removeBackend($backend) {
107
+        $this->cachedUsers = array();
108
+        if (($i = array_search($backend, $this->backends)) !== false) {
109
+            unset($this->backends[$i]);
110
+        }
111
+    }
112
+
113
+    /**
114
+     * remove all user backends
115
+     */
116
+    public function clearBackends() {
117
+        $this->cachedUsers = array();
118
+        $this->backends = array();
119
+    }
120
+
121
+    /**
122
+     * get a user by user id
123
+     *
124
+     * @param string $uid
125
+     * @return \OC\User\User|null Either the user or null if the specified user does not exist
126
+     */
127
+    public function get($uid) {
128
+        if (isset($this->cachedUsers[$uid])) { //check the cache first to prevent having to loop over the backends
129
+            return $this->cachedUsers[$uid];
130
+        }
131
+        foreach ($this->backends as $backend) {
132
+            if ($backend->userExists($uid)) {
133
+                return $this->getUserObject($uid, $backend);
134
+            }
135
+        }
136
+        return null;
137
+    }
138
+
139
+    /**
140
+     * get or construct the user object
141
+     *
142
+     * @param string $uid
143
+     * @param \OCP\UserInterface $backend
144
+     * @param bool $cacheUser If false the newly created user object will not be cached
145
+     * @return \OC\User\User
146
+     */
147
+    protected function getUserObject($uid, $backend, $cacheUser = true) {
148
+        if (isset($this->cachedUsers[$uid])) {
149
+            return $this->cachedUsers[$uid];
150
+        }
151
+
152
+        if (method_exists($backend, 'loginName2UserName')) {
153
+            $loginName = $backend->loginName2UserName($uid);
154
+            if ($loginName !== false) {
155
+                $uid = $loginName;
156
+            }
157
+            if (isset($this->cachedUsers[$uid])) {
158
+                return $this->cachedUsers[$uid];
159
+            }
160
+        }
161
+
162
+        $user = new User($uid, $backend, $this, $this->config);
163
+        if ($cacheUser) {
164
+            $this->cachedUsers[$uid] = $user;
165
+        }
166
+        return $user;
167
+    }
168
+
169
+    /**
170
+     * check if a user exists
171
+     *
172
+     * @param string $uid
173
+     * @return bool
174
+     */
175
+    public function userExists($uid) {
176
+        $user = $this->get($uid);
177
+        return ($user !== null);
178
+    }
179
+
180
+    /**
181
+     * Check if the password is valid for the user
182
+     *
183
+     * @param string $loginName
184
+     * @param string $password
185
+     * @return mixed the User object on success, false otherwise
186
+     */
187
+    public function checkPassword($loginName, $password) {
188
+        $result = $this->checkPasswordNoLogging($loginName, $password);
189
+
190
+        if ($result === false) {
191
+            \OC::$server->getLogger()->warning('Login failed: \''. $loginName .'\' (Remote IP: \''. \OC::$server->getRequest()->getRemoteAddress(). '\')', ['app' => 'core']);
192
+        }
193
+
194
+        return $result;
195
+    }
196
+
197
+    /**
198
+     * Check if the password is valid for the user
199
+     *
200
+     * @internal
201
+     * @param string $loginName
202
+     * @param string $password
203
+     * @return mixed the User object on success, false otherwise
204
+     */
205
+    public function checkPasswordNoLogging($loginName, $password) {
206
+        $loginName = str_replace("\0", '', $loginName);
207
+        $password = str_replace("\0", '', $password);
208
+
209
+        foreach ($this->backends as $backend) {
210
+            if ($backend->implementsActions(Backend::CHECK_PASSWORD)) {
211
+                $uid = $backend->checkPassword($loginName, $password);
212
+                if ($uid !== false) {
213
+                    return $this->getUserObject($uid, $backend);
214
+                }
215
+            }
216
+        }
217
+
218
+        return false;
219
+    }
220
+
221
+    /**
222
+     * search by user id
223
+     *
224
+     * @param string $pattern
225
+     * @param int $limit
226
+     * @param int $offset
227
+     * @return \OC\User\User[]
228
+     */
229
+    public function search($pattern, $limit = null, $offset = null) {
230
+        $users = array();
231
+        foreach ($this->backends as $backend) {
232
+            $backendUsers = $backend->getUsers($pattern, $limit, $offset);
233
+            if (is_array($backendUsers)) {
234
+                foreach ($backendUsers as $uid) {
235
+                    $users[$uid] = $this->getUserObject($uid, $backend);
236
+                }
237
+            }
238
+        }
239
+
240
+        uasort($users, function ($a, $b) {
241
+            /**
242
+             * @var \OC\User\User $a
243
+             * @var \OC\User\User $b
244
+             */
245
+            return strcmp($a->getUID(), $b->getUID());
246
+        });
247
+        return $users;
248
+    }
249
+
250
+    /**
251
+     * search by displayName
252
+     *
253
+     * @param string $pattern
254
+     * @param int $limit
255
+     * @param int $offset
256
+     * @return \OC\User\User[]
257
+     */
258
+    public function searchDisplayName($pattern, $limit = null, $offset = null) {
259
+        $users = array();
260
+        foreach ($this->backends as $backend) {
261
+            $backendUsers = $backend->getDisplayNames($pattern, $limit, $offset);
262
+            if (is_array($backendUsers)) {
263
+                foreach ($backendUsers as $uid => $displayName) {
264
+                    $users[] = $this->getUserObject($uid, $backend);
265
+                }
266
+            }
267
+        }
268
+
269
+        usort($users, function ($a, $b) {
270
+            /**
271
+             * @var \OC\User\User $a
272
+             * @var \OC\User\User $b
273
+             */
274
+            return strcmp(strtolower($a->getDisplayName()), strtolower($b->getDisplayName()));
275
+        });
276
+        return $users;
277
+    }
278
+
279
+    /**
280
+     * @param string $uid
281
+     * @param string $password
282
+     * @throws \Exception
283
+     * @return bool|\OC\User\User the created user or false
284
+     */
285
+    public function createUser($uid, $password) {
286
+        $l = \OC::$server->getL10N('lib');
287
+        // Check the name for bad characters
288
+        // Allowed are: "a-z", "A-Z", "0-9" and "_.@-'"
289
+        if (preg_match('/[^a-zA-Z0-9 _\.@\-\']/', $uid)) {
290
+            throw new \Exception($l->t('Only the following characters are allowed in a username:'
291
+                . ' "a-z", "A-Z", "0-9", and "_.@-\'"'));
292
+        }
293
+        // No empty username
294
+        if (trim($uid) == '') {
295
+            throw new \Exception($l->t('A valid username must be provided'));
296
+        }
297
+        // No whitespace at the beginning or at the end
298
+        if (trim($uid) !== $uid) {
299
+            throw new \Exception($l->t('Username contains whitespace at the beginning or at the end'));
300
+        }
301
+        // Username only consists of 1 or 2 dots (directory traversal)
302
+        if ($uid === '.' || $uid === '..') {
303
+            throw new \Exception($l->t('Username must not consist of dots only'));
304
+        }
305
+        // No empty password
306
+        if (trim($password) == '') {
307
+            throw new \Exception($l->t('A valid password must be provided'));
308
+        }
309
+
310
+        // Check if user already exists
311
+        if ($this->userExists($uid)) {
312
+            throw new \Exception($l->t('The username is already being used'));
313
+        }
314
+
315
+        $this->emit('\OC\User', 'preCreateUser', array($uid, $password));
316
+        foreach ($this->backends as $backend) {
317
+            if ($backend->implementsActions(Backend::CREATE_USER)) {
318
+                $backend->createUser($uid, $password);
319
+                $user = $this->getUserObject($uid, $backend);
320
+                $this->emit('\OC\User', 'postCreateUser', array($user, $password));
321
+                return $user;
322
+            }
323
+        }
324
+        return false;
325
+    }
326
+
327
+    /**
328
+     * returns how many users per backend exist (if supported by backend)
329
+     *
330
+     * @param boolean $hasLoggedIn when true only users that have a lastLogin
331
+     *                entry in the preferences table will be affected
332
+     * @return array|int an array of backend class as key and count number as value
333
+     *                if $hasLoggedIn is true only an int is returned
334
+     */
335
+    public function countUsers($hasLoggedIn = false) {
336
+        if ($hasLoggedIn) {
337
+            return $this->countSeenUsers();
338
+        }
339
+        $userCountStatistics = [];
340
+        foreach ($this->backends as $backend) {
341
+            if ($backend->implementsActions(Backend::COUNT_USERS)) {
342
+                $backendUsers = $backend->countUsers();
343
+                if($backendUsers !== false) {
344
+                    if($backend instanceof IUserBackend) {
345
+                        $name = $backend->getBackendName();
346
+                    } else {
347
+                        $name = get_class($backend);
348
+                    }
349
+                    if(isset($userCountStatistics[$name])) {
350
+                        $userCountStatistics[$name] += $backendUsers;
351
+                    } else {
352
+                        $userCountStatistics[$name] = $backendUsers;
353
+                    }
354
+                }
355
+            }
356
+        }
357
+        return $userCountStatistics;
358
+    }
359
+
360
+    /**
361
+     * The callback is executed for each user on each backend.
362
+     * If the callback returns false no further users will be retrieved.
363
+     *
364
+     * @param \Closure $callback
365
+     * @param string $search
366
+     * @param boolean $onlySeen when true only users that have a lastLogin entry
367
+     *                in the preferences table will be affected
368
+     * @since 9.0.0
369
+     */
370
+    public function callForAllUsers(\Closure $callback, $search = '', $onlySeen = false) {
371
+        if ($onlySeen) {
372
+            $this->callForSeenUsers($callback);
373
+        } else {
374
+            foreach ($this->getBackends() as $backend) {
375
+                $limit = 500;
376
+                $offset = 0;
377
+                do {
378
+                    $users = $backend->getUsers($search, $limit, $offset);
379
+                    foreach ($users as $uid) {
380
+                        if (!$backend->userExists($uid)) {
381
+                            continue;
382
+                        }
383
+                        $user = $this->getUserObject($uid, $backend, false);
384
+                        $return = $callback($user);
385
+                        if ($return === false) {
386
+                            break;
387
+                        }
388
+                    }
389
+                    $offset += $limit;
390
+                } while (count($users) >= $limit);
391
+            }
392
+        }
393
+    }
394
+
395
+    /**
396
+     * returns how many users have logged in once
397
+     *
398
+     * @return int
399
+     * @since 12.0.0
400
+     */
401
+    public function countDisabledUsers() {
402
+        $queryBuilder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
403
+        $queryBuilder->select($queryBuilder->createFunction('COUNT(*)'))
404
+            ->from('preferences')
405
+            ->where($queryBuilder->expr()->eq('appid', $queryBuilder->createNamedParameter('core')))
406
+            ->andWhere($queryBuilder->expr()->eq('configkey', $queryBuilder->createNamedParameter('enabled')))
407
+            ->andWhere($queryBuilder->expr()->eq('configvalue', $queryBuilder->createNamedParameter('false')));
408
+
409
+        $query = $queryBuilder->execute();
410
+
411
+        $result = (int)$query->fetchColumn();
412
+        $query->closeCursor();
413
+
414
+        return $result;
415
+    }
416
+
417
+    /**
418
+     * returns how many users have logged in once
419
+     *
420
+     * @return int
421
+     * @since 11.0.0
422
+     */
423
+    public function countSeenUsers() {
424
+        $queryBuilder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
425
+        $queryBuilder->select($queryBuilder->createFunction('COUNT(*)'))
426
+            ->from('preferences')
427
+            ->where($queryBuilder->expr()->eq('appid', $queryBuilder->createNamedParameter('login')))
428
+            ->andWhere($queryBuilder->expr()->eq('configkey', $queryBuilder->createNamedParameter('lastLogin')))
429
+            ->andWhere($queryBuilder->expr()->isNotNull('configvalue'));
430
+
431
+        $query = $queryBuilder->execute();
432
+
433
+        $result = (int)$query->fetchColumn();
434
+        $query->closeCursor();
435
+
436
+        return $result;
437
+    }
438
+
439
+    /**
440
+     * @param \Closure $callback
441
+     * @since 11.0.0
442
+     */
443
+    public function callForSeenUsers(\Closure $callback) {
444
+        $limit = 1000;
445
+        $offset = 0;
446
+        do {
447
+            $userIds = $this->getSeenUserIds($limit, $offset);
448
+            $offset += $limit;
449
+            foreach ($userIds as $userId) {
450
+                foreach ($this->backends as $backend) {
451
+                    if ($backend->userExists($userId)) {
452
+                        $user = $this->getUserObject($userId, $backend, false);
453
+                        $return = $callback($user);
454
+                        if ($return === false) {
455
+                            return;
456
+                        }
457
+                    }
458
+                }
459
+            }
460
+        } while (count($userIds) >= $limit);
461
+    }
462
+
463
+    /**
464
+     * Getting all userIds that have a listLogin value requires checking the
465
+     * value in php because on oracle you cannot use a clob in a where clause,
466
+     * preventing us from doing a not null or length(value) > 0 check.
467
+     * 
468
+     * @param int $limit
469
+     * @param int $offset
470
+     * @return string[] with user ids
471
+     */
472
+    private function getSeenUserIds($limit = null, $offset = null) {
473
+        $queryBuilder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
474
+        $queryBuilder->select(['userid'])
475
+            ->from('preferences')
476
+            ->where($queryBuilder->expr()->eq(
477
+                'appid', $queryBuilder->createNamedParameter('login'))
478
+            )
479
+            ->andWhere($queryBuilder->expr()->eq(
480
+                'configkey', $queryBuilder->createNamedParameter('lastLogin'))
481
+            )
482
+            ->andWhere($queryBuilder->expr()->isNotNull('configvalue')
483
+            );
484
+
485
+        if ($limit !== null) {
486
+            $queryBuilder->setMaxResults($limit);
487
+        }
488
+        if ($offset !== null) {
489
+            $queryBuilder->setFirstResult($offset);
490
+        }
491
+        $query = $queryBuilder->execute();
492
+        $result = [];
493
+
494
+        while ($row = $query->fetch()) {
495
+            $result[] = $row['userid'];
496
+        }
497
+
498
+        $query->closeCursor();
499
+
500
+        return $result;
501
+    }
502
+
503
+    /**
504
+     * @param string $email
505
+     * @return IUser[]
506
+     * @since 9.1.0
507
+     */
508
+    public function getByEmail($email) {
509
+        $userIds = $this->config->getUsersForUserValue('settings', 'email', $email);
510
+
511
+        return array_map(function($uid) {
512
+            return $this->get($uid);
513
+        }, $userIds);
514
+    }
515 515
 }
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -75,7 +75,7 @@  discard block
 block discarded – undo
75 75
 	public function __construct(IConfig $config) {
76 76
 		$this->config = $config;
77 77
 		$cachedUsers = &$this->cachedUsers;
78
-		$this->listen('\OC\User', 'postDelete', function ($user) use (&$cachedUsers) {
78
+		$this->listen('\OC\User', 'postDelete', function($user) use (&$cachedUsers) {
79 79
 			/** @var \OC\User\User $user */
80 80
 			unset($cachedUsers[$user->getUID()]);
81 81
 		});
@@ -188,7 +188,7 @@  discard block
 block discarded – undo
188 188
 		$result = $this->checkPasswordNoLogging($loginName, $password);
189 189
 
190 190
 		if ($result === false) {
191
-			\OC::$server->getLogger()->warning('Login failed: \''. $loginName .'\' (Remote IP: \''. \OC::$server->getRequest()->getRemoteAddress(). '\')', ['app' => 'core']);
191
+			\OC::$server->getLogger()->warning('Login failed: \''.$loginName.'\' (Remote IP: \''.\OC::$server->getRequest()->getRemoteAddress().'\')', ['app' => 'core']);
192 192
 		}
193 193
 
194 194
 		return $result;
@@ -237,7 +237,7 @@  discard block
 block discarded – undo
237 237
 			}
238 238
 		}
239 239
 
240
-		uasort($users, function ($a, $b) {
240
+		uasort($users, function($a, $b) {
241 241
 			/**
242 242
 			 * @var \OC\User\User $a
243 243
 			 * @var \OC\User\User $b
@@ -266,7 +266,7 @@  discard block
 block discarded – undo
266 266
 			}
267 267
 		}
268 268
 
269
-		usort($users, function ($a, $b) {
269
+		usort($users, function($a, $b) {
270 270
 			/**
271 271
 			 * @var \OC\User\User $a
272 272
 			 * @var \OC\User\User $b
@@ -340,13 +340,13 @@  discard block
 block discarded – undo
340 340
 		foreach ($this->backends as $backend) {
341 341
 			if ($backend->implementsActions(Backend::COUNT_USERS)) {
342 342
 				$backendUsers = $backend->countUsers();
343
-				if($backendUsers !== false) {
344
-					if($backend instanceof IUserBackend) {
343
+				if ($backendUsers !== false) {
344
+					if ($backend instanceof IUserBackend) {
345 345
 						$name = $backend->getBackendName();
346 346
 					} else {
347 347
 						$name = get_class($backend);
348 348
 					}
349
-					if(isset($userCountStatistics[$name])) {
349
+					if (isset($userCountStatistics[$name])) {
350 350
 						$userCountStatistics[$name] += $backendUsers;
351 351
 					} else {
352 352
 						$userCountStatistics[$name] = $backendUsers;
@@ -408,7 +408,7 @@  discard block
 block discarded – undo
408 408
 
409 409
 		$query = $queryBuilder->execute();
410 410
 
411
-		$result = (int)$query->fetchColumn();
411
+		$result = (int) $query->fetchColumn();
412 412
 		$query->closeCursor();
413 413
 
414 414
 		return $result;
@@ -430,7 +430,7 @@  discard block
 block discarded – undo
430 430
 
431 431
 		$query = $queryBuilder->execute();
432 432
 
433
-		$result = (int)$query->fetchColumn();
433
+		$result = (int) $query->fetchColumn();
434 434
 		$query->closeCursor();
435 435
 
436 436
 		return $result;
Please login to merge, or discard this patch.
settings/users.php 2 patches
Indentation   +35 added lines, -35 removed lines patch added patch discarded remove patch
@@ -47,13 +47,13 @@  discard block
 block discarded – undo
47 47
 
48 48
 $isLDAPUsed = false;
49 49
 if (\OC_App::isEnabled('user_ldap')) {
50
-	$isLDAPUsed =
51
-		   $groupManager->isBackendUsed('\OCA\User_LDAP\Group_LDAP')
52
-		|| $groupManager->isBackendUsed('\OCA\User_LDAP\Group_Proxy');
53
-	if ($isLDAPUsed) {
54
-		// LDAP user count can be slow, so we sort by group name here
55
-		$sortGroupsBy = \OC\Group\MetaData::SORT_GROUPNAME;
56
-	}
50
+    $isLDAPUsed =
51
+            $groupManager->isBackendUsed('\OCA\User_LDAP\Group_LDAP')
52
+        || $groupManager->isBackendUsed('\OCA\User_LDAP\Group_Proxy');
53
+    if ($isLDAPUsed) {
54
+        // LDAP user count can be slow, so we sort by group name here
55
+        $sortGroupsBy = \OC\Group\MetaData::SORT_GROUPNAME;
56
+    }
57 57
 }
58 58
 
59 59
 $config = \OC::$server->getConfig();
@@ -63,58 +63,58 @@  discard block
 block discarded – undo
63 63
 $isDisabled = !OC_User::isEnabled(OC_User::getUser());
64 64
 
65 65
 $groupsInfo = new \OC\Group\MetaData(
66
-	OC_User::getUser(),
67
-	$isAdmin,
68
-	$groupManager,
69
-	\OC::$server->getUserSession()
66
+    OC_User::getUser(),
67
+    $isAdmin,
68
+    $groupManager,
69
+    \OC::$server->getUserSession()
70 70
 );
71 71
 
72 72
 $groupsInfo->setSorting($sortGroupsBy);
73 73
 list($adminGroup, $groups) = $groupsInfo->get();
74 74
 
75 75
 $recoveryAdminEnabled = OC_App::isEnabled('encryption') &&
76
-					    $config->getAppValue( 'encryption', 'recoveryAdminEnabled', null );
76
+                        $config->getAppValue( 'encryption', 'recoveryAdminEnabled', null );
77 77
 
78 78
 if($isAdmin) {
79
-	$subAdmins = \OC::$server->getGroupManager()->getSubAdmin()->getAllSubAdmins();
80
-	// New class returns IUser[] so convert back
81
-	$result = [];
82
-	foreach ($subAdmins as $subAdmin) {
83
-		$result[] = [
84
-			'gid' => $subAdmin['group']->getGID(),
85
-			'uid' => $subAdmin['user']->getUID(),
86
-		];
87
-	}
88
-	$subAdmins = $result;
79
+    $subAdmins = \OC::$server->getGroupManager()->getSubAdmin()->getAllSubAdmins();
80
+    // New class returns IUser[] so convert back
81
+    $result = [];
82
+    foreach ($subAdmins as $subAdmin) {
83
+        $result[] = [
84
+            'gid' => $subAdmin['group']->getGID(),
85
+            'uid' => $subAdmin['user']->getUID(),
86
+        ];
87
+    }
88
+    $subAdmins = $result;
89 89
 }else{
90
-	/* Retrieve group IDs from $groups array, so we can pass that information into OC_Group::displayNamesInGroups() */
91
-	$gids = array();
92
-	foreach($groups as $group) {
93
-		if (isset($group['id'])) {
94
-			$gids[] = $group['id'];
95
-		}
96
-	}
97
-	$subAdmins = false;
90
+    /* Retrieve group IDs from $groups array, so we can pass that information into OC_Group::displayNamesInGroups() */
91
+    $gids = array();
92
+    foreach($groups as $group) {
93
+        if (isset($group['id'])) {
94
+            $gids[] = $group['id'];
95
+        }
96
+    }
97
+    $subAdmins = false;
98 98
 }
99 99
 
100 100
 $disabledUsers = $isLDAPUsed ? 0 : $userManager->countDisabledUsers();
101 101
 $disabledUsersGroup = [
102
-	'id' => '_disabledUsers',
103
-	'name' => '_disabledUsers',
104
-	'usercount' => $disabledUsers
102
+    'id' => '_disabledUsers',
103
+    'name' => '_disabledUsers',
104
+    'usercount' => $disabledUsers
105 105
 ];
106 106
 
107 107
 // load preset quotas
108 108
 $quotaPreset=$config->getAppValue('files', 'quota_preset', '1 GB, 5 GB, 10 GB');
109 109
 $quotaPreset=explode(',', $quotaPreset);
110 110
 foreach($quotaPreset as &$preset) {
111
-	$preset=trim($preset);
111
+    $preset=trim($preset);
112 112
 }
113 113
 $quotaPreset=array_diff($quotaPreset, array('default', 'none'));
114 114
 
115 115
 $defaultQuota=$config->getAppValue('files', 'default_quota', 'none');
116 116
 $defaultQuotaIsUserDefined=array_search($defaultQuota, $quotaPreset)===false
117
-	&& array_search($defaultQuota, array('none', 'default'))===false;
117
+    && array_search($defaultQuota, array('none', 'default'))===false;
118 118
 
119 119
 \OC::$server->getEventDispatcher()->dispatch('OC\Settings\Users::loadAdditionalScripts');
120 120
 
Please login to merge, or discard this patch.
Spacing   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -73,9 +73,9 @@  discard block
 block discarded – undo
73 73
 list($adminGroup, $groups) = $groupsInfo->get();
74 74
 
75 75
 $recoveryAdminEnabled = OC_App::isEnabled('encryption') &&
76
-					    $config->getAppValue( 'encryption', 'recoveryAdminEnabled', null );
76
+					    $config->getAppValue('encryption', 'recoveryAdminEnabled', null);
77 77
 
78
-if($isAdmin) {
78
+if ($isAdmin) {
79 79
 	$subAdmins = \OC::$server->getGroupManager()->getSubAdmin()->getAllSubAdmins();
80 80
 	// New class returns IUser[] so convert back
81 81
 	$result = [];
@@ -86,10 +86,10 @@  discard block
 block discarded – undo
86 86
 		];
87 87
 	}
88 88
 	$subAdmins = $result;
89
-}else{
89
+} else {
90 90
 	/* Retrieve group IDs from $groups array, so we can pass that information into OC_Group::displayNamesInGroups() */
91 91
 	$gids = array();
92
-	foreach($groups as $group) {
92
+	foreach ($groups as $group) {
93 93
 		if (isset($group['id'])) {
94 94
 			$gids[] = $group['id'];
95 95
 		}
@@ -105,16 +105,16 @@  discard block
 block discarded – undo
105 105
 ];
106 106
 
107 107
 // load preset quotas
108
-$quotaPreset=$config->getAppValue('files', 'quota_preset', '1 GB, 5 GB, 10 GB');
109
-$quotaPreset=explode(',', $quotaPreset);
110
-foreach($quotaPreset as &$preset) {
111
-	$preset=trim($preset);
108
+$quotaPreset = $config->getAppValue('files', 'quota_preset', '1 GB, 5 GB, 10 GB');
109
+$quotaPreset = explode(',', $quotaPreset);
110
+foreach ($quotaPreset as &$preset) {
111
+	$preset = trim($preset);
112 112
 }
113
-$quotaPreset=array_diff($quotaPreset, array('default', 'none'));
113
+$quotaPreset = array_diff($quotaPreset, array('default', 'none'));
114 114
 
115
-$defaultQuota=$config->getAppValue('files', 'default_quota', 'none');
116
-$defaultQuotaIsUserDefined=array_search($defaultQuota, $quotaPreset)===false
117
-	&& array_search($defaultQuota, array('none', 'default'))===false;
115
+$defaultQuota = $config->getAppValue('files', 'default_quota', 'none');
116
+$defaultQuotaIsUserDefined = array_search($defaultQuota, $quotaPreset) === false
117
+	&& array_search($defaultQuota, array('none', 'default')) === false;
118 118
 
119 119
 \OC::$server->getEventDispatcher()->dispatch('OC\Settings\Users::loadAdditionalScripts');
120 120
 
@@ -123,7 +123,7 @@  discard block
 block discarded – undo
123 123
 $tmpl->assign('sortGroups', $sortGroupsBy);
124 124
 $tmpl->assign('adminGroup', $adminGroup);
125 125
 $tmpl->assign('disabledUsersGroup', $disabledUsersGroup);
126
-$tmpl->assign('isAdmin', (int)$isAdmin);
126
+$tmpl->assign('isAdmin', (int) $isAdmin);
127 127
 $tmpl->assign('subadmins', $subAdmins);
128 128
 $tmpl->assign('numofgroups', count($groups) + count($adminGroup));
129 129
 $tmpl->assign('quota_preset', $quotaPreset);
Please login to merge, or discard this patch.
settings/Controller/UsersController.php 2 patches
Indentation   +820 added lines, -820 removed lines patch added patch discarded remove patch
@@ -54,825 +54,825 @@
 block discarded – undo
54 54
  * @package OC\Settings\Controller
55 55
  */
56 56
 class UsersController extends Controller {
57
-	/** @var IL10N */
58
-	private $l10n;
59
-	/** @var IUserSession */
60
-	private $userSession;
61
-	/** @var bool */
62
-	private $isAdmin;
63
-	/** @var IUserManager */
64
-	private $userManager;
65
-	/** @var IGroupManager */
66
-	private $groupManager;
67
-	/** @var IConfig */
68
-	private $config;
69
-	/** @var ILogger */
70
-	private $log;
71
-	/** @var IMailer */
72
-	private $mailer;
73
-	/** @var bool contains the state of the encryption app */
74
-	private $isEncryptionAppEnabled;
75
-	/** @var bool contains the state of the admin recovery setting */
76
-	private $isRestoreEnabled = false;
77
-	/** @var IAvatarManager */
78
-	private $avatarManager;
79
-	/** @var AccountManager */
80
-	private $accountManager;
81
-	/** @var ISecureRandom */
82
-	private $secureRandom;
83
-	/** @var NewUserMailHelper */
84
-	private $newUserMailHelper;
85
-
86
-	/**
87
-	 * @param string $appName
88
-	 * @param IRequest $request
89
-	 * @param IUserManager $userManager
90
-	 * @param IGroupManager $groupManager
91
-	 * @param IUserSession $userSession
92
-	 * @param IConfig $config
93
-	 * @param bool $isAdmin
94
-	 * @param IL10N $l10n
95
-	 * @param ILogger $log
96
-	 * @param IMailer $mailer
97
-	 * @param IURLGenerator $urlGenerator
98
-	 * @param IAppManager $appManager
99
-	 * @param IAvatarManager $avatarManager
100
-	 * @param AccountManager $accountManager
101
-	 * @param ISecureRandom $secureRandom
102
-	 * @param NewUserMailHelper $newUserMailHelper
103
-	 */
104
-	public function __construct($appName,
105
-								IRequest $request,
106
-								IUserManager $userManager,
107
-								IGroupManager $groupManager,
108
-								IUserSession $userSession,
109
-								IConfig $config,
110
-								$isAdmin,
111
-								IL10N $l10n,
112
-								ILogger $log,
113
-								IMailer $mailer,
114
-								IURLGenerator $urlGenerator,
115
-								IAppManager $appManager,
116
-								IAvatarManager $avatarManager,
117
-								AccountManager $accountManager,
118
-								ISecureRandom $secureRandom,
119
-								NewUserMailHelper $newUserMailHelper) {
120
-		parent::__construct($appName, $request);
121
-		$this->userManager = $userManager;
122
-		$this->groupManager = $groupManager;
123
-		$this->userSession = $userSession;
124
-		$this->config = $config;
125
-		$this->isAdmin = $isAdmin;
126
-		$this->l10n = $l10n;
127
-		$this->log = $log;
128
-		$this->mailer = $mailer;
129
-		$this->avatarManager = $avatarManager;
130
-		$this->accountManager = $accountManager;
131
-		$this->secureRandom = $secureRandom;
132
-		$this->newUserMailHelper = $newUserMailHelper;
133
-
134
-		// check for encryption state - TODO see formatUserForIndex
135
-		$this->isEncryptionAppEnabled = $appManager->isEnabledForUser('encryption');
136
-		if($this->isEncryptionAppEnabled) {
137
-			// putting this directly in empty is possible in PHP 5.5+
138
-			$result = $config->getAppValue('encryption', 'recoveryAdminEnabled', 0);
139
-			$this->isRestoreEnabled = !empty($result);
140
-		}
141
-	}
142
-
143
-	/**
144
-	 * @param IUser $user
145
-	 * @param array $userGroups
146
-	 * @return array
147
-	 */
148
-	private function formatUserForIndex(IUser $user, array $userGroups = null) {
149
-
150
-		// TODO: eliminate this encryption specific code below and somehow
151
-		// hook in additional user info from other apps
152
-
153
-		// recovery isn't possible if admin or user has it disabled and encryption
154
-		// is enabled - so we eliminate the else paths in the conditional tree
155
-		// below
156
-		$restorePossible = false;
157
-
158
-		if ($this->isEncryptionAppEnabled) {
159
-			if ($this->isRestoreEnabled) {
160
-				// check for the users recovery setting
161
-				$recoveryMode = $this->config->getUserValue($user->getUID(), 'encryption', 'recoveryEnabled', '0');
162
-				// method call inside empty is possible with PHP 5.5+
163
-				$recoveryModeEnabled = !empty($recoveryMode);
164
-				if ($recoveryModeEnabled) {
165
-					// user also has recovery mode enabled
166
-					$restorePossible = true;
167
-				}
168
-			}
169
-		} else {
170
-			// recovery is possible if encryption is disabled (plain files are
171
-			// available)
172
-			$restorePossible = true;
173
-		}
174
-
175
-		$subAdminGroups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($user);
176
-		foreach($subAdminGroups as $key => $subAdminGroup) {
177
-			$subAdminGroups[$key] = $subAdminGroup->getGID();
178
-		}
179
-
180
-		$displayName = $user->getEMailAddress();
181
-		if (is_null($displayName)) {
182
-			$displayName = '';
183
-		}
184
-
185
-		$avatarAvailable = false;
186
-		try {
187
-			$avatarAvailable = $this->avatarManager->getAvatar($user->getUID())->exists();
188
-		} catch (\Exception $e) {
189
-			//No avatar yet
190
-		}
191
-
192
-		return [
193
-			'name' => $user->getUID(),
194
-			'displayname' => $user->getDisplayName(),
195
-			'groups' => (empty($userGroups)) ? $this->groupManager->getUserGroupIds($user) : $userGroups,
196
-			'subadmin' => $subAdminGroups,
197
-			'quota' => $user->getQuota(),
198
-			'storageLocation' => $user->getHome(),
199
-			'lastLogin' => $user->getLastLogin() * 1000,
200
-			'backend' => $user->getBackendClassName(),
201
-			'email' => $displayName,
202
-			'isRestoreDisabled' => !$restorePossible,
203
-			'isAvatarAvailable' => $avatarAvailable,
204
-			'isEnabled' => $user->isEnabled(),
205
-		];
206
-	}
207
-
208
-	/**
209
-	 * @param array $userIDs Array with schema [$uid => $displayName]
210
-	 * @return IUser[]
211
-	 */
212
-	private function getUsersForUID(array $userIDs) {
213
-		$users = [];
214
-		foreach ($userIDs as $uid => $displayName) {
215
-			$users[$uid] = $this->userManager->get($uid);
216
-		}
217
-		return $users;
218
-	}
219
-
220
-	/**
221
-	 * @NoAdminRequired
222
-	 *
223
-	 * @param int $offset
224
-	 * @param int $limit
225
-	 * @param string $gid GID to filter for
226
-	 * @param string $pattern Pattern to search for in the username
227
-	 * @param string $backend Backend to filter for (class-name)
228
-	 * @return DataResponse
229
-	 *
230
-	 * TODO: Tidy up and write unit tests - code is mainly static method calls
231
-	 */
232
-	public function index($offset = 0, $limit = 10, $gid = '', $pattern = '', $backend = '') {
233
-		// Remove backends
234
-		if(!empty($backend)) {
235
-			$activeBackends = $this->userManager->getBackends();
236
-			$this->userManager->clearBackends();
237
-			foreach($activeBackends as $singleActiveBackend) {
238
-				if($backend === get_class($singleActiveBackend)) {
239
-					$this->userManager->registerBackend($singleActiveBackend);
240
-					break;
241
-				}
242
-			}
243
-		}
244
-
245
-		$users = [];
246
-		if ($this->isAdmin) {
247
-			if($gid !== '' && $gid !== '_disabledUsers') {
248
-				$batch = $this->getUsersForUID($this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset));
249
-			} else {
250
-				$batch = $this->userManager->search($pattern, $limit, $offset);
251
-			}
252
-
253
-			foreach ($batch as $user) {
254
-				if( ($gid !== '_disabledUsers' && $user->isEnabled()) ||
255
-					($gid === '_disabledUsers' && !$user->isEnabled())
256
-				) {
257
-					$users[] = $this->formatUserForIndex($user);
258
-				}
259
-			}
260
-
261
-		} else {
262
-			$subAdminOfGroups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($this->userSession->getUser());
263
-			// New class returns IGroup[] so convert back
264
-			$gids = [];
265
-			foreach ($subAdminOfGroups as $group) {
266
-				$gids[] = $group->getGID();
267
-			}
268
-			$subAdminOfGroups = $gids;
269
-
270
-			// Set the $gid parameter to an empty value if the subadmin has no rights to access a specific group
271
-			if($gid !== '' && $gid !== '_disabledUsers' && !in_array($gid, $subAdminOfGroups)) {
272
-				$gid = '';
273
-			}
274
-
275
-			// Batch all groups the user is subadmin of when a group is specified
276
-			$batch = [];
277
-			if($gid === '') {
278
-				foreach($subAdminOfGroups as $group) {
279
-					$groupUsers = $this->groupManager->displayNamesInGroup($group, $pattern, $limit, $offset);
280
-
281
-					foreach($groupUsers as $uid => $displayName) {
282
-						$batch[$uid] = $displayName;
283
-					}
284
-				}
285
-			} else {
286
-				$batch = $this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset);
287
-			}
288
-			$batch = $this->getUsersForUID($batch);
289
-
290
-			foreach ($batch as $user) {
291
-				// Only add the groups, this user is a subadmin of
292
-				$userGroups = array_values(array_intersect(
293
-					$this->groupManager->getUserGroupIds($user),
294
-					$subAdminOfGroups
295
-				));
296
-				if( ($gid !== '_disabledUsers' && $user->isEnabled()) ||
297
-					($gid === '_disabledUsers' && !$user->isEnabled())
298
-				) {
299
-					$users[] = $this->formatUserForIndex($user, $userGroups);
300
-				}
301
-			}
302
-		}
303
-
304
-		return new DataResponse($users);
305
-	}
306
-
307
-	/**
308
-	 * @NoAdminRequired
309
-	 * @PasswordConfirmationRequired
310
-	 *
311
-	 * @param string $username
312
-	 * @param string $password
313
-	 * @param array $groups
314
-	 * @param string $email
315
-	 * @return DataResponse
316
-	 */
317
-	public function create($username, $password, array $groups=[], $email='') {
318
-		if($email !== '' && !$this->mailer->validateMailAddress($email)) {
319
-			return new DataResponse(
320
-				[
321
-					'message' => (string)$this->l10n->t('Invalid mail address')
322
-				],
323
-				Http::STATUS_UNPROCESSABLE_ENTITY
324
-			);
325
-		}
326
-
327
-		$currentUser = $this->userSession->getUser();
328
-
329
-		if (!$this->isAdmin) {
330
-			if (!empty($groups)) {
331
-				foreach ($groups as $key => $group) {
332
-					$groupObject = $this->groupManager->get($group);
333
-					if($groupObject === null) {
334
-						unset($groups[$key]);
335
-						continue;
336
-					}
337
-
338
-					if (!$this->groupManager->getSubAdmin()->isSubAdminofGroup($currentUser, $groupObject)) {
339
-						unset($groups[$key]);
340
-					}
341
-				}
342
-			}
343
-
344
-			if (empty($groups)) {
345
-				return new DataResponse(
346
-					[
347
-						'message' => $this->l10n->t('No valid group selected'),
348
-					],
349
-					Http::STATUS_FORBIDDEN
350
-				);
351
-			}
352
-		}
353
-
354
-		if ($this->userManager->userExists($username)) {
355
-			return new DataResponse(
356
-				[
357
-					'message' => (string)$this->l10n->t('A user with that name already exists.')
358
-				],
359
-				Http::STATUS_CONFLICT
360
-			);
361
-		}
362
-
363
-		$generatePasswordResetToken = false;
364
-		if ($password === '') {
365
-			if ($email === '') {
366
-				return new DataResponse(
367
-					[
368
-						'message' => (string)$this->l10n->t('To send a password link to the user an email address is required.')
369
-					],
370
-					Http::STATUS_UNPROCESSABLE_ENTITY
371
-				);
372
-			}
373
-
374
-			$password = $this->secureRandom->generate(32);
375
-			$generatePasswordResetToken = true;
376
-		}
377
-
378
-		try {
379
-			$user = $this->userManager->createUser($username, $password);
380
-		} catch (\Exception $exception) {
381
-			$message = $exception->getMessage();
382
-			if (!$message) {
383
-				$message = $this->l10n->t('Unable to create user.');
384
-			}
385
-			return new DataResponse(
386
-				[
387
-					'message' => (string) $message,
388
-				],
389
-				Http::STATUS_FORBIDDEN
390
-			);
391
-		}
392
-
393
-		if($user instanceof IUser) {
394
-			if($groups !== null) {
395
-				foreach($groups as $groupName) {
396
-					$group = $this->groupManager->get($groupName);
397
-
398
-					if(empty($group)) {
399
-						$group = $this->groupManager->createGroup($groupName);
400
-					}
401
-					$group->addUser($user);
402
-				}
403
-			}
404
-			/**
405
-			 * Send new user mail only if a mail is set
406
-			 */
407
-			if($email !== '') {
408
-				$user->setEMailAddress($email);
409
-				try {
410
-					$emailTemplate = $this->newUserMailHelper->generateTemplate($user, $generatePasswordResetToken);
411
-					$this->newUserMailHelper->sendMail($user, $emailTemplate);
412
-				} catch(\Exception $e) {
413
-					$this->log->error("Can't send new user mail to $email: " . $e->getMessage(), ['app' => 'settings']);
414
-				}
415
-			}
416
-			// fetch users groups
417
-			$userGroups = $this->groupManager->getUserGroupIds($user);
418
-
419
-			return new DataResponse(
420
-				$this->formatUserForIndex($user, $userGroups),
421
-				Http::STATUS_CREATED
422
-			);
423
-		}
424
-
425
-		return new DataResponse(
426
-			[
427
-				'message' => (string) $this->l10n->t('Unable to create user.')
428
-			],
429
-			Http::STATUS_FORBIDDEN
430
-		);
431
-
432
-	}
433
-
434
-	/**
435
-	 * @NoAdminRequired
436
-	 * @PasswordConfirmationRequired
437
-	 *
438
-	 * @param string $id
439
-	 * @return DataResponse
440
-	 */
441
-	public function destroy($id) {
442
-		$userId = $this->userSession->getUser()->getUID();
443
-		$user = $this->userManager->get($id);
444
-
445
-		if($userId === $id) {
446
-			return new DataResponse(
447
-				[
448
-					'status' => 'error',
449
-					'data' => [
450
-						'message' => (string) $this->l10n->t('Unable to delete user.')
451
-					]
452
-				],
453
-				Http::STATUS_FORBIDDEN
454
-			);
455
-		}
456
-
457
-		if(!$this->isAdmin && !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)) {
458
-			return new DataResponse(
459
-				[
460
-					'status' => 'error',
461
-					'data' => [
462
-						'message' => (string)$this->l10n->t('Authentication error')
463
-					]
464
-				],
465
-				Http::STATUS_FORBIDDEN
466
-			);
467
-		}
468
-
469
-		if($user) {
470
-			if($user->delete()) {
471
-				return new DataResponse(
472
-					[
473
-						'status' => 'success',
474
-						'data' => [
475
-							'username' => $id
476
-						]
477
-					],
478
-					Http::STATUS_NO_CONTENT
479
-				);
480
-			}
481
-		}
482
-
483
-		return new DataResponse(
484
-			[
485
-				'status' => 'error',
486
-				'data' => [
487
-					'message' => (string)$this->l10n->t('Unable to delete user.')
488
-				]
489
-			],
490
-			Http::STATUS_FORBIDDEN
491
-		);
492
-	}
493
-
494
-	/**
495
-	 * @NoAdminRequired
496
-	 *
497
-	 * @param string $id
498
-	 * @param int $enabled
499
-	 * @return DataResponse
500
-	 */
501
-	public function setEnabled($id, $enabled) {
502
-		$enabled = (bool)$enabled;
503
-		if($enabled) {
504
-			$errorMsgGeneral = (string) $this->l10n->t('Error while enabling user.');
505
-		} else {
506
-			$errorMsgGeneral = (string) $this->l10n->t('Error while disabling user.');
507
-		}
508
-
509
-		$userId = $this->userSession->getUser()->getUID();
510
-		$user = $this->userManager->get($id);
511
-
512
-		if ($userId === $id) {
513
-			return new DataResponse(
514
-				[
515
-					'status' => 'error',
516
-					'data' => [
517
-						'message' => $errorMsgGeneral
518
-					]
519
-				], Http::STATUS_FORBIDDEN
520
-			);
521
-		}
522
-
523
-		if($user) {
524
-			if (!$this->isAdmin && !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)) {
525
-				return new DataResponse(
526
-					[
527
-						'status' => 'error',
528
-						'data' => [
529
-							'message' => (string) $this->l10n->t('Authentication error')
530
-						]
531
-					],
532
-					Http::STATUS_FORBIDDEN
533
-				);
534
-			}
535
-
536
-			$user->setEnabled($enabled);
537
-			return new DataResponse(
538
-				[
539
-					'status' => 'success',
540
-					'data' => [
541
-						'username' => $id,
542
-						'enabled' => $enabled
543
-					]
544
-				]
545
-			);
546
-		} else {
547
-			return new DataResponse(
548
-				[
549
-					'status' => 'error',
550
-					'data' => [
551
-						'message' => $errorMsgGeneral
552
-					]
553
-				],
554
-				Http::STATUS_FORBIDDEN
555
-			);
556
-		}
557
-
558
-	}
559
-
560
-	/**
561
-	 * Set the mail address of a user
562
-	 *
563
-	 * @NoAdminRequired
564
-	 * @NoSubadminRequired
565
-	 * @PasswordConfirmationRequired
566
-	 *
567
-	 * @param string $avatarScope
568
-	 * @param string $displayname
569
-	 * @param string $displaynameScope
570
-	 * @param string $phone
571
-	 * @param string $phoneScope
572
-	 * @param string $email
573
-	 * @param string $emailScope
574
-	 * @param string $website
575
-	 * @param string $websiteScope
576
-	 * @param string $address
577
-	 * @param string $addressScope
578
-	 * @param string $twitter
579
-	 * @param string $twitterScope
580
-	 * @return DataResponse
581
-	 */
582
-	public function setUserSettings($avatarScope,
583
-									$displayname,
584
-									$displaynameScope,
585
-									$phone,
586
-									$phoneScope,
587
-									$email,
588
-									$emailScope,
589
-									$website,
590
-									$websiteScope,
591
-									$address,
592
-									$addressScope,
593
-									$twitter,
594
-									$twitterScope
595
-	) {
596
-
597
-		if (!empty($email) && !$this->mailer->validateMailAddress($email)) {
598
-			return new DataResponse(
599
-				[
600
-					'status' => 'error',
601
-					'data' => [
602
-						'message' => (string) $this->l10n->t('Invalid mail address')
603
-					]
604
-				],
605
-				Http::STATUS_UNPROCESSABLE_ENTITY
606
-			);
607
-		}
608
-
609
-		$data = [
610
-			AccountManager::PROPERTY_AVATAR =>  ['scope' => $avatarScope],
611
-			AccountManager::PROPERTY_DISPLAYNAME => ['value' => $displayname, 'scope' => $displaynameScope],
612
-			AccountManager::PROPERTY_EMAIL=> ['value' => $email, 'scope' => $emailScope],
613
-			AccountManager::PROPERTY_WEBSITE => ['value' => $website, 'scope' => $websiteScope],
614
-			AccountManager::PROPERTY_ADDRESS => ['value' => $address, 'scope' => $addressScope],
615
-			AccountManager::PROPERTY_PHONE => ['value' => $phone, 'scope' => $phoneScope],
616
-			AccountManager::PROPERTY_TWITTER => ['value' => $twitter, 'scope' => $twitterScope]
617
-		];
618
-
619
-		$user = $this->userSession->getUser();
620
-
621
-		try {
622
-			$this->saveUserSettings($user, $data);
623
-			return new DataResponse(
624
-				[
625
-					'status' => 'success',
626
-					'data' => [
627
-						'userId' => $user->getUID(),
628
-						'avatarScope' => $avatarScope,
629
-						'displayname' => $displayname,
630
-						'displaynameScope' => $displaynameScope,
631
-						'email' => $email,
632
-						'emailScope' => $emailScope,
633
-						'website' => $website,
634
-						'websiteScope' => $websiteScope,
635
-						'address' => $address,
636
-						'addressScope' => $addressScope,
637
-						'message' => (string) $this->l10n->t('Settings saved')
638
-					]
639
-				],
640
-				Http::STATUS_OK
641
-			);
642
-		} catch (ForbiddenException $e) {
643
-			return new DataResponse([
644
-				'status' => 'error',
645
-				'data' => [
646
-					'message' => $e->getMessage()
647
-				],
648
-			]);
649
-		}
650
-
651
-	}
652
-
653
-
654
-	/**
655
-	 * update account manager with new user data
656
-	 *
657
-	 * @param IUser $user
658
-	 * @param array $data
659
-	 * @throws ForbiddenException
660
-	 */
661
-	protected function saveUserSettings(IUser $user, $data) {
662
-
663
-		// keep the user back-end up-to-date with the latest display name and email
664
-		// address
665
-		$oldDisplayName = $user->getDisplayName();
666
-		$oldDisplayName = is_null($oldDisplayName) ? '' : $oldDisplayName;
667
-		if (isset($data[AccountManager::PROPERTY_DISPLAYNAME]['value'])
668
-			&& $oldDisplayName !== $data[AccountManager::PROPERTY_DISPLAYNAME]['value']
669
-		) {
670
-			$result = $user->setDisplayName($data[AccountManager::PROPERTY_DISPLAYNAME]['value']);
671
-			if ($result === false) {
672
-				throw new ForbiddenException($this->l10n->t('Unable to change full name'));
673
-			}
674
-		}
675
-
676
-		$oldEmailAddress = $user->getEMailAddress();
677
-		$oldEmailAddress = is_null($oldEmailAddress) ? '' : $oldEmailAddress;
678
-		if (isset($data[AccountManager::PROPERTY_EMAIL]['value'])
679
-			&& $oldEmailAddress !== $data[AccountManager::PROPERTY_EMAIL]['value']
680
-		) {
681
-			// this is the only permission a backend provides and is also used
682
-			// for the permission of setting a email address
683
-			if (!$user->canChangeDisplayName()) {
684
-				throw new ForbiddenException($this->l10n->t('Unable to change email address'));
685
-			}
686
-			$user->setEMailAddress($data[AccountManager::PROPERTY_EMAIL]['value']);
687
-		}
688
-
689
-		$this->accountManager->updateUser($user, $data);
690
-	}
691
-
692
-	/**
693
-	 * Count all unique users visible for the current admin/subadmin.
694
-	 *
695
-	 * @NoAdminRequired
696
-	 *
697
-	 * @return DataResponse
698
-	 */
699
-	public function stats() {
700
-		$userCount = 0;
701
-		if ($this->isAdmin) {
702
-			$countByBackend = $this->userManager->countUsers();
703
-
704
-			if (!empty($countByBackend)) {
705
-				foreach ($countByBackend as $count) {
706
-					$userCount += $count;
707
-				}
708
-			}
709
-		} else {
710
-			$groups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($this->userSession->getUser());
711
-
712
-			$uniqueUsers = [];
713
-			foreach ($groups as $group) {
714
-				foreach($group->getUsers() as $uid => $displayName) {
715
-					$uniqueUsers[$uid] = true;
716
-				}
717
-			}
718
-
719
-			$userCount = count($uniqueUsers);
720
-		}
721
-
722
-		return new DataResponse(
723
-			[
724
-				'totalUsers' => $userCount
725
-			]
726
-		);
727
-	}
728
-
729
-
730
-	/**
731
-	 * Set the displayName of a user
732
-	 *
733
-	 * @NoAdminRequired
734
-	 * @NoSubadminRequired
735
-	 * @PasswordConfirmationRequired
736
-	 * @todo merge into saveUserSettings
737
-	 *
738
-	 * @param string $username
739
-	 * @param string $displayName
740
-	 * @return DataResponse
741
-	 */
742
-	public function setDisplayName($username, $displayName) {
743
-		$currentUser = $this->userSession->getUser();
744
-		$user = $this->userManager->get($username);
745
-
746
-		if ($user === null ||
747
-			!$user->canChangeDisplayName() ||
748
-			(
749
-				!$this->groupManager->isAdmin($currentUser->getUID()) &&
750
-				!$this->groupManager->getSubAdmin()->isUserAccessible($currentUser, $user) &&
751
-				$currentUser->getUID() !== $username
752
-
753
-			)
754
-		) {
755
-			return new DataResponse([
756
-				'status' => 'error',
757
-				'data' => [
758
-					'message' => $this->l10n->t('Authentication error'),
759
-				],
760
-			]);
761
-		}
762
-
763
-		$userData = $this->accountManager->getUser($user);
764
-		$userData[AccountManager::PROPERTY_DISPLAYNAME]['value'] = $displayName;
765
-
766
-
767
-		try {
768
-			$this->saveUserSettings($user, $userData);
769
-			return new DataResponse([
770
-				'status' => 'success',
771
-				'data' => [
772
-					'message' => $this->l10n->t('Your full name has been changed.'),
773
-					'username' => $username,
774
-					'displayName' => $displayName,
775
-				],
776
-			]);
777
-		} catch (ForbiddenException $e) {
778
-			return new DataResponse([
779
-				'status' => 'error',
780
-				'data' => [
781
-					'message' => $e->getMessage(),
782
-					'displayName' => $user->getDisplayName(),
783
-				],
784
-			]);
785
-		}
786
-	}
787
-
788
-	/**
789
-	 * Set the mail address of a user
790
-	 *
791
-	 * @NoAdminRequired
792
-	 * @NoSubadminRequired
793
-	 * @PasswordConfirmationRequired
794
-	 *
795
-	 * @param string $id
796
-	 * @param string $mailAddress
797
-	 * @return DataResponse
798
-	 */
799
-	public function setEMailAddress($id, $mailAddress) {
800
-		$user = $this->userManager->get($id);
801
-		if (!$this->isAdmin
802
-			&& !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)
803
-		) {
804
-			return new DataResponse(
805
-				[
806
-					'status' => 'error',
807
-					'data' => [
808
-						'message' => (string) $this->l10n->t('Forbidden')
809
-					]
810
-				],
811
-				Http::STATUS_FORBIDDEN
812
-			);
813
-		}
814
-
815
-		if($mailAddress !== '' && !$this->mailer->validateMailAddress($mailAddress)) {
816
-			return new DataResponse(
817
-				[
818
-					'status' => 'error',
819
-					'data' => [
820
-						'message' => (string) $this->l10n->t('Invalid mail address')
821
-					]
822
-				],
823
-				Http::STATUS_UNPROCESSABLE_ENTITY
824
-			);
825
-		}
826
-
827
-		if (!$user) {
828
-			return new DataResponse(
829
-				[
830
-					'status' => 'error',
831
-					'data' => [
832
-						'message' => (string) $this->l10n->t('Invalid user')
833
-					]
834
-				],
835
-				Http::STATUS_UNPROCESSABLE_ENTITY
836
-			);
837
-		}
838
-		// this is the only permission a backend provides and is also used
839
-		// for the permission of setting a email address
840
-		if (!$user->canChangeDisplayName()) {
841
-			return new DataResponse(
842
-				[
843
-					'status' => 'error',
844
-					'data' => [
845
-						'message' => (string) $this->l10n->t('Unable to change mail address')
846
-					]
847
-				],
848
-				Http::STATUS_FORBIDDEN
849
-			);
850
-		}
851
-
852
-		$userData = $this->accountManager->getUser($user);
853
-		$userData[AccountManager::PROPERTY_EMAIL]['value'] = $mailAddress;
854
-
855
-		try {
856
-			$this->saveUserSettings($user, $userData);
857
-			return new DataResponse(
858
-				[
859
-					'status' => 'success',
860
-					'data' => [
861
-						'username' => $id,
862
-						'mailAddress' => $mailAddress,
863
-						'message' => (string) $this->l10n->t('Email saved')
864
-					]
865
-				],
866
-				Http::STATUS_OK
867
-			);
868
-		} catch (ForbiddenException $e) {
869
-			return new DataResponse([
870
-				'status' => 'error',
871
-				'data' => [
872
-					'message' => $e->getMessage()
873
-				],
874
-			]);
875
-		}
876
-	}
57
+    /** @var IL10N */
58
+    private $l10n;
59
+    /** @var IUserSession */
60
+    private $userSession;
61
+    /** @var bool */
62
+    private $isAdmin;
63
+    /** @var IUserManager */
64
+    private $userManager;
65
+    /** @var IGroupManager */
66
+    private $groupManager;
67
+    /** @var IConfig */
68
+    private $config;
69
+    /** @var ILogger */
70
+    private $log;
71
+    /** @var IMailer */
72
+    private $mailer;
73
+    /** @var bool contains the state of the encryption app */
74
+    private $isEncryptionAppEnabled;
75
+    /** @var bool contains the state of the admin recovery setting */
76
+    private $isRestoreEnabled = false;
77
+    /** @var IAvatarManager */
78
+    private $avatarManager;
79
+    /** @var AccountManager */
80
+    private $accountManager;
81
+    /** @var ISecureRandom */
82
+    private $secureRandom;
83
+    /** @var NewUserMailHelper */
84
+    private $newUserMailHelper;
85
+
86
+    /**
87
+     * @param string $appName
88
+     * @param IRequest $request
89
+     * @param IUserManager $userManager
90
+     * @param IGroupManager $groupManager
91
+     * @param IUserSession $userSession
92
+     * @param IConfig $config
93
+     * @param bool $isAdmin
94
+     * @param IL10N $l10n
95
+     * @param ILogger $log
96
+     * @param IMailer $mailer
97
+     * @param IURLGenerator $urlGenerator
98
+     * @param IAppManager $appManager
99
+     * @param IAvatarManager $avatarManager
100
+     * @param AccountManager $accountManager
101
+     * @param ISecureRandom $secureRandom
102
+     * @param NewUserMailHelper $newUserMailHelper
103
+     */
104
+    public function __construct($appName,
105
+                                IRequest $request,
106
+                                IUserManager $userManager,
107
+                                IGroupManager $groupManager,
108
+                                IUserSession $userSession,
109
+                                IConfig $config,
110
+                                $isAdmin,
111
+                                IL10N $l10n,
112
+                                ILogger $log,
113
+                                IMailer $mailer,
114
+                                IURLGenerator $urlGenerator,
115
+                                IAppManager $appManager,
116
+                                IAvatarManager $avatarManager,
117
+                                AccountManager $accountManager,
118
+                                ISecureRandom $secureRandom,
119
+                                NewUserMailHelper $newUserMailHelper) {
120
+        parent::__construct($appName, $request);
121
+        $this->userManager = $userManager;
122
+        $this->groupManager = $groupManager;
123
+        $this->userSession = $userSession;
124
+        $this->config = $config;
125
+        $this->isAdmin = $isAdmin;
126
+        $this->l10n = $l10n;
127
+        $this->log = $log;
128
+        $this->mailer = $mailer;
129
+        $this->avatarManager = $avatarManager;
130
+        $this->accountManager = $accountManager;
131
+        $this->secureRandom = $secureRandom;
132
+        $this->newUserMailHelper = $newUserMailHelper;
133
+
134
+        // check for encryption state - TODO see formatUserForIndex
135
+        $this->isEncryptionAppEnabled = $appManager->isEnabledForUser('encryption');
136
+        if($this->isEncryptionAppEnabled) {
137
+            // putting this directly in empty is possible in PHP 5.5+
138
+            $result = $config->getAppValue('encryption', 'recoveryAdminEnabled', 0);
139
+            $this->isRestoreEnabled = !empty($result);
140
+        }
141
+    }
142
+
143
+    /**
144
+     * @param IUser $user
145
+     * @param array $userGroups
146
+     * @return array
147
+     */
148
+    private function formatUserForIndex(IUser $user, array $userGroups = null) {
149
+
150
+        // TODO: eliminate this encryption specific code below and somehow
151
+        // hook in additional user info from other apps
152
+
153
+        // recovery isn't possible if admin or user has it disabled and encryption
154
+        // is enabled - so we eliminate the else paths in the conditional tree
155
+        // below
156
+        $restorePossible = false;
157
+
158
+        if ($this->isEncryptionAppEnabled) {
159
+            if ($this->isRestoreEnabled) {
160
+                // check for the users recovery setting
161
+                $recoveryMode = $this->config->getUserValue($user->getUID(), 'encryption', 'recoveryEnabled', '0');
162
+                // method call inside empty is possible with PHP 5.5+
163
+                $recoveryModeEnabled = !empty($recoveryMode);
164
+                if ($recoveryModeEnabled) {
165
+                    // user also has recovery mode enabled
166
+                    $restorePossible = true;
167
+                }
168
+            }
169
+        } else {
170
+            // recovery is possible if encryption is disabled (plain files are
171
+            // available)
172
+            $restorePossible = true;
173
+        }
174
+
175
+        $subAdminGroups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($user);
176
+        foreach($subAdminGroups as $key => $subAdminGroup) {
177
+            $subAdminGroups[$key] = $subAdminGroup->getGID();
178
+        }
179
+
180
+        $displayName = $user->getEMailAddress();
181
+        if (is_null($displayName)) {
182
+            $displayName = '';
183
+        }
184
+
185
+        $avatarAvailable = false;
186
+        try {
187
+            $avatarAvailable = $this->avatarManager->getAvatar($user->getUID())->exists();
188
+        } catch (\Exception $e) {
189
+            //No avatar yet
190
+        }
191
+
192
+        return [
193
+            'name' => $user->getUID(),
194
+            'displayname' => $user->getDisplayName(),
195
+            'groups' => (empty($userGroups)) ? $this->groupManager->getUserGroupIds($user) : $userGroups,
196
+            'subadmin' => $subAdminGroups,
197
+            'quota' => $user->getQuota(),
198
+            'storageLocation' => $user->getHome(),
199
+            'lastLogin' => $user->getLastLogin() * 1000,
200
+            'backend' => $user->getBackendClassName(),
201
+            'email' => $displayName,
202
+            'isRestoreDisabled' => !$restorePossible,
203
+            'isAvatarAvailable' => $avatarAvailable,
204
+            'isEnabled' => $user->isEnabled(),
205
+        ];
206
+    }
207
+
208
+    /**
209
+     * @param array $userIDs Array with schema [$uid => $displayName]
210
+     * @return IUser[]
211
+     */
212
+    private function getUsersForUID(array $userIDs) {
213
+        $users = [];
214
+        foreach ($userIDs as $uid => $displayName) {
215
+            $users[$uid] = $this->userManager->get($uid);
216
+        }
217
+        return $users;
218
+    }
219
+
220
+    /**
221
+     * @NoAdminRequired
222
+     *
223
+     * @param int $offset
224
+     * @param int $limit
225
+     * @param string $gid GID to filter for
226
+     * @param string $pattern Pattern to search for in the username
227
+     * @param string $backend Backend to filter for (class-name)
228
+     * @return DataResponse
229
+     *
230
+     * TODO: Tidy up and write unit tests - code is mainly static method calls
231
+     */
232
+    public function index($offset = 0, $limit = 10, $gid = '', $pattern = '', $backend = '') {
233
+        // Remove backends
234
+        if(!empty($backend)) {
235
+            $activeBackends = $this->userManager->getBackends();
236
+            $this->userManager->clearBackends();
237
+            foreach($activeBackends as $singleActiveBackend) {
238
+                if($backend === get_class($singleActiveBackend)) {
239
+                    $this->userManager->registerBackend($singleActiveBackend);
240
+                    break;
241
+                }
242
+            }
243
+        }
244
+
245
+        $users = [];
246
+        if ($this->isAdmin) {
247
+            if($gid !== '' && $gid !== '_disabledUsers') {
248
+                $batch = $this->getUsersForUID($this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset));
249
+            } else {
250
+                $batch = $this->userManager->search($pattern, $limit, $offset);
251
+            }
252
+
253
+            foreach ($batch as $user) {
254
+                if( ($gid !== '_disabledUsers' && $user->isEnabled()) ||
255
+                    ($gid === '_disabledUsers' && !$user->isEnabled())
256
+                ) {
257
+                    $users[] = $this->formatUserForIndex($user);
258
+                }
259
+            }
260
+
261
+        } else {
262
+            $subAdminOfGroups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($this->userSession->getUser());
263
+            // New class returns IGroup[] so convert back
264
+            $gids = [];
265
+            foreach ($subAdminOfGroups as $group) {
266
+                $gids[] = $group->getGID();
267
+            }
268
+            $subAdminOfGroups = $gids;
269
+
270
+            // Set the $gid parameter to an empty value if the subadmin has no rights to access a specific group
271
+            if($gid !== '' && $gid !== '_disabledUsers' && !in_array($gid, $subAdminOfGroups)) {
272
+                $gid = '';
273
+            }
274
+
275
+            // Batch all groups the user is subadmin of when a group is specified
276
+            $batch = [];
277
+            if($gid === '') {
278
+                foreach($subAdminOfGroups as $group) {
279
+                    $groupUsers = $this->groupManager->displayNamesInGroup($group, $pattern, $limit, $offset);
280
+
281
+                    foreach($groupUsers as $uid => $displayName) {
282
+                        $batch[$uid] = $displayName;
283
+                    }
284
+                }
285
+            } else {
286
+                $batch = $this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset);
287
+            }
288
+            $batch = $this->getUsersForUID($batch);
289
+
290
+            foreach ($batch as $user) {
291
+                // Only add the groups, this user is a subadmin of
292
+                $userGroups = array_values(array_intersect(
293
+                    $this->groupManager->getUserGroupIds($user),
294
+                    $subAdminOfGroups
295
+                ));
296
+                if( ($gid !== '_disabledUsers' && $user->isEnabled()) ||
297
+                    ($gid === '_disabledUsers' && !$user->isEnabled())
298
+                ) {
299
+                    $users[] = $this->formatUserForIndex($user, $userGroups);
300
+                }
301
+            }
302
+        }
303
+
304
+        return new DataResponse($users);
305
+    }
306
+
307
+    /**
308
+     * @NoAdminRequired
309
+     * @PasswordConfirmationRequired
310
+     *
311
+     * @param string $username
312
+     * @param string $password
313
+     * @param array $groups
314
+     * @param string $email
315
+     * @return DataResponse
316
+     */
317
+    public function create($username, $password, array $groups=[], $email='') {
318
+        if($email !== '' && !$this->mailer->validateMailAddress($email)) {
319
+            return new DataResponse(
320
+                [
321
+                    'message' => (string)$this->l10n->t('Invalid mail address')
322
+                ],
323
+                Http::STATUS_UNPROCESSABLE_ENTITY
324
+            );
325
+        }
326
+
327
+        $currentUser = $this->userSession->getUser();
328
+
329
+        if (!$this->isAdmin) {
330
+            if (!empty($groups)) {
331
+                foreach ($groups as $key => $group) {
332
+                    $groupObject = $this->groupManager->get($group);
333
+                    if($groupObject === null) {
334
+                        unset($groups[$key]);
335
+                        continue;
336
+                    }
337
+
338
+                    if (!$this->groupManager->getSubAdmin()->isSubAdminofGroup($currentUser, $groupObject)) {
339
+                        unset($groups[$key]);
340
+                    }
341
+                }
342
+            }
343
+
344
+            if (empty($groups)) {
345
+                return new DataResponse(
346
+                    [
347
+                        'message' => $this->l10n->t('No valid group selected'),
348
+                    ],
349
+                    Http::STATUS_FORBIDDEN
350
+                );
351
+            }
352
+        }
353
+
354
+        if ($this->userManager->userExists($username)) {
355
+            return new DataResponse(
356
+                [
357
+                    'message' => (string)$this->l10n->t('A user with that name already exists.')
358
+                ],
359
+                Http::STATUS_CONFLICT
360
+            );
361
+        }
362
+
363
+        $generatePasswordResetToken = false;
364
+        if ($password === '') {
365
+            if ($email === '') {
366
+                return new DataResponse(
367
+                    [
368
+                        'message' => (string)$this->l10n->t('To send a password link to the user an email address is required.')
369
+                    ],
370
+                    Http::STATUS_UNPROCESSABLE_ENTITY
371
+                );
372
+            }
373
+
374
+            $password = $this->secureRandom->generate(32);
375
+            $generatePasswordResetToken = true;
376
+        }
377
+
378
+        try {
379
+            $user = $this->userManager->createUser($username, $password);
380
+        } catch (\Exception $exception) {
381
+            $message = $exception->getMessage();
382
+            if (!$message) {
383
+                $message = $this->l10n->t('Unable to create user.');
384
+            }
385
+            return new DataResponse(
386
+                [
387
+                    'message' => (string) $message,
388
+                ],
389
+                Http::STATUS_FORBIDDEN
390
+            );
391
+        }
392
+
393
+        if($user instanceof IUser) {
394
+            if($groups !== null) {
395
+                foreach($groups as $groupName) {
396
+                    $group = $this->groupManager->get($groupName);
397
+
398
+                    if(empty($group)) {
399
+                        $group = $this->groupManager->createGroup($groupName);
400
+                    }
401
+                    $group->addUser($user);
402
+                }
403
+            }
404
+            /**
405
+             * Send new user mail only if a mail is set
406
+             */
407
+            if($email !== '') {
408
+                $user->setEMailAddress($email);
409
+                try {
410
+                    $emailTemplate = $this->newUserMailHelper->generateTemplate($user, $generatePasswordResetToken);
411
+                    $this->newUserMailHelper->sendMail($user, $emailTemplate);
412
+                } catch(\Exception $e) {
413
+                    $this->log->error("Can't send new user mail to $email: " . $e->getMessage(), ['app' => 'settings']);
414
+                }
415
+            }
416
+            // fetch users groups
417
+            $userGroups = $this->groupManager->getUserGroupIds($user);
418
+
419
+            return new DataResponse(
420
+                $this->formatUserForIndex($user, $userGroups),
421
+                Http::STATUS_CREATED
422
+            );
423
+        }
424
+
425
+        return new DataResponse(
426
+            [
427
+                'message' => (string) $this->l10n->t('Unable to create user.')
428
+            ],
429
+            Http::STATUS_FORBIDDEN
430
+        );
431
+
432
+    }
433
+
434
+    /**
435
+     * @NoAdminRequired
436
+     * @PasswordConfirmationRequired
437
+     *
438
+     * @param string $id
439
+     * @return DataResponse
440
+     */
441
+    public function destroy($id) {
442
+        $userId = $this->userSession->getUser()->getUID();
443
+        $user = $this->userManager->get($id);
444
+
445
+        if($userId === $id) {
446
+            return new DataResponse(
447
+                [
448
+                    'status' => 'error',
449
+                    'data' => [
450
+                        'message' => (string) $this->l10n->t('Unable to delete user.')
451
+                    ]
452
+                ],
453
+                Http::STATUS_FORBIDDEN
454
+            );
455
+        }
456
+
457
+        if(!$this->isAdmin && !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)) {
458
+            return new DataResponse(
459
+                [
460
+                    'status' => 'error',
461
+                    'data' => [
462
+                        'message' => (string)$this->l10n->t('Authentication error')
463
+                    ]
464
+                ],
465
+                Http::STATUS_FORBIDDEN
466
+            );
467
+        }
468
+
469
+        if($user) {
470
+            if($user->delete()) {
471
+                return new DataResponse(
472
+                    [
473
+                        'status' => 'success',
474
+                        'data' => [
475
+                            'username' => $id
476
+                        ]
477
+                    ],
478
+                    Http::STATUS_NO_CONTENT
479
+                );
480
+            }
481
+        }
482
+
483
+        return new DataResponse(
484
+            [
485
+                'status' => 'error',
486
+                'data' => [
487
+                    'message' => (string)$this->l10n->t('Unable to delete user.')
488
+                ]
489
+            ],
490
+            Http::STATUS_FORBIDDEN
491
+        );
492
+    }
493
+
494
+    /**
495
+     * @NoAdminRequired
496
+     *
497
+     * @param string $id
498
+     * @param int $enabled
499
+     * @return DataResponse
500
+     */
501
+    public function setEnabled($id, $enabled) {
502
+        $enabled = (bool)$enabled;
503
+        if($enabled) {
504
+            $errorMsgGeneral = (string) $this->l10n->t('Error while enabling user.');
505
+        } else {
506
+            $errorMsgGeneral = (string) $this->l10n->t('Error while disabling user.');
507
+        }
508
+
509
+        $userId = $this->userSession->getUser()->getUID();
510
+        $user = $this->userManager->get($id);
511
+
512
+        if ($userId === $id) {
513
+            return new DataResponse(
514
+                [
515
+                    'status' => 'error',
516
+                    'data' => [
517
+                        'message' => $errorMsgGeneral
518
+                    ]
519
+                ], Http::STATUS_FORBIDDEN
520
+            );
521
+        }
522
+
523
+        if($user) {
524
+            if (!$this->isAdmin && !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)) {
525
+                return new DataResponse(
526
+                    [
527
+                        'status' => 'error',
528
+                        'data' => [
529
+                            'message' => (string) $this->l10n->t('Authentication error')
530
+                        ]
531
+                    ],
532
+                    Http::STATUS_FORBIDDEN
533
+                );
534
+            }
535
+
536
+            $user->setEnabled($enabled);
537
+            return new DataResponse(
538
+                [
539
+                    'status' => 'success',
540
+                    'data' => [
541
+                        'username' => $id,
542
+                        'enabled' => $enabled
543
+                    ]
544
+                ]
545
+            );
546
+        } else {
547
+            return new DataResponse(
548
+                [
549
+                    'status' => 'error',
550
+                    'data' => [
551
+                        'message' => $errorMsgGeneral
552
+                    ]
553
+                ],
554
+                Http::STATUS_FORBIDDEN
555
+            );
556
+        }
557
+
558
+    }
559
+
560
+    /**
561
+     * Set the mail address of a user
562
+     *
563
+     * @NoAdminRequired
564
+     * @NoSubadminRequired
565
+     * @PasswordConfirmationRequired
566
+     *
567
+     * @param string $avatarScope
568
+     * @param string $displayname
569
+     * @param string $displaynameScope
570
+     * @param string $phone
571
+     * @param string $phoneScope
572
+     * @param string $email
573
+     * @param string $emailScope
574
+     * @param string $website
575
+     * @param string $websiteScope
576
+     * @param string $address
577
+     * @param string $addressScope
578
+     * @param string $twitter
579
+     * @param string $twitterScope
580
+     * @return DataResponse
581
+     */
582
+    public function setUserSettings($avatarScope,
583
+                                    $displayname,
584
+                                    $displaynameScope,
585
+                                    $phone,
586
+                                    $phoneScope,
587
+                                    $email,
588
+                                    $emailScope,
589
+                                    $website,
590
+                                    $websiteScope,
591
+                                    $address,
592
+                                    $addressScope,
593
+                                    $twitter,
594
+                                    $twitterScope
595
+    ) {
596
+
597
+        if (!empty($email) && !$this->mailer->validateMailAddress($email)) {
598
+            return new DataResponse(
599
+                [
600
+                    'status' => 'error',
601
+                    'data' => [
602
+                        'message' => (string) $this->l10n->t('Invalid mail address')
603
+                    ]
604
+                ],
605
+                Http::STATUS_UNPROCESSABLE_ENTITY
606
+            );
607
+        }
608
+
609
+        $data = [
610
+            AccountManager::PROPERTY_AVATAR =>  ['scope' => $avatarScope],
611
+            AccountManager::PROPERTY_DISPLAYNAME => ['value' => $displayname, 'scope' => $displaynameScope],
612
+            AccountManager::PROPERTY_EMAIL=> ['value' => $email, 'scope' => $emailScope],
613
+            AccountManager::PROPERTY_WEBSITE => ['value' => $website, 'scope' => $websiteScope],
614
+            AccountManager::PROPERTY_ADDRESS => ['value' => $address, 'scope' => $addressScope],
615
+            AccountManager::PROPERTY_PHONE => ['value' => $phone, 'scope' => $phoneScope],
616
+            AccountManager::PROPERTY_TWITTER => ['value' => $twitter, 'scope' => $twitterScope]
617
+        ];
618
+
619
+        $user = $this->userSession->getUser();
620
+
621
+        try {
622
+            $this->saveUserSettings($user, $data);
623
+            return new DataResponse(
624
+                [
625
+                    'status' => 'success',
626
+                    'data' => [
627
+                        'userId' => $user->getUID(),
628
+                        'avatarScope' => $avatarScope,
629
+                        'displayname' => $displayname,
630
+                        'displaynameScope' => $displaynameScope,
631
+                        'email' => $email,
632
+                        'emailScope' => $emailScope,
633
+                        'website' => $website,
634
+                        'websiteScope' => $websiteScope,
635
+                        'address' => $address,
636
+                        'addressScope' => $addressScope,
637
+                        'message' => (string) $this->l10n->t('Settings saved')
638
+                    ]
639
+                ],
640
+                Http::STATUS_OK
641
+            );
642
+        } catch (ForbiddenException $e) {
643
+            return new DataResponse([
644
+                'status' => 'error',
645
+                'data' => [
646
+                    'message' => $e->getMessage()
647
+                ],
648
+            ]);
649
+        }
650
+
651
+    }
652
+
653
+
654
+    /**
655
+     * update account manager with new user data
656
+     *
657
+     * @param IUser $user
658
+     * @param array $data
659
+     * @throws ForbiddenException
660
+     */
661
+    protected function saveUserSettings(IUser $user, $data) {
662
+
663
+        // keep the user back-end up-to-date with the latest display name and email
664
+        // address
665
+        $oldDisplayName = $user->getDisplayName();
666
+        $oldDisplayName = is_null($oldDisplayName) ? '' : $oldDisplayName;
667
+        if (isset($data[AccountManager::PROPERTY_DISPLAYNAME]['value'])
668
+            && $oldDisplayName !== $data[AccountManager::PROPERTY_DISPLAYNAME]['value']
669
+        ) {
670
+            $result = $user->setDisplayName($data[AccountManager::PROPERTY_DISPLAYNAME]['value']);
671
+            if ($result === false) {
672
+                throw new ForbiddenException($this->l10n->t('Unable to change full name'));
673
+            }
674
+        }
675
+
676
+        $oldEmailAddress = $user->getEMailAddress();
677
+        $oldEmailAddress = is_null($oldEmailAddress) ? '' : $oldEmailAddress;
678
+        if (isset($data[AccountManager::PROPERTY_EMAIL]['value'])
679
+            && $oldEmailAddress !== $data[AccountManager::PROPERTY_EMAIL]['value']
680
+        ) {
681
+            // this is the only permission a backend provides and is also used
682
+            // for the permission of setting a email address
683
+            if (!$user->canChangeDisplayName()) {
684
+                throw new ForbiddenException($this->l10n->t('Unable to change email address'));
685
+            }
686
+            $user->setEMailAddress($data[AccountManager::PROPERTY_EMAIL]['value']);
687
+        }
688
+
689
+        $this->accountManager->updateUser($user, $data);
690
+    }
691
+
692
+    /**
693
+     * Count all unique users visible for the current admin/subadmin.
694
+     *
695
+     * @NoAdminRequired
696
+     *
697
+     * @return DataResponse
698
+     */
699
+    public function stats() {
700
+        $userCount = 0;
701
+        if ($this->isAdmin) {
702
+            $countByBackend = $this->userManager->countUsers();
703
+
704
+            if (!empty($countByBackend)) {
705
+                foreach ($countByBackend as $count) {
706
+                    $userCount += $count;
707
+                }
708
+            }
709
+        } else {
710
+            $groups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($this->userSession->getUser());
711
+
712
+            $uniqueUsers = [];
713
+            foreach ($groups as $group) {
714
+                foreach($group->getUsers() as $uid => $displayName) {
715
+                    $uniqueUsers[$uid] = true;
716
+                }
717
+            }
718
+
719
+            $userCount = count($uniqueUsers);
720
+        }
721
+
722
+        return new DataResponse(
723
+            [
724
+                'totalUsers' => $userCount
725
+            ]
726
+        );
727
+    }
728
+
729
+
730
+    /**
731
+     * Set the displayName of a user
732
+     *
733
+     * @NoAdminRequired
734
+     * @NoSubadminRequired
735
+     * @PasswordConfirmationRequired
736
+     * @todo merge into saveUserSettings
737
+     *
738
+     * @param string $username
739
+     * @param string $displayName
740
+     * @return DataResponse
741
+     */
742
+    public function setDisplayName($username, $displayName) {
743
+        $currentUser = $this->userSession->getUser();
744
+        $user = $this->userManager->get($username);
745
+
746
+        if ($user === null ||
747
+            !$user->canChangeDisplayName() ||
748
+            (
749
+                !$this->groupManager->isAdmin($currentUser->getUID()) &&
750
+                !$this->groupManager->getSubAdmin()->isUserAccessible($currentUser, $user) &&
751
+                $currentUser->getUID() !== $username
752
+
753
+            )
754
+        ) {
755
+            return new DataResponse([
756
+                'status' => 'error',
757
+                'data' => [
758
+                    'message' => $this->l10n->t('Authentication error'),
759
+                ],
760
+            ]);
761
+        }
762
+
763
+        $userData = $this->accountManager->getUser($user);
764
+        $userData[AccountManager::PROPERTY_DISPLAYNAME]['value'] = $displayName;
765
+
766
+
767
+        try {
768
+            $this->saveUserSettings($user, $userData);
769
+            return new DataResponse([
770
+                'status' => 'success',
771
+                'data' => [
772
+                    'message' => $this->l10n->t('Your full name has been changed.'),
773
+                    'username' => $username,
774
+                    'displayName' => $displayName,
775
+                ],
776
+            ]);
777
+        } catch (ForbiddenException $e) {
778
+            return new DataResponse([
779
+                'status' => 'error',
780
+                'data' => [
781
+                    'message' => $e->getMessage(),
782
+                    'displayName' => $user->getDisplayName(),
783
+                ],
784
+            ]);
785
+        }
786
+    }
787
+
788
+    /**
789
+     * Set the mail address of a user
790
+     *
791
+     * @NoAdminRequired
792
+     * @NoSubadminRequired
793
+     * @PasswordConfirmationRequired
794
+     *
795
+     * @param string $id
796
+     * @param string $mailAddress
797
+     * @return DataResponse
798
+     */
799
+    public function setEMailAddress($id, $mailAddress) {
800
+        $user = $this->userManager->get($id);
801
+        if (!$this->isAdmin
802
+            && !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)
803
+        ) {
804
+            return new DataResponse(
805
+                [
806
+                    'status' => 'error',
807
+                    'data' => [
808
+                        'message' => (string) $this->l10n->t('Forbidden')
809
+                    ]
810
+                ],
811
+                Http::STATUS_FORBIDDEN
812
+            );
813
+        }
814
+
815
+        if($mailAddress !== '' && !$this->mailer->validateMailAddress($mailAddress)) {
816
+            return new DataResponse(
817
+                [
818
+                    'status' => 'error',
819
+                    'data' => [
820
+                        'message' => (string) $this->l10n->t('Invalid mail address')
821
+                    ]
822
+                ],
823
+                Http::STATUS_UNPROCESSABLE_ENTITY
824
+            );
825
+        }
826
+
827
+        if (!$user) {
828
+            return new DataResponse(
829
+                [
830
+                    'status' => 'error',
831
+                    'data' => [
832
+                        'message' => (string) $this->l10n->t('Invalid user')
833
+                    ]
834
+                ],
835
+                Http::STATUS_UNPROCESSABLE_ENTITY
836
+            );
837
+        }
838
+        // this is the only permission a backend provides and is also used
839
+        // for the permission of setting a email address
840
+        if (!$user->canChangeDisplayName()) {
841
+            return new DataResponse(
842
+                [
843
+                    'status' => 'error',
844
+                    'data' => [
845
+                        'message' => (string) $this->l10n->t('Unable to change mail address')
846
+                    ]
847
+                ],
848
+                Http::STATUS_FORBIDDEN
849
+            );
850
+        }
851
+
852
+        $userData = $this->accountManager->getUser($user);
853
+        $userData[AccountManager::PROPERTY_EMAIL]['value'] = $mailAddress;
854
+
855
+        try {
856
+            $this->saveUserSettings($user, $userData);
857
+            return new DataResponse(
858
+                [
859
+                    'status' => 'success',
860
+                    'data' => [
861
+                        'username' => $id,
862
+                        'mailAddress' => $mailAddress,
863
+                        'message' => (string) $this->l10n->t('Email saved')
864
+                    ]
865
+                ],
866
+                Http::STATUS_OK
867
+            );
868
+        } catch (ForbiddenException $e) {
869
+            return new DataResponse([
870
+                'status' => 'error',
871
+                'data' => [
872
+                    'message' => $e->getMessage()
873
+                ],
874
+            ]);
875
+        }
876
+    }
877 877
 
878 878
 }
Please login to merge, or discard this patch.
Spacing   +36 added lines, -36 removed lines patch added patch discarded remove patch
@@ -133,7 +133,7 @@  discard block
 block discarded – undo
133 133
 
134 134
 		// check for encryption state - TODO see formatUserForIndex
135 135
 		$this->isEncryptionAppEnabled = $appManager->isEnabledForUser('encryption');
136
-		if($this->isEncryptionAppEnabled) {
136
+		if ($this->isEncryptionAppEnabled) {
137 137
 			// putting this directly in empty is possible in PHP 5.5+
138 138
 			$result = $config->getAppValue('encryption', 'recoveryAdminEnabled', 0);
139 139
 			$this->isRestoreEnabled = !empty($result);
@@ -173,7 +173,7 @@  discard block
 block discarded – undo
173 173
 		}
174 174
 
175 175
 		$subAdminGroups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($user);
176
-		foreach($subAdminGroups as $key => $subAdminGroup) {
176
+		foreach ($subAdminGroups as $key => $subAdminGroup) {
177 177
 			$subAdminGroups[$key] = $subAdminGroup->getGID();
178 178
 		}
179 179
 
@@ -231,11 +231,11 @@  discard block
 block discarded – undo
231 231
 	 */
232 232
 	public function index($offset = 0, $limit = 10, $gid = '', $pattern = '', $backend = '') {
233 233
 		// Remove backends
234
-		if(!empty($backend)) {
234
+		if (!empty($backend)) {
235 235
 			$activeBackends = $this->userManager->getBackends();
236 236
 			$this->userManager->clearBackends();
237
-			foreach($activeBackends as $singleActiveBackend) {
238
-				if($backend === get_class($singleActiveBackend)) {
237
+			foreach ($activeBackends as $singleActiveBackend) {
238
+				if ($backend === get_class($singleActiveBackend)) {
239 239
 					$this->userManager->registerBackend($singleActiveBackend);
240 240
 					break;
241 241
 				}
@@ -244,14 +244,14 @@  discard block
 block discarded – undo
244 244
 
245 245
 		$users = [];
246 246
 		if ($this->isAdmin) {
247
-			if($gid !== '' && $gid !== '_disabledUsers') {
247
+			if ($gid !== '' && $gid !== '_disabledUsers') {
248 248
 				$batch = $this->getUsersForUID($this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset));
249 249
 			} else {
250 250
 				$batch = $this->userManager->search($pattern, $limit, $offset);
251 251
 			}
252 252
 
253 253
 			foreach ($batch as $user) {
254
-				if( ($gid !== '_disabledUsers' && $user->isEnabled()) ||
254
+				if (($gid !== '_disabledUsers' && $user->isEnabled()) ||
255 255
 					($gid === '_disabledUsers' && !$user->isEnabled())
256 256
 				) {
257 257
 					$users[] = $this->formatUserForIndex($user);
@@ -268,17 +268,17 @@  discard block
 block discarded – undo
268 268
 			$subAdminOfGroups = $gids;
269 269
 
270 270
 			// Set the $gid parameter to an empty value if the subadmin has no rights to access a specific group
271
-			if($gid !== '' && $gid !== '_disabledUsers' && !in_array($gid, $subAdminOfGroups)) {
271
+			if ($gid !== '' && $gid !== '_disabledUsers' && !in_array($gid, $subAdminOfGroups)) {
272 272
 				$gid = '';
273 273
 			}
274 274
 
275 275
 			// Batch all groups the user is subadmin of when a group is specified
276 276
 			$batch = [];
277
-			if($gid === '') {
278
-				foreach($subAdminOfGroups as $group) {
277
+			if ($gid === '') {
278
+				foreach ($subAdminOfGroups as $group) {
279 279
 					$groupUsers = $this->groupManager->displayNamesInGroup($group, $pattern, $limit, $offset);
280 280
 
281
-					foreach($groupUsers as $uid => $displayName) {
281
+					foreach ($groupUsers as $uid => $displayName) {
282 282
 						$batch[$uid] = $displayName;
283 283
 					}
284 284
 				}
@@ -293,7 +293,7 @@  discard block
 block discarded – undo
293 293
 					$this->groupManager->getUserGroupIds($user),
294 294
 					$subAdminOfGroups
295 295
 				));
296
-				if( ($gid !== '_disabledUsers' && $user->isEnabled()) ||
296
+				if (($gid !== '_disabledUsers' && $user->isEnabled()) ||
297 297
 					($gid === '_disabledUsers' && !$user->isEnabled())
298 298
 				) {
299 299
 					$users[] = $this->formatUserForIndex($user, $userGroups);
@@ -314,11 +314,11 @@  discard block
 block discarded – undo
314 314
 	 * @param string $email
315 315
 	 * @return DataResponse
316 316
 	 */
317
-	public function create($username, $password, array $groups=[], $email='') {
318
-		if($email !== '' && !$this->mailer->validateMailAddress($email)) {
317
+	public function create($username, $password, array $groups = [], $email = '') {
318
+		if ($email !== '' && !$this->mailer->validateMailAddress($email)) {
319 319
 			return new DataResponse(
320 320
 				[
321
-					'message' => (string)$this->l10n->t('Invalid mail address')
321
+					'message' => (string) $this->l10n->t('Invalid mail address')
322 322
 				],
323 323
 				Http::STATUS_UNPROCESSABLE_ENTITY
324 324
 			);
@@ -330,7 +330,7 @@  discard block
 block discarded – undo
330 330
 			if (!empty($groups)) {
331 331
 				foreach ($groups as $key => $group) {
332 332
 					$groupObject = $this->groupManager->get($group);
333
-					if($groupObject === null) {
333
+					if ($groupObject === null) {
334 334
 						unset($groups[$key]);
335 335
 						continue;
336 336
 					}
@@ -354,7 +354,7 @@  discard block
 block discarded – undo
354 354
 		if ($this->userManager->userExists($username)) {
355 355
 			return new DataResponse(
356 356
 				[
357
-					'message' => (string)$this->l10n->t('A user with that name already exists.')
357
+					'message' => (string) $this->l10n->t('A user with that name already exists.')
358 358
 				],
359 359
 				Http::STATUS_CONFLICT
360 360
 			);
@@ -365,7 +365,7 @@  discard block
 block discarded – undo
365 365
 			if ($email === '') {
366 366
 				return new DataResponse(
367 367
 					[
368
-						'message' => (string)$this->l10n->t('To send a password link to the user an email address is required.')
368
+						'message' => (string) $this->l10n->t('To send a password link to the user an email address is required.')
369 369
 					],
370 370
 					Http::STATUS_UNPROCESSABLE_ENTITY
371 371
 				);
@@ -390,12 +390,12 @@  discard block
 block discarded – undo
390 390
 			);
391 391
 		}
392 392
 
393
-		if($user instanceof IUser) {
394
-			if($groups !== null) {
395
-				foreach($groups as $groupName) {
393
+		if ($user instanceof IUser) {
394
+			if ($groups !== null) {
395
+				foreach ($groups as $groupName) {
396 396
 					$group = $this->groupManager->get($groupName);
397 397
 
398
-					if(empty($group)) {
398
+					if (empty($group)) {
399 399
 						$group = $this->groupManager->createGroup($groupName);
400 400
 					}
401 401
 					$group->addUser($user);
@@ -404,13 +404,13 @@  discard block
 block discarded – undo
404 404
 			/**
405 405
 			 * Send new user mail only if a mail is set
406 406
 			 */
407
-			if($email !== '') {
407
+			if ($email !== '') {
408 408
 				$user->setEMailAddress($email);
409 409
 				try {
410 410
 					$emailTemplate = $this->newUserMailHelper->generateTemplate($user, $generatePasswordResetToken);
411 411
 					$this->newUserMailHelper->sendMail($user, $emailTemplate);
412
-				} catch(\Exception $e) {
413
-					$this->log->error("Can't send new user mail to $email: " . $e->getMessage(), ['app' => 'settings']);
412
+				} catch (\Exception $e) {
413
+					$this->log->error("Can't send new user mail to $email: ".$e->getMessage(), ['app' => 'settings']);
414 414
 				}
415 415
 			}
416 416
 			// fetch users groups
@@ -442,7 +442,7 @@  discard block
 block discarded – undo
442 442
 		$userId = $this->userSession->getUser()->getUID();
443 443
 		$user = $this->userManager->get($id);
444 444
 
445
-		if($userId === $id) {
445
+		if ($userId === $id) {
446 446
 			return new DataResponse(
447 447
 				[
448 448
 					'status' => 'error',
@@ -454,20 +454,20 @@  discard block
 block discarded – undo
454 454
 			);
455 455
 		}
456 456
 
457
-		if(!$this->isAdmin && !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)) {
457
+		if (!$this->isAdmin && !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)) {
458 458
 			return new DataResponse(
459 459
 				[
460 460
 					'status' => 'error',
461 461
 					'data' => [
462
-						'message' => (string)$this->l10n->t('Authentication error')
462
+						'message' => (string) $this->l10n->t('Authentication error')
463 463
 					]
464 464
 				],
465 465
 				Http::STATUS_FORBIDDEN
466 466
 			);
467 467
 		}
468 468
 
469
-		if($user) {
470
-			if($user->delete()) {
469
+		if ($user) {
470
+			if ($user->delete()) {
471 471
 				return new DataResponse(
472 472
 					[
473 473
 						'status' => 'success',
@@ -484,7 +484,7 @@  discard block
 block discarded – undo
484 484
 			[
485 485
 				'status' => 'error',
486 486
 				'data' => [
487
-					'message' => (string)$this->l10n->t('Unable to delete user.')
487
+					'message' => (string) $this->l10n->t('Unable to delete user.')
488 488
 				]
489 489
 			],
490 490
 			Http::STATUS_FORBIDDEN
@@ -499,8 +499,8 @@  discard block
 block discarded – undo
499 499
 	 * @return DataResponse
500 500
 	 */
501 501
 	public function setEnabled($id, $enabled) {
502
-		$enabled = (bool)$enabled;
503
-		if($enabled) {
502
+		$enabled = (bool) $enabled;
503
+		if ($enabled) {
504 504
 			$errorMsgGeneral = (string) $this->l10n->t('Error while enabling user.');
505 505
 		} else {
506 506
 			$errorMsgGeneral = (string) $this->l10n->t('Error while disabling user.');
@@ -520,7 +520,7 @@  discard block
 block discarded – undo
520 520
 			);
521 521
 		}
522 522
 
523
-		if($user) {
523
+		if ($user) {
524 524
 			if (!$this->isAdmin && !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)) {
525 525
 				return new DataResponse(
526 526
 					[
@@ -711,7 +711,7 @@  discard block
 block discarded – undo
711 711
 
712 712
 			$uniqueUsers = [];
713 713
 			foreach ($groups as $group) {
714
-				foreach($group->getUsers() as $uid => $displayName) {
714
+				foreach ($group->getUsers() as $uid => $displayName) {
715 715
 					$uniqueUsers[$uid] = true;
716 716
 				}
717 717
 			}
@@ -812,7 +812,7 @@  discard block
 block discarded – undo
812 812
 			);
813 813
 		}
814 814
 
815
-		if($mailAddress !== '' && !$this->mailer->validateMailAddress($mailAddress)) {
815
+		if ($mailAddress !== '' && !$this->mailer->validateMailAddress($mailAddress)) {
816 816
 			return new DataResponse(
817 817
 				[
818 818
 					'status' => 'error',
Please login to merge, or discard this patch.