mirror of
https://gitlab.archlinux.org/archlinux/aurweb.git
synced 2025-02-03 10:43:03 +01:00
add account edit (settings) routes
* Added account_url filter to jinja2 environment. This produces a path to the user's account url (/account/{username}). * Updated archdev-navbar to link to new edit route. + Added migrate_cookies(request, response) to aurweb.util, a function that simply migrates the request cookies to response and returns it. + Added account_edit tests to test_accounts_routes.py. Signed-off-by: Kevin Morris <kevr@0cost.org>
This commit is contained in:
parent
d323c1f95b
commit
4e9ef6fb00
7 changed files with 522 additions and 5 deletions
|
@ -1,5 +1,6 @@
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
|
|
||||||
from fastapi import APIRouter, Form, Request
|
from fastapi import APIRouter, Form, Request
|
||||||
|
@ -284,6 +285,7 @@ def make_account_form_context(context: dict,
|
||||||
context["cn"] = args.get("CN", user.CommentNotify)
|
context["cn"] = args.get("CN", user.CommentNotify)
|
||||||
context["un"] = args.get("UN", user.UpdateNotify)
|
context["un"] = args.get("UN", user.UpdateNotify)
|
||||||
context["on"] = args.get("ON", user.OwnershipNotify)
|
context["on"] = args.get("ON", user.OwnershipNotify)
|
||||||
|
context["inactive"] = args.get("J", user.InactivityTS != 0)
|
||||||
else:
|
else:
|
||||||
context["username"] = args.get("U", str())
|
context["username"] = args.get("U", str())
|
||||||
context["account_type"] = args.get("T", user_account_type_id)
|
context["account_type"] = args.get("T", user_account_type_id)
|
||||||
|
@ -301,6 +303,7 @@ def make_account_form_context(context: dict,
|
||||||
context["cn"] = args.get("CN", True)
|
context["cn"] = args.get("CN", True)
|
||||||
context["un"] = args.get("UN", False)
|
context["un"] = args.get("UN", False)
|
||||||
context["on"] = args.get("ON", True)
|
context["on"] = args.get("ON", True)
|
||||||
|
context["inactive"] = args.get("J", False)
|
||||||
|
|
||||||
context["password"] = args.get("P", str())
|
context["password"] = args.get("P", str())
|
||||||
context["confirm"] = args.get("C", str())
|
context["confirm"] = args.get("C", str())
|
||||||
|
@ -409,3 +412,145 @@ async def account_register_post(request: Request,
|
||||||
context["complete"] = True
|
context["complete"] = True
|
||||||
context["user"] = user
|
context["user"] = user
|
||||||
return render_template(request, "register.html", context)
|
return render_template(request, "register.html", context)
|
||||||
|
|
||||||
|
|
||||||
|
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",
|
||||||
|
approved=[user])
|
||||||
|
if not has_dev_cred:
|
||||||
|
return HTMLResponse(status_code=int(HTTPStatus.UNAUTHORIZED))
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/account/{username}/edit", response_class=HTMLResponse)
|
||||||
|
@auth_required(True)
|
||||||
|
async def account_edit(request: Request,
|
||||||
|
username: str):
|
||||||
|
user = db.query(User, User.Username == username).first()
|
||||||
|
response = cannot_edit(request, user)
|
||||||
|
if response:
|
||||||
|
return response
|
||||||
|
|
||||||
|
context = await make_variable_context(request, "Accounts")
|
||||||
|
context["user"] = user
|
||||||
|
|
||||||
|
context = make_account_form_context(context, request, user, dict())
|
||||||
|
return render_template(request, "account/edit.html", context)
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/account/{username}/edit", response_class=HTMLResponse)
|
||||||
|
@auth_required(True)
|
||||||
|
async def account_edit_post(request: Request,
|
||||||
|
username: str,
|
||||||
|
U: str = Form(default=str()), # Username
|
||||||
|
J: bool = Form(default=False),
|
||||||
|
E: str = Form(default=str()), # Email
|
||||||
|
H: str = Form(default=False), # Hide Email
|
||||||
|
BE: str = Form(default=None), # Backup Email
|
||||||
|
R: str = Form(default=None), # Real Name
|
||||||
|
HP: str = Form(default=None), # Homepage
|
||||||
|
I: str = Form(default=None), # IRC Nick
|
||||||
|
K: str = Form(default=None), # PGP Key
|
||||||
|
L: str = Form(aurweb.config.get(
|
||||||
|
"options", "default_lang")),
|
||||||
|
TZ: str = Form(aurweb.config.get(
|
||||||
|
"options", "default_timezone")),
|
||||||
|
P: str = Form(default=str()), # New Password
|
||||||
|
C: str = Form(default=None), # Password Confirm
|
||||||
|
PK: str = Form(default=None), # PubKey
|
||||||
|
CN: bool = Form(default=False), # Comment Notify
|
||||||
|
UN: bool = Form(default=False), # Update Notify
|
||||||
|
ON: bool = Form(default=False), # Owner Notify
|
||||||
|
passwd: str = Form(default=str())):
|
||||||
|
from aurweb.db import session
|
||||||
|
|
||||||
|
user = session.query(User).filter(User.Username == username).first()
|
||||||
|
response = cannot_edit(request, user)
|
||||||
|
if response:
|
||||||
|
return response
|
||||||
|
|
||||||
|
context = await make_variable_context(request, "Accounts")
|
||||||
|
context["user"] = user
|
||||||
|
|
||||||
|
if not passwd:
|
||||||
|
context["errors"] = ["Invalid password."]
|
||||||
|
return render_template(request, "account/edit.html", context,
|
||||||
|
status_code=int(HTTPStatus.BAD_REQUEST))
|
||||||
|
|
||||||
|
args = dict(await request.form())
|
||||||
|
context = make_account_form_context(context, request, user, args)
|
||||||
|
ok, errors = process_account_form(request, user, args)
|
||||||
|
|
||||||
|
if not ok:
|
||||||
|
context["errors"] = errors
|
||||||
|
return render_template(request, "account/edit.html", context,
|
||||||
|
status_code=int(HTTPStatus.BAD_REQUEST))
|
||||||
|
|
||||||
|
# Set all updated fields as needed.
|
||||||
|
user.Username = U or user.Username
|
||||||
|
user.Email = E or user.Email
|
||||||
|
user.HideEmail = bool(H)
|
||||||
|
user.BackupEmail = BE or user.BackupEmail
|
||||||
|
user.RealName = R or user.RealName
|
||||||
|
user.Homepage = HP or user.Homepage
|
||||||
|
user.IRCNick = I or user.IRCNick
|
||||||
|
user.PGPKey = K or user.PGPKey
|
||||||
|
user.InactivityTS = datetime.utcnow().timestamp() if J else 0
|
||||||
|
|
||||||
|
# If we update the language, update the cookie as well.
|
||||||
|
if L and L != user.LangPreference:
|
||||||
|
request.cookies["AURLANG"] = L
|
||||||
|
user.LangPreference = L
|
||||||
|
context["language"] = L
|
||||||
|
|
||||||
|
# If we update the timezone, also update the cookie.
|
||||||
|
if TZ and TZ != user.Timezone:
|
||||||
|
user.Timezone = TZ
|
||||||
|
request.cookies["AURTZ"] = TZ
|
||||||
|
context["timezone"] = TZ
|
||||||
|
|
||||||
|
user.CommentNotify = bool(CN)
|
||||||
|
user.UpdateNotify = bool(UN)
|
||||||
|
user.OwnershipNotify = bool(ON)
|
||||||
|
|
||||||
|
# If a PK is given, compare it against the target user's PK.
|
||||||
|
if PK:
|
||||||
|
# Get the second token in the public key, which is the actual key.
|
||||||
|
pubkey = PK.strip().rstrip()
|
||||||
|
fingerprint = get_fingerprint(pubkey)
|
||||||
|
if not user.ssh_pub_key:
|
||||||
|
# No public key exists, create one.
|
||||||
|
user.ssh_pub_key = SSHPubKey(UserID=user.ID,
|
||||||
|
PubKey=PK,
|
||||||
|
Fingerprint=fingerprint)
|
||||||
|
elif user.ssh_pub_key.Fingerprint != fingerprint:
|
||||||
|
# A public key already exists, update it.
|
||||||
|
user.ssh_pub_key.PubKey = PK
|
||||||
|
user.ssh_pub_key.Fingerprint = fingerprint
|
||||||
|
elif user.ssh_pub_key:
|
||||||
|
# Else, if the user has a public key already, delete it.
|
||||||
|
session.delete(user.ssh_pub_key)
|
||||||
|
|
||||||
|
# Commit changes, if any.
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
if P and not user.valid_password(P):
|
||||||
|
# Remove the fields we consumed for passwords.
|
||||||
|
context["P"] = context["C"] = str()
|
||||||
|
|
||||||
|
# If a password was given and it doesn't match the user's, update it.
|
||||||
|
user.update_password(P)
|
||||||
|
if user == request.user:
|
||||||
|
# If the target user is the request user, login with
|
||||||
|
# the updated password and update AURSID.
|
||||||
|
request.cookies["AURSID"] = user.login(request, P)
|
||||||
|
|
||||||
|
if not errors:
|
||||||
|
context["complete"] = True
|
||||||
|
|
||||||
|
# Update cookies with requests, in case they were changed.
|
||||||
|
response = render_template(request, "account/edit.html", context)
|
||||||
|
return util.migrate_cookies(request, response)
|
||||||
|
>>>>>> > dddd1137... add account edit(settings) routes
|
||||||
|
|
|
@ -12,7 +12,7 @@ from fastapi.responses import HTMLResponse
|
||||||
|
|
||||||
import aurweb.config
|
import aurweb.config
|
||||||
|
|
||||||
from aurweb import captcha, l10n, time
|
from aurweb import captcha, l10n, time, util
|
||||||
|
|
||||||
# Prepare jinja2 objects.
|
# Prepare jinja2 objects.
|
||||||
loader = jinja2.FileSystemLoader(os.path.join(
|
loader = jinja2.FileSystemLoader(os.path.join(
|
||||||
|
@ -27,6 +27,9 @@ env.filters["tr"] = l10n.tr
|
||||||
env.filters["captcha_salt"] = captcha.captcha_salt_filter
|
env.filters["captcha_salt"] = captcha.captcha_salt_filter
|
||||||
env.filters["captcha_cmdline"] = captcha.captcha_cmdline_filter
|
env.filters["captcha_cmdline"] = captcha.captcha_cmdline_filter
|
||||||
|
|
||||||
|
# Add account utility filters.
|
||||||
|
env.filters["account_url"] = util.account_url
|
||||||
|
|
||||||
|
|
||||||
def make_context(request: Request, title: str, next: str = None):
|
def make_context(request: Request, title: str, next: str = None):
|
||||||
""" Create a context for a jinja2 TemplateResponse. """
|
""" Create a context for a jinja2 TemplateResponse. """
|
||||||
|
|
|
@ -82,6 +82,12 @@ def valid_ssh_pubkey(pk):
|
||||||
return base64.b64encode(base64.b64decode(tokens[1])).decode() == tokens[1]
|
return base64.b64encode(base64.b64decode(tokens[1])).decode() == tokens[1]
|
||||||
|
|
||||||
|
|
||||||
|
def migrate_cookies(request, response):
|
||||||
|
for k, v in request.cookies.items():
|
||||||
|
response.set_cookie(k, v)
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
@jinja2.contextfilter
|
@jinja2.contextfilter
|
||||||
def account_url(context, user):
|
def account_url(context, user):
|
||||||
request = context.get("request")
|
request = context.get("request")
|
||||||
|
|
46
templates/account/edit.html
Normal file
46
templates/account/edit.html
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
{% extends "partials/layout.html" %}
|
||||||
|
|
||||||
|
{% block pageContent %}
|
||||||
|
<div class="box">
|
||||||
|
<h2>{% trans %}Accounts{% endtrans %}</h2>
|
||||||
|
|
||||||
|
{% if complete %}
|
||||||
|
|
||||||
|
{{
|
||||||
|
"The account, %s%s%s, has been successfully modified."
|
||||||
|
| tr
|
||||||
|
| format("<strong>", user.Username, "</strong>")
|
||||||
|
| safe
|
||||||
|
}}
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
{% if errors %}
|
||||||
|
{% include "partials/error.html" %}
|
||||||
|
{% else %}
|
||||||
|
<p>
|
||||||
|
{{ "Click %shere%s if you want to permanently delete this account."
|
||||||
|
| tr
|
||||||
|
| format('<a href="%s/delete">' | format(user | account_url),
|
||||||
|
"</a>")
|
||||||
|
| safe
|
||||||
|
}}
|
||||||
|
{{ "Click %shere%s for user details."
|
||||||
|
| tr
|
||||||
|
| format('<a href="%s">' | format(user | account_url),
|
||||||
|
"</a>")
|
||||||
|
| safe
|
||||||
|
}}
|
||||||
|
{{ "Click %shere%s to list the comments made by this account."
|
||||||
|
| tr
|
||||||
|
| format('<a href="%s/comments">' | format(user | account_url),
|
||||||
|
"</a>")
|
||||||
|
| safe
|
||||||
|
}}
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% set form_type = "UpdateAccount" %}
|
||||||
|
{% include "partials/account_form.html" %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -42,6 +42,15 @@
|
||||||
"account is inactive." | tr }}</em>
|
"account is inactive." | tr }}</em>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<label for="id_inactive">{% trans %}Inactive{% endtrans %}:</label>
|
||||||
|
<input id="id_inactive" type="checkbox" name="J"
|
||||||
|
{% if inactive %}
|
||||||
|
checked="checked"
|
||||||
|
{% endif %}
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
|
||||||
{% if request.user.has_credential("CRED_ACCOUNT_CHANGE_TYPE") %}
|
{% if request.user.has_credential("CRED_ACCOUNT_CHANGE_TYPE") %}
|
||||||
<p>
|
<p>
|
||||||
<label for="id_type">
|
<label for="id_type">
|
||||||
|
|
|
@ -6,16 +6,28 @@
|
||||||
<li><a href="/">AUR {% trans %}Home{% endtrans %}</a></li>
|
<li><a href="/">AUR {% trans %}Home{% endtrans %}</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li><a href="/packages/">{% trans %}Packages{% endtrans %}</a></li>
|
<li><a href="/packages/">{% trans %}Packages{% endtrans %}</a></li>
|
||||||
<li><a href="/register/">{% trans %}Register{% endtrans %}</a></li>
|
{% if request.user.is_authenticated() %}
|
||||||
<li>
|
<li>
|
||||||
{% if request.user.is_authenticated() %}
|
<a href="/account/{{ request.user.Username }}/edit">
|
||||||
|
{% trans %} My Account{% endtrans %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
<a href="/logout/?next={{ next }}">
|
<a href="/logout/?next={{ next }}">
|
||||||
{% trans %}Logout{% endtrans %}
|
{% trans %}Logout{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
{% else %}
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li>
|
||||||
|
<a href="/register">
|
||||||
|
{% trans %}Register{% endtrans %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
<a href="/login/?next={{ next }}">
|
<a href="/login/?next={{ next }}">
|
||||||
{% trans %}Login{% endtrans %}
|
{% trans %}Login{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -5,6 +5,7 @@ from datetime import datetime
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
from subprocess import Popen
|
from subprocess import Popen
|
||||||
|
|
||||||
|
import lxml.html
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from fastapi.testclient import TestClient
|
from fastapi.testclient import TestClient
|
||||||
|
@ -574,3 +575,298 @@ def test_post_register_with_ssh_pubkey():
|
||||||
response = post_register(request, PK=pk)
|
response = post_register(request, PK=pk)
|
||||||
|
|
||||||
assert response.status_code == int(HTTPStatus.OK)
|
assert response.status_code == int(HTTPStatus.OK)
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_account_edit():
|
||||||
|
request = Request()
|
||||||
|
sid = user.login(request, "testPassword")
|
||||||
|
|
||||||
|
with client as request:
|
||||||
|
response = request.get("/account/test/edit", cookies={
|
||||||
|
"AURSID": sid
|
||||||
|
}, allow_redirects=False)
|
||||||
|
|
||||||
|
assert response.status_code == int(HTTPStatus.OK)
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_account_edit_unauthorized():
|
||||||
|
request = Request()
|
||||||
|
sid = user.login(request, "testPassword")
|
||||||
|
|
||||||
|
create(User, Username="test2", Email="test2@example.org",
|
||||||
|
Passwd="testPassword")
|
||||||
|
|
||||||
|
with client as request:
|
||||||
|
# Try to edit `test2` while authenticated as `test`.
|
||||||
|
response = request.get("/account/test2/edit", cookies={
|
||||||
|
"AURSID": sid
|
||||||
|
}, allow_redirects=False)
|
||||||
|
|
||||||
|
assert response.status_code == int(HTTPStatus.UNAUTHORIZED)
|
||||||
|
|
||||||
|
|
||||||
|
def test_post_account_edit():
|
||||||
|
request = Request()
|
||||||
|
sid = user.login(request, "testPassword")
|
||||||
|
|
||||||
|
post_data = {
|
||||||
|
"U": "test",
|
||||||
|
"E": "test666@example.org",
|
||||||
|
"passwd": "testPassword"
|
||||||
|
}
|
||||||
|
|
||||||
|
with client as request:
|
||||||
|
response = request.post("/account/test/edit", cookies={
|
||||||
|
"AURSID": sid
|
||||||
|
}, data=post_data, allow_redirects=False)
|
||||||
|
|
||||||
|
assert response.status_code == int(HTTPStatus.OK)
|
||||||
|
|
||||||
|
expected = "The account, <strong>test</strong>, "
|
||||||
|
expected += "has been successfully modified."
|
||||||
|
assert expected in response.content.decode()
|
||||||
|
|
||||||
|
|
||||||
|
def test_post_account_edit_dev():
|
||||||
|
from aurweb.db import session
|
||||||
|
|
||||||
|
# Modify our user to be a "Trusted User & Developer"
|
||||||
|
name = "Trusted User & Developer"
|
||||||
|
tu_or_dev = query(AccountType, AccountType.AccountType == name).first()
|
||||||
|
user.AccountType = tu_or_dev
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
request = Request()
|
||||||
|
sid = user.login(request, "testPassword")
|
||||||
|
|
||||||
|
post_data = {
|
||||||
|
"U": "test",
|
||||||
|
"E": "test666@example.org",
|
||||||
|
"passwd": "testPassword"
|
||||||
|
}
|
||||||
|
|
||||||
|
with client as request:
|
||||||
|
response = request.post("/account/test/edit", cookies={
|
||||||
|
"AURSID": sid
|
||||||
|
}, data=post_data, allow_redirects=False)
|
||||||
|
|
||||||
|
assert response.status_code == int(HTTPStatus.OK)
|
||||||
|
|
||||||
|
expected = "The account, <strong>test</strong>, "
|
||||||
|
expected += "has been successfully modified."
|
||||||
|
assert expected in response.content.decode()
|
||||||
|
|
||||||
|
|
||||||
|
def test_post_account_edit_language():
|
||||||
|
request = Request()
|
||||||
|
sid = user.login(request, "testPassword")
|
||||||
|
|
||||||
|
post_data = {
|
||||||
|
"U": "test",
|
||||||
|
"E": "test@example.org",
|
||||||
|
"L": "de", # German
|
||||||
|
"passwd": "testPassword"
|
||||||
|
}
|
||||||
|
|
||||||
|
with client as request:
|
||||||
|
response = request.post("/account/test/edit", cookies={
|
||||||
|
"AURSID": sid
|
||||||
|
}, data=post_data, allow_redirects=False)
|
||||||
|
|
||||||
|
assert response.status_code == int(HTTPStatus.OK)
|
||||||
|
|
||||||
|
# Parse the response content html into an lxml root, then make
|
||||||
|
# sure we see a 'de' option selected on the page.
|
||||||
|
content = response.content.decode()
|
||||||
|
root = lxml.html.fromstring(content)
|
||||||
|
lang_nodes = root.xpath('//option[@value="de"]/@selected')
|
||||||
|
assert lang_nodes and len(lang_nodes) != 0
|
||||||
|
assert lang_nodes[0] == "selected"
|
||||||
|
|
||||||
|
|
||||||
|
def test_post_account_edit_timezone():
|
||||||
|
request = Request()
|
||||||
|
sid = user.login(request, "testPassword")
|
||||||
|
|
||||||
|
post_data = {
|
||||||
|
"U": "test",
|
||||||
|
"E": "test@example.org",
|
||||||
|
"TZ": "CET",
|
||||||
|
"passwd": "testPassword"
|
||||||
|
}
|
||||||
|
|
||||||
|
with client as request:
|
||||||
|
response = request.post("/account/test/edit", cookies={
|
||||||
|
"AURSID": sid
|
||||||
|
}, data=post_data, allow_redirects=False)
|
||||||
|
|
||||||
|
assert response.status_code == int(HTTPStatus.OK)
|
||||||
|
|
||||||
|
|
||||||
|
def test_post_account_edit_error_missing_password():
|
||||||
|
request = Request()
|
||||||
|
sid = user.login(request, "testPassword")
|
||||||
|
|
||||||
|
post_data = {
|
||||||
|
"U": "test",
|
||||||
|
"E": "test@example.org",
|
||||||
|
"TZ": "CET",
|
||||||
|
"passwd": ""
|
||||||
|
}
|
||||||
|
|
||||||
|
with client as request:
|
||||||
|
response = request.post("/account/test/edit", cookies={
|
||||||
|
"AURSID": sid
|
||||||
|
}, data=post_data, allow_redirects=False)
|
||||||
|
|
||||||
|
assert response.status_code == int(HTTPStatus.BAD_REQUEST)
|
||||||
|
|
||||||
|
content = response.content.decode()
|
||||||
|
assert "Invalid password." in content
|
||||||
|
|
||||||
|
|
||||||
|
def test_post_account_edit_error_invalid_password():
|
||||||
|
request = Request()
|
||||||
|
sid = user.login(request, "testPassword")
|
||||||
|
|
||||||
|
post_data = {
|
||||||
|
"U": "test",
|
||||||
|
"E": "test@example.org",
|
||||||
|
"TZ": "CET",
|
||||||
|
"passwd": "invalid"
|
||||||
|
}
|
||||||
|
|
||||||
|
with client as request:
|
||||||
|
response = request.post("/account/test/edit", cookies={
|
||||||
|
"AURSID": sid
|
||||||
|
}, data=post_data, allow_redirects=False)
|
||||||
|
|
||||||
|
assert response.status_code == int(HTTPStatus.BAD_REQUEST)
|
||||||
|
|
||||||
|
content = response.content.decode()
|
||||||
|
assert "Invalid password." in content
|
||||||
|
|
||||||
|
|
||||||
|
def test_post_account_edit_error_unauthorized():
|
||||||
|
request = Request()
|
||||||
|
sid = user.login(request, "testPassword")
|
||||||
|
|
||||||
|
test2 = create(User, Username="test2", Email="test2@example.org",
|
||||||
|
Passwd="testPassword")
|
||||||
|
|
||||||
|
post_data = {
|
||||||
|
"U": "test",
|
||||||
|
"E": "test@example.org",
|
||||||
|
"TZ": "CET",
|
||||||
|
"passwd": "testPassword"
|
||||||
|
}
|
||||||
|
|
||||||
|
with client as request:
|
||||||
|
# Attempt to edit 'test2' while logged in as 'test'.
|
||||||
|
response = request.post("/account/test2/edit", cookies={
|
||||||
|
"AURSID": sid
|
||||||
|
}, data=post_data, allow_redirects=False)
|
||||||
|
|
||||||
|
assert response.status_code == int(HTTPStatus.UNAUTHORIZED)
|
||||||
|
|
||||||
|
|
||||||
|
def test_post_account_edit_ssh_pub_key():
|
||||||
|
pk = str()
|
||||||
|
|
||||||
|
# Create a public key with ssh-keygen (this adds ssh-keygen as a
|
||||||
|
# dependency to passing this test).
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
|
with open("/dev/null", "w") as null:
|
||||||
|
proc = Popen(["ssh-keygen", "-f", f"{tmpdir}/test.ssh", "-N", ""],
|
||||||
|
stdout=null, stderr=null)
|
||||||
|
proc.wait()
|
||||||
|
assert proc.returncode == 0
|
||||||
|
|
||||||
|
# Read in the public key, then delete the temp dir we made.
|
||||||
|
pk = open(f"{tmpdir}/test.ssh.pub").read().rstrip()
|
||||||
|
|
||||||
|
request = Request()
|
||||||
|
sid = user.login(request, "testPassword")
|
||||||
|
|
||||||
|
post_data = {
|
||||||
|
"U": "test",
|
||||||
|
"E": "test@example.org",
|
||||||
|
"PK": pk,
|
||||||
|
"passwd": "testPassword"
|
||||||
|
}
|
||||||
|
|
||||||
|
with client as request:
|
||||||
|
response = request.post("/account/test/edit", cookies={
|
||||||
|
"AURSID": sid
|
||||||
|
}, data=post_data, allow_redirects=False)
|
||||||
|
|
||||||
|
assert response.status_code == int(HTTPStatus.OK)
|
||||||
|
|
||||||
|
# Now let's update what's already there to gain coverage over that path.
|
||||||
|
pk = str()
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
|
with open("/dev/null", "w") as null:
|
||||||
|
proc = Popen(["ssh-keygen", "-f", f"{tmpdir}/test.ssh", "-N", ""],
|
||||||
|
stdout=null, stderr=null)
|
||||||
|
proc.wait()
|
||||||
|
assert proc.returncode == 0
|
||||||
|
|
||||||
|
# Read in the public key, then delete the temp dir we made.
|
||||||
|
pk = open(f"{tmpdir}/test.ssh.pub").read().rstrip()
|
||||||
|
|
||||||
|
post_data["PK"] = pk
|
||||||
|
|
||||||
|
with client as request:
|
||||||
|
response = request.post("/account/test/edit", cookies={
|
||||||
|
"AURSID": sid
|
||||||
|
}, data=post_data, allow_redirects=False)
|
||||||
|
|
||||||
|
assert response.status_code == int(HTTPStatus.OK)
|
||||||
|
|
||||||
|
|
||||||
|
def test_post_account_edit_invalid_ssh_pubkey():
|
||||||
|
pubkey = "ssh-rsa fake key"
|
||||||
|
|
||||||
|
request = Request()
|
||||||
|
sid = user.login(request, "testPassword")
|
||||||
|
|
||||||
|
post_data = {
|
||||||
|
"U": "test",
|
||||||
|
"E": "test@example.org",
|
||||||
|
"P": "newPassword",
|
||||||
|
"C": "newPassword",
|
||||||
|
"PK": pubkey,
|
||||||
|
"passwd": "testPassword"
|
||||||
|
}
|
||||||
|
|
||||||
|
with client as request:
|
||||||
|
response = request.post("/account/test/edit", cookies={
|
||||||
|
"AURSID": sid
|
||||||
|
}, data=post_data, allow_redirects=False)
|
||||||
|
|
||||||
|
assert response.status_code == int(HTTPStatus.BAD_REQUEST)
|
||||||
|
|
||||||
|
|
||||||
|
def test_post_account_edit_password():
|
||||||
|
request = Request()
|
||||||
|
sid = user.login(request, "testPassword")
|
||||||
|
|
||||||
|
post_data = {
|
||||||
|
"U": "test",
|
||||||
|
"E": "test@example.org",
|
||||||
|
"P": "newPassword",
|
||||||
|
"C": "newPassword",
|
||||||
|
"passwd": "testPassword"
|
||||||
|
}
|
||||||
|
|
||||||
|
with client as request:
|
||||||
|
response = request.post("/account/test/edit", cookies={
|
||||||
|
"AURSID": sid
|
||||||
|
}, data=post_data, allow_redirects=False)
|
||||||
|
|
||||||
|
assert response.status_code == int(HTTPStatus.OK)
|
||||||
|
|
||||||
|
assert user.valid_password("newPassword")
|
||||||
|
|
||||||
|
|
||||||
|
>>>>>> > dddd1137... add account edit(settings) routes
|
||||||
|
|
Loading…
Add table
Reference in a new issue