Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception only for single node #1387

Open
McCrafterIV opened this issue Jan 31, 2022 · 0 comments
Open

Exception only for single node #1387

McCrafterIV opened this issue Jan 31, 2022 · 0 comments

Comments

@McCrafterIV
Copy link

I want to create a simple permission system and be able to control if a user can read and/or write a in a directory. For that, I created a plugin. If the user doesn't have the correct permissions, a Forbidden exception is thrown. Let's imagine the following directory structure with the respecting permissions for the current user:

  • Folder 1 (read & write)
    • Subfolder 1 (no read nor write)
      • ...
  • Folder 2 (read & write)
  • ....

Everything works great when the users tries to access Folder 2 or Subfolder 1. He either gets the expected folder data (Folder 2) or a Forbidden exception (Subfolder 1). But if he tries to access Folder 1, a Forbidden exception is thrown. How can I implement this in a way, that the user can still access Folder 1 but not Subfolder 1?
This is my current (simplified) code:

class SabreServerPlugin extends \Sabre\DAV\ServerPlugin
{
    public const BEFORE_CREATE_FILE = 'beforeCreateFile';
    public const BEFORE_FILE_UPDATE = 'beforeWriteContent';
    public const BEFORE_CREATION_DUE_TO_UPDATE = 'beforeBind';
    public const BEFORE_DELETION_DUE_TO_UPDATE = 'beforeUnbind';
    public const BEFORE_LOCK = 'beforeLock';
    public const BEFORE_UNLOCK = 'beforeUnlock';
    public const BEFORE_PROPERTY_REQUEST = 'propFind';

    private Server $server;
    private Security $security;

    public function __construct(Security $security)
    {
        $this->security = $security;
    }

    public function initialize(Server $server): void
    {
        $this->server = $server;
        $this->server->on(self::BEFORE_CREATE_FILE, [$this, 'beforeCreateFile']);
        $this->server->on(self::BEFORE_FILE_UPDATE, [$this, 'beforeFileUpdate']);
        $this->server->on(self::BEFORE_CREATION_DUE_TO_UPDATE, [$this, 'beforeCreationDueToUpdate']);
        $this->server->on(self::BEFORE_DELETION_DUE_TO_UPDATE, [$this, 'beforeDeletionDueToUpdate']);
        $this->server->on(self::BEFORE_LOCK, [$this, 'beforeLock']);
        $this->server->on(self::BEFORE_UNLOCK, [$this, 'beforeUnlock']);
        $this->server->on(self::BEFORE_PROPERTY_REQUEST, [$this, 'beforePropertyRequest']);
    }

    public function beforeCreateFile(string $path, &$data, \Sabre\DAV\ICollection $parent, &$modified): void
    {
        if (!$this->security->isGranted(FileVoter::CREATE, $path)) {
            throw new Forbidden();
        }
    }

    public function beforeFileUpdate($path, \Sabre\DAV\IFile $node, &$data, &$modified): void
    {
        if (!$this->security->isGranted(FileVoter::UPDATE, $path)) {
            throw new Forbidden();
        }
    }

    public function beforeCreationDueToUpdate($path): bool
    {
        if (!$this->security->isGranted(FileVoter::CREATE, $path)) {
            throw new Forbidden();
        }

        return true;
    }

    public function beforeDeletionDueToUpdate($path): bool
    {
        if (!$this->security->isGranted(FileVoter::DELETE, $path)) {
            throw new Forbidden();
        }

        return true;
    }

    public function beforeLock($path, \Sabre\DAV\Locks\LockInfo $lock): bool
    {
        if (!$this->security->isGranted(FileVoter::UPDATE, $path)) {
            throw new Forbidden();
        }

        return true;
    }

    public function beforeUnlock($path, \Sabre\DAV\Locks\LockInfo $lock): bool
    {
        if (!$this->security->isGranted(FileVoter::UPDATE, $path)) {
            throw new Forbidden();
        }

        return true;
    }

    public function beforePropertyRequest(\Sabre\DAV\PropFind $propfind, \Sabre\Dav\INode $node): void
    {
        if (!$this->security->isGranted(FileVoter::VIEW, $path)) {
            throw new Forbidden();
        }
    }
}

From my understanding, the exception is only thrown when the profind for the path "Subfolder 2" is handled, which is correct, but the exception isn't contained inside this node and therefor doesn't mark ONLY the folder/node "Subfolder 2" as Forbidden.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant