diff options
Diffstat (limited to 'apps/user_ldap/lib/Group_Proxy.php')
-rw-r--r-- | apps/user_ldap/lib/Group_Proxy.php | 251 |
1 files changed, 168 insertions, 83 deletions
diff --git a/apps/user_ldap/lib/Group_Proxy.php b/apps/user_ldap/lib/Group_Proxy.php index ad3fba4092f..f0cdc7a465d 100644 --- a/apps/user_ldap/lib/Group_Proxy.php +++ b/apps/user_ldap/lib/Group_Proxy.php @@ -1,63 +1,61 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Arthur Schiwon <blizzz@arthur-schiwon.de> - * @author Christopher Schäpers <kondou@ts.unde.re> - * @author Joas Schilling <coding@schilljs.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin McCorkell <robin@mccorkell.me.uk> - * @author Vinicius Cubas Brand <vinicius@eita.org.br> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ - namespace OCA\User_LDAP; -class Group_Proxy extends Proxy implements \OCP\GroupInterface, IGroupLDAP { - private $backends = array(); - private $refBackend = null; +use OC\ServerNotAvailableException; +use OCP\Group\Backend\IBatchMethodsBackend; +use OCP\Group\Backend\IDeleteGroupBackend; +use OCP\Group\Backend\IGetDisplayNameBackend; +use OCP\Group\Backend\IGroupDetailsBackend; +use OCP\Group\Backend\IIsAdminBackend; +use OCP\Group\Backend\INamedBackend; +use OCP\GroupInterface; +use OCP\IConfig; +use OCP\IUserManager; - /** - * Constructor - * @param string[] $serverConfigPrefixes array containing the config Prefixes - */ - public function __construct($serverConfigPrefixes, ILDAPWrapper $ldap, GroupPluginManager $groupPluginManager) { - parent::__construct($ldap); - foreach($serverConfigPrefixes as $configPrefix) { - $this->backends[$configPrefix] = - new \OCA\User_LDAP\Group_LDAP($this->getAccess($configPrefix), $groupPluginManager); - if(is_null($this->refBackend)) { - $this->refBackend = &$this->backends[$configPrefix]; - } - } +/** + * @template-extends Proxy<Group_LDAP> + */ +class Group_Proxy extends Proxy implements GroupInterface, IGroupLDAP, IGetDisplayNameBackend, INamedBackend, IDeleteGroupBackend, IBatchMethodsBackend, IIsAdminBackend { + public function __construct( + private Helper $helper, + ILDAPWrapper $ldap, + AccessFactory $accessFactory, + private GroupPluginManager $groupPluginManager, + private IConfig $config, + private IUserManager $ncUserManager, + ) { + parent::__construct($helper, $ldap, $accessFactory); + } + + + protected function newInstance(string $configPrefix): Group_LDAP { + return new Group_LDAP($this->getAccess($configPrefix), $this->groupPluginManager, $this->config, $this->ncUserManager); } /** * Tries the backends one after the other until a positive result is returned from the specified method - * @param string $gid the gid connected to the request + * + * @param string $id the gid connected to the request * @param string $method the method of the group backend that shall be called * @param array $parameters an array of parameters to be passed - * @return mixed, the result of the method or false + * @return mixed the result of the method or false */ - protected function walkBackends($gid, $method, $parameters) { + protected function walkBackends($id, $method, $parameters) { + $this->setup(); + + $gid = $id; $cacheKey = $this->getGroupCacheKey($gid); - foreach($this->backends as $configPrefix => $backend) { - if($result = call_user_func_array(array($backend, $method), $parameters)) { - $this->writeToCache($cacheKey, $configPrefix); + foreach ($this->backends as $configPrefix => $backend) { + if ($result = call_user_func_array([$backend, $method], $parameters)) { + if (!$this->isSingleBackend()) { + $this->writeToCache($cacheKey, $configPrefix); + } return $result; } } @@ -66,27 +64,31 @@ class Group_Proxy extends Proxy implements \OCP\GroupInterface, IGroupLDAP { /** * Asks the backend connected to the server that supposely takes care of the gid from the request. - * @param string $gid the gid connected to the request + * + * @param string $id the gid connected to the request * @param string $method the method of the group backend that shall be called * @param array $parameters an array of parameters to be passed * @param mixed $passOnWhen the result matches this variable - * @return mixed, the result of the method or false + * @return mixed the result of the method or false */ - protected function callOnLastSeenOn($gid, $method, $parameters, $passOnWhen) { - $cacheKey = $this->getGroupCacheKey($gid);; + protected function callOnLastSeenOn($id, $method, $parameters, $passOnWhen) { + $this->setup(); + + $gid = $id; + $cacheKey = $this->getGroupCacheKey($gid); $prefix = $this->getFromCache($cacheKey); //in case the uid has been found in the past, try this stored connection first - if(!is_null($prefix)) { - if(isset($this->backends[$prefix])) { - $result = call_user_func_array(array($this->backends[$prefix], $method), $parameters); - if($result === $passOnWhen) { + if (!is_null($prefix)) { + if (isset($this->backends[$prefix])) { + $result = call_user_func_array([$this->backends[$prefix], $method], $parameters); + if ($result === $passOnWhen) { //not found here, reset cache to null if group vanished //because sometimes methods return false with a reason $groupExists = call_user_func_array( - array($this->backends[$prefix], 'groupExists'), - array($gid) + [$this->backends[$prefix], 'groupExists'], + [$gid] ); - if(!$groupExists) { + if (!$groupExists) { $this->writeToCache($cacheKey, null); } } @@ -96,8 +98,14 @@ class Group_Proxy extends Proxy implements \OCP\GroupInterface, IGroupLDAP { return false; } + protected function activeBackends(): int { + $this->setup(); + return count($this->backends); + } + /** * is user in group? + * * @param string $uid uid of the user * @param string $gid gid of the group * @return bool @@ -105,38 +113,40 @@ class Group_Proxy extends Proxy implements \OCP\GroupInterface, IGroupLDAP { * Checks whether the user is member of a group or not. */ public function inGroup($uid, $gid) { - return $this->handleRequest($gid, 'inGroup', array($uid, $gid)); + return $this->handleRequest($gid, 'inGroup', [$uid, $gid]); } /** * Get all groups a user belongs to + * * @param string $uid Name of the user - * @return string[] with group names + * @return list<string> with group names * * This function fetches all groups a user belongs to. It does not check * if the user exists at all. */ public function getUserGroups($uid) { - $groups = array(); + $this->setup(); - foreach($this->backends as $backend) { + $groups = []; + foreach ($this->backends as $backend) { $backendGroups = $backend->getUserGroups($uid); - if (is_array($backendGroups)) { - $groups = array_merge($groups, $backendGroups); - } + $groups = array_merge($groups, $backendGroups); } - return $groups; + return array_values(array_unique($groups)); } /** * get a list of all users in a group - * @return string[] with user ids + * + * @return array<int,string> user ids */ public function usersInGroup($gid, $search = '', $limit = -1, $offset = 0) { - $users = array(); + $this->setup(); - foreach($this->backends as $backend) { + $users = []; + foreach ($this->backends as $backend) { $backendUsers = $backend->usersInGroup($gid, $search, $limit, $offset); if (is_array($backendUsers)) { $users = array_merge($users, $backendUsers); @@ -152,21 +162,20 @@ class Group_Proxy extends Proxy implements \OCP\GroupInterface, IGroupLDAP { */ public function createGroup($gid) { return $this->handleRequest( - $gid, 'createGroup', array($gid)); + $gid, 'createGroup', [$gid]); } /** * delete a group - * @param string $gid gid of the group to delete - * @return bool */ - public function deleteGroup($gid) { + public function deleteGroup(string $gid): bool { return $this->handleRequest( - $gid, 'deleteGroup', array($gid)); + $gid, 'deleteGroup', [$gid]); } /** * Add a user to a group + * * @param string $uid Name of the user to add to group * @param string $gid Name of the group in which add the user * @return bool @@ -175,11 +184,12 @@ class Group_Proxy extends Proxy implements \OCP\GroupInterface, IGroupLDAP { */ public function addToGroup($uid, $gid) { return $this->handleRequest( - $gid, 'addToGroup', array($uid, $gid)); + $gid, 'addToGroup', [$uid, $gid]); } /** * Removes a user from a group + * * @param string $uid Name of the user to remove from group * @param string $gid Name of the group from which remove the user * @return bool @@ -188,40 +198,59 @@ class Group_Proxy extends Proxy implements \OCP\GroupInterface, IGroupLDAP { */ public function removeFromGroup($uid, $gid) { return $this->handleRequest( - $gid, 'removeFromGroup', array($uid, $gid)); + $gid, 'removeFromGroup', [$uid, $gid]); } /** * returns the number of users in a group, who match the search term + * * @param string $gid the internal group name * @param string $search optional, a search string * @return int|bool */ public function countUsersInGroup($gid, $search = '') { return $this->handleRequest( - $gid, 'countUsersInGroup', array($gid, $search)); + $gid, 'countUsersInGroup', [$gid, $search]); } /** * get an array with group details + * * @param string $gid * @return array|false */ public function getGroupDetails($gid) { return $this->handleRequest( - $gid, 'getGroupDetails', array($gid)); + $gid, 'getGroupDetails', [$gid]); + } + + /** + * {@inheritdoc} + */ + public function getGroupsDetails(array $gids): array { + if (!($this instanceof IGroupDetailsBackend || $this->implementsActions(GroupInterface::GROUP_DETAILS))) { + throw new \Exception('Should not have been called'); + } + + $groupData = []; + foreach ($gids as $gid) { + $groupData[$gid] = $this->handleRequest($gid, 'getGroupDetails', [$gid]); + } + return $groupData; } /** * get a list of all groups + * * @return string[] with group names * * Returns a list with all groups */ public function getGroups($search = '', $limit = -1, $offset = 0) { - $groups = array(); + $this->setup(); - foreach($this->backends as $backend) { + $groups = []; + foreach ($this->backends as $backend) { $backendGroups = $backend->getGroups($search, $limit, $offset); if (is_array($backendGroups)) { $groups = array_merge($groups, $backendGroups); @@ -233,15 +262,44 @@ class Group_Proxy extends Proxy implements \OCP\GroupInterface, IGroupLDAP { /** * check if a group exists + * * @param string $gid * @return bool */ public function groupExists($gid) { - return $this->handleRequest($gid, 'groupExists', array($gid)); + return $this->handleRequest($gid, 'groupExists', [$gid]); + } + + /** + * Check if a group exists + * + * @throws ServerNotAvailableException + */ + public function groupExistsOnLDAP(string $gid, bool $ignoreCache = false): bool { + return $this->handleRequest($gid, 'groupExistsOnLDAP', [$gid, $ignoreCache]); + } + + /** + * returns the groupname for the given LDAP DN, if available + */ + public function dn2GroupName(string $dn): string|false { + $id = 'DN,' . $dn; + return $this->handleRequest($id, 'dn2GroupName', [$dn]); + } + + /** + * {@inheritdoc} + */ + public function groupsExists(array $gids): array { + return array_values(array_filter( + $gids, + fn (string $gid): bool => $this->handleRequest($gid, 'groupExists', [$gid]), + )); } /** * Check if backend implements actions + * * @param int $actions bitwise-or'ed actions * @return boolean * @@ -249,12 +307,14 @@ class Group_Proxy extends Proxy implements \OCP\GroupInterface, IGroupLDAP { * compared with \OCP\GroupInterface::CREATE_GROUP etc. */ public function implementsActions($actions) { + $this->setup(); //it's the same across all our user backends obviously return $this->refBackend->implementsActions($actions); } /** * Return access for LDAP interaction. + * * @param string $gid * @return Access instance of Access for LDAP interaction */ @@ -265,11 +325,36 @@ class Group_Proxy extends Proxy implements \OCP\GroupInterface, IGroupLDAP { /** * Return a new LDAP connection for the specified group. * The connection needs to be closed manually. + * * @param string $gid - * @return resource of the LDAP connection + * @return \LDAP\Connection The LDAP connection */ - public function getNewLDAPConnection($gid) { - return $this->handleRequest($gid, 'getNewLDAPConnection', array($gid)); + public function getNewLDAPConnection($gid): \LDAP\Connection { + return $this->handleRequest($gid, 'getNewLDAPConnection', [$gid]); + } + + public function getDisplayName(string $gid): string { + return $this->handleRequest($gid, 'getDisplayName', [$gid]); } + /** + * Backend name to be shown in group management + * @return string the name of the backend to be shown + * @since 22.0.0 + */ + public function getBackendName(): string { + return 'LDAP'; + } + + public function searchInGroup(string $gid, string $search = '', int $limit = -1, int $offset = 0): array { + return $this->handleRequest($gid, 'searchInGroup', [$gid, $search, $limit, $offset]); + } + + public function addRelationshipToCaches(string $uid, ?string $dnUser, string $gid): void { + $this->handleRequest($gid, 'addRelationshipToCaches', [$uid, $dnUser, $gid]); + } + + public function isAdmin(string $uid): bool { + return $this->handleRequest($uid, 'isAdmin', [$uid]); + } } |