Proxy.php 3.9 KB

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