diff --git a/includes/Helpers/AbilityHelper.php b/includes/Helpers/AbilityHelper.php index 97caf25..f4df8e2 100644 --- a/includes/Helpers/AbilityHelper.php +++ b/includes/Helpers/AbilityHelper.php @@ -5,31 +5,64 @@ use PonePaste\Models\User; use PonePaste\Models\Paste; class AbilityHelper { - private const DESTRUCTIVE_ACTIONS = [ - 'edit', 'delete' - ]; - + private array $modelToActions = []; private User | null $user; public function __construct(User | null $user) { $this->user = $user; + $this->setupAllowedActions(); } public function can(string $action, mixed $subject) : bool { - $is_destructive = in_array($action, self::DESTRUCTIVE_ACTIONS); - - if (is_a($subject, 'PonePaste\\Models\\Paste')) { - if (((int) $subject->visible === Paste::VISIBILITY_PRIVATE) || $is_destructive) { - return $this->user !== null && $subject->user_id === $this->user->id; - } - + if ($this->user && $this->user->admin) { return true; } - if (is_a($subject, 'PonePaste\\Models\\User')) { - return !$is_destructive || ($this->user !== null && $subject->id === $this->user->id); - } + return $this->modelToActions[$subject::class][$action]($this->user, $subject); - return false; +// $is_destructive = in_array($action, self::DESTRUCTIVE_ACTIONS); +// +// if (is_a($subject, 'PonePaste\\Models\\Paste')) { +// if (((int) $subject->visible === Paste::VISIBILITY_PRIVATE) || $is_destructive) { +// return $this->user !== null && $subject->user_id === $this->user->id; +// } +// +// if ($subject->is_hidden) { +// return false; +// } +// +// return true; +// } +// +// if (is_a($subject, 'PonePaste\\Models\\User')) { +// return !$is_destructive || ($this->user !== null && $subject->id === $this->user->id); +// } +// +// return false; + } + + private function setupAllowedActions() : void { + $this->modelToActions['PonePaste\\Models\\Paste'] = [ + 'view' => function(User | null $user, Paste $paste) { + return ((int) $paste->visible !== Paste::VISIBILITY_PRIVATE && !$paste->is_hidden) || ($user !== null && $user->id === $paste->user_id); + }, + 'edit' => function(User | null $user, Paste $paste) { + return $user !== null && $user->id === $paste->user_id; + }, + 'hide' => function(User | null $user, Paste $paste) { + return $user !== null && $user->admin; + }, + 'delete' => function(User | null $user, Paste $paste) { + return $user !== null && $user->id === $paste->user_id; + } + ]; + $this->modelToActions['PonePaste\\Models\\User'] = [ + 'view' => function(User | null $user, User $subject) { + return true; + }, + 'edit' => function(User | null $user, User $subject) { + return $user !== null && $user->id === $subject->id; + }, + ]; } } diff --git a/includes/Models/Paste.php b/includes/Models/Paste.php index 3156b0f..765ae23 100644 --- a/includes/Models/Paste.php +++ b/includes/Models/Paste.php @@ -31,6 +31,10 @@ class Paste extends Model { return $this->belongsToMany(User::class, 'user_favourites'); } + public function reports() { + return $this->hasMany(Report::class); + } + public function replaceTags(array $tags) { $this->tags()->detach(); @@ -63,6 +67,7 @@ class Paste extends Model { return Paste::with('user') ->orderBy('created_at', 'DESC') ->where('visible', self::VISIBILITY_PUBLIC) + ->where('is_hidden', false) ->whereRaw("((expiry IS NULL) OR ((expiry != 'SELF') AND (expiry > NOW())))") ->limit($count)->get(); } @@ -71,6 +76,7 @@ class Paste extends Model { return Paste::with('user') ->orderBy('updated_at', 'DESC') ->where('visible', self::VISIBILITY_PUBLIC) + ->where('is_hidden', false) ->whereRaw("((expiry IS NULL) OR ((expiry != 'SELF') AND (expiry > NOW())))") ->limit($count)->get(); } @@ -79,6 +85,7 @@ class Paste extends Model { return Paste::with('user') ->orderBy('views') ->where('visible', self::VISIBILITY_PUBLIC) + ->where('is_hidden', false) ->whereRaw("((expiry IS NULL) OR ((expiry != 'SELF') AND (expiry > NOW())))") ->limit($count)->get(); } @@ -87,6 +94,7 @@ class Paste extends Model { return Paste::with('user') ->whereRaw('MONTH(created_at) = MONTH(NOW())') ->where('visible', self::VISIBILITY_PUBLIC) + ->where('is_hidden', false) ->whereRaw("((expiry IS NULL) OR ((expiry != 'SELF') AND (expiry > NOW())))") ->orderBy('views') ->limit($count)->get(); @@ -94,9 +102,10 @@ class Paste extends Model { public static function getRandom(int $count = 10) : Collection { return Paste::with('user') - ->orderByRaw('RAND()') ->where('visible', self::VISIBILITY_PUBLIC) + ->where('is_hidden', false) ->whereRaw("((expiry IS NULL) OR ((expiry != 'SELF') AND (expiry > NOW())))") + ->orderByRaw('RAND()') ->limit($count)->get(); } } diff --git a/includes/Models/Report.php b/includes/Models/Report.php new file mode 100644 index 0000000..a14600f --- /dev/null +++ b/includes/Models/Report.php @@ -0,0 +1,22 @@ +belongsTo(User::class); + } + + public function paste() { + return $this->belongsTo(Paste::class); + } +} diff --git a/includes/Models/User.php b/includes/Models/User.php index 95fd362..55f0334 100644 --- a/includes/Models/User.php +++ b/includes/Models/User.php @@ -14,7 +14,7 @@ class User extends Model { } public function favourites() { - return $this->belongsToMany(Paste::class, 'user_favourites')->withPivot('f_time') + return $this->belongsToMany(Paste::class, 'user_favourites')->withPivot('created_at') ->whereRaw("((expiry IS NULL) OR ((expiry != 'SELF') AND (expiry > NOW())))"); } diff --git a/includes/common.php b/includes/common.php index eef5949..c678b28 100644 --- a/includes/common.php +++ b/includes/common.php @@ -41,6 +41,14 @@ function urlForPaste(Paste $paste) : string { return "/paste.php?id={$paste->id}"; } +function urlForReport(Paste $paste) : string { + if (PP_MOD_REWRITE) { + return "/{$paste->id}/report"; + } + + return "/report.php?id={$paste->id}"; +} + function urlForMember(User $user) : string { if (PP_MOD_REWRITE) { return '/user/' . urlencode($user->username); @@ -268,6 +276,7 @@ $total_page_views = PageView::select('tpage')->orderBy('id', 'desc')->first()->t $total_unique_views = PageView::select('tvisit')->orderBy('id', 'desc')->first()->tvisit; $current_user = SessionHelper::currentUser(); +$start = microtime(true); function can(string $action, mixed $subject) : bool { global $current_user; diff --git a/public/admin/common.php b/public/admin/common.php index 25ca205..4ae35b3 100644 --- a/public/admin/common.php +++ b/public/admin/common.php @@ -37,3 +37,4 @@ if (isset($_GET['logout'])) { exit(); } +$flashes = getFlashes(); diff --git a/public/admin/index.php b/public/admin/index.php index c16c631..7efe277 100644 --- a/public/admin/index.php +++ b/public/admin/index.php @@ -20,6 +20,11 @@ if ($current_user === null || !$current_user->admin) { die(); } +if (isset($_SESSION['admin_login']) && $_SESSION['admin_login']) { + header('Location: dashboard.php'); + exit(); +} + if ($_SERVER['REQUEST_METHOD'] == 'POST') { if (pp_password_verify($_POST['password'], $current_user->admin_password_hash)) { updateAdminHistory($current_user, AdminLog::ACTION_LOGIN); @@ -34,7 +39,6 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') { } } ?> - diff --git a/public/admin/menu.php b/public/admin/menu.php index 9c3771f..61ea563 100644 --- a/public/admin/menu.php +++ b/public/admin/menu.php @@ -1,36 +1,25 @@ + 'Dashboard', 'icon' => 'fa-home', 'path' => '/admin/dashboard.php'], + ['name' => 'Configuration', 'icon' => 'fa-cogs', 'path' => '/admin/configuration.php'], + ['name' => 'Admin Password', 'icon' => 'fa-user', 'path' => '/admin/admin.php'], + ['name' => 'Reports', 'icon' => 'fa-flag', 'path' => '/admin/reports.php'], + ['name' => 'Pastes', 'icon' => 'fa-clipboard', 'path' => '/admin/pastes.php'], + ['name' => 'Users', 'icon' => 'fa-users', 'path' => '/admin/users.php'] + ]; + $current_path = $_SERVER['PHP_SELF']; +?>
-
\ No newline at end of file + diff --git a/public/admin/pastes.php b/public/admin/pastes.php index b0f1804..fe8e750 100644 --- a/public/admin/pastes.php +++ b/public/admin/pastes.php @@ -1,6 +1,17 @@ orderBy('id', 'desc') + ->limit($per_page) + ->offset($current_page * $per_page) + ->get(); ?> @@ -26,7 +37,7 @@ require_once('common.php');