mirror of
https://github.com/Neetpone/ponepaste.git
synced 2025-03-12 06:30:07 +01:00
feat: reporting, lots of admin improvements
This commit is contained in:
parent
708eb9be6f
commit
c4d653b13f
20 changed files with 414 additions and 445 deletions
|
@ -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);
|
||||
|
||||
// $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;
|
||||
}
|
||||
|
||||
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;
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
22
includes/Models/Report.php
Normal file
22
includes/Models/Report.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
namespace PonePaste\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Report extends Model {
|
||||
protected $table = 'reports';
|
||||
protected $fillable = [
|
||||
'paste_id',
|
||||
'user_id',
|
||||
'reason',
|
||||
'open'
|
||||
];
|
||||
|
||||
public function user() {
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function paste() {
|
||||
return $this->belongsTo(Paste::class);
|
||||
}
|
||||
}
|
|
@ -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())))");
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -37,3 +37,4 @@ if (isset($_GET['logout'])) {
|
|||
exit();
|
||||
}
|
||||
|
||||
$flashes = getFlashes();
|
||||
|
|
|
@ -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') {
|
|||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
|
|
|
@ -1,36 +1,25 @@
|
|||
<?php
|
||||
$menu_options = [
|
||||
['name' => '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'];
|
||||
?>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<ul class="panel quick-menu clearfix">
|
||||
<li class="col-xs-3 col-sm-2 col-md-1 menu-active">
|
||||
<a href="dashboard.php"><i class="fa fa-home"></i>Dashboard</a>
|
||||
</li>
|
||||
<li class="col-xs-3 col-sm-2 col-md-1">
|
||||
<a href="configuration.php"><i class="fa fa-cogs"></i>Configuration</a>
|
||||
</li>
|
||||
<li class="col-xs-3 col-sm-2 col-md-1">
|
||||
<a href="admin.php"><i class="fa fa-user"></i>Admin Account</a>
|
||||
</li>
|
||||
<li class="col-xs-3 col-sm-2 col-md-1">
|
||||
<a href="reports.php"><i class="fa fa-flag"></i>Reports</a>
|
||||
</li>
|
||||
<li class="col-xs-3 col-sm-2 col-md-1">
|
||||
<a href="pastes.php"><i class="fa fa-clipboard"></i>Pastes</a>
|
||||
</li>
|
||||
<li class="col-xs-3 col-sm-2 col-md-1">
|
||||
<a href="users.php"><i class="fa fa-users"></i>Users</a>
|
||||
</li>
|
||||
<li class="col-xs-3 col-sm-2 col-md-1">
|
||||
<a href="ipbans.php"><i class="fa fa-ban"></i>IP Bans</a>
|
||||
</li>
|
||||
<li class="col-xs-3 col-sm-2 col-md-1">
|
||||
<a href="stats.php"><i class="fa fa-line-chart"></i>Statistics</a>
|
||||
</li>
|
||||
<li class="col-xs-3 col-sm-2 col-md-1">
|
||||
<a href="sitemap.php"><i class="fa fa-map-signs"></i>Sitemap</a>
|
||||
</li>
|
||||
<li class="col-xs-3 col-sm-2 col-md-1">
|
||||
<a href="tasks.php"><i class="fa fa-tasks"></i>Tasks</a>
|
||||
<?php foreach ($menu_options as $option): ?>
|
||||
<li class="col-xs-3 col-sm-2 col-md-1 <?= ($option['path'] === $current_path) ? 'menu-active' : '' ?>">
|
||||
<a href="<?= $option['path']; ?>">
|
||||
<i class="fa <?= $option['icon']; ?>"></i>
|
||||
<?= $option['name']; ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
|
@ -1,6 +1,17 @@
|
|||
<?php
|
||||
define('IN_PONEPASTE', 1);
|
||||
require_once('common.php');
|
||||
require_once(__DIR__ . '/common.php');
|
||||
|
||||
use PonePaste\Models\Paste;
|
||||
|
||||
list($per_page, $current_page) = pp_setup_pagination();
|
||||
|
||||
$total_pastes = Paste::count();
|
||||
$pastes = Paste::with('user')
|
||||
->orderBy('id', 'desc')
|
||||
->limit($per_page)
|
||||
->offset($current_page * $per_page)
|
||||
->get();
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
@ -66,114 +77,6 @@ require_once('common.php');
|
|||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="panel panel-widget">
|
||||
<?php
|
||||
if (isset($_GET['details'])) {
|
||||
$detail_id = htmlentities(Trim($_GET['details']));
|
||||
$query = "SELECT * FROM pastes WHERE id='$detail_id'";
|
||||
$result = mysqli_query($con, $query);
|
||||
while ($row = mysqli_fetch_array($result)) {
|
||||
$p_title = $row['title'];
|
||||
$p_content = $row['content'];
|
||||
$p_visible = $row['visible'];
|
||||
$p_code = $row['code'];
|
||||
$p_expiry = $row['expiry'];
|
||||
$p_password = $row['password'];
|
||||
$p_member = $row['member'];
|
||||
$p_date = $row['date'];
|
||||
$p_encrypt = $row['encrypt'];
|
||||
$p_views = $row['views'];
|
||||
$p_ip = $row['ip'];
|
||||
}
|
||||
if ($p_encrypt == "" || $p_encrypt == null || $p_encrypt == '0') {
|
||||
$encrypt = "Not Encrypted";
|
||||
} else {
|
||||
$encrypt = "Encrypted";
|
||||
}
|
||||
if ($p_expiry == "NULL") {
|
||||
$expiry = "Never";
|
||||
} else {
|
||||
$input_time = $p_expiry;
|
||||
$current_time = mktime(date("H"), date("i"), date("s"), date("n"), date("j"), date("Y"));
|
||||
if ($input_time < $current_time) {
|
||||
$expiry = "Paste is expired";
|
||||
} else {
|
||||
$expiry = "Paste is not expired";
|
||||
}
|
||||
}
|
||||
|
||||
if ($p_password == 'NONE') {
|
||||
$pass = "Not protected";
|
||||
} else {
|
||||
$pass = "Password protected paste";
|
||||
}
|
||||
if ($p_visible == '0') {
|
||||
$visible = "Public";
|
||||
} elseif ($p_visible == '1') {
|
||||
$visible = "Unlisted";
|
||||
} elseif ($p_visible == '2') {
|
||||
$visible = "Private";
|
||||
} else {
|
||||
$visible = "Something went wrong";
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="panel-title">
|
||||
Details of Paste ID <?php echo $detail_id; ?>
|
||||
</div>
|
||||
|
||||
<div class="panel-body table-responsive">
|
||||
<table class="table display dataTable">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td> Username</td>
|
||||
<td> <?php echo $p_member; ?> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> Paste Title</td>
|
||||
<td> <?php echo $p_title; ?> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> Visibility</td>
|
||||
<td> <?php echo $visible; ?> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> Password</td>
|
||||
<td> <?php echo $pass; ?> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> Views</td>
|
||||
<td> <?php echo $p_views; ?> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> IP</td>
|
||||
<td> <?php echo $p_ip; ?> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> Syntax Highlighting</td>
|
||||
<td> <?php echo $p_code; ?> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> Expiration</td>
|
||||
<td> <?php echo $expiry; ?> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> Encrypted Paste</td>
|
||||
<td> <?php echo $encrypt; ?></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<?php } else { ?>
|
||||
|
||||
<div class="panel-body">
|
||||
<div class="panel-title">
|
||||
Manage Pastes
|
||||
|
@ -186,22 +89,33 @@ require_once('common.php');
|
|||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Title</th>
|
||||
<th>Username</th>
|
||||
<th>IP</th>
|
||||
<th>Visibility</th>
|
||||
<th>More Details</th>
|
||||
<th>View Paste</th>
|
||||
<th>Delete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<?php foreach ($pastes as $paste): ?>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="<?= urlForPaste($paste) ?>">
|
||||
<?= pp_html_escape($paste->id); ?>
|
||||
</a>
|
||||
</td>
|
||||
<td><?= pp_html_escape($paste->title); ?></td>
|
||||
<td><?= pp_html_escape($paste->user->username); ?></td>
|
||||
<td><?= pp_html_escape($paste->ip); ?></td>
|
||||
<td><?= pp_html_escape($paste->visible); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
<?= paginate($current_page, $per_page, $total_pastes); ?>
|
||||
|
||||
</div>
|
||||
<!-- End Admin Settings -->
|
||||
</div>
|
||||
|
|
|
@ -1,24 +1,23 @@
|
|||
<?php
|
||||
session_start();
|
||||
define('IN_PONEPASTE', 1);
|
||||
require_once(__DIR__ . '/common.php');
|
||||
|
||||
if (!isset($_SESSION['login'])) {
|
||||
header("Location: .");
|
||||
exit();
|
||||
use PonePaste\Models\Report;
|
||||
|
||||
if (isset($_POST['close_report']) && isset($_POST['report_id'])) {
|
||||
$report = Report::find((int) $_POST['report_id']);
|
||||
if ($report) {
|
||||
$report->open = false;
|
||||
$report->save();
|
||||
}
|
||||
|
||||
if (isset($_GET['logout'])) {
|
||||
if (isset($_SESSION['login']))
|
||||
unset($_SESSION['login']);
|
||||
|
||||
session_destroy();
|
||||
header("Location: .");
|
||||
exit();
|
||||
flashSuccess('Report has been closed.');
|
||||
}
|
||||
|
||||
$date = date('jS F Y');
|
||||
$ip = $_SERVER['REMOTE_ADDR'];
|
||||
require_once('../includes/config.php');
|
||||
|
||||
$reports_count = Report::count();
|
||||
$reports = Report::with('paste', 'user')
|
||||
->orderBy('id', 'desc')
|
||||
->get();
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
@ -62,155 +61,14 @@ require_once('../includes/config.php');
|
|||
<?php include 'menu.php'; ?>
|
||||
<!-- End Menu -->
|
||||
|
||||
<?php
|
||||
if (isset($_GET['remove'])) {
|
||||
$delid = htmlentities(Trim($_GET['remove']));
|
||||
$query = "DELETE FROM user_reports WHERE id=$delid";
|
||||
$result = mysqli_query($con, $query);
|
||||
if (mysqli_errno($con)) {
|
||||
$msg = '<div class="paste-alert alert6" style="text-align: center;">
|
||||
' . mysqli_error($con) . '
|
||||
</div>';
|
||||
} else {
|
||||
$msg = '<div class="paste-alert alert3" style="text-align: center;">
|
||||
Report Removed
|
||||
</div>';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (isset($_GET['delete'])) {
|
||||
$delid = htmlentities(Trim($_GET['delete']));
|
||||
$query = "DELETE FROM pastes WHERE id=$delid";
|
||||
$result = mysqli_query($con, $query);
|
||||
if (mysqli_errno($con)) {
|
||||
$msg = '<div class="paste-alert alert6" style="text-align: center;">
|
||||
' . mysqli_error($con) . '
|
||||
</div>';
|
||||
} else {
|
||||
$msg = '<div class="paste-alert alert3" style="text-align: center;">
|
||||
Report Removed
|
||||
</div>';
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
|
||||
<!-- Start Pastes -->
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="panel panel-widget">
|
||||
<?php
|
||||
if (isset($_GET['details'])) {
|
||||
$detail_id = htmlentities(Trim($_GET['details']));
|
||||
$query = "SELECT * FROM pastes WHERE id='$detail_id'";
|
||||
$result = mysqli_query($con, $query);
|
||||
while ($row = mysqli_fetch_array($result)) {
|
||||
$p_title = $row['title'];
|
||||
$p_content = $row['content'];
|
||||
$p_visible = $row['visible'];
|
||||
$p_code = $row['code'];
|
||||
$p_expiry = $row['expiry'];
|
||||
$p_password = $row['password'];
|
||||
$p_member = $row['member'];
|
||||
$p_date = $row['date'];
|
||||
$p_encrypt = $row['encrypt'];
|
||||
$p_views = $row['views'];
|
||||
$p_ip = $row['ip'];
|
||||
}
|
||||
if ($p_encrypt == "" || $p_encrypt == null || $p_encrypt == '0') {
|
||||
$encrypt = "Not Encrypted";
|
||||
} else {
|
||||
$encrypt = "Encrypted";
|
||||
}
|
||||
if ($p_expiry == "NULL") {
|
||||
$expiry = "Never";
|
||||
} else {
|
||||
$input_time = $p_expiry;
|
||||
$current_time = mktime(date("H"), date("i"), date("s"), date("n"), date("j"), date("Y"));
|
||||
if ($input_time < $current_time) {
|
||||
$expiry = "Paste is expired";
|
||||
} else {
|
||||
$expiry = "Paste is not expired";
|
||||
}
|
||||
}
|
||||
|
||||
if ($p_password == 'NONE') {
|
||||
$pass = "Not protected";
|
||||
} else {
|
||||
$pass = "Password protected paste";
|
||||
}
|
||||
if ($p_visible == '0') {
|
||||
$visible = "Public";
|
||||
} elseif ($p_visible == '1') {
|
||||
$visible = "Unlisted";
|
||||
} elseif ($p_visible == '2') {
|
||||
$visible = "Private";
|
||||
} else {
|
||||
$visible = "Something went wrong";
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="panel-title">
|
||||
Details of Paste ID <?php echo $detail_id; ?>
|
||||
</div>
|
||||
|
||||
<div class="panel-body table-responsive">
|
||||
<table class="table display dataTable">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td> Username</td>
|
||||
<td> <?php echo $p_member; ?> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> Paste Title</td>
|
||||
<td> <?php echo $p_title; ?> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> Visibility</td>
|
||||
<td> <?php echo $visible; ?> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> Password</td>
|
||||
<td> <?php echo $pass; ?> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> Views</td>
|
||||
<td> <?php echo $p_views; ?> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> IP</td>
|
||||
<td> <?php echo $p_ip; ?> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> Syntax Highlighting</td>
|
||||
<td> <?php echo $p_code; ?> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> Expiration</td>
|
||||
<td> <?php echo $expiry; ?> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> Encrypted Paste</td>
|
||||
<td> <?php echo $encrypt; ?></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<?php } else { ?>
|
||||
|
||||
<div class="panel-body">
|
||||
<?php outputFlashes($flashes); ?>
|
||||
<div class="panel-title">
|
||||
Manage Pastes
|
||||
Reports
|
||||
</div>
|
||||
|
||||
<?php if (isset($msg)) echo $msg; ?>
|
||||
|
@ -219,21 +77,45 @@ require_once('../includes/config.php');
|
|||
id="pastesTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>User Reported</th>
|
||||
<th>Paste ID</th>
|
||||
<th>Reason</th>
|
||||
<th>More Details</th>
|
||||
<th>View Paste</th>
|
||||
<th>Delete</th>
|
||||
<th>Time</th>
|
||||
<th>Paste</th>
|
||||
<th>User</th>
|
||||
<th>Report Reason</th>
|
||||
<th>Close Report</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<?php foreach ($reports as $report): ?>
|
||||
<tr class="<?= $report->open ? 'success' : 'danger' ?>">
|
||||
<td><?= pp_html_escape($report->created_at); ?></td>
|
||||
<td>
|
||||
<a href="<?= urlForPaste($report->paste); ?>">
|
||||
<?= pp_html_escape($report->paste->title); ?>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="<?= urlForMember($report->user); ?>">
|
||||
<?= pp_html_escape($report->user->username); ?>
|
||||
</a>
|
||||
</td>
|
||||
<td><?= pp_html_escape($report->reason); ?></td>
|
||||
<td>
|
||||
<?php if ($report->open): ?>
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?= $csrf_token ?> "/>
|
||||
<input type="hidden" name="report_id" value="<?= $report->id ?> "/>
|
||||
<input type="submit" name="close_report" value="Close"
|
||||
class="btn btn-danger"/>
|
||||
</form>
|
||||
<?php else: ?>
|
||||
Already Closed
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -243,28 +125,10 @@ require_once('../includes/config.php');
|
|||
|
||||
<!-- Start Footer -->
|
||||
<div class="row footer">
|
||||
<div class="col-md-6 text-left">
|
||||
<a href="https://github.com/jordansamuel/PASTE" target="_blank">Updates</a> — <a
|
||||
href="https://github.com/jordansamuel/PASTE/issues" target="_blank">Bugs</a>
|
||||
</div>
|
||||
<div class="col-md-6 text-right">
|
||||
Powered by <a href="https://phpaste.sourceforge.io" target="_blank">Paste</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Footer -->
|
||||
|
||||
</div>
|
||||
<!-- End content -->
|
||||
|
||||
<script type="text/javascript" language="javascript" class="init">
|
||||
$(document).ready(function () {
|
||||
$('#pastesTable').dataTable({
|
||||
"processing": true,
|
||||
"serverSide": true,
|
||||
"ajax": "ajax_reports.php"
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript" src="js/bootstrap.min.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -104,6 +104,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||
}
|
||||
|
||||
$editing = isset($_POST['edit']);
|
||||
$deleting = isset($_POST['delete']);
|
||||
|
||||
$paste_title = trim($_POST['title']);
|
||||
|
||||
|
|
|
@ -78,12 +78,17 @@ $paste_is_favourited = $current_user !== null && $current_user->favourites->wher
|
|||
$is_private = $paste->visible === Paste::VISIBILITY_PRIVATE;
|
||||
|
||||
if (!can('view', $paste)) {
|
||||
if ($paste->is_hidden) {
|
||||
$error = 'This paste has been removed by the moderation team.';
|
||||
} else {
|
||||
$error = 'This is a private paste. If you created this paste, please log in to view it.';
|
||||
}
|
||||
|
||||
goto Not_Valid_Paste;
|
||||
}
|
||||
|
||||
/* Paste deletion */
|
||||
if (isset($_POST['delete'])) {
|
||||
if (false && isset($_POST['delete'])) {
|
||||
if (!can('delete', $paste)) {
|
||||
$error = 'You cannot delete someone else\'s paste!';
|
||||
goto Not_Valid_Paste;
|
||||
|
@ -95,6 +100,25 @@ if (isset($_POST['delete'])) {
|
|||
die();
|
||||
}
|
||||
|
||||
if (isset($_POST['hide'])) {
|
||||
if (!can('hide', $paste)) {
|
||||
$error = 'You do not have permission to hide this paste.';
|
||||
goto Not_Valid_Paste;
|
||||
}
|
||||
|
||||
$is_hidden = !$paste->is_hidden;
|
||||
|
||||
if ($is_hidden) {
|
||||
$paste->reports()->update(['open' => false]);
|
||||
}
|
||||
|
||||
$paste->is_hidden = $is_hidden;
|
||||
$paste->save();
|
||||
flashSuccess('Paste hidden.');
|
||||
header('Location: /');
|
||||
die();
|
||||
}
|
||||
|
||||
/* Verify paste password */
|
||||
$password_required = $p_password !== null && $p_password !== 'NONE';
|
||||
$password_valid = true;
|
||||
|
|
81
public/report.php
Normal file
81
public/report.php
Normal file
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
define('IN_PONEPASTE', 1);
|
||||
require_once(__DIR__ . '/../includes/common.php');
|
||||
|
||||
use PonePaste\Models\Paste;
|
||||
|
||||
$error = null;
|
||||
|
||||
if ($current_user === null) {
|
||||
header("Location: /login");
|
||||
die();
|
||||
}
|
||||
|
||||
$paste = Paste::find((int) $_REQUEST['id']);
|
||||
|
||||
if (!$paste) {
|
||||
header('HTTP/1.1 404 Not Found');
|
||||
$error = 'Not found';
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!can('view', $paste)) {
|
||||
$error = 'This is a private paste. Why are you attempting to report it?';
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* $password_ok_pastes is an array of IDs of pastes for which a correct password has already been entered this session. */
|
||||
if (isset($_SESSION['password_ok'])) {
|
||||
$password_ok_pastes = json_decode($_SESSION['password_ok']);
|
||||
} else {
|
||||
$password_ok_pastes = [];
|
||||
}
|
||||
|
||||
$password_required = $paste->password !== null && $paste->password !== 'NONE';
|
||||
if ($password_required && !in_array($paste->id, $password_ok_pastes)) {
|
||||
$error = 'This is a passworded paste, but you have not entered the password for it.';
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (!verifyCsrfToken()) {
|
||||
$error = 'Invalid CSRF token (do you have cookies enabled?)';
|
||||
goto done;
|
||||
}
|
||||
|
||||
// TODO: Check if the paste has already been reported.
|
||||
|
||||
if (empty($_POST['reason'])) {
|
||||
$error = 'You must provide a report reason.';
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ($paste->reports->where('open', true)->isNotEmpty()) {
|
||||
$error = 'This paste has already been reported.';
|
||||
goto done;
|
||||
}
|
||||
|
||||
$paste->reports()->create([
|
||||
'user_id' => $current_user->id,
|
||||
'reason' => $_POST['reason'],
|
||||
'open' => true
|
||||
]);
|
||||
|
||||
flashSuccess('Paste successfully reported.');
|
||||
header('Location: ' . urlForPaste($paste));
|
||||
die();
|
||||
}
|
||||
|
||||
$csrf_token = setupCsrfToken();
|
||||
|
||||
|
||||
$page_template = 'report';
|
||||
$page_title = 'Report Paste';
|
||||
|
||||
done:
|
||||
if ($error) {
|
||||
$page_title = 'Error';
|
||||
$page_template = 'errors';
|
||||
}
|
||||
|
||||
require_once(__DIR__ . '/../theme/' . $default_theme . '/common.php');
|
2
public/theme/bulma/css/bulma.min.css
vendored
2
public/theme/bulma/css/bulma.min.css
vendored
|
@ -8267,7 +8267,7 @@ a.has-text-link-dark:hover {
|
|||
background-color: #2160c4 !important;
|
||||
}
|
||||
.has-text-info {
|
||||
color: #3298dc !important;
|
||||
color: #3298dc;
|
||||
}
|
||||
a.has-text-info:focus,
|
||||
a.has-text-info:hover {
|
||||
|
|
2
public/theme/bulma/css/bulmaswatch.min.css
vendored
2
public/theme/bulma/css/bulmaswatch.min.css
vendored
File diff suppressed because one or more lines are too long
|
@ -1,12 +1,13 @@
|
|||
<?php
|
||||
/* prevent inclusion of arbitrary files */
|
||||
|
||||
use PonePaste\Models\Report;
|
||||
|
||||
$template_candidates = scandir(__DIR__);
|
||||
if (!in_array($page_template . '.php', $template_candidates)) {
|
||||
die('Failed to find template');
|
||||
}
|
||||
|
||||
$start = microtime(true);
|
||||
|
||||
$flashes = getFlashes();
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
|
@ -80,6 +81,15 @@ $flashes = getFlashes();
|
|||
</span>
|
||||
<span>Events</span>
|
||||
</a>
|
||||
<?php if ($current_user !== null && $current_user->admin): ?>
|
||||
<?php $has_reports = Report::where(['open' => true])->count() > 0; ?>
|
||||
<a class="button navbar-item mx-2" href="/admin" <?= $has_reports ? 'style="color: red;"' : '' ?>>
|
||||
<span class="icon has-text-info">
|
||||
<i class="fa <?= $has_reports ? 'fa-exclamation' : 'fa-toolbox' ?>" aria-hidden="true" <?= $has_reports ? 'style="color: red;"' : '' ?>></i>
|
||||
</span>
|
||||
<span>Admin</span>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<?php endif; /* !$site_is_private */ ?>
|
||||
|
||||
<div class="navbar-item has-dropdown is-hoverable">
|
||||
|
|
|
@ -128,6 +128,7 @@
|
|||
<?php }
|
||||
}
|
||||
?>
|
||||
<?php outputFlashes($flashes); ?>
|
||||
<h1 class="subtitle is-4">
|
||||
New Paste
|
||||
</h1>
|
||||
|
|
32
theme/bulma/report.php
Normal file
32
theme/bulma/report.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<main class="bd-main">
|
||||
<div class="bd-side-background"></div>
|
||||
<div class="bd-main-container container">
|
||||
<div class="bd-duo">
|
||||
<div class="bd-lead">
|
||||
<h1 class="title is-5">Reporting <b><?= pp_html_escape($paste->title) ?></b></h1>
|
||||
<form method="post">
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<div class="field">
|
||||
<label class="label" for="reason">Reason</label>
|
||||
<div class="control has-icons-left has-icons-right">
|
||||
<input type="text" class="input" name="reason" id="reason"
|
||||
placeholder="Reason for reporting this paste" maxlength="255">
|
||||
<span class="icon is-small is-left">
|
||||
<i class="fas fa-info"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<?php if (isset($csrf_token)): ?>
|
||||
<input type="hidden" name="csrf_token" value="<?= $csrf_token ?>" />
|
||||
<?php endif; ?>
|
||||
<button type="submit" class="button is-info">Report</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
|
@ -176,8 +176,8 @@
|
|||
<?php foreach ($profile_favs as $paste): ?>
|
||||
<?php
|
||||
$escaped_title = pp_html_escape(truncate($paste->title, 20, 50));
|
||||
$f_date = new DateTime($paste->pivot->f_time);
|
||||
$update_date = new DateTime($paste->updated_at);
|
||||
$f_date = new DateTime($paste->pivot->created_at);
|
||||
$update_date = $paste->updated_at !== null ? new DateTime($paste->updated_at) : $f_date;
|
||||
$delta = $update_date->diff(new DateTime(), true);
|
||||
$pasteJson = array_merge(
|
||||
$paste->only('id', 'title', 'tags', 'views', 'created_at'),
|
||||
|
|
|
@ -56,54 +56,15 @@ $selectedloader = "$bg[$i]"; // set variable equal to which random filename was
|
|||
<div class="bd-duo">
|
||||
<div class="bd-lead">
|
||||
<div class="content panel">
|
||||
<article class="message is-danger" id="panel" style="display: none;">
|
||||
<div class="message-header" style="margin-bottom: 0;">
|
||||
<p style="margin-bottom: 1px;">Report Paste</p>
|
||||
<button class="delete" onclick="closereport()" aria-label="delete"></button>
|
||||
</div>
|
||||
|
||||
<div class="message-body">
|
||||
<div class="columns">
|
||||
<p>Reporting is currently non-functional. Please email admin ( a t ) ponepaste (.) org if this is a serious violation.</p>
|
||||
<!--<div class="column">
|
||||
<p>Please select how this paste violates a rule:</p>
|
||||
</div>
|
||||
<div class="column">
|
||||
<form class="form-horizontal" id="reportpaste" name="preport" action="report.php"
|
||||
method="POST">
|
||||
<div class="select">
|
||||
<select name="reasonrep">
|
||||
<option>Select dropdown</option>
|
||||
<option value="0">Not /mlp/ Related</option>
|
||||
<option value="1">Links to Illegal Content</option>
|
||||
<option value="2">Paste has personal information (Dox)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>-->
|
||||
</div>
|
||||
</div>
|
||||
<!--<div class="column">
|
||||
<input type="hidden" name="reppasteid" value="<?php echo($paste->id); ?>">
|
||||
<div>
|
||||
<div style="text-align: center;">
|
||||
<div id="reportbutton" class="column">
|
||||
<input class="button is-danger is-fullwidth" type="submit" name="reportpaste"
|
||||
id="report" value="Report Paste"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>-->
|
||||
</article>
|
||||
|
||||
<?php outputFlashes($flashes) ?>
|
||||
<div class="columns is-multiline">
|
||||
<div class="column is-4">
|
||||
<span class="tag is-normal"><i class="fa fa-code fa-lg"
|
||||
aria-hidden="true"></i> <?php echo strtoupper(pp_html_escape($paste['code'])); ?></span>
|
||||
aria-hidden="true"></i> <?= strtoupper(pp_html_escape($paste['code'])); ?></span>
|
||||
<span class="tag is-normal"><i class="fa fa-eye fa-lg"
|
||||
aria-hidden="true"></i> <?php echo $paste['views']; ?></span>
|
||||
aria-hidden="true"></i> <?= pp_html_escape($paste['views']); ?></span>
|
||||
<span class="tag is-normal"><i class="fa fa-star fa-lg"
|
||||
aria-hidden="true"></i> <?php echo $fav_count; ?></span>
|
||||
aria-hidden="true"></i> <?= pp_html_escape($fav_count); ?></span>
|
||||
<br>
|
||||
<span class="tag is-normal">
|
||||
<i class="fa fa-file-word fa-lg" aria-hidden="true"></i>
|
||||
|
@ -116,7 +77,7 @@ $selectedloader = "$bg[$i]"; // set variable equal to which random filename was
|
|||
</span>
|
||||
<span class="tag is-normal">
|
||||
<i class="fa fa-list-ol fa-lg" aria-hidden="true"></i>
|
||||
<?php echo substr_count($op_content, "\n") + 1; ?>
|
||||
<?= substr_count($op_content, "\n") + 1; ?>
|
||||
</span>
|
||||
</div>
|
||||
<div class="column is-4 has-text-centered">
|
||||
|
@ -144,7 +105,7 @@ $selectedloader = "$bg[$i]"; // set variable equal to which random filename was
|
|||
<button type="submit" class="icon tool-icon button--no-style"><i class="fas fa-star fa-lg <?= $paste_is_favourited ? '' : 'has-text-grey' ?>" title="Favourite"></i></button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
<a class="icon tool-icon flip" onclick="openreport()"><i
|
||||
<a class="icon tool-icon flip" href="<?= urlForReport($paste); ?>"><i
|
||||
class="far fa-flag fa-lg has-text-grey" title="Report Paste"></i></a>
|
||||
<?php if ($paste['code'] != "pastedown") { ?>
|
||||
<a class="icon tool-icon" href="javascript:togglev();"><i
|
||||
|
@ -205,6 +166,20 @@ $selectedloader = "$bg[$i]"; // set variable equal to which random filename was
|
|||
<div id="paste" style="line-height: 18px;"><?= $p_content ?></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if (can('hide', $paste)): ?>
|
||||
<div class="mod-tools">
|
||||
<p>Moderation Tools</p>
|
||||
<form method="post">
|
||||
<?php if (isset($csrf_token)): ?>
|
||||
<input type="hidden" name="csrf_token" value="<?= $csrf_token ?>" />
|
||||
<?php endif; ?>
|
||||
<div class="field">
|
||||
<input class="button is-small <?= $paste->is_hidden ? 'is-success' : 'is-danger' ?>" type="submit" name="hide" id="hide"
|
||||
value="<?= $paste->is_hidden ? 'Unhide' : 'Hide' ?> Paste" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<!-- Guests -->
|
||||
<?php if ($totalpastes !== 0 && !can('edit', $paste)) { ?>
|
||||
<hr>
|
||||
|
@ -255,7 +230,7 @@ $selectedloader = "$bg[$i]"; // set variable equal to which random filename was
|
|||
onclick="highlight(document.getElementById('code')); return false;"><i
|
||||
class="fa fa-indent"></i> Highlight</a>
|
||||
</div>
|
||||
<div class="level-item">
|
||||
<div class="level-item mx-1">
|
||||
<?php if (isset($csrf_token)): ?>
|
||||
<input type="hidden" name="csrf_token" value="<?= $csrf_token ?>" />
|
||||
<?php endif; ?>
|
||||
|
|
Loading…
Add table
Reference in a new issue