Added ImageDownloadingEvent that allows extensions to stop a user from viewing an image or perform other operations on the image before the image is downloaded to the user

This commit is contained in:
Matthew Barbour 2020-06-16 18:40:13 -05:00 committed by Shish
parent 40b80bca93
commit 9b5d963aa3
8 changed files with 130 additions and 14 deletions

View file

@ -99,9 +99,9 @@ class Approval extends Extension
public function onDisplayingImage(DisplayingImageEvent $event)
{
global $user, $page, $config;
global $page;
if ($config->get_bool(ApprovalConfig::IMAGES) && $event->image->approved===false && !$user->can(Permissions::APPROVE_IMAGE)) {
if (!$this->check_permissions(($event->image))) {
$page->set_mode(PageMode::REDIRECT);
$page->set_redirect(make_link("post/list"));
}
@ -187,6 +187,26 @@ class Approval extends Extension
);
}
private function check_permissions(Image $image): bool
{
global $user, $config;
if ($config->get_bool(ApprovalConfig::IMAGES) && $image->approved===false && !$user->can(Permissions::APPROVE_IMAGE)) {
return false;
}
return true;
}
public function onImageDownloading(ImageDownloadingEvent $event)
{
/**
* Deny images upon insufficient permissions.
**/
if (!$this->check_permissions($event->image)) {
throw new SCoreException("Access denied");
}
}
public function onImageAdminBlockBuilding(ImageAdminBlockBuildingEvent $event)
{
global $user, $config;

16
ext/download/events.php Normal file
View file

@ -0,0 +1,16 @@
<?php
class ImageDownloadingEvent extends Event
{
public $image;
public $mime;
public $path;
public $file_modified = false;
public function __construct(Image $image, String $path, string $mime)
{
$this->image = $image;
$this->path = $path;
$this->mime = $mime;
}
}

14
ext/download/info.php Normal file
View file

@ -0,0 +1,14 @@
<?php
class DownloadInfo extends ExtensionInfo
{
public const KEY = "download";
public $key = self::KEY;
public $name = "Download";
public $authors = ["Matthew Barbour"=>"matthew@darkholme.net"];
public $license = self::LICENSE_WTFPL;
public $description = "System-wide download functions";
public $core = true;
public $visibility = self::VISIBLE_HIDDEN;
}

26
ext/download/main.php Normal file
View file

@ -0,0 +1,26 @@
<?php
require_once "events.php";
class Download extends Extension
{
public function get_priority(): int
{
// Set near the end to give everything else a chance to process
return 99;
}
public function onImageDownloading(ImageDownloadingEvent $event)
{
global $page;
$page->set_mime($event->mime);
$page->set_mode(PageMode::FILE);
$page->set_file($event->path, $event->file_modified);
$event->stop_processing = true;
}
}

View file

@ -271,10 +271,9 @@ class ImageIO extends Extension
private function send_file(int $image_id, string $type)
{
global $config;
$image = Image::by_id($image_id);
global $config, $page;
global $page;
$image = Image::by_id($image_id);
if (!is_null($image)) {
if ($type == "thumb") {
$ext = $config->get_string(ImageConfig::THUMB_TYPE);
@ -285,7 +284,6 @@ class ImageIO extends Extension
$page->set_type($image->get_mime_type());
$file = $image->get_image_filename();
}
if (!file_exists($file)) {
http_response_code(404);
die();
@ -319,6 +317,8 @@ class ImageIO extends Extension
}
$page->add_http_header('Expires: ' . $expires);
}
send_event(new ImageDownloadingEvent($image, $file, $mime));
} else {
$page->set_title("Not Found");
$page->set_heading("Not Found");

View file

@ -28,9 +28,9 @@ class RandomImage extends Extension
}
if ($action === "download") {
$page->set_mode(PageMode::DATA);
$page->set_type($image->get_mime_type());
$page->set_data(file_get_contents($image->get_image_filename()));
if (!is_null($image)) {
send_event(new ImageDownloadingEvent($image, $image->get_image_filename(), $image->get_mime_type()));
}
} elseif ($action === "view") {
send_event(new DisplayingImageEvent($image));
} elseif ($action === "widget") {

View file

@ -115,11 +115,32 @@ class Ratings extends Extension
}
}
private function check_permissions(Image $image): bool
{
global $user;
$user_view_level = Ratings::get_user_class_privs($user);
if (!in_array($image->rating, $user_view_level)) {
return false;
}
return true;
}
public function onInitUserConfig(InitUserConfigEvent $event)
{
$event->user_config->set_default_array(RatingsConfig::USER_DEFAULTS, self::get_user_class_privs($event->user));
}
public function onImageDownloading(ImageDownloadingEvent $event)
{
/**
* Deny images upon insufficient permissions.
**/
if (!$this->check_permissions($event->image)) {
throw new SCoreException("Access denied");
}
}
public function onUserOptionsBuilding(UserOptionsBuildingEvent $event)
{
global $user;
@ -159,12 +180,11 @@ class Ratings extends Extension
public function onDisplayingImage(DisplayingImageEvent $event)
{
global $user, $page;
global $page;
/**
* Deny images upon insufficient permissions.
**/
$user_view_level = Ratings::get_user_class_privs($user);
if (!in_array($event->image->rating, $user_view_level)) {
if (!$this->check_permissions($event->image)) {
$page->set_mode(PageMode::REDIRECT);
$page->set_redirect(make_link("post/list"));
}

View file

@ -41,11 +41,31 @@ class Trash extends Extension
}
}
private function check_permissions(Image $image): bool
{
global $user;
if ($image->trash===true && !$user->can(Permissions::VIEW_TRASH)) {
return false;
}
return true;
}
public function onImageDownloading(ImageDownloadingEvent $event)
{
/**
* Deny images upon insufficient permissions.
**/
if (!$this->check_permissions($event->image)) {
throw new SCoreException("Access denied");
}
}
public function onDisplayingImage(DisplayingImageEvent $event)
{
global $user, $page;
global $page;
if ($event->image->trash===true && !$user->can(Permissions::VIEW_TRASH)) {
if (!$this->check_permissions(($event->image))) {
$page->set_mode(PageMode::REDIRECT);
$page->set_redirect(make_link("post/list"));
}