Proxy.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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 OCA\User_LDAP;
  8. use OCA\User_LDAP\Mapping\GroupMapping;
  9. use OCA\User_LDAP\Mapping\UserMapping;
  10. use OCP\ICache;
  11. use OCP\Server;
  12. abstract class Proxy {
  13. /** @var array<string,Access> */
  14. private static array $accesses = [];
  15. private ?bool $isSingleBackend = null;
  16. private ?ICache $cache = null;
  17. public function __construct(
  18. private ILDAPWrapper $ldap,
  19. private AccessFactory $accessFactory,
  20. ) {
  21. $memcache = \OC::$server->getMemCacheFactory();
  22. if ($memcache->isAvailable()) {
  23. $this->cache = $memcache->createDistributed();
  24. }
  25. }
  26. private function addAccess(string $configPrefix): void {
  27. $userMap = Server::get(UserMapping::class);
  28. $groupMap = Server::get(GroupMapping::class);
  29. $connector = new Connection($this->ldap, $configPrefix);
  30. $access = $this->accessFactory->get($connector);
  31. $access->setUserMapper($userMap);
  32. $access->setGroupMapper($groupMap);
  33. self::$accesses[$configPrefix] = $access;
  34. }
  35. protected function getAccess(string $configPrefix): Access {
  36. if (!isset(self::$accesses[$configPrefix])) {
  37. $this->addAccess($configPrefix);
  38. }
  39. return self::$accesses[$configPrefix];
  40. }
  41. /**
  42. * @param string $uid
  43. * @return string
  44. */
  45. protected function getUserCacheKey($uid) {
  46. return 'user-' . $uid . '-lastSeenOn';
  47. }
  48. /**
  49. * @param string $gid
  50. * @return string
  51. */
  52. protected function getGroupCacheKey($gid) {
  53. return 'group-' . $gid . '-lastSeenOn';
  54. }
  55. /**
  56. * @param string $id
  57. * @param string $method
  58. * @param array $parameters
  59. * @param bool $passOnWhen
  60. * @return mixed
  61. */
  62. abstract protected function callOnLastSeenOn($id, $method, $parameters, $passOnWhen);
  63. /**
  64. * @param string $id
  65. * @param string $method
  66. * @param array $parameters
  67. * @return mixed
  68. */
  69. abstract protected function walkBackends($id, $method, $parameters);
  70. /**
  71. * @param string $id
  72. * @return Access
  73. */
  74. abstract public function getLDAPAccess($id);
  75. abstract protected function activeBackends(): int;
  76. protected function isSingleBackend(): bool {
  77. if ($this->isSingleBackend === null) {
  78. $this->isSingleBackend = $this->activeBackends() === 1;
  79. }
  80. return $this->isSingleBackend;
  81. }
  82. /**
  83. * Takes care of the request to the User backend
  84. *
  85. * @param string $id
  86. * @param string $method string, the method of the user backend that shall be called
  87. * @param array $parameters an array of parameters to be passed
  88. * @param bool $passOnWhen
  89. * @return mixed the result of the specified method
  90. */
  91. protected function handleRequest($id, $method, $parameters, $passOnWhen = false) {
  92. if (!$this->isSingleBackend()) {
  93. $result = $this->callOnLastSeenOn($id, $method, $parameters, $passOnWhen);
  94. }
  95. if (!isset($result) || $result === $passOnWhen) {
  96. $result = $this->walkBackends($id, $method, $parameters);
  97. }
  98. return $result;
  99. }
  100. /**
  101. * @param string|null $key
  102. * @return string
  103. */
  104. private function getCacheKey($key) {
  105. $prefix = 'LDAP-Proxy-';
  106. if ($key === null) {
  107. return $prefix;
  108. }
  109. return $prefix . hash('sha256', $key);
  110. }
  111. /**
  112. * @param string $key
  113. * @return mixed|null
  114. */
  115. public function getFromCache($key) {
  116. if ($this->cache === null) {
  117. return null;
  118. }
  119. $key = $this->getCacheKey($key);
  120. $value = $this->cache->get($key);
  121. if ($value === null) {
  122. return null;
  123. }
  124. return json_decode(base64_decode($value));
  125. }
  126. /**
  127. * @param string $key
  128. * @param mixed $value
  129. */
  130. public function writeToCache($key, $value) {
  131. if ($this->cache === null) {
  132. return;
  133. }
  134. $key = $this->getCacheKey($key);
  135. $value = base64_encode(json_encode($value));
  136. $this->cache->set($key, $value, 2592000);
  137. }
  138. public function clearCache() {
  139. if ($this->cache === null) {
  140. return;
  141. }
  142. $this->cache->clear($this->getCacheKey(null));
  143. }
  144. }