Initial previewer for public links
This commit is contained in:
parent
8374a49cc1
commit
0a9d1ed3a6
11 changed files with 178 additions and 115 deletions
2
apps/files_sharing/css/public.css
Normal file
2
apps/files_sharing/css/public.css
Normal file
|
@ -0,0 +1,2 @@
|
|||
#content { position:relative; }
|
||||
#preview p { text-align: center; }
|
|
@ -1,88 +0,0 @@
|
|||
<?php
|
||||
// only need authentication apps
|
||||
$RUNTIME_APPTYPES=array('authentication');
|
||||
OC_App::loadApps($RUNTIME_APPTYPES);
|
||||
|
||||
OCP\JSON::checkAppEnabled('files_sharing');
|
||||
//FIXME lib_share / OC_Share no longer exists
|
||||
require_once 'lib_share.php';
|
||||
|
||||
//get the path of the shared file
|
||||
if (isset($_GET['token']) && $source = OC_Share::getSource($_GET['token'])) {
|
||||
$token = $_GET['token'];
|
||||
// TODO Manipulating the string may not be the best choice. Is there an alternative?
|
||||
$user = substr($source, 1, strpos($source, "/", 1) - 1);
|
||||
OC_Util::setupFS($user);
|
||||
$source = substr($source, strlen("/".$user."/files"));
|
||||
$subPath = isset( $_GET['path'] ) ? $_GET['path'] : '';
|
||||
$root = $source;
|
||||
$source .= $subPath;
|
||||
if (!OC_Filesystem::file_exists($source)) {
|
||||
header("HTTP/1.0 404 Not Found");
|
||||
$tmpl = new OCP\Template("", "404", "guest");
|
||||
$tmpl->assign("file", $subPath);
|
||||
$tmpl->printPage();
|
||||
exit;
|
||||
}
|
||||
if (OC_Filesystem::is_dir($source)) {
|
||||
$files = array();
|
||||
$rootLength = strlen($root);
|
||||
foreach (OC_Files::getdirectorycontent($source) as $i) {
|
||||
$i['date'] = OCP\Util::formatDate($i['mtime'] );
|
||||
if ($i['type'] == 'file') {
|
||||
$fileinfo = pathinfo($i['name']);
|
||||
$i['basename'] = $fileinfo['filename'];
|
||||
$i['extension'] = isset($fileinfo['extension']) ? ('.'.$fileinfo['extension']) : '';
|
||||
}
|
||||
$i['directory'] = substr($i['directory'], $rootLength);
|
||||
if ($i['directory'] == "/") {
|
||||
$i['directory'] = "";
|
||||
}
|
||||
$files[] = $i;
|
||||
}
|
||||
// Make breadcrumb
|
||||
$breadcrumb = array();
|
||||
$pathtohere = "";
|
||||
foreach (explode("/", $subPath) as $i) {
|
||||
if ($i != "") {
|
||||
$pathtohere .= "/$i";
|
||||
$breadcrumb[] = array("dir" => $pathtohere, "name" => $i);
|
||||
}
|
||||
}
|
||||
// Load the files we need
|
||||
OCP\Util::addStyle("files", "files");
|
||||
$breadcrumbNav = new OCP\Template("files", "part.breadcrumb", "");
|
||||
$breadcrumbNav->assign("breadcrumb", $breadcrumb);
|
||||
$breadcrumbNav->assign("baseURL", OCP\Util::linkTo("", "public.php")."?service=files&token=".$token."&path=");
|
||||
$list = new OCP\Template("files", "part.list", "");
|
||||
$list->assign("files", $files);
|
||||
$list->assign("baseURL", OCP\Util::linkTo("", "public.php")."?service=files&token=".$token."&path=");
|
||||
$list->assign("downloadURL", OCP\Util::linkTo("", "public.php")."?service=files&token=".$token."&path=");
|
||||
$list->assign("readonly", true);
|
||||
$tmpl = new OCP\Template("files", "index", "user");
|
||||
$tmpl->assign("fileList", $list->fetchPage(), false);
|
||||
$tmpl->assign("breadcrumb", $breadcrumbNav->fetchPage());
|
||||
$tmpl->assign("readonly", true);
|
||||
$tmpl->assign("allowZipDownload", false);
|
||||
$tmpl->assign("dir", 'shared dir');
|
||||
$tmpl->printPage();
|
||||
} else {
|
||||
//get time mimetype and set the headers
|
||||
$mimetype = OC_Filesystem::getMimeType($source);
|
||||
header("Content-Transfer-Encoding: binary");
|
||||
OCP\Response::disableCaching();
|
||||
header('Content-Disposition: attachment; filename="'.basename($source).'"');
|
||||
header("Content-Type: " . $mimetype);
|
||||
header("Content-Length: " . OC_Filesystem::filesize($source));
|
||||
//download the file
|
||||
@ob_clean();
|
||||
//FIXME OC_Share no longer exists
|
||||
OCP\Util::emitHook('OC_Share', 'public-download', array('source'=>$source, 'token'=>$token));
|
||||
OC_Filesystem::readfile($source);
|
||||
}
|
||||
} else {
|
||||
header("HTTP/1.0 404 Not Found");
|
||||
$tmpl = new OCP\Template("", "404", "guest");
|
||||
$tmpl->printPage();
|
||||
die();
|
||||
}
|
18
apps/files_sharing/js/public.js
Normal file
18
apps/files_sharing/js/public.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Override download path to files_sharing/public.php
|
||||
function fileDownloadPath(dir, file) {
|
||||
return $('#downloadURL').val();
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
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') {
|
||||
// Trigger default action if not download TODO
|
||||
var action = FileActions.getDefault(mimetype, 'file', FileActions.PERMISSION_READ);
|
||||
action($('#filename').val());
|
||||
}
|
||||
}
|
||||
|
||||
});
|
69
apps/files_sharing/public.php
Normal file
69
apps/files_sharing/public.php
Normal file
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
// Load other apps for file previews
|
||||
OC_App::loadApps();
|
||||
if (isset($_GET['file'])) {
|
||||
$pos = strpos($_GET['file'], '/', 1);
|
||||
$uidOwner = substr($_GET['file'], 1, $pos - 1);
|
||||
if (OCP\User::userExists($uidOwner)) {
|
||||
OC_Util::setupFS($uidOwner);
|
||||
$file = substr($_GET['file'], $pos);
|
||||
$fileSource = OC_Filecache::getId($_GET['file'], '');
|
||||
if ($linkItem = OCP\Share::getItemSharedWithByLink('file', $fileSource, $uidOwner)) {
|
||||
if (isset($linkItem['share_with'])) {
|
||||
// Check password
|
||||
if (isset($_POST['password'])) {
|
||||
$password = $_POST['password'];
|
||||
$storedHash = $linkItem['share_with'];
|
||||
$forcePortable = (CRYPT_BLOWFISH != 1);
|
||||
$hasher = new PasswordHash(8, $forcePortable);
|
||||
if (!($hasher->CheckPassword($password.OC_Config::getValue('passwordsalt', ''), $storedHash))) {
|
||||
$tmpl = new OCP\Template('files_sharing', 'authenticate', 'guest');
|
||||
$tmpl->assign('error', true);
|
||||
$tmpl->printPage();
|
||||
exit();
|
||||
}
|
||||
// Continue on if password is valid
|
||||
} else {
|
||||
// Prompt for password
|
||||
$tmpl = new OCP\Template('files_sharing', 'authenticate', 'guest');
|
||||
$tmpl->printPage();
|
||||
exit();
|
||||
}
|
||||
}
|
||||
$path = $linkItem['path'];
|
||||
// Download the file
|
||||
if (isset($_GET['download'])) {
|
||||
$mimetype = OC_Filesystem::getMimeType($path);
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
header('Content-Disposition: attachment; filename="'.basename($path).'"');
|
||||
header('Content-Type: '.$mimetype);
|
||||
header('Content-Length: '.OC_Filesystem::filesize($path));
|
||||
OCP\Response::disableCaching();
|
||||
@ob_clean();
|
||||
OC_Filesystem::readfile($path);
|
||||
} else {
|
||||
OCP\Util::addStyle('files_sharing', 'public');
|
||||
OCP\Util::addScript('files_sharing', 'public');
|
||||
OCP\Util::addScript('files', 'fileactions');
|
||||
$tmpl = new OCP\Template('files_sharing', 'public', 'guest');
|
||||
$tmpl->assign('owner', $uidOwner);
|
||||
$tmpl->assign('name', basename($path));
|
||||
// Show file list
|
||||
if (OC_Filesystem::is_dir($path)) {
|
||||
// TODO
|
||||
} else {
|
||||
// Show file preview if viewer is available
|
||||
$tmpl->assign('dir', dirname($path));
|
||||
$tmpl->assign('filename', basename($path));
|
||||
$tmpl->assign('mimetype', OC_Filesystem::getMimeType($path));
|
||||
$tmpl->assign('downloadURL', OCP\Util::linkToPublic('files').'&file='.$_GET['file'].'&download');
|
||||
}
|
||||
$tmpl->printPage();
|
||||
}
|
||||
exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
$tmpl = new OCP\Template('', '404', 'guest');
|
||||
$tmpl->printPage();
|
9
apps/files_sharing/templates/authenticate.php
Normal file
9
apps/files_sharing/templates/authenticate.php
Normal file
|
@ -0,0 +1,9 @@
|
|||
<form action="index.php" method="post">
|
||||
<fieldset>
|
||||
<p>
|
||||
<label for="password" class="infield"><?php echo $l->t('Password'); ?></label>
|
||||
<input type="password" name="password" id="password" value="" />
|
||||
<input type="submit" value="<?php echo $l->t('Submit'); ?>" />
|
||||
</p>
|
||||
</fieldset>
|
||||
</form>
|
|
@ -1,11 +0,0 @@
|
|||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th id="headerSize"><?php echo $l->t( 'Size' ); ?></th>
|
||||
<th id="headerDate"><span id="modified"><?php echo $l->t( 'Modified' ); ?></span><span class="selectedActions"><a href="" class="delete"><?php echo $l->t('Delete all')?> <img class="svg" alt="<?php echo $l->t('Delete')?>" src="<?php echo OCP\image_path("core", "actions/delete.svg"); ?>" /></a></span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="fileList" data-readonly="<?php echo $_['readonly'];?>">
|
||||
<?php echo($_['fileList']); ?>
|
||||
</tbody>
|
||||
</table>
|
13
apps/files_sharing/templates/public.php
Executable file
13
apps/files_sharing/templates/public.php
Executable file
|
@ -0,0 +1,13 @@
|
|||
<input type="hidden" name="dir" value="<?php echo $_['dir'] ?>" id="dir">
|
||||
<input type="hidden" name="downloadURL" value="<?php echo $_['downloadURL'] ?>" id="downloadURL">
|
||||
<input type="hidden" name="filename" value="<?php echo $_['filename'] ?>" id="filename">
|
||||
<input type="hidden" name="mimetype" value="<?php echo $_['mimetype'] ?>" id="mimetype">
|
||||
<div id="preview">
|
||||
<p><?php echo $_['owner']; ?> shared the file <?php echo $_['name'] ?> with you</p>
|
||||
</div>
|
||||
<div id="content">
|
||||
<?php if (substr($_['mimetype'], 0 , strpos($_['mimetype'], '/')) == 'image'): ?>
|
||||
<img src="<?php echo $_['downloadURL']; ?>" />
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<a href="<?php echo $_['downloadURL']; ?>">Download</a>
|
|
@ -29,6 +29,16 @@ function t(app,text){
|
|||
}
|
||||
t.cache={};
|
||||
|
||||
/**
|
||||
* Get the path to download a file
|
||||
* @param file The filename
|
||||
* @param dir The directory the file is in - e.g. $('#dir').val()
|
||||
* @return string
|
||||
*/
|
||||
function fileDownloadPath(dir, file) {
|
||||
return OC.filePath('files', 'ajax', 'download.php')+encodeURIComponent('?files='+encodeURIComponent(file)+'&dir='+encodeURIComponent(dir));
|
||||
}
|
||||
|
||||
OC={
|
||||
webroot:oc_webroot,
|
||||
appswebroots:oc_appswebroots,
|
||||
|
|
|
@ -100,6 +100,17 @@ class OC_Helper {
|
|||
return self::linkToAbsolute( '', 'remote.php') . '/' . $service . (($add_slash && $service[strlen($service)-1]!='/')?'/':'');
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates an absolute url for public use
|
||||
* @param $service id
|
||||
* @returns the url
|
||||
*
|
||||
* Returns a absolute url to the given service.
|
||||
*/
|
||||
public static function linkToPublic($service, $add_slash = false) {
|
||||
return self::linkToAbsolute( '', 'public.php') . '?service=' . $service . (($add_slash && $service[strlen($service)-1]!='/')?'/':'');
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates path to an image
|
||||
* @param $app app
|
||||
|
|
|
@ -32,7 +32,7 @@ class Share {
|
|||
|
||||
const SHARE_TYPE_USER = 0;
|
||||
const SHARE_TYPE_GROUP = 1;
|
||||
const SHARE_TYPE_PRIVATE_LINK = 3;
|
||||
const SHARE_TYPE_LINK = 3;
|
||||
const SHARE_TYPE_EMAIL = 4;
|
||||
const SHARE_TYPE_CONTACT = 5;
|
||||
const SHARE_TYPE_REMOTE = 6;
|
||||
|
@ -112,6 +112,17 @@ class Share {
|
|||
return self::getItems($itemType, $itemSource, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format, $parameters, 1, $includeCollections, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the item of item type shared by a link
|
||||
* @param string Item type
|
||||
* @param string Item source
|
||||
* @param string Owner of link
|
||||
* @return Item
|
||||
*/
|
||||
public static function getItemSharedWithByLink($itemType, $itemSource, $uidOwner) {
|
||||
return self::getItems($itemType, $itemSource, self::SHARE_TYPE_LINK, null, $uidOwner, self::FORMAT_NONE, null, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the shared items of item type owned by the current user
|
||||
* @param string Item type
|
||||
|
@ -138,7 +149,7 @@ class Share {
|
|||
* @brief Share an item with a user, group, or via private link
|
||||
* @param string Item type
|
||||
* @param string Item source
|
||||
* @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_PRIVATE_LINK
|
||||
* @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
|
||||
* @param string User or group the item is being shared with
|
||||
* @param int CRUDS permissions
|
||||
* @return bool Returns true on success or false on failure
|
||||
|
@ -198,8 +209,13 @@ class Share {
|
|||
$shareWith = array();
|
||||
$shareWith['group'] = $group;
|
||||
$shareWith['users'] = array_diff(\OC_Group::usersInGroup($group), array($uidOwner));
|
||||
} else if ($shareType === self::SHARE_TYPE_PRIVATE_LINK) {
|
||||
$shareWith = md5(uniqid($itemSource, true));
|
||||
} else if ($shareType === self::SHARE_TYPE_LINK) {
|
||||
// Generate hash of password - same method as user passwords
|
||||
if (isset($shareWith)) {
|
||||
$forcePortable = (CRYPT_BLOWFISH != 1);
|
||||
$hasher = new \PasswordHash(8, $forcePortable);
|
||||
$shareWith = $hasher->HashPassword($shareWith.\OC_Config::getValue('passwordsalt', ''));
|
||||
}
|
||||
return self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions);
|
||||
} else if ($shareType === self::SHARE_TYPE_CONTACT) {
|
||||
if (!\OC_App::isEnabled('contacts')) {
|
||||
|
@ -262,7 +278,7 @@ class Share {
|
|||
* @brief Unshare an item from a user, group, or delete a private link
|
||||
* @param string Item type
|
||||
* @param string Item source
|
||||
* @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_PRIVATE_LINK
|
||||
* @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
|
||||
* @param string User or group the item is being shared with
|
||||
* @return Returns true on success or false on failure
|
||||
*/
|
||||
|
@ -298,7 +314,7 @@ class Share {
|
|||
* @brief Set the permissions of an item for a specific user or group
|
||||
* @param string Item type
|
||||
* @param string Item source
|
||||
* @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_PRIVATE_LINK
|
||||
* @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
|
||||
* @param string User or group the item is being shared with
|
||||
* @param int CRUDS permissions
|
||||
* @return Returns true on success or false on failure
|
||||
|
@ -407,7 +423,7 @@ class Share {
|
|||
* @brief Get shared items from the database
|
||||
* @param string Item type
|
||||
* @param string Item source or target (optional)
|
||||
* @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, SHARE_TYPE_PRIVATE_LINK, $shareTypeUserAndGroups, or $shareTypeGroupUserUnique
|
||||
* @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, SHARE_TYPE_LINK, $shareTypeUserAndGroups, or $shareTypeGroupUserUnique
|
||||
* @param string User or group the item is being shared with
|
||||
* @param string User that is the owner of shared items (optional)
|
||||
* @param int Format to convert items to with formatItems()
|
||||
|
@ -444,9 +460,9 @@ class Share {
|
|||
$queryArgs = array($itemType);
|
||||
}
|
||||
}
|
||||
if (isset($shareType) && isset($shareWith)) {
|
||||
if (isset($shareType)) {
|
||||
// Include all user and group items
|
||||
if ($shareType == self::$shareTypeUserAndGroups) {
|
||||
if ($shareType == self::$shareTypeUserAndGroups && isset($shareWith)) {
|
||||
$where .= ' AND `share_type` IN (?,?,?)';
|
||||
$queryArgs[] = self::SHARE_TYPE_USER;
|
||||
$queryArgs[] = self::SHARE_TYPE_GROUP;
|
||||
|
@ -459,11 +475,14 @@ class Share {
|
|||
$where .= ' AND `uid_owner` != ?';
|
||||
$queryArgs[] = $shareWith;
|
||||
} else {
|
||||
$where .= ' AND `share_type` = ? AND `share_with` = ?';
|
||||
$where .= ' AND `share_type` = ?';
|
||||
$queryArgs[] = $shareType;
|
||||
if (isset($shareWith)) {
|
||||
$where .= ' AND `share_with` = ?';
|
||||
$queryArgs[] = $shareWith;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($uidOwner)) {
|
||||
$where .= ' AND `uid_owner` = ?';
|
||||
$queryArgs[] = $uidOwner;
|
||||
|
@ -650,7 +669,7 @@ class Share {
|
|||
$column = 'path';
|
||||
}
|
||||
foreach ($items as $item) {
|
||||
if ($item['share_type'] == self::SHARE_TYPE_PRIVATE_LINK) {
|
||||
if ($item['share_type'] == self::SHARE_TYPE_LINK) {
|
||||
$statuses[$item[$column]] = true;
|
||||
} else if (!isset($statuses[$item[$column]])) {
|
||||
$statuses[$item[$column]] = false;
|
||||
|
@ -670,7 +689,7 @@ class Share {
|
|||
* @brief Put shared item into the database
|
||||
* @param string Item type
|
||||
* @param string Item source
|
||||
* @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_PRIVATE_LINK
|
||||
* @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
|
||||
* @param string User or group the item is being shared with
|
||||
* @param int CRUDS permissions
|
||||
* @param bool|array Parent folder target (optional)
|
||||
|
@ -827,7 +846,7 @@ class Share {
|
|||
* @brief Generate a unique target for the item
|
||||
* @param string Item type
|
||||
* @param string Item source
|
||||
* @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_PRIVATE_LINK
|
||||
* @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
|
||||
* @param string User or group the item is being shared with
|
||||
* @return string Item target
|
||||
*
|
||||
|
@ -836,7 +855,7 @@ class Share {
|
|||
*/
|
||||
private static function generateTarget($itemType, $itemSource, $shareType, $shareWith, $uidOwner) {
|
||||
$backend = self::getBackend($itemType);
|
||||
if ($shareType == self::SHARE_TYPE_PRIVATE_LINK) {
|
||||
if ($shareType == self::SHARE_TYPE_LINK) {
|
||||
return $backend->generateTarget($itemSource, false);
|
||||
} else {
|
||||
if ($itemType == 'file' || $itemType == 'folder') {
|
||||
|
|
|
@ -144,6 +144,17 @@ class Util {
|
|||
return(\OC_Helper::linkToRemote( $service ));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates an absolute url for public use
|
||||
* @param $service id
|
||||
* @returns the url
|
||||
*
|
||||
* Returns a absolute url to the given app and file.
|
||||
*/
|
||||
public static function linkToPublic($service) {
|
||||
return \OC_Helper::linkToPublic($service);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Creates an url
|
||||
|
|
Loading…
Reference in a new issue