Require users to login to view attachments on private sites

Thank you jeff-themovie for this implementation!
This commit is contained in:
Craig Andrews 2010-01-05 17:47:37 -05:00
parent 7e01bb8d4f
commit 250bcfa8dc
6 changed files with 104 additions and 49 deletions

20
README
View File

@ -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
=========

View File

@ -1,13 +1,13 @@
<?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);
}
}
}

View File

@ -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));
} else {
$path = common_config('attachments', 'path');
if ($path[strlen($path)-1] != '/') {
$path .= '/';
}
if ($path[0] != '/') {
$path = '/'.$path;
}
$server = common_config('attachments', 'server');
if (empty($server)) {
$server = common_config('site', 'server');
}
// XXX: protocol
return 'http://'.$server.$path.$filename;
}
if ($path[0] != '/') {
$path = '/'.$path;
}
$server = common_config('attachments', 'server');
if (empty($server)) {
$server = common_config('site', 'server');
}
// XXX: protocol
return 'http://'.$server.$path.$filename;
}
function getEnclosure(){

View File

@ -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/';

View File

@ -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]

View File

@ -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',