When you delete something in /cloud stay in the right folder.

When you deleted a file in /cloud you was always jumped back to /cloud/[channel],
now you will stay in the parent folder.
Some more doxygen documentation.
Removed duplicate data from logging output and reduced logging in RedDAV in general.
This commit is contained in:
Klaus Weidenbach 2014-10-14 00:08:55 +02:00
parent 1eefed0333
commit bc2ad74813
7 changed files with 248 additions and 197 deletions

View File

@ -46,7 +46,7 @@ class RedBasicAuth extends DAV\Auth\Backend\AbstractBasic {
/** /**
* *
* @see RedBrowser::set_writeable() * @see RedBrowser::set_writeable()
* @var DAV\Browser\Plugin * @var \Sabre\DAV\Browser\Plugin
*/ */
public $browser; public $browser;
/** /**
@ -85,7 +85,7 @@ class RedBasicAuth extends DAV\Auth\Backend\AbstractBasic {
*/ */
protected function validateUserPass($username, $password) { protected function validateUserPass($username, $password) {
if (trim($password) === '+++') { if (trim($password) === '+++') {
logger('(DAV): RedBasicAuth::validateUserPass(): guest ' . $username); logger('guest: ' . $username);
return true; return true;
} }
@ -112,13 +112,14 @@ class RedBasicAuth extends DAV\Auth\Backend\AbstractBasic {
foreach ($x as $record) { foreach ($x as $record) {
if (($record['account_flags'] == ACCOUNT_OK) || ($record['account_flags'] == ACCOUNT_UNVERIFIED) if (($record['account_flags'] == ACCOUNT_OK) || ($record['account_flags'] == ACCOUNT_UNVERIFIED)
&& (hash('whirlpool', $record['account_salt'] . $password) === $record['account_password'])) { && (hash('whirlpool', $record['account_salt'] . $password) === $record['account_password'])) {
logger('(DAV) RedBasicAuth: password verified for ' . $username); logger('password verified for ' . $username);
return $this->setAuthenticated($r[0]); return $this->setAuthenticated($r[0]);
} }
} }
} }
} }
logger('(DAV) RedBasicAuth: password failed for ' . $username); logger('password failed for ' . $username);
// @TODO add security logger
return false; return false;
} }
@ -186,23 +187,23 @@ class RedBasicAuth extends DAV\Auth\Backend\AbstractBasic {
* @brief Set browser plugin for SabreDAV. * @brief Set browser plugin for SabreDAV.
* *
* @see RedBrowser::set_writeable() * @see RedBrowser::set_writeable()
* @param DAV\Browser\Plugin $browser * @param \Sabre\DAV\Browser\Plugin $browser
*/ */
public function setBrowserPlugin($browser) { public function setBrowserPlugin($browser) {
$this->browser = $browser; $this->browser = $browser;
} }
/** /**
* Prints out all RedBasicAuth variables to logger(). * @brief Prints out all RedBasicAuth variables to logger().
* *
* @return void * @return void
*/ */
public function log() { public function log() {
logger('dav: auth: channel_name ' . $this->channel_name, LOGGER_DATA); logger('channel_name ' . $this->channel_name, LOGGER_DATA);
logger('dav: auth: channel_id ' . $this->channel_id, LOGGER_DATA); logger('channel_id ' . $this->channel_id, LOGGER_DATA);
logger('dav: auth: channel_hash ' . $this->channel_hash, LOGGER_DATA); logger('channel_hash ' . $this->channel_hash, LOGGER_DATA);
logger('dav: auth: observer ' . $this->observer, LOGGER_DATA); logger('observer ' . $this->observer, LOGGER_DATA);
logger('dav: auth: owner_id ' . $this->owner_id, LOGGER_DATA); logger('owner_id ' . $this->owner_id, LOGGER_DATA);
logger('dav: auth: owner_nick ' . $this->owner_nick, LOGGER_DATA); logger('owner_nick ' . $this->owner_nick, LOGGER_DATA);
} }
} }

View File

@ -262,6 +262,14 @@ class RedBrowser extends DAV\Browser\Plugin {
construct_page(get_app()); construct_page(get_app());
} }
/**
* @brief Returns a human readable formatted string for filesizes.
*
* Don't we need such a functionality in other places, too?
*
* @param int $size filesize in bytes
* @return string
*/
function userReadableSize($size) { function userReadableSize($size) {
$ret = ""; $ret = "";
if (is_numeric($size)) { if (is_numeric($size)) {

View File

@ -49,7 +49,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
* @param RedBasicAuth &$auth_plugin * @param RedBasicAuth &$auth_plugin
*/ */
public function __construct($ext_path, &$auth_plugin) { public function __construct($ext_path, &$auth_plugin) {
logger('RedDirectory::__construct() ' . $ext_path, LOGGER_DATA); //logger('directory ' . $ext_path, LOGGER_DATA);
$this->ext_path = $ext_path; $this->ext_path = $ext_path;
// remove "/cloud" from the beginning of the path // remove "/cloud" from the beginning of the path
$this->red_path = ((strpos($ext_path, '/cloud') === 0) ? substr($ext_path, 6) : $ext_path); $this->red_path = ((strpos($ext_path, '/cloud') === 0) ? substr($ext_path, 6) : $ext_path);
@ -66,19 +66,19 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
} }
private function log() { private function log() {
logger('RedDirectory::log() ext_path ' . $this->ext_path, LOGGER_DATA); logger('ext_path ' . $this->ext_path, LOGGER_DATA);
logger('RedDirectory::log() os_path ' . $this->os_path, LOGGER_DATA); logger('os_path ' . $this->os_path, LOGGER_DATA);
logger('RedDirectory::log() red_path ' . $this->red_path, LOGGER_DATA); logger('red_path ' . $this->red_path, LOGGER_DATA);
} }
/** /**
* @brief Returns an array with all the child nodes. * @brief Returns an array with all the child nodes.
* *
* @throws DAV\Exception\Forbidden * @throw \Sabre\DAV\Exception\Forbidden
* @return array DAV\INode[] * @return array \Sabre\DAV\INode[]
*/ */
public function getChildren() { public function getChildren() {
logger('RedDirectory::getChildren() called for ' . $this->ext_path, LOGGER_DATA); //logger('children for ' . $this->ext_path, LOGGER_DATA);
$this->log(); $this->log();
if (get_config('system', 'block_public') && (! $this->auth->channel_id) && (! $this->auth->observer)) { if (get_config('system', 'block_public') && (! $this->auth->channel_id) && (! $this->auth->observer)) {
@ -97,12 +97,12 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
* @brief Returns a child by name. * @brief Returns a child by name.
* *
* *
* @throw DAV\Exception\Forbidden * @throw \Sabre\DAV\Exception\Forbidden
* @throw DAV\Exception\NotFound * @throw \Sabre\DAV\Exception\NotFound
* @param string $name * @param string $name
*/ */
public function getChild($name) { public function getChild($name) {
logger('RedDirectory::getChild(): ' . $name, LOGGER_DATA); logger($name, LOGGER_DATA);
if (get_config('system', 'block_public') && (! $this->auth->channel_id) && (! $this->auth->observer)) { if (get_config('system', 'block_public') && (! $this->auth->channel_id) && (! $this->auth->observer)) {
throw new DAV\Exception\Forbidden('Permission denied.'); throw new DAV\Exception\Forbidden('Permission denied.');
@ -130,7 +130,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
* @return string * @return string
*/ */
public function getName() { public function getName() {
logger('RedDirectory::getName() returns: ' . basename($this->red_path), LOGGER_DATA); //logger(basename($this->red_path), LOGGER_DATA);
return (basename($this->red_path)); return (basename($this->red_path));
} }
@ -139,20 +139,20 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
* *
* @todo handle duplicate directory name * @todo handle duplicate directory name
* *
* @throw DAV\Exception\Forbidden * @throw \Sabre\DAV\Exception\Forbidden
* @param string $name The new name of the directory. * @param string $name The new name of the directory.
* @return void * @return void
*/ */
public function setName($name) { public function setName($name) {
logger('RedDirectory::setName(): ' . basename($this->red_path) . ' -> ' . $name, LOGGER_DATA); logger('old name ' . basename($this->red_path) . ' -> ' . $name, LOGGER_DATA);
if ((! $name) || (! $this->auth->owner_id)) { if ((! $name) || (! $this->auth->owner_id)) {
logger('RedDirectory::setName(): permission denied'); logger('permission denied ' . $name);
throw new DAV\Exception\Forbidden('Permission denied.'); throw new DAV\Exception\Forbidden('Permission denied.');
} }
if (! perm_is_allowed($this->auth->owner_id, $this->auth->observer, 'write_storage')) { if (! perm_is_allowed($this->auth->owner_id, $this->auth->observer, 'write_storage')) {
logger('RedDirectory::setName(): permission denied'); logger('permission denied '. $name);
throw new DAV\Exception\Forbidden('Permission denied.'); throw new DAV\Exception\Forbidden('Permission denied.');
} }
@ -177,21 +177,21 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
* After successful creation of the file, you may choose to return the ETag * After successful creation of the file, you may choose to return the ETag
* of the new file here. * of the new file here.
* *
* @throws DAV\Exception\Forbidden * @throw \Sabre\DAV\Exception\Forbidden
* @param string $name Name of the file * @param string $name Name of the file
* @param resource|string $data Initial payload * @param resource|string $data Initial payload
* @return null|string ETag * @return null|string ETag
*/ */
public function createFile($name, $data = null) { public function createFile($name, $data = null) {
logger('RedDirectory::createFile(): ' . $name, LOGGER_DATA); logger($name, LOGGER_DEBUG);
if (! $this->auth->owner_id) { if (! $this->auth->owner_id) {
logger('RedDirectory::createFile(): permission denied'); logger('permission denied ' . $name);
throw new DAV\Exception\Forbidden('Permission denied.'); throw new DAV\Exception\Forbidden('Permission denied.');
} }
if (! perm_is_allowed($this->auth->owner_id, $this->auth->observer, 'write_storage')) { if (! perm_is_allowed($this->auth->owner_id, $this->auth->observer, 'write_storage')) {
logger('RedDirectory::createFile(): permission denied'); logger('permission denied ' . $name);
throw new DAV\Exception\Forbidden('Permission denied.'); throw new DAV\Exception\Forbidden('Permission denied.');
} }
@ -203,7 +203,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
); );
if (! $c) { if (! $c) {
logger('RedDirectory::createFile(): no channel'); logger('no channel');
throw new DAV\Exception\Forbidden('Permission denied.'); throw new DAV\Exception\Forbidden('Permission denied.');
} }
@ -237,7 +237,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
$size = file_put_contents($f, $data); $size = file_put_contents($f, $data);
// delete attach entry if file_put_contents() failed // delete attach entry if file_put_contents() failed
if ($size === false) { if ($size === false) {
logger('RedDirectory::createFile(): file_put_contents() failed for ' . $name, LOGGER_DEBUG); logger('file_put_contents() failed to ' . $f);
attach_delete($c[0]['channel_id'], $hash); attach_delete($c[0]['channel_id'], $hash);
return; return;
} }
@ -273,7 +273,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
intval($c[0]['channel_account_id']) intval($c[0]['channel_account_id'])
); );
if (($x) && ($x[0]['total'] + $size > $limit)) { if (($x) && ($x[0]['total'] + $size > $limit)) {
logger('reddav: service class limit exceeded for ' . $c[0]['channel_name'] . ' total usage is ' . $x[0]['total'] . ' limit is ' . $limit); logger('service class limit exceeded for ' . $c[0]['channel_name'] . ' total usage is ' . $x[0]['total'] . ' limit is ' . $limit);
attach_delete($c[0]['channel_id'], $hash); attach_delete($c[0]['channel_id'], $hash);
return; return;
} }
@ -287,7 +287,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
* @return void * @return void
*/ */
public function createDirectory($name) { public function createDirectory($name) {
logger('RedDirectory::createDirectory(): ' . $name, LOGGER_DEBUG); logger($name, LOGGER_DEBUG);
if ((! $this->auth->owner_id) || (! perm_is_allowed($this->auth->owner_id, $this->auth->observer, 'write_storage'))) { if ((! $this->auth->owner_id) || (! perm_is_allowed($this->auth->owner_id, $this->auth->observer, 'write_storage'))) {
throw new DAV\Exception\Forbidden('Permission denied.'); throw new DAV\Exception\Forbidden('Permission denied.');
@ -301,7 +301,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
if ($r) { if ($r) {
$result = attach_mkdir($r[0], $this->auth->observer, array('filename' => $name, 'folder' => $this->folder_hash)); $result = attach_mkdir($r[0], $this->auth->observer, array('filename' => $name, 'folder' => $this->folder_hash));
if (! $result['success']) { if (! $result['success']) {
logger('RedDirectory::createDirectory(): ' . print_r($result, true), LOGGER_DEBUG); logger('error ' . print_r($result, true), LOGGER_DEBUG);
} }
} }
} }
@ -310,31 +310,33 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
* @brief Checks if a child exists. * @brief Checks if a child exists.
* *
* @param string $name * @param string $name
* The name to check if it exists.
* @return boolean * @return boolean
*/ */
public function childExists($name) { public function childExists($name) {
// On /cloud we show a list of available channels. // On /cloud we show a list of available channels.
// @todo what happens if no channels are available? // @todo what happens if no channels are available?
if ($this->red_path === '/' && $name === 'cloud') { if ($this->red_path === '/' && $name === 'cloud') {
logger('RedDirectory::childExists() /cloud: true', LOGGER_DATA); //logger('We are at /cloud show a channel list', LOGGER_DEBUG);
return true; return true;
} }
$x = RedFileData($this->ext_path . '/' . $name, $this->auth, true); $x = RedFileData($this->ext_path . '/' . $name, $this->auth, true);
logger('RedFileData returns: ' . print_r($x, true), LOGGER_DATA); //logger('RedFileData returns: ' . print_r($x, true), LOGGER_DATA);
if ($x) if ($x)
return true; return true;
return false; return false;
} }
/** /**
* @todo add description of what this function does. * @todo add description of what this function does.
* *
* @throw DAV\Exception\NotFound * @throw \Sabre\DAV\Exception\NotFound
* @return void * @return void
*/ */
function getDir() { function getDir() {
logger('RedDirectory::getDir(): ' . $this->ext_path, LOGGER_DEBUG); //logger($this->ext_path, LOGGER_DEBUG);
$this->auth->log(); $this->auth->log();
$file = $this->ext_path; $file = $this->ext_path;
@ -356,7 +358,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
if (! $path_arr) if (! $path_arr)
return; return;
logger('RedDirectory::getDir(): path: ' . print_r($path_arr, true), LOGGER_DATA); logger('paths: ' . print_r($path_arr, true), LOGGER_DATA);
$channel_name = $path_arr[0]; $channel_name = $path_arr[0];
@ -367,7 +369,6 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
if (! $r) { if (! $r) {
throw new DAV\Exception\NotFound('The file with name: ' . $channel_name . ' could not be found.'); throw new DAV\Exception\NotFound('The file with name: ' . $channel_name . ' could not be found.');
return;
} }
$channel_id = $r[0]['channel_id']; $channel_id = $r[0]['channel_id'];
@ -397,7 +398,6 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
} }
$this->folder_hash = $folder; $this->folder_hash = $folder;
$this->os_path = $os_path; $this->os_path = $os_path;
return;
} }
/** /**
@ -429,7 +429,8 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
/** /**
* @brief Return quota usage. * @brief Return quota usage.
* *
* Do guests relly see the used/free values from filesystem of the complete store directory? * @fixme Should guests relly see the used/free values from filesystem of the
* complete store directory?
* *
* @return array with used and free values in bytes. * @return array with used and free values in bytes.
*/ */

View File

@ -49,7 +49,7 @@ class RedFile extends DAV\Node implements DAV\IFile {
$this->data = $data; $this->data = $data;
$this->auth = $auth; $this->auth = $auth;
logger('RedFile::__construct(): ' . print_r($this->data, true), LOGGER_DATA); //logger(print_r($this->data, true), LOGGER_DATA);
} }
/** /**
@ -58,7 +58,7 @@ class RedFile extends DAV\Node implements DAV\IFile {
* @return string * @return string
*/ */
public function getName() { public function getName() {
logger('RedFile::getName(): ' . basename($this->name), LOGGER_DEBUG); //logger(basename($this->name), LOGGER_DATA);
return basename($this->name); return basename($this->name);
} }
@ -70,9 +70,10 @@ class RedFile extends DAV\Node implements DAV\IFile {
* @return void * @return void
*/ */
public function setName($newName) { public function setName($newName) {
logger('RedFile::setName(): ' . basename($this->name) . ' -> ' . $newName, LOGGER_DEBUG); logger('old name ' . basename($this->name) . ' -> ' . $newName, LOGGER_DATA);
if ((! $newName) || (! $this->auth->owner_id) || (! perm_is_allowed($this->auth->owner_id, $this->auth->observer, 'write_storage'))) { if ((! $newName) || (! $this->auth->owner_id) || (! perm_is_allowed($this->auth->owner_id, $this->auth->observer, 'write_storage'))) {
logger('permission denied '. $newName);
throw new DAV\Exception\Forbidden('Permission denied.'); throw new DAV\Exception\Forbidden('Permission denied.');
} }
@ -91,7 +92,7 @@ class RedFile extends DAV\Node implements DAV\IFile {
* @return void * @return void
*/ */
public function put($data) { public function put($data) {
logger('RedFile::put(): ' . basename($this->name), LOGGER_DEBUG); logger('put file: ' . basename($this->name), LOGGER_DEBUG);
$size = 0; $size = 0;
// @todo only 3 values are needed // @todo only 3 values are needed
@ -110,7 +111,7 @@ class RedFile extends DAV\Node implements DAV\IFile {
// @todo check return value and set $size directly // @todo check return value and set $size directly
@file_put_contents($f, $data); @file_put_contents($f, $data);
$size = @filesize($f); $size = @filesize($f);
logger('RedFile::put(): filename: ' . $f . ' size: ' . $size, LOGGER_DEBUG); logger('filename: ' . $f . ' size: ' . $size, LOGGER_DEBUG);
} else { } else {
$r = q("UPDATE attach SET data = '%s' WHERE hash = '%s' AND uid = %d LIMIT 1", $r = q("UPDATE attach SET data = '%s' WHERE hash = '%s' AND uid = %d LIMIT 1",
dbesc(stream_get_contents($data)), dbesc(stream_get_contents($data)),
@ -161,7 +162,7 @@ class RedFile extends DAV\Node implements DAV\IFile {
intval($c[0]['channel_account_id']) intval($c[0]['channel_account_id'])
); );
if (($x) && ($x[0]['total'] + $size > $limit)) { if (($x) && ($x[0]['total'] + $size > $limit)) {
logger('RedFile::put(): service class limit exceeded for ' . $c[0]['channel_name'] . ' total usage is ' . $x[0]['total'] . ' limit is ' . $limit); logger('service class limit exceeded for ' . $c[0]['channel_name'] . ' total usage is ' . $x[0]['total'] . ' limit is ' . $limit);
attach_delete($c[0]['channel_id'], $this->data['hash']); attach_delete($c[0]['channel_id'], $this->data['hash']);
return; return;
} }
@ -174,7 +175,7 @@ class RedFile extends DAV\Node implements DAV\IFile {
* @return string * @return string
*/ */
public function get() { public function get() {
logger('RedFile::get(): ' . basename($this->name), LOGGER_DEBUG); logger('get file ' . basename($this->name), LOGGER_DEBUG);
$r = q("SELECT data, flags, filename, filetype FROM attach WHERE hash = '%s' AND uid = %d LIMIT 1", $r = q("SELECT data, flags, filename, filetype FROM attach WHERE hash = '%s' AND uid = %d LIMIT 1",
dbesc($this->data['hash']), dbesc($this->data['hash']),
@ -206,7 +207,7 @@ class RedFile extends DAV\Node implements DAV\IFile {
* *
* Return null if the ETag can not effectively be determined. * Return null if the ETag can not effectively be determined.
* *
* @return mixed * @return null|string
*/ */
public function getETag() { public function getETag() {
$ret = null; $ret = null;
@ -236,6 +237,7 @@ class RedFile extends DAV\Node implements DAV\IFile {
* @brief Returns the size of the node, in bytes. * @brief Returns the size of the node, in bytes.
* *
* @return int * @return int
* filesize in bytes
*/ */
public function getSize() { public function getSize() {
return $this->data['filesize']; return $this->data['filesize'];
@ -254,11 +256,13 @@ class RedFile extends DAV\Node implements DAV\IFile {
/** /**
* @brief Delete the file. * @brief Delete the file.
* *
* @throw Sabre\DAV\Exception\Forbidden * This method checks the permissions and then calls attach_delete() function
* @return void * to actually remove the file.
*
* @throw \Sabre\DAV\Exception\Forbidden
*/ */
public function delete() { public function delete() {
logger('RedFile::delete(): ' . basename($this->name), LOGGER_DEBUG); logger('delete file ' . basename($this->name), LOGGER_DEBUG);
if ((! $this->auth->owner_id) || (! perm_is_allowed($this->auth->owner_id, $this->auth->observer, 'write_storage'))) { if ((! $this->auth->owner_id) || (! perm_is_allowed($this->auth->owner_id, $this->auth->observer, 'write_storage'))) {
throw new DAV\Exception\Forbidden('Permission denied.'); throw new DAV\Exception\Forbidden('Permission denied.');

View File

@ -78,7 +78,6 @@ function z_mime_content_type($filename) {
'xls' => 'application/vnd.ms-excel', 'xls' => 'application/vnd.ms-excel',
'ppt' => 'application/vnd.ms-powerpoint', 'ppt' => 'application/vnd.ms-powerpoint',
// open office // open office
'odt' => 'application/vnd.oasis.opendocument.text', 'odt' => 'application/vnd.oasis.opendocument.text',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet', 'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
@ -93,10 +92,8 @@ function z_mime_content_type($filename) {
} }
return 'application/octet-stream'; return 'application/octet-stream';
} }
/** /**
* @brief Count files/attachments. * @brief Count files/attachments.
* *
@ -138,8 +135,8 @@ function attach_count_files($channel_id, $observer, $hash = '', $filename = '',
$ret['success'] = ((is_array($r)) ? true : false); $ret['success'] = ((is_array($r)) ? true : false);
$ret['results'] = ((is_array($r)) ? count($r) : false); $ret['results'] = ((is_array($r)) ? count($r) : false);
return $ret;
return $ret;
} }
/** /**
@ -190,8 +187,8 @@ function attach_list_files($channel_id, $observer, $hash = '', $filename = '', $
$ret['success'] = ((is_array($r)) ? true : false); $ret['success'] = ((is_array($r)) ? true : false);
$ret['results'] = ((is_array($r)) ? $r : false); $ret['results'] = ((is_array($r)) ? $r : false);
return $ret;
return $ret;
} }
/** /**
@ -246,8 +243,8 @@ function attach_by_hash($hash, $rev = 0) {
$ret['success'] = true; $ret['success'] = true;
$ret['data'] = $r[0]; $ret['data'] = $r[0];
return $ret;
return $ret;
} }
/** /**
@ -301,7 +298,6 @@ function attach_by_hash_nodata($hash, $rev = 0) {
$ret['success'] = true; $ret['success'] = true;
$ret['data'] = $r[0]; $ret['data'] = $r[0];
return $ret; return $ret;
} }
/** /**
@ -400,6 +396,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
if(! isset($hash)) if(! isset($hash))
$hash = random_string(); $hash = random_string();
$created = datetime_convert(); $created = datetime_convert();
if($options === 'replace') { if($options === 'replace') {
@ -490,6 +487,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
$ret['success'] = true; $ret['success'] = true;
$ret['data'] = $r[0]; $ret['data'] = $r[0];
return $ret; return $ret;
} }
@ -507,8 +505,8 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
* $ret['data'] = array of attach DB entries without data component * $ret['data'] = array of attach DB entries without data component
*/ */
function z_readdir($channel_id, $observer_hash, $pathname, $parent_hash = '') { function z_readdir($channel_id, $observer_hash, $pathname, $parent_hash = '') {
$ret = array('success' => false); $ret = array('success' => false);
if(! perm_is_allowed($r[0]['uid'], get_observer_hash(), 'view_storage')) { if(! perm_is_allowed($r[0]['uid'], get_observer_hash(), 'view_storage')) {
$ret['message'] = t('Permission denied.'); $ret['message'] = t('Permission denied.');
return $ret; return $ret;
@ -547,6 +545,7 @@ function z_readdir($channel_id, $observer_hash, $pathname, $parent_hash = '') {
} }
$ret['success'] = true; $ret['success'] = true;
$ret['data'] = $r; $ret['data'] = $r;
return $ret; return $ret;
} }
@ -686,7 +685,6 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
} }
return $ret; return $ret;
} }
/** /**
@ -732,15 +730,19 @@ function attach_change_permissions($channel_id, $resource, $allow_cid, $allow_gi
dbesc($resource), dbesc($resource),
intval($channel_id) intval($channel_id)
); );
return;
} }
/** /**
* @brief Delete a file/directory. * @brief Delete a file/directory from a channel.
*
* If the provided resource hash is from a directory it will delete everything
* recursively under this directory.
* *
* @param int $channel_id * @param int $channel_id
* @param string $resource a hash to delete * The id of the channel
* @param string $resource
* The hash to delete
* @return void
*/ */
function attach_delete($channel_id, $resource) { function attach_delete($channel_id, $resource) {
@ -760,7 +762,7 @@ function attach_delete($channel_id, $resource) {
// If resource is a directory delete everything in the directory recursive // If resource is a directory delete everything in the directory recursive
if($r[0]['flags'] & ATTACH_FLAG_DIR) { if($r[0]['flags'] & ATTACH_FLAG_DIR) {
$x = q("select hash, flags from attach where folder = '%s' and uid = %d", $x = q("SELECT hash, flags FROM attach WHERE folder = '%s' AND uid = %d",
dbesc($resource), dbesc($resource),
intval($channel_id) intval($channel_id)
); );
@ -799,19 +801,21 @@ function attach_delete($channel_id, $resource) {
dbesc($r[0]['folder']), dbesc($r[0]['folder']),
intval($channel_id) intval($channel_id)
); );
return;
} }
/** /**
* @brief Returns path to file in cloud/. * @brief Returns path to file in cloud/.
* *
* @param $arr * @param array
* @return string with the path the file to cloud/ * $arr[uid] int the channels uid
* $arr[folder] string
* $arr[filename]] string
* @return string
* path to the file in cloud/
*/ */
function get_cloudpath($arr) { function get_cloudpath($arr) {
$basepath = 'cloud/'; $basepath = 'cloud/';
if($arr['uid']) { if($arr['uid']) {
$r = q("select channel_address from channel where channel_id = %d limit 1", $r = q("select channel_address from channel where channel_id = %d limit 1",
intval($arr['uid']) intval($arr['uid'])
@ -823,7 +827,6 @@ function get_cloudpath($arr) {
$path = $basepath; $path = $basepath;
if($arr['folder']) { if($arr['folder']) {
$lpath = ''; $lpath = '';
$lfile = $arr['folder']; $lfile = $arr['folder'];
@ -846,56 +849,79 @@ function get_cloudpath($arr) {
$path .= $lpath; $path .= $lpath;
} }
$path .= $arr['filename']; $path .= $arr['filename'];
return $path; return $path;
} }
/** /**
* @brief Returns path to parent folder in cloud/. * @brief Returns path to parent folder in cloud/.
* *
* @param $arr * @param int $channel_id
* @return string with the folder path * The id of the channel
* @param string $channel_name
* The name of the channel
* @param string $attachHash
* @return string with the full folder path
*/ */
function get_parent_cloudpath($channel_id, $channel_name, $attachHash) { function get_parent_cloudpath($channel_id, $channel_name, $attachHash) {
//Build directory tree and redirect // build directory tree
$parentHash = $attachHash; $parentHash = $attachHash;
do { do {
$parentHash = find_folder_hash_by_attach_hash($channel_id, $parentHash); $parentHash = find_folder_hash_by_attach_hash($channel_id, $parentHash);
if ($parentHash) { if ($parentHash) {
$parentName = find_filename_by_hash($channel_id, $parentHash); $parentName = find_filename_by_hash($channel_id, $parentHash);
$parentFullPath = $parentName."/".$parentFullPath; $parentFullPath = $parentName . '/' . $parentFullPath;
} }
} while ($parentHash); } while ($parentHash);
$parentFullPath = z_root() . "/cloud/" . $channel_name . "/" . $parentFullPath; $parentFullPath = z_root() . '/cloud/' . $channel_name . '/' . $parentFullPath;
return $parentFullPath; return $parentFullPath;
} }
/**
* @brief Return the hash of an attachment's folder.
*
* @param int $channel_id
* The id of the channel
* @param string $attachHash
* The hash of the attachment
* @return string
*/
function find_folder_hash_by_attach_hash($channel_id, $attachHash) { function find_folder_hash_by_attach_hash($channel_id, $attachHash) {
$r = q("select * from attach where uid = %d and hash = '%s' limit 1", $r = q("SELECT folder FROM attach WHERE uid = %d AND hash = '%s' LIMIT 1",
intval($channel_id), dbesc($attachHash) intval($channel_id),
dbesc($attachHash)
); );
$hash = ""; $hash = '';
if ($r) { if ($r) {
foreach($r as $rr) { $hash = $r[0]['folder'];
$hash = $rr['folder'];
}
} }
return $hash; return $hash;
} }
/**
* @brief Returns the filename of an attachment in a given channel.
*
* @param mixed $channel_id
* The id of the channel
* @param mixed $attachHash
* The hash of the attachment
* @return string
* The filename of the attachment
*/
function find_filename_by_hash($channel_id, $attachHash) { function find_filename_by_hash($channel_id, $attachHash) {
$r = q("select * from attach where uid = %d and hash = '%s' limit 1", $r = q("SELECT filename FROM attach WHERE uid = %d AND hash = '%s' LIMIT 1",
intval($channel_id), dbesc($attachHash) intval($channel_id),
dbesc($attachHash)
); );
$filename = ""; $filename = '';
if ($r) { if ($r) {
foreach($r as $rr) { $filename = $r[0]['filename'];
$filename = $rr['filename'];
}
} }
return $filename; return $filename;
} }
/** /**
* *
* @param $in * @param $in

View File

@ -36,8 +36,8 @@ require_once('include/RedDAV/RedBasicAuth.php');
* @todo Is there any reason why this is not inside RedDirectory class? * @todo Is there any reason why this is not inside RedDirectory class?
* @fixme function name looks like a class name, should we rename it? * @fixme function name looks like a class name, should we rename it?
* *
* @param $auth * @param RedBasicAuth &$auth
* @return array containing RedDirectory objects * @return array RedDirectory[]
*/ */
function RedChannelList(&$auth) { function RedChannelList(&$auth) {
$ret = array(); $ret = array();
@ -50,7 +50,7 @@ function RedChannelList(&$auth) {
if ($r) { if ($r) {
foreach ($r as $rr) { foreach ($r as $rr) {
if (perm_is_allowed($rr['channel_id'], $auth->observer, 'view_storage')) { if (perm_is_allowed($rr['channel_id'], $auth->observer, 'view_storage')) {
logger('RedChannelList: ' . '/cloud/' . $rr['channel_address'], LOGGER_DATA); logger('found channel: /cloud/' . $rr['channel_address'], LOGGER_DEBUG);
// @todo can't we drop '/cloud'? It gets stripped off anyway in RedDirectory // @todo can't we drop '/cloud'? It gets stripped off anyway in RedDirectory
$ret[] = new RedDAV\RedDirectory('/cloud/' . $rr['channel_address'], $auth); $ret[] = new RedDAV\RedDirectory('/cloud/' . $rr['channel_address'], $auth);
} }
@ -70,8 +70,10 @@ function RedChannelList(&$auth) {
* @fixme function name looks like a class name, should we rename it? * @fixme function name looks like a class name, should we rename it?
* *
* @param string $file path to a directory * @param string $file path to a directory
* @param &$auth * @param RedBasicAuth &$auth
* @returns array DAV\INode[] * @returns null|array \Sabre\DAV\INode[]
* @throw \Sabre\DAV\Exception\Forbidden
* @throw \Sabre\DAV\Exception\NotFound
*/ */
function RedCollectionData($file, &$auth) { function RedCollectionData($file, &$auth) {
$ret = array(); $ret = array();
@ -150,7 +152,7 @@ function RedCollectionData($file, &$auth) {
// This should no longer be needed since we just returned errors for paths not found // This should no longer be needed since we just returned errors for paths not found
if ($path !== '/' . $file) { if ($path !== '/' . $file) {
logger("RedCollectionData: Path mismatch: $path !== /$file"); logger("Path mismatch: $path !== /$file");
return NULL; return NULL;
} }
@ -160,8 +162,7 @@ function RedCollectionData($file, &$auth) {
); );
foreach ($r as $rr) { foreach ($r as $rr) {
logger('RedCollectionData: filename: ' . $rr['filename'], LOGGER_DATA); //logger('filename: ' . $rr['filename'], LOGGER_DEBUG);
if ($rr['flags'] & ATTACH_FLAG_DIR) { if ($rr['flags'] & ATTACH_FLAG_DIR) {
// @todo can't we drop '/cloud'? it gets stripped off anyway in RedDirectory // @todo can't we drop '/cloud'? it gets stripped off anyway in RedDirectory
$ret[] = new RedDAV\RedDirectory('/cloud' . $path . '/' . $rr['filename'], $auth); $ret[] = new RedDAV\RedDirectory('/cloud' . $path . '/' . $rr['filename'], $auth);
@ -180,11 +181,14 @@ function RedCollectionData($file, &$auth) {
* @fixme function name looks like a class name, should we rename it? * @fixme function name looks like a class name, should we rename it?
* *
* @param string $file * @param string $file
* @param &$auth * path to file or directory
* @param RedBasicAuth &$auth
* @param boolean $test (optional) enable test mode * @param boolean $test (optional) enable test mode
* @return RedFile|RedDirectory|boolean|null
* @throw \Sabre\DAV\Exception\Forbidden
*/ */
function RedFileData($file, &$auth, $test = false) { function RedFileData($file, &$auth, $test = false) {
logger('RedFileData:' . $file . (($test) ? ' (test mode) ' : ''), LOGGER_DEBUG); logger($file . (($test) ? ' (test mode) ' : ''), LOGGER_DEBUG);
$x = strpos($file, '/cloud'); $x = strpos($file, '/cloud');
if ($x === 0) { if ($x === 0) {
@ -267,11 +271,11 @@ function RedFileData($file, &$auth, $test = false) {
} }
if ($errors) { if ($errors) {
logger('RedFileData: not found'); logger('not found ' . $file);
if ($test) if ($test)
return false; return false;
if ($permission_error) { if ($permission_error) {
logger('RedFileData: permission error'); logger('permission error ' . $file);
throw new DAV\Exception\Forbidden('Permission denied.'); throw new DAV\Exception\Forbidden('Permission denied.');
} }
return; return;

View File

@ -1,7 +1,15 @@
<?php <?php
/**
* @file mod/filestorage.php
*
*/
require_once('include/attach.php'); require_once('include/attach.php');
/**
*
* @param object &$a
*/
function filestorage_post(&$a) { function filestorage_post(&$a) {
$channel_id = ((x($_POST, 'uid')) ? intval($_POST['uid']) : 0); $channel_id = ((x($_POST, 'uid')) ? intval($_POST['uid']) : 0);
@ -69,7 +77,6 @@ function filestorage_content(&$a) {
return; return;
} }
if(argc() > 3 && argv(3) === 'delete') { if(argc() > 3 && argv(3) === 'delete') {
if(! $perms['write_storage']) { if(! $perms['write_storage']) {
notice( t('Permission denied.') . EOL); notice( t('Permission denied.') . EOL);
@ -77,7 +84,7 @@ function filestorage_content(&$a) {
} }
$file = intval(argv(2)); $file = intval(argv(2));
$r = q("select hash from attach where id = %d and uid = %d limit 1", $r = q("SELECT hash FROM attach WHERE id = %d AND uid = %d LIMIT 1",
dbesc($file), dbesc($file),
intval($owner) intval($owner)
); );
@ -86,12 +93,16 @@ function filestorage_content(&$a) {
goaway(z_root() . '/cloud/' . $which); goaway(z_root() . '/cloud/' . $which);
} }
attach_delete($owner,$r[0]['hash']); $f = $r[0];
$channel = $a->get_channel();
goaway(z_root() . '/cloud/' . $which); $parentpath = get_parent_cloudpath($channel['channel_id'], $channel['channel_address'], $f['hash']);
attach_delete($owner, $f['hash']);
goaway($parentpath);
} }
if(argc() > 3 && argv(3) === 'edit') { if(argc() > 3 && argv(3) === 'edit') {
require_once('include/acl_selectors.php'); require_once('include/acl_selectors.php');
if(! $perms['write_storage']) { if(! $perms['write_storage']) {
@ -106,7 +117,6 @@ function filestorage_content(&$a) {
); );
$f = $r[0]; $f = $r[0];
$channel = $a->get_channel(); $channel = $a->get_channel();
$cloudpath = get_cloudpath($f) . (($f['flags'] & ATTACH_FLAG_DIR) ? '?f=&davguest=1' : ''); $cloudpath = get_cloudpath($f) . (($f['flags'] & ATTACH_FLAG_DIR) ? '?f=&davguest=1' : '');
@ -117,7 +127,6 @@ function filestorage_content(&$a) {
$lockstate = (($f['allow_cid'] || $f['allow_gid'] || $f['deny_cid'] || $f['deny_gid']) ? 'lock' : 'unlock'); $lockstate = (($f['allow_cid'] || $f['allow_gid'] || $f['deny_cid'] || $f['deny_gid']) ? 'lock' : 'unlock');
$o = replace_macros(get_markup_template('attach_edit.tpl'), array( $o = replace_macros(get_markup_template('attach_edit.tpl'), array(
'$header' => t('Edit file permissions'), '$header' => t('Edit file permissions'),
'$file' => $f, '$file' => $f,
@ -135,12 +144,10 @@ function filestorage_content(&$a) {
'$cpdesc' => t('Copy/paste this code to attach file to a post'), '$cpdesc' => t('Copy/paste this code to attach file to a post'),
'$cpldesc' => t('Copy/paste this URL to link file from a web page'), '$cpldesc' => t('Copy/paste this URL to link file from a web page'),
'$submit' => t('Submit') '$submit' => t('Submit')
)); ));
return $o; return $o;
} }
goaway(z_root() . '/cloud/' . $which); goaway(z_root() . '/cloud/' . $which);
} }