Clean up audit_log reasons

This commit is contained in:
rubenwardy 2021-02-02 17:29:03 +00:00
parent 912ebbc409
commit a040c7dd2e
5 changed files with 56 additions and 15 deletions

@ -25,11 +25,14 @@ def error(code: int, msg: str):
abort(make_response(jsonify({ "success": False, "error": msg }), code)) abort(make_response(jsonify({ "success": False, "error": msg }), code))
# Catches LogicErrors and aborts with JSON error # Catches LogicErrors and aborts with JSON error
def run_safe(f, *args, **kwargs): def guard(f):
try: def ret(*args, **kwargs):
return f(*args, **kwargs) try:
except LogicError as e: return f(*args, **kwargs)
error(e.code, e.message) except LogicError as e:
error(e.code, e.message)
return ret
def api_create_vcs_release(token: APIToken, package: Package, title: str, ref: str, def api_create_vcs_release(token: APIToken, package: Package, title: str, ref: str,
@ -37,7 +40,9 @@ def api_create_vcs_release(token: APIToken, package: Package, title: str, ref: s
if not token.canOperateOnPackage(package): if not token.canOperateOnPackage(package):
error(403, "API token does not have access to the package") error(403, "API token does not have access to the package")
rel = run_safe(do_create_vcs_release, token.owner, package, title, ref, None, None, reason) reason += ", token=" + token.name
rel = guard(do_create_vcs_release)(token.owner, package, title, ref, None, None, reason)
return jsonify({ return jsonify({
"success": True, "success": True,
@ -50,7 +55,9 @@ def api_create_zip_release(token: APIToken, package: Package, title: str, file,
if not token.canOperateOnPackage(package): if not token.canOperateOnPackage(package):
error(403, "API token does not have access to the package") error(403, "API token does not have access to the package")
rel = run_safe(do_create_zip_release, token.owner, package, title, file, None, None, reason) reason += ", token=" + token.name
rel = guard(do_create_zip_release)(token.owner, package, title, file, None, None, reason)
return jsonify({ return jsonify({
"success": True, "success": True,
@ -59,11 +66,13 @@ def api_create_zip_release(token: APIToken, package: Package, title: str, file,
}) })
def api_create_screenshot(token: APIToken, package: Package, title: str, file): def api_create_screenshot(token: APIToken, package: Package, title: str, file, reason="API"):
if not token.canOperateOnPackage(package): if not token.canOperateOnPackage(package):
error(403, "API token does not have access to the package") error(403, "API token does not have access to the package")
ss : PackageScreenshot = run_safe(do_create_screenshot, token.owner, package, title, file) reason += ", token=" + token.name
ss : PackageScreenshot = guard(do_create_screenshot)(token.owner, package, title, file, reason)
return jsonify({ return jsonify({
"success": True, "success": True,
@ -75,7 +84,7 @@ def api_order_screenshots(token: APIToken, package: Package, order: [any]):
if not token.canOperateOnPackage(package): if not token.canOperateOnPackage(package):
error(403, "API token does not have access to the package") error(403, "API token does not have access to the package")
run_safe(do_order_screenshots, token.owner, package, order) guard(do_order_screenshots)(token.owner, package, order)
return jsonify({ return jsonify({
"success": True "success": True

@ -95,6 +95,7 @@ curl -X DELETE https://content.minetest.net/api/packages/username/name/releases/
* `approved`: true if approved and visible. * `approved`: true if approved and visible.
* `title`: human-readable name for the screenshot, shown as a caption and alt text. * `title`: human-readable name for the screenshot, shown as a caption and alt text.
* `url`: absolute URL to screenshot. * `url`: absolute URL to screenshot.
* `created_at`: ISO time.
* `order`: Number used in ordering. * `order`: Number used in ordering.
* GET `/api/packages/<username>/<name>/screenshots/<id>/` (Read) * GET `/api/packages/<username>/<name>/screenshots/<id>/` (Read)
* Returns screenshot dictionary like above. * Returns screenshot dictionary like above.

@ -2,11 +2,11 @@ import datetime
from app.logic.LogicError import LogicError from app.logic.LogicError import LogicError
from app.logic.uploads import upload_file from app.logic.uploads import upload_file
from app.models import User, Package, PackageScreenshot, Permission, NotificationType, db from app.models import User, Package, PackageScreenshot, Permission, NotificationType, db, AuditSeverity
from app.utils import addNotification from app.utils import addNotification, addAuditLog
def do_create_screenshot(user: User, package: Package, title: str, file): def do_create_screenshot(user: User, package: Package, title: str, file, reason: str = None):
thirty_minutes_ago = datetime.datetime.now() - datetime.timedelta(minutes=30) thirty_minutes_ago = datetime.datetime.now() - datetime.timedelta(minutes=30)
count = package.screenshots.filter(PackageScreenshot.created_at > thirty_minutes_ago).count() count = package.screenshots.filter(PackageScreenshot.created_at > thirty_minutes_ago).count()
if count >= 20: if count >= 20:
@ -27,9 +27,14 @@ def do_create_screenshot(user: User, package: Package, title: str, file):
ss.order = counter ss.order = counter
db.session.add(ss) db.session.add(ss)
msg = "Screenshot added {}" \ if reason is None:
.format(ss.title) msg = "Created screenshot {}".format(ss.title)
else:
msg = "Created screenshot {} ({})".format(ss.title, reason)
addNotification(package.maintainers, user, NotificationType.PACKAGE_EDIT, msg, package.getDetailsURL(), package) addNotification(package.maintainers, user, NotificationType.PACKAGE_EDIT, msg, package.getDetailsURL(), package)
addAuditLog(AuditSeverity.NORMAL, user, msg, package.getDetailsURL(), package)
db.session.commit() db.session.commit()
return ss return ss

@ -900,6 +900,7 @@ class PackageScreenshot(db.Model):
title = db.Column(db.String(100), nullable=False) title = db.Column(db.String(100), nullable=False)
url = db.Column(db.String(100), nullable=False) url = db.Column(db.String(100), nullable=False)
approved = db.Column(db.Boolean, nullable=False, default=False) approved = db.Column(db.Boolean, nullable=False, default=False)
created_at = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow)
def getEditURL(self): def getEditURL(self):
return url_for("packages.edit_screenshot", return url_for("packages.edit_screenshot",
@ -923,6 +924,7 @@ class PackageScreenshot(db.Model):
"title": self.title, "title": self.title,
"url": base_url + self.url, "url": base_url + self.url,
"approved": self.approved, "approved": self.approved,
"created_at": self.created_at.isoformat(),
} }

@ -0,0 +1,24 @@
"""empty message
Revision ID: e82c2141fae3
Revises: 96811eb565c1
Create Date: 2021-02-02 17:25:04.070483
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = 'e82c2141fae3'
down_revision = '96811eb565c1'
branch_labels = None
depends_on = None
def upgrade():
op.add_column('package_screenshot', sa.Column('created_at', sa.DateTime(), nullable=False, server_default="now()"))
def downgrade():
op.drop_column('package_screenshot', 'created_at')