summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Schießle <schiessle@owncloud.com>2014-05-16 12:23:01 -0400
committerBjörn Schießle <schiessle@owncloud.com>2014-05-16 12:23:01 -0400
commitb52cb8f5570f4ec0e73aa5b2e1a5dbd178135382 (patch)
tree8e622b686a60a49bbe6cf21469a232dcb72e6eea
parentd5f60a8eb0b3521ba0d85e9191468f09ea37803e (diff)
parentb6e14af861481d0b2ebf6ca752d994c5adfce866 (diff)
downloadnextcloud-server-b52cb8f5570f4ec0e73aa5b2e1a5dbd178135382.tar.gz
nextcloud-server-b52cb8f5570f4ec0e73aa5b2e1a5dbd178135382.zip
Merge pull request #8604 from owncloud/sharing_encforce_password
allow admin to enforce passwords for public link shares
-rw-r--r--apps/files_sharing/lib/api.php19
-rw-r--r--apps/files_sharing/tests/api.php54
-rw-r--r--core/js/config.php1
-rw-r--r--core/js/share.js52
-rw-r--r--lib/private/share/share.php11
-rwxr-xr-xlib/private/util.php10
-rw-r--r--lib/public/util.php8
-rwxr-xr-xsettings/admin.php1
-rw-r--r--settings/templates/admin.php5
9 files changed, 132 insertions, 29 deletions
diff --git a/apps/files_sharing/lib/api.php b/apps/files_sharing/lib/api.php
index d554d68c6bd..fd3c4a7756a 100644
--- a/apps/files_sharing/lib/api.php
+++ b/apps/files_sharing/lib/api.php
@@ -418,13 +418,18 @@ class Api {
return new \OC_OCS_Result(null, 404, "share doesn't exists, can't change password");
}
- $result = \OCP\Share::shareItem(
- $itemType,
- $itemSource,
- \OCP\Share::SHARE_TYPE_LINK,
- $shareWith,
- $permissions
- );
+ try {
+ $result = \OCP\Share::shareItem(
+ $itemType,
+ $itemSource,
+ \OCP\Share::SHARE_TYPE_LINK,
+ $shareWith,
+ $permissions
+ );
+ } catch (\Exception $e) {
+ return new \OC_OCS_Result(null, 403, $e->getMessage());
+ }
+
if($result) {
return new \OC_OCS_Result();
}
diff --git a/apps/files_sharing/tests/api.php b/apps/files_sharing/tests/api.php
index 2193717f4b4..a908caf6632 100644
--- a/apps/files_sharing/tests/api.php
+++ b/apps/files_sharing/tests/api.php
@@ -113,11 +113,65 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base {
$fileinfo = $this->view->getFileInfo($this->folder);
\OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, null);
+ }
+
+ function testEnfoceLinkPassword() {
+
+ $appConfig = \OC::$server->getAppConfig();
+ $appConfig->setValue('core', 'shareapi_enforce_links_password', 'yes');
+
+ // don't allow to share link without a password
+ $_POST['path'] = $this->folder;
+ $_POST['shareType'] = \OCP\Share::SHARE_TYPE_LINK;
+
+
+ $result = Share\Api::createShare(array());
+ $this->assertFalse($result->succeeded());
+
+
+ // don't allow to share link without a empty password
+ $_POST['path'] = $this->folder;
+ $_POST['shareType'] = \OCP\Share::SHARE_TYPE_LINK;
+ $_POST['password'] = '';
+
+ $result = Share\Api::createShare(array());
+ $this->assertFalse($result->succeeded());
+
+ // share with password should succeed
+ $_POST['path'] = $this->folder;
+ $_POST['shareType'] = \OCP\Share::SHARE_TYPE_LINK;
+ $_POST['password'] = 'foo';
+ $result = Share\Api::createShare(array());
+ $this->assertTrue($result->succeeded());
+
+ $data = $result->getData();
+
+ // setting new password should succeed
+ $params = array();
+ $params['id'] = $data['id'];
+ $params['_put'] = array();
+ $params['_put']['password'] = 'bar';
+
+ $result = Share\Api::updateShare($params);
+ $this->assertTrue($result->succeeded());
+ // removing password should fail
+ $params = array();
+ $params['id'] = $data['id'];
+ $params['_put'] = array();
+ $params['_put']['password'] = '';
+
+ $result = Share\Api::updateShare($params);
+ $this->assertFalse($result->succeeded());
+ // cleanup
+ $fileinfo = $this->view->getFileInfo($this->folder);
+ \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, null);
+ $appConfig->setValue('core', 'shareapi_enforce_links_password', 'no');
}
+
/**
* @medium
* @depends testCreateShare
diff --git a/core/js/config.php b/core/js/config.php
index 9169cc14a7b..33665b8401c 100644
--- a/core/js/config.php
+++ b/core/js/config.php
@@ -79,6 +79,7 @@ $array = array(
'defaultExpireDateEnabled' => $defaultExpireDateEnabled,
'defaultExpireDate' => $defaultExpireDate,
'defaultExpireDateEnforced' => $enforceDefaultExpireDate,
+ 'enforcePasswordForPublicLink' => \OCP\Util::isPublicLinkPasswordRequired(),
)
)
),
diff --git a/core/js/share.js b/core/js/share.js
index 9ceca85bff7..6c6631aa2b2 100644
--- a/core/js/share.js
+++ b/core/js/share.js
@@ -230,11 +230,11 @@ OC.Share={
}
html += '<input id="linkText" type="text" readonly="readonly" />';
-
html += '<input type="checkbox" name="showPassword" id="showPassword" value="1" style="display:none;" /><label for="showPassword" style="display:none;">'+t('core', 'Password protect')+'</label>';
html += '<div id="linkPass">';
- html += '<input id="linkPassText" type="password" placeholder="'+t('core', 'Password')+'" />';
+ html += '<input id="linkPassText" type="password" placeholder="'+t('core', 'Choose a password for the public link')+'" />';
html += '</div>';
+
if (itemType === 'folder' && (possiblePermissions & OC.PERMISSION_CREATE) && publicUploadEnabled === 'yes') {
html += '<div id="allowPublicUploadWrapper" style="display:none;">';
html += '<input type="checkbox" value="1" name="allowPublicUpload" id="sharingDialogAllowPublicUpload"' + ((allowPublicUploadStatus) ? 'checked="checked"' : '') + ' />';
@@ -494,8 +494,10 @@ OC.Share={
$('#linkText').val(link);
$('#linkText').show('blind');
$('#linkText').css('display','block');
- $('#showPassword').show();
- $('#showPassword+label').show();
+ if (oc_appconfig.core.enforcePasswordForPublicLink === false || password === null) {
+ $('#showPassword').show();
+ $('#showPassword+label').show();
+ }
if (password != null) {
$('#linkPass').show('blind');
$('#showPassword').attr('checked', true);
@@ -512,7 +514,7 @@ OC.Share={
$('#defaultExpireMessage').hide();
$('#showPassword').hide();
$('#showPassword+label').hide();
- $('#linkPass').hide();
+ $('#linkPass').hide('blind');
$('#emailPrivateLink #email').hide();
$('#emailPrivateLink #emailButton').hide();
$('#allowPublicUploadWrapper').hide();
@@ -643,20 +645,27 @@ $(document).ready(function() {
var itemSourceName = $('#dropdown').data('item-source-name');
if (this.checked) {
// Create a link
- OC.Share.share(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, '', OC.PERMISSION_READ, itemSourceName, function(data) {
- OC.Share.showLink(data.token, null, itemSource);
- OC.Share.updateIcon(itemType, itemSource);
- });
+ if (oc_appconfig.core.enforcePasswordForPublicLink === false) {
+ OC.Share.share(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, '', OC.PERMISSION_READ, itemSourceName, function(data) {
+ OC.Share.showLink(data.token, null, itemSource);
+ OC.Share.updateIcon(itemType, itemSource);
+ });
+ } else {
+ $('#linkPass').toggle('blind');
+ $('#linkPassText').focus();
+ }
} else {
// Delete private link
- OC.Share.unshare(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, '', function() {
- OC.Share.hideLink();
- OC.Share.itemShares[OC.Share.SHARE_TYPE_LINK] = false;
- OC.Share.updateIcon(itemType, itemSource);
- if (typeof OC.Share.statuses[itemSource] === 'undefined') {
- $('#expiration').hide('blind');
- }
- });
+ OC.Share.hideLink();
+ if ($('#linkText').val() !== '') {
+ OC.Share.unshare(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, '', function() {
+ OC.Share.itemShares[OC.Share.SHARE_TYPE_LINK] = false;
+ OC.Share.updateIcon(itemType, itemSource);
+ if (typeof OC.Share.statuses[itemSource] === 'undefined') {
+ $('#expiration').hide('blind');
+ }
+ });
+ }
}
});
@@ -728,11 +737,16 @@ $(document).ready(function() {
permissions = OC.PERMISSION_READ;
}
- OC.Share.share(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, $('#linkPassText').val(), permissions, itemSourceName, function() {
- console.log("password set to: '" + linkPassText.val() +"' by event: " + event.type);
+ OC.Share.share(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, $('#linkPassText').val(), permissions, itemSourceName, function(data) {
linkPassText.val('');
linkPassText.attr('placeholder', t('core', 'Password protected'));
+
+ if (oc_appconfig.core.enforcePasswordForPublicLink) {
+ OC.Share.showLink(data.token, "password set", itemSource);
+ OC.Share.updateIcon(itemType, itemSource);
+ }
});
+
}
});
diff --git a/lib/private/share/share.php b/lib/private/share/share.php
index a8537a916fb..440889ea6dc 100644
--- a/lib/private/share/share.php
+++ b/lib/private/share/share.php
@@ -588,7 +588,9 @@ class Share extends \OC\Share\Constants {
$shareWith['users'] = array_diff(\OC_Group::usersInGroup($group), array($uidOwner));
} else if ($shareType === self::SHARE_TYPE_LINK) {
if (\OC_Appconfig::getValue('core', 'shareapi_allow_links', 'yes') == 'yes') {
+
// when updating a link share
+ // FIXME Don't delete link if we update it
if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_LINK, null,
$uidOwner, self::FORMAT_NONE, null, 1)) {
// remember old token
@@ -599,7 +601,7 @@ class Share extends \OC\Share\Constants {
}
// Generate hash of password - same method as user passwords
- if (isset($shareWith)) {
+ if (!empty($shareWith)) {
$forcePortable = (CRYPT_BLOWFISH != 1);
$hasher = new \PasswordHash(8, $forcePortable);
$shareWith = $hasher->HashPassword($shareWith.\OC_Config::getValue('passwordsalt', ''));
@@ -611,6 +613,13 @@ class Share extends \OC\Share\Constants {
}
}
+ if (\OCP\Util::isPublicLinkPasswordRequired() && empty($shareWith)) {
+ $message = 'You need to provide a password to create a public link, only protected links are allowed';
+ $message_t = $l->t('You need to provide a password to create a public link, only protected links are allowed');
+ \OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
+ throw new \Exception($message_t);
+ }
+
// Generate token
if (isset($oldToken)) {
$token = $oldToken;
diff --git a/lib/private/util.php b/lib/private/util.php
index f76ee7b338a..107dc6b9a9f 100755
--- a/lib/private/util.php
+++ b/lib/private/util.php
@@ -87,6 +87,16 @@ class OC_Util {
}
/**
+ * @brief check if a password is required for each public link
+ * @return boolean
+ */
+ public static function isPublicLinkPasswordRequired() {
+ $appConfig = \OC::$server->getAppConfig();
+ $enforcePassword = $appConfig->getValue('core', 'shareapi_enforce_links_password', 'no');
+ return ($enforcePassword === 'yes') ? true : false;
+ }
+
+ /**
* Get the quota of a user
* @param string $user
* @return int Quota bytes
diff --git a/lib/public/util.php b/lib/public/util.php
index 8aeb03aef8e..929d86859a1 100644
--- a/lib/public/util.php
+++ b/lib/public/util.php
@@ -499,4 +499,12 @@ class Util {
public static function generateRandomBytes($length = 30) {
return \OC_Util::generateRandomBytes($length);
}
+
+ /**
+ * @brief check if a password is required for each public link
+ * @return boolean
+ */
+ public static function isPublicLinkPasswordRequired() {
+ return \OC_Util::isPublicLinkPasswordRequired();
+ }
}
diff --git a/settings/admin.php b/settings/admin.php
index 49dde59ce2a..f9406246e76 100755
--- a/settings/admin.php
+++ b/settings/admin.php
@@ -60,6 +60,7 @@ $tmpl->assign('isConnectedViaHTTPS', $connectedHTTPS);
$tmpl->assign('enforceHTTPSEnabled', OC_Config::getValue( "forcessl", false));
$tmpl->assign('allowLinks', OC_Appconfig::getValue('core', 'shareapi_allow_links', 'yes'));
+$tmpl->assign('enforceLinkPassword', \OCP\Util::isPublicLinkPasswordRequired());
$tmpl->assign('allowPublicUpload', OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes'));
$tmpl->assign('allowResharing', OC_Appconfig::getValue('core', 'shareapi_allow_resharing', 'yes'));
$tmpl->assign('allowMailNotification', OC_Appconfig::getValue('core', 'shareapi_allow_mail_notification', 'yes'));
diff --git a/settings/templates/admin.php b/settings/templates/admin.php
index 4d453b01270..d1f519a072d 100644
--- a/settings/templates/admin.php
+++ b/settings/templates/admin.php
@@ -217,9 +217,10 @@ if (!$_['internetconnectionworking']) {
<input type="checkbox" name="shareapi_allow_links" id="allowLinks"
value="1" <?php if ($_['allowLinks'] === 'yes') print_unescaped('checked="checked"'); ?> />
<label for="allowLinks"><?php p($l->t('Allow links'));?></label><br/>
-
<div <?php ($_['allowLinks'] === 'yes') ? print_unescaped('class="indent"') : print_unescaped('class="hidden indent"');?> id="publicLinkSettings">
-
+ <input type="checkbox" name="shareapi_enforce_links_password" id="enforceLinkPassword"
+ value="1" <?php if ($_['enforceLinkPassword']) print_unescaped('checked="checked"'); ?> />
+ <label for="enforceLinkPassword"><?php p($l->t('Enforce password protection'));?></label><br/>
<input type="checkbox" name="shareapi_allow_public_upload" id="allowPublicUpload"
value="1" <?php if ($_['allowPublicUpload'] == 'yes') print_unescaped('checked="checked"'); ?> />
<label for="allowPublicUpload"><?php p($l->t('Allow public uploads'));?></label><br/>