Created
February 14, 2013 20:17
-
-
Save mgmartel/4956003 to your computer and use it in GitHub Desktop.
Secures attachments for messages in BuddyPress when using the BuddyPress Message Attachment plugin, by only service the file to users that are part of the thread the file is attached to.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* This gist secures attachments for messages in BuddyPress when | |
* using the BuddyPress Message Attachment plugin, by only serving | |
* the file to users that are part of the thread the file is attached | |
* to. | |
* | |
* =Usage= | |
* Add the functions in this file to your theme's functions.php or | |
* wherever you want it. Then add the following rewrite rule to your | |
* .htaccess file: | |
* | |
* RewriteRule ^wp\-content/uploads/message\-attachements/(.*) /?bp_message_attachment=$1 [R,L] | |
* | |
* (if you use a custom uploads folder, replace wp-content/uploads with | |
* the path to your upload folder) | |
* | |
* | |
* Inspired by http://dev.commons.gc.cuny.edu/2011/02/05/hardening-buddypress-group-documents/ | |
* See http://wordpress.org/extend/plugins/buddypress-message-attachment/ | |
* | |
* @version 0.1 | |
* @author mike@trenvo.com | |
*/ | |
function bp_catch_msg_att_request() { | |
global $wpdb, $bp; | |
/** | |
* Internal error handler | |
* @param str $msg | |
*/ | |
function _att_request_handle_error( $msg ) { | |
global $bp; | |
$messages_url = trailingslashit( bp_loggedin_user_domain() . $bp->messages->slug ); | |
bp_core_add_message( $msg, 'error' ); | |
bp_core_redirect( $messages_url ); | |
exit; | |
} | |
// Check if we need to load | |
if ( ! isset ( $_GET['bp_message_attachment'] ) || empty ( $_GET['bp_message_attachment'] ) ) | |
return; | |
/** | |
* Get conversation by attachment | |
*/ | |
/** 1. Get attachment post **/ | |
$file_path = $_GET['bp_message_attachment']; | |
// Make sure the file path doesn't start with a slash | |
if ( substr ( $file_path, 0, 1 ) == '/' ) | |
$file_path = substr ( $file_path, 1 ); | |
$upload_dir = wp_upload_dir(); | |
// Stitch together the url of the attachment | |
$file_url = trailingslashit( $upload_dir['url'] ) . 'message-attachements/' . $file_path; | |
$args = array ( | |
"meta_key" => "bp_msgat_attachement_url", | |
"meta_value" => $file_url, | |
"post_type" => "messageattachements" | |
); | |
$attachment_post = current ( get_posts ( $args ) ); | |
if ( ! $attachment_post ) | |
return _att_request_handle_error( __( 'You requested a file that does not exist.', 'bp-msgat' ) ); | |
$file_name = $attachment_post->post_title; | |
/** 2. Get the thread **/ | |
$message_id = get_post_meta ( $attachment_post->ID, 'bp_msgat_message_id', true ); | |
$thread_id = current ( explode ( "=", $message_id) ); | |
/** | |
* Check if the current user is part of the conversation | |
*/ | |
// Get the thread recipients | |
$recipients = array(); | |
$results = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->messages->table_name_recipients} WHERE thread_id = %d", $thread_id ) ); | |
foreach ( (array) $results as $recipient ) | |
$recipients[] = $recipient->user_id; | |
$recipients = array_unique( $recipients ); | |
// Check if the current user is in the recipient list | |
$current_user = get_current_user_id(); | |
if ( ! in_array ( $current_user, $recipients ) ) | |
return _att_request_handle_error( __( 'You do not have access to this file.', 'bp-msgat' ) ); | |
/** | |
* We're through! Let's serve the user the attachment | |
*/ | |
$attachment_path = $upload_dir['path'] . '/message-attachements/' . $file_path; | |
if ( file_exists( $attachment_path ) ) { | |
$mime_type = mime_content_type( $attachment_path ); | |
$file_size = filesize( $attachment_path ); | |
header("Cache-Control: public, must-revalidate, post-check=0, pre-check=0"); | |
header("Pragma: hack"); | |
header("Content-Type: $mime_type; name='" . $file_name . "'"); | |
header("Content-Length: " . $file_size ); | |
header('Content-Disposition: attachment; filename="' . $file_name . '"'); | |
header("Content-Transfer-Encoding: binary"); | |
ob_clean(); | |
flush(); | |
readfile( $attachment_path ); | |
die(); | |
} else { | |
// File does not exist anymore | |
return _att_request_handle_error( __( 'An error has occurred, we could not find your file anymore.', 'bp-msgat' ) ); | |
} | |
} | |
add_filter( 'wp', 'bp_catch_msg_att_request', 1 ); | |
// http://www.php.net/manual/en/function.mime-content-type.php#87856 | |
if(!function_exists('mime_content_type')) { | |
function 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', | |
// 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', | |
'qt' => 'video/quicktime', | |
'mov' => 'video/quicktime', | |
// 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', | |
); | |
$ext = strtolower(array_pop(explode('.',$filename))); | |
if (array_key_exists($ext, $mime_types)) { | |
return $mime_types[$ext]; | |
} | |
elseif (function_exists('finfo_open')) { | |
$finfo = finfo_open(FILEINFO_MIME); | |
$mimetype = finfo_file($finfo, $filename); | |
finfo_close($finfo); | |
return $mimetype; | |
} | |
else { | |
return 'application/octet-stream'; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment