From: Michael Tremer Date: Tue, 3 Mar 2026 11:26:14 +0000 (+0000) Subject: reports: Implement some basic permissions check X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=01d05fc46198f484a7f0b2561f08c3fec7df57b2;p=dbl.git reports: Implement some basic permissions check Signed-off-by: Michael Tremer --- diff --git a/src/dbl/api/reports.py b/src/dbl/api/reports.py index 6e1a8e8..0bcb2c2 100644 --- a/src/dbl/api/reports.py +++ b/src/dbl/api/reports.py @@ -106,6 +106,11 @@ async def close_report( report: reports.Report = fastapi.Depends(get_report_from_path), user: users.User = fastapi.Depends(require_current_user), ) -> fastapi.Response: + # Check for permissions + if not await report.has_perm(user, accept=data.accept): + raise fastapi.HTTPError(403, "You don't have permission to change this report") + + # Close the report await report.close( closed_by = user, accept = data.accept, diff --git a/src/dbl/reports.py b/src/dbl/reports.py index 3b46d72..6e1876d 100644 --- a/src/dbl/reports.py +++ b/src/dbl/reports.py @@ -250,6 +250,27 @@ class Report(sqlmodel.SQLModel, database.BackendMixin, table=True): # Accepted? accepted : bool = False + # Permissions check + async def has_perm(self, user, accept=False): + """ + Returns True if the given user has permission to make changes to this report. + """ + # Admins and moderators have all permissions + if user.is_admin() or user.is_moderator(): + return True + + # The owners have some permissions... + if self.reported_by == user.uid: + # Users cannot accept their own reports + if accept: + return False + + # Otherwise users can manage their own reports + return True + + # Everybody else has no permissions + return False + # Close! async def close(self, closed_by=None, accept=True, update_stats=True): @@ -257,10 +278,12 @@ class Report(sqlmodel.SQLModel, database.BackendMixin, table=True): Called when a moderator has made a decision """ # Prevent a report from being closed again - if self.is_closed() + if self.is_closed(): raise RuntimeError("Report %s has already been closed" % self) - # XXX Check for permissions + # Check for permissions + if not await self.has_perm(closed_by, accept=accept): + raise RuntimeError("%s does not have permission to change report %s" % (closed_by, self.id)) # Only the the user ID in the database if isinstance(closed_by, users.User): diff --git a/src/dbl/users.py b/src/dbl/users.py index 5ea7f82..df019ff 100644 --- a/src/dbl/users.py +++ b/src/dbl/users.py @@ -20,6 +20,7 @@ import email.message import email.utils +import functools import ldap import logging import smtplib @@ -167,6 +168,20 @@ class User(LDAPObject): """ return self._get_string("mail") + @functools.cache + def is_admin(self): + """ + Returns True if this user is an admin + """ + return self in self.backend.users.admins + + @functools.cache + def is_moderator(self): + """ + Returns True if this user is a moderator + """ + return self in self.backend.users.moderators + def sendmail(self, message, sender=None, headers=None): """ Sends the given message to this user