123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- <?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;
- }
- }
|