git.gnu.io has moved to IP address 209.51.188.249 -- please double check where you are logging in.

Commit 250bcfa8 authored by Craig Andrews's avatar Craig Andrews

Require users to login to view attachments on private sites

Thank you jeff-themovie for this implementation!
parent 7e01bb8d
......@@ -710,11 +710,21 @@ private site, but users of the private site may be able to subscribe
to users on a remote site. (Or not... it's not well tested.) The
"proper behaviour" hasn't been defined here, so handle with care.
If fancy URLs is enabled, access to file attachments can also be
restricted to logged-in users only. Uncomment the appropriate rewrite
rule in .htaccess or your server's httpd.conf. (This most likely will
not work if you are using a virtual server for attachments, so consider
the performance/security tradeoff.)
Access to file attachments can also be restricted to logged-in users only.
1. Add a directory outside the web root where your file uploads will be
stored. Usually a command like this will work:
mkdir /var/www/mublog-files
2. Make the file uploads directory writeable by the web server. An
insecure way to do this is:
chmod a+x /var/www/mublog-files
3. Tell StatusNet to use this directory for file uploads. Add a line
like this to your config.php:
$config['attachments']['dir'] = '/var/www/mublog-files';
Upgrading
=========
......
<?php
/**
* StatusNet, the distributed open-source microblogging tool
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2009, StatusNet, Inc.
*
* Returns a given file attachment, allowing private sites to only allow
* access to file attachments after login.
* Return a requested file
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
......@@ -20,28 +20,32 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Personal
* @category PrivateAttachments
* @package StatusNet
* @author Jeffery To <jeffery.to@gmail.com>
* @copyright 2008-2009 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @copyright 2009 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET') && !defined('LACONICA')) {
if (!defined('STATUSNET')) {
exit(1);
}
require_once 'MIME/Type.php';
/**
* Action for getting a file attachment
* An action for returning a requested file
*
* @category Personal
* @package StatusNet
* @author Jeffery To <jeffery.to@gmail.com>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
* The StatusNet system will do an implicit user check if the site is
* private before allowing this to continue
*
* @category PrivateAttachments
* @package StatusNet
* @author Jeffery To <jeffery.to@gmail.com>
* @copyright 2009 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
class GetfileAction extends Action
......@@ -68,7 +72,7 @@ class GetfileAction extends Action
$path = null;
if ($filename) {
$path = common_config('attachments', 'dir') . $filename;
$path = File::path($filename);
}
if (empty($path) or !file_exists($path)) {
......@@ -103,6 +107,10 @@ class GetfileAction extends Action
function lastModified()
{
if (common_config('site', 'use_x_sendfile')) {
return null;
}
return filemtime($this->path);
}
......@@ -114,8 +122,24 @@ class GetfileAction extends Action
*
* @return string etag http header
*/
function etag()
{
if (common_config('site', 'use_x_sendfile')) {
return null;
}
$cache = common_memcache();
if($cache) {
$key = common_cache_key('attachments:etag:' . $this->path);
$etag = $cache->get($key);
if($etag === false) {
$etag = crc32(file_get_contents($this->path));
$cache->set($key,$etag);
}
return $etag;
}
$stat = stat($this->path);
return '"' . $stat['ino'] . '-' . $stat['size'] . '-' . $stat['mtime'] . '"';
}
......@@ -133,13 +157,19 @@ class GetfileAction extends Action
// undo headers set by PHP sessions
$sec = session_cache_expire() * 60;
header('Expires: ' . date(DATE_RFC1123, time() + $sec));
header('Cache-Control: public, max-age=' . $sec);
header('Pragma: public');
header('Cache-Control: max-age=' . $sec);
parent::handle($args);
$path = $this->path;
header('Content-Type: ' . MIME_Type::autoDetect($path));
readfile($path);
if (common_config('site', 'use_x_sendfile')) {
header('X-Sendfile: ' . $path);
} else {
header('Content-Length: ' . filesize($path));
readfile($path);
}
}
}
......@@ -182,25 +182,32 @@ class File extends Memcached_DataObject
static function url($filename)
{
$path = common_config('attachments', 'path');
if(common_config('site','private')) {
if ($path[strlen($path)-1] != '/') {
$path .= '/';
}
return common_local_url('getfile',
array('filename' => $filename));
if ($path[0] != '/') {
$path = '/'.$path;
}
} else {
$path = common_config('attachments', 'path');
$server = common_config('attachments', 'server');
if ($path[strlen($path)-1] != '/') {
$path .= '/';
}
if (empty($server)) {
$server = common_config('site', 'server');
}
if ($path[0] != '/') {
$path = '/'.$path;
}
$server = common_config('attachments', 'server');
// XXX: protocol
if (empty($server)) {
$server = common_config('site', 'server');
}
return 'http://'.$server.$path.$filename;
// XXX: protocol
return 'http://'.$server.$path.$filename;
}
}
function getEnclosure(){
......
......@@ -41,6 +41,20 @@ $config['site']['path'] = 'statusnet';
// Make the site invisible to non-logged-in users
// $config['site']['private'] = true;
// If your web server supports X-Sendfile (Apache with mod_xsendfile,
// lighttpd, nginx), you can enable X-Sendfile support for better
// performance. Presently, only attachment serving when the site is
// in private mode will use X-Sendfile.
// $config['site']['X-Sendfile'] = false;
// You may also need to enable X-Sendfile support for your web server and
// allow it to access files outside of the web root. For Apache with
// mod_xsendfile, you can add these to your .htaccess or server config:
//
// XSendFile on
// XSendFileAllowAbove on
//
// See http://tn123.ath.cx/mod_xsendfile/ for mod_xsendfile.
// If you want logging sent to a file instead of syslog
// $config['site']['logfile'] = '/tmp/statusnet.log';
......@@ -265,6 +279,7 @@ $config['sphinx']['port'] = 3312;
// $config['attachments']['user_quota'] = 50000000;
// $config['attachments']['monthly_quota'] = 15000000;
// $config['attachments']['uploads'] = true;
// $config['attachments']['path'] = "/file/";
// $config['attachments']['path'] = "/file/"; //ignored if site is private
// $config['attachments']['dir'] = INSTALLDIR . '/file/';
// $config['oohembed']['endpoint'] = 'http://oohembed.com/oohembed/';
......@@ -5,14 +5,6 @@
RewriteBase /mublog/
# If your site is private and want to only allow logged-in users to
# be able to download file attachments, uncomment this rule.
#
# If you have a custom attachment path
# ($config['attachments']['path']), change "file/" to match.
#
#RewriteRule ^file/(.*) getfile/$1
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php?p=$1 [L,QSA]
......
......@@ -54,6 +54,7 @@ $default =
'dupelimit' => 60, # default for same person saying the same thing
'textlimit' => 140,
'indent' => true,
'use_x_sendfile' => false,
),
'db' =>
array('database' => 'YOU HAVE TO SET THIS IN config.php',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment