replace the veto system with exceptions
This commit is contained in:
parent
76f79668b5
commit
1c8094cabf
@ -30,15 +30,13 @@ porn
|
||||
else if($word[0] == '/') {
|
||||
// lines that start with slash are regex
|
||||
if(preg_match($word, $comment)) {
|
||||
$event->veto("Comment contains banned terms");
|
||||
break;
|
||||
throw new CommentPostingException("Comment contains banned terms");
|
||||
}
|
||||
}
|
||||
else {
|
||||
// other words are literal
|
||||
if(strpos($comment, $word) !== false) {
|
||||
$event->veto("Comment contains banned terms");
|
||||
break;
|
||||
throw new CommentPostingException("Comment contains banned terms");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,10 +35,12 @@ class BulkAdd implements Extension {
|
||||
$metadata['extension'] = $pathinfo['extension'];
|
||||
$metadata['tags'] = $tags;
|
||||
$metadata['source'] = null;
|
||||
try {
|
||||
$event = new DataUploadEvent($user, $tmpname, $metadata);
|
||||
send_event($event);
|
||||
if($event->vetoed) {
|
||||
return $event->veto_reason;
|
||||
}
|
||||
catch(Exception $ex) {
|
||||
return $ex->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -223,15 +223,10 @@ class DanbooruApi implements Extension
|
||||
$metadata['tags'] = $posttags;
|
||||
$metadata['source'] = $source;
|
||||
|
||||
try {
|
||||
$nevent = new DataUploadEvent($user, $file, $metadata);
|
||||
send_event($nevent);
|
||||
// Did something screw up?
|
||||
if($event->vetoed) {
|
||||
header("HTTP/1.0 409 Conflict");
|
||||
header("X-Danbooru-Errors: $event->veto_reason");
|
||||
return;
|
||||
} else
|
||||
{ // If it went ok, grab the id for the newly uploaded image and pass it in the header
|
||||
// If it went ok, grab the id for the newly uploaded image and pass it in the header
|
||||
$newimg = Image::by_hash($config, $database, $hash);
|
||||
$newid = make_link("post/view/" . $newimg->id);
|
||||
// Did we POST or GET this call?
|
||||
@ -242,6 +237,12 @@ class DanbooruApi implements Extension
|
||||
else
|
||||
header("Location: $newid");
|
||||
}
|
||||
catch(UploadException $ex) {
|
||||
// Did something screw up?
|
||||
header("HTTP/1.0 409 Conflict");
|
||||
header("X-Danbooru-Errors: ". $ex->getMessage());
|
||||
return;
|
||||
}
|
||||
} else
|
||||
{
|
||||
header("HTTP/1.0 409 Conflict");
|
||||
|
@ -47,10 +47,12 @@ class ArchiveFileHandler implements Extension {
|
||||
$metadata['extension'] = $pathinfo['extension'];
|
||||
$metadata['tags'] = $tags;
|
||||
$metadata['source'] = null;
|
||||
try {
|
||||
$event = new DataUploadEvent($user, $tmpname, $metadata);
|
||||
send_event($event);
|
||||
if($event->vetoed) {
|
||||
return $event->veto_reason;
|
||||
}
|
||||
catch(UploadException $ex) {
|
||||
return $ex->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,9 +18,9 @@ class FlashFileHandler implements Extension {
|
||||
send_event(new ThumbnailGenerationEvent($event->hash, $event->type));
|
||||
$image = $this->create_image_from_data("images/$ha/$hash", $event->metadata);
|
||||
if(is_null($image)) {
|
||||
$event->veto("Flash Handler failed to create image object from data. ".
|
||||
throw new UploadException(
|
||||
"Flash Handler failed to create image object from data. ".
|
||||
"Note: compressed flash files are currently unsupported");
|
||||
return;
|
||||
}
|
||||
send_event(new ImageAdditionEvent($event->user, $image));
|
||||
}
|
||||
|
@ -18,16 +18,9 @@ class IcoFileHandler implements Extension {
|
||||
send_event(new ThumbnailGenerationEvent($event->hash, $event->type));
|
||||
$image = $this->create_image_from_data("images/$ha/$hash", $event->metadata);
|
||||
if(is_null($image)) {
|
||||
$event->veto("Handler failed to create image object from data");
|
||||
return;
|
||||
}
|
||||
|
||||
$iae = new ImageAdditionEvent($event->user, $image);
|
||||
send_event($iae);
|
||||
if($iae->vetoed) {
|
||||
$event->veto($iae->veto_reason);
|
||||
return;
|
||||
throw new UploadException("Icon handler failed to create image object from data");
|
||||
}
|
||||
send_event(new ImageAdditionEvent($event->user, $image));
|
||||
}
|
||||
|
||||
if(($event instanceof ThumbnailGenerationEvent) && $this->supported_ext($event->type)) {
|
||||
|
@ -18,8 +18,7 @@ class MP3FileHandler implements Extension {
|
||||
send_event(new ThumbnailGenerationEvent($event->hash, $event->type));
|
||||
$image = $this->create_image_from_data("images/$ha/$hash", $event->metadata);
|
||||
if(is_null($image)) {
|
||||
$event->veto("MP3 Handler failed to create image object from data");
|
||||
return;
|
||||
throw new UploadException("MP3 handler failed to create image object from data");
|
||||
}
|
||||
send_event(new ImageAdditionEvent($event->user, $image));
|
||||
}
|
||||
|
@ -18,8 +18,7 @@ class SVGFileHandler implements Extension {
|
||||
send_event(new ThumbnailGenerationEvent($event->hash, $event->type));
|
||||
$image = $this->create_image_from_data("images/$ha/$hash", $event->metadata);
|
||||
if(is_null($image)) {
|
||||
$event->veto("SVG Handler failed to create image object from data");
|
||||
return;
|
||||
throw new UploadException("SVG handler failed to create image object from data");
|
||||
}
|
||||
send_event(new ImageAdditionEvent($event->user, $image));
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ class ImageBan implements Extension {
|
||||
|
||||
$row = $database->db->GetRow("SELECT * FROM image_bans WHERE hash = ?", $event->hash);
|
||||
if($row) {
|
||||
$event->veto("Image ".html_escape($row["hash"])." has been banned, reason: ".format_text($row["reason"]));
|
||||
throw new UploadException("Image ".html_escape($row["hash"])." has been banned, reason: ".format_text($row["reason"]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,10 +18,10 @@ class ResolutionLimit implements Extension {
|
||||
|
||||
$image = $event->image;
|
||||
|
||||
if($min_w > 0 && $image->width < $min_w) $event->veto("Image too small");
|
||||
if($min_h > 0 && $image->height < $min_h) $event->veto("Image too small");
|
||||
if($max_w > 0 && $image->width > $min_w) $event->veto("Image too large");
|
||||
if($max_h > 0 && $image->height > $min_h) $event->veto("Image too large");
|
||||
if($min_w > 0 && $image->width < $min_w) throw new UploadException("Image too small");
|
||||
if($min_h > 0 && $image->height < $min_h) throw new UploadException("Image too small");
|
||||
if($max_w > 0 && $image->width > $min_w) throw new UploadExceptiono("Image too large");
|
||||
if($max_h > 0 && $image->height > $min_h) throw new UploadException("Image too large");
|
||||
|
||||
if(count($ratios) > 0) {
|
||||
$ok = false;
|
||||
@ -36,7 +36,9 @@ class ResolutionLimit implements Extension {
|
||||
}
|
||||
}
|
||||
if(!$ok) {
|
||||
$event->veto("Image needs to be in one of these ratios: ".html_escape($config->get_string("upload_ratios", "")));
|
||||
throw new UploadException(
|
||||
"Image needs to be in one of these ratios: ".
|
||||
html_escape($config->get_string("upload_ratios", "")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,17 +5,10 @@
|
||||
*/
|
||||
abstract class Event {
|
||||
var $context;
|
||||
var $vetoed = false;
|
||||
var $veto_reason;
|
||||
|
||||
public function __construct(RequestContext $context) {
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
public function veto($reason="") {
|
||||
$this->vetoed = true;
|
||||
$this->veto_reason = $reason;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -485,7 +485,7 @@ function move_upload_to_archive($event) {
|
||||
$hash = $event->hash;
|
||||
$ha = substr($hash, 0, 2);
|
||||
if(!@copy($event->tmpname, "images/$ha/$hash")) {
|
||||
$event->veto("Failed to copy file from uploads ({$event->tmpname}) to archive (images/$ha/$hash)");
|
||||
throw new UploadException("Failed to copy file from uploads ({$event->tmpname}) to archive (images/$ha/$hash)");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -380,7 +380,6 @@ function send_event(Event $event) {
|
||||
ksort($my_event_listeners);
|
||||
foreach($my_event_listeners as $listener) {
|
||||
$listener->receive_event($event);
|
||||
if($event->vetoed) break;
|
||||
}
|
||||
$_event_count++;
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ class AddAliasEvent extends Event {
|
||||
}
|
||||
}
|
||||
|
||||
class AddAliasException extends SCoreException {}
|
||||
|
||||
class AliasEditor implements Extension {
|
||||
var $theme;
|
||||
|
||||
@ -20,15 +22,15 @@ class AliasEditor implements Extension {
|
||||
if($event->get_arg(0) == "add") {
|
||||
if($event->user->is_admin()) {
|
||||
if(isset($_POST['oldtag']) && isset($_POST['newtag'])) {
|
||||
try {
|
||||
$aae = new AddAliasEvent($_POST['oldtag'], $_POST['newtag']);
|
||||
send_event($aae);
|
||||
if($aae->vetoed) {
|
||||
$this->theme->display_error($event->page, "Error adding alias", $aae->veto_reason);
|
||||
}
|
||||
else {
|
||||
$event->page->set_mode("redirect");
|
||||
$event->page->set_redirect(make_link("alias/list"));
|
||||
}
|
||||
catch(AddAliasException $ex) {
|
||||
$this->theme->display_error($event->page, "Error adding alias", $ex->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -80,7 +82,7 @@ class AliasEditor implements Extension {
|
||||
global $database;
|
||||
$pair = array($event->oldtag, $event->newtag);
|
||||
if($database->db->GetRow("SELECT * FROM aliases WHERE oldtag=? AND lower(newtag)=lower(?)", $pair)) {
|
||||
$event->veto("That alias already exists");
|
||||
throw new AddAliasException("That alias already exists");
|
||||
}
|
||||
else {
|
||||
$database->Execute("INSERT INTO aliases(oldtag, newtag) VALUES(?, ?)", $pair);
|
||||
|
@ -35,6 +35,7 @@ class CommentDeletionEvent extends Event {
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
class CommentPostingException extends SCoreException {}
|
||||
|
||||
class Comment { // {{{
|
||||
public function Comment($row) {
|
||||
@ -68,15 +69,15 @@ class CommentList implements Extension {
|
||||
|
||||
if(($event instanceof PageRequestEvent) && $event->page_matches("comment")) {
|
||||
if($event->get_arg(0) == "add") {
|
||||
try {
|
||||
$cpe = new CommentPostingEvent($_POST['image_id'], $event->user, $_POST['comment']);
|
||||
send_event($cpe);
|
||||
if($cpe->vetoed) {
|
||||
$this->theme->display_error($event->page, "Comment Blocked", $cpe->veto_reason);
|
||||
}
|
||||
else {
|
||||
$event->page->set_mode("redirect");
|
||||
$event->page->set_redirect(make_link("post/view/".int_escape($_POST['image_id'])));
|
||||
}
|
||||
catch(CommentPostingException $ex) {
|
||||
$this->theme->display_error($event->page, "Comment Blocked", $ex->getMessage());
|
||||
}
|
||||
}
|
||||
else if($event->get_arg(0) == "delete") {
|
||||
if($event->user->is_admin()) {
|
||||
@ -346,37 +347,39 @@ class CommentList implements Extension {
|
||||
|
||||
// basic sanity checks
|
||||
if(!$config->get_bool('comment_anon') && $user->is_anonymous()) {
|
||||
$event->veto("Anonymous posting has been disabled");
|
||||
throw new CommentPostingException("Anonymous posting has been disabled");
|
||||
}
|
||||
else if(is_null(Image::by_id($config, $database, $image_id))) {
|
||||
$event->veto("The image does not exist");
|
||||
throw new CommentPostingException("The image does not exist");
|
||||
}
|
||||
else if(trim($comment) == "") {
|
||||
$event->veto("Comments need text...");
|
||||
throw new CommentPostingException("Comments need text...");
|
||||
}
|
||||
else if(strlen($comment) > 9000) {
|
||||
$event->veto("Comment too long~");
|
||||
throw new CommentPostingException("Comment too long~");
|
||||
}
|
||||
|
||||
// advanced sanity checks
|
||||
else if(strlen($comment)/strlen(gzcompress($comment)) > 10) {
|
||||
$event->veto("Comment too repetitive~");
|
||||
throw new CommentPostingException("Comment too repetitive~");
|
||||
}
|
||||
else if($user->is_anonymous() && !$this->hash_match()) {
|
||||
$event->veto("Comment submission form is out of date; refresh the comment form to show you aren't a spammer~");
|
||||
throw new CommentPostingException(
|
||||
"Comment submission form is out of date; refresh the ".
|
||||
"comment form to show you aren't a spammer~");
|
||||
}
|
||||
|
||||
// database-querying checks
|
||||
else if($this->is_comment_limit_hit()) {
|
||||
$event->veto("You've posted several comments recently; wait a minute and try again...");
|
||||
throw new CommentPostingException("You've posted several comments recently; wait a minute and try again...");
|
||||
}
|
||||
else if($this->is_dupe($image_id, $comment)) {
|
||||
$event->veto("Someone already made that comment on that image -- try and be more original?");
|
||||
throw new CommentPostingException("Someone already made that comment on that image -- try and be more original?");
|
||||
}
|
||||
|
||||
// rate-limited external service checks last
|
||||
else if($user->is_anonymous() && $this->is_spam($comment)) {
|
||||
$event->veto("Akismet thinks that your comment is spam. Try rewriting the comment, or logging in.");
|
||||
throw new CommentPostingException("Akismet thinks that your comment is spam. Try rewriting the comment, or logging in.");
|
||||
}
|
||||
|
||||
// all checks passed
|
||||
|
@ -18,16 +18,11 @@ class PixelFileHandler implements Extension {
|
||||
send_event(new ThumbnailGenerationEvent($event->hash, $event->type));
|
||||
$image = $this->create_image_from_data("images/$ha/$hash", $event->metadata);
|
||||
if(is_null($image)) {
|
||||
$event->veto("Pixel Handler failed to create image object from data");
|
||||
return;
|
||||
throw new UploadException("Pixel Handler failed to create image object from data");
|
||||
}
|
||||
|
||||
$iae = new ImageAdditionEvent($event->user, $image);
|
||||
send_event($iae);
|
||||
if($iae->vetoed) {
|
||||
$event->veto($iae->veto_reason);
|
||||
return;
|
||||
}
|
||||
send_event($iae); // this might raise an exception, but all we'd do is re-throw it...
|
||||
}
|
||||
|
||||
if(($event instanceof ThumbnailGenerationEvent) && $this->supported_ext($event->type)) {
|
||||
|
@ -107,7 +107,7 @@ class ImageIO implements Extension {
|
||||
|
||||
if($event instanceof ImageAdditionEvent) {
|
||||
$error = $this->add_image($event->image);
|
||||
if(!empty($error)) $event->veto($error);
|
||||
if(!empty($error)) throw new UploadException($error);
|
||||
}
|
||||
|
||||
if($event instanceof ImageDeletionEvent) {
|
||||
|
@ -59,7 +59,6 @@ class Index implements Extension {
|
||||
else {
|
||||
$event->page->set_mode("redirect");
|
||||
$event->page->set_redirect(make_link("post/list/$search/1"));
|
||||
//$event->veto();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -24,6 +24,8 @@ class DataUploadEvent extends Event {
|
||||
}
|
||||
}
|
||||
|
||||
class UploadException extends SCoreException {}
|
||||
|
||||
class Upload implements Extension {
|
||||
var $theme;
|
||||
// event handling {{{
|
||||
@ -113,12 +115,12 @@ class Upload implements Extension {
|
||||
if($event instanceof DataUploadEvent) {
|
||||
global $config;
|
||||
if($is_full) {
|
||||
$event->veto("Upload failed; disk nearly full");
|
||||
throw new UploadException("Upload failed; disk nearly full");
|
||||
}
|
||||
if(filesize($event->tmpname) > $config->get_int('upload_size')) {
|
||||
$size = to_shorthand_int(filesize($event->tmpname));
|
||||
$limit = to_shorthand_int($config->get_int('upload_size'));
|
||||
$event->veto("File too large ($size > $limit)");
|
||||
throw new UploadException("File too large ($size > $limit)");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -146,10 +148,12 @@ class Upload implements Extension {
|
||||
$metadata['tags'] = $tags;
|
||||
$metadata['source'] = $source;
|
||||
$event = new DataUploadEvent($user, $file['tmp_name'], $metadata);
|
||||
try {
|
||||
send_event($event);
|
||||
if($event->vetoed) {
|
||||
}
|
||||
catch(UploadException $ex) {
|
||||
$this->theme->display_upload_error($page, "Error with ".html_escape($file['name']),
|
||||
$event->veto_reason);
|
||||
$ex->getMessage());
|
||||
$ok = false;
|
||||
}
|
||||
}
|
||||
@ -224,10 +228,12 @@ class Upload implements Extension {
|
||||
$metadata['tags'] = $tags;
|
||||
$metadata['source'] = $source;
|
||||
$event = new DataUploadEvent($user, $tmp_filename, $metadata);
|
||||
try {
|
||||
send_event($event);
|
||||
if($event->vetoed) {
|
||||
}
|
||||
catch(UploadException $ex) {
|
||||
$this->theme->display_upload_error($page, "Error with ".html_escape($url),
|
||||
$event->veto_reason);
|
||||
$ex->getMessage());
|
||||
$ok = false;
|
||||
}
|
||||
}
|
||||
@ -238,5 +244,5 @@ class Upload implements Extension {
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
add_event_listener(new Upload(), 40); // early, so it can veto the DataUploadEvent before any data handlers see it
|
||||
add_event_listener(new Upload(), 40); // early, so it can stop the DataUploadEvent before any data handlers see it
|
||||
?>
|
||||
|
@ -36,6 +36,8 @@ class UserCreationEvent extends Event {
|
||||
}
|
||||
}
|
||||
|
||||
class UserCreationException extends SCoreException {}
|
||||
|
||||
class UserPage implements Extension {
|
||||
var $theme;
|
||||
|
||||
@ -81,16 +83,16 @@ class UserPage implements Extension {
|
||||
$this->theme->display_error($event->page, "Password Mismatch", "Passwords don't match");
|
||||
}
|
||||
else {
|
||||
try {
|
||||
$uce = new UserCreationEvent($_POST['name'], $_POST['pass1'], $_POST['email']);
|
||||
send_event($uce);
|
||||
if($uce->vetoed) {
|
||||
$this->theme->display_error($event->page, "User Creation Error", $uce->veto_reason);
|
||||
}
|
||||
else {
|
||||
$this->set_login_cookie($uce->username, $uce->password);
|
||||
$event->page->set_mode("redirect");
|
||||
$event->page->set_redirect(make_link("user"));
|
||||
}
|
||||
catch(UserCreationException $ex) {
|
||||
$this->theme->display_error($event->page, "User Creation Error", $ex->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if($event->get_arg(0) == "set_more") {
|
||||
@ -210,16 +212,16 @@ class UserPage implements Extension {
|
||||
global $database;
|
||||
|
||||
if(strlen($name) < 1) {
|
||||
$event->veto("Username must be at least 1 character");
|
||||
throw new UserCreationException("Username must be at least 1 character");
|
||||
}
|
||||
else if(!preg_match('/^[a-zA-Z0-9-_]+$/', $name)) {
|
||||
$event->veto("Username contains invalid characters. Allowed characters are letters, numbers, dash, and underscore");
|
||||
throw new UserCreationException(
|
||||
"Username contains invalid characters. Allowed characters are ".
|
||||
"letters, numbers, dash, and underscore");
|
||||
}
|
||||
else if($database->db->GetRow("SELECT * FROM users WHERE name = ?", array($name))) {
|
||||
$event->veto("That username is already taken");
|
||||
throw new UserCreationException("That username is already taken");
|
||||
}
|
||||
|
||||
return (!$event->vetoed);
|
||||
}
|
||||
|
||||
private function create_user($event) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user