Skip to content

Commit

Permalink
Merge pull request #7363 from nextcloud/default-share-perms
Browse files Browse the repository at this point in the history
Let the admin configure the default share permissions
  • Loading branch information
MorrisJobke authored Feb 27, 2018
2 parents 01f420c + 20ec034 commit 7bc3c2e
Show file tree
Hide file tree
Showing 17 changed files with 244 additions and 64 deletions.
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

0 comments on commit 7bc3c2e

Please sign in to comment.