cleanup.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. <?php
  2. /**
  3. * @author Arthur Schiwon <blizzz@owncloud.com>
  4. * @author Morris Jobke <hey@morrisjobke.de>
  5. *
  6. * @copyright Copyright (c) 2015, ownCloud, Inc.
  7. * @license AGPL-3.0
  8. *
  9. * This code is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Affero General Public License, version 3,
  11. * as published by the Free Software Foundation.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU Affero General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public License, version 3,
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>
  20. *
  21. */
  22. namespace OCA\User_LDAP\Jobs;
  23. use \OC\BackgroundJob\TimedJob;
  24. use \OCA\user_ldap\User_LDAP;
  25. use \OCA\user_ldap\User_Proxy;
  26. use \OCA\user_ldap\lib\Helper;
  27. use \OCA\user_ldap\lib\LDAP;
  28. use \OCA\user_ldap\lib\user\DeletedUsersIndex;
  29. use \OCA\User_LDAP\Mapping\UserMapping;
  30. /**
  31. * Class CleanUp
  32. *
  33. * a Background job to clean up deleted users
  34. *
  35. * @package OCA\user_ldap\lib;
  36. */
  37. class CleanUp extends TimedJob {
  38. /** @var int $limit amount of users that should be checked per run */
  39. protected $limit = 50;
  40. /** @var int $defaultIntervalMin default interval in minutes */
  41. protected $defaultIntervalMin = 51;
  42. /** @var User_LDAP|User_Proxy $userBackend */
  43. protected $userBackend;
  44. /** @var \OCP\IConfig $ocConfig */
  45. protected $ocConfig;
  46. /** @var \OCP\IDBConnection $db */
  47. protected $db;
  48. /** @var Helper $ldapHelper */
  49. protected $ldapHelper;
  50. /** @var \OCA\User_LDAP\Mapping\UserMapping */
  51. protected $mapping;
  52. /** @var \OCA\User_LDAP\lib\User\DeletedUsersIndex */
  53. protected $dui;
  54. public function __construct() {
  55. $minutes = \OC::$server->getConfig()->getSystemValue(
  56. 'ldapUserCleanupInterval', strval($this->defaultIntervalMin));
  57. $this->setInterval(intval($minutes) * 60);
  58. }
  59. /**
  60. * assigns the instances passed to run() to the class properties
  61. * @param array $arguments
  62. */
  63. public function setArguments($arguments) {
  64. //Dependency Injection is not possible, because the constructor will
  65. //only get values that are serialized to JSON. I.e. whatever we would
  66. //pass in app.php we do add here, except something else is passed e.g.
  67. //in tests.
  68. if(isset($arguments['helper'])) {
  69. $this->ldapHelper = $arguments['helper'];
  70. } else {
  71. $this->ldapHelper = new Helper();
  72. }
  73. if(isset($arguments['ocConfig'])) {
  74. $this->ocConfig = $arguments['ocConfig'];
  75. } else {
  76. $this->ocConfig = \OC::$server->getConfig();
  77. }
  78. if(isset($arguments['userBackend'])) {
  79. $this->userBackend = $arguments['userBackend'];
  80. } else {
  81. $this->userBackend = new User_Proxy(
  82. $this->ldapHelper->getServerConfigurationPrefixes(true),
  83. new LDAP(),
  84. $this->ocConfig
  85. );
  86. }
  87. if(isset($arguments['db'])) {
  88. $this->db = $arguments['db'];
  89. } else {
  90. $this->db = \OC::$server->getDatabaseConnection();
  91. }
  92. if(isset($arguments['mapping'])) {
  93. $this->mapping = $arguments['mapping'];
  94. } else {
  95. $this->mapping = new UserMapping($this->db);
  96. }
  97. if(isset($arguments['deletedUsersIndex'])) {
  98. $this->dui = $arguments['deletedUsersIndex'];
  99. } else {
  100. $this->dui = new DeletedUsersIndex(
  101. $this->ocConfig, $this->db, $this->mapping);
  102. }
  103. }
  104. /**
  105. * makes the background job do its work
  106. * @param array $argument
  107. */
  108. public function run($argument) {
  109. $this->setArguments($argument);
  110. if(!$this->isCleanUpAllowed()) {
  111. return;
  112. }
  113. $users = $this->mapping->getList($this->getOffset(), $this->limit);
  114. if(!is_array($users)) {
  115. //something wrong? Let's start from the beginning next time and
  116. //abort
  117. $this->setOffset(true);
  118. return;
  119. }
  120. $resetOffset = $this->isOffsetResetNecessary(count($users));
  121. $this->checkUsers($users);
  122. $this->setOffset($resetOffset);
  123. }
  124. /**
  125. * checks whether next run should start at 0 again
  126. * @param int $resultCount
  127. * @return bool
  128. */
  129. public function isOffsetResetNecessary($resultCount) {
  130. return ($resultCount < $this->limit) ? true : false;
  131. }
  132. /**
  133. * checks whether cleaning up LDAP users is allowed
  134. * @return bool
  135. */
  136. public function isCleanUpAllowed() {
  137. try {
  138. if($this->ldapHelper->haveDisabledConfigurations()) {
  139. return false;
  140. }
  141. } catch (\Exception $e) {
  142. return false;
  143. }
  144. $enabled = $this->isCleanUpEnabled();
  145. return $enabled;
  146. }
  147. /**
  148. * checks whether clean up is enabled by configuration
  149. * @return bool
  150. */
  151. private function isCleanUpEnabled() {
  152. return (bool)$this->ocConfig->getSystemValue(
  153. 'ldapUserCleanupInterval', strval($this->defaultIntervalMin));
  154. }
  155. /**
  156. * checks users whether they are still existing
  157. * @param array $users result from getMappedUsers()
  158. */
  159. private function checkUsers(array $users) {
  160. foreach($users as $user) {
  161. $this->checkUser($user);
  162. }
  163. }
  164. /**
  165. * checks whether a user is still existing in LDAP
  166. * @param string[] $user
  167. */
  168. private function checkUser(array $user) {
  169. if($this->userBackend->userExistsOnLDAP($user['name'])) {
  170. //still available, all good
  171. return;
  172. }
  173. $this->dui->markUser($user['name']);
  174. }
  175. /**
  176. * gets the offset to fetch users from the mappings table
  177. * @return int
  178. */
  179. private function getOffset() {
  180. return intval($this->ocConfig->getAppValue('user_ldap', 'cleanUpJobOffset', 0));
  181. }
  182. /**
  183. * sets the new offset for the next run
  184. * @param bool $reset whether the offset should be set to 0
  185. */
  186. public function setOffset($reset = false) {
  187. $newOffset = $reset ? 0 :
  188. $this->getOffset() + $this->limit;
  189. $this->ocConfig->setAppValue('user_ldap', 'cleanUpJobOffset', $newOffset);
  190. }
  191. /**
  192. * returns the chunk size (limit in DB speak)
  193. * @return int
  194. */
  195. public function getChunkSize() {
  196. return $this->limit;
  197. }
  198. }