diff options
author | Pellaeon Lin <nfsmwlin@gmail.com> | 2014-01-30 22:50:20 +0800 |
---|---|---|
committer | Pellaeon Lin <nfsmwlin@gmail.com> | 2014-01-30 22:50:20 +0800 |
commit | 099b71c712c38de7dac7e386252da02bb0cadf12 (patch) | |
tree | 84bcf83efdc4cc759a5ff184fa5148195abaab51 /apps/files_sharing | |
parent | 929c930b0afd682bb98eb389d7ebad91bb34d643 (diff) | |
parent | 299a8285bd2601ccbac988b2e3e9b067d47921a2 (diff) | |
download | nextcloud-server-099b71c712c38de7dac7e386252da02bb0cadf12.tar.gz nextcloud-server-099b71c712c38de7dac7e386252da02bb0cadf12.zip |
Merge branch 'master' into pr-exceed_upload_limit_msg
Conflicts:
apps/files/templates/index.php
apps/files_sharing/templates/public.php
Diffstat (limited to 'apps/files_sharing')
26 files changed, 363 insertions, 269 deletions
diff --git a/apps/files_sharing/ajax/publicpreview.php b/apps/files_sharing/ajax/publicpreview.php index 8c3085f1589..a52f522afac 100644 --- a/apps/files_sharing/ajax/publicpreview.php +++ b/apps/files_sharing/ajax/publicpreview.php @@ -36,7 +36,10 @@ if(!isset($linkedItem['uid_owner']) || !isset($linkedItem['file_source'])) { exit; } -$userId = $linkedItem['uid_owner']; +$rootLinkItem = OCP\Share::resolveReShare($linkedItem); +$userId = $rootLinkItem['uid_owner']; + +OCP\JSON::checkUserExists($rootLinkItem['uid_owner']); \OC_Util::setupFS($userId); \OC\Files\Filesystem::initMountPoints($userId); $view = new \OC\Files\View('/' . $userId . '/files'); @@ -86,4 +89,4 @@ try{ } catch (\Exception $e) { \OC_Response::setStatus(500); \OC_Log::write('core', $e->getmessage(), \OC_Log::DEBUG); -}
\ No newline at end of file +} diff --git a/apps/files_sharing/appinfo/update.php b/apps/files_sharing/appinfo/update.php index 0d827da28ea..4b716e764f4 100644 --- a/apps/files_sharing/appinfo/update.php +++ b/apps/files_sharing/appinfo/update.php @@ -44,6 +44,7 @@ if (version_compare($installedVersion, '0.3', '<')) { $shareType = OCP\Share::SHARE_TYPE_USER; $shareWith = $row['uid_shared_with']; } + OCP\JSON::checkUserExists($row['uid_owner']); OC_User::setUserId($row['uid_owner']); //we need to setup the filesystem for the user, otherwise OC_FileSystem::getRoot will fail and break OC_Util::setupFS($row['uid_owner']); diff --git a/apps/files_sharing/css/authenticate.css b/apps/files_sharing/css/authenticate.css index cebe906dd59..ef963ba7c65 100644 --- a/apps/files_sharing/css/authenticate.css +++ b/apps/files_sharing/css/authenticate.css @@ -11,16 +11,13 @@ margin: 6px; } -input[type="submit"]{ +input[type='submit'] { width: 45px; height: 45px; margin: 6px; - background-image: url('%webroot%/core/img/actions/confirm.svg'); - background-repeat: no-repeat; - background-position: center; } -#body-login input[type="submit"] { +#body-login input[type='submit'] { position: absolute; top: 0px; } diff --git a/apps/files_sharing/css/mobile.css b/apps/files_sharing/css/mobile.css new file mode 100644 index 00000000000..7d2116d190d --- /dev/null +++ b/apps/files_sharing/css/mobile.css @@ -0,0 +1,49 @@ +@media only screen and (max-width: 600px) { + +/* make header scroll up for single shares, more view of content on small screens */ +#header.share-file { + position: absolute !important; +} + +/* hide size and date columns */ +table th#headerSize, +table td.filesize, +table th#headerDate, +table td.date { + display: none; +} + +/* restrict length of displayed filename to prevent overflow */ +table td.filename .nametext { + max-width: 75% !important; +} + +/* on mobile, show single shared image at full width without margin */ +#imgframe { + width: 100%; + padding: 0; + margin-bottom: 35px; +} +/* some margin for the file type icon */ +#imgframe .publicpreview { + margin-top: 32px; +} + +/* always show actions on mobile */ +#fileList a.action { + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)" !important; + filter: alpha(opacity=20) !important; + opacity: .2 !important; + display: inline !important; +} +/* some padding for better clickability */ +#fileList a.action img { + padding: 0 6px 0 12px; +} +/* hide text of the actions on mobile */ +#fileList a.action span { + display: none; +} + + +} diff --git a/apps/files_sharing/css/public.css b/apps/files_sharing/css/public.css index 3ccb35e327a..21f0c82b829 100644 --- a/apps/files_sharing/css/public.css +++ b/apps/files_sharing/css/public.css @@ -3,7 +3,7 @@ body { } #header { - background: #1d2d44 url('%webroot%/core/img/noise.png') repeat; + background-color: #1d2d44; height:32px; left:0; line-height:32px; @@ -14,39 +14,17 @@ body { padding:7px; } -#details { - color:#fff; - float: left; -} - -#public_upload, -#download { - font-weight:700; - margin: 0 0 0 .4em; - padding: 0 5px; - height: 32px; - float: left; - -} - -.header-right #details { - margin-right: 28px; -} - .header-right { padding: 0; height: 32px; } -#public_upload { - margin-left: 0.3em; -} - -#public_upload img, -#download img { - padding-left:.1em; - padding-right:.3em; - vertical-align:text-bottom; +#details { + color:#fff; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; + filter: alpha(opacity=50); + opacity: .5; + padding-right: 5px; } #controls { @@ -61,19 +39,18 @@ body { #noPreview { display:none; - padding-top:5em; + padding-top:80px; } footer { - margin-top: 45px; + margin-top: 65px; } p.info { color: #777; text-align: center; - width: 22em; margin: 0 auto; - padding: 20px; + padding: 20px 0; } p.info a { @@ -83,8 +60,8 @@ p.info a { #imgframe { height:75%; - padding-bottom:2em; - padding-top:2em; + padding-bottom:32px; + padding-top:32px; width:80%; margin:0 auto; } @@ -94,9 +71,13 @@ p.info a { max-width:100%; } -thead{ - background-color: white; - padding-left:0 !important; /* fixes multiselect bar offset on shared page */ +/* some margin for the file type icon */ +#imgframe .publicpreview { + margin-top: 10%; +} + +thead { + padding-left: 0 !important; /* fixes multiselect bar offset on shared page */ } #data-upload-form { @@ -110,41 +91,20 @@ thead{ margin: 0; } -#file_upload_start { - -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; - filter: alpha(opacity=0); - opacity: 0; - z-index: 20; - position: absolute !important; - top: 0; - left: 0; - width: 100% !important; +.directDownload, +.directLink { + margin-bottom: 20px; } - -#publicUploadButtonMock { - position:relative; - display:block; - width:100%; - height:32px; - cursor:pointer; - z-index:10; - background-image:url('%webroot%/core/img/actions/upload.svg'); - background-repeat:no-repeat; - background-position:7px 8px; +.directDownload .button img { + vertical-align: text-bottom; } - -#publicUploadButtonMock span { - margin: 0 5px 0 28px; - color: #555; +.directLink label { + font-weight: normal; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; + filter: alpha(opacity=50); + opacity: .5; } - -.directLink { - margin-bottom: 20px; +.directLink input { + margin-left: 5px; + width: 300px; } - .directLink label { - font-weight: normal; - } - .directLink input { - margin-left: 10px; - width: 300px; - } diff --git a/apps/files_sharing/js/public.js b/apps/files_sharing/js/public.js index eacd4096ed8..c1b7eee3fb7 100644 --- a/apps/files_sharing/js/public.js +++ b/apps/files_sharing/js/public.js @@ -9,43 +9,32 @@ function fileDownloadPath(dir, file) { $(document).ready(function() { - $('#data-upload-form').tipsy({gravity:'ne', fade:true}); - if (typeof FileActions !== 'undefined') { var mimetype = $('#mimetype').val(); // Show file preview if previewer is available, images are already handled by the template if (mimetype.substr(0, mimetype.indexOf('/')) != 'image' && $('.publicpreview').length === 0) { // Trigger default action if not download TODO var action = FileActions.getDefault(mimetype, 'file', OC.PERMISSION_READ); - if (typeof action === 'undefined') { - $('#noPreview').show(); - if (mimetype != 'httpd/unix-directory') { - // NOTE: Remove when a better file previewer solution exists - $('#content').remove(); - $('table').remove(); - } - } else { + if (typeof action !== 'undefined') { action($('#filename').val()); } } FileActions.register('dir', 'Open', OC.PERMISSION_READ, '', function(filename) { - var tr = $('tr').filterAttr('data-file', filename); - if (tr.length > 0) { - window.location = $(tr).find('a.name').attr('href'); - } - }); - FileActions.register('file', 'Download', OC.PERMISSION_READ, '', function(filename) { - var tr = $('tr').filterAttr('data-file', filename); + var tr = FileList.findFileEl(filename); if (tr.length > 0) { window.location = $(tr).find('a.name').attr('href'); } }); - FileActions.register('dir', 'Download', OC.PERMISSION_READ, '', function(filename) { - var tr = $('tr').filterAttr('data-file', filename); + + // override since the format is different + FileList.getDownloadUrl = function(filename, dir) { + // we use this because we need the service and token attributes + var tr = FileList.findFileEl(filename); if (tr.length > 0) { - window.location = $(tr).find('a.name').attr('href')+'&download'; + return $(tr).find('a.name').attr('href') + '&download'; } - }); + return null; + }; } var file_upload_start = $('#file_upload_start'); @@ -58,15 +47,9 @@ $(document).ready(function() { }; }); - // Add Uploadprogress Wrapper to controls bar - $('#controls').append($('#additional_controls div#uploadprogresswrapper')); - - // Cancel upload trigger - $('#cancel_upload_button').click(function() { - OC.Upload.cancelUploads(); - procesSelection(); + $(document).on('click', '#directLink', function() { + $(this).focus(); + $(this).select(); }); - $('#directLink').focus(); - }); diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js index 340e0939445..36de452a55e 100644 --- a/apps/files_sharing/js/share.js +++ b/apps/files_sharing/js/share.js @@ -22,7 +22,7 @@ $(document).ready(function() { } else { var item = $('#dir').val() + '/' + filename; } - var tr = $('tr').filterAttr('data-file', filename); + var tr = FileList.findFileEl(filename); if ($(tr).data('type') == 'dir') { var itemType = 'folder'; } else { diff --git a/apps/files_sharing/l10n/da.php b/apps/files_sharing/l10n/da.php index aef3ad98811..849b0e28d30 100644 --- a/apps/files_sharing/l10n/da.php +++ b/apps/files_sharing/l10n/da.php @@ -1,5 +1,6 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Delingen er beskyttet af kodeord", "The password is wrong. Try again." => "Kodeordet er forkert. Prøv igen.", "Password" => "Kodeord", "Sorry, this link doesn’t seem to work anymore." => "Desværre, dette link ser ikke ud til at fungerer længere.", @@ -13,6 +14,7 @@ $TRANSLATIONS = array( "Download" => "Download", "Upload" => "Upload", "Cancel upload" => "Fortryd upload", -"No preview available for" => "Forhåndsvisning ikke tilgængelig for" +"No preview available for" => "Forhåndsvisning ikke tilgængelig for", +"Direct link" => "Direkte link" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/el.php b/apps/files_sharing/l10n/el.php index 79387a91472..3ea666504b1 100644 --- a/apps/files_sharing/l10n/el.php +++ b/apps/files_sharing/l10n/el.php @@ -1,19 +1,19 @@ <?php $TRANSLATIONS = array( "This share is password-protected" => "Αυτός ο κοινόχρηστος φάκελος προστατεύεται με κωδικό", -"The password is wrong. Try again." => "Εσφαλμένο συνθηματικό. Προσπαθήστε ξανά.", -"Password" => "Συνθηματικό", +"The password is wrong. Try again." => "Εσφαλμένος κωδικός πρόσβασης. Προσπαθήστε ξανά.", +"Password" => "Κωδικός πρόσβασης", "Sorry, this link doesn’t seem to work anymore." => "Συγγνώμη, αυτός ο σύνδεσμος μοιάζει να μην ισχύει πια.", "Reasons might be:" => "Οι λόγοι μπορεί να είναι:", "the item was removed" => "το αντικείμενο απομακρύνθηκε", "the link expired" => "ο σύνδεσμος έληξε", "sharing is disabled" => "ο διαμοιρασμός απενεργοποιήθηκε", "For more info, please ask the person who sent this link." => "Για περισσότερες πληροφορίες, παρακαλώ ρωτήστε το άτομο που σας έστειλε αυτόν τον σύνδεσμο.", -"%s shared the folder %s with you" => "%s μοιράστηκε τον φάκελο %s μαζί σας", -"%s shared the file %s with you" => "%s μοιράστηκε το αρχείο %s μαζί σας", +"%s shared the folder %s with you" => "Ο %s μοιράστηκε τον φάκελο %s μαζί σας", +"%s shared the file %s with you" => "Ο %s μοιράστηκε το αρχείο %s μαζί σας", "Download" => "Λήψη", "Upload" => "Μεταφόρτωση", -"Cancel upload" => "Ακύρωση αποστολής", +"Cancel upload" => "Ακύρωση μεταφόρτωσης", "No preview available for" => "Δεν υπάρχει διαθέσιμη προεπισκόπηση για", "Direct link" => "Άμεσος σύνδεσμος" ); diff --git a/apps/files_sharing/l10n/es_CL.php b/apps/files_sharing/l10n/es_CL.php new file mode 100644 index 00000000000..31dc045870c --- /dev/null +++ b/apps/files_sharing/l10n/es_CL.php @@ -0,0 +1,6 @@ +<?php +$TRANSLATIONS = array( +"Password" => "Clave", +"Upload" => "Subir" +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/es_MX.php b/apps/files_sharing/l10n/es_MX.php new file mode 100644 index 00000000000..9100ef8b35f --- /dev/null +++ b/apps/files_sharing/l10n/es_MX.php @@ -0,0 +1,20 @@ +<?php +$TRANSLATIONS = array( +"This share is password-protected" => "Este elemento compartido esta protegido por contraseña", +"The password is wrong. Try again." => "La contraseña introducida es errónea. Inténtelo de nuevo.", +"Password" => "Contraseña", +"Sorry, this link doesn’t seem to work anymore." => "Lo siento, este enlace al parecer ya no funciona.", +"Reasons might be:" => "Las causas podrían ser:", +"the item was removed" => "el elemento fue eliminado", +"the link expired" => "el enlace expiró", +"sharing is disabled" => "compartir está desactivado", +"For more info, please ask the person who sent this link." => "Para mayor información, contacte a la persona que le envió el enlace.", +"%s shared the folder %s with you" => "%s compartió la carpeta %s contigo", +"%s shared the file %s with you" => "%s compartió el archivo %s contigo", +"Download" => "Descargar", +"Upload" => "Subir", +"Cancel upload" => "Cancelar subida", +"No preview available for" => "No hay vista previa disponible para", +"Direct link" => "Enlace directo" +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_sharing/l10n/id.php b/apps/files_sharing/l10n/id.php index e91ef94bf38..865a951c2d2 100644 --- a/apps/files_sharing/l10n/id.php +++ b/apps/files_sharing/l10n/id.php @@ -1,11 +1,20 @@ <?php $TRANSLATIONS = array( +"This share is password-protected" => "Berbagi ini dilindungi sandi", +"The password is wrong. Try again." => "Sandi salah. Coba lagi", "Password" => "Sandi", +"Sorry, this link doesn’t seem to work anymore." => "Maaf, tautan ini tampaknya tidak berfungsi lagi.", +"Reasons might be:" => "Alasan mungkin:", +"the item was removed" => "item telah dihapus", +"the link expired" => "tautan telah kadaluarsa", +"sharing is disabled" => "berbagi dinonaktifkan", +"For more info, please ask the person who sent this link." => "Untuk info lebih lanjut, silakan tanyakan orang yang mengirim tautan ini.", "%s shared the folder %s with you" => "%s membagikan folder %s dengan Anda", -"%s shared the file %s with you" => "%s membagikan file %s dengan Anda", +"%s shared the file %s with you" => "%s membagikan berkas %s dengan Anda", "Download" => "Unduh", "Upload" => "Unggah", -"Cancel upload" => "Batal pengunggahan", -"No preview available for" => "Tidak ada pratinjau tersedia untuk" +"Cancel upload" => "Batal unggah", +"No preview available for" => "Tidak ada pratinjau yang tersedia untuk", +"Direct link" => "Tautan langsung" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_sharing/l10n/ko.php b/apps/files_sharing/l10n/ko.php index 90f59ed1673..03c4c1aea94 100644 --- a/apps/files_sharing/l10n/ko.php +++ b/apps/files_sharing/l10n/ko.php @@ -1,18 +1,20 @@ <?php $TRANSLATIONS = array( -"The password is wrong. Try again." => "비밀번호가 틀립니다. 다시 입력해주세요.", +"This share is password-protected" => "이 공유는 암호로 보호되어 있습니다", +"The password is wrong. Try again." => "암호가 잘못되었습니다. 다시 입력해 주십시오.", "Password" => "암호", -"Sorry, this link doesn’t seem to work anymore." => "죄송합니다만 이 링크는 더이상 작동되지 않습니다.", +"Sorry, this link doesn’t seem to work anymore." => "죄송합니다. 이 링크는 더 이상 작동하지 않습니다.", "Reasons might be:" => "이유는 다음과 같을 수 있습니다:", -"the item was removed" => "이 항목은 삭제되었습니다", -"the link expired" => "링크가 만료되었습니다", -"sharing is disabled" => "공유가 비활성되었습니다", -"For more info, please ask the person who sent this link." => "더 자세한 설명은 링크를 보내신 분에게 여쭤보십시오", +"the item was removed" => "항목이 삭제됨", +"the link expired" => "링크가 만료됨", +"sharing is disabled" => "공유가 비활성화됨", +"For more info, please ask the person who sent this link." => "자세한 정보는 링크를 보낸 사람에게 문의하십시오.", "%s shared the folder %s with you" => "%s 님이 폴더 %s을(를) 공유하였습니다", "%s shared the file %s with you" => "%s 님이 파일 %s을(를) 공유하였습니다", "Download" => "다운로드", "Upload" => "업로드", "Cancel upload" => "업로드 취소", -"No preview available for" => "다음 항목을 미리 볼 수 없음:" +"No preview available for" => "다음 항목을 미리 볼 수 없음:", +"Direct link" => "직접 링크" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_sharing/l10n/ru_RU.php b/apps/files_sharing/l10n/ru_RU.php deleted file mode 100644 index 2686b1e852d..00000000000 --- a/apps/files_sharing/l10n/ru_RU.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Password" => "Пароль", -"Download" => "Загрузка", -"Upload" => "Загрузка", -"Cancel upload" => "Отмена загрузки" -); -$PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/apps/files_sharing/l10n/sk.php b/apps/files_sharing/l10n/sk.php new file mode 100644 index 00000000000..72c9039571e --- /dev/null +++ b/apps/files_sharing/l10n/sk.php @@ -0,0 +1,5 @@ +<?php +$TRANSLATIONS = array( +"Download" => "Stiahnuť" +); +$PLURAL_FORMS = "nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"; diff --git a/apps/files_sharing/lib/api.php b/apps/files_sharing/lib/api.php index 84e90c71681..f828a4e840d 100644 --- a/apps/files_sharing/lib/api.php +++ b/apps/files_sharing/lib/api.php @@ -162,7 +162,7 @@ class Api { $view = new \OC\Files\View('/'.\OCP\User::getUser().'/files'); if(!$view->is_dir($path)) { - return new \OC_OCS_Result(null, 404, "not a directory"); + return new \OC_OCS_Result(null, 400, "not a directory"); } $content = $view->getDirectoryContent($path); @@ -220,10 +220,8 @@ class Api { $shareWith = isset($_POST['password']) ? $_POST['password'] : null; //check public link share $publicUploadEnabled = \OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes'); - $encryptionEnabled = \OC_App::isEnabled('files_encryption'); - if(isset($_POST['publicUpload']) && - ($encryptionEnabled || $publicUploadEnabled !== 'yes')) { - return new \OC_OCS_Result(null, 404, "public upload disabled by the administrator"); + if(isset($_POST['publicUpload']) && $publicUploadEnabled !== 'yes') { + return new \OC_OCS_Result(null, 403, "public upload disabled by the administrator"); } $publicUpload = isset($_POST['publicUpload']) ? $_POST['publicUpload'] : 'false'; // read, create, update (7) if public upload is enabled or @@ -231,7 +229,7 @@ class Api { $permissions = $publicUpload === 'true' ? 7 : 1; break; default: - return new \OC_OCS_Result(null, 404, "unknown share type"); + return new \OC_OCS_Result(null, 400, "unknown share type"); } try { @@ -243,7 +241,7 @@ class Api { $permissions ); } catch (\Exception $e) { - return new \OC_OCS_Result(null, 404, $e->getMessage()); + return new \OC_OCS_Result(null, 403, $e->getMessage()); } if ($token) { @@ -321,11 +319,8 @@ class Api { $permissions = isset($params['_put']['permissions']) ? (int)$params['_put']['permissions'] : null; $publicUploadStatus = \OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes'); - $encryptionEnabled = \OC_App::isEnabled('files_encryption'); - $publicUploadEnabled = false; - if(!$encryptionEnabled && $publicUploadStatus === 'yes') { - $publicUploadEnabled = true; - } + $publicUploadEnabled = ($publicUploadStatus === 'yes') ? true : false; + // only change permissions for public shares if public upload is enabled // and we want to set permissions to 1 (read only) or 7 (allow upload) @@ -363,9 +358,8 @@ class Api { private static function updatePublicUpload($share, $params) { $publicUploadEnabled = \OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes'); - $encryptionEnabled = \OC_App::isEnabled('files_encryption'); - if($encryptionEnabled || $publicUploadEnabled !== 'yes') { - return new \OC_OCS_Result(null, 404, "public upload disabled by the administrator"); + if($publicUploadEnabled !== 'yes') { + return new \OC_OCS_Result(null, 403, "public upload disabled by the administrator"); } if ($share['item_type'] !== 'folder' || diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 90440d08f4e..425d51113b1 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -127,7 +127,18 @@ class Shared_Cache extends Cache { return $files; } else { if ($cache = $this->getSourceCache($folder)) { - return $cache->getFolderContents($this->files[$folder]); + $sourceFolderContent = $cache->getFolderContents($this->files[$folder]); + foreach ($sourceFolderContent as $key => $c) { + $ownerPathParts = explode('/', \OC_Filesystem::normalizePath($c['path'])); + $userPathParts = explode('/', \OC_Filesystem::normalizePath($folder)); + $usersPath = 'files/Shared/'.$userPathParts[1]; + foreach (array_slice($ownerPathParts, 3) as $part) { + $usersPath .= '/'.$part; + } + $sourceFolderContent[$key]['usersPath'] = $usersPath; + } + + return $sourceFolderContent; } } return false; @@ -260,7 +271,7 @@ class Shared_Cache extends Cache { return $this->searchWithWhere($where, $value); } - + /** * The maximum number of placeholders that can be used in an SQL query. * Value MUST be <= 1000 for oracle: @@ -268,7 +279,7 @@ class Shared_Cache extends Cache { * FIXME we should get this from doctrine as other DBs allow a lot more placeholders */ const MAX_SQL_CHUNK_SIZE = 1000; - + /** * search for files with a custom where clause and value * the $wherevalue will be array_merge()d with the file id chunks @@ -282,16 +293,16 @@ class Shared_Cache extends Cache { $ids = $this->getAll(); $files = array(); - + // divide into chunks $chunks = array_chunk($ids, $chunksize); - + foreach ($chunks as $chunk) { $placeholders = join(',', array_fill(0, count($chunk), '?')); $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `unencrypted_size`, `etag` FROM `*PREFIX*filecache` WHERE ' . $sqlwhere . ' `fileid` IN (' . $placeholders . ')'; - + $stmt = \OC_DB::prepare($sql); $result = $stmt->execute(array_merge(array($wherevalue), $chunk)); diff --git a/apps/files_sharing/lib/permissions.php b/apps/files_sharing/lib/permissions.php index e2978e12bfb..1dc53428a7f 100644 --- a/apps/files_sharing/lib/permissions.php +++ b/apps/files_sharing/lib/permissions.php @@ -42,6 +42,19 @@ class Shared_Permissions extends Permissions { } } + private function getFile($fileId, $user) { + if ($fileId == -1) { + return \OCP\PERMISSION_READ; + } + $source = \OCP\Share::getItemSharedWithBySource('file', $fileId, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE, + null, false); + if ($source) { + return $source['permissions']; + } else { + return -1; + } + } + /** * set the permissions of a file * @@ -82,7 +95,7 @@ class Shared_Permissions extends Permissions { if ($parentId === -1) { return \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_PERMISSIONS); } - $permissions = $this->get($parentId, $user); + $permissions = $this->getFile($parentId, $user); $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `parent` = ?'); $result = $query->execute(array($parentId)); $filePermissions = array(); diff --git a/apps/files_sharing/lib/share/file.php b/apps/files_sharing/lib/share/file.php index 07e7a4ca0c5..c956c55a1df 100644 --- a/apps/files_sharing/lib/share/file.php +++ b/apps/files_sharing/lib/share/file.php @@ -172,7 +172,7 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent { $source['fileOwner'] = $fileOwner; return $source; } - \OCP\Util::writeLog('files_sharing', 'File source not found for: '.$target, \OCP\Util::ERROR); + \OCP\Util::writeLog('files_sharing', 'File source not found for: '.$target, \OCP\Util::DEBUG); return false; } diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 3116cd717fb..afe5dffdebd 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -279,43 +279,26 @@ class Shared extends \OC\Files\Storage\Common { if ($this->isDeletable($path)) { list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->unlink($internalPath); - } else if (dirname($path) == '/' || dirname($path) == '.') { - // Unshare the file from the user if in the root of the Shared folder - if ($this->is_dir($path)) { - $itemType = 'folder'; - } else { - $itemType = 'file'; - } - return \OCP\Share::unshareFromSelf($itemType, $path); } } return false; } public function rename($path1, $path2) { - // Check for partial files - if (pathinfo($path1, PATHINFO_EXTENSION) === 'part') { - if ($oldSource = $this->getSourcePath($path1)) { + // Renaming/moving is only allowed within shared folders + $pos1 = strpos($path1, '/', 1); + $pos2 = strpos($path2, '/', 1); + if ($pos1 !== false && $pos2 !== false && ($oldSource = $this->getSourcePath($path1))) { + $newSource = $this->getSourcePath(dirname($path2)) . '/' . basename($path2); + // Within the same folder, we only need UPDATE permissions + if (dirname($path1) == dirname($path2) and $this->isUpdatable($path1)) { list($storage, $oldInternalPath) = \OC\Files\Filesystem::resolvePath($oldSource); - $newInternalPath = substr($oldInternalPath, 0, -5); + list(, $newInternalPath) = \OC\Files\Filesystem::resolvePath($newSource); return $storage->rename($oldInternalPath, $newInternalPath); - } - } else { - // Renaming/moving is only allowed within shared folders - $pos1 = strpos($path1, '/', 1); - $pos2 = strpos($path2, '/', 1); - if ($pos1 !== false && $pos2 !== false && ($oldSource = $this->getSourcePath($path1))) { - $newSource = $this->getSourcePath(dirname($path2)) . '/' . basename($path2); - // Within the same folder, we only need UPDATE permissions - if (dirname($path1) == dirname($path2) and $this->isUpdatable($path1)) { - list($storage, $oldInternalPath) = \OC\Files\Filesystem::resolvePath($oldSource); - list(, $newInternalPath) = \OC\Files\Filesystem::resolvePath($newSource); - return $storage->rename($oldInternalPath, $newInternalPath); - // otherwise DELETE and CREATE permissions required - } elseif ($this->isDeletable($path1) && $this->isCreatable(dirname($path2))) { - $rootView = new \OC\Files\View(''); - return $rootView->rename($oldSource, $newSource); - } + // otherwise DELETE and CREATE permissions required + } elseif ($this->isDeletable($path1) && $this->isCreatable(dirname($path2))) { + $rootView = new \OC\Files\View(''); + return $rootView->rename($oldSource, $newSource); } } return false; diff --git a/apps/files_sharing/lib/watcher.php b/apps/files_sharing/lib/watcher.php index c40cf6911b8..285b1a58c6e 100644 --- a/apps/files_sharing/lib/watcher.php +++ b/apps/files_sharing/lib/watcher.php @@ -32,7 +32,7 @@ class Shared_Watcher extends Watcher { * @param string $path */ public function checkUpdate($path) { - if ($path != '' && parent::checkUpdate($path)) { + if ($path != '' && parent::checkUpdate($path) === true) { // since checkUpdate() has already updated the size of the subdirs, // only apply the update to the owner's parent dirs diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index 540f2b004c6..b187da41324 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -35,7 +35,7 @@ function determineIcon($file, $sharingRoot, $sharingToken) { if (isset($_GET['t'])) { $token = $_GET['t']; - $linkItem = OCP\Share::getShareByToken($token); + $linkItem = OCP\Share::getShareByToken($token, false); if (is_array($linkItem) && isset($linkItem['uid_owner'])) { // seems to be a valid share $type = $linkItem['item_type']; @@ -43,10 +43,10 @@ if (isset($_GET['t'])) { $shareOwner = $linkItem['uid_owner']; $path = null; $rootLinkItem = OCP\Share::resolveReShare($linkItem); - $fileOwner = $rootLinkItem['uid_owner']; - if (isset($fileOwner)) { + if (isset($rootLinkItem['uid_owner'])) { + OCP\JSON::checkUserExists($rootLinkItem['uid_owner']); OC_Util::tearDownFS(); - OC_Util::setupFS($fileOwner); + OC_Util::setupFS($rootLinkItem['uid_owner']); $path = \OC\Files\Filesystem::getPath($linkItem['file_source']); } } @@ -111,6 +111,7 @@ if (isset($path)) { } } $basePath = $path; + $rootName = basename($path); if (isset($_GET['path']) && \OC\Files\Filesystem::isReadable($basePath . $_GET['path'])) { $getPath = \OC\Files\Filesystem::normalizePath($_GET['path']); $path .= $getPath; @@ -136,6 +137,7 @@ if (isset($path)) { } else { OCP\Util::addScript('files', 'file-upload'); OCP\Util::addStyle('files_sharing', 'public'); + OCP\Util::addStyle('files_sharing', 'mobile'); OCP\Util::addScript('files_sharing', 'public'); OCP\Util::addScript('files', 'fileactions'); OCP\Util::addScript('files', 'jquery.iframe-transport'); @@ -160,7 +162,6 @@ if (isset($path)) { if ($linkItem['item_type'] !== 'folder') { $allowPublicUploadEnabled = false; } - $tmpl->assign('allowPublicUploadEnabled', $allowPublicUploadEnabled); $tmpl->assign('uploadMaxFilesize', $maxUploadFilesize); $tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); $tmpl->assign('freeSpace', $freeSpace); @@ -192,8 +193,8 @@ if (isset($path)) { } else { $i['extension'] = ''; } - $i['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($i['mimetype']); } + $i['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($i['mimetype']); $i['directory'] = $getPath; $i['permissions'] = OCP\PERMISSION_READ; $i['icon'] = determineIcon($i, $basePath, $token); @@ -220,6 +221,7 @@ if (isset($path)) { $list->assign('sharingroot', $basePath); $breadcrumbNav = new OCP\Template('files', 'part.breadcrumb', ''); $breadcrumbNav->assign('breadcrumb', $breadcrumb); + $breadcrumbNav->assign('rootBreadCrumb', $rootName); $breadcrumbNav->assign('baseURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&path='); $maxUploadFilesize=OCP\Util::maxUploadFilesize($path); $fileHeader = (!isset($files) or count($files) > 0); @@ -228,7 +230,8 @@ if (isset($path)) { $folder->assign('fileList', $list->fetchPage()); $folder->assign('breadcrumb', $breadcrumbNav->fetchPage()); $folder->assign('dir', $getPath); - $folder->assign('isCreatable', false); + $folder->assign('isCreatable', $allowPublicUploadEnabled); + $folder->assign('dirToken', $linkItem['token']); $folder->assign('permissions', OCP\PERMISSION_READ); $folder->assign('isPublic',true); $folder->assign('publicUploadEnabled', 'no'); diff --git a/apps/files_sharing/templates/authenticate.php b/apps/files_sharing/templates/authenticate.php index 6b98e6c9f34..928be93fc96 100644 --- a/apps/files_sharing/templates/authenticate.php +++ b/apps/files_sharing/templates/authenticate.php @@ -9,7 +9,7 @@ <p class="infield"> <label for="password" class="infield"><?php p($l->t('Password')); ?></label> <input type="password" name="password" id="password" placeholder="" value="" autofocus /> - <input type="submit" value="" class="svg" /> + <input type="submit" value="" class="svg icon icon-confirm" /> </p> </fieldset> </form> diff --git a/apps/files_sharing/templates/public.php b/apps/files_sharing/templates/public.php index 124b4a1ae9f..3ddaf4446df 100644 --- a/apps/files_sharing/templates/public.php +++ b/apps/files_sharing/templates/public.php @@ -9,66 +9,14 @@ <input type="hidden" name="sharingToken" value="<?php p($_['sharingToken']) ?>" id="sharingToken"> <input type="hidden" name="filename" value="<?php p($_['filename']) ?>" id="filename"> <input type="hidden" name="mimetype" value="<?php p($_['mimetype']) ?>" id="mimetype"> -<header><div id="header"> +<header><div id="header" class="icon icon-noise <?php p((isset($_['folder']) ? 'share-folder' : 'share-file')) ?>"> <a href="<?php print_unescaped(link_to('', 'index.php')); ?>" title="" id="owncloud"><img class="svg" src="<?php print_unescaped(image_path('', 'logo-wide.svg')); ?>" alt="<?php p($theme->getName()); ?>" /></a> <div id="logo-claim" style="display:none;"><?php p($theme->getLogoClaim()); ?></div> <div class="header-right"> - <?php if (isset($_['folder'])): ?> - <span id="details"><?php p($l->t('%s shared the folder %s with you', - array($_['displayName'], $_['filename']))) ?></span> - <?php else: ?> - <span id="details"><?php p($l->t('%s shared the file %s with you', - array($_['displayName'], $_['filename']))) ?></span> - <?php endif; ?> - - - <?php if (!isset($_['folder']) || $_['allowZipDownload']): ?> - <a href="<?php p($_['downloadURL']); ?>" class="button" id="download"><img - class="svg" alt="Download" src="<?php print_unescaped(OCP\image_path("core", "actions/download.svg")); ?>" - /><span><?php p($l->t('Download'))?></span></a> - <?php endif; ?> - - <?php if ($_['allowPublicUploadEnabled']):?> - - - <input type="hidden" id="publicUploadRequestToken" name="requesttoken" value="<?php p($_['requesttoken']) ?>" /> - <input type="hidden" id="dirToken" name="dirToken" value="<?php p($_['dirToken']) ?>" /> - <input type="hidden" id="upload_limit" value="<?php p($_['uploadLimit']) ?>"> - <input type="hidden" id="free_space" value="<?php p($_['freeSpace']) ?>"> - <input type="hidden" id="uploadMaxFilesize" name="uploadMaxFilesize" value="<?php p($_['uploadMaxFilesize']) ?>" /> - <input type="hidden" id="uploadMaxHumanFilesize" name="uploadMaxHumanFilesize" value="<?php p($_['uploadMaxHumanFilesize']) ?>" /> - <input type="hidden" id="directory_path" name="directory_path" value="<?php p($_['directory_path']) ?>" /> - <?php if($_['uploadMaxFilesize'] >= 0):?> - <input type="hidden" name="MAX_FILE_SIZE" id="max_upload" - value="<?php p($_['uploadMaxFilesize']) ?>"> - <?php endif;?> - - - <div id="data-upload-form" class="button" title="<?php p($l->t('Upload') . ' max. '.$_['uploadMaxHumanFilesize']) ?>"> - <input id="file_upload_start" type="file" name="files[]" data-url="<?php print_unescaped(OCP\Util::linkTo('files', 'ajax/upload.php')); ?>" multiple> - <a href="#" id="publicUploadButtonMock" class="svg"> - <span><?php p($l->t('Upload'))?></span> - </a> - </div> - + <span id="details"><?php p($l->t('shared by %s', array($_['displayName']))) ?></span> </div> - - <div id="additional_controls" style="display:none"> - <div id="uploadprogresswrapper"> - <div id="uploadprogressbar"></div> - <input id="cancel_upload_button" type="button" class="stop" style="display:none" - value="<?php p($l->t('Cancel upload'));?>" - /> - </div> - - - - - <?php endif; ?> - - </div> - </div></header> +</div></header> <div id="content"> <div id="preview"> <?php if (isset($_['folder'])): ?> @@ -84,25 +32,28 @@ <source src="<?php p($_['downloadURL']); ?>" type="<?php p($_['mimetype']); ?>" /> </video> </div> - <?php elseif (\OC\Preview::isMimeSupported($_['mimetype'])): ?> + <?php else: ?> <div id="imgframe"> - <img src="<?php p(OCP\Util::linkToRoute( 'core_ajax_public_preview', array('x' => 500, 'y' => 500, 'file' => urlencode($_['directory_path']), 't' => $_['dirToken']))); ?>" class="publicpreview"/> + <?php $size = \OC\Preview::isMimeSupported($_['mimetype']) ? 500 : 128 ?> + <img src="<?php p(OCP\Util::linkToRoute( 'core_ajax_public_preview', array('x' => $size, 'y' => $size, 'file' => urlencode($_['directory_path']), 't' => $_['dirToken']))); ?>" class="publicpreview"/> </div> - <?php else: ?> - <ul id="noPreview"> - <li class="error"> - <?php p($l->t('No preview available for').' '.$_['filename']); ?><br /> - <a href="<?php p($_['downloadURL']); ?>" id="download"><img class="svg" alt="Download" - src="<?php print_unescaped(OCP\image_path("core", "actions/download.svg")); ?>" - /><?php p($l->t('Download'))?></a> - </li> - </ul> <?php endif; ?> - <div class="directLink"><label for="directLink"><?php p($l->t('Direct link')) ?></label><input id="directLink" type="text" readonly value="<?php p($_['downloadURL']); ?>"></input></div> + <div class="directDownload"> + <a href="<?php p($_['downloadURL']); ?>" id="download" class="button"> + <img class="svg" alt="" src="<?php print_unescaped(OCP\image_path("core", "actions/download.svg")); ?>"/> + <?php p($l->t('Download %s', array($_['filename'])))?> + </a> + </div> + <div class="directLink"> + <label for="directLink"><?php p($l->t('Direct link')) ?></label> + <input id="directLink" type="text" readonly value="<?php p($_['downloadURL']); ?>"> + </div> <?php endif; ?> </div> - <footer> - <p class="info"> - <?php print_unescaped($theme->getLongFooter()); ?> - </p> - </footer> + +</div> +<footer> + <p class="info"> + <?php print_unescaped($theme->getLongFooter()); ?> + </p> +</footer> diff --git a/apps/files_sharing/tests/base.php b/apps/files_sharing/tests/base.php index 689c80cb9e6..3e283271f5d 100644 --- a/apps/files_sharing/tests/base.php +++ b/apps/files_sharing/tests/base.php @@ -132,8 +132,8 @@ abstract class Test_Files_Sharing_Base extends \PHPUnit_Framework_TestCase { $share = Null; - if ($result && $result->numRows() > 0) { - $share = $result->fetchRow(); + if ($result) { + $share = $result->fetchRow(); } return $share; diff --git a/apps/files_sharing/tests/permissions.php b/apps/files_sharing/tests/permissions.php new file mode 100644 index 00000000000..e301d384a49 --- /dev/null +++ b/apps/files_sharing/tests/permissions.php @@ -0,0 +1,110 @@ +<?php +/** + * ownCloud + * + * @author Vincent Petry + * @copyright 2013 Vincent Petry <pvince81@owncloud.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ +require_once __DIR__ . '/base.php'; + +class Test_Files_Sharing_Permissions extends Test_Files_Sharing_Base { + + function setUp() { + parent::setUp(); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + + // prepare user1's dir structure + $textData = "dummy file data\n"; + $this->view->mkdir('container'); + $this->view->mkdir('container/shareddir'); + $this->view->mkdir('container/shareddir/subdir'); + $this->view->mkdir('container/shareddirrestricted'); + $this->view->mkdir('container/shareddirrestricted/subdir'); + $this->view->file_put_contents('container/shareddir/textfile.txt', $textData); + $this->view->file_put_contents('container/shareddirrestricted/textfile1.txt', $textData); + + list($this->ownerStorage, $internalPath) = $this->view->resolvePath(''); + $this->ownerCache = $this->ownerStorage->getCache(); + $this->ownerStorage->getScanner()->scan(''); + + // share "shareddir" with user2 + $fileinfo = $this->view->getFileInfo('container/shareddir'); + \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + self::TEST_FILES_SHARING_API_USER2, 31); + $fileinfo2 = $this->view->getFileInfo('container/shareddirrestricted'); + \OCP\Share::shareItem('folder', $fileinfo2['fileid'], \OCP\Share::SHARE_TYPE_USER, + self::TEST_FILES_SHARING_API_USER2, 7); + + // login as user2 + self::loginHelper(self::TEST_FILES_SHARING_API_USER2); + + // retrieve the shared storage + $this->secondView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2); + list($this->sharedStorage, $internalPath) = $this->secondView->resolvePath('files/Shared/shareddir'); + $this->sharedCache = $this->sharedStorage->getCache(); + } + + function tearDown() { + $this->sharedCache->clear(); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + + $fileinfo = $this->view->getFileInfo('container/shareddir'); + \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, + self::TEST_FILES_SHARING_API_USER2); + $fileinfo2 = $this->view->getFileInfo('container/shareddirrestricted'); + \OCP\Share::unshare('folder', $fileinfo2['fileid'], \OCP\Share::SHARE_TYPE_USER, + self::TEST_FILES_SHARING_API_USER2); + + $this->view->deleteAll('container'); + + $this->ownerCache->clear(); + + parent::tearDown(); + } + + /** + * Test that the permissions of shared directory are returned correctly + */ + function testGetPermissions() { + $sharedDirPerms = $this->sharedStorage->getPermissions('shareddir'); + $this->assertEquals(31, $sharedDirPerms); + $sharedDirPerms = $this->sharedStorage->getPermissions('shareddir/textfile.txt'); + $this->assertEquals(31, $sharedDirPerms); + $sharedDirRestrictedPerms = $this->sharedStorage->getPermissions('shareddirrestricted'); + $this->assertEquals(7, $sharedDirRestrictedPerms); + $sharedDirRestrictedPerms = $this->sharedStorage->getPermissions('shareddirrestricted/textfile.txt'); + $this->assertEquals(7, $sharedDirRestrictedPerms); + } + + /** + * Test that the permissions of shared directory are returned correctly + */ + function testGetDirectoryPermissions() { + $contents = $this->secondView->getDirectoryContent('files/Shared/shareddir'); + $this->assertEquals('subdir', $contents[0]['name']); + $this->assertEquals(31, $contents[0]['permissions']); + $this->assertEquals('textfile.txt', $contents[1]['name']); + $this->assertEquals(31, $contents[1]['permissions']); + $contents = $this->secondView->getDirectoryContent('files/Shared/shareddirrestricted'); + $this->assertEquals('subdir', $contents[0]['name']); + $this->assertEquals(7, $contents[0]['permissions']); + $this->assertEquals('textfile1.txt', $contents[1]['name']); + $this->assertEquals(7, $contents[1]['permissions']); + } +} |