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

Let the admin configure the default share permissions #7363

Merged
merged 7 commits into from
Feb 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/files_sharing/lib/Capabilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
namespace OCA\Files_Sharing;

use OCP\Capabilities\ICapability;
use OCP\Constants;
use \OCP\IConfig;

/**
Expand Down Expand Up @@ -86,6 +87,7 @@ public function getCapabilities() {
$res['group'] = [];
$res['group']['enabled'] = $this->config->getAppValue('core', 'shareapi_allow_group_sharing', 'yes') === 'yes';
$res['group']['expire_date']['enabled'] = true;
$res['default_permissions'] = (int)$this->config->getAppValue('core', 'shareapi_default_permissions', Constants::PERMISSION_ALL);
}

//Federated sharing
Expand Down
63 changes: 35 additions & 28 deletions apps/files_sharing/lib/Controller/ShareAPIController.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@
use OCP\AppFramework\OCS\OCSForbiddenException;
use OCP\AppFramework\OCS\OCSNotFoundException;
use OCP\AppFramework\OCSController;
use OCP\Constants;
use OCP\Files\Node;
use OCP\Files\NotFoundException;
use OCP\IConfig;
use OCP\IGroupManager;
use OCP\IL10N;
use OCP\IUserManager;
Expand Down Expand Up @@ -75,6 +77,8 @@ class ShareAPIController extends OCSController {
private $l;
/** @var \OCP\Files\Node */
private $lockedNode;
/** @var IConfig */
private $config;

/**
* Share20OCS constructor.
Expand All @@ -88,6 +92,7 @@ class ShareAPIController extends OCSController {
* @param IURLGenerator $urlGenerator
* @param string $userId
* @param IL10N $l10n
* @param IConfig $config
*/
public function __construct(
$appName,
Expand All @@ -98,7 +103,8 @@ public function __construct(
IRootFolder $rootFolder,
IURLGenerator $urlGenerator,
$userId,
IL10N $l10n
IL10N $l10n,
IConfig $config
) {
parent::__construct($appName, $request);

Expand All @@ -110,6 +116,7 @@ public function __construct(
$this->urlGenerator = $urlGenerator;
$this->currentUser = $userId;
$this->l = $l10n;
$this->config = $config;
}

/**
Expand Down Expand Up @@ -318,7 +325,7 @@ public function deleteShare($id) {
*/
public function createShare(
$path = null,
$permissions = \OCP\Constants::PERMISSION_ALL,
$permissions = null,
$shareType = -1,
$shareWith = null,
$publicUpload = 'false',
Expand All @@ -327,6 +334,10 @@ public function createShare(
) {
$share = $this->shareManager->newShare();

if ($permissions === null) {
$permissions = $this->config->getAppValue('core', 'shareapi_default_permissions', Constants::PERMISSION_ALL);
}

// Verify path
if ($path === null) {
throw new OCSNotFoundException($this->l->t('Please specify a file or folder path'));
Expand All @@ -347,17 +358,17 @@ public function createShare(
throw new OCSNotFoundException($this->l->t('Could not create share'));
}

if ($permissions < 0 || $permissions > \OCP\Constants::PERMISSION_ALL) {
if ($permissions < 0 || $permissions > Constants::PERMISSION_ALL) {
throw new OCSNotFoundException($this->l->t('invalid permissions'));
}

// Shares always require read permissions
$permissions |= \OCP\Constants::PERMISSION_READ;
$permissions |= Constants::PERMISSION_READ;

if ($path instanceof \OCP\Files\File) {
// Single file shares should never have delete or create permissions
$permissions &= ~\OCP\Constants::PERMISSION_DELETE;
$permissions &= ~\OCP\Constants::PERMISSION_CREATE;
$permissions &= ~Constants::PERMISSION_DELETE;
$permissions &= ~Constants::PERMISSION_CREATE;
}

/*
Expand Down Expand Up @@ -414,13 +425,13 @@ public function createShare(
}

$share->setPermissions(
\OCP\Constants::PERMISSION_READ |
\OCP\Constants::PERMISSION_CREATE |
\OCP\Constants::PERMISSION_UPDATE |
\OCP\Constants::PERMISSION_DELETE
Constants::PERMISSION_READ |
Constants::PERMISSION_CREATE |
Constants::PERMISSION_UPDATE |
Constants::PERMISSION_DELETE
);
} else {
$share->setPermissions(\OCP\Constants::PERMISSION_READ);
$share->setPermissions(Constants::PERMISSION_READ);
}

// Set password
Expand All @@ -447,13 +458,9 @@ public function createShare(
$share->setPermissions($permissions);
} else if ($shareType === \OCP\Share::SHARE_TYPE_EMAIL) {
if ($share->getNodeType() === 'file') {
$share->setPermissions(\OCP\Constants::PERMISSION_READ);
$share->setPermissions(Constants::PERMISSION_READ);
} else {
$share->setPermissions(
\OCP\Constants::PERMISSION_READ |
\OCP\Constants::PERMISSION_CREATE |
\OCP\Constants::PERMISSION_UPDATE |
\OCP\Constants::PERMISSION_DELETE);
$share->setPermissions($permissions);
}
$share->setSharedWith($shareWith);
} else if ($shareType === \OCP\Share::SHARE_TYPE_CIRCLE) {
Expand Down Expand Up @@ -698,33 +705,33 @@ public function updateShare(

$newPermissions = null;
if ($publicUpload === 'true') {
$newPermissions = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE;
$newPermissions = Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE;
} else if ($publicUpload === 'false') {
$newPermissions = \OCP\Constants::PERMISSION_READ;
$newPermissions = Constants::PERMISSION_READ;
}

if ($permissions !== null) {
$newPermissions = (int)$permissions;
$newPermissions = $newPermissions & ~\OCP\Constants::PERMISSION_SHARE;
$newPermissions = $newPermissions & ~Constants::PERMISSION_SHARE;
}

if ($newPermissions !== null &&
!in_array($newPermissions, [
\OCP\Constants::PERMISSION_READ,
\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE, // legacy
\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE, // correct
\OCP\Constants::PERMISSION_CREATE, // hidden file list
\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_UPDATE, // allow to edit single files
Constants::PERMISSION_READ,
Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE, // legacy
Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE, // correct
Constants::PERMISSION_CREATE, // hidden file list
Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE, // allow to edit single files
])
) {
throw new OCSBadRequestException($this->l->t('Can\'t change permissions for public share links'));
}

if (
// legacy
$newPermissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE) ||
$newPermissions === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE) ||
// correct
$newPermissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE)
$newPermissions === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE)
) {
if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
Expand All @@ -735,7 +742,7 @@ public function updateShare(
}

// normalize to correct public upload permissions
$newPermissions = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE;
$newPermissions = Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE;
}

if ($newPermissions !== null) {
Expand Down
5 changes: 4 additions & 1 deletion apps/files_sharing/tests/ApiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
use OCP\AppFramework\OCS\OCSException;
use OCP\AppFramework\OCS\OCSForbiddenException;
use OCP\AppFramework\OCS\OCSNotFoundException;
use OCP\IConfig;
use OCP\IL10N;
use OCP\IRequest;

Expand Down Expand Up @@ -105,6 +106,7 @@ private function createOCS($userId) {
->will($this->returnCallback(function($text, $parameters = []) {
return vsprintf($text, $parameters);
}));
$config = $this->createMock(IConfig::class);

return new ShareAPIController(
self::APP_NAME,
Expand All @@ -115,7 +117,8 @@ private function createOCS($userId) {
\OC::$server->getRootFolder(),
\OC::$server->getURLGenerator(),
$userId,
$l
$l,
$config
);
}

Expand Down
13 changes: 12 additions & 1 deletion apps/files_sharing/tests/Controller/ShareAPIControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
use OCP\Files\File;
use OCP\Files\Folder;
use OCP\Files\Storage;
use OCP\IConfig;
use OCP\IL10N;
use OCA\Files_Sharing\Controller\ShareAPIController;
use OCP\Files\NotFoundException;
Expand Down Expand Up @@ -84,6 +85,9 @@ class ShareAPIControllerTest extends TestCase {
/** @var IL10N|\PHPUnit_Framework_MockObject_MockObject */
private $l;

/** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
private $config;

protected function setUp() {
$this->shareManager = $this->createMock(IManager::class);
$this->shareManager
Expand All @@ -102,6 +106,7 @@ protected function setUp() {
->will($this->returnCallback(function($text, $parameters = []) {
return vsprintf($text, $parameters);
}));
$this->config = $this->createMock(IConfig::class);

$this->ocs = new ShareAPIController(
$this->appName,
Expand All @@ -112,7 +117,8 @@ protected function setUp() {
$this->rootFolder,
$this->urlGenerator,
$this->currentUser,
$this->l
$this->l,
$this->config
);
}

Expand All @@ -131,6 +137,7 @@ private function mockFormatShare() {
$this->urlGenerator,
$this->currentUser,
$this->l,
$this->config
])->setMethods(['formatShare'])
->getMock();
}
Expand Down Expand Up @@ -439,6 +446,7 @@ public function testGetShare(\OCP\Share\IShare $share, array $result) {
$this->urlGenerator,
$this->currentUser,
$this->l,
$this->config
])->setMethods(['canAccessShare'])
->getMock();

Expand Down Expand Up @@ -707,6 +715,7 @@ public function testCreateShareUser() {
$this->urlGenerator,
$this->currentUser,
$this->l,
$this->config
])->setMethods(['formatShare'])
->getMock();

Expand Down Expand Up @@ -804,6 +813,7 @@ public function testCreateShareGroup() {
$this->urlGenerator,
$this->currentUser,
$this->l,
$this->config
])->setMethods(['formatShare'])
->getMock();

Expand Down Expand Up @@ -1119,6 +1129,7 @@ public function testCreateReshareOfFederatedMountNoDeletePermissions() {
$this->urlGenerator,
$this->currentUser,
$this->l,
$this->config
])->setMethods(['formatShare'])
->getMock();

Expand Down
8 changes: 6 additions & 2 deletions core/Controller/OCJSController.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
namespace OC\Core\Controller;

use bantu\IniGetWrapper\IniGetWrapper;
use OC\CapabilitiesManager;
use OC\Template\JSConfigHelper;
use OCP\App\IAppManager;
use OCP\AppFramework\Controller;
Expand Down Expand Up @@ -59,6 +60,7 @@ class OCJSController extends Controller {
* @param IGroupManager $groupManager
* @param IniGetWrapper $iniWrapper
* @param IURLGenerator $urlGenerator
* @param CapabilitiesManager $capabilitiesManager
*/
public function __construct($appName,
IRequest $request,
Expand All @@ -70,7 +72,8 @@ public function __construct($appName,
IConfig $config,
IGroupManager $groupManager,
IniGetWrapper $iniWrapper,
IURLGenerator $urlGenerator) {
IURLGenerator $urlGenerator,
CapabilitiesManager $capabilitiesManager) {
parent::__construct($appName, $request);

$this->helper = new JSConfigHelper(
Expand All @@ -82,7 +85,8 @@ public function __construct($appName,
$config,
$groupManager,
$iniWrapper,
$urlGenerator
$urlGenerator,
$capabilitiesManager
);
}

Expand Down
19 changes: 19 additions & 0 deletions core/js/js.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ var OCP = {},
*/
webroot:oc_webroot,

/**
* Capabilities
*
* @type array
*/
_capabilities: window.oc_capabilities || null,

appswebroots:(typeof oc_appswebroots !== 'undefined') ? oc_appswebroots:false,
/**
* Currently logged in user or null if none
Expand Down Expand Up @@ -308,6 +315,18 @@ var OCP = {},
return OC.webroot;
},


/**
* Returns the capabilities
*
* @return {array} capabilities
*
* @since 14.0
*/
getCapabilities: function() {
return OC._capabilities;
},

/**
* Returns the currently logged in user or null if there is no logged in
* user (public page mode)
Expand Down
17 changes: 9 additions & 8 deletions core/js/shareitemmodel.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,23 +158,24 @@
var shareType = attributes.shareType;
attributes = _.extend({}, attributes);

// Default permissions are Edit (CRUD) and Share
// Check if these permissions are possible
var permissions = OC.PERMISSION_READ;
// get default permissions
var defaultPermissions = OC.getCapabilities()['files_sharing']['default_permissions'] || OC.PERMISSION_ALL;
var possiblePermissions = OC.PERMISSION_READ;

if (this.updatePermissionPossible()) {
permissions = permissions | OC.PERMISSION_UPDATE;
possiblePermissions = possiblePermissions | OC.PERMISSION_UPDATE;
}
if (this.createPermissionPossible()) {
permissions = permissions | OC.PERMISSION_CREATE;
possiblePermissions = possiblePermissions | OC.PERMISSION_CREATE;
}
if (this.deletePermissionPossible()) {
permissions = permissions | OC.PERMISSION_DELETE;
possiblePermissions = possiblePermissions | OC.PERMISSION_DELETE;
}
if (this.configModel.get('isResharingAllowed') && (this.sharePermissionPossible())) {
permissions = permissions | OC.PERMISSION_SHARE;
possiblePermissions = possiblePermissions | OC.PERMISSION_SHARE;
}

attributes.permissions = permissions;
attributes.permissions = defaultPermissions & possiblePermissions;
if (_.isUndefined(attributes.path)) {
attributes.path = this.fileInfoModel.getFullPath();
}
Expand Down
Loading