Commit 8c0ef4c4 authored by Roeland Jago Douma's avatar Roeland Jago Douma
Browse files

Add sharePermissions webdav property

This property can be queries by the clients so they know the max
permissions they can use to share a file with. This will improve the UX.

The oc:permissions proptery is not enough since mountpoints have
different permissions (delete + move by default).

By making it a new property the clients can just request it. On older
servers it will just return a 404 for that property (and thus they know
they have to fall back to their hacky work arounds). But if the property
is returned the client can show proper info.

* unit tests
* intergration test
parent bfb5748f
......@@ -45,6 +45,7 @@ class FilesPlugin extends \Sabre\DAV\ServerPlugin {
const FILEID_PROPERTYNAME = '{http://owncloud.org/ns}id';
const INTERNAL_FILEID_PROPERTYNAME = '{http://owncloud.org/ns}fileid';
const PERMISSIONS_PROPERTYNAME = '{http://owncloud.org/ns}permissions';
const SHARE_PERMISSIONS_PROPERTYNAME = '{http://owncloud.org/ns}share-permissions';
const DOWNLOADURL_PROPERTYNAME = '{http://owncloud.org/ns}downloadURL';
const SIZE_PROPERTYNAME = '{http://owncloud.org/ns}size';
const GETETAG_PROPERTYNAME = '{DAV:}getetag';
......@@ -116,6 +117,7 @@ class FilesPlugin extends \Sabre\DAV\ServerPlugin {
$server->protectedProperties[] = self::FILEID_PROPERTYNAME;
$server->protectedProperties[] = self::INTERNAL_FILEID_PROPERTYNAME;
$server->protectedProperties[] = self::PERMISSIONS_PROPERTYNAME;
$server->protectedProperties[] = self::SHARE_PERMISSIONS_PROPERTYNAME;
$server->protectedProperties[] = self::SIZE_PROPERTYNAME;
$server->protectedProperties[] = self::DOWNLOADURL_PROPERTYNAME;
$server->protectedProperties[] = self::OWNER_ID_PROPERTYNAME;
......@@ -245,6 +247,10 @@ class FilesPlugin extends \Sabre\DAV\ServerPlugin {
return $perms;
});
$propFind->handle(self::SHARE_PERMISSIONS_PROPERTYNAME, function() use ($node) {
return $node->getSharePermissions();
});
$propFind->handle(self::GETETAG_PROPERTYNAME, function() use ($node) {
return $node->getETag();
});
......
......@@ -213,6 +213,39 @@ abstract class Node implements \Sabre\DAV\INode {
return $this->info->getId();
}
/**
* @return int
*/
public function getSharePermissions() {
$storage = $this->info->getStorage();
$path = $this->info->getInternalPath();
if ($storage->instanceOfStorage('\OC\Files\Storage\Shared')) {
/** @var \OC\Files\Storage\Shared $storage */
$permissions = (int)$storage->getShare()['permissions'];
} else {
$permissions = $storage->getPermissions($path);
}
/*
* Without sharing permissions there are also no other permissions
*/
if (!($permissions & \OCP\Constants::PERMISSION_SHARE) ||
!($permissions & \OCP\Constants::PERMISSION_READ)) {
return 0;
}
/*
* Files can't have create or delete permissions
*/
if ($this->info->getType() === \OCP\Files\FileInfo::TYPE_FILE) {
$permissions &= ~(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_DELETE);
}
return $permissions;
}
/**
* @return string
*/
......
......@@ -63,4 +63,65 @@ class Node extends \Test\TestCase {
$node = new \OCA\DAV\Connector\Sabre\File($view, $info);
$this->assertEquals($expected, $node->getDavPermissions());
}
public function sharePermissionsProvider() {
return [
[\OCP\Files\FileInfo::TYPE_FILE, 1, 0],
[\OCP\Files\FileInfo::TYPE_FILE, 3, 0],
[\OCP\Files\FileInfo::TYPE_FILE, 5, 0],
[\OCP\Files\FileInfo::TYPE_FILE, 7, 0],
[\OCP\Files\FileInfo::TYPE_FILE, 9, 0],
[\OCP\Files\FileInfo::TYPE_FILE, 11, 0],
[\OCP\Files\FileInfo::TYPE_FILE, 13, 0],
[\OCP\Files\FileInfo::TYPE_FILE, 15, 0],
[\OCP\Files\FileInfo::TYPE_FILE, 17, 17],
[\OCP\Files\FileInfo::TYPE_FILE, 19, 19],
[\OCP\Files\FileInfo::TYPE_FILE, 21, 17],
[\OCP\Files\FileInfo::TYPE_FILE, 23, 19],
[\OCP\Files\FileInfo::TYPE_FILE, 25, 17],
[\OCP\Files\FileInfo::TYPE_FILE, 27, 19],
[\OCP\Files\FileInfo::TYPE_FILE, 29, 17],
[\OCP\Files\FileInfo::TYPE_FILE, 30, 0],
[\OCP\Files\FileInfo::TYPE_FILE, 31, 19],
[\OCP\Files\FileInfo::TYPE_FOLDER, 1, 0],
[\OCP\Files\FileInfo::TYPE_FOLDER, 3, 0],
[\OCP\Files\FileInfo::TYPE_FOLDER, 5, 0],
[\OCP\Files\FileInfo::TYPE_FOLDER, 7, 0],
[\OCP\Files\FileInfo::TYPE_FOLDER, 9, 0],
[\OCP\Files\FileInfo::TYPE_FOLDER, 11, 0],
[\OCP\Files\FileInfo::TYPE_FOLDER, 13, 0],
[\OCP\Files\FileInfo::TYPE_FOLDER, 15, 0],
[\OCP\Files\FileInfo::TYPE_FOLDER, 17, 17],
[\OCP\Files\FileInfo::TYPE_FOLDER, 19, 19],
[\OCP\Files\FileInfo::TYPE_FOLDER, 21, 21],
[\OCP\Files\FileInfo::TYPE_FOLDER, 23, 23],
[\OCP\Files\FileInfo::TYPE_FOLDER, 25, 25],
[\OCP\Files\FileInfo::TYPE_FOLDER, 27, 27],
[\OCP\Files\FileInfo::TYPE_FOLDER, 29, 29],
[\OCP\Files\FileInfo::TYPE_FOLDER, 30, 0],
[\OCP\Files\FileInfo::TYPE_FOLDER, 31, 31],
];
}
/**
* @dataProvider sharePermissionsProvider
*/
public function testSharePermissions($type, $permissions, $expected) {
$storage = $this->getMock('\OCP\Files\Storage');
$storage->method('getPermissions')->willReturn($permissions);
$info = $this->getMockBuilder('\OC\Files\FileInfo')
->disableOriginalConstructor()
->setMethods(array('getStorage', 'getType'))
->getMock();
$info->method('getStorage')->willReturn($storage);
$info->method('getType')->willReturn($type);
$view = $this->getMock('\OC\Files\View');
$node = new \OCA\DAV\Connector\Sabre\File($view, $info);
$this->assertEquals($expected, $node->getSharePermissions());
}
}
......@@ -315,6 +315,20 @@ trait WebDav {
}
}
/**
* @When User :user uploads file with content :content to :destination
*/
public function userUploadsAFileWithContentTo($user, $content, $destination)
{
$file = \GuzzleHttp\Stream\Stream::factory($content);
try {
$this->response = $this->makeDavRequest($user, "PUT", $destination, [], $file);
} catch (\GuzzleHttp\Exception\ServerException $e) {
// 4xx and 5xx responses cause an exception
$this->response = $e->getResponse();
}
}
/**
* @When User :user deletes file :file
* @param string $user
......
......@@ -566,3 +566,107 @@ Feature: sharing
| path | welcome.txt |
| shareType | 3 |
Then share ids should match
Scenario: Correct webdav share-permissions for owned file
Given user "user0" exists
And User "user0" uploads file with content "foo" to "/tmp.txt"
When as "user0" gets properties of folder "/tmp.txt" with
|{http://owncloud.org/ns}share-permissions|
Then the single response should contain a property "{http://owncloud.org/ns}share-permissions" with value "19"
Scenario: Correct webdav share-permissions for received file with edit and reshare permissions
Given user "user0" exists
And user "user1" exists
And User "user0" uploads file with content "foo" to "/tmp.txt"
And file "tmp.txt" of user "user0" is shared with user "user1"
When as "user1" gets properties of folder "/tmp.txt" with
|{http://owncloud.org/ns}share-permissions|
Then the single response should contain a property "{http://owncloud.org/ns}share-permissions" with value "19"
Scenario: Correct webdav share-permissions for received file with edit permissions but no reshare permissions
Given user "user0" exists
And user "user1" exists
And User "user0" uploads file with content "foo" to "/tmp.txt"
And file "tmp.txt" of user "user0" is shared with user "user1"
And As an "user0"
And Updating last share with
| permissions | 3 |
When as "user1" gets properties of folder "/tmp.txt" with
|{http://owncloud.org/ns}share-permissions|
Then the single response should contain a property "{http://owncloud.org/ns}share-permissions" with value "0"
Scenario: Correct webdav share-permissions for received file with reshare permissions but no edit permissions
Given user "user0" exists
And user "user1" exists
And User "user0" uploads file with content "foo" to "/tmp.txt"
And file "tmp.txt" of user "user0" is shared with user "user1"
And As an "user0"
And Updating last share with
| permissions | 17 |
When as "user1" gets properties of folder "/tmp.txt" with
|{http://owncloud.org/ns}share-permissions|
Then the single response should contain a property "{http://owncloud.org/ns}share-permissions" with value "17"
Scenario: Correct webdav share-permissions for owned folder
Given user "user0" exists
And user "user0" created a folder "/tmp"
When as "user0" gets properties of folder "/" with
|{http://owncloud.org/ns}share-permissions|
Then the single response should contain a property "{http://owncloud.org/ns}share-permissions" with value "31"
Scenario: Correct webdav share-permissions for received folder with all permissions
Given user "user0" exists
And user "user1" exists
And user "user0" created a folder "/tmp"
And file "/tmp" of user "user0" is shared with user "user1"
When as "user1" gets properties of folder "/tmp" with
|{http://owncloud.org/ns}share-permissions|
Then the single response should contain a property "{http://owncloud.org/ns}share-permissions" with value "31"
Scenario: Correct webdav share-permissions for received folder with all permissions but edit
Given user "user0" exists
And user "user1" exists
And user "user0" created a folder "/tmp"
And file "/tmp" of user "user0" is shared with user "user1"
And As an "user0"
And Updating last share with
| permissions | 29 |
When as "user1" gets properties of folder "/tmp" with
|{http://owncloud.org/ns}share-permissions|
Then the single response should contain a property "{http://owncloud.org/ns}share-permissions" with value "29"
Scenario: Correct webdav share-permissions for received folder with all permissions but create
Given user "user0" exists
And user "user1" exists
And user "user0" created a folder "/tmp"
And file "/tmp" of user "user0" is shared with user "user1"
And As an "user0"
And Updating last share with
| permissions | 27 |
When as "user1" gets properties of folder "/tmp" with
|{http://owncloud.org/ns}share-permissions|
Then the single response should contain a property "{http://owncloud.org/ns}share-permissions" with value "27"
Scenario: Correct webdav share-permissions for received folder with all permissions but delete
Given user "user0" exists
And user "user1" exists
And user "user0" created a folder "/tmp"
And file "/tmp" of user "user0" is shared with user "user1"
And As an "user0"
And Updating last share with
| permissions | 23 |
When as "user1" gets properties of folder "/tmp" with
|{http://owncloud.org/ns}share-permissions|
Then the single response should contain a property "{http://owncloud.org/ns}share-permissions" with value "23"
Scenario: Correct webdav share-permissions for received folder with all permissions but share
Given user "user0" exists
And user "user1" exists
And user "user0" created a folder "/tmp"
And file "/tmp" of user "user0" is shared with user "user1"
And As an "user0"
And Updating last share with
| permissions | 15 |
When as "user1" gets properties of folder "/tmp" with
|{http://owncloud.org/ns}share-permissions|
Then the single response should contain a property "{http://owncloud.org/ns}share-permissions" with value "0"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment