317 lines
9.9 KiB
PHP
317 lines
9.9 KiB
PHP
<?php
|
|
|
|
class Alti_ProtectUploads_Admin
|
|
{
|
|
|
|
private $plugin_name;
|
|
private $version;
|
|
private $messages = array();
|
|
|
|
public function __construct($plugin_name, $version)
|
|
{
|
|
$this->plugin_name = $plugin_name;
|
|
$this->version = $version;
|
|
}
|
|
|
|
public function get_plugin_name()
|
|
{
|
|
return $this->plugin_name;
|
|
}
|
|
|
|
public function add_submenu_page()
|
|
{
|
|
add_submenu_page('upload.php', $this->plugin_name, 'Protect Uploads <span class="dashicons dashicons-shield-alt" style="font-size:15px;"></span>', 'manage_options', $this->plugin_name . '-settings-page', array($this, 'render_settings_page'));
|
|
}
|
|
|
|
public function render_settings_page()
|
|
{
|
|
require plugin_dir_path(__FILE__) . 'views/' . $this->plugin_name . '-admin-settings-page.php';
|
|
}
|
|
|
|
public function enqueue_styles()
|
|
{
|
|
wp_enqueue_style($this->plugin_name, plugin_dir_url(__FILE__) . 'assets/css/protect-uploads-admin.css', array(), $this->version, 'all');
|
|
}
|
|
|
|
public function add_settings_link($links)
|
|
{
|
|
$settings_link = '<a href="upload.php?page=' . $this->plugin_name . '-settings-page">' . __('Settings') . '</a>';
|
|
array_unshift($links, $settings_link);
|
|
return $links;
|
|
}
|
|
|
|
public function get_uploads_dir()
|
|
{
|
|
$uploads_dir = wp_upload_dir();
|
|
return $uploads_dir['basedir'];
|
|
}
|
|
|
|
public function get_uploads_url()
|
|
{
|
|
$uploads_dir = wp_upload_dir();
|
|
return $uploads_dir['baseurl'];
|
|
}
|
|
|
|
public function get_uploads_subdirectories()
|
|
{
|
|
|
|
$directories = scandir(self::get_uploads_dir());
|
|
$subs = array(self::get_uploads_dir());
|
|
|
|
foreach ($directories as $directory) {
|
|
|
|
if (is_dir(self::get_uploads_dir() . '/' . $directory) && !preg_match('/^\.*$/', $directory)) {
|
|
$subs[] = self::get_uploads_dir() . '/' . $directory;
|
|
$subDirectories = scandir(self::get_uploads_dir() . '/' . $directory);
|
|
foreach ($subDirectories as $subDirectory) {
|
|
if (is_dir(self::get_uploads_dir() . '/' . $directory . '/' . $subDirectory) && !preg_match('/^\.*$/', $subDirectory)) $subs[] = self::get_uploads_dir() . '/' . $directory . '/' . $subDirectory;
|
|
}
|
|
}
|
|
}
|
|
return $subs;
|
|
}
|
|
|
|
public function save_form($form)
|
|
{
|
|
if ($form['protection'] == 'index_php') {
|
|
$this->create_index();
|
|
}
|
|
if ($form['protection'] == 'htaccess') {
|
|
$this->create_htaccess();
|
|
}
|
|
if ($form['protection'] == 'remove') {
|
|
$this->remove_index();
|
|
$this->remove_htaccess();
|
|
}
|
|
}
|
|
|
|
// used to check if the current htaccess has been generated by the plugin
|
|
public function get_htaccess_identifier()
|
|
{
|
|
return "[plugin_name=" . $this->plugin_name . "]";
|
|
}
|
|
|
|
public function create_index()
|
|
{
|
|
// check if index php does not exists
|
|
if (self::check_protective_file('index.php') === false) {
|
|
|
|
$indexContent = "<?php // Silence is golden \n // " . self::get_htaccess_identifier() . " \n // https://www.alticreation.com/en/protect-uploads/ \n // date:" . date('d/m/Y') . "\n // .";
|
|
$i = 0;
|
|
foreach (self::get_uploads_subdirectories() as $subDirectory) {
|
|
|
|
if (!file_put_contents($subDirectory . '/' . 'index.php', $indexContent)) {
|
|
self::register_message('Impossible to create or modified the index.php file in ' . $subDirectory, 'error');
|
|
} else {
|
|
$i++;
|
|
}
|
|
}
|
|
|
|
if ($i == count(self::get_uploads_subdirectories())) {
|
|
self::register_message('The index.php file has been created in main folder and subfolders (two levels max).');
|
|
}
|
|
}
|
|
// if index php already exists
|
|
else {
|
|
self::register_message('The index.php file already exists', 'error');
|
|
}
|
|
}
|
|
|
|
public function create_htaccess()
|
|
{
|
|
// Content for htaccess file
|
|
$date = date('Y-m-d H:i.s');
|
|
$phpv = phpversion();
|
|
|
|
$htaccessContent = "\n# BEGIN " . $this->get_plugin_name() . " Plugin\n";
|
|
$htaccessContent .= "\tOptions -Indexes\n";
|
|
$htaccessContent .= "# [date={$date}] [php={$phpv}] " . self::get_htaccess_identifier() . " [version={$this->version}]\n";
|
|
$htaccessContent .= "# END " . $this->get_plugin_name() . " Plugin\n";
|
|
|
|
// if htaccess does NOT exist yet
|
|
if (self::check_protective_file('.htaccess') === false) {
|
|
// try to create and save the new htaccess file
|
|
if (!file_put_contents(self::get_uploads_dir() . '/' . '.htaccess', $htaccessContent)) {
|
|
self::register_message('Impossible to create or modified the htaccess file.', 'error');
|
|
} else {
|
|
self::register_message('The htaccess file has been created.');
|
|
}
|
|
}
|
|
else {
|
|
// if content added to existing htaccess
|
|
if (file_put_contents(self::get_uploads_dir() . '/.htaccess', $htaccessContent, FILE_APPEND | LOCK_EX)) {
|
|
self::register_message('The htaccess file has been updated.');
|
|
} else {
|
|
self::register_message('The existing htaccess file couldn\'t be updated. Please check file permissions.', 'error');
|
|
}
|
|
}
|
|
}
|
|
|
|
public function remove_index()
|
|
{
|
|
$i = 0;
|
|
foreach (self::get_uploads_subdirectories() as $subDirectory) {
|
|
if (file_exists($subDirectory . '/index.php')) {
|
|
unlink($subDirectory . '/index.php');
|
|
$i++;
|
|
}
|
|
}
|
|
if ($i == count(self::get_uploads_subdirectories())) {
|
|
self::register_message('The index.php file(s) have(has) been deleted.');
|
|
}
|
|
}
|
|
|
|
public function remove_htaccess()
|
|
{
|
|
if (file_exists(self::get_uploads_dir() . '/.htaccess')) {
|
|
|
|
$htaccessContent = file_get_contents(self::get_uploads_dir() . '/.htaccess');
|
|
$htaccessContent = preg_replace('/(# BEGIN protect-uploads Plugin)(.*?)(# END protect-uploads Plugin)/is', '', $htaccessContent);
|
|
file_put_contents(self::get_uploads_dir() . '/.htaccess', $htaccessContent, LOCK_EX);
|
|
|
|
// if htaccess is empty, we remove it.
|
|
if (strlen(preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "", file_get_contents(self::get_uploads_dir() . '/.htaccess'))) == 0) {
|
|
unlink(self::get_uploads_dir() . '/.htaccess');
|
|
}
|
|
|
|
|
|
//
|
|
self::register_message('The htaccess file has been updated.');
|
|
}
|
|
}
|
|
|
|
public function get_protective_files_array()
|
|
{
|
|
$uploads_files = ['index.php', 'index.html', '.htaccess'];
|
|
$response = [];
|
|
foreach ($uploads_files as $file) {
|
|
if (file_exists(self::get_uploads_dir() . '/' . $file)) {
|
|
$response[] = $file;
|
|
}
|
|
}
|
|
return $response;
|
|
}
|
|
|
|
public function check_protective_file($file)
|
|
{
|
|
if (in_array($file, self::get_protective_files_array())) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public function get_uploads_root_response_code()
|
|
{
|
|
$uploads_headers = get_headers(self::get_uploads_url() . '/');
|
|
$response = null;
|
|
if (is_array($uploads_headers)) {
|
|
if (preg_match('/200/', $uploads_headers[0])) $response = 200;
|
|
if (preg_match('/403/', $uploads_headers[0])) $response = 403;
|
|
}
|
|
return $response;
|
|
}
|
|
|
|
public function get_htaccess_content()
|
|
{
|
|
return file_get_contents(self::get_uploads_dir() . '/.htaccess');
|
|
}
|
|
|
|
public function check_htaccess_is_self_generated()
|
|
{
|
|
if (self::check_protective_file('.htaccess') && preg_match('/' . self::get_htaccess_identifier() . '/', self::get_htaccess_content())) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// heart? <3
|
|
public function check_uploads_is_protected()
|
|
{
|
|
foreach (self::get_protective_files_array() as $file) {
|
|
if ($file === 'index.html') {
|
|
return true;
|
|
break;
|
|
}
|
|
if ($file === 'index.php') {
|
|
return true;
|
|
break;
|
|
}
|
|
if ($file === '.htaccess' && self::get_uploads_root_response_code() === 200) {
|
|
return false;
|
|
break;
|
|
}
|
|
}
|
|
if (self::get_uploads_root_response_code() === 403) {
|
|
return true;
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public function check_protective_file_removable() {
|
|
if( self::check_protective_file('index.html') ) {
|
|
return false;
|
|
}
|
|
elseif( self::check_protective_file('.htaccess') === false && self::get_uploads_root_response_code() === 403 ) {
|
|
return false;
|
|
}
|
|
else {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public function get_uploads_protection_message_array()
|
|
{
|
|
$response = [];
|
|
foreach (self::get_protective_files_array() as $file) {
|
|
if ($file === '.htaccess' && self::get_uploads_root_response_code() === 403) {
|
|
$response[] = '<span class="dashicons dashicons-yes"></span> ' . __('.htaccess file is present and access to uploads directory returns 403 code.', $this->plugin_name);
|
|
}
|
|
if ($file === 'index.php') {
|
|
$response[] = '<span class="dashicons dashicons-yes"></span> ' . __('index.php file is present.', $this->plugin_name);
|
|
}
|
|
if ($file === 'index.html') {
|
|
$response[] = '<span class="dashicons dashicons-yes"></span> ' . __('index.html file is present.', $this->plugin_name);
|
|
}
|
|
}
|
|
if (self::check_protective_file('.htaccess') === true && self::get_uploads_root_response_code() === 200) {
|
|
$response[] = '<span class="dashicons dashicons-search"></span> ' . __('.htaccess file is present but not protecting uploads directory.', $this->plugin_name);
|
|
}
|
|
if (self::check_protective_file('.htaccess') === false && self::get_uploads_root_response_code() === 403) {
|
|
$response[] = '<span class="dashicons dashicons-yes"></span> ' . __('Access to uploads directory is protected (403) with a global .htaccess or another global declaration.', $this->plugin_name);
|
|
}
|
|
return $response;
|
|
}
|
|
|
|
public function check_apache()
|
|
{
|
|
|
|
if (!function_exists('apache_get_modules')) {
|
|
self::register_message('The Protect Uploads plugin cannot work without Apache. Yourself or your web host has to activate this module.');
|
|
}
|
|
}
|
|
|
|
|
|
public function register_message($message, $type = 'updated', $id = 0)
|
|
{
|
|
$this->messages['apache'][] = array(
|
|
'message' => __($message, $this->plugin_name),
|
|
'type' => $type,
|
|
'id' => $id
|
|
);
|
|
}
|
|
|
|
public function display_messages()
|
|
{
|
|
|
|
foreach ($this->messages as $name => $messages) {
|
|
foreach ($messages as $message) {
|
|
return '<div id="message" class="' . $message['type'] . '"><p>' . $message['message'] . '</p></div>';
|
|
}
|
|
}
|
|
}
|
|
}
|