1
0

Compare commits

...

2 Commits

Author SHA1 Message Date
c95bdf0ae5 updated readme 2024-10-11 15:47:21 +00:00
44a5d16921 added attachment anonymizing feature 2024-10-11 15:45:18 +00:00
2 changed files with 107 additions and 51 deletions

View File

@ -2,9 +2,10 @@
/**
* Plugin Name: antisocial-safety
* Description: Secures attachment uploads and comments with the OpenAI moderation endpoint
* Version: 1.6
* Version: 1.7
*/
// Prevent direct access to the file
if (!defined('ABSPATH')) {
exit;
@ -54,9 +55,14 @@ function oai_moderate_attachment($post_ID) {
if ($result['flagged']) {
// Mark as flagged
update_post_meta($post_ID, '_oai_moderation_flagged', true);
} else {
// Remove any previous flag
delete_post_meta($post_ID, '_oai_moderation_flagged');
// Delete the flagged attachment
wp_delete_attachment($post_ID, true);
// Set a transient to show an admin notice
set_transient('oai_flagged_upload_notice', __('An uploaded image was flagged by OpenAI Moderation and has been removed.', 'antisocial-safety'), 10);
// Optionally, you can log this event or take other actions
}
}
}
@ -93,7 +99,7 @@ function oai_moderate_image($image_url) {
if (is_wp_error($response)) {
// For graceful failure, return an empty array
return array();
return array('error' => $response->get_error_message());
}
$body = wp_remote_retrieve_body($response);
@ -107,22 +113,14 @@ function oai_moderate_image($image_url) {
}
}
// Hook into 'template_redirect' to block access to flagged attachments
add_action('template_redirect', 'oai_block_flagged_attachments');
// Display admin notice if an upload was flagged and removed
add_action('admin_notices', 'oai_flagged_upload_admin_notice');
function oai_block_flagged_attachments() {
if (is_attachment()) {
global $post;
if ($post) {
$flagged = get_post_meta($post->ID, '_oai_moderation_flagged', true);
if ($flagged) {
// Send 403 Forbidden header and exit
status_header(403);
nocache_headers();
// Optionally, display a message
wp_die(__('You are not allowed to access this content.', 'oai'), __('Forbidden', 'oai'), array('response' => 403));
}
}
function oai_flagged_upload_admin_notice() {
if ($message = get_transient('oai_flagged_upload_notice')) {
echo '<div class="notice notice-warning is-dismissible">
<p>' . esc_html($message) . '</p>
</div>';
}
}
@ -231,7 +229,7 @@ function oai_moderate_text($text) {
if (is_wp_error($response)) {
// For graceful failure, return an empty array
return array();
return array('error' => $response->get_error_message());
}
$body = wp_remote_retrieve_body($response);
@ -245,6 +243,47 @@ function oai_moderate_text($text) {
}
}
/**
* Anonymizer Functionality
*/
// Hook into 'wp_handle_upload_prefilter' to anonymize filenames if enabled
add_filter('wp_handle_upload_prefilter', 'oai_anonymize_filename');
function oai_anonymize_filename($file) {
// Check if anonymizer is enabled
$anonymizer_enabled = get_option('oai_enable_anonymizer', false);
if (!$anonymizer_enabled) {
return $file;
}
// Get the file extension
$file_info = pathinfo($file['name']);
$extension = isset($file_info['extension']) ? '.' . strtolower($file_info['extension']) : '';
// Generate a unique 10-digit filename
$new_filename = oai_generate_unique_filename($extension);
// Replace the original filename with the new anonymized filename
$file['name'] = $new_filename;
return $file;
}
function oai_generate_unique_filename($extension) {
$upload_dir = wp_upload_dir();
$base_dir = trailingslashit($upload_dir['basedir']);
do {
// Generate a random number between 0000000000 and 9999999999
$random_number = str_pad(mt_rand(0, 9999999999), 10, '0', STR_PAD_LEFT);
$new_filename = $random_number . $extension;
$file_path = $base_dir . $new_filename;
} while (file_exists($file_path));
return $new_filename;
}
/**
* Admin Columns for Media and Comments
*/
@ -252,18 +291,19 @@ function oai_moderate_text($text) {
// Add a custom column to the media library
add_filter('manage_media_columns', 'oai_add_media_column');
function oai_add_media_column($columns) {
$columns['oai_moderation'] = __('Moderation', 'oai');
$columns['oai_moderation'] = __('Moderation', 'antisocial-safety');
return $columns;
}
add_action('manage_media_custom_column', 'oai_media_column_content', 10, 2);
function oai_media_column_content($column_name, $post_ID) {
if ($column_name == 'oai_moderation') {
$moderation_result = get_post_meta($post_ID, '_oai_moderation_result', true);
$flagged = get_post_meta($post_ID, '_oai_moderation_flagged', true);
if ($flagged) {
echo '<span style="color:red;">' . __('Flagged', 'oai') . '</span>';
echo '<span style="color:red;">' . __('Flagged', 'antisocial-safety') . '</span>';
} else {
echo '<span style="color:green;">' . __('OK', 'oai') . '</span>';
echo '<span style="color:green;">' . __('OK', 'antisocial-safety') . '</span>';
}
}
}
@ -271,7 +311,7 @@ function oai_media_column_content($column_name, $post_ID) {
// Add a custom column to the comments list
add_filter('manage_edit-comments_columns', 'oai_add_comments_column');
function oai_add_comments_column($columns) {
$columns['oai_moderation'] = __('Moderation', 'oai');
$columns['oai_moderation'] = __('Moderation', 'antisocial-safety');
return $columns;
}
@ -280,11 +320,11 @@ function oai_comments_column_content($column_name, $comment_ID) {
if ($column_name == 'oai_moderation') {
$flagged = get_comment_meta($comment_ID, '_oai_moderation_flagged', true);
if ($flagged === 'pending') {
echo '<span style="color:orange;">' . __('Pending Approval', 'oai') . '</span>';
echo '<span style="color:orange;">' . __('Pending Approval', 'antisocial-safety') . '</span>';
} elseif ($flagged === 'flagged') {
echo '<span style="color:red;">' . __('Flagged', 'oai') . '</span>';
echo '<span style="color:red;">' . __('Flagged', 'antisocial-safety') . '</span>';
} else {
echo '<span style="color:green;">' . __('OK', 'oai') . '</span>';
echo '<span style="color:green;">' . __('OK', 'antisocial-safety') . '</span>';
}
}
}
@ -307,22 +347,22 @@ function oai_attachment_fields($form_fields, $post) {
if ($flagged) {
$form_fields['oai_moderation'] = array(
'label' => __('OpenAI Moderation', 'oai'),
'label' => __('OpenAI Moderation', 'antisocial-safety'),
'input' => 'html',
'html' => '<span style="color:red;">' . __('This attachment has been flagged by OpenAI Moderation.', 'oai') . '</span>',
'helps' => __('Flagged content is blocked from being served to users.', 'oai'),
'html' => '<span style="color:red;">' . __('This attachment was flagged by OpenAI Moderation and has been removed.', 'antisocial-safety') . '</span>',
'helps' => __('Flagged content is blocked from being served to users.', 'antisocial-safety'),
);
} else {
$form_fields['oai_moderation'] = array(
'label' => __('OpenAI Moderation', 'oai'),
'label' => __('OpenAI Moderation', 'antisocial-safety'),
'input' => 'html',
'html' => '<span style="color:green;">' . __('This attachment passed OpenAI Moderation.', 'oai') . '</span>',
'html' => '<span style="color:green;">' . __('This attachment passed OpenAI Moderation.', 'antisocial-safety') . '</span>',
);
}
if ($moderation_result) {
$form_fields['oai_moderation_result'] = array(
'label' => __('Moderation Details', 'oai'),
'label' => __('Moderation Details', 'antisocial-safety'),
'input' => 'html',
'html' => '<pre>' . esc_html(print_r($moderation_result, true)) . '</pre>',
);
@ -336,7 +376,7 @@ add_action('add_meta_boxes_comment', 'oai_add_comment_meta_box');
function oai_add_comment_meta_box() {
add_meta_box(
'oai_comment_moderation',
__('OpenAI Moderation Details', 'oai'),
__('OpenAI Moderation Details', 'antisocial-safety'),
'oai_comment_moderation_meta_box',
'comment',
'normal',
@ -355,20 +395,20 @@ function oai_comment_moderation_meta_box($comment) {
$flagged = get_comment_meta($comment->comment_ID, '_oai_moderation_flagged', true);
if ($flagged) {
echo '<p><strong>' . __('Status:', 'oai') . '</strong> ';
echo '<p><strong>' . __('Status:', 'antisocial-safety') . '</strong> ';
if ($flagged === 'pending') {
echo '<span style="color:orange;">' . __('Pending Approval', 'oai') . '</span>';
echo '<span style="color:orange;">' . __('Pending Approval', 'antisocial-safety') . '</span>';
} elseif ($flagged === 'flagged') {
echo '<span style="color:red;">' . __('Flagged', 'oai') . '</span>';
echo '<span style="color:red;">' . __('Flagged', 'antisocial-safety') . '</span>';
}
echo '</p>';
if ($moderation_result) {
echo '<h4>' . __('Moderation Details', 'oai') . '</h4>';
echo '<h4>' . __('Moderation Details', 'antisocial-safety') . '</h4>';
echo '<pre>' . esc_html(print_r($moderation_result, true)) . '</pre>';
}
} else {
echo '<p><span style="color:green;">' . __('This comment passed OpenAI Moderation.', 'oai') . '</span></p>';
echo '<p><span style="color:green;">' . __('This comment passed OpenAI Moderation.', 'antisocial-safety') . '</span></p>';
}
}
@ -381,8 +421,8 @@ add_action('admin_menu', 'oai_add_admin_menu');
function oai_add_admin_menu() {
add_options_page(
__('OpenAI Moderation', 'oai'),
__('OpenAI Moderation', 'oai'),
__('OpenAI Moderation', 'antisocial-safety'),
__('OpenAI Moderation', 'antisocial-safety'),
'manage_options',
'openai-moderation',
'oai_options_page'
@ -392,7 +432,7 @@ function oai_add_admin_menu() {
function oai_options_page() {
?>
<div class="wrap">
<h1><?php esc_html_e('OpenAI Moderation Settings', 'oai'); ?></h1>
<h1><?php esc_html_e('OpenAI Moderation Settings', 'antisocial-safety'); ?></h1>
<form method="post" action="options.php">
<?php
settings_fields('oai_options_group');
@ -409,25 +449,34 @@ add_action('admin_init', 'oai_settings_init');
function oai_settings_init() {
register_setting('oai_options_group', 'oai_api_key');
register_setting('oai_options_group', 'oai_enable_anonymizer');
add_settings_section(
'oai_settings_section',
__('OpenAI API Settings', 'oai'),
__('OpenAI API Settings', 'antisocial-safety'),
'oai_settings_section_callback',
'openai-moderation'
);
add_settings_field(
'oai_api_key_field',
__('OpenAI API Key', 'oai'),
__('OpenAI API Key', 'antisocial-safety'),
'oai_api_key_render',
'openai-moderation',
'oai_settings_section'
);
add_settings_field(
'oai_enable_anonymizer_field',
__('Enable Filename Anonymizer', 'antisocial-safety'),
'oai_enable_anonymizer_render',
'openai-moderation',
'oai_settings_section'
);
}
function oai_settings_section_callback() {
echo '<p>' . esc_html__('Enter your OpenAI API key to enable moderation.', 'oai') . '</p>';
echo '<p>' . esc_html__('Enter your OpenAI API key to enable moderation. You can also toggle the filename anonymizer below.', 'antisocial-safety') . '</p>';
}
function oai_api_key_render() {
@ -437,6 +486,14 @@ function oai_api_key_render() {
<?php
}
function oai_enable_anonymizer_render() {
$enabled = get_option('oai_enable_anonymizer', false);
?>
<input type="checkbox" name="oai_enable_anonymizer" value="1" <?php checked(1, $enabled, true); ?> />
<label for="oai_enable_anonymizer"><?php esc_html_e('Rename uploaded files to unique 10-digit random numbers.', 'antisocial-safety'); ?></label>
<?php
}
// Display admin notice if API key is not set
add_action('admin_notices', 'oai_admin_notices');
@ -454,7 +511,7 @@ function oai_admin_notices() {
$api_key = get_option('oai_api_key');
if (!$api_key) {
echo '<div class="notice notice-warning is-dismissible">
<p>' . __('OpenAI API key is not set. Moderation features are disabled until you enter a valid API key.', 'oai') . '</p>
<p>' . __('OpenAI API key is not set. Moderation features are disabled until you enter a valid API key.', 'antisocial-safety') . '</p>
</div>';
}
}
}

View File

@ -8,7 +8,7 @@ it keeps your site clean by blocking offensive or illegal images and comments be
## features
- **attachment moderation**: images are checked during upload. flagged images are blocked from being accessed.
- **attachment moderation**: images are checked during upload. flagged images are blocked. optionally, anonymize file names.
- **comment moderation**: comments are reviewed before they're saved. flagged comments are set to unapproved.
- **admin integration**: see moderation status directly in your media library and comments list. detailed info available in edit screens.
- **easy setup**: just add your openai api key in the settings.
@ -24,7 +24,7 @@ it keeps your site clean by blocking offensive or illegal images and comments be
### attachment moderation
- when an image is uploaded, the plugin sends it to openai's moderation api using the `omni-moderation-latest` model.
- if the image is flagged, the plugin blocks access to it by sending a 403 forbidden response when someone tries to view it.
- if the image is flagged in any of the abuse categories, the attachment does not get created.
### comment moderation
@ -34,7 +34,6 @@ it keeps your site clean by blocking offensive or illegal images and comments be
### backend functionality
- hooks into `add_attachment` to moderate images upon upload.
- uses `template_redirect` to block access to flagged attachments.
- hooks into `preprocess_comment` and `pre_comment_approved` to moderate comments before saving.
- stores moderation results in post and comment meta.
- adds custom columns in admin screens to display moderation status.