SubAdmin.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-only
  6. */
  7. namespace OC;
  8. use OC\Hooks\PublicEmitter;
  9. use OCP\EventDispatcher\IEventDispatcher;
  10. use OCP\Group\Events\SubAdminAddedEvent;
  11. use OCP\Group\Events\SubAdminRemovedEvent;
  12. use OCP\Group\ISubAdmin;
  13. use OCP\IDBConnection;
  14. use OCP\IGroup;
  15. use OCP\IGroupManager;
  16. use OCP\IUser;
  17. use OCP\IUserManager;
  18. class SubAdmin extends PublicEmitter implements ISubAdmin {
  19. public function __construct(
  20. private IUserManager $userManager,
  21. private IGroupManager $groupManager,
  22. private IDBConnection $dbConn,
  23. private IEventDispatcher $eventDispatcher,
  24. ) {
  25. $this->userManager->listen('\OC\User', 'postDelete', function ($user) {
  26. $this->post_deleteUser($user);
  27. });
  28. $this->groupManager->listen('\OC\Group', 'postDelete', function ($group) {
  29. $this->post_deleteGroup($group);
  30. });
  31. }
  32. /**
  33. * add a SubAdmin
  34. * @param IUser $user user to be SubAdmin
  35. * @param IGroup $group group $user becomes subadmin of
  36. */
  37. public function createSubAdmin(IUser $user, IGroup $group): void {
  38. $qb = $this->dbConn->getQueryBuilder();
  39. $qb->insert('group_admin')
  40. ->values([
  41. 'gid' => $qb->createNamedParameter($group->getGID()),
  42. 'uid' => $qb->createNamedParameter($user->getUID())
  43. ])
  44. ->executeStatement();
  45. /** @deprecated 21.0.0 - use type SubAdminAddedEvent instead */
  46. $this->emit('\OC\SubAdmin', 'postCreateSubAdmin', [$user, $group]);
  47. $event = new SubAdminAddedEvent($group, $user);
  48. $this->eventDispatcher->dispatchTyped($event);
  49. }
  50. /**
  51. * delete a SubAdmin
  52. * @param IUser $user the user that is the SubAdmin
  53. * @param IGroup $group the group
  54. */
  55. public function deleteSubAdmin(IUser $user, IGroup $group): void {
  56. $qb = $this->dbConn->getQueryBuilder();
  57. $qb->delete('group_admin')
  58. ->where($qb->expr()->eq('gid', $qb->createNamedParameter($group->getGID())))
  59. ->andWhere($qb->expr()->eq('uid', $qb->createNamedParameter($user->getUID())))
  60. ->executeStatement();
  61. /** @deprecated 21.0.0 - use type SubAdminRemovedEvent instead */
  62. $this->emit('\OC\SubAdmin', 'postDeleteSubAdmin', [$user, $group]);
  63. $event = new SubAdminRemovedEvent($group, $user);
  64. $this->eventDispatcher->dispatchTyped($event);
  65. }
  66. /**
  67. * get groups of a SubAdmin
  68. * @param IUser $user the SubAdmin
  69. * @return IGroup[]
  70. */
  71. public function getSubAdminsGroups(IUser $user): array {
  72. $groupIds = $this->getSubAdminsGroupIds($user);
  73. $groups = [];
  74. foreach ($groupIds as $groupId) {
  75. $group = $this->groupManager->get($groupId);
  76. if ($group !== null) {
  77. $groups[$group->getGID()] = $group;
  78. }
  79. }
  80. return $groups;
  81. }
  82. /**
  83. * Get group ids of a SubAdmin
  84. * @param IUser $user the SubAdmin
  85. * @return string[]
  86. */
  87. public function getSubAdminsGroupIds(IUser $user): array {
  88. $qb = $this->dbConn->getQueryBuilder();
  89. $result = $qb->select('gid')
  90. ->from('group_admin')
  91. ->where($qb->expr()->eq('uid', $qb->createNamedParameter($user->getUID())))
  92. ->executeQuery();
  93. $groups = [];
  94. while ($row = $result->fetch()) {
  95. $groups[] = $row['gid'];
  96. }
  97. $result->closeCursor();
  98. return $groups;
  99. }
  100. /**
  101. * get an array of groupid and displayName for a user
  102. * @param IUser $user
  103. * @return array ['displayName' => displayname]
  104. */
  105. public function getSubAdminsGroupsName(IUser $user): array {
  106. return array_map(function ($group) {
  107. return ['displayName' => $group->getDisplayName()];
  108. }, $this->getSubAdminsGroups($user));
  109. }
  110. /**
  111. * get SubAdmins of a group
  112. * @param IGroup $group the group
  113. * @return IUser[]
  114. */
  115. public function getGroupsSubAdmins(IGroup $group): array {
  116. $qb = $this->dbConn->getQueryBuilder();
  117. $result = $qb->select('uid')
  118. ->from('group_admin')
  119. ->where($qb->expr()->eq('gid', $qb->createNamedParameter($group->getGID())))
  120. ->executeQuery();
  121. $users = [];
  122. while ($row = $result->fetch()) {
  123. $user = $this->userManager->get($row['uid']);
  124. if (!is_null($user)) {
  125. $users[] = $user;
  126. }
  127. }
  128. $result->closeCursor();
  129. return $users;
  130. }
  131. /**
  132. * get all SubAdmins
  133. * @return array
  134. */
  135. public function getAllSubAdmins(): array {
  136. $qb = $this->dbConn->getQueryBuilder();
  137. $result = $qb->select('*')
  138. ->from('group_admin')
  139. ->executeQuery();
  140. $subadmins = [];
  141. while ($row = $result->fetch()) {
  142. $user = $this->userManager->get($row['uid']);
  143. $group = $this->groupManager->get($row['gid']);
  144. if (!is_null($user) && !is_null($group)) {
  145. $subadmins[] = [
  146. 'user' => $user,
  147. 'group' => $group
  148. ];
  149. }
  150. }
  151. $result->closeCursor();
  152. return $subadmins;
  153. }
  154. /**
  155. * checks if a user is a SubAdmin of a group
  156. * @param IUser $user
  157. * @param IGroup $group
  158. * @return bool
  159. */
  160. public function isSubAdminOfGroup(IUser $user, IGroup $group): bool {
  161. $qb = $this->dbConn->getQueryBuilder();
  162. /*
  163. * Primary key is ('gid', 'uid') so max 1 result possible here
  164. */
  165. $result = $qb->select('*')
  166. ->from('group_admin')
  167. ->where($qb->expr()->eq('gid', $qb->createNamedParameter($group->getGID())))
  168. ->andWhere($qb->expr()->eq('uid', $qb->createNamedParameter($user->getUID())))
  169. ->executeQuery();
  170. $fetch = $result->fetch();
  171. $result->closeCursor();
  172. $result = !empty($fetch) ? true : false;
  173. return $result;
  174. }
  175. /**
  176. * checks if a user is a SubAdmin
  177. * @param IUser $user
  178. * @return bool
  179. */
  180. public function isSubAdmin(IUser $user): bool {
  181. // Check if the user is already an admin
  182. if ($this->groupManager->isAdmin($user->getUID())) {
  183. return true;
  184. }
  185. // Check if the user is already an admin
  186. if ($this->groupManager->isDelegatedAdmin($user->getUID())) {
  187. return true;
  188. }
  189. $qb = $this->dbConn->getQueryBuilder();
  190. $result = $qb->select('gid')
  191. ->from('group_admin')
  192. ->andWhere($qb->expr()->eq('uid', $qb->createNamedParameter($user->getUID())))
  193. ->setMaxResults(1)
  194. ->executeQuery();
  195. $isSubAdmin = $result->fetch();
  196. $result->closeCursor();
  197. return $isSubAdmin !== false;
  198. }
  199. /**
  200. * checks if a user is a accessible by a subadmin
  201. * @param IUser $subadmin
  202. * @param IUser $user
  203. * @return bool
  204. */
  205. public function isUserAccessible(IUser $subadmin, IUser $user): bool {
  206. if ($subadmin->getUID() === $user->getUID()) {
  207. return true;
  208. }
  209. if (!$this->isSubAdmin($subadmin)) {
  210. return false;
  211. }
  212. if ($this->groupManager->isAdmin($user->getUID())) {
  213. return false;
  214. }
  215. $accessibleGroups = $this->getSubAdminsGroupIds($subadmin);
  216. $userGroups = $this->groupManager->getUserGroupIds($user);
  217. return !empty(array_intersect($accessibleGroups, $userGroups));
  218. }
  219. /**
  220. * delete all SubAdmins by $user
  221. * @param IUser $user
  222. */
  223. private function post_deleteUser(IUser $user) {
  224. $qb = $this->dbConn->getQueryBuilder();
  225. $qb->delete('group_admin')
  226. ->where($qb->expr()->eq('uid', $qb->createNamedParameter($user->getUID())))
  227. ->executeStatement();
  228. }
  229. /**
  230. * delete all SubAdmins by $group
  231. * @param IGroup $group
  232. */
  233. private function post_deleteGroup(IGroup $group) {
  234. $qb = $this->dbConn->getQueryBuilder();
  235. $qb->delete('group_admin')
  236. ->where($qb->expr()->eq('gid', $qb->createNamedParameter($group->getGID())))
  237. ->executeStatement();
  238. }
  239. }