<?php /** * Plugin Name: wp-mat * Plugin URI: https://git.autistici.org/noblogs/wp-mat * Description: Process uploaded files through MAT * Version: 0.1.4 * Author: Autistici/Inventati * Author URI: https://www.autistici.org/ * License: MIT * License URI: http://opensource.org/licenses/MIT */ if (!defined("WP_MAT_ENDPOINT")) { define("WP_MAT_ENDPOINT", "http://localhost:7111/api/cleanup"); } // This is generally useful for debugging. if (!function_exists('wp_handle_upload_error')) { function wp_handle_upload_error(&$file, $message) { error_log("wp_handle_upload_error: ".$message); return array( "error" => $message ); } } class WP_Mat { // Check if the mime type is one of those we want to clean up. // Use a blacklist, currently empty. Send everything by default // except video, and pdf. function is_supported_mime_type($mimetype) { if (substr($mimetype, 0, 6) === "video/") { return false; } if ($mimetype === "application/pdf") { return false; } return true; } // Make a POST request to the MAT service with the uploaded file and // store the results into '$output_path'. Returns true on success, // false on any error. function issue_cleanup_request($path, $mimetype, $output_path) { $upfile = new CURLFile($path, $mimetype, 'input'); $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, WP_MAT_ENDPOINT); curl_setopt($curl, CURLOPT_USERAGENT, 'Wordpress'); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, array( "file" => $upfile, "mime_type" => $mimetype, )); if (($fp = fopen($output_path, "wb")) === false) { throw new Exception("fopen error for filename $output_path"); } curl_setopt($curl, CURLOPT_FILE, $fp); curl_setopt($curl, CURLOPT_BINARYTRANSFER, true); $ret = curl_exec($curl); if ($ret === false) { error_log("wp-mat: curl error: ".curl_error($curl)); } else { $status = curl_getinfo($curl, CURLINFO_HTTP_CODE); if ($status != 200) { error_log("wp-mat: curl error: server returned HTTP status ".$status); $ret = false; } } fclose($fp); curl_close($curl); return $ret; } // Filter uploaded files before they are processed by Wordpress. function handle_upload_prefilter($file) { if (isset($file['error']) && $file['error']) { return $file; } if (get_option('wpmat_disabled')) { return $file; } // Autodetect MIME type if not passed by the browser. if (!$file['type']) { $file['type'] = mime_content_type($file['tmp_name']); } // Check if it's one of the MIME types we support. if (!$this->is_supported_mime_type($file['type'])) { error_log("wp-mat: unsupported mime type ".$file['type']); return $file; } // Issue a request to the MAT API, and if successful replace the // file with the sanitized one. $new_tmp_file = tempnam("", "wp_mat_"); if ($this->issue_cleanup_request($file['tmp_name'], $file['type'], $new_tmp_file)) { // Rename the cleaned up file to the original file, or WP // will not pass the is_uploaded_file() check in wp_handle_upload(). unlink($file['tmp_name']); rename($new_tmp_file, $file['tmp_name']); $new_file = array( "name" => $file['name'], "type" => $file['type'], "tmp_name" => $file['tmp_name'], "size" => filesize($file['tmp_name']), "error" => 0, ); error_log("wp-mat: successfully cleaned file=".json_encode($new_file)); $file = $new_file; } else { error_log("wp-mat: server error for file=".json_encode($file)); @unlink($new_tmp_file); } return $file; } function settings_api_init() { // Add the section to reading settings so we can add our // fields to it. add_settings_section( 'wpmat_settings_section', 'Metadata anonymization for uploads', array($this, 'settings_section_callback'), 'media' ); // Add the field with the names and function to use for our new // settings, put it in our new section. add_settings_field( 'wpmat_disabled', 'Disable metadata anonymization', array($this, 'settings_field_callback'), 'media', 'wpmat_settings_section' ); // Register our setting so that $_POST handling is done for us and // our callback function just has to echo the <input>. register_setting('media', 'wpmat_disabled'); } function settings_section_callback() { echo('<p>Control whether uploaded files are run through metadata anonymization (using <a href="https://0xacab.org/jvoisin/mat2">MAT2</a>). '); echo('This feature is enabled by default but it can be disabled in case you are experiencing problems uploading files.</p>'); } function settings_field_callback() { echo('<input name="wpmat_disabled" id="wpmat_disabled" type="checkbox" value="1" class="code" ' . checked(1, get_option('wpmat_disabled'), false) . ' /> <label for="wpmat_disabled">Disable metadata anonymization</label>'); } function __construct() { add_filter('wp_handle_upload_prefilter', array($this, 'handle_upload_prefilter')); add_action('admin_init', array($this, 'settings_api_init')); } } new WP_Mat();