Passed
Push — master ( 157c65...2ad95f )
by Morris
10:50 queued 10s
created
apps/files_sharing/lib/ShareBackend/File.php 1 patch
Indentation   +214 added lines, -214 removed lines patch added patch discarded remove patch
@@ -38,218 +38,218 @@
 block discarded – undo
38 38
 use OCP\Share\IShare;
39 39
 
40 40
 class File implements \OCP\Share_Backend_File_Dependent {
41
-	public const FORMAT_SHARED_STORAGE = 0;
42
-	public const FORMAT_GET_FOLDER_CONTENTS = 1;
43
-	public const FORMAT_FILE_APP_ROOT = 2;
44
-	public const FORMAT_OPENDIR = 3;
45
-	public const FORMAT_GET_ALL = 4;
46
-	public const FORMAT_PERMISSIONS = 5;
47
-	public const FORMAT_TARGET_NAMES = 6;
48
-
49
-	private $path;
50
-
51
-	/** @var FederatedShareProvider */
52
-	private $federatedShareProvider;
53
-
54
-	public function __construct(FederatedShareProvider $federatedShareProvider = null) {
55
-		if ($federatedShareProvider) {
56
-			$this->federatedShareProvider = $federatedShareProvider;
57
-		} else {
58
-			$this->federatedShareProvider = \OC::$server->query(FederatedShareProvider::class);
59
-		}
60
-	}
61
-
62
-	public function isValidSource($itemSource, $uidOwner) {
63
-		try {
64
-			$path = \OC\Files\Filesystem::getPath($itemSource);
65
-			// FIXME: attributes should not be set here,
66
-			// keeping this pattern for now to avoid unexpected
67
-			// regressions
68
-			$this->path = \OC\Files\Filesystem::normalizePath(basename($path));
69
-			return true;
70
-		} catch (\OCP\Files\NotFoundException $e) {
71
-			return false;
72
-		}
73
-	}
74
-
75
-	public function getFilePath($itemSource, $uidOwner) {
76
-		if (isset($this->path)) {
77
-			$path = $this->path;
78
-			$this->path = null;
79
-			return $path;
80
-		} else {
81
-			try {
82
-				$path = \OC\Files\Filesystem::getPath($itemSource);
83
-				return $path;
84
-			} catch (\OCP\Files\NotFoundException $e) {
85
-				return false;
86
-			}
87
-		}
88
-	}
89
-
90
-	/**
91
-	 * create unique target
92
-	 * @param string $filePath
93
-	 * @param string $shareWith
94
-	 * @param array $exclude (optional)
95
-	 * @return string
96
-	 */
97
-	public function generateTarget($filePath, $shareWith, $exclude = null) {
98
-		$shareFolder = \OCA\Files_Sharing\Helper::getShareFolder();
99
-		$target = \OC\Files\Filesystem::normalizePath($shareFolder . '/' . basename($filePath));
100
-
101
-		// for group shares we return the target right away
102
-		if ($shareWith === false) {
103
-			return $target;
104
-		}
105
-
106
-		\OC\Files\Filesystem::initMountPoints($shareWith);
107
-		$view = new \OC\Files\View('/' . $shareWith . '/files');
108
-
109
-		if (!$view->is_dir($shareFolder)) {
110
-			$dir = '';
111
-			$subdirs = explode('/', $shareFolder);
112
-			foreach ($subdirs as $subdir) {
113
-				$dir = $dir . '/' . $subdir;
114
-				if (!$view->is_dir($dir)) {
115
-					$view->mkdir($dir);
116
-				}
117
-			}
118
-		}
119
-
120
-		$excludeList = is_array($exclude) ? $exclude : [];
121
-
122
-		return \OCA\Files_Sharing\Helper::generateUniqueTarget($target, $excludeList, $view);
123
-	}
124
-
125
-	public function formatItems($items, $format, $parameters = null) {
126
-		if ($format === self::FORMAT_SHARED_STORAGE) {
127
-			// Only 1 item should come through for this format call
128
-			$item = array_shift($items);
129
-			return [
130
-				'parent' => $item['parent'],
131
-				'path' => $item['path'],
132
-				'storage' => $item['storage'],
133
-				'permissions' => $item['permissions'],
134
-				'uid_owner' => $item['uid_owner'],
135
-			];
136
-		} elseif ($format === self::FORMAT_GET_FOLDER_CONTENTS) {
137
-			$files = [];
138
-			foreach ($items as $item) {
139
-				$file = [];
140
-				$file['fileid'] = $item['file_source'];
141
-				$file['storage'] = $item['storage'];
142
-				$file['path'] = $item['file_target'];
143
-				$file['parent'] = $item['file_parent'];
144
-				$file['name'] = basename($item['file_target']);
145
-				$file['mimetype'] = $item['mimetype'];
146
-				$file['mimepart'] = $item['mimepart'];
147
-				$file['mtime'] = $item['mtime'];
148
-				$file['encrypted'] = $item['encrypted'];
149
-				$file['etag'] = $item['etag'];
150
-				$file['uid_owner'] = $item['uid_owner'];
151
-				$file['displayname_owner'] = $item['displayname_owner'];
152
-
153
-				$storage = \OC\Files\Filesystem::getStorage('/');
154
-				$cache = $storage->getCache();
155
-				$file['size'] = $item['size'];
156
-				$files[] = $file;
157
-			}
158
-			return $files;
159
-		} elseif ($format === self::FORMAT_OPENDIR) {
160
-			$files = [];
161
-			foreach ($items as $item) {
162
-				$files[] = basename($item['file_target']);
163
-			}
164
-			return $files;
165
-		} elseif ($format === self::FORMAT_GET_ALL) {
166
-			$ids = [];
167
-			foreach ($items as $item) {
168
-				$ids[] = $item['file_source'];
169
-			}
170
-			return $ids;
171
-		} elseif ($format === self::FORMAT_PERMISSIONS) {
172
-			$filePermissions = [];
173
-			foreach ($items as $item) {
174
-				$filePermissions[$item['file_source']] = $item['permissions'];
175
-			}
176
-			return $filePermissions;
177
-		} elseif ($format === self::FORMAT_TARGET_NAMES) {
178
-			$targets = [];
179
-			foreach ($items as $item) {
180
-				$targets[] = $item['file_target'];
181
-			}
182
-			return $targets;
183
-		}
184
-		return [];
185
-	}
186
-
187
-	/**
188
-	 * check if server2server share is enabled
189
-	 *
190
-	 * @param int $shareType
191
-	 * @return boolean
192
-	 */
193
-	public function isShareTypeAllowed($shareType) {
194
-		if ($shareType === IShare::TYPE_REMOTE) {
195
-			return $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
196
-		}
197
-
198
-		if ($shareType === IShare::TYPE_REMOTE_GROUP) {
199
-			return $this->federatedShareProvider->isOutgoingServer2serverGroupShareEnabled();
200
-		}
201
-
202
-		return true;
203
-	}
204
-
205
-	/**
206
-	 * resolve reshares to return the correct source item
207
-	 * @param array $source
208
-	 * @return array source item
209
-	 */
210
-	protected static function resolveReshares($source) {
211
-		if (isset($source['parent'])) {
212
-			$parent = $source['parent'];
213
-			while (isset($parent)) {
214
-				$qb = \OC::$server->getDatabaseConnection()->getQueryBuilder();
215
-				$qb->select('parent', 'uid_owner')
216
-					->from('share')
217
-					->where(
218
-						$qb->expr()->eq('id', $qb->createNamedParameter($parent))
219
-					);
220
-				$result = $qb->execute();
221
-				$item = $result->fetch();
222
-				$result->closeCursor();
223
-				if (isset($item['parent'])) {
224
-					$parent = $item['parent'];
225
-				} else {
226
-					$fileOwner = $item['uid_owner'];
227
-					break;
228
-				}
229
-			}
230
-		} else {
231
-			$fileOwner = $source['uid_owner'];
232
-		}
233
-		if (isset($fileOwner)) {
234
-			$source['fileOwner'] = $fileOwner;
235
-		} else {
236
-			\OC::$server->getLogger()->error('No owner found for reshare', ['app' => 'files_sharing']);
237
-		}
238
-
239
-		return $source;
240
-	}
241
-
242
-	/**
243
-	 * @param string $target
244
-	 * @param array $share
245
-	 * @return array|false source item
246
-	 */
247
-	public static function getSource($target, $share) {
248
-		if ($share['item_type'] === 'folder' && $target !== '') {
249
-			// note: in case of ext storage mount points the path might be empty
250
-			// which would cause a leading slash to appear
251
-			$share['path'] = ltrim($share['path'] . '/' . $target, '/');
252
-		}
253
-		return self::resolveReshares($share);
254
-	}
41
+    public const FORMAT_SHARED_STORAGE = 0;
42
+    public const FORMAT_GET_FOLDER_CONTENTS = 1;
43
+    public const FORMAT_FILE_APP_ROOT = 2;
44
+    public const FORMAT_OPENDIR = 3;
45
+    public const FORMAT_GET_ALL = 4;
46
+    public const FORMAT_PERMISSIONS = 5;
47
+    public const FORMAT_TARGET_NAMES = 6;
48
+
49
+    private $path;
50
+
51
+    /** @var FederatedShareProvider */
52
+    private $federatedShareProvider;
53
+
54
+    public function __construct(FederatedShareProvider $federatedShareProvider = null) {
55
+        if ($federatedShareProvider) {
56
+            $this->federatedShareProvider = $federatedShareProvider;
57
+        } else {
58
+            $this->federatedShareProvider = \OC::$server->query(FederatedShareProvider::class);
59
+        }
60
+    }
61
+
62
+    public function isValidSource($itemSource, $uidOwner) {
63
+        try {
64
+            $path = \OC\Files\Filesystem::getPath($itemSource);
65
+            // FIXME: attributes should not be set here,
66
+            // keeping this pattern for now to avoid unexpected
67
+            // regressions
68
+            $this->path = \OC\Files\Filesystem::normalizePath(basename($path));
69
+            return true;
70
+        } catch (\OCP\Files\NotFoundException $e) {
71
+            return false;
72
+        }
73
+    }
74
+
75
+    public function getFilePath($itemSource, $uidOwner) {
76
+        if (isset($this->path)) {
77
+            $path = $this->path;
78
+            $this->path = null;
79
+            return $path;
80
+        } else {
81
+            try {
82
+                $path = \OC\Files\Filesystem::getPath($itemSource);
83
+                return $path;
84
+            } catch (\OCP\Files\NotFoundException $e) {
85
+                return false;
86
+            }
87
+        }
88
+    }
89
+
90
+    /**
91
+     * create unique target
92
+     * @param string $filePath
93
+     * @param string $shareWith
94
+     * @param array $exclude (optional)
95
+     * @return string
96
+     */
97
+    public function generateTarget($filePath, $shareWith, $exclude = null) {
98
+        $shareFolder = \OCA\Files_Sharing\Helper::getShareFolder();
99
+        $target = \OC\Files\Filesystem::normalizePath($shareFolder . '/' . basename($filePath));
100
+
101
+        // for group shares we return the target right away
102
+        if ($shareWith === false) {
103
+            return $target;
104
+        }
105
+
106
+        \OC\Files\Filesystem::initMountPoints($shareWith);
107
+        $view = new \OC\Files\View('/' . $shareWith . '/files');
108
+
109
+        if (!$view->is_dir($shareFolder)) {
110
+            $dir = '';
111
+            $subdirs = explode('/', $shareFolder);
112
+            foreach ($subdirs as $subdir) {
113
+                $dir = $dir . '/' . $subdir;
114
+                if (!$view->is_dir($dir)) {
115
+                    $view->mkdir($dir);
116
+                }
117
+            }
118
+        }
119
+
120
+        $excludeList = is_array($exclude) ? $exclude : [];
121
+
122
+        return \OCA\Files_Sharing\Helper::generateUniqueTarget($target, $excludeList, $view);
123
+    }
124
+
125
+    public function formatItems($items, $format, $parameters = null) {
126
+        if ($format === self::FORMAT_SHARED_STORAGE) {
127
+            // Only 1 item should come through for this format call
128
+            $item = array_shift($items);
129
+            return [
130
+                'parent' => $item['parent'],
131
+                'path' => $item['path'],
132
+                'storage' => $item['storage'],
133
+                'permissions' => $item['permissions'],
134
+                'uid_owner' => $item['uid_owner'],
135
+            ];
136
+        } elseif ($format === self::FORMAT_GET_FOLDER_CONTENTS) {
137
+            $files = [];
138
+            foreach ($items as $item) {
139
+                $file = [];
140
+                $file['fileid'] = $item['file_source'];
141
+                $file['storage'] = $item['storage'];
142
+                $file['path'] = $item['file_target'];
143
+                $file['parent'] = $item['file_parent'];
144
+                $file['name'] = basename($item['file_target']);
145
+                $file['mimetype'] = $item['mimetype'];
146
+                $file['mimepart'] = $item['mimepart'];
147
+                $file['mtime'] = $item['mtime'];
148
+                $file['encrypted'] = $item['encrypted'];
149
+                $file['etag'] = $item['etag'];
150
+                $file['uid_owner'] = $item['uid_owner'];
151
+                $file['displayname_owner'] = $item['displayname_owner'];
152
+
153
+                $storage = \OC\Files\Filesystem::getStorage('/');
154
+                $cache = $storage->getCache();
155
+                $file['size'] = $item['size'];
156
+                $files[] = $file;
157
+            }
158
+            return $files;
159
+        } elseif ($format === self::FORMAT_OPENDIR) {
160
+            $files = [];
161
+            foreach ($items as $item) {
162
+                $files[] = basename($item['file_target']);
163
+            }
164
+            return $files;
165
+        } elseif ($format === self::FORMAT_GET_ALL) {
166
+            $ids = [];
167
+            foreach ($items as $item) {
168
+                $ids[] = $item['file_source'];
169
+            }
170
+            return $ids;
171
+        } elseif ($format === self::FORMAT_PERMISSIONS) {
172
+            $filePermissions = [];
173
+            foreach ($items as $item) {
174
+                $filePermissions[$item['file_source']] = $item['permissions'];
175
+            }
176
+            return $filePermissions;
177
+        } elseif ($format === self::FORMAT_TARGET_NAMES) {
178
+            $targets = [];
179
+            foreach ($items as $item) {
180
+                $targets[] = $item['file_target'];
181
+            }
182
+            return $targets;
183
+        }
184
+        return [];
185
+    }
186
+
187
+    /**
188
+     * check if server2server share is enabled
189
+     *
190
+     * @param int $shareType
191
+     * @return boolean
192
+     */
193
+    public function isShareTypeAllowed($shareType) {
194
+        if ($shareType === IShare::TYPE_REMOTE) {
195
+            return $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
196
+        }
197
+
198
+        if ($shareType === IShare::TYPE_REMOTE_GROUP) {
199
+            return $this->federatedShareProvider->isOutgoingServer2serverGroupShareEnabled();
200
+        }
201
+
202
+        return true;
203
+    }
204
+
205
+    /**
206
+     * resolve reshares to return the correct source item
207
+     * @param array $source
208
+     * @return array source item
209
+     */
210
+    protected static function resolveReshares($source) {
211
+        if (isset($source['parent'])) {
212
+            $parent = $source['parent'];
213
+            while (isset($parent)) {
214
+                $qb = \OC::$server->getDatabaseConnection()->getQueryBuilder();
215
+                $qb->select('parent', 'uid_owner')
216
+                    ->from('share')
217
+                    ->where(
218
+                        $qb->expr()->eq('id', $qb->createNamedParameter($parent))
219
+                    );
220
+                $result = $qb->execute();
221
+                $item = $result->fetch();
222
+                $result->closeCursor();
223
+                if (isset($item['parent'])) {
224
+                    $parent = $item['parent'];
225
+                } else {
226
+                    $fileOwner = $item['uid_owner'];
227
+                    break;
228
+                }
229
+            }
230
+        } else {
231
+            $fileOwner = $source['uid_owner'];
232
+        }
233
+        if (isset($fileOwner)) {
234
+            $source['fileOwner'] = $fileOwner;
235
+        } else {
236
+            \OC::$server->getLogger()->error('No owner found for reshare', ['app' => 'files_sharing']);
237
+        }
238
+
239
+        return $source;
240
+    }
241
+
242
+    /**
243
+     * @param string $target
244
+     * @param array $share
245
+     * @return array|false source item
246
+     */
247
+    public static function getSource($target, $share) {
248
+        if ($share['item_type'] === 'folder' && $target !== '') {
249
+            // note: in case of ext storage mount points the path might be empty
250
+            // which would cause a leading slash to appear
251
+            $share['path'] = ltrim($share['path'] . '/' . $target, '/');
252
+        }
253
+        return self::resolveReshares($share);
254
+    }
255 255
 }
Please login to merge, or discard this patch.
apps/provisioning_api/lib/Controller/UsersController.php 1 patch
Indentation   +902 added lines, -902 removed lines patch added patch discarded remove patch
@@ -62,906 +62,906 @@
 block discarded – undo
62 62
 
63 63
 class UsersController extends AUserData {
64 64
 
65
-	/** @var IAppManager */
66
-	private $appManager;
67
-	/** @var ILogger */
68
-	private $logger;
69
-	/** @var IFactory */
70
-	protected $l10nFactory;
71
-	/** @var NewUserMailHelper */
72
-	private $newUserMailHelper;
73
-	/** @var FederatedShareProviderFactory */
74
-	private $federatedShareProviderFactory;
75
-	/** @var ISecureRandom */
76
-	private $secureRandom;
77
-	/** @var RemoteWipe */
78
-	private $remoteWipe;
79
-
80
-	public function __construct(string $appName,
81
-								IRequest $request,
82
-								IUserManager $userManager,
83
-								IConfig $config,
84
-								IAppManager $appManager,
85
-								IGroupManager $groupManager,
86
-								IUserSession $userSession,
87
-								AccountManager $accountManager,
88
-								ILogger $logger,
89
-								IFactory $l10nFactory,
90
-								NewUserMailHelper $newUserMailHelper,
91
-								FederatedShareProviderFactory $federatedShareProviderFactory,
92
-								ISecureRandom $secureRandom,
93
-								RemoteWipe $remoteWipe) {
94
-		parent::__construct($appName,
95
-							$request,
96
-							$userManager,
97
-							$config,
98
-							$groupManager,
99
-							$userSession,
100
-							$accountManager,
101
-							$l10nFactory);
102
-
103
-		$this->appManager = $appManager;
104
-		$this->logger = $logger;
105
-		$this->l10nFactory = $l10nFactory;
106
-		$this->newUserMailHelper = $newUserMailHelper;
107
-		$this->federatedShareProviderFactory = $federatedShareProviderFactory;
108
-		$this->secureRandom = $secureRandom;
109
-		$this->remoteWipe = $remoteWipe;
110
-	}
111
-
112
-	/**
113
-	 * @NoAdminRequired
114
-	 *
115
-	 * returns a list of users
116
-	 *
117
-	 * @param string $search
118
-	 * @param int $limit
119
-	 * @param int $offset
120
-	 * @return DataResponse
121
-	 */
122
-	public function getUsers(string $search = '', int $limit = null, int $offset = 0): DataResponse {
123
-		$user = $this->userSession->getUser();
124
-		$users = [];
125
-
126
-		// Admin? Or SubAdmin?
127
-		$uid = $user->getUID();
128
-		$subAdminManager = $this->groupManager->getSubAdmin();
129
-		if ($this->groupManager->isAdmin($uid)) {
130
-			$users = $this->userManager->search($search, $limit, $offset);
131
-		} elseif ($subAdminManager->isSubAdmin($user)) {
132
-			$subAdminOfGroups = $subAdminManager->getSubAdminsGroups($user);
133
-			foreach ($subAdminOfGroups as $key => $group) {
134
-				$subAdminOfGroups[$key] = $group->getGID();
135
-			}
136
-
137
-			$users = [];
138
-			foreach ($subAdminOfGroups as $group) {
139
-				$users = array_merge($users, $this->groupManager->displayNamesInGroup($group, $search, $limit, $offset));
140
-			}
141
-		}
142
-
143
-		$users = array_keys($users);
144
-
145
-		return new DataResponse([
146
-			'users' => $users
147
-		]);
148
-	}
149
-
150
-	/**
151
-	 * @NoAdminRequired
152
-	 *
153
-	 * returns a list of users and their data
154
-	 */
155
-	public function getUsersDetails(string $search = '', int $limit = null, int $offset = 0): DataResponse {
156
-		$currentUser = $this->userSession->getUser();
157
-		$users = [];
158
-
159
-		// Admin? Or SubAdmin?
160
-		$uid = $currentUser->getUID();
161
-		$subAdminManager = $this->groupManager->getSubAdmin();
162
-		if ($this->groupManager->isAdmin($uid)) {
163
-			$users = $this->userManager->search($search, $limit, $offset);
164
-			$users = array_keys($users);
165
-		} elseif ($subAdminManager->isSubAdmin($currentUser)) {
166
-			$subAdminOfGroups = $subAdminManager->getSubAdminsGroups($currentUser);
167
-			foreach ($subAdminOfGroups as $key => $group) {
168
-				$subAdminOfGroups[$key] = $group->getGID();
169
-			}
170
-
171
-			$users = [];
172
-			foreach ($subAdminOfGroups as $group) {
173
-				$users[] = array_keys($this->groupManager->displayNamesInGroup($group, $search, $limit, $offset));
174
-			}
175
-			$users = array_merge(...$users);
176
-		}
177
-
178
-		$usersDetails = [];
179
-		foreach ($users as $userId) {
180
-			$userId = (string) $userId;
181
-			$userData = $this->getUserData($userId);
182
-			// Do not insert empty entry
183
-			if (!empty($userData)) {
184
-				$usersDetails[$userId] = $userData;
185
-			} else {
186
-				// Logged user does not have permissions to see this user
187
-				// only showing its id
188
-				$usersDetails[$userId] = ['id' => $userId];
189
-			}
190
-		}
191
-
192
-		return new DataResponse([
193
-			'users' => $usersDetails
194
-		]);
195
-	}
196
-
197
-	/**
198
-	 * @throws OCSException
199
-	 */
200
-	private function createNewUserId(): string {
201
-		$attempts = 0;
202
-		do {
203
-			$uidCandidate = $this->secureRandom->generate(10, ISecureRandom::CHAR_HUMAN_READABLE);
204
-			if (!$this->userManager->userExists($uidCandidate)) {
205
-				return $uidCandidate;
206
-			}
207
-			$attempts++;
208
-		} while ($attempts < 10);
209
-		throw new OCSException('Could not create non-existing user id', 111);
210
-	}
211
-
212
-	/**
213
-	 * @PasswordConfirmationRequired
214
-	 * @NoAdminRequired
215
-	 *
216
-	 * @param string $userid
217
-	 * @param string $password
218
-	 * @param string $displayName
219
-	 * @param string $email
220
-	 * @param array $groups
221
-	 * @param array $subadmin
222
-	 * @param string $quota
223
-	 * @param string $language
224
-	 * @return DataResponse
225
-	 * @throws OCSException
226
-	 */
227
-	public function addUser(string $userid,
228
-							string $password = '',
229
-							string $displayName = '',
230
-							string $email = '',
231
-							array $groups = [],
232
-							array $subadmin = [],
233
-							string $quota = '',
234
-							string $language = ''): DataResponse {
235
-		$user = $this->userSession->getUser();
236
-		$isAdmin = $this->groupManager->isAdmin($user->getUID());
237
-		$subAdminManager = $this->groupManager->getSubAdmin();
238
-
239
-		if (empty($userid) && $this->config->getAppValue('core', 'newUser.generateUserID', 'no') === 'yes') {
240
-			$userid = $this->createNewUserId();
241
-		}
242
-
243
-		if ($this->userManager->userExists($userid)) {
244
-			$this->logger->error('Failed addUser attempt: User already exists.', ['app' => 'ocs_api']);
245
-			throw new OCSException('User already exists', 102);
246
-		}
247
-
248
-		if ($groups !== []) {
249
-			foreach ($groups as $group) {
250
-				if (!$this->groupManager->groupExists($group)) {
251
-					throw new OCSException('group '.$group.' does not exist', 104);
252
-				}
253
-				if (!$isAdmin && !$subAdminManager->isSubAdminOfGroup($user, $this->groupManager->get($group))) {
254
-					throw new OCSException('insufficient privileges for group '. $group, 105);
255
-				}
256
-			}
257
-		} else {
258
-			if (!$isAdmin) {
259
-				throw new OCSException('no group specified (required for subadmins)', 106);
260
-			}
261
-		}
262
-
263
-		$subadminGroups = [];
264
-		if ($subadmin !== []) {
265
-			foreach ($subadmin as $groupid) {
266
-				$group = $this->groupManager->get($groupid);
267
-				// Check if group exists
268
-				if ($group === null) {
269
-					throw new OCSException('Subadmin group does not exist',  102);
270
-				}
271
-				// Check if trying to make subadmin of admin group
272
-				if ($group->getGID() === 'admin') {
273
-					throw new OCSException('Cannot create subadmins for admin group', 103);
274
-				}
275
-				// Check if has permission to promote subadmins
276
-				if (!$subAdminManager->isSubAdminOfGroup($user, $group) && !$isAdmin) {
277
-					throw new OCSForbiddenException('No permissions to promote subadmins');
278
-				}
279
-				$subadminGroups[] = $group;
280
-			}
281
-		}
282
-
283
-		$generatePasswordResetToken = false;
284
-		if ($password === '') {
285
-			if ($email === '') {
286
-				throw new OCSException('To send a password link to the user an email address is required.', 108);
287
-			}
288
-
289
-			$password = $this->secureRandom->generate(10);
290
-			// Make sure we pass the password_policy
291
-			$password .= $this->secureRandom->generate(2, '$!.,;:-~+*[]{}()');
292
-			$generatePasswordResetToken = true;
293
-		}
294
-
295
-		if ($email === '' && $this->config->getAppValue('core', 'newUser.requireEmail', 'no') === 'yes') {
296
-			throw new OCSException('Required email address was not provided', 110);
297
-		}
298
-
299
-		try {
300
-			$newUser = $this->userManager->createUser($userid, $password);
301
-			$this->logger->info('Successful addUser call with userid: ' . $userid, ['app' => 'ocs_api']);
302
-
303
-			foreach ($groups as $group) {
304
-				$this->groupManager->get($group)->addUser($newUser);
305
-				$this->logger->info('Added userid ' . $userid . ' to group ' . $group, ['app' => 'ocs_api']);
306
-			}
307
-			foreach ($subadminGroups as $group) {
308
-				$subAdminManager->createSubAdmin($newUser, $group);
309
-			}
310
-
311
-			if ($displayName !== '') {
312
-				$this->editUser($userid, 'display', $displayName);
313
-			}
314
-
315
-			if ($quota !== '') {
316
-				$this->editUser($userid, 'quota', $quota);
317
-			}
318
-
319
-			if ($language !== '') {
320
-				$this->editUser($userid, 'language', $language);
321
-			}
322
-
323
-			// Send new user mail only if a mail is set
324
-			if ($email !== '' && $this->config->getAppValue('core', 'newUser.sendEmail', 'yes') === 'yes') {
325
-				$newUser->setEMailAddress($email);
326
-				try {
327
-					$emailTemplate = $this->newUserMailHelper->generateTemplate($newUser, $generatePasswordResetToken);
328
-					$this->newUserMailHelper->sendMail($newUser, $emailTemplate);
329
-				} catch (\Exception $e) {
330
-					// Mail could be failing hard or just be plain not configured
331
-					// Logging error as it is the hardest of the two
332
-					$this->logger->logException($e, [
333
-						'message' => "Unable to send the invitation mail to $email",
334
-						'level' => ILogger::ERROR,
335
-						'app' => 'ocs_api',
336
-					]);
337
-				}
338
-			}
339
-
340
-			return new DataResponse(['id' => $userid]);
341
-		} catch (HintException $e) {
342
-			$this->logger->logException($e, [
343
-				'message' => 'Failed addUser attempt with hint exception.',
344
-				'level' => ILogger::WARN,
345
-				'app' => 'ocs_api',
346
-			]);
347
-			throw new OCSException($e->getHint(), 107);
348
-		} catch (OCSException $e) {
349
-			$this->logger->logException($e, [
350
-				'message' => 'Failed addUser attempt with ocs exeption.',
351
-				'level' => ILogger::ERROR,
352
-				'app' => 'ocs_api',
353
-			]);
354
-			throw $e;
355
-		} catch (\Exception $e) {
356
-			$this->logger->logException($e, [
357
-				'message' => 'Failed addUser attempt with exception.',
358
-				'level' => ILogger::ERROR,
359
-				'app' => 'ocs_api',
360
-			]);
361
-			throw new OCSException('Bad request', 101);
362
-		}
363
-	}
364
-
365
-	/**
366
-	 * @NoAdminRequired
367
-	 * @NoSubAdminRequired
368
-	 *
369
-	 * gets user info
370
-	 *
371
-	 * @param string $userId
372
-	 * @return DataResponse
373
-	 * @throws OCSException
374
-	 */
375
-	public function getUser(string $userId): DataResponse {
376
-		$data = $this->getUserData($userId);
377
-		// getUserData returns empty array if not enough permissions
378
-		if (empty($data)) {
379
-			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
380
-		}
381
-		return new DataResponse($data);
382
-	}
383
-
384
-	/**
385
-	 * @NoAdminRequired
386
-	 * @NoSubAdminRequired
387
-	 *
388
-	 * gets user info from the currently logged in user
389
-	 *
390
-	 * @return DataResponse
391
-	 * @throws OCSException
392
-	 */
393
-	public function getCurrentUser(): DataResponse {
394
-		$user = $this->userSession->getUser();
395
-		if ($user) {
396
-			$data =  $this->getUserData($user->getUID());
397
-			// rename "displayname" to "display-name" only for this call to keep
398
-			// the API stable.
399
-			$data['display-name'] = $data['displayname'];
400
-			unset($data['displayname']);
401
-			return new DataResponse($data);
402
-		}
403
-
404
-		throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
405
-	}
406
-
407
-	/**
408
-	 * @NoAdminRequired
409
-	 * @NoSubAdminRequired
410
-	 */
411
-	public function getEditableFields(): DataResponse {
412
-		$permittedFields = [];
413
-
414
-		// Editing self (display, email)
415
-		if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
416
-			$permittedFields[] = AccountManager::PROPERTY_DISPLAYNAME;
417
-			$permittedFields[] = AccountManager::PROPERTY_EMAIL;
418
-		}
419
-
420
-		if ($this->appManager->isEnabledForUser('federatedfilesharing')) {
421
-			$shareProvider = $this->federatedShareProviderFactory->get();
422
-			if ($shareProvider->isLookupServerUploadEnabled()) {
423
-				$permittedFields[] = AccountManager::PROPERTY_PHONE;
424
-				$permittedFields[] = AccountManager::PROPERTY_ADDRESS;
425
-				$permittedFields[] = AccountManager::PROPERTY_WEBSITE;
426
-				$permittedFields[] = AccountManager::PROPERTY_TWITTER;
427
-			}
428
-		}
429
-
430
-		return new DataResponse($permittedFields);
431
-	}
432
-
433
-	/**
434
-	 * @NoAdminRequired
435
-	 * @NoSubAdminRequired
436
-	 * @PasswordConfirmationRequired
437
-	 *
438
-	 * edit users
439
-	 *
440
-	 * @param string $userId
441
-	 * @param string $key
442
-	 * @param string $value
443
-	 * @return DataResponse
444
-	 * @throws OCSException
445
-	 */
446
-	public function editUser(string $userId, string $key, string $value): DataResponse {
447
-		$currentLoggedInUser = $this->userSession->getUser();
448
-
449
-		$targetUser = $this->userManager->get($userId);
450
-		if ($targetUser === null) {
451
-			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
452
-		}
453
-
454
-		$permittedFields = [];
455
-		if ($targetUser->getUID() === $currentLoggedInUser->getUID()) {
456
-			// Editing self (display, email)
457
-			if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
458
-				$permittedFields[] = 'display';
459
-				$permittedFields[] = AccountManager::PROPERTY_DISPLAYNAME;
460
-				$permittedFields[] = AccountManager::PROPERTY_EMAIL;
461
-			}
462
-
463
-			$permittedFields[] = 'password';
464
-			if ($this->config->getSystemValue('force_language', false) === false ||
465
-				$this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
466
-				$permittedFields[] = 'language';
467
-			}
468
-
469
-			if ($this->config->getSystemValue('force_locale', false) === false ||
470
-				$this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
471
-				$permittedFields[] = 'locale';
472
-			}
473
-
474
-			if ($this->appManager->isEnabledForUser('federatedfilesharing')) {
475
-				$shareProvider = $this->federatedShareProviderFactory->get();
476
-				if ($shareProvider->isLookupServerUploadEnabled()) {
477
-					$permittedFields[] = AccountManager::PROPERTY_PHONE;
478
-					$permittedFields[] = AccountManager::PROPERTY_ADDRESS;
479
-					$permittedFields[] = AccountManager::PROPERTY_WEBSITE;
480
-					$permittedFields[] = AccountManager::PROPERTY_TWITTER;
481
-				}
482
-			}
483
-
484
-			// If admin they can edit their own quota
485
-			if ($this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
486
-				$permittedFields[] = 'quota';
487
-			}
488
-		} else {
489
-			// Check if admin / subadmin
490
-			$subAdminManager = $this->groupManager->getSubAdmin();
491
-			if ($this->groupManager->isAdmin($currentLoggedInUser->getUID())
492
-			|| $subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
493
-				// They have permissions over the user
494
-				$permittedFields[] = 'display';
495
-				$permittedFields[] = AccountManager::PROPERTY_DISPLAYNAME;
496
-				$permittedFields[] = AccountManager::PROPERTY_EMAIL;
497
-				$permittedFields[] = 'password';
498
-				$permittedFields[] = 'language';
499
-				$permittedFields[] = 'locale';
500
-				$permittedFields[] = AccountManager::PROPERTY_PHONE;
501
-				$permittedFields[] = AccountManager::PROPERTY_ADDRESS;
502
-				$permittedFields[] = AccountManager::PROPERTY_WEBSITE;
503
-				$permittedFields[] = AccountManager::PROPERTY_TWITTER;
504
-				$permittedFields[] = 'quota';
505
-			} else {
506
-				// No rights
507
-				throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
508
-			}
509
-		}
510
-		// Check if permitted to edit this field
511
-		if (!in_array($key, $permittedFields)) {
512
-			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
513
-		}
514
-		// Process the edit
515
-		switch ($key) {
516
-			case 'display':
517
-			case AccountManager::PROPERTY_DISPLAYNAME:
518
-				$targetUser->setDisplayName($value);
519
-				break;
520
-			case 'quota':
521
-				$quota = $value;
522
-				if ($quota !== 'none' && $quota !== 'default') {
523
-					if (is_numeric($quota)) {
524
-						$quota = (float) $quota;
525
-					} else {
526
-						$quota = \OCP\Util::computerFileSize($quota);
527
-					}
528
-					if ($quota === false) {
529
-						throw new OCSException('Invalid quota value '.$value, 103);
530
-					}
531
-					if ($quota === -1) {
532
-						$quota = 'none';
533
-					} else {
534
-						$quota = \OCP\Util::humanFileSize($quota);
535
-					}
536
-				}
537
-				$targetUser->setQuota($quota);
538
-				break;
539
-			case 'password':
540
-				try {
541
-					if (!$targetUser->canChangePassword()) {
542
-						throw new OCSException('Setting the password is not supported by the users backend', 103);
543
-					}
544
-					$targetUser->setPassword($value);
545
-				} catch (HintException $e) { // password policy error
546
-					throw new OCSException($e->getMessage(), 103);
547
-				}
548
-				break;
549
-			case 'language':
550
-				$languagesCodes = $this->l10nFactory->findAvailableLanguages();
551
-				if (!in_array($value, $languagesCodes, true) && $value !== 'en') {
552
-					throw new OCSException('Invalid language', 102);
553
-				}
554
-				$this->config->setUserValue($targetUser->getUID(), 'core', 'lang', $value);
555
-				break;
556
-			case 'locale':
557
-				if (!$this->l10nFactory->localeExists($value)) {
558
-					throw new OCSException('Invalid locale', 102);
559
-				}
560
-				$this->config->setUserValue($targetUser->getUID(), 'core', 'locale', $value);
561
-				break;
562
-			case AccountManager::PROPERTY_EMAIL:
563
-				if (filter_var($value, FILTER_VALIDATE_EMAIL) || $value === '') {
564
-					$targetUser->setEMailAddress($value);
565
-				} else {
566
-					throw new OCSException('', 102);
567
-				}
568
-				break;
569
-			case AccountManager::PROPERTY_PHONE:
570
-			case AccountManager::PROPERTY_ADDRESS:
571
-			case AccountManager::PROPERTY_WEBSITE:
572
-			case AccountManager::PROPERTY_TWITTER:
573
-				$userAccount = $this->accountManager->getUser($targetUser);
574
-				if ($userAccount[$key]['value'] !== $value) {
575
-					$userAccount[$key]['value'] = $value;
576
-					$this->accountManager->updateUser($targetUser, $userAccount);
577
-				}
578
-				break;
579
-			default:
580
-				throw new OCSException('', 103);
581
-		}
582
-		return new DataResponse();
583
-	}
584
-
585
-	/**
586
-	 * @PasswordConfirmationRequired
587
-	 * @NoAdminRequired
588
-	 *
589
-	 * @param string $userId
590
-	 *
591
-	 * @return DataResponse
592
-	 *
593
-	 * @throws OCSException
594
-	 */
595
-	public function wipeUserDevices(string $userId): DataResponse {
596
-		/** @var IUser $currentLoggedInUser */
597
-		$currentLoggedInUser = $this->userSession->getUser();
598
-
599
-		$targetUser = $this->userManager->get($userId);
600
-
601
-		if ($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
602
-			throw new OCSException('', 101);
603
-		}
604
-
605
-		// If not permitted
606
-		$subAdminManager = $this->groupManager->getSubAdmin();
607
-		if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
608
-			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
609
-		}
610
-
611
-		$this->remoteWipe->markAllTokensForWipe($targetUser);
612
-
613
-		return new DataResponse();
614
-	}
615
-
616
-	/**
617
-	 * @PasswordConfirmationRequired
618
-	 * @NoAdminRequired
619
-	 *
620
-	 * @param string $userId
621
-	 * @return DataResponse
622
-	 * @throws OCSException
623
-	 */
624
-	public function deleteUser(string $userId): DataResponse {
625
-		$currentLoggedInUser = $this->userSession->getUser();
626
-
627
-		$targetUser = $this->userManager->get($userId);
628
-
629
-		if ($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
630
-			throw new OCSException('', 101);
631
-		}
632
-
633
-		// If not permitted
634
-		$subAdminManager = $this->groupManager->getSubAdmin();
635
-		if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
636
-			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
637
-		}
638
-
639
-		// Go ahead with the delete
640
-		if ($targetUser->delete()) {
641
-			return new DataResponse();
642
-		} else {
643
-			throw new OCSException('', 101);
644
-		}
645
-	}
646
-
647
-	/**
648
-	 * @PasswordConfirmationRequired
649
-	 * @NoAdminRequired
650
-	 *
651
-	 * @param string $userId
652
-	 * @return DataResponse
653
-	 * @throws OCSException
654
-	 * @throws OCSForbiddenException
655
-	 */
656
-	public function disableUser(string $userId): DataResponse {
657
-		return $this->setEnabled($userId, false);
658
-	}
659
-
660
-	/**
661
-	 * @PasswordConfirmationRequired
662
-	 * @NoAdminRequired
663
-	 *
664
-	 * @param string $userId
665
-	 * @return DataResponse
666
-	 * @throws OCSException
667
-	 * @throws OCSForbiddenException
668
-	 */
669
-	public function enableUser(string $userId): DataResponse {
670
-		return $this->setEnabled($userId, true);
671
-	}
672
-
673
-	/**
674
-	 * @param string $userId
675
-	 * @param bool $value
676
-	 * @return DataResponse
677
-	 * @throws OCSException
678
-	 */
679
-	private function setEnabled(string $userId, bool $value): DataResponse {
680
-		$currentLoggedInUser = $this->userSession->getUser();
681
-
682
-		$targetUser = $this->userManager->get($userId);
683
-		if ($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
684
-			throw new OCSException('', 101);
685
-		}
686
-
687
-		// If not permitted
688
-		$subAdminManager = $this->groupManager->getSubAdmin();
689
-		if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
690
-			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
691
-		}
692
-
693
-		// enable/disable the user now
694
-		$targetUser->setEnabled($value);
695
-		return new DataResponse();
696
-	}
697
-
698
-	/**
699
-	 * @NoAdminRequired
700
-	 * @NoSubAdminRequired
701
-	 *
702
-	 * @param string $userId
703
-	 * @return DataResponse
704
-	 * @throws OCSException
705
-	 */
706
-	public function getUsersGroups(string $userId): DataResponse {
707
-		$loggedInUser = $this->userSession->getUser();
708
-
709
-		$targetUser = $this->userManager->get($userId);
710
-		if ($targetUser === null) {
711
-			throw new OCSException('', \OCP\API::RESPOND_NOT_FOUND);
712
-		}
713
-
714
-		if ($targetUser->getUID() === $loggedInUser->getUID() || $this->groupManager->isAdmin($loggedInUser->getUID())) {
715
-			// Self lookup or admin lookup
716
-			return new DataResponse([
717
-				'groups' => $this->groupManager->getUserGroupIds($targetUser)
718
-			]);
719
-		} else {
720
-			$subAdminManager = $this->groupManager->getSubAdmin();
721
-
722
-			// Looking up someone else
723
-			if ($subAdminManager->isUserAccessible($loggedInUser, $targetUser)) {
724
-				// Return the group that the method caller is subadmin of for the user in question
725
-				/** @var IGroup[] $getSubAdminsGroups */
726
-				$getSubAdminsGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
727
-				foreach ($getSubAdminsGroups as $key => $group) {
728
-					$getSubAdminsGroups[$key] = $group->getGID();
729
-				}
730
-				$groups = array_intersect(
731
-					$getSubAdminsGroups,
732
-					$this->groupManager->getUserGroupIds($targetUser)
733
-				);
734
-				return new DataResponse(['groups' => $groups]);
735
-			} else {
736
-				// Not permitted
737
-				throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
738
-			}
739
-		}
740
-	}
741
-
742
-	/**
743
-	 * @PasswordConfirmationRequired
744
-	 * @NoAdminRequired
745
-	 *
746
-	 * @param string $userId
747
-	 * @param string $groupid
748
-	 * @return DataResponse
749
-	 * @throws OCSException
750
-	 */
751
-	public function addToGroup(string $userId, string $groupid = ''): DataResponse {
752
-		if ($groupid === '') {
753
-			throw new OCSException('', 101);
754
-		}
755
-
756
-		$group = $this->groupManager->get($groupid);
757
-		$targetUser = $this->userManager->get($userId);
758
-		if ($group === null) {
759
-			throw new OCSException('', 102);
760
-		}
761
-		if ($targetUser === null) {
762
-			throw new OCSException('', 103);
763
-		}
764
-
765
-		// If they're not an admin, check they are a subadmin of the group in question
766
-		$loggedInUser = $this->userSession->getUser();
767
-		$subAdminManager = $this->groupManager->getSubAdmin();
768
-		if (!$this->groupManager->isAdmin($loggedInUser->getUID()) && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
769
-			throw new OCSException('', 104);
770
-		}
771
-
772
-		// Add user to group
773
-		$group->addUser($targetUser);
774
-		return new DataResponse();
775
-	}
776
-
777
-	/**
778
-	 * @PasswordConfirmationRequired
779
-	 * @NoAdminRequired
780
-	 *
781
-	 * @param string $userId
782
-	 * @param string $groupid
783
-	 * @return DataResponse
784
-	 * @throws OCSException
785
-	 */
786
-	public function removeFromGroup(string $userId, string $groupid): DataResponse {
787
-		$loggedInUser = $this->userSession->getUser();
788
-
789
-		if ($groupid === null || trim($groupid) === '') {
790
-			throw new OCSException('', 101);
791
-		}
792
-
793
-		$group = $this->groupManager->get($groupid);
794
-		if ($group === null) {
795
-			throw new OCSException('', 102);
796
-		}
797
-
798
-		$targetUser = $this->userManager->get($userId);
799
-		if ($targetUser === null) {
800
-			throw new OCSException('', 103);
801
-		}
802
-
803
-		// If they're not an admin, check they are a subadmin of the group in question
804
-		$subAdminManager = $this->groupManager->getSubAdmin();
805
-		if (!$this->groupManager->isAdmin($loggedInUser->getUID()) && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
806
-			throw new OCSException('', 104);
807
-		}
808
-
809
-		// Check they aren't removing themselves from 'admin' or their 'subadmin; group
810
-		if ($targetUser->getUID() === $loggedInUser->getUID()) {
811
-			if ($this->groupManager->isAdmin($loggedInUser->getUID())) {
812
-				if ($group->getGID() === 'admin') {
813
-					throw new OCSException('Cannot remove yourself from the admin group', 105);
814
-				}
815
-			} else {
816
-				// Not an admin, so the user must be a subadmin of this group, but that is not allowed.
817
-				throw new OCSException('Cannot remove yourself from this group as you are a SubAdmin', 105);
818
-			}
819
-		} elseif (!$this->groupManager->isAdmin($loggedInUser->getUID())) {
820
-			/** @var IGroup[] $subAdminGroups */
821
-			$subAdminGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
822
-			$subAdminGroups = array_map(function (IGroup $subAdminGroup) {
823
-				return $subAdminGroup->getGID();
824
-			}, $subAdminGroups);
825
-			$userGroups = $this->groupManager->getUserGroupIds($targetUser);
826
-			$userSubAdminGroups = array_intersect($subAdminGroups, $userGroups);
827
-
828
-			if (count($userSubAdminGroups) <= 1) {
829
-				// Subadmin must not be able to remove a user from all their subadmin groups.
830
-				throw new OCSException('Not viable to remove user from the last group you are SubAdmin of', 105);
831
-			}
832
-		}
833
-
834
-		// Remove user from group
835
-		$group->removeUser($targetUser);
836
-		return new DataResponse();
837
-	}
838
-
839
-	/**
840
-	 * Creates a subadmin
841
-	 *
842
-	 * @PasswordConfirmationRequired
843
-	 *
844
-	 * @param string $userId
845
-	 * @param string $groupid
846
-	 * @return DataResponse
847
-	 * @throws OCSException
848
-	 */
849
-	public function addSubAdmin(string $userId, string $groupid): DataResponse {
850
-		$group = $this->groupManager->get($groupid);
851
-		$user = $this->userManager->get($userId);
852
-
853
-		// Check if the user exists
854
-		if ($user === null) {
855
-			throw new OCSException('User does not exist', 101);
856
-		}
857
-		// Check if group exists
858
-		if ($group === null) {
859
-			throw new OCSException('Group does not exist',  102);
860
-		}
861
-		// Check if trying to make subadmin of admin group
862
-		if ($group->getGID() === 'admin') {
863
-			throw new OCSException('Cannot create subadmins for admin group', 103);
864
-		}
865
-
866
-		$subAdminManager = $this->groupManager->getSubAdmin();
867
-
868
-		// We cannot be subadmin twice
869
-		if ($subAdminManager->isSubAdminOfGroup($user, $group)) {
870
-			return new DataResponse();
871
-		}
872
-		// Go
873
-		$subAdminManager->createSubAdmin($user, $group);
874
-		return new DataResponse();
875
-	}
876
-
877
-	/**
878
-	 * Removes a subadmin from a group
879
-	 *
880
-	 * @PasswordConfirmationRequired
881
-	 *
882
-	 * @param string $userId
883
-	 * @param string $groupid
884
-	 * @return DataResponse
885
-	 * @throws OCSException
886
-	 */
887
-	public function removeSubAdmin(string $userId, string $groupid): DataResponse {
888
-		$group = $this->groupManager->get($groupid);
889
-		$user = $this->userManager->get($userId);
890
-		$subAdminManager = $this->groupManager->getSubAdmin();
891
-
892
-		// Check if the user exists
893
-		if ($user === null) {
894
-			throw new OCSException('User does not exist', 101);
895
-		}
896
-		// Check if the group exists
897
-		if ($group === null) {
898
-			throw new OCSException('Group does not exist', 101);
899
-		}
900
-		// Check if they are a subadmin of this said group
901
-		if (!$subAdminManager->isSubAdminOfGroup($user, $group)) {
902
-			throw new OCSException('User is not a subadmin of this group', 102);
903
-		}
904
-
905
-		// Go
906
-		$subAdminManager->deleteSubAdmin($user, $group);
907
-		return new DataResponse();
908
-	}
909
-
910
-	/**
911
-	 * Get the groups a user is a subadmin of
912
-	 *
913
-	 * @param string $userId
914
-	 * @return DataResponse
915
-	 * @throws OCSException
916
-	 */
917
-	public function getUserSubAdminGroups(string $userId): DataResponse {
918
-		$groups = $this->getUserSubAdminGroupsData($userId);
919
-		return new DataResponse($groups);
920
-	}
921
-
922
-	/**
923
-	 * @NoAdminRequired
924
-	 * @PasswordConfirmationRequired
925
-	 *
926
-	 * resend welcome message
927
-	 *
928
-	 * @param string $userId
929
-	 * @return DataResponse
930
-	 * @throws OCSException
931
-	 */
932
-	public function resendWelcomeMessage(string $userId): DataResponse {
933
-		$currentLoggedInUser = $this->userSession->getUser();
934
-
935
-		$targetUser = $this->userManager->get($userId);
936
-		if ($targetUser === null) {
937
-			throw new OCSException('', \OCP\API::RESPOND_NOT_FOUND);
938
-		}
939
-
940
-		// Check if admin / subadmin
941
-		$subAdminManager = $this->groupManager->getSubAdmin();
942
-		if (!$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
943
-			&& !$this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
944
-			// No rights
945
-			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
946
-		}
947
-
948
-		$email = $targetUser->getEMailAddress();
949
-		if ($email === '' || $email === null) {
950
-			throw new OCSException('Email address not available', 101);
951
-		}
952
-
953
-		try {
954
-			$emailTemplate = $this->newUserMailHelper->generateTemplate($targetUser, false);
955
-			$this->newUserMailHelper->sendMail($targetUser, $emailTemplate);
956
-		} catch (\Exception $e) {
957
-			$this->logger->logException($e, [
958
-				'message' => "Can't send new user mail to $email",
959
-				'level' => ILogger::ERROR,
960
-				'app' => 'settings',
961
-			]);
962
-			throw new OCSException('Sending email failed', 102);
963
-		}
964
-
965
-		return new DataResponse();
966
-	}
65
+    /** @var IAppManager */
66
+    private $appManager;
67
+    /** @var ILogger */
68
+    private $logger;
69
+    /** @var IFactory */
70
+    protected $l10nFactory;
71
+    /** @var NewUserMailHelper */
72
+    private $newUserMailHelper;
73
+    /** @var FederatedShareProviderFactory */
74
+    private $federatedShareProviderFactory;
75
+    /** @var ISecureRandom */
76
+    private $secureRandom;
77
+    /** @var RemoteWipe */
78
+    private $remoteWipe;
79
+
80
+    public function __construct(string $appName,
81
+                                IRequest $request,
82
+                                IUserManager $userManager,
83
+                                IConfig $config,
84
+                                IAppManager $appManager,
85
+                                IGroupManager $groupManager,
86
+                                IUserSession $userSession,
87
+                                AccountManager $accountManager,
88
+                                ILogger $logger,
89
+                                IFactory $l10nFactory,
90
+                                NewUserMailHelper $newUserMailHelper,
91
+                                FederatedShareProviderFactory $federatedShareProviderFactory,
92
+                                ISecureRandom $secureRandom,
93
+                                RemoteWipe $remoteWipe) {
94
+        parent::__construct($appName,
95
+                            $request,
96
+                            $userManager,
97
+                            $config,
98
+                            $groupManager,
99
+                            $userSession,
100
+                            $accountManager,
101
+                            $l10nFactory);
102
+
103
+        $this->appManager = $appManager;
104
+        $this->logger = $logger;
105
+        $this->l10nFactory = $l10nFactory;
106
+        $this->newUserMailHelper = $newUserMailHelper;
107
+        $this->federatedShareProviderFactory = $federatedShareProviderFactory;
108
+        $this->secureRandom = $secureRandom;
109
+        $this->remoteWipe = $remoteWipe;
110
+    }
111
+
112
+    /**
113
+     * @NoAdminRequired
114
+     *
115
+     * returns a list of users
116
+     *
117
+     * @param string $search
118
+     * @param int $limit
119
+     * @param int $offset
120
+     * @return DataResponse
121
+     */
122
+    public function getUsers(string $search = '', int $limit = null, int $offset = 0): DataResponse {
123
+        $user = $this->userSession->getUser();
124
+        $users = [];
125
+
126
+        // Admin? Or SubAdmin?
127
+        $uid = $user->getUID();
128
+        $subAdminManager = $this->groupManager->getSubAdmin();
129
+        if ($this->groupManager->isAdmin($uid)) {
130
+            $users = $this->userManager->search($search, $limit, $offset);
131
+        } elseif ($subAdminManager->isSubAdmin($user)) {
132
+            $subAdminOfGroups = $subAdminManager->getSubAdminsGroups($user);
133
+            foreach ($subAdminOfGroups as $key => $group) {
134
+                $subAdminOfGroups[$key] = $group->getGID();
135
+            }
136
+
137
+            $users = [];
138
+            foreach ($subAdminOfGroups as $group) {
139
+                $users = array_merge($users, $this->groupManager->displayNamesInGroup($group, $search, $limit, $offset));
140
+            }
141
+        }
142
+
143
+        $users = array_keys($users);
144
+
145
+        return new DataResponse([
146
+            'users' => $users
147
+        ]);
148
+    }
149
+
150
+    /**
151
+     * @NoAdminRequired
152
+     *
153
+     * returns a list of users and their data
154
+     */
155
+    public function getUsersDetails(string $search = '', int $limit = null, int $offset = 0): DataResponse {
156
+        $currentUser = $this->userSession->getUser();
157
+        $users = [];
158
+
159
+        // Admin? Or SubAdmin?
160
+        $uid = $currentUser->getUID();
161
+        $subAdminManager = $this->groupManager->getSubAdmin();
162
+        if ($this->groupManager->isAdmin($uid)) {
163
+            $users = $this->userManager->search($search, $limit, $offset);
164
+            $users = array_keys($users);
165
+        } elseif ($subAdminManager->isSubAdmin($currentUser)) {
166
+            $subAdminOfGroups = $subAdminManager->getSubAdminsGroups($currentUser);
167
+            foreach ($subAdminOfGroups as $key => $group) {
168
+                $subAdminOfGroups[$key] = $group->getGID();
169
+            }
170
+
171
+            $users = [];
172
+            foreach ($subAdminOfGroups as $group) {
173
+                $users[] = array_keys($this->groupManager->displayNamesInGroup($group, $search, $limit, $offset));
174
+            }
175
+            $users = array_merge(...$users);
176
+        }
177
+
178
+        $usersDetails = [];
179
+        foreach ($users as $userId) {
180
+            $userId = (string) $userId;
181
+            $userData = $this->getUserData($userId);
182
+            // Do not insert empty entry
183
+            if (!empty($userData)) {
184
+                $usersDetails[$userId] = $userData;
185
+            } else {
186
+                // Logged user does not have permissions to see this user
187
+                // only showing its id
188
+                $usersDetails[$userId] = ['id' => $userId];
189
+            }
190
+        }
191
+
192
+        return new DataResponse([
193
+            'users' => $usersDetails
194
+        ]);
195
+    }
196
+
197
+    /**
198
+     * @throws OCSException
199
+     */
200
+    private function createNewUserId(): string {
201
+        $attempts = 0;
202
+        do {
203
+            $uidCandidate = $this->secureRandom->generate(10, ISecureRandom::CHAR_HUMAN_READABLE);
204
+            if (!$this->userManager->userExists($uidCandidate)) {
205
+                return $uidCandidate;
206
+            }
207
+            $attempts++;
208
+        } while ($attempts < 10);
209
+        throw new OCSException('Could not create non-existing user id', 111);
210
+    }
211
+
212
+    /**
213
+     * @PasswordConfirmationRequired
214
+     * @NoAdminRequired
215
+     *
216
+     * @param string $userid
217
+     * @param string $password
218
+     * @param string $displayName
219
+     * @param string $email
220
+     * @param array $groups
221
+     * @param array $subadmin
222
+     * @param string $quota
223
+     * @param string $language
224
+     * @return DataResponse
225
+     * @throws OCSException
226
+     */
227
+    public function addUser(string $userid,
228
+                            string $password = '',
229
+                            string $displayName = '',
230
+                            string $email = '',
231
+                            array $groups = [],
232
+                            array $subadmin = [],
233
+                            string $quota = '',
234
+                            string $language = ''): DataResponse {
235
+        $user = $this->userSession->getUser();
236
+        $isAdmin = $this->groupManager->isAdmin($user->getUID());
237
+        $subAdminManager = $this->groupManager->getSubAdmin();
238
+
239
+        if (empty($userid) && $this->config->getAppValue('core', 'newUser.generateUserID', 'no') === 'yes') {
240
+            $userid = $this->createNewUserId();
241
+        }
242
+
243
+        if ($this->userManager->userExists($userid)) {
244
+            $this->logger->error('Failed addUser attempt: User already exists.', ['app' => 'ocs_api']);
245
+            throw new OCSException('User already exists', 102);
246
+        }
247
+
248
+        if ($groups !== []) {
249
+            foreach ($groups as $group) {
250
+                if (!$this->groupManager->groupExists($group)) {
251
+                    throw new OCSException('group '.$group.' does not exist', 104);
252
+                }
253
+                if (!$isAdmin && !$subAdminManager->isSubAdminOfGroup($user, $this->groupManager->get($group))) {
254
+                    throw new OCSException('insufficient privileges for group '. $group, 105);
255
+                }
256
+            }
257
+        } else {
258
+            if (!$isAdmin) {
259
+                throw new OCSException('no group specified (required for subadmins)', 106);
260
+            }
261
+        }
262
+
263
+        $subadminGroups = [];
264
+        if ($subadmin !== []) {
265
+            foreach ($subadmin as $groupid) {
266
+                $group = $this->groupManager->get($groupid);
267
+                // Check if group exists
268
+                if ($group === null) {
269
+                    throw new OCSException('Subadmin group does not exist',  102);
270
+                }
271
+                // Check if trying to make subadmin of admin group
272
+                if ($group->getGID() === 'admin') {
273
+                    throw new OCSException('Cannot create subadmins for admin group', 103);
274
+                }
275
+                // Check if has permission to promote subadmins
276
+                if (!$subAdminManager->isSubAdminOfGroup($user, $group) && !$isAdmin) {
277
+                    throw new OCSForbiddenException('No permissions to promote subadmins');
278
+                }
279
+                $subadminGroups[] = $group;
280
+            }
281
+        }
282
+
283
+        $generatePasswordResetToken = false;
284
+        if ($password === '') {
285
+            if ($email === '') {
286
+                throw new OCSException('To send a password link to the user an email address is required.', 108);
287
+            }
288
+
289
+            $password = $this->secureRandom->generate(10);
290
+            // Make sure we pass the password_policy
291
+            $password .= $this->secureRandom->generate(2, '$!.,;:-~+*[]{}()');
292
+            $generatePasswordResetToken = true;
293
+        }
294
+
295
+        if ($email === '' && $this->config->getAppValue('core', 'newUser.requireEmail', 'no') === 'yes') {
296
+            throw new OCSException('Required email address was not provided', 110);
297
+        }
298
+
299
+        try {
300
+            $newUser = $this->userManager->createUser($userid, $password);
301
+            $this->logger->info('Successful addUser call with userid: ' . $userid, ['app' => 'ocs_api']);
302
+
303
+            foreach ($groups as $group) {
304
+                $this->groupManager->get($group)->addUser($newUser);
305
+                $this->logger->info('Added userid ' . $userid . ' to group ' . $group, ['app' => 'ocs_api']);
306
+            }
307
+            foreach ($subadminGroups as $group) {
308
+                $subAdminManager->createSubAdmin($newUser, $group);
309
+            }
310
+
311
+            if ($displayName !== '') {
312
+                $this->editUser($userid, 'display', $displayName);
313
+            }
314
+
315
+            if ($quota !== '') {
316
+                $this->editUser($userid, 'quota', $quota);
317
+            }
318
+
319
+            if ($language !== '') {
320
+                $this->editUser($userid, 'language', $language);
321
+            }
322
+
323
+            // Send new user mail only if a mail is set
324
+            if ($email !== '' && $this->config->getAppValue('core', 'newUser.sendEmail', 'yes') === 'yes') {
325
+                $newUser->setEMailAddress($email);
326
+                try {
327
+                    $emailTemplate = $this->newUserMailHelper->generateTemplate($newUser, $generatePasswordResetToken);
328
+                    $this->newUserMailHelper->sendMail($newUser, $emailTemplate);
329
+                } catch (\Exception $e) {
330
+                    // Mail could be failing hard or just be plain not configured
331
+                    // Logging error as it is the hardest of the two
332
+                    $this->logger->logException($e, [
333
+                        'message' => "Unable to send the invitation mail to $email",
334
+                        'level' => ILogger::ERROR,
335
+                        'app' => 'ocs_api',
336
+                    ]);
337
+                }
338
+            }
339
+
340
+            return new DataResponse(['id' => $userid]);
341
+        } catch (HintException $e) {
342
+            $this->logger->logException($e, [
343
+                'message' => 'Failed addUser attempt with hint exception.',
344
+                'level' => ILogger::WARN,
345
+                'app' => 'ocs_api',
346
+            ]);
347
+            throw new OCSException($e->getHint(), 107);
348
+        } catch (OCSException $e) {
349
+            $this->logger->logException($e, [
350
+                'message' => 'Failed addUser attempt with ocs exeption.',
351
+                'level' => ILogger::ERROR,
352
+                'app' => 'ocs_api',
353
+            ]);
354
+            throw $e;
355
+        } catch (\Exception $e) {
356
+            $this->logger->logException($e, [
357
+                'message' => 'Failed addUser attempt with exception.',
358
+                'level' => ILogger::ERROR,
359
+                'app' => 'ocs_api',
360
+            ]);
361
+            throw new OCSException('Bad request', 101);
362
+        }
363
+    }
364
+
365
+    /**
366
+     * @NoAdminRequired
367
+     * @NoSubAdminRequired
368
+     *
369
+     * gets user info
370
+     *
371
+     * @param string $userId
372
+     * @return DataResponse
373
+     * @throws OCSException
374
+     */
375
+    public function getUser(string $userId): DataResponse {
376
+        $data = $this->getUserData($userId);
377
+        // getUserData returns empty array if not enough permissions
378
+        if (empty($data)) {
379
+            throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
380
+        }
381
+        return new DataResponse($data);
382
+    }
383
+
384
+    /**
385
+     * @NoAdminRequired
386
+     * @NoSubAdminRequired
387
+     *
388
+     * gets user info from the currently logged in user
389
+     *
390
+     * @return DataResponse
391
+     * @throws OCSException
392
+     */
393
+    public function getCurrentUser(): DataResponse {
394
+        $user = $this->userSession->getUser();
395
+        if ($user) {
396
+            $data =  $this->getUserData($user->getUID());
397
+            // rename "displayname" to "display-name" only for this call to keep
398
+            // the API stable.
399
+            $data['display-name'] = $data['displayname'];
400
+            unset($data['displayname']);
401
+            return new DataResponse($data);
402
+        }
403
+
404
+        throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
405
+    }
406
+
407
+    /**
408
+     * @NoAdminRequired
409
+     * @NoSubAdminRequired
410
+     */
411
+    public function getEditableFields(): DataResponse {
412
+        $permittedFields = [];
413
+
414
+        // Editing self (display, email)
415
+        if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
416
+            $permittedFields[] = AccountManager::PROPERTY_DISPLAYNAME;
417
+            $permittedFields[] = AccountManager::PROPERTY_EMAIL;
418
+        }
419
+
420
+        if ($this->appManager->isEnabledForUser('federatedfilesharing')) {
421
+            $shareProvider = $this->federatedShareProviderFactory->get();
422
+            if ($shareProvider->isLookupServerUploadEnabled()) {
423
+                $permittedFields[] = AccountManager::PROPERTY_PHONE;
424
+                $permittedFields[] = AccountManager::PROPERTY_ADDRESS;
425
+                $permittedFields[] = AccountManager::PROPERTY_WEBSITE;
426
+                $permittedFields[] = AccountManager::PROPERTY_TWITTER;
427
+            }
428
+        }
429
+
430
+        return new DataResponse($permittedFields);
431
+    }
432
+
433
+    /**
434
+     * @NoAdminRequired
435
+     * @NoSubAdminRequired
436
+     * @PasswordConfirmationRequired
437
+     *
438
+     * edit users
439
+     *
440
+     * @param string $userId
441
+     * @param string $key
442
+     * @param string $value
443
+     * @return DataResponse
444
+     * @throws OCSException
445
+     */
446
+    public function editUser(string $userId, string $key, string $value): DataResponse {
447
+        $currentLoggedInUser = $this->userSession->getUser();
448
+
449
+        $targetUser = $this->userManager->get($userId);
450
+        if ($targetUser === null) {
451
+            throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
452
+        }
453
+
454
+        $permittedFields = [];
455
+        if ($targetUser->getUID() === $currentLoggedInUser->getUID()) {
456
+            // Editing self (display, email)
457
+            if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
458
+                $permittedFields[] = 'display';
459
+                $permittedFields[] = AccountManager::PROPERTY_DISPLAYNAME;
460
+                $permittedFields[] = AccountManager::PROPERTY_EMAIL;
461
+            }
462
+
463
+            $permittedFields[] = 'password';
464
+            if ($this->config->getSystemValue('force_language', false) === false ||
465
+                $this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
466
+                $permittedFields[] = 'language';
467
+            }
468
+
469
+            if ($this->config->getSystemValue('force_locale', false) === false ||
470
+                $this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
471
+                $permittedFields[] = 'locale';
472
+            }
473
+
474
+            if ($this->appManager->isEnabledForUser('federatedfilesharing')) {
475
+                $shareProvider = $this->federatedShareProviderFactory->get();
476
+                if ($shareProvider->isLookupServerUploadEnabled()) {
477
+                    $permittedFields[] = AccountManager::PROPERTY_PHONE;
478
+                    $permittedFields[] = AccountManager::PROPERTY_ADDRESS;
479
+                    $permittedFields[] = AccountManager::PROPERTY_WEBSITE;
480
+                    $permittedFields[] = AccountManager::PROPERTY_TWITTER;
481
+                }
482
+            }
483
+
484
+            // If admin they can edit their own quota
485
+            if ($this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
486
+                $permittedFields[] = 'quota';
487
+            }
488
+        } else {
489
+            // Check if admin / subadmin
490
+            $subAdminManager = $this->groupManager->getSubAdmin();
491
+            if ($this->groupManager->isAdmin($currentLoggedInUser->getUID())
492
+            || $subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
493
+                // They have permissions over the user
494
+                $permittedFields[] = 'display';
495
+                $permittedFields[] = AccountManager::PROPERTY_DISPLAYNAME;
496
+                $permittedFields[] = AccountManager::PROPERTY_EMAIL;
497
+                $permittedFields[] = 'password';
498
+                $permittedFields[] = 'language';
499
+                $permittedFields[] = 'locale';
500
+                $permittedFields[] = AccountManager::PROPERTY_PHONE;
501
+                $permittedFields[] = AccountManager::PROPERTY_ADDRESS;
502
+                $permittedFields[] = AccountManager::PROPERTY_WEBSITE;
503
+                $permittedFields[] = AccountManager::PROPERTY_TWITTER;
504
+                $permittedFields[] = 'quota';
505
+            } else {
506
+                // No rights
507
+                throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
508
+            }
509
+        }
510
+        // Check if permitted to edit this field
511
+        if (!in_array($key, $permittedFields)) {
512
+            throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
513
+        }
514
+        // Process the edit
515
+        switch ($key) {
516
+            case 'display':
517
+            case AccountManager::PROPERTY_DISPLAYNAME:
518
+                $targetUser->setDisplayName($value);
519
+                break;
520
+            case 'quota':
521
+                $quota = $value;
522
+                if ($quota !== 'none' && $quota !== 'default') {
523
+                    if (is_numeric($quota)) {
524
+                        $quota = (float) $quota;
525
+                    } else {
526
+                        $quota = \OCP\Util::computerFileSize($quota);
527
+                    }
528
+                    if ($quota === false) {
529
+                        throw new OCSException('Invalid quota value '.$value, 103);
530
+                    }
531
+                    if ($quota === -1) {
532
+                        $quota = 'none';
533
+                    } else {
534
+                        $quota = \OCP\Util::humanFileSize($quota);
535
+                    }
536
+                }
537
+                $targetUser->setQuota($quota);
538
+                break;
539
+            case 'password':
540
+                try {
541
+                    if (!$targetUser->canChangePassword()) {
542
+                        throw new OCSException('Setting the password is not supported by the users backend', 103);
543
+                    }
544
+                    $targetUser->setPassword($value);
545
+                } catch (HintException $e) { // password policy error
546
+                    throw new OCSException($e->getMessage(), 103);
547
+                }
548
+                break;
549
+            case 'language':
550
+                $languagesCodes = $this->l10nFactory->findAvailableLanguages();
551
+                if (!in_array($value, $languagesCodes, true) && $value !== 'en') {
552
+                    throw new OCSException('Invalid language', 102);
553
+                }
554
+                $this->config->setUserValue($targetUser->getUID(), 'core', 'lang', $value);
555
+                break;
556
+            case 'locale':
557
+                if (!$this->l10nFactory->localeExists($value)) {
558
+                    throw new OCSException('Invalid locale', 102);
559
+                }
560
+                $this->config->setUserValue($targetUser->getUID(), 'core', 'locale', $value);
561
+                break;
562
+            case AccountManager::PROPERTY_EMAIL:
563
+                if (filter_var($value, FILTER_VALIDATE_EMAIL) || $value === '') {
564
+                    $targetUser->setEMailAddress($value);
565
+                } else {
566
+                    throw new OCSException('', 102);
567
+                }
568
+                break;
569
+            case AccountManager::PROPERTY_PHONE:
570
+            case AccountManager::PROPERTY_ADDRESS:
571
+            case AccountManager::PROPERTY_WEBSITE:
572
+            case AccountManager::PROPERTY_TWITTER:
573
+                $userAccount = $this->accountManager->getUser($targetUser);
574
+                if ($userAccount[$key]['value'] !== $value) {
575
+                    $userAccount[$key]['value'] = $value;
576
+                    $this->accountManager->updateUser($targetUser, $userAccount);
577
+                }
578
+                break;
579
+            default:
580
+                throw new OCSException('', 103);
581
+        }
582
+        return new DataResponse();
583
+    }
584
+
585
+    /**
586
+     * @PasswordConfirmationRequired
587
+     * @NoAdminRequired
588
+     *
589
+     * @param string $userId
590
+     *
591
+     * @return DataResponse
592
+     *
593
+     * @throws OCSException
594
+     */
595
+    public function wipeUserDevices(string $userId): DataResponse {
596
+        /** @var IUser $currentLoggedInUser */
597
+        $currentLoggedInUser = $this->userSession->getUser();
598
+
599
+        $targetUser = $this->userManager->get($userId);
600
+
601
+        if ($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
602
+            throw new OCSException('', 101);
603
+        }
604
+
605
+        // If not permitted
606
+        $subAdminManager = $this->groupManager->getSubAdmin();
607
+        if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
608
+            throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
609
+        }
610
+
611
+        $this->remoteWipe->markAllTokensForWipe($targetUser);
612
+
613
+        return new DataResponse();
614
+    }
615
+
616
+    /**
617
+     * @PasswordConfirmationRequired
618
+     * @NoAdminRequired
619
+     *
620
+     * @param string $userId
621
+     * @return DataResponse
622
+     * @throws OCSException
623
+     */
624
+    public function deleteUser(string $userId): DataResponse {
625
+        $currentLoggedInUser = $this->userSession->getUser();
626
+
627
+        $targetUser = $this->userManager->get($userId);
628
+
629
+        if ($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
630
+            throw new OCSException('', 101);
631
+        }
632
+
633
+        // If not permitted
634
+        $subAdminManager = $this->groupManager->getSubAdmin();
635
+        if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
636
+            throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
637
+        }
638
+
639
+        // Go ahead with the delete
640
+        if ($targetUser->delete()) {
641
+            return new DataResponse();
642
+        } else {
643
+            throw new OCSException('', 101);
644
+        }
645
+    }
646
+
647
+    /**
648
+     * @PasswordConfirmationRequired
649
+     * @NoAdminRequired
650
+     *
651
+     * @param string $userId
652
+     * @return DataResponse
653
+     * @throws OCSException
654
+     * @throws OCSForbiddenException
655
+     */
656
+    public function disableUser(string $userId): DataResponse {
657
+        return $this->setEnabled($userId, false);
658
+    }
659
+
660
+    /**
661
+     * @PasswordConfirmationRequired
662
+     * @NoAdminRequired
663
+     *
664
+     * @param string $userId
665
+     * @return DataResponse
666
+     * @throws OCSException
667
+     * @throws OCSForbiddenException
668
+     */
669
+    public function enableUser(string $userId): DataResponse {
670
+        return $this->setEnabled($userId, true);
671
+    }
672
+
673
+    /**
674
+     * @param string $userId
675
+     * @param bool $value
676
+     * @return DataResponse
677
+     * @throws OCSException
678
+     */
679
+    private function setEnabled(string $userId, bool $value): DataResponse {
680
+        $currentLoggedInUser = $this->userSession->getUser();
681
+
682
+        $targetUser = $this->userManager->get($userId);
683
+        if ($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
684
+            throw new OCSException('', 101);
685
+        }
686
+
687
+        // If not permitted
688
+        $subAdminManager = $this->groupManager->getSubAdmin();
689
+        if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
690
+            throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
691
+        }
692
+
693
+        // enable/disable the user now
694
+        $targetUser->setEnabled($value);
695
+        return new DataResponse();
696
+    }
697
+
698
+    /**
699
+     * @NoAdminRequired
700
+     * @NoSubAdminRequired
701
+     *
702
+     * @param string $userId
703
+     * @return DataResponse
704
+     * @throws OCSException
705
+     */
706
+    public function getUsersGroups(string $userId): DataResponse {
707
+        $loggedInUser = $this->userSession->getUser();
708
+
709
+        $targetUser = $this->userManager->get($userId);
710
+        if ($targetUser === null) {
711
+            throw new OCSException('', \OCP\API::RESPOND_NOT_FOUND);
712
+        }
713
+
714
+        if ($targetUser->getUID() === $loggedInUser->getUID() || $this->groupManager->isAdmin($loggedInUser->getUID())) {
715
+            // Self lookup or admin lookup
716
+            return new DataResponse([
717
+                'groups' => $this->groupManager->getUserGroupIds($targetUser)
718
+            ]);
719
+        } else {
720
+            $subAdminManager = $this->groupManager->getSubAdmin();
721
+
722
+            // Looking up someone else
723
+            if ($subAdminManager->isUserAccessible($loggedInUser, $targetUser)) {
724
+                // Return the group that the method caller is subadmin of for the user in question
725
+                /** @var IGroup[] $getSubAdminsGroups */
726
+                $getSubAdminsGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
727
+                foreach ($getSubAdminsGroups as $key => $group) {
728
+                    $getSubAdminsGroups[$key] = $group->getGID();
729
+                }
730
+                $groups = array_intersect(
731
+                    $getSubAdminsGroups,
732
+                    $this->groupManager->getUserGroupIds($targetUser)
733
+                );
734
+                return new DataResponse(['groups' => $groups]);
735
+            } else {
736
+                // Not permitted
737
+                throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
738
+            }
739
+        }
740
+    }
741
+
742
+    /**
743
+     * @PasswordConfirmationRequired
744
+     * @NoAdminRequired
745
+     *
746
+     * @param string $userId
747
+     * @param string $groupid
748
+     * @return DataResponse
749
+     * @throws OCSException
750
+     */
751
+    public function addToGroup(string $userId, string $groupid = ''): DataResponse {
752
+        if ($groupid === '') {
753
+            throw new OCSException('', 101);
754
+        }
755
+
756
+        $group = $this->groupManager->get($groupid);
757
+        $targetUser = $this->userManager->get($userId);
758
+        if ($group === null) {
759
+            throw new OCSException('', 102);
760
+        }
761
+        if ($targetUser === null) {
762
+            throw new OCSException('', 103);
763
+        }
764
+
765
+        // If they're not an admin, check they are a subadmin of the group in question
766
+        $loggedInUser = $this->userSession->getUser();
767
+        $subAdminManager = $this->groupManager->getSubAdmin();
768
+        if (!$this->groupManager->isAdmin($loggedInUser->getUID()) && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
769
+            throw new OCSException('', 104);
770
+        }
771
+
772
+        // Add user to group
773
+        $group->addUser($targetUser);
774
+        return new DataResponse();
775
+    }
776
+
777
+    /**
778
+     * @PasswordConfirmationRequired
779
+     * @NoAdminRequired
780
+     *
781
+     * @param string $userId
782
+     * @param string $groupid
783
+     * @return DataResponse
784
+     * @throws OCSException
785
+     */
786
+    public function removeFromGroup(string $userId, string $groupid): DataResponse {
787
+        $loggedInUser = $this->userSession->getUser();
788
+
789
+        if ($groupid === null || trim($groupid) === '') {
790
+            throw new OCSException('', 101);
791
+        }
792
+
793
+        $group = $this->groupManager->get($groupid);
794
+        if ($group === null) {
795
+            throw new OCSException('', 102);
796
+        }
797
+
798
+        $targetUser = $this->userManager->get($userId);
799
+        if ($targetUser === null) {
800
+            throw new OCSException('', 103);
801
+        }
802
+
803
+        // If they're not an admin, check they are a subadmin of the group in question
804
+        $subAdminManager = $this->groupManager->getSubAdmin();
805
+        if (!$this->groupManager->isAdmin($loggedInUser->getUID()) && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
806
+            throw new OCSException('', 104);
807
+        }
808
+
809
+        // Check they aren't removing themselves from 'admin' or their 'subadmin; group
810
+        if ($targetUser->getUID() === $loggedInUser->getUID()) {
811
+            if ($this->groupManager->isAdmin($loggedInUser->getUID())) {
812
+                if ($group->getGID() === 'admin') {
813
+                    throw new OCSException('Cannot remove yourself from the admin group', 105);
814
+                }
815
+            } else {
816
+                // Not an admin, so the user must be a subadmin of this group, but that is not allowed.
817
+                throw new OCSException('Cannot remove yourself from this group as you are a SubAdmin', 105);
818
+            }
819
+        } elseif (!$this->groupManager->isAdmin($loggedInUser->getUID())) {
820
+            /** @var IGroup[] $subAdminGroups */
821
+            $subAdminGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
822
+            $subAdminGroups = array_map(function (IGroup $subAdminGroup) {
823
+                return $subAdminGroup->getGID();
824
+            }, $subAdminGroups);
825
+            $userGroups = $this->groupManager->getUserGroupIds($targetUser);
826
+            $userSubAdminGroups = array_intersect($subAdminGroups, $userGroups);
827
+
828
+            if (count($userSubAdminGroups) <= 1) {
829
+                // Subadmin must not be able to remove a user from all their subadmin groups.
830
+                throw new OCSException('Not viable to remove user from the last group you are SubAdmin of', 105);
831
+            }
832
+        }
833
+
834
+        // Remove user from group
835
+        $group->removeUser($targetUser);
836
+        return new DataResponse();
837
+    }
838
+
839
+    /**
840
+     * Creates a subadmin
841
+     *
842
+     * @PasswordConfirmationRequired
843
+     *
844
+     * @param string $userId
845
+     * @param string $groupid
846
+     * @return DataResponse
847
+     * @throws OCSException
848
+     */
849
+    public function addSubAdmin(string $userId, string $groupid): DataResponse {
850
+        $group = $this->groupManager->get($groupid);
851
+        $user = $this->userManager->get($userId);
852
+
853
+        // Check if the user exists
854
+        if ($user === null) {
855
+            throw new OCSException('User does not exist', 101);
856
+        }
857
+        // Check if group exists
858
+        if ($group === null) {
859
+            throw new OCSException('Group does not exist',  102);
860
+        }
861
+        // Check if trying to make subadmin of admin group
862
+        if ($group->getGID() === 'admin') {
863
+            throw new OCSException('Cannot create subadmins for admin group', 103);
864
+        }
865
+
866
+        $subAdminManager = $this->groupManager->getSubAdmin();
867
+
868
+        // We cannot be subadmin twice
869
+        if ($subAdminManager->isSubAdminOfGroup($user, $group)) {
870
+            return new DataResponse();
871
+        }
872
+        // Go
873
+        $subAdminManager->createSubAdmin($user, $group);
874
+        return new DataResponse();
875
+    }
876
+
877
+    /**
878
+     * Removes a subadmin from a group
879
+     *
880
+     * @PasswordConfirmationRequired
881
+     *
882
+     * @param string $userId
883
+     * @param string $groupid
884
+     * @return DataResponse
885
+     * @throws OCSException
886
+     */
887
+    public function removeSubAdmin(string $userId, string $groupid): DataResponse {
888
+        $group = $this->groupManager->get($groupid);
889
+        $user = $this->userManager->get($userId);
890
+        $subAdminManager = $this->groupManager->getSubAdmin();
891
+
892
+        // Check if the user exists
893
+        if ($user === null) {
894
+            throw new OCSException('User does not exist', 101);
895
+        }
896
+        // Check if the group exists
897
+        if ($group === null) {
898
+            throw new OCSException('Group does not exist', 101);
899
+        }
900
+        // Check if they are a subadmin of this said group
901
+        if (!$subAdminManager->isSubAdminOfGroup($user, $group)) {
902
+            throw new OCSException('User is not a subadmin of this group', 102);
903
+        }
904
+
905
+        // Go
906
+        $subAdminManager->deleteSubAdmin($user, $group);
907
+        return new DataResponse();
908
+    }
909
+
910
+    /**
911
+     * Get the groups a user is a subadmin of
912
+     *
913
+     * @param string $userId
914
+     * @return DataResponse
915
+     * @throws OCSException
916
+     */
917
+    public function getUserSubAdminGroups(string $userId): DataResponse {
918
+        $groups = $this->getUserSubAdminGroupsData($userId);
919
+        return new DataResponse($groups);
920
+    }
921
+
922
+    /**
923
+     * @NoAdminRequired
924
+     * @PasswordConfirmationRequired
925
+     *
926
+     * resend welcome message
927
+     *
928
+     * @param string $userId
929
+     * @return DataResponse
930
+     * @throws OCSException
931
+     */
932
+    public function resendWelcomeMessage(string $userId): DataResponse {
933
+        $currentLoggedInUser = $this->userSession->getUser();
934
+
935
+        $targetUser = $this->userManager->get($userId);
936
+        if ($targetUser === null) {
937
+            throw new OCSException('', \OCP\API::RESPOND_NOT_FOUND);
938
+        }
939
+
940
+        // Check if admin / subadmin
941
+        $subAdminManager = $this->groupManager->getSubAdmin();
942
+        if (!$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
943
+            && !$this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
944
+            // No rights
945
+            throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
946
+        }
947
+
948
+        $email = $targetUser->getEMailAddress();
949
+        if ($email === '' || $email === null) {
950
+            throw new OCSException('Email address not available', 101);
951
+        }
952
+
953
+        try {
954
+            $emailTemplate = $this->newUserMailHelper->generateTemplate($targetUser, false);
955
+            $this->newUserMailHelper->sendMail($targetUser, $emailTemplate);
956
+        } catch (\Exception $e) {
957
+            $this->logger->logException($e, [
958
+                'message' => "Can't send new user mail to $email",
959
+                'level' => ILogger::ERROR,
960
+                'app' => 'settings',
961
+            ]);
962
+            throw new OCSException('Sending email failed', 102);
963
+        }
964
+
965
+        return new DataResponse();
966
+    }
967 967
 }
Please login to merge, or discard this patch.
apps/provisioning_api/lib/FederatedShareProviderFactory.php 1 patch
Indentation   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -30,14 +30,14 @@
 block discarded – undo
30 30
 
31 31
 class FederatedShareProviderFactory {
32 32
 
33
-	/** @var IServerContainer */
34
-	private $serverContainer;
33
+    /** @var IServerContainer */
34
+    private $serverContainer;
35 35
 
36
-	public function __construct(IServerContainer $serverContainer) {
37
-		$this->serverContainer = $serverContainer;
38
-	}
36
+    public function __construct(IServerContainer $serverContainer) {
37
+        $this->serverContainer = $serverContainer;
38
+    }
39 39
 
40
-	public function get(): FederatedShareProvider {
41
-		return $this->serverContainer->query(FederatedShareProvider::class);
42
-	}
40
+    public function get(): FederatedShareProvider {
41
+        return $this->serverContainer->query(FederatedShareProvider::class);
42
+    }
43 43
 }
Please login to merge, or discard this patch.
apps/dav/appinfo/v1/publicwebdav.php 1 patch
Indentation   +52 added lines, -52 removed lines patch added patch discarded remove patch
@@ -40,23 +40,23 @@  discard block
 block discarded – undo
40 40
 
41 41
 // Backends
42 42
 $authBackend = new OCA\DAV\Connector\PublicAuth(
43
-	\OC::$server->getRequest(),
44
-	\OC::$server->getShareManager(),
45
-	\OC::$server->getSession()
43
+    \OC::$server->getRequest(),
44
+    \OC::$server->getShareManager(),
45
+    \OC::$server->getSession()
46 46
 );
47 47
 $authPlugin = new \Sabre\DAV\Auth\Plugin($authBackend);
48 48
 
49 49
 $serverFactory = new OCA\DAV\Connector\Sabre\ServerFactory(
50
-	\OC::$server->getConfig(),
51
-	\OC::$server->getLogger(),
52
-	\OC::$server->getDatabaseConnection(),
53
-	\OC::$server->getUserSession(),
54
-	\OC::$server->getMountManager(),
55
-	\OC::$server->getTagManager(),
56
-	\OC::$server->getRequest(),
57
-	\OC::$server->getPreviewManager(),
58
-	\OC::$server->getEventDispatcher(),
59
-	\OC::$server->getL10N('dav')
50
+    \OC::$server->getConfig(),
51
+    \OC::$server->getLogger(),
52
+    \OC::$server->getDatabaseConnection(),
53
+    \OC::$server->getUserSession(),
54
+    \OC::$server->getMountManager(),
55
+    \OC::$server->getTagManager(),
56
+    \OC::$server->getRequest(),
57
+    \OC::$server->getPreviewManager(),
58
+    \OC::$server->getEventDispatcher(),
59
+    \OC::$server->getL10N('dav')
60 60
 );
61 61
 
62 62
 $requestUri = \OC::$server->getRequest()->getRequestUri();
@@ -65,45 +65,45 @@  discard block
 block discarded – undo
65 65
 $filesDropPlugin = new \OCA\DAV\Files\Sharing\FilesDropPlugin();
66 66
 
67 67
 $server = $serverFactory->createServer($baseuri, $requestUri, $authPlugin, function (\Sabre\DAV\Server $server) use ($authBackend, $linkCheckPlugin, $filesDropPlugin) {
68
-	$isAjax = (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest');
69
-	/** @var \OCA\FederatedFileSharing\FederatedShareProvider $shareProvider */
70
-	$federatedShareProvider = \OC::$server->query(\OCA\FederatedFileSharing\FederatedShareProvider::class);
71
-	if ($federatedShareProvider->isOutgoingServer2serverShareEnabled() === false && !$isAjax) {
72
-		// this is what is thrown when trying to access a non-existing share
73
-		throw new \Sabre\DAV\Exception\NotAuthenticated();
74
-	}
75
-
76
-	$share = $authBackend->getShare();
77
-	$owner = $share->getShareOwner();
78
-	$isReadable = $share->getPermissions() & \OCP\Constants::PERMISSION_READ;
79
-	$fileId = $share->getNodeId();
80
-
81
-	// FIXME: should not add storage wrappers outside of preSetup, need to find a better way
82
-	$previousLog = \OC\Files\Filesystem::logWarningWhenAddingStorageWrapper(false);
83
-	\OC\Files\Filesystem::addStorageWrapper('sharePermissions', function ($mountPoint, $storage) use ($share) {
84
-		return new \OC\Files\Storage\Wrapper\PermissionsMask(['storage' => $storage, 'mask' => $share->getPermissions() | \OCP\Constants::PERMISSION_SHARE]);
85
-	});
86
-	\OC\Files\Filesystem::addStorageWrapper('shareOwner', function ($mountPoint, $storage) use ($share) {
87
-		return new \OCA\DAV\Storage\PublicOwnerWrapper(['storage' => $storage, 'owner' => $share->getShareOwner()]);
88
-	});
89
-	\OC\Files\Filesystem::logWarningWhenAddingStorageWrapper($previousLog);
90
-
91
-	OC_Util::tearDownFS();
92
-	OC_Util::setupFS($owner);
93
-	$ownerView = new \OC\Files\View('/'. $owner . '/files');
94
-	$path = $ownerView->getPath($fileId);
95
-	$fileInfo = $ownerView->getFileInfo($path);
96
-	$linkCheckPlugin->setFileInfo($fileInfo);
97
-
98
-	// If not readble (files_drop) enable the filesdrop plugin
99
-	if (!$isReadable) {
100
-		$filesDropPlugin->enable();
101
-	}
102
-
103
-	$view = new \OC\Files\View($ownerView->getAbsolutePath($path));
104
-	$filesDropPlugin->setView($view);
105
-
106
-	return $view;
68
+    $isAjax = (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest');
69
+    /** @var \OCA\FederatedFileSharing\FederatedShareProvider $shareProvider */
70
+    $federatedShareProvider = \OC::$server->query(\OCA\FederatedFileSharing\FederatedShareProvider::class);
71
+    if ($federatedShareProvider->isOutgoingServer2serverShareEnabled() === false && !$isAjax) {
72
+        // this is what is thrown when trying to access a non-existing share
73
+        throw new \Sabre\DAV\Exception\NotAuthenticated();
74
+    }
75
+
76
+    $share = $authBackend->getShare();
77
+    $owner = $share->getShareOwner();
78
+    $isReadable = $share->getPermissions() & \OCP\Constants::PERMISSION_READ;
79
+    $fileId = $share->getNodeId();
80
+
81
+    // FIXME: should not add storage wrappers outside of preSetup, need to find a better way
82
+    $previousLog = \OC\Files\Filesystem::logWarningWhenAddingStorageWrapper(false);
83
+    \OC\Files\Filesystem::addStorageWrapper('sharePermissions', function ($mountPoint, $storage) use ($share) {
84
+        return new \OC\Files\Storage\Wrapper\PermissionsMask(['storage' => $storage, 'mask' => $share->getPermissions() | \OCP\Constants::PERMISSION_SHARE]);
85
+    });
86
+    \OC\Files\Filesystem::addStorageWrapper('shareOwner', function ($mountPoint, $storage) use ($share) {
87
+        return new \OCA\DAV\Storage\PublicOwnerWrapper(['storage' => $storage, 'owner' => $share->getShareOwner()]);
88
+    });
89
+    \OC\Files\Filesystem::logWarningWhenAddingStorageWrapper($previousLog);
90
+
91
+    OC_Util::tearDownFS();
92
+    OC_Util::setupFS($owner);
93
+    $ownerView = new \OC\Files\View('/'. $owner . '/files');
94
+    $path = $ownerView->getPath($fileId);
95
+    $fileInfo = $ownerView->getFileInfo($path);
96
+    $linkCheckPlugin->setFileInfo($fileInfo);
97
+
98
+    // If not readble (files_drop) enable the filesdrop plugin
99
+    if (!$isReadable) {
100
+        $filesDropPlugin->enable();
101
+    }
102
+
103
+    $view = new \OC\Files\View($ownerView->getAbsolutePath($path));
104
+    $filesDropPlugin->setView($view);
105
+
106
+    return $view;
107 107
 });
108 108
 
109 109
 $server->addPlugin($linkCheckPlugin);
Please login to merge, or discard this patch.
apps/federatedfilesharing/lib/Listeners/LoadAdditionalScriptsListener.php 1 patch
Indentation   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -31,20 +31,20 @@
 block discarded – undo
31 31
 use OCP\EventDispatcher\IEventListener;
32 32
 
33 33
 class LoadAdditionalScriptsListener implements IEventListener {
34
-	/** @var FederatedShareProvider */
35
-	protected $federatedShareProvider;
34
+    /** @var FederatedShareProvider */
35
+    protected $federatedShareProvider;
36 36
 
37
-	public function __construct(FederatedShareProvider $federatedShareProvider) {
38
-		$this->federatedShareProvider = $federatedShareProvider;
39
-	}
37
+    public function __construct(FederatedShareProvider $federatedShareProvider) {
38
+        $this->federatedShareProvider = $federatedShareProvider;
39
+    }
40 40
 
41
-	public function handle(Event $event): void {
42
-		if (!$event instanceof LoadAdditionalScriptsEvent) {
43
-			return;
44
-		}
41
+    public function handle(Event $event): void {
42
+        if (!$event instanceof LoadAdditionalScriptsEvent) {
43
+            return;
44
+        }
45 45
 
46
-		if ($this->federatedShareProvider->isIncomingServer2serverShareEnabled()) {
47
-			\OCP\Util::addScript('federatedfilesharing', 'external');
48
-		}
49
-	}
46
+        if ($this->federatedShareProvider->isIncomingServer2serverShareEnabled()) {
47
+            \OCP\Util::addScript('federatedfilesharing', 'external');
48
+        }
49
+    }
50 50
 }
Please login to merge, or discard this patch.
apps/federatedfilesharing/lib/AppInfo/Application.php 1 patch
Indentation   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -38,25 +38,25 @@
 block discarded – undo
38 38
 use OCP\AppFramework\Bootstrap\IRegistrationContext;
39 39
 
40 40
 class Application extends App implements IBootstrap {
41
-	public function __construct() {
42
-		parent::__construct('federatedfilesharing');
43
-	}
41
+    public function __construct() {
42
+        parent::__construct('federatedfilesharing');
43
+    }
44 44
 
45
-	public function register(IRegistrationContext $context): void {
46
-		$context->registerEventListener(LoadAdditionalScriptsEvent::class, LoadAdditionalScriptsListener::class);
47
-	}
45
+    public function register(IRegistrationContext $context): void {
46
+        $context->registerEventListener(LoadAdditionalScriptsEvent::class, LoadAdditionalScriptsListener::class);
47
+    }
48 48
 
49
-	public function boot(IBootContext $context): void {
50
-		$server = $context->getServerContainer();
49
+    public function boot(IBootContext $context): void {
50
+        $server = $context->getServerContainer();
51 51
 
52
-		$cloudFederationManager = $server->getCloudFederationProviderManager();
53
-		$cloudFederationManager->addCloudFederationProvider('file',
54
-			'Federated Files Sharing',
55
-			function () use ($server) {
56
-				return $server->query(CloudFederationProviderFiles::class);
57
-			});
52
+        $cloudFederationManager = $server->getCloudFederationProviderManager();
53
+        $cloudFederationManager->addCloudFederationProvider('file',
54
+            'Federated Files Sharing',
55
+            function () use ($server) {
56
+                return $server->query(CloudFederationProviderFiles::class);
57
+            });
58 58
 
59
-		$manager = $server->getNotificationManager();
60
-		$manager->registerNotifierService(Notifier::class);
61
-	}
59
+        $manager = $server->getNotificationManager();
60
+        $manager->registerNotifierService(Notifier::class);
61
+    }
62 62
 }
Please login to merge, or discard this patch.
apps/settings/lib/Controller/UsersController.php 1 patch
Indentation   +464 added lines, -464 removed lines patch added patch discarded remove patch
@@ -58,468 +58,468 @@
 block discarded – undo
58 58
 use function in_array;
59 59
 
60 60
 class UsersController extends Controller {
61
-	/** @var IUserManager */
62
-	private $userManager;
63
-	/** @var IGroupManager */
64
-	private $groupManager;
65
-	/** @var IUserSession */
66
-	private $userSession;
67
-	/** @var IConfig */
68
-	private $config;
69
-	/** @var bool */
70
-	private $isAdmin;
71
-	/** @var IL10N */
72
-	private $l10n;
73
-	/** @var IMailer */
74
-	private $mailer;
75
-	/** @var IFactory */
76
-	private $l10nFactory;
77
-	/** @var IAppManager */
78
-	private $appManager;
79
-	/** @var AccountManager */
80
-	private $accountManager;
81
-	/** @var Manager */
82
-	private $keyManager;
83
-	/** @var IJobList */
84
-	private $jobList;
85
-	/** @var IManager */
86
-	private $encryptionManager;
87
-
88
-
89
-	public function __construct(string $appName,
90
-								IRequest $request,
91
-								IUserManager $userManager,
92
-								IGroupManager $groupManager,
93
-								IUserSession $userSession,
94
-								IConfig $config,
95
-								bool $isAdmin,
96
-								IL10N $l10n,
97
-								IMailer $mailer,
98
-								IFactory $l10nFactory,
99
-								IAppManager $appManager,
100
-								AccountManager $accountManager,
101
-								Manager $keyManager,
102
-								IJobList $jobList,
103
-								IManager $encryptionManager) {
104
-		parent::__construct($appName, $request);
105
-		$this->userManager = $userManager;
106
-		$this->groupManager = $groupManager;
107
-		$this->userSession = $userSession;
108
-		$this->config = $config;
109
-		$this->isAdmin = $isAdmin;
110
-		$this->l10n = $l10n;
111
-		$this->mailer = $mailer;
112
-		$this->l10nFactory = $l10nFactory;
113
-		$this->appManager = $appManager;
114
-		$this->accountManager = $accountManager;
115
-		$this->keyManager = $keyManager;
116
-		$this->jobList = $jobList;
117
-		$this->encryptionManager = $encryptionManager;
118
-	}
119
-
120
-
121
-	/**
122
-	 * @NoCSRFRequired
123
-	 * @NoAdminRequired
124
-	 *
125
-	 * Display users list template
126
-	 *
127
-	 * @return TemplateResponse
128
-	 */
129
-	public function usersListByGroup() {
130
-		return $this->usersList();
131
-	}
132
-
133
-	/**
134
-	 * @NoCSRFRequired
135
-	 * @NoAdminRequired
136
-	 *
137
-	 * Display users list template
138
-	 *
139
-	 * @return TemplateResponse
140
-	 */
141
-	public function usersList() {
142
-		$user = $this->userSession->getUser();
143
-		$uid = $user->getUID();
144
-
145
-		\OC::$server->getNavigationManager()->setActiveEntry('core_users');
146
-
147
-		/* SORT OPTION: SORT_USERCOUNT or SORT_GROUPNAME */
148
-		$sortGroupsBy = \OC\Group\MetaData::SORT_USERCOUNT;
149
-		$isLDAPUsed = false;
150
-		if ($this->config->getSystemValue('sort_groups_by_name', false)) {
151
-			$sortGroupsBy = \OC\Group\MetaData::SORT_GROUPNAME;
152
-		} else {
153
-			if ($this->appManager->isEnabledForUser('user_ldap')) {
154
-				$isLDAPUsed =
155
-					$this->groupManager->isBackendUsed('\OCA\User_LDAP\Group_Proxy');
156
-				if ($isLDAPUsed) {
157
-					// LDAP user count can be slow, so we sort by group name here
158
-					$sortGroupsBy = \OC\Group\MetaData::SORT_GROUPNAME;
159
-				}
160
-			}
161
-		}
162
-
163
-		$canChangePassword = $this->canAdminChangeUserPasswords();
164
-
165
-		/* GROUPS */
166
-		$groupsInfo = new \OC\Group\MetaData(
167
-			$uid,
168
-			$this->isAdmin,
169
-			$this->groupManager,
170
-			$this->userSession
171
-		);
172
-
173
-		$groupsInfo->setSorting($sortGroupsBy);
174
-		list($adminGroup, $groups) = $groupsInfo->get();
175
-
176
-		if (!$isLDAPUsed && $this->appManager->isEnabledForUser('user_ldap')) {
177
-			$isLDAPUsed = (bool)array_reduce($this->userManager->getBackends(), function ($ldapFound, $backend) {
178
-				return $ldapFound || $backend instanceof User_Proxy;
179
-			});
180
-		}
181
-
182
-		$disabledUsers = -1;
183
-		$userCount = 0;
184
-
185
-		if (!$isLDAPUsed) {
186
-			if ($this->isAdmin) {
187
-				$disabledUsers = $this->userManager->countDisabledUsers();
188
-				$userCount = array_reduce($this->userManager->countUsers(), function ($v, $w) {
189
-					return $v + (int)$w;
190
-				}, 0);
191
-			} else {
192
-				// User is subadmin !
193
-				// Map group list to names to retrieve the countDisabledUsersOfGroups
194
-				$userGroups = $this->groupManager->getUserGroups($user);
195
-				$groupsNames = [];
196
-
197
-				foreach ($groups as $key => $group) {
198
-					// $userCount += (int)$group['usercount'];
199
-					array_push($groupsNames, $group['name']);
200
-					// we prevent subadmins from looking up themselves
201
-					// so we lower the count of the groups he belongs to
202
-					if (array_key_exists($group['id'], $userGroups)) {
203
-						$groups[$key]['usercount']--;
204
-						$userCount -= 1; // we also lower from one the total count
205
-					}
206
-				};
207
-				$userCount += $this->userManager->countUsersOfGroups($groupsInfo->getGroups());
208
-				$disabledUsers = $this->userManager->countDisabledUsersOfGroups($groupsNames);
209
-			}
210
-
211
-			$userCount -= $disabledUsers;
212
-		}
213
-
214
-		$disabledUsersGroup = [
215
-			'id' => 'disabled',
216
-			'name' => 'Disabled users',
217
-			'usercount' => $disabledUsers
218
-		];
219
-
220
-		/* QUOTAS PRESETS */
221
-		$quotaPreset = $this->parseQuotaPreset($this->config->getAppValue('files', 'quota_preset', '1 GB, 5 GB, 10 GB'));
222
-		$defaultQuota = $this->config->getAppValue('files', 'default_quota', 'none');
223
-
224
-		\OC::$server->getEventDispatcher()->dispatch('OC\Settings\Users::loadAdditionalScripts');
225
-
226
-		/* LANGUAGES */
227
-		$languages = $this->l10nFactory->getLanguages();
228
-
229
-		/* FINAL DATA */
230
-		$serverData = [];
231
-		// groups
232
-		$serverData['groups'] = array_merge_recursive($adminGroup, [$disabledUsersGroup], $groups);
233
-		// Various data
234
-		$serverData['isAdmin'] = $this->isAdmin;
235
-		$serverData['sortGroups'] = $sortGroupsBy;
236
-		$serverData['quotaPreset'] = $quotaPreset;
237
-		$serverData['userCount'] = $userCount;
238
-		$serverData['languages'] = $languages;
239
-		$serverData['defaultLanguage'] = $this->config->getSystemValue('default_language', 'en');
240
-		$serverData['forceLanguage'] = $this->config->getSystemValue('force_language', false);
241
-		// Settings
242
-		$serverData['defaultQuota'] = $defaultQuota;
243
-		$serverData['canChangePassword'] = $canChangePassword;
244
-		$serverData['newUserGenerateUserID'] = $this->config->getAppValue('core', 'newUser.generateUserID', 'no') === 'yes';
245
-		$serverData['newUserRequireEmail'] = $this->config->getAppValue('core', 'newUser.requireEmail', 'no') === 'yes';
246
-		$serverData['newUserSendEmail'] = $this->config->getAppValue('core', 'newUser.sendEmail', 'yes') === 'yes';
247
-
248
-		return new TemplateResponse('settings', 'settings-vue', ['serverData' => $serverData]);
249
-	}
250
-
251
-	/**
252
-	 * @param string $key
253
-	 * @param string $value
254
-	 *
255
-	 * @return JSONResponse
256
-	 */
257
-	public function setPreference(string $key, string $value): JSONResponse {
258
-		$allowed = ['newUser.sendEmail'];
259
-		if (!in_array($key, $allowed, true)) {
260
-			return new JSONResponse([], Http::STATUS_FORBIDDEN);
261
-		}
262
-
263
-		$this->config->setAppValue('core', $key, $value);
264
-
265
-		return new JSONResponse([]);
266
-	}
267
-
268
-	/**
269
-	 * Parse the app value for quota_present
270
-	 *
271
-	 * @param string $quotaPreset
272
-	 * @return array
273
-	 */
274
-	protected function parseQuotaPreset(string $quotaPreset): array {
275
-		// 1 GB, 5 GB, 10 GB => [1 GB, 5 GB, 10 GB]
276
-		$presets = array_filter(array_map('trim', explode(',', $quotaPreset)));
277
-		// Drop default and none, Make array indexes numerically
278
-		return array_values(array_diff($presets, ['default', 'none']));
279
-	}
280
-
281
-	/**
282
-	 * check if the admin can change the users password
283
-	 *
284
-	 * The admin can change the passwords if:
285
-	 *
286
-	 *   - no encryption module is loaded and encryption is disabled
287
-	 *   - encryption module is loaded but it doesn't require per user keys
288
-	 *
289
-	 * The admin can not change the passwords if:
290
-	 *
291
-	 *   - an encryption module is loaded and it uses per-user keys
292
-	 *   - encryption is enabled but no encryption modules are loaded
293
-	 *
294
-	 * @return bool
295
-	 */
296
-	protected function canAdminChangeUserPasswords() {
297
-		$isEncryptionEnabled = $this->encryptionManager->isEnabled();
298
-		try {
299
-			$noUserSpecificEncryptionKeys =!$this->encryptionManager->getEncryptionModule()->needDetailedAccessList();
300
-			$isEncryptionModuleLoaded = true;
301
-		} catch (ModuleDoesNotExistsException $e) {
302
-			$noUserSpecificEncryptionKeys = true;
303
-			$isEncryptionModuleLoaded = false;
304
-		}
305
-
306
-		$canChangePassword = ($isEncryptionEnabled && $isEncryptionModuleLoaded  && $noUserSpecificEncryptionKeys)
307
-			|| (!$isEncryptionEnabled && !$isEncryptionModuleLoaded)
308
-			|| (!$isEncryptionEnabled && $isEncryptionModuleLoaded && $noUserSpecificEncryptionKeys);
309
-
310
-		return $canChangePassword;
311
-	}
312
-
313
-	/**
314
-	 * @NoAdminRequired
315
-	 * @NoSubAdminRequired
316
-	 * @PasswordConfirmationRequired
317
-	 *
318
-	 * @param string $avatarScope
319
-	 * @param string $displayname
320
-	 * @param string $displaynameScope
321
-	 * @param string $phone
322
-	 * @param string $phoneScope
323
-	 * @param string $email
324
-	 * @param string $emailScope
325
-	 * @param string $website
326
-	 * @param string $websiteScope
327
-	 * @param string $address
328
-	 * @param string $addressScope
329
-	 * @param string $twitter
330
-	 * @param string $twitterScope
331
-	 * @return DataResponse
332
-	 */
333
-	public function setUserSettings($avatarScope,
334
-									$displayname,
335
-									$displaynameScope,
336
-									$phone,
337
-									$phoneScope,
338
-									$email,
339
-									$emailScope,
340
-									$website,
341
-									$websiteScope,
342
-									$address,
343
-									$addressScope,
344
-									$twitter,
345
-									$twitterScope
346
-	) {
347
-		if (!empty($email) && !$this->mailer->validateMailAddress($email)) {
348
-			return new DataResponse(
349
-				[
350
-					'status' => 'error',
351
-					'data' => [
352
-						'message' => $this->l10n->t('Invalid mail address')
353
-					]
354
-				],
355
-				Http::STATUS_UNPROCESSABLE_ENTITY
356
-			);
357
-		}
358
-		$user = $this->userSession->getUser();
359
-		$data = $this->accountManager->getUser($user);
360
-		$data[AccountManager::PROPERTY_AVATAR] = ['scope' => $avatarScope];
361
-		if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
362
-			$data[AccountManager::PROPERTY_DISPLAYNAME] = ['value' => $displayname, 'scope' => $displaynameScope];
363
-			$data[AccountManager::PROPERTY_EMAIL] = ['value' => $email, 'scope' => $emailScope];
364
-		}
365
-		if ($this->appManager->isEnabledForUser('federatedfilesharing')) {
366
-			$shareProvider = \OC::$server->query(FederatedShareProvider::class);
367
-			if ($shareProvider->isLookupServerUploadEnabled()) {
368
-				$data[AccountManager::PROPERTY_WEBSITE] = ['value' => $website, 'scope' => $websiteScope];
369
-				$data[AccountManager::PROPERTY_ADDRESS] = ['value' => $address, 'scope' => $addressScope];
370
-				$data[AccountManager::PROPERTY_PHONE] = ['value' => $phone, 'scope' => $phoneScope];
371
-				$data[AccountManager::PROPERTY_TWITTER] = ['value' => $twitter, 'scope' => $twitterScope];
372
-			}
373
-		}
374
-		try {
375
-			$this->saveUserSettings($user, $data);
376
-			return new DataResponse(
377
-				[
378
-					'status' => 'success',
379
-					'data' => [
380
-						'userId' => $user->getUID(),
381
-						'avatarScope' => $data[AccountManager::PROPERTY_AVATAR]['scope'],
382
-						'displayname' => $data[AccountManager::PROPERTY_DISPLAYNAME]['value'],
383
-						'displaynameScope' => $data[AccountManager::PROPERTY_DISPLAYNAME]['scope'],
384
-						'email' => $data[AccountManager::PROPERTY_EMAIL]['value'],
385
-						'emailScope' => $data[AccountManager::PROPERTY_EMAIL]['scope'],
386
-						'website' => $data[AccountManager::PROPERTY_WEBSITE]['value'],
387
-						'websiteScope' => $data[AccountManager::PROPERTY_WEBSITE]['scope'],
388
-						'address' => $data[AccountManager::PROPERTY_ADDRESS]['value'],
389
-						'addressScope' => $data[AccountManager::PROPERTY_ADDRESS]['scope'],
390
-						'message' => $this->l10n->t('Settings saved')
391
-					]
392
-				],
393
-				Http::STATUS_OK
394
-			);
395
-		} catch (ForbiddenException $e) {
396
-			return new DataResponse([
397
-				'status' => 'error',
398
-				'data' => [
399
-					'message' => $e->getMessage()
400
-				],
401
-			]);
402
-		}
403
-	}
404
-	/**
405
-	 * update account manager with new user data
406
-	 *
407
-	 * @param IUser $user
408
-	 * @param array $data
409
-	 * @throws ForbiddenException
410
-	 */
411
-	protected function saveUserSettings(IUser $user, array $data) {
412
-		// keep the user back-end up-to-date with the latest display name and email
413
-		// address
414
-		$oldDisplayName = $user->getDisplayName();
415
-		$oldDisplayName = is_null($oldDisplayName) ? '' : $oldDisplayName;
416
-		if (isset($data[AccountManager::PROPERTY_DISPLAYNAME]['value'])
417
-			&& $oldDisplayName !== $data[AccountManager::PROPERTY_DISPLAYNAME]['value']
418
-		) {
419
-			$result = $user->setDisplayName($data[AccountManager::PROPERTY_DISPLAYNAME]['value']);
420
-			if ($result === false) {
421
-				throw new ForbiddenException($this->l10n->t('Unable to change full name'));
422
-			}
423
-		}
424
-		$oldEmailAddress = $user->getEMailAddress();
425
-		$oldEmailAddress = is_null($oldEmailAddress) ? '' : $oldEmailAddress;
426
-		if (isset($data[AccountManager::PROPERTY_EMAIL]['value'])
427
-			&& $oldEmailAddress !== $data[AccountManager::PROPERTY_EMAIL]['value']
428
-		) {
429
-			// this is the only permission a backend provides and is also used
430
-			// for the permission of setting a email address
431
-			if (!$user->canChangeDisplayName()) {
432
-				throw new ForbiddenException($this->l10n->t('Unable to change email address'));
433
-			}
434
-			$user->setEMailAddress($data[AccountManager::PROPERTY_EMAIL]['value']);
435
-		}
436
-		$this->accountManager->updateUser($user, $data);
437
-	}
438
-
439
-	/**
440
-	 * Set the mail address of a user
441
-	 *
442
-	 * @NoAdminRequired
443
-	 * @NoSubAdminRequired
444
-	 * @PasswordConfirmationRequired
445
-	 *
446
-	 * @param string $account
447
-	 * @param bool $onlyVerificationCode only return verification code without updating the data
448
-	 * @return DataResponse
449
-	 */
450
-	public function getVerificationCode(string $account, bool $onlyVerificationCode): DataResponse {
451
-		$user = $this->userSession->getUser();
452
-
453
-		if ($user === null) {
454
-			return new DataResponse([], Http::STATUS_BAD_REQUEST);
455
-		}
456
-
457
-		$accountData = $this->accountManager->getUser($user);
458
-		$cloudId = $user->getCloudId();
459
-		$message = 'Use my Federated Cloud ID to share with me: ' . $cloudId;
460
-		$signature = $this->signMessage($user, $message);
461
-
462
-		$code = $message . ' ' . $signature;
463
-		$codeMd5 = $message . ' ' . md5($signature);
464
-
465
-		switch ($account) {
466
-			case 'verify-twitter':
467
-				$accountData[AccountManager::PROPERTY_TWITTER]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS;
468
-				$msg = $this->l10n->t('In order to verify your Twitter account, post the following tweet on Twitter (please make sure to post it without any line breaks):');
469
-				$code = $codeMd5;
470
-				$type = AccountManager::PROPERTY_TWITTER;
471
-				$data = $accountData[AccountManager::PROPERTY_TWITTER]['value'];
472
-				$accountData[AccountManager::PROPERTY_TWITTER]['signature'] = $signature;
473
-				break;
474
-			case 'verify-website':
475
-				$accountData[AccountManager::PROPERTY_WEBSITE]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS;
476
-				$msg = $this->l10n->t('In order to verify your Website, store the following content in your web-root at \'.well-known/CloudIdVerificationCode.txt\' (please make sure that the complete text is in one line):');
477
-				$type = AccountManager::PROPERTY_WEBSITE;
478
-				$data = $accountData[AccountManager::PROPERTY_WEBSITE]['value'];
479
-				$accountData[AccountManager::PROPERTY_WEBSITE]['signature'] = $signature;
480
-				break;
481
-			default:
482
-				return new DataResponse([], Http::STATUS_BAD_REQUEST);
483
-		}
484
-
485
-		if ($onlyVerificationCode === false) {
486
-			$this->accountManager->updateUser($user, $accountData);
487
-
488
-			$this->jobList->add(VerifyUserData::class,
489
-				[
490
-					'verificationCode' => $code,
491
-					'data' => $data,
492
-					'type' => $type,
493
-					'uid' => $user->getUID(),
494
-					'try' => 0,
495
-					'lastRun' => $this->getCurrentTime()
496
-				]
497
-			);
498
-		}
499
-
500
-		return new DataResponse(['msg' => $msg, 'code' => $code]);
501
-	}
502
-
503
-	/**
504
-	 * get current timestamp
505
-	 *
506
-	 * @return int
507
-	 */
508
-	protected function getCurrentTime(): int {
509
-		return time();
510
-	}
511
-
512
-	/**
513
-	 * sign message with users private key
514
-	 *
515
-	 * @param IUser $user
516
-	 * @param string $message
517
-	 *
518
-	 * @return string base64 encoded signature
519
-	 */
520
-	protected function signMessage(IUser $user, string $message): string {
521
-		$privateKey = $this->keyManager->getKey($user)->getPrivate();
522
-		openssl_sign(json_encode($message), $signature, $privateKey, OPENSSL_ALGO_SHA512);
523
-		return base64_encode($signature);
524
-	}
61
+    /** @var IUserManager */
62
+    private $userManager;
63
+    /** @var IGroupManager */
64
+    private $groupManager;
65
+    /** @var IUserSession */
66
+    private $userSession;
67
+    /** @var IConfig */
68
+    private $config;
69
+    /** @var bool */
70
+    private $isAdmin;
71
+    /** @var IL10N */
72
+    private $l10n;
73
+    /** @var IMailer */
74
+    private $mailer;
75
+    /** @var IFactory */
76
+    private $l10nFactory;
77
+    /** @var IAppManager */
78
+    private $appManager;
79
+    /** @var AccountManager */
80
+    private $accountManager;
81
+    /** @var Manager */
82
+    private $keyManager;
83
+    /** @var IJobList */
84
+    private $jobList;
85
+    /** @var IManager */
86
+    private $encryptionManager;
87
+
88
+
89
+    public function __construct(string $appName,
90
+                                IRequest $request,
91
+                                IUserManager $userManager,
92
+                                IGroupManager $groupManager,
93
+                                IUserSession $userSession,
94
+                                IConfig $config,
95
+                                bool $isAdmin,
96
+                                IL10N $l10n,
97
+                                IMailer $mailer,
98
+                                IFactory $l10nFactory,
99
+                                IAppManager $appManager,
100
+                                AccountManager $accountManager,
101
+                                Manager $keyManager,
102
+                                IJobList $jobList,
103
+                                IManager $encryptionManager) {
104
+        parent::__construct($appName, $request);
105
+        $this->userManager = $userManager;
106
+        $this->groupManager = $groupManager;
107
+        $this->userSession = $userSession;
108
+        $this->config = $config;
109
+        $this->isAdmin = $isAdmin;
110
+        $this->l10n = $l10n;
111
+        $this->mailer = $mailer;
112
+        $this->l10nFactory = $l10nFactory;
113
+        $this->appManager = $appManager;
114
+        $this->accountManager = $accountManager;
115
+        $this->keyManager = $keyManager;
116
+        $this->jobList = $jobList;
117
+        $this->encryptionManager = $encryptionManager;
118
+    }
119
+
120
+
121
+    /**
122
+     * @NoCSRFRequired
123
+     * @NoAdminRequired
124
+     *
125
+     * Display users list template
126
+     *
127
+     * @return TemplateResponse
128
+     */
129
+    public function usersListByGroup() {
130
+        return $this->usersList();
131
+    }
132
+
133
+    /**
134
+     * @NoCSRFRequired
135
+     * @NoAdminRequired
136
+     *
137
+     * Display users list template
138
+     *
139
+     * @return TemplateResponse
140
+     */
141
+    public function usersList() {
142
+        $user = $this->userSession->getUser();
143
+        $uid = $user->getUID();
144
+
145
+        \OC::$server->getNavigationManager()->setActiveEntry('core_users');
146
+
147
+        /* SORT OPTION: SORT_USERCOUNT or SORT_GROUPNAME */
148
+        $sortGroupsBy = \OC\Group\MetaData::SORT_USERCOUNT;
149
+        $isLDAPUsed = false;
150
+        if ($this->config->getSystemValue('sort_groups_by_name', false)) {
151
+            $sortGroupsBy = \OC\Group\MetaData::SORT_GROUPNAME;
152
+        } else {
153
+            if ($this->appManager->isEnabledForUser('user_ldap')) {
154
+                $isLDAPUsed =
155
+                    $this->groupManager->isBackendUsed('\OCA\User_LDAP\Group_Proxy');
156
+                if ($isLDAPUsed) {
157
+                    // LDAP user count can be slow, so we sort by group name here
158
+                    $sortGroupsBy = \OC\Group\MetaData::SORT_GROUPNAME;
159
+                }
160
+            }
161
+        }
162
+
163
+        $canChangePassword = $this->canAdminChangeUserPasswords();
164
+
165
+        /* GROUPS */
166
+        $groupsInfo = new \OC\Group\MetaData(
167
+            $uid,
168
+            $this->isAdmin,
169
+            $this->groupManager,
170
+            $this->userSession
171
+        );
172
+
173
+        $groupsInfo->setSorting($sortGroupsBy);
174
+        list($adminGroup, $groups) = $groupsInfo->get();
175
+
176
+        if (!$isLDAPUsed && $this->appManager->isEnabledForUser('user_ldap')) {
177
+            $isLDAPUsed = (bool)array_reduce($this->userManager->getBackends(), function ($ldapFound, $backend) {
178
+                return $ldapFound || $backend instanceof User_Proxy;
179
+            });
180
+        }
181
+
182
+        $disabledUsers = -1;
183
+        $userCount = 0;
184
+
185
+        if (!$isLDAPUsed) {
186
+            if ($this->isAdmin) {
187
+                $disabledUsers = $this->userManager->countDisabledUsers();
188
+                $userCount = array_reduce($this->userManager->countUsers(), function ($v, $w) {
189
+                    return $v + (int)$w;
190
+                }, 0);
191
+            } else {
192
+                // User is subadmin !
193
+                // Map group list to names to retrieve the countDisabledUsersOfGroups
194
+                $userGroups = $this->groupManager->getUserGroups($user);
195
+                $groupsNames = [];
196
+
197
+                foreach ($groups as $key => $group) {
198
+                    // $userCount += (int)$group['usercount'];
199
+                    array_push($groupsNames, $group['name']);
200
+                    // we prevent subadmins from looking up themselves
201
+                    // so we lower the count of the groups he belongs to
202
+                    if (array_key_exists($group['id'], $userGroups)) {
203
+                        $groups[$key]['usercount']--;
204
+                        $userCount -= 1; // we also lower from one the total count
205
+                    }
206
+                };
207
+                $userCount += $this->userManager->countUsersOfGroups($groupsInfo->getGroups());
208
+                $disabledUsers = $this->userManager->countDisabledUsersOfGroups($groupsNames);
209
+            }
210
+
211
+            $userCount -= $disabledUsers;
212
+        }
213
+
214
+        $disabledUsersGroup = [
215
+            'id' => 'disabled',
216
+            'name' => 'Disabled users',
217
+            'usercount' => $disabledUsers
218
+        ];
219
+
220
+        /* QUOTAS PRESETS */
221
+        $quotaPreset = $this->parseQuotaPreset($this->config->getAppValue('files', 'quota_preset', '1 GB, 5 GB, 10 GB'));
222
+        $defaultQuota = $this->config->getAppValue('files', 'default_quota', 'none');
223
+
224
+        \OC::$server->getEventDispatcher()->dispatch('OC\Settings\Users::loadAdditionalScripts');
225
+
226
+        /* LANGUAGES */
227
+        $languages = $this->l10nFactory->getLanguages();
228
+
229
+        /* FINAL DATA */
230
+        $serverData = [];
231
+        // groups
232
+        $serverData['groups'] = array_merge_recursive($adminGroup, [$disabledUsersGroup], $groups);
233
+        // Various data
234
+        $serverData['isAdmin'] = $this->isAdmin;
235
+        $serverData['sortGroups'] = $sortGroupsBy;
236
+        $serverData['quotaPreset'] = $quotaPreset;
237
+        $serverData['userCount'] = $userCount;
238
+        $serverData['languages'] = $languages;
239
+        $serverData['defaultLanguage'] = $this->config->getSystemValue('default_language', 'en');
240
+        $serverData['forceLanguage'] = $this->config->getSystemValue('force_language', false);
241
+        // Settings
242
+        $serverData['defaultQuota'] = $defaultQuota;
243
+        $serverData['canChangePassword'] = $canChangePassword;
244
+        $serverData['newUserGenerateUserID'] = $this->config->getAppValue('core', 'newUser.generateUserID', 'no') === 'yes';
245
+        $serverData['newUserRequireEmail'] = $this->config->getAppValue('core', 'newUser.requireEmail', 'no') === 'yes';
246
+        $serverData['newUserSendEmail'] = $this->config->getAppValue('core', 'newUser.sendEmail', 'yes') === 'yes';
247
+
248
+        return new TemplateResponse('settings', 'settings-vue', ['serverData' => $serverData]);
249
+    }
250
+
251
+    /**
252
+     * @param string $key
253
+     * @param string $value
254
+     *
255
+     * @return JSONResponse
256
+     */
257
+    public function setPreference(string $key, string $value): JSONResponse {
258
+        $allowed = ['newUser.sendEmail'];
259
+        if (!in_array($key, $allowed, true)) {
260
+            return new JSONResponse([], Http::STATUS_FORBIDDEN);
261
+        }
262
+
263
+        $this->config->setAppValue('core', $key, $value);
264
+
265
+        return new JSONResponse([]);
266
+    }
267
+
268
+    /**
269
+     * Parse the app value for quota_present
270
+     *
271
+     * @param string $quotaPreset
272
+     * @return array
273
+     */
274
+    protected function parseQuotaPreset(string $quotaPreset): array {
275
+        // 1 GB, 5 GB, 10 GB => [1 GB, 5 GB, 10 GB]
276
+        $presets = array_filter(array_map('trim', explode(',', $quotaPreset)));
277
+        // Drop default and none, Make array indexes numerically
278
+        return array_values(array_diff($presets, ['default', 'none']));
279
+    }
280
+
281
+    /**
282
+     * check if the admin can change the users password
283
+     *
284
+     * The admin can change the passwords if:
285
+     *
286
+     *   - no encryption module is loaded and encryption is disabled
287
+     *   - encryption module is loaded but it doesn't require per user keys
288
+     *
289
+     * The admin can not change the passwords if:
290
+     *
291
+     *   - an encryption module is loaded and it uses per-user keys
292
+     *   - encryption is enabled but no encryption modules are loaded
293
+     *
294
+     * @return bool
295
+     */
296
+    protected function canAdminChangeUserPasswords() {
297
+        $isEncryptionEnabled = $this->encryptionManager->isEnabled();
298
+        try {
299
+            $noUserSpecificEncryptionKeys =!$this->encryptionManager->getEncryptionModule()->needDetailedAccessList();
300
+            $isEncryptionModuleLoaded = true;
301
+        } catch (ModuleDoesNotExistsException $e) {
302
+            $noUserSpecificEncryptionKeys = true;
303
+            $isEncryptionModuleLoaded = false;
304
+        }
305
+
306
+        $canChangePassword = ($isEncryptionEnabled && $isEncryptionModuleLoaded  && $noUserSpecificEncryptionKeys)
307
+            || (!$isEncryptionEnabled && !$isEncryptionModuleLoaded)
308
+            || (!$isEncryptionEnabled && $isEncryptionModuleLoaded && $noUserSpecificEncryptionKeys);
309
+
310
+        return $canChangePassword;
311
+    }
312
+
313
+    /**
314
+     * @NoAdminRequired
315
+     * @NoSubAdminRequired
316
+     * @PasswordConfirmationRequired
317
+     *
318
+     * @param string $avatarScope
319
+     * @param string $displayname
320
+     * @param string $displaynameScope
321
+     * @param string $phone
322
+     * @param string $phoneScope
323
+     * @param string $email
324
+     * @param string $emailScope
325
+     * @param string $website
326
+     * @param string $websiteScope
327
+     * @param string $address
328
+     * @param string $addressScope
329
+     * @param string $twitter
330
+     * @param string $twitterScope
331
+     * @return DataResponse
332
+     */
333
+    public function setUserSettings($avatarScope,
334
+                                    $displayname,
335
+                                    $displaynameScope,
336
+                                    $phone,
337
+                                    $phoneScope,
338
+                                    $email,
339
+                                    $emailScope,
340
+                                    $website,
341
+                                    $websiteScope,
342
+                                    $address,
343
+                                    $addressScope,
344
+                                    $twitter,
345
+                                    $twitterScope
346
+    ) {
347
+        if (!empty($email) && !$this->mailer->validateMailAddress($email)) {
348
+            return new DataResponse(
349
+                [
350
+                    'status' => 'error',
351
+                    'data' => [
352
+                        'message' => $this->l10n->t('Invalid mail address')
353
+                    ]
354
+                ],
355
+                Http::STATUS_UNPROCESSABLE_ENTITY
356
+            );
357
+        }
358
+        $user = $this->userSession->getUser();
359
+        $data = $this->accountManager->getUser($user);
360
+        $data[AccountManager::PROPERTY_AVATAR] = ['scope' => $avatarScope];
361
+        if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
362
+            $data[AccountManager::PROPERTY_DISPLAYNAME] = ['value' => $displayname, 'scope' => $displaynameScope];
363
+            $data[AccountManager::PROPERTY_EMAIL] = ['value' => $email, 'scope' => $emailScope];
364
+        }
365
+        if ($this->appManager->isEnabledForUser('federatedfilesharing')) {
366
+            $shareProvider = \OC::$server->query(FederatedShareProvider::class);
367
+            if ($shareProvider->isLookupServerUploadEnabled()) {
368
+                $data[AccountManager::PROPERTY_WEBSITE] = ['value' => $website, 'scope' => $websiteScope];
369
+                $data[AccountManager::PROPERTY_ADDRESS] = ['value' => $address, 'scope' => $addressScope];
370
+                $data[AccountManager::PROPERTY_PHONE] = ['value' => $phone, 'scope' => $phoneScope];
371
+                $data[AccountManager::PROPERTY_TWITTER] = ['value' => $twitter, 'scope' => $twitterScope];
372
+            }
373
+        }
374
+        try {
375
+            $this->saveUserSettings($user, $data);
376
+            return new DataResponse(
377
+                [
378
+                    'status' => 'success',
379
+                    'data' => [
380
+                        'userId' => $user->getUID(),
381
+                        'avatarScope' => $data[AccountManager::PROPERTY_AVATAR]['scope'],
382
+                        'displayname' => $data[AccountManager::PROPERTY_DISPLAYNAME]['value'],
383
+                        'displaynameScope' => $data[AccountManager::PROPERTY_DISPLAYNAME]['scope'],
384
+                        'email' => $data[AccountManager::PROPERTY_EMAIL]['value'],
385
+                        'emailScope' => $data[AccountManager::PROPERTY_EMAIL]['scope'],
386
+                        'website' => $data[AccountManager::PROPERTY_WEBSITE]['value'],
387
+                        'websiteScope' => $data[AccountManager::PROPERTY_WEBSITE]['scope'],
388
+                        'address' => $data[AccountManager::PROPERTY_ADDRESS]['value'],
389
+                        'addressScope' => $data[AccountManager::PROPERTY_ADDRESS]['scope'],
390
+                        'message' => $this->l10n->t('Settings saved')
391
+                    ]
392
+                ],
393
+                Http::STATUS_OK
394
+            );
395
+        } catch (ForbiddenException $e) {
396
+            return new DataResponse([
397
+                'status' => 'error',
398
+                'data' => [
399
+                    'message' => $e->getMessage()
400
+                ],
401
+            ]);
402
+        }
403
+    }
404
+    /**
405
+     * update account manager with new user data
406
+     *
407
+     * @param IUser $user
408
+     * @param array $data
409
+     * @throws ForbiddenException
410
+     */
411
+    protected function saveUserSettings(IUser $user, array $data) {
412
+        // keep the user back-end up-to-date with the latest display name and email
413
+        // address
414
+        $oldDisplayName = $user->getDisplayName();
415
+        $oldDisplayName = is_null($oldDisplayName) ? '' : $oldDisplayName;
416
+        if (isset($data[AccountManager::PROPERTY_DISPLAYNAME]['value'])
417
+            && $oldDisplayName !== $data[AccountManager::PROPERTY_DISPLAYNAME]['value']
418
+        ) {
419
+            $result = $user->setDisplayName($data[AccountManager::PROPERTY_DISPLAYNAME]['value']);
420
+            if ($result === false) {
421
+                throw new ForbiddenException($this->l10n->t('Unable to change full name'));
422
+            }
423
+        }
424
+        $oldEmailAddress = $user->getEMailAddress();
425
+        $oldEmailAddress = is_null($oldEmailAddress) ? '' : $oldEmailAddress;
426
+        if (isset($data[AccountManager::PROPERTY_EMAIL]['value'])
427
+            && $oldEmailAddress !== $data[AccountManager::PROPERTY_EMAIL]['value']
428
+        ) {
429
+            // this is the only permission a backend provides and is also used
430
+            // for the permission of setting a email address
431
+            if (!$user->canChangeDisplayName()) {
432
+                throw new ForbiddenException($this->l10n->t('Unable to change email address'));
433
+            }
434
+            $user->setEMailAddress($data[AccountManager::PROPERTY_EMAIL]['value']);
435
+        }
436
+        $this->accountManager->updateUser($user, $data);
437
+    }
438
+
439
+    /**
440
+     * Set the mail address of a user
441
+     *
442
+     * @NoAdminRequired
443
+     * @NoSubAdminRequired
444
+     * @PasswordConfirmationRequired
445
+     *
446
+     * @param string $account
447
+     * @param bool $onlyVerificationCode only return verification code without updating the data
448
+     * @return DataResponse
449
+     */
450
+    public function getVerificationCode(string $account, bool $onlyVerificationCode): DataResponse {
451
+        $user = $this->userSession->getUser();
452
+
453
+        if ($user === null) {
454
+            return new DataResponse([], Http::STATUS_BAD_REQUEST);
455
+        }
456
+
457
+        $accountData = $this->accountManager->getUser($user);
458
+        $cloudId = $user->getCloudId();
459
+        $message = 'Use my Federated Cloud ID to share with me: ' . $cloudId;
460
+        $signature = $this->signMessage($user, $message);
461
+
462
+        $code = $message . ' ' . $signature;
463
+        $codeMd5 = $message . ' ' . md5($signature);
464
+
465
+        switch ($account) {
466
+            case 'verify-twitter':
467
+                $accountData[AccountManager::PROPERTY_TWITTER]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS;
468
+                $msg = $this->l10n->t('In order to verify your Twitter account, post the following tweet on Twitter (please make sure to post it without any line breaks):');
469
+                $code = $codeMd5;
470
+                $type = AccountManager::PROPERTY_TWITTER;
471
+                $data = $accountData[AccountManager::PROPERTY_TWITTER]['value'];
472
+                $accountData[AccountManager::PROPERTY_TWITTER]['signature'] = $signature;
473
+                break;
474
+            case 'verify-website':
475
+                $accountData[AccountManager::PROPERTY_WEBSITE]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS;
476
+                $msg = $this->l10n->t('In order to verify your Website, store the following content in your web-root at \'.well-known/CloudIdVerificationCode.txt\' (please make sure that the complete text is in one line):');
477
+                $type = AccountManager::PROPERTY_WEBSITE;
478
+                $data = $accountData[AccountManager::PROPERTY_WEBSITE]['value'];
479
+                $accountData[AccountManager::PROPERTY_WEBSITE]['signature'] = $signature;
480
+                break;
481
+            default:
482
+                return new DataResponse([], Http::STATUS_BAD_REQUEST);
483
+        }
484
+
485
+        if ($onlyVerificationCode === false) {
486
+            $this->accountManager->updateUser($user, $accountData);
487
+
488
+            $this->jobList->add(VerifyUserData::class,
489
+                [
490
+                    'verificationCode' => $code,
491
+                    'data' => $data,
492
+                    'type' => $type,
493
+                    'uid' => $user->getUID(),
494
+                    'try' => 0,
495
+                    'lastRun' => $this->getCurrentTime()
496
+                ]
497
+            );
498
+        }
499
+
500
+        return new DataResponse(['msg' => $msg, 'code' => $code]);
501
+    }
502
+
503
+    /**
504
+     * get current timestamp
505
+     *
506
+     * @return int
507
+     */
508
+    protected function getCurrentTime(): int {
509
+        return time();
510
+    }
511
+
512
+    /**
513
+     * sign message with users private key
514
+     *
515
+     * @param IUser $user
516
+     * @param string $message
517
+     *
518
+     * @return string base64 encoded signature
519
+     */
520
+    protected function signMessage(IUser $user, string $message): string {
521
+        $privateKey = $this->keyManager->getKey($user)->getPrivate();
522
+        openssl_sign(json_encode($message), $signature, $privateKey, OPENSSL_ALGO_SHA512);
523
+        return base64_encode($signature);
524
+    }
525 525
 }
Please login to merge, or discard this patch.
apps/settings/lib/Settings/Personal/PersonalInfo.php 1 patch
Indentation   +241 added lines, -241 removed lines patch added patch discarded remove patch
@@ -47,245 +47,245 @@
 block discarded – undo
47 47
 
48 48
 class PersonalInfo implements ISettings {
49 49
 
50
-	/** @var IConfig */
51
-	private $config;
52
-	/** @var IUserManager */
53
-	private $userManager;
54
-	/** @var AccountManager */
55
-	private $accountManager;
56
-	/** @var IGroupManager */
57
-	private $groupManager;
58
-	/** @var IAppManager */
59
-	private $appManager;
60
-	/** @var IFactory */
61
-	private $l10nFactory;
62
-	/** @var IL10N */
63
-	private $l;
64
-
65
-	/**
66
-	 * @param IConfig $config
67
-	 * @param IUserManager $userManager
68
-	 * @param IGroupManager $groupManager
69
-	 * @param AccountManager $accountManager
70
-	 * @param IFactory $l10nFactory
71
-	 * @param IL10N $l
72
-	 */
73
-	public function __construct(
74
-		IConfig $config,
75
-		IUserManager $userManager,
76
-		IGroupManager $groupManager,
77
-		AccountManager $accountManager,
78
-		IAppManager $appManager,
79
-		IFactory $l10nFactory,
80
-		IL10N $l
81
-	) {
82
-		$this->config = $config;
83
-		$this->userManager = $userManager;
84
-		$this->accountManager = $accountManager;
85
-		$this->groupManager = $groupManager;
86
-		$this->appManager = $appManager;
87
-		$this->l10nFactory = $l10nFactory;
88
-		$this->l = $l;
89
-	}
90
-
91
-	/**
92
-	 * @return TemplateResponse returns the instance with all parameters set, ready to be rendered
93
-	 * @since 9.1
94
-	 */
95
-	public function getForm() {
96
-		$federatedFileSharingEnabled = $this->appManager->isEnabledForUser('federatedfilesharing');
97
-		$lookupServerUploadEnabled = false;
98
-		if ($federatedFileSharingEnabled) {
99
-			/** @var FederatedShareProvider $shareProvider */
100
-			$shareProvider = \OC::$server->query(FederatedShareProvider::class);
101
-			$lookupServerUploadEnabled = $shareProvider->isLookupServerUploadEnabled();
102
-		}
103
-
104
-		$uid = \OC_User::getUser();
105
-		$user = $this->userManager->get($uid);
106
-		$userData = $this->accountManager->getUser($user);
107
-
108
-		$storageInfo = \OC_Helper::getStorageInfo('/');
109
-		if ($storageInfo['quota'] === FileInfo::SPACE_UNLIMITED) {
110
-			$totalSpace = $this->l->t('Unlimited');
111
-		} else {
112
-			$totalSpace = \OC_Helper::humanFileSize($storageInfo['total']);
113
-		}
114
-
115
-		$languageParameters = $this->getLanguages($user);
116
-		$localeParameters = $this->getLocales($user);
117
-		$messageParameters = $this->getMessageParameters($userData);
118
-
119
-		$parameters = [
120
-			'total_space' => $totalSpace,
121
-			'usage' => \OC_Helper::humanFileSize($storageInfo['used']),
122
-			'usage_relative' => round($storageInfo['relative']),
123
-			'quota' => $storageInfo['quota'],
124
-			'avatarChangeSupported' => $user->canChangeAvatar(),
125
-			'lookupServerUploadEnabled' => $lookupServerUploadEnabled,
126
-			'avatarScope' => $userData[AccountManager::PROPERTY_AVATAR]['scope'],
127
-			'displayNameChangeSupported' => $user->canChangeDisplayName(),
128
-			'displayName' => $userData[AccountManager::PROPERTY_DISPLAYNAME]['value'],
129
-			'displayNameScope' => $userData[AccountManager::PROPERTY_DISPLAYNAME]['scope'],
130
-			'email' => $userData[AccountManager::PROPERTY_EMAIL]['value'],
131
-			'emailScope' => $userData[AccountManager::PROPERTY_EMAIL]['scope'],
132
-			'emailVerification' => $userData[AccountManager::PROPERTY_EMAIL]['verified'],
133
-			'phone' => $userData[AccountManager::PROPERTY_PHONE]['value'],
134
-			'phoneScope' => $userData[AccountManager::PROPERTY_PHONE]['scope'],
135
-			'address' => $userData[AccountManager::PROPERTY_ADDRESS]['value'],
136
-			'addressScope' => $userData[AccountManager::PROPERTY_ADDRESS]['scope'],
137
-			'website' =>  $userData[AccountManager::PROPERTY_WEBSITE]['value'],
138
-			'websiteScope' =>  $userData[AccountManager::PROPERTY_WEBSITE]['scope'],
139
-			'websiteVerification' => $userData[AccountManager::PROPERTY_WEBSITE]['verified'],
140
-			'twitter' => $userData[AccountManager::PROPERTY_TWITTER]['value'],
141
-			'twitterScope' => $userData[AccountManager::PROPERTY_TWITTER]['scope'],
142
-			'twitterVerification' => $userData[AccountManager::PROPERTY_TWITTER]['verified'],
143
-			'groups' => $this->getGroups($user),
144
-		] + $messageParameters + $languageParameters + $localeParameters;
145
-
146
-
147
-		return new TemplateResponse('settings', 'settings/personal/personal.info', $parameters, '');
148
-	}
149
-
150
-	/**
151
-	 * @return string the section ID, e.g. 'sharing'
152
-	 * @since 9.1
153
-	 */
154
-	public function getSection() {
155
-		return 'personal-info';
156
-	}
157
-
158
-	/**
159
-	 * @return int whether the form should be rather on the top or bottom of
160
-	 * the admin section. The forms are arranged in ascending order of the
161
-	 * priority values. It is required to return a value between 0 and 100.
162
-	 *
163
-	 * E.g.: 70
164
-	 * @since 9.1
165
-	 */
166
-	public function getPriority() {
167
-		return 10;
168
-	}
169
-
170
-	/**
171
-	 * returns a sorted list of the user's group GIDs
172
-	 *
173
-	 * @param IUser $user
174
-	 * @return array
175
-	 */
176
-	private function getGroups(IUser $user) {
177
-		$groups = array_map(
178
-			function (IGroup $group) {
179
-				return $group->getDisplayName();
180
-			},
181
-			$this->groupManager->getUserGroups($user)
182
-		);
183
-		sort($groups);
184
-
185
-		return $groups;
186
-	}
187
-
188
-	/**
189
-	 * returns the user language, common language and other languages in an
190
-	 * associative array
191
-	 *
192
-	 * @param IUser $user
193
-	 * @return array
194
-	 */
195
-	private function getLanguages(IUser $user) {
196
-		$forceLanguage = $this->config->getSystemValue('force_language', false);
197
-		if ($forceLanguage !== false) {
198
-			return [];
199
-		}
200
-
201
-		$uid = $user->getUID();
202
-
203
-		$userConfLang = $this->config->getUserValue($uid, 'core', 'lang', $this->l10nFactory->findLanguage());
204
-		$languages = $this->l10nFactory->getLanguages();
205
-
206
-		// associate the user language with the proper array
207
-		$userLangIndex = array_search($userConfLang, array_column($languages['commonlanguages'], 'code'));
208
-		$userLang = $languages['commonlanguages'][$userLangIndex];
209
-		// search in the other languages
210
-		if ($userLangIndex === false) {
211
-			$userLangIndex = array_search($userConfLang, array_column($languages['languages'], 'code'));
212
-			$userLang = $languages['languages'][$userLangIndex];
213
-		}
214
-		// if user language is not available but set somehow: show the actual code as name
215
-		if (!is_array($userLang)) {
216
-			$userLang = [
217
-				'code' => $userConfLang,
218
-				'name' => $userConfLang,
219
-			];
220
-		}
221
-
222
-		return array_merge(
223
-			['activelanguage' => $userLang],
224
-			$languages
225
-		);
226
-	}
227
-
228
-	private function getLocales(IUser $user) {
229
-		$forceLanguage = $this->config->getSystemValue('force_locale', false);
230
-		if ($forceLanguage !== false) {
231
-			return [];
232
-		}
233
-
234
-		$uid = $user->getUID();
235
-
236
-		$userLocaleString = $this->config->getUserValue($uid, 'core', 'locale', $this->l10nFactory->findLocale());
237
-
238
-		$userLang = $this->config->getUserValue($uid, 'core', 'lang', $this->l10nFactory->findLanguage());
239
-
240
-		$localeCodes = $this->l10nFactory->findAvailableLocales();
241
-
242
-		$userLocale = array_filter($localeCodes, function ($value) use ($userLocaleString) {
243
-			return $userLocaleString === $value['code'];
244
-		});
245
-
246
-		if (!empty($userLocale)) {
247
-			$userLocale = reset($userLocale);
248
-		}
249
-
250
-		$localesForLanguage = array_filter($localeCodes, function ($localeCode) use ($userLang) {
251
-			return 0 === strpos($localeCode['code'], $userLang);
252
-		});
253
-
254
-		if (!$userLocale) {
255
-			$userLocale = [
256
-				'code' => 'en',
257
-				'name' => 'English'
258
-			];
259
-		}
260
-
261
-		return [
262
-			'activelocaleLang' => $userLocaleString,
263
-			'activelocale' => $userLocale,
264
-			'locales' => $localeCodes,
265
-			'localesForLanguage' => $localesForLanguage,
266
-		];
267
-	}
268
-
269
-	/**
270
-	 * @param array $userData
271
-	 * @return array
272
-	 */
273
-	private function getMessageParameters(array $userData) {
274
-		$needVerifyMessage = [AccountManager::PROPERTY_EMAIL, AccountManager::PROPERTY_WEBSITE, AccountManager::PROPERTY_TWITTER];
275
-		$messageParameters = [];
276
-		foreach ($needVerifyMessage as $property) {
277
-			switch ($userData[$property]['verified']) {
278
-				case AccountManager::VERIFIED:
279
-					$message = $this->l->t('Verifying');
280
-					break;
281
-				case AccountManager::VERIFICATION_IN_PROGRESS:
282
-					$message = $this->l->t('Verifying …');
283
-					break;
284
-				default:
285
-					$message = $this->l->t('Verify');
286
-			}
287
-			$messageParameters[$property . 'Message'] = $message;
288
-		}
289
-		return $messageParameters;
290
-	}
50
+    /** @var IConfig */
51
+    private $config;
52
+    /** @var IUserManager */
53
+    private $userManager;
54
+    /** @var AccountManager */
55
+    private $accountManager;
56
+    /** @var IGroupManager */
57
+    private $groupManager;
58
+    /** @var IAppManager */
59
+    private $appManager;
60
+    /** @var IFactory */
61
+    private $l10nFactory;
62
+    /** @var IL10N */
63
+    private $l;
64
+
65
+    /**
66
+     * @param IConfig $config
67
+     * @param IUserManager $userManager
68
+     * @param IGroupManager $groupManager
69
+     * @param AccountManager $accountManager
70
+     * @param IFactory $l10nFactory
71
+     * @param IL10N $l
72
+     */
73
+    public function __construct(
74
+        IConfig $config,
75
+        IUserManager $userManager,
76
+        IGroupManager $groupManager,
77
+        AccountManager $accountManager,
78
+        IAppManager $appManager,
79
+        IFactory $l10nFactory,
80
+        IL10N $l
81
+    ) {
82
+        $this->config = $config;
83
+        $this->userManager = $userManager;
84
+        $this->accountManager = $accountManager;
85
+        $this->groupManager = $groupManager;
86
+        $this->appManager = $appManager;
87
+        $this->l10nFactory = $l10nFactory;
88
+        $this->l = $l;
89
+    }
90
+
91
+    /**
92
+     * @return TemplateResponse returns the instance with all parameters set, ready to be rendered
93
+     * @since 9.1
94
+     */
95
+    public function getForm() {
96
+        $federatedFileSharingEnabled = $this->appManager->isEnabledForUser('federatedfilesharing');
97
+        $lookupServerUploadEnabled = false;
98
+        if ($federatedFileSharingEnabled) {
99
+            /** @var FederatedShareProvider $shareProvider */
100
+            $shareProvider = \OC::$server->query(FederatedShareProvider::class);
101
+            $lookupServerUploadEnabled = $shareProvider->isLookupServerUploadEnabled();
102
+        }
103
+
104
+        $uid = \OC_User::getUser();
105
+        $user = $this->userManager->get($uid);
106
+        $userData = $this->accountManager->getUser($user);
107
+
108
+        $storageInfo = \OC_Helper::getStorageInfo('/');
109
+        if ($storageInfo['quota'] === FileInfo::SPACE_UNLIMITED) {
110
+            $totalSpace = $this->l->t('Unlimited');
111
+        } else {
112
+            $totalSpace = \OC_Helper::humanFileSize($storageInfo['total']);
113
+        }
114
+
115
+        $languageParameters = $this->getLanguages($user);
116
+        $localeParameters = $this->getLocales($user);
117
+        $messageParameters = $this->getMessageParameters($userData);
118
+
119
+        $parameters = [
120
+            'total_space' => $totalSpace,
121
+            'usage' => \OC_Helper::humanFileSize($storageInfo['used']),
122
+            'usage_relative' => round($storageInfo['relative']),
123
+            'quota' => $storageInfo['quota'],
124
+            'avatarChangeSupported' => $user->canChangeAvatar(),
125
+            'lookupServerUploadEnabled' => $lookupServerUploadEnabled,
126
+            'avatarScope' => $userData[AccountManager::PROPERTY_AVATAR]['scope'],
127
+            'displayNameChangeSupported' => $user->canChangeDisplayName(),
128
+            'displayName' => $userData[AccountManager::PROPERTY_DISPLAYNAME]['value'],
129
+            'displayNameScope' => $userData[AccountManager::PROPERTY_DISPLAYNAME]['scope'],
130
+            'email' => $userData[AccountManager::PROPERTY_EMAIL]['value'],
131
+            'emailScope' => $userData[AccountManager::PROPERTY_EMAIL]['scope'],
132
+            'emailVerification' => $userData[AccountManager::PROPERTY_EMAIL]['verified'],
133
+            'phone' => $userData[AccountManager::PROPERTY_PHONE]['value'],
134
+            'phoneScope' => $userData[AccountManager::PROPERTY_PHONE]['scope'],
135
+            'address' => $userData[AccountManager::PROPERTY_ADDRESS]['value'],
136
+            'addressScope' => $userData[AccountManager::PROPERTY_ADDRESS]['scope'],
137
+            'website' =>  $userData[AccountManager::PROPERTY_WEBSITE]['value'],
138
+            'websiteScope' =>  $userData[AccountManager::PROPERTY_WEBSITE]['scope'],
139
+            'websiteVerification' => $userData[AccountManager::PROPERTY_WEBSITE]['verified'],
140
+            'twitter' => $userData[AccountManager::PROPERTY_TWITTER]['value'],
141
+            'twitterScope' => $userData[AccountManager::PROPERTY_TWITTER]['scope'],
142
+            'twitterVerification' => $userData[AccountManager::PROPERTY_TWITTER]['verified'],
143
+            'groups' => $this->getGroups($user),
144
+        ] + $messageParameters + $languageParameters + $localeParameters;
145
+
146
+
147
+        return new TemplateResponse('settings', 'settings/personal/personal.info', $parameters, '');
148
+    }
149
+
150
+    /**
151
+     * @return string the section ID, e.g. 'sharing'
152
+     * @since 9.1
153
+     */
154
+    public function getSection() {
155
+        return 'personal-info';
156
+    }
157
+
158
+    /**
159
+     * @return int whether the form should be rather on the top or bottom of
160
+     * the admin section. The forms are arranged in ascending order of the
161
+     * priority values. It is required to return a value between 0 and 100.
162
+     *
163
+     * E.g.: 70
164
+     * @since 9.1
165
+     */
166
+    public function getPriority() {
167
+        return 10;
168
+    }
169
+
170
+    /**
171
+     * returns a sorted list of the user's group GIDs
172
+     *
173
+     * @param IUser $user
174
+     * @return array
175
+     */
176
+    private function getGroups(IUser $user) {
177
+        $groups = array_map(
178
+            function (IGroup $group) {
179
+                return $group->getDisplayName();
180
+            },
181
+            $this->groupManager->getUserGroups($user)
182
+        );
183
+        sort($groups);
184
+
185
+        return $groups;
186
+    }
187
+
188
+    /**
189
+     * returns the user language, common language and other languages in an
190
+     * associative array
191
+     *
192
+     * @param IUser $user
193
+     * @return array
194
+     */
195
+    private function getLanguages(IUser $user) {
196
+        $forceLanguage = $this->config->getSystemValue('force_language', false);
197
+        if ($forceLanguage !== false) {
198
+            return [];
199
+        }
200
+
201
+        $uid = $user->getUID();
202
+
203
+        $userConfLang = $this->config->getUserValue($uid, 'core', 'lang', $this->l10nFactory->findLanguage());
204
+        $languages = $this->l10nFactory->getLanguages();
205
+
206
+        // associate the user language with the proper array
207
+        $userLangIndex = array_search($userConfLang, array_column($languages['commonlanguages'], 'code'));
208
+        $userLang = $languages['commonlanguages'][$userLangIndex];
209
+        // search in the other languages
210
+        if ($userLangIndex === false) {
211
+            $userLangIndex = array_search($userConfLang, array_column($languages['languages'], 'code'));
212
+            $userLang = $languages['languages'][$userLangIndex];
213
+        }
214
+        // if user language is not available but set somehow: show the actual code as name
215
+        if (!is_array($userLang)) {
216
+            $userLang = [
217
+                'code' => $userConfLang,
218
+                'name' => $userConfLang,
219
+            ];
220
+        }
221
+
222
+        return array_merge(
223
+            ['activelanguage' => $userLang],
224
+            $languages
225
+        );
226
+    }
227
+
228
+    private function getLocales(IUser $user) {
229
+        $forceLanguage = $this->config->getSystemValue('force_locale', false);
230
+        if ($forceLanguage !== false) {
231
+            return [];
232
+        }
233
+
234
+        $uid = $user->getUID();
235
+
236
+        $userLocaleString = $this->config->getUserValue($uid, 'core', 'locale', $this->l10nFactory->findLocale());
237
+
238
+        $userLang = $this->config->getUserValue($uid, 'core', 'lang', $this->l10nFactory->findLanguage());
239
+
240
+        $localeCodes = $this->l10nFactory->findAvailableLocales();
241
+
242
+        $userLocale = array_filter($localeCodes, function ($value) use ($userLocaleString) {
243
+            return $userLocaleString === $value['code'];
244
+        });
245
+
246
+        if (!empty($userLocale)) {
247
+            $userLocale = reset($userLocale);
248
+        }
249
+
250
+        $localesForLanguage = array_filter($localeCodes, function ($localeCode) use ($userLang) {
251
+            return 0 === strpos($localeCode['code'], $userLang);
252
+        });
253
+
254
+        if (!$userLocale) {
255
+            $userLocale = [
256
+                'code' => 'en',
257
+                'name' => 'English'
258
+            ];
259
+        }
260
+
261
+        return [
262
+            'activelocaleLang' => $userLocaleString,
263
+            'activelocale' => $userLocale,
264
+            'locales' => $localeCodes,
265
+            'localesForLanguage' => $localesForLanguage,
266
+        ];
267
+    }
268
+
269
+    /**
270
+     * @param array $userData
271
+     * @return array
272
+     */
273
+    private function getMessageParameters(array $userData) {
274
+        $needVerifyMessage = [AccountManager::PROPERTY_EMAIL, AccountManager::PROPERTY_WEBSITE, AccountManager::PROPERTY_TWITTER];
275
+        $messageParameters = [];
276
+        foreach ($needVerifyMessage as $property) {
277
+            switch ($userData[$property]['verified']) {
278
+                case AccountManager::VERIFIED:
279
+                    $message = $this->l->t('Verifying');
280
+                    break;
281
+                case AccountManager::VERIFICATION_IN_PROGRESS:
282
+                    $message = $this->l->t('Verifying …');
283
+                    break;
284
+                default:
285
+                    $message = $this->l->t('Verify');
286
+            }
287
+            $messageParameters[$property . 'Message'] = $message;
288
+        }
289
+        return $messageParameters;
290
+    }
291 291
 }
Please login to merge, or discard this patch.