diff options
-rwxr-xr-x | boot.php | 2 | ||||
-rw-r--r-- | doc/hidden_configs.bb | 3 | ||||
-rw-r--r-- | doc/install/sample-nginx.conf | 2 | ||||
-rw-r--r-- | include/RedDAV/RedBasicAuth.php | 25 | ||||
-rw-r--r-- | include/RedDAV/RedBrowser.php | 8 | ||||
-rw-r--r-- | include/RedDAV/RedDirectory.php | 67 | ||||
-rw-r--r-- | include/RedDAV/RedFile.php | 26 | ||||
-rw-r--r-- | include/attach.php | 244 | ||||
-rwxr-xr-x | include/diaspora.php | 11 | ||||
-rw-r--r-- | include/hubloc.php | 57 | ||||
-rw-r--r-- | include/identity.php | 7 | ||||
-rw-r--r-- | include/network.php | 2 | ||||
-rw-r--r-- | include/reddav.php | 34 | ||||
-rw-r--r-- | include/zot.php | 35 | ||||
-rw-r--r-- | install/update.php | 9 | ||||
-rw-r--r-- | mod/chanman.php | 31 | ||||
-rw-r--r-- | mod/filestorage.php | 47 | ||||
-rw-r--r-- | mod/import.php | 2 | ||||
-rw-r--r-- | mod/locs.php | 90 | ||||
-rw-r--r-- | mod/photos.php | 9 | ||||
-rw-r--r-- | version.inc | 2 | ||||
-rw-r--r-- | view/css/widgets.css | 7 | ||||
-rw-r--r-- | view/js/main.js | 1 | ||||
-rwxr-xr-x | view/tpl/group_side.tpl | 10 | ||||
-rwxr-xr-x | view/tpl/photo_item.tpl | 41 | ||||
-rwxr-xr-x | view/tpl/photo_view.tpl | 4 |
26 files changed, 493 insertions, 283 deletions
@@ -48,7 +48,7 @@ define ( 'RED_PLATFORM', 'redmatrix' ); define ( 'RED_VERSION', trim(file_get_contents('version.inc')) . 'R'); define ( 'ZOT_REVISION', 1 ); -define ( 'DB_UPDATE_VERSION', 1129 ); +define ( 'DB_UPDATE_VERSION', 1130 ); define ( 'EOL', '<br />' . "\r\n" ); define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' ); diff --git a/doc/hidden_configs.bb b/doc/hidden_configs.bb index 4ad38a499..0fc04b766 100644 --- a/doc/hidden_configs.bb +++ b/doc/hidden_configs.bb @@ -98,3 +98,6 @@ This document assumes you're an administrator. Logfile to use for logging auth errors. Used to plug in to server side software such as fail2ban. Auth failures are still logged to the main logs as well. + [b]system > hide_in_statistics[/b] + Tell the red statistics servers to completely hide this hub in hub lists. +
\ No newline at end of file diff --git a/doc/install/sample-nginx.conf b/doc/install/sample-nginx.conf index f53a3d5fb..dd3b63d3b 100644 --- a/doc/install/sample-nginx.conf +++ b/doc/install/sample-nginx.conf @@ -55,7 +55,7 @@ server { ssl_certificate /etc/nginx/ssl/red.example.net.chain.pem; ssl_certificate_key /etc/nginx/ssl/example.net.key; ssl_session_timeout 5m; - ssl_protocols SSLv3 TLSv1; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP; ssl_prefer_server_ciphers on; diff --git a/include/RedDAV/RedBasicAuth.php b/include/RedDAV/RedBasicAuth.php index c1da73da1..2f86d4f82 100644 --- a/include/RedDAV/RedBasicAuth.php +++ b/include/RedDAV/RedBasicAuth.php @@ -46,7 +46,7 @@ class RedBasicAuth extends DAV\Auth\Backend\AbstractBasic { /** * * @see RedBrowser::set_writeable() - * @var DAV\Browser\Plugin + * @var \Sabre\DAV\Browser\Plugin */ public $browser; /** @@ -85,7 +85,7 @@ class RedBasicAuth extends DAV\Auth\Backend\AbstractBasic { */ protected function validateUserPass($username, $password) { if (trim($password) === '+++') { - logger('(DAV): RedBasicAuth::validateUserPass(): guest ' . $username); + logger('guest: ' . $username); return true; } @@ -112,13 +112,14 @@ class RedBasicAuth extends DAV\Auth\Backend\AbstractBasic { foreach ($x as $record) { if (($record['account_flags'] == ACCOUNT_OK) || ($record['account_flags'] == ACCOUNT_UNVERIFIED) && (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]); } } } } - logger('(DAV) RedBasicAuth: password failed for ' . $username); + logger('password failed for ' . $username); + // @TODO add security logger return false; } @@ -186,23 +187,23 @@ class RedBasicAuth extends DAV\Auth\Backend\AbstractBasic { * @brief Set browser plugin for SabreDAV. * * @see RedBrowser::set_writeable() - * @param DAV\Browser\Plugin $browser + * @param \Sabre\DAV\Browser\Plugin $browser */ public function setBrowserPlugin($browser) { $this->browser = $browser; } /** - * Prints out all RedBasicAuth variables to logger(). + * @brief Prints out all RedBasicAuth variables to logger(). * * @return void */ public function log() { - logger('dav: auth: channel_name ' . $this->channel_name, LOGGER_DATA); - logger('dav: auth: channel_id ' . $this->channel_id, LOGGER_DATA); - logger('dav: auth: channel_hash ' . $this->channel_hash, LOGGER_DATA); - logger('dav: auth: observer ' . $this->observer, LOGGER_DATA); - logger('dav: auth: owner_id ' . $this->owner_id, LOGGER_DATA); - logger('dav: auth: owner_nick ' . $this->owner_nick, LOGGER_DATA); + logger('channel_name ' . $this->channel_name, LOGGER_DATA); + logger('channel_id ' . $this->channel_id, LOGGER_DATA); + logger('channel_hash ' . $this->channel_hash, LOGGER_DATA); + logger('observer ' . $this->observer, LOGGER_DATA); + logger('owner_id ' . $this->owner_id, LOGGER_DATA); + logger('owner_nick ' . $this->owner_nick, LOGGER_DATA); } }
\ No newline at end of file diff --git a/include/RedDAV/RedBrowser.php b/include/RedDAV/RedBrowser.php index 1f2550ac1..6ec5c978d 100644 --- a/include/RedDAV/RedBrowser.php +++ b/include/RedDAV/RedBrowser.php @@ -262,6 +262,14 @@ class RedBrowser extends DAV\Browser\Plugin { 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) { $ret = ""; if (is_numeric($size)) { diff --git a/include/RedDAV/RedDirectory.php b/include/RedDAV/RedDirectory.php index 72b0fe789..a46b77f5f 100644 --- a/include/RedDAV/RedDirectory.php +++ b/include/RedDAV/RedDirectory.php @@ -49,7 +49,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota { * @param RedBasicAuth &$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; // remove "/cloud" from the beginning of the 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() { - logger('RedDirectory::log() ext_path ' . $this->ext_path, LOGGER_DATA); - logger('RedDirectory::log() os_path ' . $this->os_path, LOGGER_DATA); - logger('RedDirectory::log() red_path ' . $this->red_path, LOGGER_DATA); + logger('ext_path ' . $this->ext_path, LOGGER_DATA); + logger('os_path ' . $this->os_path, LOGGER_DATA); + logger('red_path ' . $this->red_path, LOGGER_DATA); } /** * @brief Returns an array with all the child nodes. * - * @throws DAV\Exception\Forbidden - * @return array DAV\INode[] + * @throw \Sabre\DAV\Exception\Forbidden + * @return array \Sabre\DAV\INode[] */ public function getChildren() { - logger('RedDirectory::getChildren() called for ' . $this->ext_path, LOGGER_DATA); + //logger('children for ' . $this->ext_path, LOGGER_DATA); $this->log(); 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. * * - * @throw DAV\Exception\Forbidden - * @throw DAV\Exception\NotFound + * @throw \Sabre\DAV\Exception\Forbidden + * @throw \Sabre\DAV\Exception\NotFound * @param string $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)) { throw new DAV\Exception\Forbidden('Permission denied.'); @@ -130,7 +130,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota { * @return string */ 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)); } @@ -139,20 +139,20 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota { * * @todo handle duplicate directory name * - * @throw DAV\Exception\Forbidden + * @throw \Sabre\DAV\Exception\Forbidden * @param string $name The new name of the directory. * @return void */ 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)) { - logger('RedDirectory::setName(): permission denied'); + logger('permission denied ' . $name); throw new DAV\Exception\Forbidden('Permission denied.'); } 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.'); } @@ -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 * of the new file here. * - * @throws DAV\Exception\Forbidden + * @throw \Sabre\DAV\Exception\Forbidden * @param string $name Name of the file * @param resource|string $data Initial payload * @return null|string ETag */ public function createFile($name, $data = null) { - logger('RedDirectory::createFile(): ' . $name, LOGGER_DATA); + logger($name, LOGGER_DEBUG); if (! $this->auth->owner_id) { - logger('RedDirectory::createFile(): permission denied'); + logger('permission denied ' . $name); throw new DAV\Exception\Forbidden('Permission denied.'); } 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.'); } @@ -203,7 +203,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota { ); if (! $c) { - logger('RedDirectory::createFile(): no channel'); + logger('no channel'); 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); // delete attach entry if file_put_contents() failed 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); return; } @@ -273,7 +273,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota { intval($c[0]['channel_account_id']) ); 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); return; } @@ -287,7 +287,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota { * @return void */ 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'))) { throw new DAV\Exception\Forbidden('Permission denied.'); @@ -301,7 +301,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota { if ($r) { $result = attach_mkdir($r[0], $this->auth->observer, array('filename' => $name, 'folder' => $this->folder_hash)); 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. * * @param string $name + * The name to check if it exists. * @return boolean */ public function childExists($name) { // On /cloud we show a list of available channels. // @todo what happens if no channels are available? 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; } $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) return true; + return false; } /** * @todo add description of what this function does. * - * @throw DAV\Exception\NotFound + * @throw \Sabre\DAV\Exception\NotFound * @return void */ function getDir() { - logger('RedDirectory::getDir(): ' . $this->ext_path, LOGGER_DEBUG); + //logger($this->ext_path, LOGGER_DEBUG); $this->auth->log(); $file = $this->ext_path; @@ -356,7 +358,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota { if (! $path_arr) 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]; @@ -367,7 +369,6 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota { if (! $r) { throw new DAV\Exception\NotFound('The file with name: ' . $channel_name . ' could not be found.'); - return; } $channel_id = $r[0]['channel_id']; @@ -397,12 +398,11 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota { } $this->folder_hash = $folder; $this->os_path = $os_path; - return; } /** * @brief Returns the last modification time for the directory, as a UNIX - * timestamp. + * timestamp. * * It looks for the last edited file in the folder. If it is an empty folder * it returns the lastmodified time of the folder itself, to prevent zero @@ -429,7 +429,8 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota { /** * @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. */ diff --git a/include/RedDAV/RedFile.php b/include/RedDAV/RedFile.php index 32dbc17e5..f96790631 100644 --- a/include/RedDAV/RedFile.php +++ b/include/RedDAV/RedFile.php @@ -49,7 +49,7 @@ class RedFile extends DAV\Node implements DAV\IFile { $this->data = $data; $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 */ public function getName() { - logger('RedFile::getName(): ' . basename($this->name), LOGGER_DEBUG); + //logger(basename($this->name), LOGGER_DATA); return basename($this->name); } @@ -70,9 +70,10 @@ class RedFile extends DAV\Node implements DAV\IFile { * @return void */ 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'))) { + logger('permission denied '. $newName); throw new DAV\Exception\Forbidden('Permission denied.'); } @@ -91,7 +92,7 @@ class RedFile extends DAV\Node implements DAV\IFile { * @return void */ public function put($data) { - logger('RedFile::put(): ' . basename($this->name), LOGGER_DEBUG); + logger('put file: ' . basename($this->name), LOGGER_DEBUG); $size = 0; // @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 @file_put_contents($f, $data); $size = @filesize($f); - logger('RedFile::put(): filename: ' . $f . ' size: ' . $size, LOGGER_DEBUG); + logger('filename: ' . $f . ' size: ' . $size, LOGGER_DEBUG); } else { $r = q("UPDATE attach SET data = '%s' WHERE hash = '%s' AND uid = %d LIMIT 1", dbesc(stream_get_contents($data)), @@ -161,7 +162,7 @@ class RedFile extends DAV\Node implements DAV\IFile { intval($c[0]['channel_account_id']) ); 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']); return; } @@ -174,7 +175,7 @@ class RedFile extends DAV\Node implements DAV\IFile { * @return string */ 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", 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 mixed + * @return null|string */ public function getETag() { $ret = null; @@ -236,6 +237,7 @@ class RedFile extends DAV\Node implements DAV\IFile { * @brief Returns the size of the node, in bytes. * * @return int + * filesize in bytes */ public function getSize() { return $this->data['filesize']; @@ -254,11 +256,13 @@ class RedFile extends DAV\Node implements DAV\IFile { /** * @brief Delete the file. * - * @throw Sabre\DAV\Exception\Forbidden - * @return void + * This method checks the permissions and then calls attach_delete() function + * to actually remove the file. + * + * @throw \Sabre\DAV\Exception\Forbidden */ 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'))) { throw new DAV\Exception\Forbidden('Permission denied.'); diff --git a/include/attach.php b/include/attach.php index 0df2e82a5..6bce617cd 100644 --- a/include/attach.php +++ b/include/attach.php @@ -26,77 +26,74 @@ function z_mime_content_type($filename) { $mime_types = array( - 'txt' => 'text/plain', - 'htm' => 'text/html', - 'html' => 'text/html', - 'php' => 'text/html', - 'css' => 'text/css', - 'js' => 'application/javascript', - 'json' => 'application/json', - 'xml' => 'application/xml', - 'swf' => 'application/x-shockwave-flash', - 'flv' => 'video/x-flv', - 'epub' => 'application/epub+zip', - - // images - 'png' => 'image/png', - 'jpe' => 'image/jpeg', - 'jpeg' => 'image/jpeg', - 'jpg' => 'image/jpeg', - 'gif' => 'image/gif', - 'bmp' => 'image/bmp', - 'ico' => 'image/vnd.microsoft.icon', - 'tiff' => 'image/tiff', - 'tif' => 'image/tiff', - 'svg' => 'image/svg+xml', - 'svgz' => 'image/svg+xml', - - // archives - 'zip' => 'application/zip', - 'rar' => 'application/x-rar-compressed', - 'exe' => 'application/x-msdownload', - 'msi' => 'application/x-msdownload', - 'cab' => 'application/vnd.ms-cab-compressed', - - // audio/video - 'mp3' => 'audio/mpeg', - 'wav' => 'audio/wav', - 'qt' => 'video/quicktime', - 'mov' => 'video/quicktime', - 'ogg' => 'application/ogg', - - // adobe - 'pdf' => 'application/pdf', - 'psd' => 'image/vnd.adobe.photoshop', - 'ai' => 'application/postscript', - 'eps' => 'application/postscript', - 'ps' => 'application/postscript', - - // ms office - 'doc' => 'application/msword', - 'rtf' => 'application/rtf', - 'xls' => 'application/vnd.ms-excel', - 'ppt' => 'application/vnd.ms-powerpoint', - - - // open office - 'odt' => 'application/vnd.oasis.opendocument.text', - 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', + 'txt' => 'text/plain', + 'htm' => 'text/html', + 'html' => 'text/html', + 'php' => 'text/html', + 'css' => 'text/css', + 'js' => 'application/javascript', + 'json' => 'application/json', + 'xml' => 'application/xml', + 'swf' => 'application/x-shockwave-flash', + 'flv' => 'video/x-flv', + 'epub' => 'application/epub+zip', + + // images + 'png' => 'image/png', + 'jpe' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'gif' => 'image/gif', + 'bmp' => 'image/bmp', + 'ico' => 'image/vnd.microsoft.icon', + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'svg' => 'image/svg+xml', + 'svgz' => 'image/svg+xml', + + // archives + 'zip' => 'application/zip', + 'rar' => 'application/x-rar-compressed', + 'exe' => 'application/x-msdownload', + 'msi' => 'application/x-msdownload', + 'cab' => 'application/vnd.ms-cab-compressed', + + // audio/video + 'mp3' => 'audio/mpeg', + 'wav' => 'audio/wav', + 'qt' => 'video/quicktime', + 'mov' => 'video/quicktime', + 'ogg' => 'application/ogg', + + // adobe + 'pdf' => 'application/pdf', + 'psd' => 'image/vnd.adobe.photoshop', + 'ai' => 'application/postscript', + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', + + // ms office + 'doc' => 'application/msword', + 'rtf' => 'application/rtf', + 'xls' => 'application/vnd.ms-excel', + 'ppt' => 'application/vnd.ms-powerpoint', + + // open office + 'odt' => 'application/vnd.oasis.opendocument.text', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', ); - $dot = strpos($filename,'.'); - if($dot !== false) { - $ext = strtolower(substr($filename,$dot+1)); + $dot = strpos($filename, '.'); + if ($dot !== false) { + $ext = strtolower(substr($filename, $dot + 1)); if (array_key_exists($ext, $mime_types)) { return $mime_types[$ext]; } } return 'application/octet-stream'; - } - /** * @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['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['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['data'] = $r[0]; - return $ret; + return $ret; } /** @@ -301,7 +298,6 @@ function attach_by_hash_nodata($hash, $rev = 0) { $ret['success'] = true; $ret['data'] = $r[0]; return $ret; - } /** @@ -400,6 +396,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { if(! isset($hash)) $hash = random_string(); + $created = datetime_convert(); if($options === 'replace') { @@ -432,7 +429,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { dbesc($x[0]['deny_cid']), dbesc($x[0]['deny_gid']) ); - } + } elseif($options === 'update') { $r = q("update attach set filename = '%s', filetype = '%s', edited = '%s', allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' where id = %d and uid = %d limit 1", @@ -446,7 +443,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { intval($x[0]['id']), intval($x[0]['uid']) ); - } + } else { $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, filesize, revision, data, created, edited, allow_cid, allow_gid,deny_cid, deny_gid ) VALUES ( %d, %d, '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ", @@ -466,7 +463,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { dbesc(($arr && array_key_exists('deny_cid',$arr)) ? $arr['deny_cid'] : ''), dbesc(($arr && array_key_exists('deny_gid',$arr)) ? $arr['deny_gid'] : '') ); - } + } if($options !== 'update') @unlink($src); @@ -490,6 +487,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) { $ret['success'] = true; $ret['data'] = $r[0]; + 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 */ function z_readdir($channel_id, $observer_hash, $pathname, $parent_hash = '') { - $ret = array('success' => false); + if(! perm_is_allowed($r[0]['uid'], get_observer_hash(), 'view_storage')) { $ret['message'] = t('Permission denied.'); return $ret; @@ -547,6 +545,7 @@ function z_readdir($channel_id, $observer_hash, $pathname, $parent_hash = '') { } $ret['success'] = true; $ret['data'] = $r; + return $ret; } @@ -686,7 +685,6 @@ function attach_mkdir($channel, $observer_hash, $arr = null) { } return $ret; - } /** @@ -732,15 +730,19 @@ function attach_change_permissions($channel_id, $resource, $allow_cid, $allow_gi dbesc($resource), 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 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) { @@ -760,7 +762,7 @@ function attach_delete($channel_id, $resource) { // If resource is a directory delete everything in the directory recursive 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), intval($channel_id) ); @@ -799,19 +801,21 @@ function attach_delete($channel_id, $resource) { dbesc($r[0]['folder']), intval($channel_id) ); - - return; } /** * @brief Returns path to file in cloud/. * - * @param $arr - * @return string with the path the file to cloud/ + * @param array + * $arr[uid] int the channels uid + * $arr[folder] string + * $arr[filename]] string + * @return string + * path to the file in cloud/ */ function get_cloudpath($arr) { - $basepath = 'cloud/'; + if($arr['uid']) { $r = q("select channel_address from channel where channel_id = %d limit 1", intval($arr['uid']) @@ -823,7 +827,6 @@ function get_cloudpath($arr) { $path = $basepath; if($arr['folder']) { - $lpath = ''; $lfile = $arr['folder']; @@ -842,60 +845,83 @@ function get_cloudpath($arr) { $lpath = $r[0]['filename'] . '/' . $lpath; $lfile = $r[0]['folder']; - } while ( ($r[0]['folder']) && ($r[0]['flags'] & ATTACH_FLAG_DIR)) ; + } while ( ($r[0]['folder']) && ($r[0]['flags'] & ATTACH_FLAG_DIR)); - $path .= $lpath; + $path .= $lpath; } - $path .= $arr['filename']; + return $path; } /** * @brief Returns path to parent folder in cloud/. - * - * @param $arr - * @return string with the folder path + * + * @param int $channel_id + * 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) { - //Build directory tree and redirect + // build directory tree $parentHash = $attachHash; do { $parentHash = find_folder_hash_by_attach_hash($channel_id, $parentHash); if ($parentHash) { $parentName = find_filename_by_hash($channel_id, $parentHash); - $parentFullPath = $parentName."/".$parentFullPath; + $parentFullPath = $parentName . '/' . $parentFullPath; } } while ($parentHash); - $parentFullPath = z_root() . "/cloud/" . $channel_name . "/" . $parentFullPath; + $parentFullPath = z_root() . '/cloud/' . $channel_name . '/' . $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) { - $r = q("select * from attach where uid = %d and hash = '%s' limit 1", - intval($channel_id), dbesc($attachHash) + $r = q("SELECT folder FROM attach WHERE uid = %d AND hash = '%s' LIMIT 1", + intval($channel_id), + dbesc($attachHash) ); - $hash = ""; - if($r) { - foreach($r as $rr) { - $hash = $rr['folder']; - } + $hash = ''; + if ($r) { + $hash = $r[0]['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) { - $r = q("select * from attach where uid = %d and hash = '%s' limit 1", - intval($channel_id), dbesc($attachHash) + $r = q("SELECT filename FROM attach WHERE uid = %d AND hash = '%s' LIMIT 1", + intval($channel_id), + dbesc($attachHash) ); - $filename = ""; - if($r) { - foreach($r as $rr) { - $filename = $rr['filename']; - } + $filename = ''; + if ($r) { + $filename = $r[0]['filename']; } - return $filename; + return $filename; } - /** * * @param $in @@ -904,6 +930,6 @@ function find_filename_by_hash($channel_id, $attachHash) { function pipe_streams($in, $out) { $size = 0; while (!feof($in)) - $size += fwrite($out, fread($in,8192)); + $size += fwrite($out, fread($in, 8192)); return $size; } diff --git a/include/diaspora.php b/include/diaspora.php index b35318eac..c6d4b7423 100755 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -927,9 +927,14 @@ function get_diaspora_reshare_xml($url,$recurse = 0) { // see if it's a reshare of a reshare - if($source_xml->root_diaspora_id && $source_xml->root_guid && $recurse < 15) { - $orig_author = notags(unxmlify($source_xml->root_diaspora_id)); - $orig_guid = notags(unxmlify($source_xml->root_guid)); + if($source_xml->post->reshare) + $xml = $source_xml->post->reshare; + else + return false; + + if($xml->root_diaspora_id && $xml->root_guid && $recurse < 15) { + $orig_author = notags(unxmlify($xml->root_diaspora_id)); + $orig_guid = notags(unxmlify($xml->root_guid)); $source_url = 'https://' . substr($orig_author,strpos($orig_author,'@')+1) . '/p/' . $orig_guid . '.xml'; $y = get_diaspora_reshare_xml($source_url,$recurse+1); if($y) diff --git a/include/hubloc.php b/include/hubloc.php index fded434d2..04c29315a 100644 --- a/include/hubloc.php +++ b/include/hubloc.php @@ -113,4 +113,61 @@ function remove_obsolete_hublocs() { } +// This actually changes other structures to match the given (presumably current) hubloc primary selection + +function hubloc_change_primary($hubloc) { + + if(! is_array($hubloc)) { + logger('no hubloc'); + return false; + } + if(! ($hubloc['hubloc_flags'] & HUBLOC_FLAGS_PRIMARY)) { + logger('not primary: ' . $hubloc['hubloc_url']); + return false; + } + + logger('setting primary: ' . $hubloc['hubloc_url']); + + // See if there's a local channel + + $r = q("select channel_id, channel_primary from channel where channel_hash = '%s' limit 1", + dbesc($hubloc['hubloc_hash']) + ); + if(($r) && (! $r[0]['channel_primary'])) { + q("update channel set channel_primary = 1 where channel_id = %d limit 1", + intval($r[0]['channel_id']) + ); + } + + // do we even have an xchan for this hubloc and if so is it already set as primary? + + $r = q("select * from xchan where xchan_hash = '%s' limit 1", + dbesc($hubloc['hubloc_hash']) + ); + if(! $r) { + logger('xchan not found'); + return false; + } + if($r[0]['xchan_addr'] === $hubloc['hubloc_addr']) { + logger('xchan already changed'); + return false; + } + + $url = $hubloc['hubloc_url']; + $lwebbie = substr($hubloc['hubloc_addr'],0,strpos($hubloc['hubloc_addr'],'@')); + + $r = q("update xchan set xchan_addr = '%s', xchan_url = '%s', xchan_follow = '%s', xchan_connurl = '%s' where xchan_hash = '%s' limit 1", + dbesc($hubloc['hubloc_addr']), + dbesc($url . '/channel/' . $lwebbie), + dbesc($url . '/follow?f=&url=%s'), + dbesc($url . '/poco/' . $lwebbie), + dbesc($hubloc['hubloc_hash']) + ); + if(! $r) + logger('xchan_update failed.'); + + logger('primary hubloc changed.' . print_r($hubloc,true),LOGGER_DEBUG); + return true; + +}
\ No newline at end of file diff --git a/include/identity.php b/include/identity.php index 4417f4028..07bfaebbd 100644 --- a/include/identity.php +++ b/include/identity.php @@ -291,8 +291,8 @@ function create_identity($arr) { // Create a verified hub location pointing to this site. $r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_flags, - hubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey ) - values ( '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s' )", + hubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey, hubloc_network ) + values ( '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s' )", dbesc($guid), dbesc($sig), dbesc($hash), @@ -302,7 +302,8 @@ function create_identity($arr) { dbesc(base64url_encode(rsa_sign(z_root(),$ret['channel']['channel_prvkey']))), dbesc(get_app()->get_hostname()), dbesc(z_root() . '/post'), - dbesc(get_config('system','pubkey')) + dbesc(get_config('system','pubkey')), + dbesc('zot') ); if(! $r) logger('create_identity: Unable to store hub location'); diff --git a/include/network.php b/include/network.php index 7286f0b12..25ed615c6 100644 --- a/include/network.php +++ b/include/network.php @@ -402,7 +402,7 @@ function validate_email($addr) { return false; $h = substr($addr,strpos($addr,'@') + 1); - if(($h) && (dns_get_record($h, DNS_A + DNS_CNAME + DNS_PTR + DNS_MX) || filter_var($h['host'], FILTER_VALIDATE_IP) )) { + if(($h) && (dns_get_record($h, DNS_A + DNS_CNAME + DNS_PTR + DNS_MX) || filter_var($h, FILTER_VALIDATE_IP) )) { return true; } return false; diff --git a/include/reddav.php b/include/reddav.php index 6785131c6..86b3a00e4 100644 --- a/include/reddav.php +++ b/include/reddav.php @@ -36,8 +36,8 @@ require_once('include/RedDAV/RedBasicAuth.php'); * @todo Is there any reason why this is not inside RedDirectory class? * @fixme function name looks like a class name, should we rename it? * - * @param $auth - * @return array containing RedDirectory objects + * @param RedBasicAuth &$auth + * @return array RedDirectory[] */ function RedChannelList(&$auth) { $ret = array(); @@ -50,7 +50,7 @@ function RedChannelList(&$auth) { if ($r) { foreach ($r as $rr) { 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 $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? * * @param string $file path to a directory - * @param &$auth - * @returns array DAV\INode[] + * @param RedBasicAuth &$auth + * @returns null|array \Sabre\DAV\INode[] + * @throw \Sabre\DAV\Exception\Forbidden + * @throw \Sabre\DAV\Exception\NotFound */ function RedCollectionData($file, &$auth) { $ret = array(); @@ -88,7 +90,7 @@ function RedCollectionData($file, &$auth) { $file = trim($file, '/'); $path_arr = explode('/', $file); - + if (! $path_arr) return null; @@ -150,7 +152,7 @@ function RedCollectionData($file, &$auth) { // This should no longer be needed since we just returned errors for paths not found if ($path !== '/' . $file) { - logger("RedCollectionData: Path mismatch: $path !== /$file"); + logger("Path mismatch: $path !== /$file"); return NULL; } @@ -160,8 +162,7 @@ function RedCollectionData($file, &$auth) { ); foreach ($r as $rr) { - logger('RedCollectionData: filename: ' . $rr['filename'], LOGGER_DATA); - + //logger('filename: ' . $rr['filename'], LOGGER_DEBUG); if ($rr['flags'] & ATTACH_FLAG_DIR) { // @todo can't we drop '/cloud'? it gets stripped off anyway in RedDirectory $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? * * @param string $file - * @param &$auth + * path to file or directory + * @param RedBasicAuth &$auth * @param boolean $test (optional) enable test mode + * @return RedFile|RedDirectory|boolean|null + * @throw \Sabre\DAV\Exception\Forbidden */ 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'); if ($x === 0) { @@ -198,7 +202,7 @@ function RedFileData($file, &$auth, $test = false) { $file = trim($file, '/'); $path_arr = explode('/', $file); - + if (! $path_arr) return null; @@ -237,7 +241,7 @@ function RedFileData($file, &$auth, $test = false) { if ($r && ( $r[0]['flags'] & ATTACH_FLAG_DIR)) { $folder = $r[0]['hash']; $path = $path . '/' . $r[0]['filename']; - } + } if (! $r) { $r = q("select id, uid, hash, filename, filetype, filesize, revision, folder, flags, created, edited from attach where folder = '%s' and filename = '%s' and uid = %d $perms group by filename limit 1", @@ -267,11 +271,11 @@ function RedFileData($file, &$auth, $test = false) { } if ($errors) { - logger('RedFileData: not found'); + logger('not found ' . $file); if ($test) return false; if ($permission_error) { - logger('RedFileData: permission error'); + logger('permission error ' . $file); throw new DAV\Exception\Forbidden('Permission denied.'); } return; diff --git a/include/zot.php b/include/zot.php index 2d674c354..869bca668 100644 --- a/include/zot.php +++ b/include/zot.php @@ -2,6 +2,7 @@ require_once('include/crypto.php'); require_once('include/items.php'); +require_once('include/hubloc.php'); /** * Red implementation of zot protocol. @@ -1714,9 +1715,14 @@ function process_location_delivery($sender,$arr,$deliveries) { ); if($r) $sender['key'] = $r[0]['xchan_pubkey']; - - $x = sync_locations($sender,$arr,true); - logger('process_location_delivery: results: ' . print_r($x,true), LOGGER_DEBUG); + if(array_key_exists('locations',$arr) && $arr['locations']) { + $x = sync_locations($sender,$arr,true); + logger('process_location_delivery: results: ' . print_r($x,true), LOGGER_DEBUG); + if($x['changed']) { + $guid = random_string() . '@' . get_app()->get_hostname(); + update_modtime($sender['hash'],$sender['guid'],$arr['locations'][0]['address'],UPDATE_FLAGS_UPDATED); + } + } } @@ -1832,17 +1838,28 @@ function sync_locations($sender,$arr,$absolute = false) { if((($r[0]['hubloc_flags'] & HUBLOC_FLAGS_PRIMARY) && (! $location['primary'])) || ((! ($r[0]['hubloc_flags'] & HUBLOC_FLAGS_PRIMARY)) && ($location['primary']))) { - $r = q("update hubloc set hubloc_flags = (hubloc_flags ^ %d), hubloc_updated = '%s' where hubloc_id = %d limit 1", + $m = q("update hubloc set hubloc_flags = (hubloc_flags ^ %d), hubloc_updated = '%s' where hubloc_id = %d limit 1", intval(HUBLOC_FLAGS_PRIMARY), dbesc(datetime_convert()), intval($r[0]['hubloc_id']) ); + // make sure hubloc_change_primary() has current data + $r[0]['hubloc_flags'] = $r[0]['hubloc_flags'] ^ HUBLOC_FLAGS_PRIMARY; + hubloc_change_primary($r[0]); $what .= 'primary_hub '; $changed = true; } + elseif($absolute) { + // Absolute sync - make sure the current primary is correctly reflected in the xchan + $pr = hubloc_change_primary($r[0]); + if($pr) { + $what .= 'xchan_primary'; + $changed = true; + } + } if((($r[0]['hubloc_flags'] & HUBLOC_FLAGS_DELETED) && (! $location['deleted'])) || ((! ($r[0]['hubloc_flags'] & HUBLOC_FLAGS_DELETED)) && ($location['deleted']))) { - $r = q("update hubloc set hubloc_flags = (hubloc_flags ^ %d), hubloc_updated = '%s' where hubloc_id = %d limit 1", + $n = q("update hubloc set hubloc_flags = (hubloc_flags ^ %d), hubloc_updated = '%s' where hubloc_id = %d limit 1", intval(HUBLOC_FLAGS_DELETED), dbesc(datetime_convert()), intval($r[0]['hubloc_id']) @@ -1884,6 +1901,14 @@ function sync_locations($sender,$arr,$absolute = false) { $what .= 'newhub '; $changed = true; + if($location['primary']) { + $r = q("select * from hubloc where hubloc_addr = '%s' and hubloc_sitekey = '%s' limit 1", + dbesc($location['address']), + dbesc($location['sitekey']) + ); + if($r) + hubloc_change_primary($r[0]); + } } // get rid of any hubs we have for this channel which weren't reported. diff --git a/install/update.php b/install/update.php index 0b1fa5d2e..c36864908 100644 --- a/install/update.php +++ b/install/update.php @@ -1,6 +1,6 @@ <?php -define( 'UPDATE_VERSION' , 1129 ); +define( 'UPDATE_VERSION' , 1130 ); /** * @@ -1457,3 +1457,10 @@ function update_r1128() { } +function update_r1129() { + $r = q("update hubloc set hubloc_network = 'zot' where hubloc_network = ''"); + if($r) + return UPDATE_SUCCESS; + return UPDATE_FAILED; +} + diff --git a/mod/chanman.php b/mod/chanman.php deleted file mode 100644 index 7a89708d7..000000000 --- a/mod/chanman.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php /** @file */ - - -/** - Placeholder file at present. This is going to involve a bit of work. - - This file will deal with the deletion of channels and management of hublocs. - - We need to provide the following functionality: - - - Delete my account and all channels from the entire network - - - Delete my account and all channels from this server - - - Delete a channel from the entire network - - - Delete a channel from this server - - - List all hub locations for this channel - - - Remove this/some hub location from this channel - - - promote this/some hub location to primary - - - Remove hub location 'xyz' from this channel, (this should possibly only be allowed if that hub has been down for a period of time) - - - Some of these actions should probably require email verification - -*/ - - diff --git a/mod/filestorage.php b/mod/filestorage.php index 383af84fc..e27087a92 100644 --- a/mod/filestorage.php +++ b/mod/filestorage.php @@ -1,18 +1,26 @@ <?php +/** + * @file mod/filestorage.php + * + */ require_once('include/attach.php'); +/** + * + * @param object &$a + */ function filestorage_post(&$a) { - $channel_id = ((x($_POST,'uid')) ? intval($_POST['uid']) : 0); + $channel_id = ((x($_POST, 'uid')) ? intval($_POST['uid']) : 0); if((! $channel_id) || (! local_user()) || ($channel_id != local_user())) { notice( t('Permission denied.') . EOL); return; } - $recurse = ((x($_POST,'recurse')) ? intval($_POST['recurse']) : 0); - $resource = ((x($_POST,'filehash')) ? notags($_POST['filehash']) : ''); + $recurse = ((x($_POST, 'recurse')) ? intval($_POST['recurse']) : 0); + $resource = ((x($_POST, 'filehash')) ? notags($_POST['filehash']) : ''); if(! $resource) { notice(t('Item not found.') . EOL); @@ -24,11 +32,11 @@ function filestorage_post(&$a) { $str_group_deny = perms2str($_REQUEST['group_deny']); $str_contact_deny = perms2str($_REQUEST['contact_deny']); - attach_change_permissions($channel_id,$resource,$str_contact_allow,$str_group_allow,$str_contact_deny,$str_group_deny,$recurse = false); + attach_change_permissions($channel_id, $resource, $str_contact_allow, $str_group_allow, $str_contact_deny,$str_group_deny, $recurse = false); //Build directory tree and redirect $channel = $a->get_channel(); - $cloudPath = get_parent_cloudpath($channel_id, $channel['channel_address'], $resource) ; + $cloudPath = get_parent_cloudpath($channel_id, $channel['channel_address'], $resource); goaway($cloudPath); } @@ -53,15 +61,15 @@ function filestorage_content(&$a) { $observer = $a->get_observer(); $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); - $perms = get_all_perms($owner,$ob_hash); + $perms = get_all_perms($owner, $ob_hash); if(! $perms['view_storage']) { notice( t('Permission denied.') . EOL); return; } - // Since we have ACL'd files in the wild, but don't have ACL here yet, we - // need to return for anyone other than the owner, despite the perms check for now. + // Since we have ACL'd files in the wild, but don't have ACL here yet, we + // need to return for anyone other than the owner, despite the perms check for now. $is_owner = (((local_user()) && ($owner == local_user())) ? true : false); if(! $is_owner) { @@ -69,7 +77,6 @@ function filestorage_content(&$a) { return; } - if(argc() > 3 && argv(3) === 'delete') { if(! $perms['write_storage']) { notice( t('Permission denied.') . EOL); @@ -77,7 +84,7 @@ function filestorage_content(&$a) { } $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), intval($owner) ); @@ -86,11 +93,15 @@ function filestorage_content(&$a) { goaway(z_root() . '/cloud/' . $which); } - attach_delete($owner,$r[0]['hash']); - - goaway(z_root() . '/cloud/' . $which); - } + $f = $r[0]; + $channel = $a->get_channel(); + + $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') { require_once('include/acl_selectors.php'); @@ -106,18 +117,16 @@ function filestorage_content(&$a) { ); $f = $r[0]; - $channel = $a->get_channel(); $cloudpath = get_cloudpath($f) . (($f['flags'] & ATTACH_FLAG_DIR) ? '?f=&davguest=1' : ''); $parentpath = get_parent_cloudpath($channel['channel_id'], $channel['channel_address'], $f['hash']); - $aclselect_e = populate_acl($f,false); + $aclselect_e = populate_acl($f, false); $is_a_dir = (($f['flags'] & ATTACH_FLAG_DIR) ? true : false); $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( '$header' => t('Edit file permissions'), '$file' => $f, @@ -135,12 +144,10 @@ function filestorage_content(&$a) { '$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'), '$submit' => t('Submit') - )); return $o; - } + } goaway(z_root() . '/cloud/' . $which); - } diff --git a/mod/import.php b/mod/import.php index 3cf114d66..44dfcc38d 100644 --- a/mod/import.php +++ b/mod/import.php @@ -344,7 +344,7 @@ function import_post(&$a) { unset($group['id']); $group['uid'] = $channel['channel_id']; dbesc_array($group); - $r = dbq("INSERT INTO group (`" + $r = dbq("INSERT INTO groups (`" . implode("`, `", array_keys($group)) . "`) VALUES ('" . implode("', '", array_values($group)) diff --git a/mod/locs.php b/mod/locs.php new file mode 100644 index 000000000..95aa7a579 --- /dev/null +++ b/mod/locs.php @@ -0,0 +1,90 @@ +<?php /** @file */ + + +/** + Placeholder file at present. This is going to involve a bit of work. + + This file will deal with the deletion of channels and management of hublocs. + + We need to provide the following functionality: + + - Delete my account and all channels from the entire network + + - Delete my account and all channels from this server + + - Delete a channel from the entire network + + - Delete a channel from this server + + - List all hub locations for this channel + + - Remove this/some hub location from this channel + + - promote this/some hub location to primary + + - Remove hub location 'xyz' from this channel, (this should possibly only be allowed if that hub has been down for a period of time) + + - Some of these actions should probably require email verification + +*/ + + +function locs_post(&$a) { + + if(! local_user()) + return; + + $channel = $a->get_channel(); + + if($_REQUEST['primary']) { + $hubloc_id = intval($_REQUEST['primary']); + if($hubloc_id) { + $r = q("select hubloc_id from hubloc where hubloc_id = %d and hubloc_hash = '%s' limit 1", + intval($hubloc_id), + dbesc($channel['channel_hash']) + ); + if(! $r) { + notice( t('Location not found.') . EOL); + return; + } + $r = q("update hubloc set hubloc_flags = (hubloc_flags ^ %d) where (hubloc_flags & %d) and hubloc_hash = '%s' ", + intval(HUBLOC_FLAGS_PRIMARY), + intval(HUBLOC_FLAGS_PRIMARY), + dbesc($channel['channel_hash']) + ); + $r = q("update hubloc set hubloc_flags = (hubloc_flags & %d) where hubloc_id = %d and hubloc_hash = '%s' limit 1", + intval(HUBLOC_FLAGS_PRIMARY), + intval($hubloc_id), + dbesc($channel['channel_hash']) + ); + proc_run('php','include/notifier.php','location',$channel['channel_id']); + return; + } + } + + if($_REQUEST['drop']) { + $hubloc_id = intval($_REQUEST['drop']); + if($hubloc_id) { + $r = q("select hubloc_id, hubloc_flags from hubloc where hubloc_id = %d and hubloc_url != '%s' and hubloc_hash = '%s' limit 1", + intval($hubloc_id), + dbesc(z_root()), + dbesc($channel['channel_hash']) + ); + if(! $r) { + notice( t('Location not found.') . EOL); + return; + } + if($r[0]['hubloc_flags'] & HUBLOC_FLAGS_PRIMARY) { + notice( t('Primary location cannot be removed.') . EOL); + return; + } + $r = q("update hubloc set hubloc_flags = (hubloc_flags & %d) where hubloc_id = %d and hubloc_hash = '%s' limit 1", + intval(HUBLOC_FLAGS_DELETED), + intval($hubloc_id), + dbesc($channel['channel_hash']) + ); + proc_run('php','include/notifier.php','location',$channel['channel_id']); + return; + } + } +}
\ No newline at end of file diff --git a/mod/photos.php b/mod/photos.php index dc593f22b..2b859b7f1 100644 --- a/mod/photos.php +++ b/mod/photos.php @@ -999,7 +999,7 @@ function photos_content(&$a) { $comments = ''; if(! count($r)) { if($can_post || $can_comment) { - $comments .= replace_macros($cmnt_tpl,array( + $commentbox = replace_macros($cmnt_tpl,array( '$return_path' => '', '$mode' => 'photos', '$jsreload' => $return_url, @@ -1070,7 +1070,7 @@ function photos_content(&$a) { $body_e = prepare_text($item['body'],$item['mimetype']); $comments .= replace_macros($template,array( - '$id' => $item['item_id'], + '$id' => $item['id'], '$mode' => 'photos', '$profile_url' => $profile_link, '$name' => $name_e, @@ -1079,7 +1079,7 @@ function photos_content(&$a) { '$title' => $title_e, '$body' => $body_e, '$ago' => relative_date($item['created']), - '$indent' => (($item['parent'] != $item['item_id']) ? ' comment' : ''), + '$indent' => (($item['parent'] != $item['id']) ? ' comment' : ''), '$drop' => $drop, '$comment' => $comment )); @@ -1087,7 +1087,7 @@ function photos_content(&$a) { } if($can_post || $can_comment) { - $comments .= replace_macros($cmnt_tpl,array( + $commentbox = replace_macros($cmnt_tpl,array( '$return_path' => '', '$jsreload' => $return_url, '$type' => 'wall-comment', @@ -1129,6 +1129,7 @@ function photos_content(&$a) { '$like' => $like_e, '$dislike' => $dislike_e, '$comments' => $comments, + '$commentbox' => $commentbox, '$paginate' => $paginate, )); diff --git a/version.inc b/version.inc index f25d8bb18..1984d7bf1 100644 --- a/version.inc +++ b/version.inc @@ -1 +1 @@ -2014-10-13.827 +2014-10-14.828 diff --git a/view/css/widgets.css b/view/css/widgets.css index 1992aa0fd..593e051da 100644 --- a/view/css/widgets.css +++ b/view/css/widgets.css @@ -81,13 +81,8 @@ /* group */ -input.group-edit-checkbox { - margin: unset; - height: 1em; - width: 1em; -} -a.group-edit-link { +a.group-edit-tool { z-index: 1; } diff --git a/view/js/main.js b/view/js/main.js index f58d3756b..32db7ccb7 100644 --- a/view/js/main.js +++ b/view/js/main.js @@ -986,6 +986,7 @@ function updateConvItems(mode,data) { $('body').css('cursor', 'wait'); $.get('contactgroup/' + gid + '/' + cid, function(data) { $('body').css('cursor', 'auto'); + $('#group-' + gid).toggleClass('icon-check icon-check-empty'); }); } diff --git a/view/tpl/group_side.tpl b/view/tpl/group_side.tpl index 6c5edba27..4afe1286f 100755 --- a/view/tpl/group_side.tpl +++ b/view/tpl/group_side.tpl @@ -5,16 +5,12 @@ {{foreach $groups as $group}} <li> {{if $group.cid}} - <a class="pull-right group-edit-link"> - <input type="checkbox" - class="{{if $group.selected}}ticked{{else}}unticked {{/if}} group-edit-checkbox" - onclick="contactgroupChangeMember('{{$group.id}}','{{$group.enc_cid}}');return true;" - {{if $group.ismember}}checked="checked"{{/if}} - /> + <a class="pull-right group-edit-tool fakelink" onclick="contactgroupChangeMember('{{$group.id}}','{{$group.enc_cid}}'); return true;"/> + <i id="group-{{$group.id}}" class="{{if $group.ismember}}icon-check{{else}}icon-check-empty{{/if}}"></i> </a> {{/if}} {{if $group.edit}} - <a class="pull-right group-edit-link" href="{{$group.edit.href}}" title="{{$edittext}}"><i class="group-edit-icon icon-pencil"></i></a> + <a class="pull-right group-edit-tool" href="{{$group.edit.href}}" title="{{$edittext}}"><i class="group-edit-icon icon-pencil"></i></a> {{/if}} <a{{if $group.selected}} class="group-selected"{{/if}} href="{{$group.href}}">{{$group.text}}</a> </li> diff --git a/view/tpl/photo_item.tpl b/view/tpl/photo_item.tpl index e7d25fd55..16f9a76c2 100755 --- a/view/tpl/photo_item.tpl +++ b/view/tpl/photo_item.tpl @@ -1,22 +1,27 @@ -<div class="wall-item-outside-wrapper{{$indent}}" id="wall-item-outside-wrapper-{{$id}}" > - <div class="wall-item-photo-wrapper" id="wall-item-photo-wrapper-{{$id}}" > - <a href="{{$profile_url}}" title="View {{$name}}'s profile" class="wall-item-photo-link" id="wall-item-photo-link-{{$id}}"> - <img src="{{$thumb}}" class="wall-item-photo" id="wall-item-photo-{{$id}}" style="height: 80px; width: 80px;" alt="{{$name}}" /></a> - </div> +<div class="wall-item-outside-wrapper {{$indent}}" id="wall-item-outside-wrapper-{{$id}}" > + <div class="wall-item-content-wrapper {{$indent}}" id="wall-item-content-wrapper-{{$id}}" style="clear:both;"> + <div class="wall-item-info" id="wall-item-info-{{$item.id}}" > + <div class="wall-item-photo-wrapper" id="wall-item-photo-wrapper-{{$id}}" > + <a href="{{$profile_url}}" title="View {{$name}}'s profile" class="wall-item-photo-link" id="wall-item-photo-link-{{$id}}"> + <img src="{{$thumb}}" class="wall-item-photo" id="wall-item-photo-{{$id}}" style="height: 80px; width: 80px;" alt="{{$name}}" /></a> + </div> + </div> + <div class="wall-item-wrapper" id="wall-item-wrapper-{{$id}}" > + <div class="wall-item-author"> + <a href="{{$profile_url}}" title="View {{$name}}'s profile" class="wall-item-name-link"><span class="wall-item-name" id="wall-item-name-{{$id}}" >{{$name}}</span></a> + </div> + <div class="wall-item-ago" id="wall-item-ago-{{$id}}">{{$ago}}</div> + </div> + <div class="wall-item-content" id="wall-item-content-{{$id}}" > + <div class="wall-item-title" id="wall-item-title-{{$id}}">{{$title}}</div> + <div class="wall-item-body" id="wall-item-body-{{$id}}" >{{$body}}</div> + </div> + {{$drop}} + <div class="wall-item-wrapper-end"></div> - <div class="wall-item-wrapper" id="wall-item-wrapper-{{$id}}" > - <a href="{{$profile_url}}" title="View {{$name}}'s profile" class="wall-item-name-link"><span class="wall-item-name" id="wall-item-name-{{$id}}" >{{$name}}</span></a> - <div class="wall-item-ago" id="wall-item-ago-{{$id}}">{{$ago}}</div> - </div> - <div class="wall-item-content" id="wall-item-content-{{$id}}" > - <div class="wall-item-title" id="wall-item-title-{{$id}}">{{$title}}</div> - <div class="wall-item-body" id="wall-item-body-{{$id}}" >{{$body}}</div> - </div> - {{$drop}} - <div class="wall-item-wrapper-end"></div> - <div class="wall-item-comment-separator"></div> - {{$comment}} + {{$comment}} -<div class="wall-item-outside-wrapper-end{{$indent}}" ></div> + <div class="wall-item-outside-wrapper-end{{$indent}}" ></div> + </div> </div> diff --git a/view/tpl/photo_view.tpl b/view/tpl/photo_view.tpl index f895b3129..4a9c0dfe8 100755 --- a/view/tpl/photo_view.tpl +++ b/view/tpl/photo_view.tpl @@ -92,6 +92,10 @@ {{$comments}} +<div class="wall-item-comment-wrapper{{if $comments}} wall-item-comment-wrapper-wc{{/if}}" > + {{$commentbox}} +</div> + </div> {{if $nextlink}}<div id="photo-next-link"><a href="{{$nextlink.0}}"><i class="icon-forward photo-icons"></i></a></div>{{/if}} |