0
0
Fork 0
mirror of https://github.com/nextcloud/server.git synced 2025-02-14 04:49:20 +00:00
nextcloud_server/apps/dav/lib/Traits/PrincipalProxyTrait.php
Andy Scherzinger 9d4b944098
chore: Add SPDX header
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
2024-05-27 20:11:22 +02:00

205 lines
5.4 KiB
PHP

<?php
/**
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\DAV\Traits;
use OCA\DAV\CalDAV\Proxy\Proxy;
use OCA\DAV\CalDAV\Proxy\ProxyMapper;
use Sabre\DAV\Exception;
/**
* Trait PrincipalTrait
*
* @package OCA\DAV\Traits
*/
trait PrincipalProxyTrait {
/**
* Returns the list of members for a group-principal
*
* @param string $principal
* @return string[]
* @throws Exception
*/
public function getGroupMemberSet($principal) {
$members = [];
if ($this->isProxyPrincipal($principal)) {
$realPrincipal = $this->getPrincipalUriFromProxyPrincipal($principal);
$principalArray = $this->getPrincipalByPath($realPrincipal);
if (!$principalArray) {
throw new Exception('Principal not found');
}
$proxies = $this->proxyMapper->getProxiesOf($principalArray['uri']);
foreach ($proxies as $proxy) {
if ($this->isReadProxyPrincipal($principal) && $proxy->getPermissions() === ProxyMapper::PERMISSION_READ) {
$members[] = $proxy->getProxyId();
}
if ($this->isWriteProxyPrincipal($principal) && $proxy->getPermissions() === (ProxyMapper::PERMISSION_READ | ProxyMapper::PERMISSION_WRITE)) {
$members[] = $proxy->getProxyId();
}
}
}
return $members;
}
/**
* Returns the list of groups a principal is a member of
*
* @param string $principal
* @param bool $needGroups
* @return array
* @throws Exception
*/
public function getGroupMembership($principal, $needGroups = false) {
[$prefix, $name] = \Sabre\Uri\split($principal);
if ($prefix !== $this->principalPrefix) {
return [];
}
$principalArray = $this->getPrincipalByPath($principal);
if (!$principalArray) {
throw new Exception('Principal not found');
}
$groups = [];
$proxies = $this->proxyMapper->getProxiesFor($principal);
foreach ($proxies as $proxy) {
if ($proxy->getPermissions() === ProxyMapper::PERMISSION_READ) {
$groups[] = $proxy->getOwnerId() . '/calendar-proxy-read';
}
if ($proxy->getPermissions() === (ProxyMapper::PERMISSION_READ | ProxyMapper::PERMISSION_WRITE)) {
$groups[] = $proxy->getOwnerId() . '/calendar-proxy-write';
}
}
return $groups;
}
/**
* Updates the list of group members for a group principal.
*
* The principals should be passed as a list of uri's.
*
* @param string $principal
* @param string[] $members
* @throws Exception
*/
public function setGroupMemberSet($principal, array $members) {
[$principalUri, $target] = \Sabre\Uri\split($principal);
if ($target !== 'calendar-proxy-write' && $target !== 'calendar-proxy-read') {
throw new Exception('Setting members of the group is not supported yet');
}
$masterPrincipalArray = $this->getPrincipalByPath($principalUri);
if (!$masterPrincipalArray) {
throw new Exception('Principal not found');
}
$permission = ProxyMapper::PERMISSION_READ;
if ($target === 'calendar-proxy-write') {
$permission |= ProxyMapper::PERMISSION_WRITE;
}
[$prefix, $owner] = \Sabre\Uri\split($principalUri);
$proxies = $this->proxyMapper->getProxiesOf($principalUri);
foreach ($members as $member) {
[$prefix, $name] = \Sabre\Uri\split($member);
if ($prefix !== $this->principalPrefix) {
throw new Exception('Invalid member group prefix: ' . $prefix);
}
$principalArray = $this->getPrincipalByPath($member);
if (!$principalArray) {
throw new Exception('Principal not found');
}
$found = false;
foreach ($proxies as $proxy) {
if ($proxy->getProxyId() === $member) {
$found = true;
$proxy->setPermissions($proxy->getPermissions() | $permission);
$this->proxyMapper->update($proxy);
$proxies = array_filter($proxies, function (Proxy $p) use ($proxy) {
return $p->getId() !== $proxy->getId();
});
break;
}
}
if ($found === false) {
$proxy = new Proxy();
$proxy->setOwnerId($principalUri);
$proxy->setProxyId($member);
$proxy->setPermissions($permission);
$this->proxyMapper->insert($proxy);
}
}
// Delete all remaining proxies
foreach ($proxies as $proxy) {
// Write and Read Proxies have individual requests,
// so only delete proxies of this permission
if ($proxy->getPermissions() === $permission) {
$this->proxyMapper->delete($proxy);
}
}
}
/**
* @param string $principalUri
* @return bool
*/
private function isProxyPrincipal(string $principalUri):bool {
[$realPrincipalUri, $proxy] = \Sabre\Uri\split($principalUri);
[$prefix, $userId] = \Sabre\Uri\split($realPrincipalUri);
if (!isset($prefix) || !isset($userId)) {
return false;
}
if ($prefix !== $this->principalPrefix) {
return false;
}
return $proxy === 'calendar-proxy-read'
|| $proxy === 'calendar-proxy-write';
}
/**
* @param string $principalUri
* @return bool
*/
private function isReadProxyPrincipal(string $principalUri):bool {
[, $proxy] = \Sabre\Uri\split($principalUri);
return $proxy === 'calendar-proxy-read';
}
/**
* @param string $principalUri
* @return bool
*/
private function isWriteProxyPrincipal(string $principalUri):bool {
[, $proxy] = \Sabre\Uri\split($principalUri);
return $proxy === 'calendar-proxy-write';
}
/**
* @param string $principalUri
* @return string
*/
private function getPrincipalUriFromProxyPrincipal(string $principalUri):string {
[$realPrincipalUri, ] = \Sabre\Uri\split($principalUri);
return $realPrincipalUri;
}
}