UpdateGroups.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. *
  5. * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
  6. * @author Bart Visscher <bartv@thisnet.nl>
  7. * @author Christoph Wurst <christoph@winzerhof-wurst.at>
  8. * @author Joas Schilling <coding@schilljs.com>
  9. * @author Lukas Reschke <lukas@statuscode.ch>
  10. * @author Morris Jobke <hey@morrisjobke.de>
  11. * @author Robin Appelman <robin@icewind.nl>
  12. * @author Robin McCorkell <robin@mccorkell.me.uk>
  13. *
  14. * @license AGPL-3.0
  15. *
  16. * This code is free software: you can redistribute it and/or modify
  17. * it under the terms of the GNU Affero General Public License, version 3,
  18. * as published by the Free Software Foundation.
  19. *
  20. * This program is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. * GNU Affero General Public License for more details.
  24. *
  25. * You should have received a copy of the GNU Affero General Public License, version 3,
  26. * along with this program. If not, see <http://www.gnu.org/licenses/>
  27. *
  28. */
  29. namespace OCA\User_LDAP\Jobs;
  30. use OC\BackgroundJob\TimedJob;
  31. use OCA\User_LDAP\Group_Proxy;
  32. use OCP\EventDispatcher\IEventDispatcher;
  33. use OCP\Group\Events\UserAddedEvent;
  34. use OCP\Group\Events\UserRemovedEvent;
  35. use OCP\IDBConnection;
  36. use OCP\IGroupManager;
  37. use OCP\IUser;
  38. use OCP\IUserManager;
  39. use Psr\Log\LoggerInterface;
  40. class UpdateGroups extends TimedJob {
  41. private $groupsFromDB;
  42. /** @var Group_Proxy */
  43. private $groupBackend;
  44. /** @var IEventDispatcher */
  45. private $dispatcher;
  46. /** @var IGroupManager */
  47. private $groupManager;
  48. /** @var IUserManager */
  49. private $userManager;
  50. /** @var LoggerInterface */
  51. private $logger;
  52. /** @var IDBConnection */
  53. private $dbc;
  54. public function __construct(
  55. Group_Proxy $groupBackend,
  56. IEventDispatcher $dispatcher,
  57. IGroupManager $groupManager,
  58. IUserManager $userManager,
  59. LoggerInterface $logger,
  60. IDBConnection $dbc
  61. ) {
  62. $this->interval = $this->getRefreshInterval();
  63. $this->groupBackend = $groupBackend;
  64. $this->dispatcher = $dispatcher;
  65. $this->groupManager = $groupManager;
  66. $this->userManager = $userManager;
  67. $this->logger = $logger;
  68. $this->dbc = $dbc;
  69. }
  70. /**
  71. * @return int
  72. */
  73. private function getRefreshInterval() {
  74. //defaults to every hour
  75. return \OC::$server->getConfig()->getAppValue('user_ldap', 'bgjRefreshInterval', 3600);
  76. }
  77. /**
  78. * @param mixed $argument
  79. */
  80. public function run($argument) {
  81. $this->updateGroups();
  82. }
  83. public function updateGroups() {
  84. $this->logger->debug(
  85. 'Run background job "updateGroups"',
  86. ['app' => 'user_ldap']
  87. );
  88. $knownGroups = array_keys($this->getKnownGroups());
  89. $actualGroups = $this->groupBackend->getGroups();
  90. if (empty($actualGroups) && empty($knownGroups)) {
  91. $this->logger->info(
  92. 'bgJ "updateGroups" – groups do not seem to be configured properly, aborting.',
  93. ['app' => 'user_ldap']
  94. );
  95. return;
  96. }
  97. $this->handleKnownGroups(array_intersect($actualGroups, $knownGroups));
  98. $this->handleCreatedGroups(array_diff($actualGroups, $knownGroups));
  99. $this->handleRemovedGroups(array_diff($knownGroups, $actualGroups));
  100. $this->logger->debug(
  101. 'bgJ "updateGroups" – Finished.',
  102. ['app' => 'user_ldap']
  103. );
  104. }
  105. /**
  106. * @return array
  107. */
  108. private function getKnownGroups() {
  109. if (is_array($this->groupsFromDB)) {
  110. $this->groupsFromDB;
  111. }
  112. $qb = $this->dbc->getQueryBuilder();
  113. $qb->select(['owncloudname', 'owncloudusers'])
  114. ->from('ldap_group_members');
  115. $qResult = $qb->execute();
  116. $result = $qResult->fetchAll();
  117. $qResult->closeCursor();
  118. $this->groupsFromDB = [];
  119. foreach ($result as $dataset) {
  120. $this->groupsFromDB[$dataset['owncloudname']] = $dataset;
  121. }
  122. return $this->groupsFromDB;
  123. }
  124. private function handleKnownGroups(array $groups) {
  125. $this->logger->debug(
  126. 'bgJ "updateGroups" – Dealing with known Groups.',
  127. ['app' => 'user_ldap']
  128. );
  129. $qb = $this->dbc->getQueryBuilder();
  130. $qb->update('ldap_group_members')
  131. ->set('owncloudusers', $qb->createParameter('members'))
  132. ->where($qb->expr()->eq('owncloudname', $qb->createParameter('groupId')));
  133. if (!is_array($this->groupsFromDB)) {
  134. $this->getKnownGroups();
  135. }
  136. foreach ($groups as $group) {
  137. $knownUsers = unserialize($this->groupsFromDB[$group]['owncloudusers']);
  138. $actualUsers = $this->groupBackend->usersInGroup($group);
  139. $hasChanged = false;
  140. $groupObject = $this->groupManager->get($group);
  141. foreach (array_diff($knownUsers, $actualUsers) as $removedUser) {
  142. $userObject = $this->userManager->get($removedUser);
  143. if ($userObject instanceof IUser) {
  144. $this->dispatcher->dispatchTyped(new UserRemovedEvent($groupObject, $userObject));
  145. }
  146. $this->logger->info(
  147. 'bgJ "updateGroups" – {user} removed from {group}',
  148. [
  149. 'app' => 'user_ldap',
  150. 'user' => $removedUser,
  151. 'group' => $group
  152. ]
  153. );
  154. $hasChanged = true;
  155. }
  156. foreach (array_diff($actualUsers, $knownUsers) as $addedUser) {
  157. $userObject = $this->userManager->get($addedUser);
  158. if ($userObject instanceof IUser) {
  159. $this->dispatcher->dispatchTyped(new UserAddedEvent($groupObject, $userObject));
  160. }
  161. $this->logger->info(
  162. 'bgJ "updateGroups" – {user} added to {group}',
  163. [
  164. 'app' => 'user_ldap',
  165. 'user' => $addedUser,
  166. 'group' => $group
  167. ]
  168. );
  169. $hasChanged = true;
  170. }
  171. if ($hasChanged) {
  172. $qb->setParameters([
  173. 'members' => serialize($actualUsers),
  174. 'groupId' => $group
  175. ]);
  176. $qb->execute();
  177. }
  178. }
  179. $this->logger->debug(
  180. 'bgJ "updateGroups" – FINISHED dealing with known Groups.',
  181. ['app' => 'user_ldap']
  182. );
  183. }
  184. /**
  185. * @param string[] $createdGroups
  186. */
  187. private function handleCreatedGroups($createdGroups) {
  188. $this->logger->debug(
  189. 'bgJ "updateGroups" – dealing with created Groups.',
  190. ['app' => 'user_ldap']
  191. );
  192. $query = $this->dbc->getQueryBuilder();
  193. $query->insert('ldap_group_members')
  194. ->setValue('owncloudname', $query->createParameter('owncloudname'))
  195. ->setValue('owncloudusers', $query->createParameter('owncloudusers'));
  196. foreach ($createdGroups as $createdGroup) {
  197. $this->logger->info(
  198. 'bgJ "updateGroups" – new group "' . $createdGroup . '" found.',
  199. ['app' => 'user_ldap']
  200. );
  201. $users = serialize($this->groupBackend->usersInGroup($createdGroup));
  202. $query->setParameter('owncloudname', $createdGroup)
  203. ->setParameter('owncloudusers', $users);
  204. $query->execute();
  205. }
  206. $this->logger->debug(
  207. 'bgJ "updateGroups" – FINISHED dealing with created Groups.',
  208. ['app' => 'user_ldap']
  209. );
  210. }
  211. /**
  212. * @param string[] $removedGroups
  213. */
  214. private function handleRemovedGroups($removedGroups) {
  215. $this->logger->debug(
  216. 'bgJ "updateGroups" – dealing with removed groups.',
  217. ['app' => 'user_ldap']
  218. );
  219. $query = $this->dbc->getQueryBuilder();
  220. $query->delete('ldap_group_members')
  221. ->where($query->expr()->eq('owncloudname', $query->createParameter('owncloudname')));
  222. foreach ($removedGroups as $removedGroup) {
  223. $this->logger->info(
  224. 'bgJ "updateGroups" – group "' . $removedGroup . '" was removed.',
  225. ['app' => 'user_ldap']
  226. );
  227. $query->setParameter('owncloudname', $removedGroup);
  228. $query->execute();
  229. }
  230. $this->logger->debug(
  231. 'bgJ "updateGroups" – FINISHED dealing with removed groups.',
  232. ['app' => 'user_ldap']
  233. );
  234. }
  235. }