@@ -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(); | |||
} |
@@ -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 |
@@ -79,6 +79,7 @@ $array = array( | |||
'defaultExpireDateEnabled' => $defaultExpireDateEnabled, | |||
'defaultExpireDate' => $defaultExpireDate, | |||
'defaultExpireDateEnforced' => $enforceDefaultExpireDate, | |||
'enforcePasswordForPublicLink' => \OCP\Util::isPublicLinkPasswordRequired(), | |||
) | |||
) | |||
), |
@@ -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); | |||
} | |||
}); | |||
} | |||
}); | |||
@@ -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; |
@@ -86,6 +86,16 @@ class OC_Util { | |||
return true; | |||
} | |||
/** | |||
* @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 |
@@ -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(); | |||
} | |||
} |
@@ -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')); |
@@ -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/> |