diff options
author | Björn Schießle <schiessle@owncloud.com> | 2014-05-16 12:23:01 -0400 |
---|---|---|
committer | Björn Schießle <schiessle@owncloud.com> | 2014-05-16 12:23:01 -0400 |
commit | b52cb8f5570f4ec0e73aa5b2e1a5dbd178135382 (patch) | |
tree | 8e622b686a60a49bbe6cf21469a232dcb72e6eea | |
parent | d5f60a8eb0b3521ba0d85e9191468f09ea37803e (diff) | |
parent | b6e14af861481d0b2ebf6ca752d994c5adfce866 (diff) | |
download | nextcloud-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.php | 19 | ||||
-rw-r--r-- | apps/files_sharing/tests/api.php | 54 | ||||
-rw-r--r-- | core/js/config.php | 1 | ||||
-rw-r--r-- | core/js/share.js | 52 | ||||
-rw-r--r-- | lib/private/share/share.php | 11 | ||||
-rwxr-xr-x | lib/private/util.php | 10 | ||||
-rw-r--r-- | lib/public/util.php | 8 | ||||
-rwxr-xr-x | settings/admin.php | 1 | ||||
-rw-r--r-- | settings/templates/admin.php | 5 |
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/> |