mirror of
https://gitlab.archlinux.org/archlinux/aurweb.git
synced 2025-02-03 10:43:03 +01:00
fix(fastapi): support "Account Type:" input for account edit
Signed-off-by: Kevin Morris <kevr@0cost.org>
This commit is contained in:
parent
7e7a1ead88
commit
65be8b8e07
4 changed files with 153 additions and 5 deletions
|
@ -47,3 +47,6 @@ ACCOUNT_TYPE_ID = {
|
||||||
DEVELOPER: DEVELOPER_ID,
|
DEVELOPER: DEVELOPER_ID,
|
||||||
TRUSTED_USER_AND_DEV: TRUSTED_USER_AND_DEV_ID
|
TRUSTED_USER_AND_DEV: TRUSTED_USER_AND_DEV_ID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Reversed ACCOUNT_TYPE_ID mapping.
|
||||||
|
ACCOUNT_TYPE_NAME = {v: k for k, v in ACCOUNT_TYPE_ID.items()}
|
||||||
|
|
|
@ -15,6 +15,8 @@ from aurweb.auth import account_type_required, auth_required
|
||||||
from aurweb.captcha import get_captcha_answer, get_captcha_salts, get_captcha_token
|
from aurweb.captcha import get_captcha_answer, get_captcha_salts, get_captcha_token
|
||||||
from aurweb.l10n import get_translator_for_request
|
from aurweb.l10n import get_translator_for_request
|
||||||
from aurweb.models import account_type
|
from aurweb.models import account_type
|
||||||
|
from aurweb.models.account_type import (DEVELOPER, DEVELOPER_ID, TRUSTED_USER, TRUSTED_USER_AND_DEV, TRUSTED_USER_AND_DEV_ID,
|
||||||
|
TRUSTED_USER_ID, USER_ID)
|
||||||
from aurweb.models.ssh_pub_key import get_fingerprint
|
from aurweb.models.ssh_pub_key import get_fingerprint
|
||||||
from aurweb.scripts.notify import ResetKeyNotification, WelcomeNotification
|
from aurweb.scripts.notify import ResetKeyNotification, WelcomeNotification
|
||||||
from aurweb.templates import make_context, make_variable_context, render_template
|
from aurweb.templates import make_context, make_variable_context, render_template
|
||||||
|
@ -226,6 +228,29 @@ def process_account_form(request: Request, user: models.User, args: dict):
|
||||||
"<strong>", fingerprint, "</strong>")
|
"<strong>", fingerprint, "</strong>")
|
||||||
])
|
])
|
||||||
|
|
||||||
|
T = int(args.get("T", user.AccountTypeID))
|
||||||
|
if T != user.AccountTypeID:
|
||||||
|
if T not in account_type.ACCOUNT_TYPE_NAME:
|
||||||
|
return (False,
|
||||||
|
["Invalid account type provided."])
|
||||||
|
elif not request.user.is_elevated():
|
||||||
|
return (False,
|
||||||
|
["You do not have permission to change account types."])
|
||||||
|
|
||||||
|
credential_checks = {
|
||||||
|
DEVELOPER_ID: request.user.is_developer,
|
||||||
|
TRUSTED_USER_AND_DEV_ID: request.user.is_developer,
|
||||||
|
TRUSTED_USER_ID: request.user.is_elevated,
|
||||||
|
USER_ID: request.user.is_elevated
|
||||||
|
}
|
||||||
|
credential_check = credential_checks.get(T)
|
||||||
|
|
||||||
|
if not credential_check():
|
||||||
|
name = account_type.ACCOUNT_TYPE_NAME.get(T)
|
||||||
|
error = _("You do not have permission to change "
|
||||||
|
"this user's account type to %s.") % name
|
||||||
|
return (False, [error])
|
||||||
|
|
||||||
captcha_salt = args.get("captcha_salt", None)
|
captcha_salt = args.get("captcha_salt", None)
|
||||||
if captcha_salt and captcha_salt not in get_captcha_salts():
|
if captcha_salt and captcha_salt not in get_captcha_salts():
|
||||||
return (False, ["This CAPTCHA has expired. Please try again."])
|
return (False, ["This CAPTCHA has expired. Please try again."])
|
||||||
|
@ -255,15 +280,16 @@ def make_account_form_context(context: dict,
|
||||||
context = copy.copy(context)
|
context = copy.copy(context)
|
||||||
|
|
||||||
context["account_types"] = [
|
context["account_types"] = [
|
||||||
(1, "Normal User"),
|
(USER_ID, "Normal User"),
|
||||||
(2, "Trusted User")
|
(TRUSTED_USER_ID, TRUSTED_USER)
|
||||||
]
|
]
|
||||||
|
|
||||||
user_account_type_id = context.get("account_types")[0][0]
|
user_account_type_id = context.get("account_types")[0][0]
|
||||||
|
|
||||||
if request.user.has_credential("CRED_ACCOUNT_EDIT_DEV"):
|
if request.user.has_credential("CRED_ACCOUNT_EDIT_DEV"):
|
||||||
context["account_types"].append((3, "Developer"))
|
context["account_types"].append((DEVELOPER_ID, DEVELOPER))
|
||||||
context["account_types"].append((4, "Trusted User & Developer"))
|
context["account_types"].append((TRUSTED_USER_AND_DEV_ID,
|
||||||
|
TRUSTED_USER_AND_DEV))
|
||||||
|
|
||||||
if request.user.is_authenticated():
|
if request.user.is_authenticated():
|
||||||
context["username"] = args.get("U", user.Username)
|
context["username"] = args.get("U", user.Username)
|
||||||
|
@ -465,6 +491,7 @@ async def account_edit_post(request: Request,
|
||||||
CN: bool = Form(default=False), # Comment Notify
|
CN: bool = Form(default=False), # Comment Notify
|
||||||
UN: bool = Form(default=False), # Update Notify
|
UN: bool = Form(default=False), # Update Notify
|
||||||
ON: bool = Form(default=False), # Owner Notify
|
ON: bool = Form(default=False), # Owner Notify
|
||||||
|
T: int = Form(default=None),
|
||||||
passwd: str = Form(default=str())):
|
passwd: str = Form(default=str())):
|
||||||
from aurweb.db import session
|
from aurweb.db import session
|
||||||
|
|
||||||
|
@ -545,6 +572,10 @@ async def account_edit_post(request: Request,
|
||||||
# Else, if the user has a public key already, delete it.
|
# Else, if the user has a public key already, delete it.
|
||||||
session.delete(user.ssh_pub_key)
|
session.delete(user.ssh_pub_key)
|
||||||
|
|
||||||
|
if T and T != user.AccountTypeID:
|
||||||
|
with db.begin():
|
||||||
|
user.AccountTypeID = T
|
||||||
|
|
||||||
if P and not user.valid_password(P):
|
if P and not user.valid_password(P):
|
||||||
# Remove the fields we consumed for passwords.
|
# Remove the fields we consumed for passwords.
|
||||||
context["P"] = context["C"] = str()
|
context["P"] = context["C"] = str()
|
||||||
|
|
|
@ -2280,3 +2280,15 @@ msgid ""
|
||||||
"Please remember to cast your vote on proposal {id} [1]. The voting period "
|
"Please remember to cast your vote on proposal {id} [1]. The voting period "
|
||||||
"ends in less than 48 hours."
|
"ends in less than 48 hours."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: aurweb/routers/accounts.py
|
||||||
|
msgid "Invalid account type provided."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: aurweb/routers/accounts.py
|
||||||
|
msgid "You do not have permission to change account types."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: aurweb/routers/accounts.py
|
||||||
|
msgid "You do not have permission to change this user's account type to %s."
|
||||||
|
msgstr ""
|
||||||
|
|
|
@ -14,13 +14,14 @@ from aurweb import captcha, db, logging
|
||||||
from aurweb.asgi import app
|
from aurweb.asgi import app
|
||||||
from aurweb.db import create, query
|
from aurweb.db import create, query
|
||||||
from aurweb.models.accepted_term import AcceptedTerm
|
from aurweb.models.accepted_term import AcceptedTerm
|
||||||
from aurweb.models.account_type import DEVELOPER_ID, TRUSTED_USER_AND_DEV_ID, TRUSTED_USER_ID, AccountType
|
from aurweb.models.account_type import DEVELOPER_ID, TRUSTED_USER_AND_DEV_ID, TRUSTED_USER_ID, USER_ID, AccountType
|
||||||
from aurweb.models.ban import Ban
|
from aurweb.models.ban import Ban
|
||||||
from aurweb.models.session import Session
|
from aurweb.models.session import Session
|
||||||
from aurweb.models.ssh_pub_key import SSHPubKey, get_fingerprint
|
from aurweb.models.ssh_pub_key import SSHPubKey, get_fingerprint
|
||||||
from aurweb.models.term import Term
|
from aurweb.models.term import Term
|
||||||
from aurweb.models.user import User
|
from aurweb.models.user import User
|
||||||
from aurweb.testing import setup_test_db
|
from aurweb.testing import setup_test_db
|
||||||
|
from aurweb.testing.html import get_errors
|
||||||
from aurweb.testing.requests import Request
|
from aurweb.testing.requests import Request
|
||||||
|
|
||||||
# Some test global constants.
|
# Some test global constants.
|
||||||
|
@ -909,6 +910,107 @@ def test_post_account_edit_password():
|
||||||
assert user.valid_password("newPassword")
|
assert user.valid_password("newPassword")
|
||||||
|
|
||||||
|
|
||||||
|
def test_post_account_edit_account_types():
|
||||||
|
request = Request()
|
||||||
|
sid = user.login(request, "testPassword")
|
||||||
|
cookies = {"AURSID": sid}
|
||||||
|
endpoint = f"/account/{user.Username}/edit"
|
||||||
|
|
||||||
|
# As a normal user, we cannot see the "Account Type:" input.
|
||||||
|
with client as request:
|
||||||
|
resp = request.get(endpoint, cookies=cookies)
|
||||||
|
assert resp.status_code == int(HTTPStatus.OK)
|
||||||
|
assert "id_type" not in resp.text
|
||||||
|
|
||||||
|
# Invalid account types return an error.
|
||||||
|
post_data = {
|
||||||
|
"U": user.Username,
|
||||||
|
"E": user.Email,
|
||||||
|
"T": 0, # Invalid type ID
|
||||||
|
"passwd": "testPassword"
|
||||||
|
}
|
||||||
|
with client as request:
|
||||||
|
resp = request.post(endpoint, data=post_data, cookies=cookies)
|
||||||
|
assert resp.status_code == int(HTTPStatus.BAD_REQUEST)
|
||||||
|
errors = get_errors(resp.text)
|
||||||
|
expected = "Invalid account type provided."
|
||||||
|
assert errors[0].text.strip() == expected
|
||||||
|
|
||||||
|
# Nor can we change any account types.
|
||||||
|
post_data = {
|
||||||
|
"U": user.Username,
|
||||||
|
"E": user.Email,
|
||||||
|
"T": TRUSTED_USER_ID,
|
||||||
|
"passwd": "testPassword"
|
||||||
|
}
|
||||||
|
with client as request:
|
||||||
|
resp = request.post(endpoint, data=post_data, cookies=cookies)
|
||||||
|
assert resp.status_code == int(HTTPStatus.BAD_REQUEST)
|
||||||
|
errors = get_errors(resp.text)
|
||||||
|
expected = "You do not have permission to change account types."
|
||||||
|
assert errors[0].text.strip() == expected
|
||||||
|
|
||||||
|
# Change user from USER_ID to TRUSTED_USER_ID.
|
||||||
|
with db.begin():
|
||||||
|
user.AccountTypeID = TRUSTED_USER_ID
|
||||||
|
|
||||||
|
# As a trusted user, we can see the "Account Type:" input.
|
||||||
|
with client as request:
|
||||||
|
resp = request.get(endpoint, cookies=cookies)
|
||||||
|
assert resp.status_code == int(HTTPStatus.OK)
|
||||||
|
assert "id_type" in resp.text
|
||||||
|
|
||||||
|
# As a trusted user, we cannot change account type to DEVELOPER_ID.
|
||||||
|
post_data = {
|
||||||
|
"U": user.Username,
|
||||||
|
"E": user.Email,
|
||||||
|
"T": DEVELOPER_ID,
|
||||||
|
"passwd": "testPassword"
|
||||||
|
}
|
||||||
|
with client as request:
|
||||||
|
resp = request.post(endpoint, data=post_data, cookies=cookies)
|
||||||
|
assert resp.status_code == int(HTTPStatus.BAD_REQUEST)
|
||||||
|
errors = get_errors(resp.text)
|
||||||
|
expected = ("You do not have permission to change "
|
||||||
|
"this user's account type to Developer.")
|
||||||
|
assert errors[0].text.strip() == expected
|
||||||
|
|
||||||
|
# However, we can modify our account type to USER_ID.
|
||||||
|
post_data = {
|
||||||
|
"U": user.Username,
|
||||||
|
"E": user.Email,
|
||||||
|
"T": USER_ID,
|
||||||
|
"passwd": "testPassword"
|
||||||
|
}
|
||||||
|
with client as request:
|
||||||
|
resp = request.post(endpoint, data=post_data, cookies=cookies)
|
||||||
|
assert resp.status_code == int(HTTPStatus.OK)
|
||||||
|
|
||||||
|
# No errors should be displayed.
|
||||||
|
errors = get_errors(resp.text)
|
||||||
|
assert not errors
|
||||||
|
|
||||||
|
# Make sure it got changed to USER_ID as we intended.
|
||||||
|
assert user.AccountTypeID == USER_ID
|
||||||
|
|
||||||
|
# Change user to a Developer.
|
||||||
|
with db.begin():
|
||||||
|
user.AccountTypeID = DEVELOPER_ID
|
||||||
|
|
||||||
|
# As a developer, we can absolutely change all account types.
|
||||||
|
# For example, from DEVELOPER_ID to TRUSTED_USER_AND_DEV_ID:
|
||||||
|
post_data = {
|
||||||
|
"U": user.Username,
|
||||||
|
"E": user.Email,
|
||||||
|
"T": TRUSTED_USER_AND_DEV_ID,
|
||||||
|
"passwd": "testPassword"
|
||||||
|
}
|
||||||
|
with client as request:
|
||||||
|
resp = request.post(endpoint, data=post_data, cookies=cookies)
|
||||||
|
assert resp.status_code == int(HTTPStatus.OK)
|
||||||
|
assert user.AccountTypeID == TRUSTED_USER_AND_DEV_ID
|
||||||
|
|
||||||
|
|
||||||
def test_get_account():
|
def test_get_account():
|
||||||
request = Request()
|
request = Request()
|
||||||
sid = user.login(request, "testPassword")
|
sid = user.login(request, "testPassword")
|
||||||
|
|
Loading…
Add table
Reference in a new issue