mirror of
https://git.wownero.com/lza_menace/suchwow.git
synced 2024-08-15 01:03:19 +00:00
add audit logs
This commit is contained in:
parent
143d08f2f7
commit
3094205362
7 changed files with 71 additions and 17 deletions
|
@ -3,7 +3,7 @@ from os import makedirs
|
|||
import click
|
||||
from flask import Blueprint, url_for, current_app
|
||||
|
||||
from suchwow.models import Post, Profile, Comment, Notification, db, Moderator, Ban
|
||||
from suchwow.models import Post, Profile, Comment, Notification, db, Moderator, Ban, AuditEvent
|
||||
from suchwow.utils.helpers import get_latest_tipped_posts
|
||||
from suchwow.utils.helpers import get_top_posters, get_top_posts
|
||||
from suchwow.reddit import make_post
|
||||
|
@ -20,7 +20,7 @@ def init():
|
|||
makedirs(f"{config.DATA_FOLDER}/{i}", exist_ok=True)
|
||||
|
||||
# init db
|
||||
db.create_tables([Post, Profile, Comment, Notification, Moderator, Ban])
|
||||
db.create_tables([Post, Profile, Comment, Notification, Moderator, Ban, AuditEvent])
|
||||
|
||||
|
||||
@bp.cli.command("post_reddit")
|
||||
|
|
|
@ -143,3 +143,12 @@ class Ban(Model):
|
|||
|
||||
class Meta:
|
||||
database = db
|
||||
|
||||
class AuditEvent(Model):
|
||||
id = AutoField()
|
||||
user = ForeignKeyField(Profile)
|
||||
timestamp = DateTimeField(default=datetime.now)
|
||||
action = CharField()
|
||||
|
||||
class Meta:
|
||||
database = db
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
from flask import Blueprint, render_template, redirect, url_for, flash, request
|
||||
|
||||
from suchwow.models import Post, Profile, Moderator, Ban, get_ban_reason
|
||||
from suchwow.models import AuditEvent, Post, Profile, Moderator, Ban, get_ban_reason
|
||||
from suchwow.utils.decorators import moderator_required
|
||||
from suchwow.utils.helpers import get_session_user
|
||||
from suchwow.utils.helpers import get_session_user, audit_event
|
||||
from suchwow import config
|
||||
|
||||
|
||||
|
@ -48,6 +48,7 @@ def manage_mods():
|
|||
flash('Cannot delete super admin you son-of-a-bitch.', 'is-danger')
|
||||
else:
|
||||
m.delete_instance()
|
||||
audit_event(f'Deleted {to_delete} from mods')
|
||||
flash(f'Removed {to_delete} from mods!', 'is-success')
|
||||
return redirect(url_for('mod.manage_mods'))
|
||||
if request.method == 'POST':
|
||||
|
@ -61,6 +62,7 @@ def manage_mods():
|
|||
else:
|
||||
m = Moderator(username=to_add)
|
||||
m.save()
|
||||
audit_event(f'Added {to_add} to mods')
|
||||
flash(f'Added {to_add} to mods!', 'is-success')
|
||||
mods = Profile.select().join(Moderator, on=(Profile.username == Moderator.username))
|
||||
return render_template('mod/manage.html', mods=mods)
|
||||
|
@ -80,6 +82,7 @@ def manage_bans():
|
|||
flash('Cannot ban super admin you son-of-a-bitch.', 'is-danger')
|
||||
else:
|
||||
ban.delete_instance()
|
||||
audit_event(f'Removed ban on {to_delete}')
|
||||
flash(f'Unbanned {to_delete}!', 'is-success')
|
||||
return redirect(url_for('mod.manage_bans'))
|
||||
if request.method == 'POST':
|
||||
|
@ -98,9 +101,14 @@ def manage_bans():
|
|||
reason = get_ban_reason()
|
||||
ban = Ban(user=u, reason=reason)
|
||||
ban.save()
|
||||
audit_event(f'Banned {to_add} ({reason})')
|
||||
flash(f'Banned {to_add}!', 'is-success')
|
||||
bans = Ban.select()
|
||||
return render_template('mod/bans.html', bans=bans)
|
||||
|
||||
# audit trail of activity
|
||||
# view wallet rpc logs
|
||||
|
||||
@bp.route('/mods/logs')
|
||||
@moderator_required
|
||||
def view_logs():
|
||||
events = AuditEvent.select().order_by(AuditEvent.timestamp.desc()).limit(50)
|
||||
return render_template('mod/logs.html', logs=events)
|
|
@ -2,6 +2,7 @@ from datetime import datetime, timedelta
|
|||
from os import path, remove
|
||||
from io import BytesIO
|
||||
from base64 import b64encode
|
||||
from sys import audit
|
||||
from qrcode import make as qrcode_make
|
||||
from flask import render_template, Blueprint, request, session, flash
|
||||
from flask import send_from_directory, redirect, url_for, current_app
|
||||
|
@ -12,8 +13,7 @@ from suchwow import config
|
|||
from suchwow.models import Post, Profile, Comment, Ban
|
||||
from suchwow.utils.decorators import login_required, profile_required, moderator_required
|
||||
from suchwow.utils.helpers import allowed_file, is_moderator, get_session_user
|
||||
from suchwow.utils.helpers import rw_cache, post_webhook
|
||||
from suchwow.reddit import make_post
|
||||
from suchwow.utils.helpers import post_webhook, audit_event
|
||||
from suchwow.discord import post_discord_webhook
|
||||
|
||||
|
||||
|
@ -57,7 +57,6 @@ def create():
|
|||
submitter = get_session_user()
|
||||
u = Profile.filter(username=submitter)
|
||||
banned = Ban.filter(user=u).first()
|
||||
print(banned)
|
||||
if banned:
|
||||
flash(f"You can't post: {banned.reason}", "is-danger")
|
||||
return redirect("/")
|
||||
|
@ -105,7 +104,7 @@ def create():
|
|||
post.save()
|
||||
post.save_thumbnail()
|
||||
url = url_for('post.read', id=post.id, _external=True)
|
||||
post_webhook(f"New post :doge2: [{post.id}]({url}) by `{submitter}` :neckbeard:")
|
||||
audit_event(f'Created new post {post.id}')
|
||||
flash("New post created and pending approval!", "is-success")
|
||||
return redirect(url_for("main.index"))
|
||||
return render_template("post/create.html")
|
||||
|
@ -119,11 +118,10 @@ def approve(id):
|
|||
if not post.approved:
|
||||
post.approved = True
|
||||
post.save()
|
||||
post_webhook(f"Post [{post.id}]({url}) approved :white_check_mark: by `{get_session_user()}` :fieri_parrot:")
|
||||
flash("Approved", "is-success")
|
||||
audit_event(f'Approved post {post.id}')
|
||||
if current_app.config["DEBUG"] is False:
|
||||
post_discord_webhook(post)
|
||||
post_webhook(f"Post [{post.id}]({url}) submitted :dab_parrot: to Discord.")
|
||||
return redirect(url_for("mod.pending_posts"))
|
||||
else:
|
||||
flash("You can't approve this", "is-success")
|
||||
|
@ -141,8 +139,8 @@ def delete(id):
|
|||
save_path_base = path.join(current_app.config["DATA_FOLDER"], "uploads")
|
||||
save_path = path.join(save_path_base, post.image_name)
|
||||
remove(save_path)
|
||||
audit_event(f'Deleted post {post.id}')
|
||||
post.delete_instance()
|
||||
post_webhook(f"Post {post.id} deleted :dumpsterfire: by `{user}` :godmode:")
|
||||
flash("Deleted that shit, brah!", "is-success")
|
||||
if is_mod:
|
||||
return redirect(url_for("mod.pending_posts"))
|
||||
|
|
29
suchwow/templates/mod/logs.html
Normal file
29
suchwow/templates/mod/logs.html
Normal file
|
@ -0,0 +1,29 @@
|
|||
{% extends 'base.html' %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="container" style="text-align:center;">
|
||||
<h1 class="title">Manage Mods</h1>
|
||||
<nav class="breadcrumb is-centered" aria-label="breadcrumbs">
|
||||
<ul>
|
||||
<li><a href="/">Home</a></li>
|
||||
<li><a href="{{ url_for('mod.main') }}">Mods</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<section class="section">
|
||||
{% for log in logs %}
|
||||
<article class="message" style="width: 40%; margin: 1em auto;">
|
||||
<div class="message-header">
|
||||
<p>{{ log.user.username }} - {{ log.timestamp | humanize }} </p>
|
||||
</div>
|
||||
<div class="message-body">
|
||||
{{ log.action }}
|
||||
</div>
|
||||
</article>
|
||||
{% endfor %}
|
||||
</section>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block footer %}{% endblock %}
|
|
@ -52,7 +52,7 @@
|
|||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a>
|
||||
<a href="{{ url_for('mod.view_logs') }}">
|
||||
<span class="icon is-small"></span>
|
||||
<span>View Logs</span>
|
||||
</a>
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import pickle
|
||||
from os import path, remove
|
||||
from os import path
|
||||
from datetime import datetime, timedelta
|
||||
from requests import post as r_post
|
||||
from json import dumps
|
||||
|
||||
from requests import post as r_post
|
||||
from flask import session, current_app
|
||||
from suchwow.models import Moderator, Post
|
||||
|
||||
from suchwow.models import Moderator, Post, AuditEvent, Profile
|
||||
from suchwow.wownero import Wallet, from_atomic
|
||||
from suchwow import config
|
||||
|
||||
|
@ -20,6 +22,14 @@ def is_moderator(username):
|
|||
else:
|
||||
return False
|
||||
|
||||
def get_profile():
|
||||
p = Profile.filter(username=get_session_user()).first()
|
||||
return p
|
||||
|
||||
def audit_event(event):
|
||||
e = AuditEvent(user=get_profile(), action=event)
|
||||
e.save()
|
||||
|
||||
def get_session_user():
|
||||
if "auth" not in session or not session["auth"]:
|
||||
return None
|
||||
|
|
Loading…
Reference in a new issue