Add changes to edit package audit log entry

This commit is contained in:
rubenwardy 2023-05-12 00:17:15 +01:00
parent 1fc4852e77
commit 19fa91d319
2 changed files with 69 additions and 3 deletions

@ -14,7 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import json
import re
import validators
from flask_babel import lazy_gettext
@ -22,7 +22,7 @@ from flask_babel import lazy_gettext
from app.logic.LogicError import LogicError
from app.models import User, Package, PackageType, MetaPackage, Tag, ContentWarning, db, Permission, AuditSeverity, \
License, UserRank, PackageDevState
from app.utils import addAuditLog, has_blocked_domains
from app.utils import addAuditLog, has_blocked_domains, diff_dictionaries, describe_difference
from app.utils.url import clean_youtube_url
@ -113,6 +113,8 @@ def do_edit_package(user: User, package: Package, was_new: bool, was_web: bool,
not package.checkPerm(user, Permission.CHANGE_NAME):
raise LogicError(403, lazy_gettext("You don't have permission to change the package name"))
before_dict = package.getAsDictionary("/")
for alias, to in ALIASES.items():
if alias in data:
data[to] = data[alias]
@ -188,14 +190,21 @@ def do_edit_package(user: User, package: Package, was_new: bool, was_web: bool,
raise LogicError(400, "Unknown warning: " + warning_id)
package.content_warnings.append(warning)
after_dict = package.getAsDictionary("/")
diff = diff_dictionaries(before_dict, after_dict)
if not was_new:
if reason is None:
msg = "Edited {}".format(package.title)
else:
msg = "Edited {} ({})".format(package.title, reason)
diff_desc = describe_difference(diff, 100 - len(msg) - 3)
if diff_desc:
msg += " [" + diff_desc + "]"
severity = AuditSeverity.NORMAL if user in package.maintainers else AuditSeverity.EDITOR
addAuditLog(severity, user, msg, package.getURL("packages.view"), package)
addAuditLog(severity, user, msg, package.getURL("packages.view"), package, json.dumps(diff, indent=4))
db.session.commit()

@ -16,6 +16,9 @@
import re
import secrets
from typing import Dict
import typing
from .flask import *
from .models import *
@ -68,3 +71,57 @@ def has_blocked_domains(text: str, username: str, location: str) -> bool:
return True
return False
def diff_dictionaries(one: Dict, two: Dict):
if len(set(one.keys()).difference(set(two.keys()))) != 0:
raise "Mismatching keys"
retval = []
for key, before in one.items():
after = two[key]
if before is dict:
diff = diff_dictionaries(before, after)
if len(diff) != 0:
retval.append({
"key": key,
"changes": diff,
})
elif before != after:
retval.append({
"key": key,
"before": before,
"after": after,
})
return retval
def describe_difference(diff: List, available_space: int) -> typing.Optional[str]:
if len(diff) == 0 or available_space <= 0:
return None
if len(diff) == 1 and "before" in diff[0] and "after" in diff[0]:
key = diff[0]["key"]
before = diff[0]["before"]
after = diff[0]["after"]
if isinstance(before, str) and isinstance(after, str):
return f"{key}: {before} -> {after}"
if isinstance(before, list) and isinstance(after, list):
removed = []
added = []
for x in before:
if x not in after:
removed.append(x)
for x in after:
if x not in before:
added.append(x)
parts = ["-" + str(x) for x in removed] + ["+" + str(x) for x in added]
return f"{key}: {', '.join(parts)}"
return ", ".join([x["key"] for x in diff])