Version bump.
// | Author: Richard Heyes <richard@phpguru.org> |
// +-----------------------------------------------------------------------+
//
-// $Id: Request.php,v 1.41 2004/12/10 14:42:57 avb Exp $
+// $Id: Request.php,v 1.43 2005/11/06 18:29:14 avb Exp $
//
// HTTP_Request Class
//
/**
* Post data
- * @var mixed
+ * @var array
*/
var $_postData;
+ /**
+ * Request body
+ * @var string
+ */
+ var $_body;
+
+ /**
+ * A list of methods that MUST NOT have a request body, per RFC 2616
+ * @var array
+ */
+ var $_bodyDisallowed = array('TRACE');
+
/**
* Files to post
* @var array
$this->_method = HTTP_REQUEST_METHOD_GET;
$this->_http = HTTP_REQUEST_HTTP_VER_1_1;
$this->_requestHeaders = array();
- $this->_postData = null;
+ $this->_postData = array();
+ $this->_body = null;
$this->_user = null;
$this->_pass = null;
// Basic authentication
if (!empty($this->_user)) {
- $this->_requestHeaders['Authorization'] = 'Basic ' . base64_encode($this->_user . ':' . $this->_pass);
+ $this->addHeader('Authorization', 'Basic ' . base64_encode($this->_user . ':' . $this->_pass));
}
// Use gzip encoding if possible
*/
function addHeader($name, $value)
{
- $this->_requestHeaders[$name] = $value;
+ $this->_requestHeaders[strtolower($name)] = $value;
}
/**
*/
function removeHeader($name)
{
- if (isset($this->_requestHeaders[$name])) {
- unset($this->_requestHeaders[$name]);
+ if (isset($this->_requestHeaders[strtolower($name)])) {
+ unset($this->_requestHeaders[strtolower($name)]);
}
}
}
/**
- * Adds raw postdata
+ * Adds raw postdata (DEPRECATED)
*
* @param string The data
* @param bool Whether data is preencoded or not, default = already encoded
* @access public
+ * @deprecated deprecated since 1.3.0, method addBody() should be used instead
*/
function addRawPostData($postdata, $preencoded = true)
{
- $this->_postData = $preencoded ? $postdata : urlencode($postdata);
+ $this->_body = $preencoded ? $postdata : urlencode($postdata);
+ }
+
+ /**
+ * Sets the request body (for POST, PUT and similar requests)
+ *
+ * @param string Request body
+ * @access public
+ */
+ function setBody($body)
+ {
+ $this->_body = $body;
}
/**
*/
function addCookie($name, $value)
{
- $cookies = isset($this->_requestHeaders['Cookie']) ? $this->_requestHeaders['Cookie']. '; ' : '';
+ $cookies = isset($this->_requestHeaders['cookie']) ? $this->_requestHeaders['cookie']. '; ' : '';
$this->addHeader('Cookie', $cookies . $name . '=' . $value);
}
$host = 'ssl://' . $host;
}
+ // magic quotes may fuck up file uploads and chunked response processing
+ $magicQuotes = ini_get('magic_quotes_runtime');
+ ini_set('magic_quotes_runtime', false);
+
// If this is a second request, we may get away without
// re-connecting if they're on the same server
- if (PEAR::isError($err = $this->_sock->connect($host, $port, null, $this->_timeout, $this->_socketOptions)) ||
- PEAR::isError($err = $this->_sock->write($this->_buildRequest()))) {
+ $err = $this->_sock->connect($host, $port, null, $this->_timeout, $this->_socketOptions);
+ PEAR::isError($err) or $err = $this->_sock->write($this->_buildRequest());
- return $err;
- }
- if (!empty($this->_readTimeout)) {
- $this->_sock->setTimeout($this->_readTimeout[0], $this->_readTimeout[1]);
+ if (!PEAR::isError($err)) {
+ if (!empty($this->_readTimeout)) {
+ $this->_sock->setTimeout($this->_readTimeout[0], $this->_readTimeout[1]);
+ }
+
+ $this->_notify('sentRequest');
+
+ // Read the response
+ $this->_response = &new HTTP_Response($this->_sock, $this->_listeners);
+ $err = $this->_response->process($this->_saveBody && $saveBody);
}
- $this->_notify('sentRequest');
+ ini_set('magic_quotes_runtime', $magicQuotes);
- // Read the response
- $this->_response = &new HTTP_Response($this->_sock, $this->_listeners);
- if (PEAR::isError($err = $this->_response->process($this->_saveBody && $saveBody)) ) {
+ if (PEAR::isError($err)) {
return $err;
}
+
// Check for redirection
- // Bugfix (PEAR) bug #18, 6 oct 2003 by Dave Mertens (headers are also stored lowercase, so we're gonna use them here)
- // some non RFC2616 compliant servers (scripts) are returning lowercase headers ('location: xxx')
if ( $this->_allowRedirects
AND $this->_redirects <= $this->_maxRedirects
AND $this->getResponseCode() > 300
if (!isset($headername)) {
return isset($this->_response->_headers)? $this->_response->_headers: array();
} else {
+ $headername = strtolower($headername);
return isset($this->_response->_headers[$headername]) ? $this->_response->_headers[$headername] : false;
}
}
$request = $this->_method . ' ' . $url . ' HTTP/' . $this->_http . "\r\n";
- if (HTTP_REQUEST_METHOD_POST != $this->_method && HTTP_REQUEST_METHOD_PUT != $this->_method) {
+ if (in_array($this->_method, $this->_bodyDisallowed) ||
+ (HTTP_REQUEST_METHOD_POST != $this->_method && empty($this->_body)) ||
+ (HTTP_REQUEST_METHOD_POST != $this->_method && empty($this->_postData) && empty($this->_postFiles))) {
+
$this->removeHeader('Content-Type');
} else {
- if (empty($this->_requestHeaders['Content-Type'])) {
+ if (empty($this->_requestHeaders['content-type'])) {
// Add default content-type
$this->addHeader('Content-Type', 'application/x-www-form-urlencoded');
- } elseif ('multipart/form-data' == $this->_requestHeaders['Content-Type']) {
+ } elseif ('multipart/form-data' == $this->_requestHeaders['content-type']) {
$boundary = 'HTTP_Request_' . md5(uniqid('request') . microtime());
$this->addHeader('Content-Type', 'multipart/form-data; boundary=' . $boundary);
}
// Request Headers
if (!empty($this->_requestHeaders)) {
foreach ($this->_requestHeaders as $name => $value) {
- $request .= $name . ': ' . $value . "\r\n";
+ $canonicalName = implode('-', array_map('ucfirst', explode('-', $name)));
+ $request .= $canonicalName . ': ' . $value . "\r\n";
}
}
// No post data or wrong method, so simply add a final CRLF
- if ((HTTP_REQUEST_METHOD_POST != $this->_method && HTTP_REQUEST_METHOD_PUT != $this->_method) ||
- (empty($this->_postData) && empty($this->_postFiles))) {
+ if (in_array($this->_method, $this->_bodyDisallowed) ||
+ (HTTP_REQUEST_METHOD_POST != $this->_method && empty($this->_body))) {
$request .= "\r\n";
+
// Post data if it's an array
- } elseif ((!empty($this->_postData) && is_array($this->_postData)) || !empty($this->_postFiles)) {
+ } elseif (HTTP_REQUEST_METHOD_POST == $this->_method &&
+ (!empty($this->_postData) || !empty($this->_postFiles))) {
+
// "normal" POST request
if (!isset($boundary)) {
$postdata = implode('&', array_map(
$postdata .= "\r\n\r\n" . $data . "\r\n";
}
}
- $postdata .= '--' . $boundary . "\r\n";
+ $postdata .= '--' . $boundary . "--\r\n";
}
$request .= 'Content-Length: ' . strlen($postdata) . "\r\n\r\n";
$request .= $postdata;
- // Post data if it's raw
- } elseif(!empty($this->_postData)) {
- $request .= 'Content-Length: ' . strlen($this->_postData) . "\r\n\r\n";
- $request .= $this->_postData;
+ // Explicitly set request body
+ } elseif (!empty($this->_body)) {
+
+ $request .= 'Content-Length: ' . strlen($this->_body) . "\r\n\r\n";
+ $request .= $this->_body;
}
return $request;
$chunked = isset($this->_headers['transfer-encoding']) && ('chunked' == $this->_headers['transfer-encoding']);
$gzipped = isset($this->_headers['content-encoding']) && ('gzip' == $this->_headers['content-encoding']);
$hasBody = false;
- while (!$this->_sock->eof()) {
- if ($chunked) {
- $data = $this->_readChunked();
- } else {
- $data = $this->_sock->read(4096);
- }
- if ('' != $data) {
- $hasBody = true;
- if ($saveBody || $gzipped) {
- $this->_body .= $data;
+ if (!isset($this->_headers['content-length']) || 0 != $this->_headers['content-length']) {
+ while (!$this->_sock->eof()) {
+ if ($chunked) {
+ $data = $this->_readChunked();
+ } else {
+ $data = $this->_sock->read(4096);
+ }
+ if ('' == $data) {
+ break;
+ } else {
+ $hasBody = true;
+ if ($saveBody || $gzipped) {
+ $this->_body .= $data;
+ }
+ $this->_notify($gzipped? 'gzTick': 'tick', $data);
}
- $this->_notify($gzipped? 'gzTick': 'tick', $data);
}
}
if ($hasBody) {
function _processHeader($header)
{
list($headername, $headervalue) = explode(':', $header, 2);
- $headername_i = strtolower($headername);
- $headervalue = ltrim($headervalue);
+ $headername = strtolower($headername);
+ $headervalue = ltrim($headervalue);
- if ('set-cookie' != $headername_i) {
- $this->_headers[$headername] = $headervalue;
- $this->_headers[$headername_i] = $headervalue;
+ if ('set-cookie' != $headername) {
+ if (isset($this->_headers[$headername])) {
+ $this->_headers[$headername] .= ',' . $headervalue;
+ } else {
+ $this->_headers[$headername] = $headervalue;
+ }
} else {
$this->_parseCookie($headervalue);
}
$this->_chunkLength = hexdec($matches[1]);
// Chunk with zero length indicates the end
if (0 == $this->_chunkLength) {
- $this->_sock->readAll(); // make this an eof()
+ $this->_sock->readLine(); // make this an eof()
return '';
}
- } elseif ($this->_sock->eof()) {
+ } else {
return '';
}
}
# $Id$
+Version 1.1-alpha1()
+------------------------------------------------------------------------
+
+ * Added first patches for image directory permissions. (garvinhicking)
+
Version 1.0-beta2 ()
------------------------------------------------------------------------
case 'delete':
$file = serendipity_fetchImageFromDatabase($serendipity['GET']['fid']);
- if (!serendipity_checkPermission('adminImagesDelete') || (!serendipity_checkPermission('adminImagesMaintainOthers') && $file['authorid'] != '0' && $file['authorid'] != $serendipity['authorid'])) {
+ if (!is_array($file) || !serendipity_checkPermission('adminImagesDelete') || (!serendipity_checkPermission('adminImagesMaintainOthers') && $file['authorid'] != '0' && $file['authorid'] != $serendipity['authorid'])) {
return;
}
$serendipity['adminFile'] = 'serendipity_admin.php';
}
$abortLoc = $serendipity['serendipityHTTPPath'] . $serendipity['adminFile'] . '?serendipity[adminModule]=images';
- $newLoc = $abortLoc . '&serendipity[adminAction]=DoDelete&serendipity[fid]=' . $serendipity['GET']['fid'] . '&' . serendipity_setFormToken('url');
+ $newLoc = $abortLoc . '&serendipity[adminAction]=DoDelete&serendipity[fid]=' . (int)$serendipity['GET']['fid'] . '&' . serendipity_setFormToken('url');
printf(ABOUT_TO_DELETE_FILE, $file['name'] .'.'. $file['extension']);
?>
$file = serendipity_fetchImageFromDatabase($serendipity['GET']['fid']);
$serendipity['GET']['newname'] = serendipity_uploadSecure($serendipity['GET']['newname'], true);
- if (!serendipity_checkFormToken() || !serendipity_checkPermission('adminImagesDelete') || (!serendipity_checkPermission('adminImagesMaintainOthers') && $file['authorid'] != '0' && $file['authorid'] != $serendipity['authorid'])) {
+ if (!is_array($file) || !serendipity_checkFormToken() || !serendipity_checkPermission('adminImagesDelete') || (!serendipity_checkPermission('adminImagesMaintainOthers') && $file['authorid'] != '0' && $file['authorid'] != $serendipity['authorid'])) {
return;
}
if (serendipity_isActiveFile(basename($serendipity['GET']['newname']))) {
- printf(ERROR_FILE_FORBIDDEN, $serendipity['GET']['newname']);
+ printf(ERROR_FILE_FORBIDDEN, htmlspecialchars($serendipity['GET']['newname']));
return;
}
break;
+ case 'directoryEdit':
+ if (!serendipity_checkPermission('adminImagesDirectories')) {
+ return;
+ }
+
+?>
+
+ <strong><?php echo MANAGE_DIRECTORIES ?></strong><br />
+ <br />
+ <form method="POST" action="?serendipity[adminModule]=images&serendipity[adminAction]=directoryDoEdit&serendipity[dir]=<?php echo htmlspecialchars($serendipity['GET']['dir']) ?>">
+ <?php echo serendipity_setFormToken(); ?>
+ <input type="hidden" name="serendipity[oldDir]" value="<?php echo serendipity_uploadSecure($serendipity['GET']['dir']); ?>" />
+ <table cellpadding="5">
+ <tr>
+ <td width="100"><strong><?php echo NAME ?></strong></td>
+ <input type="hidden" name="serendipity[newDir]" value="<?php echo serendipity_uploadSecure($serendipity['GET']['dir']); ?>" />
+ </tr>
+ </table>
+ <br />
+ <br />
+ <div align="center">
+ <input name="SAVE" value="<?php echo SAVE ?>" class="serendipityPrettyButton" type="submit" />
+ </div>
+ </form>
+
+<?php
+ break;
+
case 'directoryDelete':
if (!serendipity_checkPermission('adminImagesDirectories')) {
return;
<?php echo DELETE_DIRECTORY_DESC ?>
<br />
<br />
- <form method="POST" action="?serendipity[adminModule]=images&serendipity[adminAction]=directoryDoDelete&serendipity[dir]=<?php echo $serendipity['GET']['dir'] ?>">
+ <form method="POST" action="?serendipity[adminModule]=images&serendipity[adminAction]=directoryDoDelete&serendipity[dir]=<?php echo htmlspecialchars($serendipity['GET']['dir']) ?>">
<?php echo serendipity_setFormToken(); ?>
<table cellpadding="5">
<tr>
<td width="100"><strong><?php echo NAME ?></strong></td>
- <td><?php echo basename($serendipity['GET']['dir']) ?></td>
+ <td><?php echo basename(htmlspecialchars($serendipity['GET']['dir'])) ?></td>
</tr>
<tr>
<td colspan="2"><input type="checkbox" name="serendipity[nuke]" value="true" style="margin: 0"> <?php echo FORCE_DELETE ?></td>
<br />
<br />
<div align="center">
- <?php echo sprintf(CONFIRM_DELETE_DIRECTORY, $serendipity['GET']['dir']) ?><br />
- <input name="SAVE" value="<?php echo DELETE_DIRECTORY ?>" class="serendipityPrettyButton" type="submit">
+ <?php echo sprintf(CONFIRM_DELETE_DIRECTORY, htmlspecialchars($serendipity['GET']['dir'])) ?><br />
+ <input name="SAVE" value="<?php echo DELETE_DIRECTORY ?>" class="serendipityPrettyButton" type="submit" />
</div>
</form>
if (!serendipity_checkPermission('adminImagesDirectories')) {
return;
}
+
+ $folders = serendipity_traversePath(
+ $serendipity['serendipityPath'] . $serendipity['uploadPath'],
+ '',
+ true,
+ NULL,
+ 1,
+ NULL,
+ 'write'
+ );
?>
<strong><?php echo CREATE_DIRECTORY ?></strong><br />
<?php echo CREATE_DIRECTORY_DESC ?>
<td><?php echo PARENT_DIRECTORY ?></td>
<td><select name="serendipity[parent]">
<option value=""><?php echo BASE_DIRECTORY ?></option>
- <?php foreach ( serendipity_traversePath($serendipity['serendipityPath'] . $serendipity['uploadPath']) as $folder ) { ?>
+ <?php foreach ( $folders as $folder ) { ?>
<option value="<?php echo $folder['relpath'] ?>"><?php echo str_repeat(' ', $folder['depth']*2) . ' '. $folder['name'] ?></option>
<?php } ?>
</select>
return;
}
+ $folders = serendipity_traversePath(
+ $serendipity['serendipityPath'] . $serendipity['uploadPath'],
+ '',
+ true,
+ NULL,
+ 1,
+ NULL,
+ 'write'
+ );
+
?>
<br />
<?php echo DIRECTORIES_AVAILABLE; ?>
<br />
<table border="0" cellspacing="0" cellpadding="4" width="100%">
<tr>
- <td colspan="2"><strong><?php echo BASE_DIRECTORY ?></strong></td>
+ <td colspan="3"><strong><?php echo BASE_DIRECTORY ?></strong></td>
</tr>
- <?php foreach ( serendipity_traversePath($serendipity['serendipityPath'] . $serendipity['uploadPath']) as $folder ) { ?>
+ <?php foreach ($folders as $folder) { ?>
<tr>
- <td width="16"><a href="?serendipity[adminModule]=images&serendipity[adminAction]=directoryDelete&serendipity[dir]=<?php echo urlencode($folder['relpath']) ?>"><img src="<?php echo serendipity_getTemplateFile('admin/img/delete.png') ?>" alt="<?php echo DELETE ?>" border="0"></a></td>
+ <td width="16"><a href="?serendipity[adminModule]=images&serendipity[adminAction]=directoryEdit&serendipity[dir]=<?php echo htmlspecialchars($folder['relpath']) ?>"><img src="<?php echo serendipity_getTemplateFile('admin/img/edit.png') ?>" border="0" alt="<?php echo EDIT ?>" /></a></td>
+ <td width="16"><a href="?serendipity[adminModule]=images&serendipity[adminAction]=directoryDelete&serendipity[dir]=<?php echo htmlspecialchars($folder['relpath']) ?>"><img src="<?php echo serendipity_getTemplateFile('admin/img/delete.png') ?>" alt="<?php echo DELETE ?>" border="0"></a></td>
<td style="padding-left: <?php echo $folder['depth']*10 ?>"><?php echo $folder['name'] ?></td>
</tr>
<?php } ?>
}
serendipity_restoreVar($serendipity['COOKIE']['addmedia_directory'], $serendipity['GET']['only_path']);
+ $folders = serendipity_traversePath(
+ $serendipity['serendipityPath'] . $serendipity['uploadPath'],
+ '',
+ true,
+ NULL,
+ 1,
+ NULL,
+ 'write'
+ );
?>
<?php echo ADD_MEDIA_BLAHBLAH; ?>
<td><?php echo STORE_IN_DIRECTORY; ?></td>
<td><select id="target_directory_1" name="serendipity[target_directory][1]">
<option value=""><?php echo BASE_DIRECTORY; ?></option>
- <?php foreach (serendipity_traversePath($serendipity['serendipityPath'] . $serendipity['uploadPath']) as $folder) { ?>
+ <?php foreach ($folders as $folder) { ?>
<option <?php echo ($serendipity['GET']['only_path'] == $folder['relpath']) ? 'selected="selected"' : '' ?> value="<?php echo $folder['relpath'] ?>"><?php echo str_repeat(' ', $folder['depth']*2) . ' '. $folder['name'] ?></option>
<?php } ?>
</select>
case 'rotateCW':
$file = serendipity_fetchImageFromDatabase($serendipity['GET']['fid']);
- if (!serendipity_checkPermission('adminImagesDelete') || (!serendipity_checkPermission('adminImagesMaintainOthers') && $file['authorid'] != '0' && $file['authorid'] != $serendipity['authorid'])) {
+ if (!is_array($file) || !serendipity_checkPermission('adminImagesDelete') || (!serendipity_checkPermission('adminImagesMaintainOthers') && $file['authorid'] != '0' && $file['authorid'] != $serendipity['authorid'])) {
return;
}
case 'rotateCCW':
$file = serendipity_fetchImageFromDatabase($serendipity['GET']['fid']);
- if (!serendipity_checkPermission('adminImagesDelete') || (!serendipity_checkPermission('adminImagesMaintainOthers') && $file['authorid'] != '0' && $file['authorid'] != $serendipity['authorid'])) {
+ if (!is_array($file) || !serendipity_checkPermission('adminImagesDelete') || (!serendipity_checkPermission('adminImagesMaintainOthers') && $file['authorid'] != '0' && $file['authorid'] != $serendipity['authorid'])) {
return;
}
case 'scale':
$file = serendipity_fetchImageFromDatabase($serendipity['GET']['fid']);
- if (!serendipity_checkFormToken() || !serendipity_checkPermission('adminImagesDelete') || (!serendipity_checkPermission('adminImagesMaintainOthers') && $file['authorid'] != '0' && $file['authorid'] != $serendipity['authorid'])) {
+ if (!is_array($file) || !serendipity_checkFormToken() || !serendipity_checkPermission('adminImagesDelete') || (!serendipity_checkPermission('adminImagesMaintainOthers') && $file['authorid'] != '0' && $file['authorid'] != $serendipity['authorid'])) {
return;
}
SCALING_IMAGE . '<br />',
$file['path'] . $file['name'] .'.'. $file['extension'],
- $serendipity['GET']['width'],
- $serendipity['GET']['height']
+ (int)$serendipity['GET']['width'],
+ (int)$serendipity['GET']['height']
);
echo serendipity_scaleImg($serendipity['GET']['fid'], $serendipity['GET']['width'], $serendipity['GET']['height']) . '<br />';
case 'scaleSelect':
$file = serendipity_fetchImageFromDatabase($serendipity['GET']['fid']);
- if (!serendipity_checkPermission('adminImagesDelete') || (!serendipity_checkPermission('adminImagesMaintainOthers') && $file['authorid'] != '0' && $file['authorid'] != $serendipity['authorid'])) {
+ if (!is_array($file) || !serendipity_checkPermission('adminImagesDelete') || (!serendipity_checkPermission('adminImagesMaintainOthers') && $file['authorid'] != '0' && $file['authorid'] != $serendipity['authorid'])) {
return;
}
</script>
<?php
- printf(RESIZE_BLAHBLAH, $serendipity['GET']['fname']);
+ printf(RESIZE_BLAHBLAH, htmlspecialchars($serendipity['GET']['fname']));
printf(ORIGINAL_SIZE, $s[0],$s[1]);
echo HERE_YOU_CAN_ENTER_BLAHBLAH;
?>
* @param string The type of an artifact (category|entry)
* @param string The type of access to grant (read|write)
* @param array The ID of the group to grant access to
+ * @param string A variable option for an artifact
* @return boolean True if ACL was applied, false if not.
*/
-function serendipity_ACLGrant($artifact_id, $artifact_type, $artifact_mode, $groups) {
+function serendipity_ACLGrant($artifact_id, $artifact_type, $artifact_mode, $groups, $artifact_index = '') {
global $serendipity;
if (empty($groups) || !is_array($groups)) {
// Delete all old existing relations.
serendipity_db_query("DELETE FROM {$serendipity['dbPrefix']}access
- WHERE artifact_id = " . (int)$artifact_id . "
- AND artifact_type = '" . serendipity_db_escape_string($artifact_type) . "'
- AND artifact_mode = '" . serendipity_db_escape_string($artifact_mode) . "'");
+ WHERE artifact_id = " . (int)$artifact_id . "
+ AND artifact_type = '" . serendipity_db_escape_string($artifact_type) . "'
+ AND artifact_mode = '" . serendipity_db_escape_string($artifact_mode) . "'
+ AND artifact_index = '" . serendipity_db_escape_string($artifact_index) . "'");
$data = array(
'artifact_id' => (int)$artifact_id,
'artifact_type' => $artifact_type,
'artifact_mode' => $artifact_mode,
- 'artifact_index' => ''
+ 'artifact_index' => $artifact_index
);
if (count($data) < 1) {
* @param int The ID of the artifact to set the access
* @param string The type of an artifact (category|entry)
* @param string The type of access to check for (read|write)
+ * @param string A variable option for an artifact
* @return array Returns an array of all groups that are allowed for this kind of access. You can then check if you are the member of any of the groups returned here.
*/
-function serendipity_ACLGet($artifact_id, $artifact_type, $artifact_mode) {
+function serendipity_ACLGet($artifact_id, $artifact_type, $artifact_mode, $artifact_index) {
global $serendipity;
$sql = "SELECT groupid, artifact_index FROM {$serendipity['dbPrefix']}access
- WHERE artifact_type = '" . serendipity_db_escape_string($artifact_type) . "'
- AND artifact_id = '" . (int)$artifact_id . "'
- AND artifact_mode = '" . serendipity_db_escape_string($artifact_mode) . "'";
+ WHERE artifact_type = '" . serendipity_db_escape_string($artifact_type) . "'
+ AND artifact_id = '" . (int)$artifact_id . "'
+ AND artifact_mode = '" . serendipity_db_escape_string($artifact_mode) . "'
+ AND artifact_index = '" . serendipity_db_escape_string($artifact_index) . "'";
$rows = serendipity_db_query($sql, false, 'assoc');
if (!is_array($rows)) {
* @access private
* @param array Associative array that holds the SQL part array to be used in other functions like serendipity_fetchEntries()
* @param boolean Some queries do not need to joins categories. When ACLs need to be applied, this column is required, so if $append_category is set to true it will perform this missing JOIN.
+ * @param string The ACL type ('category', 'directory')
* @return true True if ACLs were applied, false if not.
*/
-function serendipity_ACL_SQL(&$cond, $append_category = false) {
+function serendipity_ACL_SQL(&$cond, $append_category = false, $type = 'category') {
global $serendipity;
// A global configuration item controls whether the blog should apply ACLs or not!
$cond['joins'] .= " LEFT JOIN {$serendipity['dbPrefix']}category c
ON ec.categoryid = c.categoryid";
}
+
+ switch($type) {
+ case 'directory':
+ $sql_artifact_column = 'i.path IS NULL OR
+ acl_acc.groupid IS NULL';
+ $sql_artifact = 'AND acl_acc.artifact_index = i.path';
+ break;
+
+ case 'category':
+ $sql_artifact_column = 'c.categoryid IS NULL';
+ $sql_artifact = 'AND acl_acc.artifact_id = c.categoryid';
+ break;
+ }
$cond['joins'] .= " LEFT JOIN {$serendipity['dbPrefix']}authorgroups AS acl_a
ON acl_a.authorid = " . $read_id . "
LEFT JOIN {$serendipity['dbPrefix']}access AS acl_acc
ON ( acl_acc.artifact_mode = 'read'
- AND acl_acc.artifact_type = 'category'
- AND acl_acc.artifact_id = c.categoryid
+ AND acl_acc.artifact_type = '" . $type . "'
+ " . $sql_artifact . "
)";
if (empty($cond['and'])) {
// When in Admin-Mode, apply readership permissions.
$cond['and'] .= " (
- c.categoryid IS NULL
+ " . $sql_artifact_column . "
OR ( acl_acc.groupid = " . $read_id_sql . ")
OR ( acl_acc.artifact_id IS NULL
" . (isset($serendipity['GET']['adminModule']) &&
$permsql = " WHERE $perm";
}
- $query = "SELECT i.*, a.realname AS authorname FROM {$serendipity['dbPrefix']}images AS i LEFT OUTER JOIN {$serendipity['dbPrefix']}authors AS a ON i.authorid = a.authorid $directorysql ORDER BY $order $ordermode $limitsql";
+ $cond = array(
+ 'and' => $directorysql
+ );
+ serendipity_ACL_SQL($cond, false, 'directory');
+
+ $basequery = "FROM {$serendipity['dbPrefix']}images AS i
+ LEFT OUTER JOIN {$serendipity['dbPrefix']}authors AS a
+ ON i.authorid = a.authorid
+ {$cond['joins']}
+
+ {$cond['and']}";
+
+ $query = "SELECT i.*,
+ a.realname AS authorname
+ $basequery
+ ORDER BY $order $ordermode $limitsql";
+
$rs = serendipity_db_query($query, false, 'assoc');
if (!is_array($rs)) {
return array();
}
- $total_query = "SELECT count(i.id) FROM {$serendipity['dbPrefix']}images AS i LEFT OUTER JOIN {$serendipity['dbPrefix']}authors AS a on i.authorid = a.authorid $permsql";
+ $total_query = "SELECT count(i.id)
+ $basequery";
$total_rs = serendipity_db_query($total_query, true, 'num');
if (is_array($total_rs)) {
$total = $total_rs[0];
*/
function serendipity_fetchImageFromDatabase($id) {
global $serendipity;
- $rs = serendipity_db_query("SELECT * FROM {$serendipity['dbPrefix']}images WHERE id = ". (int)$id, true, 'assoc');
+
+ $cond = array(
+ 'and' => "WHERE id = " . (int)$id
+ );
+ serendipity_ACL_SQL($cond, false, 'directory');
+
+ $rs = serendipity_db_query("SELECT i.*
+ FROM {$serendipity['dbPrefix']}images AS i
+ {$cond['joins']}
+ {$cond['and']}", true, 'assoc');
return $rs;
}
$dThumb = array();
$file = serendipity_fetchImageFromDatabase($id);
+
+ if (!is_array($file) || !isset($file['path'])) {
+ printf(FILE_NOT_FOUND . '<br />', $id);
+ return false;
+ }
+
$dFile = $file['path'] . $file['name'] . '.' . $file['extension'];
$dThumb = array(array(
global $serendipity;
$file = serendipity_fetchImageFromDatabase($id);
+ if (!is_array($file)) {
+ return false;
+ }
$admin = '';
if (!serendipity_checkPermission('adminImagesMaintainOthers') && $file['authorid'] != '0' && $file['authorid'] != $serendipity['authorid']) {
global $serendipity;
$file = serendipity_fetchImageFromDatabase($id);
+ if (!is_array($file)) {
+ return false;
+ }
$admin = '';
if (!serendipity_checkPermission('adminImagesMaintainOthers') && $file['authorid'] != '0' && $file['authorid'] != $serendipity['authorid']) {
$linkPrevious = '?' . $extraParems . 'serendipity[page]=' . ($page-1);
$linkNext = '?' . $extraParems . 'serendipity[page]=' . ($page+1);
$sort_order = serendipity_getImageFields();
- $paths = serendipity_traversePath($serendipity['serendipityPath'] . $serendipity['uploadPath']. $limit_path);
+ $paths = serendipity_traversePath(
+ $serendipity['serendipityPath'] . $serendipity['uploadPath']. $limit_path,
+ '',
+ true,
+ NULL,
+ 1,
+ NULL,
+ 'read'
+ );
if (is_null($lineBreak)) {
$lineBreak = floor(750 / ($serendipity['thumbSize'] + 20));
/**
* Recursively walk a directory tree
*
+ *
+ * @TODO - Check all serendipity_traversePath calls to see where ACL need to be applied
+ *
* @access public
* @param string The core directory
* @param string The subdirectory
* @param string A regexp patter to include files
* @param int Level of nesting (recursive use)
* @param int The maximum level of nesting (recursive use)
+ * @param mixed Toggle whether to apply serendipity_directoryACL (false / 'read' / 'write')
* @return array Array of files/directories
*/
-function serendipity_traversePath($basedir, $dir='', $onlyDirs=true, $pattern = NULL, $depth = 1, $max_depth = null) {
-
+function serendipity_traversePath($basedir, $dir='', $onlyDirs = true, $pattern = NULL, $depth = 1, $max_depth = null, $apply_ACL = false) {
- $dh = @opendir($basedir . '/' . $dir);
- if ( !$dh ) {
+ $odir = serendipity_dirSlash('end', $basedir) . serendipity_dirSlash('end', $dir);
+ $dh = @opendir($odir);
+ if (!$dh) {
return array();
}
$files = array();
while (($file = @readdir($dh)) !== false) {
if ( $file != '.' && $file != '..' ) {
- if ( $onlyDirs === false || ($onlyDirs === true && is_dir($basedir . '/' . $dir . '/' . $file)) ) {
+ if ( $onlyDirs === false || ($onlyDirs === true && is_dir($odir . $file)) ) {
if ( is_null($pattern) || preg_match($pattern, $file) ) {
$files[] = array(
'name' => $file,
'depth' => $depth,
- 'relpath' => ltrim(str_replace('\\', '/', $dir) . basename($file) . '/', '/')
+ 'relpath' => ltrim(str_replace('\\', '/', serendipity_dirSlash('end', $dir)) . basename($file) . '/', '/')
);
}
}
- if ( is_dir($basedir . '/' . $dir . '/' . $file) && ($max_depth === null || $depth < $max_depth)) {
- $files = array_merge($files, serendipity_traversePath($basedir, $dir . '/' . basename($file) . '/', $onlyDirs, $pattern, ($depth+1), $max_depth));
+
+ if (is_dir($odir . $file) && ($max_depth === null || $depth < $max_depth)) {
+ $next_dir = serendipity_dirSlash('end', $dir) . basename($file);
+ $files = array_merge($files, serendipity_traversePath($basedir, $next_dir, $onlyDirs, $pattern, ($depth+1), $max_depth));
}
}
}
@closedir($dh);
+
+ if ($depth == 1 && $apply_ACL !== FALSE) {
+ serendipity_directoryACL($files, $apply_ACL);
+ }
+
return $files;
}
function serendipity_escapeshellarg($string) {
return escapeshellarg(str_replace('%', '', $string));
}
+
+/**
+ * Rename a media directory
+ *
+ * @access public
+ * @param string Old directory name
+ * @param string New directory name
+ */
+function serendipity_renameDir($old, $new) {
+}
+
+/**
+ * Makes sure a directory begins with or ends with a "/"
+ *
+ * @access public
+ * @param string Type of where to append/prepend slash ('end', 'start', 'both')
+ * @param string Directory name
+ * @return string Output argument
+ */
+function serendipity_dirSlash($type, $dir) {
+
+ if ($dir == '') {
+ return $dir;
+ }
+
+ if ($type == 'start' || $type == 'both') {
+ if (substr($dir, 0, 1) != '/') {
+ $dir = '/' . $dir;
+ }
+ }
+
+ if ($type == 'end' || $type == 'both') {
+ if (substr($dir, -1) != '/') {
+ $dir .= '/';
+ }
+ }
+
+ return $dir;
+}
+
+/**
+ * Cycle a serendipity_traversePath resultset and apply read/write ACLs.
+ *
+ * @access public
+ * @param array serendipity_traversePath result array
+ * @param string ACL type ('read', 'write')
+ */
+function serendipity_directoryACL(&$paths, $type = 'read') {
+ global $serendipity;
+ static $debug = false;
+
+ if ($debug) {
+ echo "Applying ACL for mode '$type'.<br />\n";
+ }
+
+ if (serendipity_userLoggedIn() && (!isset($serendipity['enableACL']) || $serendipity['enableACL'] == true)) {
+ // Check if we are a cool superuser. Bail out if we are.
+ if (serendipity_checkPermission('adminImagesMaintainOthers') && serendipity_checkPermission('adminImagesDirectories')) {
+ if (!$debug) {
+ return true;
+ }
+ }
+
+ // Get list of all ACLs for directories.
+ $q = "SELECT a.artifact_index AS directory,
+ a.groupid
+ FROM {$serendipity['dbPrefix']}access AS a
+ WHERE a.artifact_type = 'directory'
+ AND a.artifact_mode = '" . serendipity_db_escape_string($type) . "'";
+ $allowed = serendipity_db_query($q);
+ if (!is_array($allowed)) {
+ return false;
+ }
+
+ // Get a list of all the groups for this user. Pipe it into a usable array.
+ $my_groups =& serendipity_getGroups($serendipity['authorid']);
+ $acl_allowed_groups = array();
+ foreach($my_groups AS $my_group) {
+ $acl_allowed_groups[$my_group['id']] = true;
+ }
+
+ // Iterate every ACL and check if we are allowed to use it.
+ $acl_allowed = array();
+ foreach($allowed AS $row) {
+ $acl_allowed[$row['directory']][$row['groupid']] = true;
+ }
+
+ // Iterate the input path array and check it against ACL.
+ foreach($paths AS $idx => $info) {
+ if (!isset($acl_allowed[$info['relpath']])) {
+ // ACL for directory not set. Assume we are allowed to access.
+ continue;
+ }
+
+ $granted = false;
+ foreach($acl_allowed[$info['relpath']] AS $groupid => $set) {
+ if (isset($acl_allowed_groups[$groupid])) {
+ // We are allowed to access this element
+ $granted = true;
+ break;
+ }
+ }
+
+ if ($granted === false) {
+ // We are not allowed to access this element
+ if ($debug) {
+ echo "ACL for " . $info['relpath'] . " DENIED.<br />\n";
+ }
+ unset($paths[$idx]);
+ } else {
+ if ($debug) {
+ echo "ACL for " . $info['relpath'] . " granted.<br />\n";
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
}
$file = serendipity_fetchImageFromDatabase($serendipity['GET']['image']);
+ if (!is_array($file)) {
+ echo PERM_DENIED;
+ break;
+ }
$file['imgsrc'] = $serendipity['serendipityHTTPPath'] . $serendipity['uploadHTTPPath'] . $file['path'] . $file['name'] . (!empty($file['thumbnail_name']) ? '.' . $file['thumbnail_name'] : '') . '.' . $file['extension'];
if ($file['hotlink']) {
$imgName = $file['path'];
include_once(S9Y_INCLUDE_PATH . 'include/compat.inc.php');
// The version string
-$serendipity['version'] = '1.0-beta2';
+$serendipity['version'] = '1.1-alpha1';
// Name of folder for the default theme
$serendipity['defaultTemplate'] = 'default';