diff --git a/aurweb/auth.py b/aurweb/auth/__init__.py similarity index 75% rename from aurweb/auth.py rename to aurweb/auth/__init__.py index 1527f0a3..82192cc2 100644 --- a/aurweb/auth.py +++ b/aurweb/auth/__init__.py @@ -250,101 +250,3 @@ def account_type_required(one_of: set): return await func(request, *args, **kwargs) return wrapper return decorator - - -CRED_ACCOUNT_CHANGE_TYPE = 1 -CRED_ACCOUNT_EDIT = 2 -CRED_ACCOUNT_EDIT_DEV = 3 -CRED_ACCOUNT_LAST_LOGIN = 4 -CRED_ACCOUNT_SEARCH = 5 -CRED_ACCOUNT_LIST_COMMENTS = 28 -CRED_COMMENT_DELETE = 6 -CRED_COMMENT_UNDELETE = 27 -CRED_COMMENT_VIEW_DELETED = 22 -CRED_COMMENT_EDIT = 25 -CRED_COMMENT_PIN = 26 -CRED_PKGBASE_ADOPT = 7 -CRED_PKGBASE_SET_KEYWORDS = 8 -CRED_PKGBASE_DELETE = 9 -CRED_PKGBASE_DISOWN = 10 -CRED_PKGBASE_EDIT_COMAINTAINERS = 24 -CRED_PKGBASE_FLAG = 11 -CRED_PKGBASE_LIST_VOTERS = 12 -CRED_PKGBASE_NOTIFY = 13 -CRED_PKGBASE_UNFLAG = 15 -CRED_PKGBASE_VOTE = 16 -CRED_PKGREQ_FILE = 23 -CRED_PKGREQ_CLOSE = 17 -CRED_PKGREQ_LIST = 18 -CRED_TU_ADD_VOTE = 19 -CRED_TU_LIST_VOTES = 20 -CRED_TU_VOTE = 21 -CRED_PKGBASE_MERGE = 29 - - -def has_any(user, *account_types): - return str(user.AccountType) in set(account_types) - - -def user_developer_or_trusted_user(user): - return True - - -def trusted_user(user): - return has_any(user, "Trusted User", "Trusted User & Developer") - - -def developer(user): - return has_any(user, "Developer", "Trusted User & Developer") - - -def trusted_user_or_dev(user): - return has_any(user, "Trusted User", "Developer", - "Trusted User & Developer") - - -# A mapping of functions that users must pass to have credentials. -cred_filters = { - CRED_PKGBASE_FLAG: user_developer_or_trusted_user, - CRED_PKGBASE_NOTIFY: user_developer_or_trusted_user, - CRED_PKGBASE_VOTE: user_developer_or_trusted_user, - CRED_PKGREQ_FILE: user_developer_or_trusted_user, - CRED_ACCOUNT_CHANGE_TYPE: trusted_user_or_dev, - CRED_ACCOUNT_EDIT: trusted_user_or_dev, - CRED_ACCOUNT_LAST_LOGIN: trusted_user_or_dev, - CRED_ACCOUNT_LIST_COMMENTS: trusted_user_or_dev, - CRED_ACCOUNT_SEARCH: trusted_user_or_dev, - CRED_COMMENT_DELETE: trusted_user_or_dev, - CRED_COMMENT_UNDELETE: trusted_user_or_dev, - CRED_COMMENT_VIEW_DELETED: trusted_user_or_dev, - CRED_COMMENT_EDIT: trusted_user_or_dev, - CRED_COMMENT_PIN: trusted_user_or_dev, - CRED_PKGBASE_ADOPT: trusted_user_or_dev, - CRED_PKGBASE_SET_KEYWORDS: trusted_user_or_dev, - CRED_PKGBASE_DELETE: trusted_user_or_dev, - CRED_PKGBASE_EDIT_COMAINTAINERS: trusted_user_or_dev, - CRED_PKGBASE_DISOWN: trusted_user_or_dev, - CRED_PKGBASE_LIST_VOTERS: trusted_user_or_dev, - CRED_PKGBASE_UNFLAG: trusted_user_or_dev, - CRED_PKGREQ_CLOSE: trusted_user_or_dev, - CRED_PKGREQ_LIST: trusted_user_or_dev, - CRED_TU_ADD_VOTE: trusted_user, - CRED_TU_LIST_VOTES: trusted_user_or_dev, - CRED_TU_VOTE: trusted_user, - CRED_ACCOUNT_EDIT_DEV: developer, - CRED_PKGBASE_MERGE: trusted_user_or_dev, -} - - -def has_credential(user: User, - credential: int, - approved_users: list = tuple()): - - if user in approved_users: - return True - - if credential in cred_filters: - cred_filter = cred_filters.get(credential) - return cred_filter(user) - - return False diff --git a/aurweb/auth/creds.py b/aurweb/auth/creds.py new file mode 100644 index 00000000..100aad8c --- /dev/null +++ b/aurweb/auth/creds.py @@ -0,0 +1,76 @@ +from aurweb.models.account_type import DEVELOPER_ID, TRUSTED_USER_AND_DEV_ID, TRUSTED_USER_ID, USER_ID +from aurweb.models.user import User + +ACCOUNT_CHANGE_TYPE = 1 +ACCOUNT_EDIT = 2 +ACCOUNT_EDIT_DEV = 3 +ACCOUNT_LAST_LOGIN = 4 +ACCOUNT_SEARCH = 5 +ACCOUNT_LIST_COMMENTS = 28 +COMMENT_DELETE = 6 +COMMENT_UNDELETE = 27 +COMMENT_VIEW_DELETED = 22 +COMMENT_EDIT = 25 +COMMENT_PIN = 26 +PKGBASE_ADOPT = 7 +PKGBASE_SET_KEYWORDS = 8 +PKGBASE_DELETE = 9 +PKGBASE_DISOWN = 10 +PKGBASE_EDIT_COMAINTAINERS = 24 +PKGBASE_FLAG = 11 +PKGBASE_LIST_VOTERS = 12 +PKGBASE_NOTIFY = 13 +PKGBASE_UNFLAG = 15 +PKGBASE_VOTE = 16 +PKGREQ_FILE = 23 +PKGREQ_CLOSE = 17 +PKGREQ_LIST = 18 +TU_ADD_VOTE = 19 +TU_LIST_VOTES = 20 +TU_VOTE = 21 +PKGBASE_MERGE = 29 + +user_developer_or_trusted_user = set([USER_ID, TRUSTED_USER_ID, DEVELOPER_ID, TRUSTED_USER_AND_DEV_ID]) +trusted_user_or_dev = set([TRUSTED_USER_ID, DEVELOPER_ID, TRUSTED_USER_AND_DEV_ID]) +developer = set([DEVELOPER_ID, TRUSTED_USER_AND_DEV_ID]) +trusted_user = set([TRUSTED_USER_ID, TRUSTED_USER_AND_DEV_ID]) + +cred_filters = { + PKGBASE_FLAG: user_developer_or_trusted_user, + PKGBASE_NOTIFY: user_developer_or_trusted_user, + PKGBASE_VOTE: user_developer_or_trusted_user, + PKGREQ_FILE: user_developer_or_trusted_user, + ACCOUNT_CHANGE_TYPE: trusted_user_or_dev, + ACCOUNT_EDIT: trusted_user_or_dev, + ACCOUNT_LAST_LOGIN: trusted_user_or_dev, + ACCOUNT_LIST_COMMENTS: trusted_user_or_dev, + ACCOUNT_SEARCH: trusted_user_or_dev, + COMMENT_DELETE: trusted_user_or_dev, + COMMENT_UNDELETE: trusted_user_or_dev, + COMMENT_VIEW_DELETED: trusted_user_or_dev, + COMMENT_EDIT: trusted_user_or_dev, + COMMENT_PIN: trusted_user_or_dev, + PKGBASE_ADOPT: trusted_user_or_dev, + PKGBASE_SET_KEYWORDS: trusted_user_or_dev, + PKGBASE_DELETE: trusted_user_or_dev, + PKGBASE_EDIT_COMAINTAINERS: trusted_user_or_dev, + PKGBASE_DISOWN: trusted_user_or_dev, + PKGBASE_LIST_VOTERS: trusted_user_or_dev, + PKGBASE_UNFLAG: trusted_user_or_dev, + PKGREQ_CLOSE: trusted_user_or_dev, + PKGREQ_LIST: trusted_user_or_dev, + TU_ADD_VOTE: trusted_user, + TU_LIST_VOTES: trusted_user_or_dev, + TU_VOTE: trusted_user, + ACCOUNT_EDIT_DEV: developer, + PKGBASE_MERGE: trusted_user_or_dev, +} + + +def has_credential(user: User, + credential: int, + approved_users: list = tuple()): + + if user in approved_users: + return True + return user.AccountTypeID in cred_filters[credential] diff --git a/aurweb/models/user.py b/aurweb/models/user.py index 03634a36..f0724202 100644 --- a/aurweb/models/user.py +++ b/aurweb/models/user.py @@ -1,6 +1,7 @@ import hashlib from datetime import datetime +from typing import List, Set import bcrypt @@ -136,10 +137,10 @@ class User(Base): request.cookies["AURSID"] = self.session.SessionID return self.session.SessionID - def has_credential(self, credential: str, approved: list = tuple()): - import aurweb.auth - cred = getattr(aurweb.auth, credential) - return aurweb.auth.has_credential(self, cred, approved) + def has_credential(self, credential: Set[int], + approved: List["User"] = list()): + from aurweb.auth.creds import has_credential + return has_credential(self, credential, approved) def logout(self, request): del request.cookies["AURSID"] diff --git a/aurweb/routers/accounts.py b/aurweb/routers/accounts.py index 545811f0..360857e8 100644 --- a/aurweb/routers/accounts.py +++ b/aurweb/routers/accounts.py @@ -10,7 +10,7 @@ from sqlalchemy import and_, or_ import aurweb.config from aurweb import cookies, db, l10n, logging, models, util -from aurweb.auth import account_type_required, auth_required +from aurweb.auth import account_type_required, auth_required, creds from aurweb.captcha import get_captcha_salts from aurweb.exceptions import ValidationError from aurweb.l10n import get_translator_for_request @@ -176,7 +176,7 @@ def make_account_form_context(context: dict, user_account_type_id = context.get("account_types")[0][0] - if request.user.has_credential("CRED_ACCOUNT_EDIT_DEV"): + if request.user.has_credential(creds.ACCOUNT_EDIT_DEV): context["account_types"].append((at.DEVELOPER_ID, at.DEVELOPER)) context["account_types"].append((at.TRUSTED_USER_AND_DEV_ID, at.TRUSTED_USER_AND_DEV)) @@ -332,7 +332,7 @@ async def account_register_post(request: Request, def cannot_edit(request, user): """ Return a 401 HTMLResponse if the request user doesn't have authorization, otherwise None. """ - has_dev_cred = request.user.has_credential("CRED_ACCOUNT_EDIT_DEV", + has_dev_cred = request.user.has_credential(creds.ACCOUNT_EDIT_DEV, approved=[user]) if not has_dev_cred: return HTMLResponse(status_code=HTTPStatus.UNAUTHORIZED) diff --git a/aurweb/routers/packages.py b/aurweb/routers/packages.py index b5f8478e..2bf04949 100644 --- a/aurweb/routers/packages.py +++ b/aurweb/routers/packages.py @@ -10,7 +10,7 @@ import aurweb.filters import aurweb.packages.util from aurweb import db, defaults, l10n, logging, models, util -from aurweb.auth import auth_required +from aurweb.auth import auth_required, creds from aurweb.exceptions import ValidationError from aurweb.models.package_request import ACCEPTED_ID, PENDING_ID, REJECTED_ID from aurweb.models.relation_type import CONFLICTS_ID, PROVIDES_ID, REPLACES_ID @@ -413,7 +413,7 @@ async def pkgbase_comment_delete(request: Request, name: str, id: int, pkgbase = get_pkg_or_base(name, models.PackageBase) comment = get_pkgbase_comment(pkgbase, id) - authorized = request.user.has_credential("CRED_COMMENT_DELETE", + authorized = request.user.has_credential(creds.COMMENT_DELETE, [comment.User]) if not authorized: _ = l10n.get_translator_for_request(request) @@ -439,7 +439,7 @@ async def pkgbase_comment_undelete(request: Request, name: str, id: int, pkgbase = get_pkg_or_base(name, models.PackageBase) comment = get_pkgbase_comment(pkgbase, id) - has_cred = request.user.has_credential("CRED_COMMENT_UNDELETE", + has_cred = request.user.has_credential(creds.COMMENT_UNDELETE, approved=[comment.User]) if not has_cred: _ = l10n.get_translator_for_request(request) @@ -464,7 +464,7 @@ async def pkgbase_comment_pin(request: Request, name: str, id: int, pkgbase = get_pkg_or_base(name, models.PackageBase) comment = get_pkgbase_comment(pkgbase, id) - has_cred = request.user.has_credential("CRED_COMMENT_PIN", + has_cred = request.user.has_credential(creds.COMMENT_PIN, approved=[pkgbase.Maintainer]) if not has_cred: _ = l10n.get_translator_for_request(request) @@ -489,7 +489,7 @@ async def pkgbase_comment_unpin(request: Request, name: str, id: int, pkgbase = get_pkg_or_base(name, models.PackageBase) comment = get_pkgbase_comment(pkgbase, id) - has_cred = request.user.has_credential("CRED_COMMENT_PIN", + has_cred = request.user.has_credential(creds.COMMENT_PIN, approved=[pkgbase.Maintainer]) if not has_cred: _ = l10n.get_translator_for_request(request) @@ -514,7 +514,7 @@ async def package_base_comaintainers(request: Request, name: str) -> Response: # Unauthorized users (Non-TU/Dev and not the pkgbase maintainer) # get redirected to the package base's page. - has_creds = request.user.has_credential("CRED_PKGBASE_EDIT_COMAINTAINERS", + has_creds = request.user.has_credential(creds.PKGBASE_EDIT_COMAINTAINERS, approved=[pkgbase.Maintainer]) if not has_creds: return RedirectResponse(f"/pkgbase/{name}", @@ -541,7 +541,7 @@ async def package_base_comaintainers_post( # Unauthorized users (Non-TU/Dev and not the pkgbase maintainer) # get redirected to the package base's page. - has_creds = request.user.has_credential("CRED_PKGBASE_EDIT_COMAINTAINERS", + has_creds = request.user.has_credential(creds.PKGBASE_EDIT_COMAINTAINERS, approved=[pkgbase.Maintainer]) if not has_creds: return RedirectResponse(f"/pkgbase/{name}", @@ -779,7 +779,7 @@ async def pkgbase_keywords(request: Request, name: str, async def pkgbase_flag_get(request: Request, name: str): pkgbase = get_pkg_or_base(name, models.PackageBase) - has_cred = request.user.has_credential("CRED_PKGBASE_FLAG") + has_cred = request.user.has_credential(creds.PKGBASE_FLAG) if not has_cred or pkgbase.Flagger is not None: return RedirectResponse(f"/pkgbase/{name}", status_code=HTTPStatus.SEE_OTHER) @@ -803,7 +803,7 @@ async def pkgbase_flag_post(request: Request, name: str, return render_template(request, "packages/flag.html", context, status_code=HTTPStatus.BAD_REQUEST) - has_cred = request.user.has_credential("CRED_PKGBASE_FLAG") + has_cred = request.user.has_credential(creds.PKGBASE_FLAG) if has_cred and not pkgbase.Flagger: now = int(datetime.utcnow().timestamp()) with db.begin(): @@ -830,7 +830,7 @@ async def pkgbase_flag_comment(request: Request, name: str): def pkgbase_unflag_instance(request: Request, pkgbase: models.PackageBase): has_cred = request.user.has_credential( - "CRED_PKGBASE_UNFLAG", approved=[pkgbase.Flagger, pkgbase.Maintainer]) + creds.PKGBASE_UNFLAG, approved=[pkgbase.Flagger, pkgbase.Maintainer]) if has_cred: with db.begin(): pkgbase.OutOfDateTS = None @@ -851,7 +851,7 @@ def pkgbase_notify_instance(request: Request, pkgbase: models.PackageBase): notif = db.query(pkgbase.notifications.filter( models.PackageNotification.UserID == request.user.ID ).exists()).scalar() - has_cred = request.user.has_credential("CRED_PKGBASE_NOTIFY") + has_cred = request.user.has_credential(creds.PKGBASE_NOTIFY) if has_cred and not notif: with db.begin(): db.create(models.PackageNotification, @@ -872,7 +872,7 @@ def pkgbase_unnotify_instance(request: Request, pkgbase: models.PackageBase): notif = pkgbase.notifications.filter( models.PackageNotification.UserID == request.user.ID ).first() - has_cred = request.user.has_credential("CRED_PKGBASE_NOTIFY") + has_cred = request.user.has_credential(creds.PKGBASE_NOTIFY) if has_cred and notif: with db.begin(): db.delete(notif) @@ -895,7 +895,7 @@ async def pkgbase_vote(request: Request, name: str): vote = pkgbase.package_votes.filter( models.PackageVote.UsersID == request.user.ID ).first() - has_cred = request.user.has_credential("CRED_PKGBASE_VOTE") + has_cred = request.user.has_credential(creds.PKGBASE_VOTE) if has_cred and not vote: now = int(datetime.utcnow().timestamp()) with db.begin(): @@ -919,7 +919,7 @@ async def pkgbase_unvote(request: Request, name: str): vote = pkgbase.package_votes.filter( models.PackageVote.UsersID == request.user.ID ).first() - has_cred = request.user.has_credential("CRED_PKGBASE_VOTE") + has_cred = request.user.has_credential(creds.PKGBASE_VOTE) if has_cred and vote: with db.begin(): db.delete(vote) @@ -958,7 +958,7 @@ def pkgbase_disown_instance(request: Request, pkgbase: models.PackageBase): async def pkgbase_disown_get(request: Request, name: str): pkgbase = get_pkg_or_base(name, models.PackageBase) - has_cred = request.user.has_credential("CRED_PKGBASE_DISOWN", + has_cred = request.user.has_credential(creds.PKGBASE_DISOWN, approved=[pkgbase.Maintainer]) if not has_cred: return RedirectResponse(f"/pkgbase/{name}", @@ -975,7 +975,7 @@ async def pkgbase_disown_post(request: Request, name: str, confirm: bool = Form(default=False)): pkgbase = get_pkg_or_base(name, models.PackageBase) - has_cred = request.user.has_credential("CRED_PKGBASE_DISOWN", + has_cred = request.user.has_credential(creds.PKGBASE_DISOWN, approved=[pkgbase.Maintainer]) if not has_cred: return RedirectResponse(f"/pkgbase/{name}", @@ -1007,7 +1007,7 @@ def pkgbase_adopt_instance(request: Request, pkgbase: models.PackageBase): async def pkgbase_adopt_post(request: Request, name: str): pkgbase = get_pkg_or_base(name, models.PackageBase) - has_cred = request.user.has_credential("CRED_PKGBASE_ADOPT") + has_cred = request.user.has_credential(creds.PKGBASE_ADOPT) if has_cred or not pkgbase.Maintainer: # If the user has credentials, they'll adopt the package regardless # of maintainership. Otherwise, we'll promote the user to maintainer @@ -1021,7 +1021,7 @@ async def pkgbase_adopt_post(request: Request, name: str): @router.get("/pkgbase/{name}/delete") @auth_required(True, redirect="/pkgbase/{name}/delete") async def pkgbase_delete_get(request: Request, name: str): - if not request.user.has_credential("CRED_PKGBASE_DELETE"): + if not request.user.has_credential(creds.PKGBASE_DELETE): return RedirectResponse(f"/pkgbase/{name}", status_code=HTTPStatus.SEE_OTHER) @@ -1036,7 +1036,7 @@ async def pkgbase_delete_post(request: Request, name: str, confirm: bool = Form(default=False)): pkgbase = get_pkg_or_base(name, models.PackageBase) - if not request.user.has_credential("CRED_PKGBASE_DELETE"): + if not request.user.has_credential(creds.PKGBASE_DELETE): return RedirectResponse(f"/pkgbase/{name}", status_code=HTTPStatus.SEE_OTHER) @@ -1070,7 +1070,7 @@ async def packages_unflag(request: Request, package_ids: List[int] = [], models.Package.ID.in_(package_ids)).all() for pkg in packages: has_cred = request.user.has_credential( - "CRED_PKGBASE_UNFLAG", approved=[pkg.PackageBase.Flagger]) + creds.PKGBASE_UNFLAG, approved=[pkg.PackageBase.Flagger]) if not has_cred: return (False, ["You did not select any packages to unflag."]) @@ -1106,7 +1106,7 @@ async def packages_notify(request: Request, package_ids: List[int] = [], notif = db.query(pkgbase.notifications.filter( models.PackageNotification.UserID == request.user.ID ).exists()).scalar() - has_cred = request.user.has_credential("CRED_PKGBASE_NOTIFY") + has_cred = request.user.has_credential(creds.PKGBASE_NOTIFY) # If the request user either does not have credentials # or the notification already exists: @@ -1178,7 +1178,7 @@ async def packages_adopt(request: Request, package_ids: List[int] = [], # Check that the user has credentials for every package they selected. for pkgbase in bases: - has_cred = request.user.has_credential("CRED_PKGBASE_ADOPT") + has_cred = request.user.has_credential(creds.PKGBASE_ADOPT) if not (has_cred or not pkgbase.Maintainer): # TODO: This error needs to be translated. return (False, ["You are not allowed to adopt one of the " @@ -1211,7 +1211,7 @@ async def packages_disown(request: Request, package_ids: List[int] = [], # Check that the user has credentials for every package they selected. for pkgbase in bases: - has_cred = request.user.has_credential("CRED_PKGBASE_DISOWN", + has_cred = request.user.has_credential(creds.PKGBASE_DISOWN, approved=[pkgbase.Maintainer]) if not has_cred: # TODO: This error needs to be translated. @@ -1235,7 +1235,7 @@ async def packages_delete(request: Request, package_ids: List[int] = [], return (False, ["The selected packages have not been deleted, " "check the confirmation checkbox."]) - if not request.user.has_credential("CRED_PKGBASE_DELETE"): + if not request.user.has_credential(creds.PKGBASE_DELETE): return (False, ["You do not have permission to delete packages."]) # A "memo" used to store names of packages that we delete. @@ -1329,10 +1329,10 @@ async def pkgbase_merge_get(request: Request, name: str, status_code = HTTPStatus.OK # TODO: Lookup errors from credential instead of hardcoding them. - # Idea: Something like credential_errors("CRED_PKGBASE_MERGE"). - # Perhaps additionally: bad_credential_status_code("CRED_PKGBASE_MERGE"). + # Idea: Something like credential_errors(creds.PKGBASE_MERGE). + # Perhaps additionally: bad_credential_status_code(creds.PKGBASE_MERGE). # Don't take these examples verbatim. We should find good naming. - if not request.user.has_credential("CRED_PKGBASE_MERGE"): + if not request.user.has_credential(creds.PKGBASE_MERGE): context["errors"] = [ "Only Trusted Users and Developers can merge packages."] status_code = HTTPStatus.UNAUTHORIZED @@ -1434,7 +1434,7 @@ async def pkgbase_merge_post(request: Request, name: str, context["pkgbase"] = pkgbase # TODO: Lookup errors from credential instead of hardcoding them. - if not request.user.has_credential("CRED_PKGBASE_MERGE"): + if not request.user.has_credential(creds.PKGBASE_MERGE): context["errors"] = [ "Only Trusted Users and Developers can merge packages."] return render_template(request, "pkgbase/merge.html", context, diff --git a/aurweb/templates.py b/aurweb/templates.py index a7102ae1..635b22b4 100644 --- a/aurweb/templates.py +++ b/aurweb/templates.py @@ -16,7 +16,7 @@ from fastapi.responses import HTMLResponse import aurweb.config -from aurweb import captcha, cookies, l10n, time, util +from aurweb import auth, captcha, cookies, l10n, time, util # Prepare jinja2 objects. _loader = jinja2.FileSystemLoader(os.path.join( @@ -107,6 +107,7 @@ def make_context(request: Request, title: str, next: str = None): "now": datetime.now(tz=zoneinfo.ZoneInfo(timezone)), "utcnow": int(datetime.utcnow().timestamp()), "config": aurweb.config, + "creds": auth.creds, "next": next if next else request.url.path } diff --git a/templates/partials/account/comment.html b/templates/partials/account/comment.html index bc167cf7..8c310738 100644 --- a/templates/partials/account/comment.html +++ b/templates/partials/account/comment.html @@ -3,7 +3,7 @@ {% set header_cls = "%s %s" | format(header_cls, "comment-deleted") %} {% endif %} -{% if not comment.Deleter or request.user.has_credential("CRED_COMMENT_VIEW_DELETED", approved=[comment.Deleter]) %} +{% if not comment.Deleter or request.user.has_credential(creds.COMMENT_VIEW_DELETED, approved=[comment.Deleter]) %} {% set commented_at = comment.CommentTS | dt | as_timezone(timezone) %}

diff --git a/templates/partials/account_form.html b/templates/partials/account_form.html index 2e47a932..f3c293d8 100644 --- a/templates/partials/account_form.html +++ b/templates/partials/account_form.html @@ -53,7 +53,7 @@

{% endif %} - {% if request.user.has_credential("CRED_ACCOUNT_CHANGE_TYPE") %} + {% if request.user.has_credential(creds.ACCOUNT_CHANGE_TYPE) %}

  • {% trans %}Accounts{% endtrans %} @@ -37,7 +37,7 @@
  • {# Only CRED_TU_LIST_VOTES privileged users see Trusted User #} - {% if request.user.has_credential("CRED_TU_LIST_VOTES") %} + {% if request.user.has_credential(creds.TU_LIST_VOTES) %}
  • {% trans %}Trusted User{% endtrans %}
  • diff --git a/templates/partials/comment_actions.html b/templates/partials/comment_actions.html index b8ccf945..78c4cc22 100644 --- a/templates/partials/comment_actions.html +++ b/templates/partials/comment_actions.html @@ -1,7 +1,7 @@ {% set pkgbasename = comment.PackageBase.Name %} {% if not comment.Deleter %} - {% if request.user.has_credential('CRED_COMMENT_DELETE', approved=[comment.User]) %} + {% if request.user.has_credential(creds.COMMENT_DELETE, approved=[comment.User]) %}
    {% endif %} - {% if request.user.has_credential('CRED_COMMENT_EDIT', approved=[comment.User]) %} + {% if request.user.has_credential(creds.COMMENT_EDIT, approved=[comment.User]) %} {% endif %} {% endif %} -{% elif request.user.has_credential("CRED_COMMENT_UNDELETE", approved=[comment.User]) %} +{% elif request.user.has_credential(creds.COMMENT_UNDELETE, approved=[comment.User]) %} {% endif %} - {% if request.user.has_credential('CRED_PKGBASE_EDIT_COMAINTAINERS', approved=[pkgbase.Maintainer]) %} + {% if request.user.has_credential(creds.PKGBASE_EDIT_COMAINTAINERS, approved=[pkgbase.Maintainer]) %}
  • {{ "Manage Co-Maintainers" | tr }} @@ -107,14 +107,14 @@ {{ "Submit Request" | tr }}
  • - {% if request.user.has_credential("CRED_PKGBASE_DELETE") %} + {% if request.user.has_credential(creds.PKGBASE_DELETE) %}
  • {{ "Delete Package" | tr }}
  • {% endif %} - {% if request.user.has_credential("CRED_PKGBASE_MERGE") %} + {% if request.user.has_credential(creds.PKGBASE_MERGE) %}
  • {{ "Merge Package" | tr }} @@ -130,7 +130,7 @@ />
  • - {% elif request.user.has_credential("CRED_PKGBASE_DISOWN", approved=[pkgbase.Maintainer]) %} + {% elif request.user.has_credential(creds.PKGBASE_DISOWN, approved=[pkgbase.Maintainer]) %}
  • {{ "Disown Package" | tr }} diff --git a/templates/partials/packages/comment.html b/templates/partials/packages/comment.html index 676a7a73..1427e0a0 100644 --- a/templates/partials/packages/comment.html +++ b/templates/partials/packages/comment.html @@ -5,7 +5,7 @@ {% set article_cls = "%s %s" | format(article_cls, "comment-deleted") %} {% endif %} -{% if not comment.Deleter or request.user.has_credential("CRED_COMMENT_VIEW_DELETED", approved=[comment.Deleter]) %} +{% if not comment.Deleter or request.user.has_credential(creds.COMMENT_VIEW_DELETED, approved=[comment.Deleter]) %}

    {% set commented_at = comment.CommentTS | dt | as_timezone(timezone) %} {% set view_account_info = 'View account information for %s' | tr | format(comment.User.Username) %} diff --git a/templates/partials/packages/details.html b/templates/partials/packages/details.html index dbb81c19..78e0ad1c 100644 --- a/templates/partials/packages/details.html +++ b/templates/partials/packages/details.html @@ -33,10 +33,10 @@ {% endif %} - {% if pkgbase.keywords.count() or request.user.has_credential("CRED_PKGBASE_SET_KEYWORDS", approved=[pkgbase.Maintainer]) %} + {% if pkgbase.keywords.count() or request.user.has_credential(creds.PKGBASE_SET_KEYWORDS, approved=[pkgbase.Maintainer]) %} {{ "Keywords" | tr }}: - {% if request.user.has_credential("CRED_PKGBASE_SET_KEYWORDS", approved=[pkgbase.Maintainer]) %} + {% if request.user.has_credential(creds.PKGBASE_SET_KEYWORDS, approved=[pkgbase.Maintainer]) %}