You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

441 lines
11 KiB

12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
  1. <?php
  2. /**
  3. * @author Lukas Reschke
  4. * @copyright 2014 Lukas Reschke lukas@owncloud.com
  5. *
  6. * This file is licensed under the Affero General Public License version 3 or
  7. * later.
  8. * See the COPYING-README file.
  9. */
  10. namespace OC\Settings\Controller;
  11. use OC\AppFramework\Http;
  12. use OC\User\Manager;
  13. use OC\User\User;
  14. use \OCP\AppFramework\Controller;
  15. use OCP\AppFramework\Http\DataResponse;
  16. use OCP\AppFramework\Http\TemplateResponse;
  17. use OCP\IConfig;
  18. use OCP\IGroupManager;
  19. use OCP\IL10N;
  20. use OCP\ILogger;
  21. use OCP\IRequest;
  22. use OCP\IURLGenerator;
  23. use OCP\IUser;
  24. use OCP\IUserManager;
  25. use OCP\IUserSession;
  26. /**
  27. * @package OC\Settings\Controller
  28. */
  29. class UsersController extends Controller {
  30. /** @var IL10N */
  31. private $l10n;
  32. /** @var IUserSession */
  33. private $userSession;
  34. /** @var bool */
  35. private $isAdmin;
  36. /** @var IUserManager */
  37. private $userManager;
  38. /** @var IGroupManager */
  39. private $groupManager;
  40. /** @var IConfig */
  41. private $config;
  42. /** @var ILogger */
  43. private $log;
  44. /** @var \OC_Defaults */
  45. private $defaults;
  46. /** @var \OC_Mail */
  47. private $mail;
  48. /** @var string */
  49. private $fromMailAddress;
  50. /** @var IURLGenerator */
  51. private $urlGenerator;
  52. /**
  53. * @param string $appName
  54. * @param IRequest $request
  55. * @param IUserManager $userManager
  56. * @param IGroupManager $groupManager
  57. * @param IUserSession $userSession
  58. * @param IConfig $config
  59. * @param bool $isAdmin
  60. * @param IL10N $l10n
  61. * @param ILogger $log
  62. * @param \OC_Defaults $defaults
  63. * @param \OC_Mail $mail
  64. * @param string $fromMailAddress
  65. */
  66. public function __construct($appName,
  67. IRequest $request,
  68. IUserManager $userManager,
  69. IGroupManager $groupManager,
  70. IUserSession $userSession,
  71. IConfig $config,
  72. $isAdmin,
  73. IL10N $l10n,
  74. ILogger $log,
  75. \OC_Defaults $defaults,
  76. \OC_Mail $mail,
  77. $fromMailAddress,
  78. IURLGenerator $urlGenerator) {
  79. parent::__construct($appName, $request);
  80. $this->userManager = $userManager;
  81. $this->groupManager = $groupManager;
  82. $this->userSession = $userSession;
  83. $this->config = $config;
  84. $this->isAdmin = $isAdmin;
  85. $this->l10n = $l10n;
  86. $this->log = $log;
  87. $this->defaults = $defaults;
  88. $this->mail = $mail;
  89. $this->fromMailAddress = $fromMailAddress;
  90. $this->urlGenerator = $urlGenerator;
  91. }
  92. /**
  93. * @param IUser $user
  94. * @param array $userGroups
  95. * @return array
  96. */
  97. private function formatUserForIndex(IUser $user, array $userGroups = null) {
  98. return array(
  99. 'name' => $user->getUID(),
  100. 'displayname' => $user->getDisplayName(),
  101. 'groups' => (empty($userGroups)) ? $this->groupManager->getUserGroupIds($user) : $userGroups,
  102. 'subadmin' => \OC_SubAdmin::getSubAdminsGroups($user->getUID()),
  103. 'quota' => $this->config->getUserValue($user->getUID(), 'files', 'quota', 'default'),
  104. 'storageLocation' => $user->getHome(),
  105. 'lastLogin' => $user->getLastLogin(),
  106. 'backend' => $user->getBackendClassName(),
  107. 'email' => $this->config->getUserValue($user->getUID(), 'settings', 'email', '')
  108. );
  109. }
  110. /**
  111. * @param array $userIDs Array with schema [$uid => $displayName]
  112. * @return IUser[]
  113. */
  114. private function getUsersForUID(array $userIDs) {
  115. $users = [];
  116. foreach ($userIDs as $uid => $displayName) {
  117. $users[] = $this->userManager->get($uid);
  118. }
  119. return $users;
  120. }
  121. /**
  122. * @NoAdminRequired
  123. *
  124. * @param int $offset
  125. * @param int $limit
  126. * @param string $gid GID to filter for
  127. * @param string $pattern Pattern to search for in the username
  128. * @param string $backend Backend to filter for (class-name)
  129. * @return DataResponse
  130. *
  131. * TODO: Tidy up and write unit tests - code is mainly static method calls
  132. */
  133. public function index($offset = 0, $limit = 10, $gid = '', $pattern = '', $backend = '') {
  134. // FIXME: The JS sends the group '_everyone' instead of no GID for the "all users" group.
  135. if($gid === '_everyone') {
  136. $gid = '';
  137. }
  138. // Remove backends
  139. if(!empty($backend)) {
  140. $activeBackends = $this->userManager->getBackends();
  141. $this->userManager->clearBackends();
  142. foreach($activeBackends as $singleActiveBackend) {
  143. if($backend === get_class($singleActiveBackend)) {
  144. $this->userManager->registerBackend($singleActiveBackend);
  145. break;
  146. }
  147. }
  148. }
  149. $users = array();
  150. if ($this->isAdmin) {
  151. if($gid !== '') {
  152. $batch = $this->getUsersForUID($this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset));
  153. } else {
  154. $batch = $this->userManager->search($pattern, $limit, $offset);
  155. }
  156. foreach ($batch as $user) {
  157. $users[] = $this->formatUserForIndex($user);
  158. }
  159. } else {
  160. // Set the $gid parameter to an empty value if the subadmin has no rights to access a specific group
  161. if($gid !== '' && !in_array($gid, \OC_SubAdmin::getSubAdminsGroups($this->userSession->getUser()->getUID()))) {
  162. $gid = '';
  163. }
  164. $batch = $this->getUsersForUID($this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset));
  165. foreach ($batch as $user) {
  166. // Only add the groups, this user is a subadmin of
  167. $userGroups = array_intersect($this->groupManager->getUserGroupIds($user),
  168. \OC_SubAdmin::getSubAdminsGroups($this->userSession->getUser()->getUID()));
  169. $users[] = $this->formatUserForIndex($user, $userGroups);
  170. }
  171. }
  172. return new DataResponse($users);
  173. }
  174. /**
  175. * @NoAdminRequired
  176. *
  177. * @param string $username
  178. * @param string $password
  179. * @param array $groups
  180. * @param string $email
  181. * @return DataResponse
  182. *
  183. * TODO: Tidy up and write unit tests - code is mainly static method calls
  184. */
  185. public function create($username, $password, array $groups=array(), $email='') {
  186. if($email !== '' && !$this->mail->validateAddress($email)) {
  187. return new DataResponse(
  188. array(
  189. 'message' => (string)$this->l10n->t('Invalid mail address')
  190. ),
  191. Http::STATUS_UNPROCESSABLE_ENTITY
  192. );
  193. }
  194. // TODO FIXME get rid of the static calls to OC_Subadmin
  195. if (!$this->isAdmin) {
  196. if (!empty($groups)) {
  197. foreach ($groups as $key => $group) {
  198. if (!\OC_SubAdmin::isGroupAccessible($this->userSession->getUser()->getUID(), $group)) {
  199. unset($groups[$key]);
  200. }
  201. }
  202. }
  203. if (empty($groups)) {
  204. $groups = \OC_SubAdmin::getSubAdminsGroups($this->userSession->getUser()->getUID());
  205. }
  206. }
  207. try {
  208. $user = $this->userManager->createUser($username, $password);
  209. } catch (\Exception $exception) {
  210. return new DataResponse(
  211. array(
  212. 'message' => (string)$this->l10n->t('Unable to create user.')
  213. ),
  214. Http::STATUS_FORBIDDEN
  215. );
  216. }
  217. if($user instanceof User) {
  218. if($groups !== null) {
  219. foreach( $groups as $groupName ) {
  220. $group = $this->groupManager->get($groupName);
  221. if(empty($group)) {
  222. $group = $this->groupManager->createGroup($groupName);
  223. }
  224. $group->addUser($user);
  225. }
  226. }
  227. /**
  228. * Send new user mail only if a mail is set
  229. */
  230. if($email !== '') {
  231. $this->config->setUserValue($username, 'settings', 'email', $email);
  232. // data for the mail template
  233. $mailData = array(
  234. 'username' => $username,
  235. 'url' => $this->urlGenerator->getAbsoluteURL('/')
  236. );
  237. $mail = new TemplateResponse('settings', 'email.new_user', $mailData, 'blank');
  238. $mailContent = $mail->render();
  239. $mail = new TemplateResponse('settings', 'email.new_user_plain_text', $mailData, 'blank');
  240. $plainTextMailContent = $mail->render();
  241. $subject = $this->l10n->t('Your %s account was created', [$this->defaults->getName()]);
  242. try {
  243. $this->mail->send(
  244. $email,
  245. $username,
  246. $subject,
  247. $mailContent,
  248. $this->fromMailAddress,
  249. $this->defaults->getName(),
  250. 1,
  251. $plainTextMailContent);
  252. } catch(\Exception $e) {
  253. $this->log->error("Can't send new user mail to $email: " . $e->getMessage(), array('app' => 'settings'));
  254. }
  255. }
  256. // fetch users groups
  257. $userGroups = $this->groupManager->getUserGroupIds($user);
  258. return new DataResponse(
  259. $this->formatUserForIndex($user, $userGroups),
  260. Http::STATUS_CREATED
  261. );
  262. }
  263. return new DataResponse(
  264. array(
  265. 'message' => (string)$this->l10n->t('Unable to create user.')
  266. ),
  267. Http::STATUS_FORBIDDEN
  268. );
  269. }
  270. /**
  271. * @NoAdminRequired
  272. *
  273. * @param string $id
  274. * @return DataResponse
  275. *
  276. * TODO: Tidy up and write unit tests - code is mainly static method calls
  277. */
  278. public function destroy($id) {
  279. if($this->userSession->getUser()->getUID() === $id) {
  280. return new DataResponse(
  281. array(
  282. 'status' => 'error',
  283. 'data' => array(
  284. 'message' => (string)$this->l10n->t('Unable to delete user.')
  285. )
  286. ),
  287. Http::STATUS_FORBIDDEN
  288. );
  289. }
  290. // FIXME: Remove this static function call at some point…
  291. if(!$this->isAdmin && !\OC_SubAdmin::isUserAccessible($this->userSession->getUser()->getUID(), $id)) {
  292. return new DataResponse(
  293. array(
  294. 'status' => 'error',
  295. 'data' => array(
  296. 'message' => (string)$this->l10n->t('Authentication error')
  297. )
  298. ),
  299. Http::STATUS_FORBIDDEN
  300. );
  301. }
  302. $user = $this->userManager->get($id);
  303. if($user) {
  304. if($user->delete()) {
  305. return new DataResponse(
  306. array(
  307. 'status' => 'success',
  308. 'data' => array(
  309. 'username' => $id
  310. )
  311. ),
  312. Http::STATUS_NO_CONTENT
  313. );
  314. }
  315. }
  316. return new DataResponse(
  317. array(
  318. 'status' => 'error',
  319. 'data' => array(
  320. 'message' => (string)$this->l10n->t('Unable to delete user.')
  321. )
  322. ),
  323. Http::STATUS_FORBIDDEN
  324. );
  325. }
  326. /**
  327. * Set the mail address of a user
  328. *
  329. * @NoAdminRequired
  330. * @NoSubadminRequired
  331. *
  332. * @param string $id
  333. * @param string $mailAddress
  334. * @return DataResponse
  335. *
  336. * TODO: Tidy up and write unit tests - code is mainly static method calls
  337. */
  338. public function setMailAddress($id, $mailAddress) {
  339. // FIXME: Remove this static function call at some point…
  340. if($this->userSession->getUser()->getUID() !== $id
  341. && !$this->isAdmin
  342. && !\OC_SubAdmin::isUserAccessible($this->userSession->getUser()->getUID(), $id)) {
  343. return new DataResponse(
  344. array(
  345. 'status' => 'error',
  346. 'data' => array(
  347. 'message' => (string)$this->l10n->t('Forbidden')
  348. )
  349. ),
  350. Http::STATUS_FORBIDDEN
  351. );
  352. }
  353. if($mailAddress !== '' && !$this->mail->validateAddress($mailAddress)) {
  354. return new DataResponse(
  355. array(
  356. 'status' => 'error',
  357. 'data' => array(
  358. 'message' => (string)$this->l10n->t('Invalid mail address')
  359. )
  360. ),
  361. Http::STATUS_UNPROCESSABLE_ENTITY
  362. );
  363. }
  364. $user = $this->userManager->get($id);
  365. if(!$user){
  366. return new DataResponse(
  367. array(
  368. 'status' => 'error',
  369. 'data' => array(
  370. 'message' => (string)$this->l10n->t('Invalid user')
  371. )
  372. ),
  373. Http::STATUS_UNPROCESSABLE_ENTITY
  374. );
  375. }
  376. // this is the only permission a backend provides and is also used
  377. // for the permission of setting a email address
  378. if(!$user->canChangeDisplayName()){
  379. return new DataResponse(
  380. array(
  381. 'status' => 'error',
  382. 'data' => array(
  383. 'message' => (string)$this->l10n->t('Unable to change mail address')
  384. )
  385. ),
  386. Http::STATUS_FORBIDDEN
  387. );
  388. }
  389. $this->config->setUserValue($id, 'settings', 'email', $mailAddress);
  390. return new DataResponse(
  391. array(
  392. 'status' => 'success',
  393. 'data' => array(
  394. 'username' => $id,
  395. 'mailAddress' => $mailAddress,
  396. 'message' => (string)$this->l10n->t('Email saved')
  397. )
  398. ),
  399. Http::STATUS_OK
  400. );
  401. }
  402. }