mirror of
https://gitlab.archlinux.org/archlinux/aurweb.git
synced 2025-02-03 10:43:03 +01:00
Merge branch 'master' into live
This commit is contained in:
commit
5eb7b43d55
12 changed files with 54 additions and 32 deletions
|
@ -6,7 +6,7 @@ from typing import Any
|
||||||
# Publicly visible version of aurweb. This is used to display
|
# Publicly visible version of aurweb. This is used to display
|
||||||
# aurweb versioning in the footer and must be maintained.
|
# aurweb versioning in the footer and must be maintained.
|
||||||
# Todo: Make this dynamic/automated.
|
# Todo: Make this dynamic/automated.
|
||||||
AURWEB_VERSION = "v6.0.6"
|
AURWEB_VERSION = "v6.0.7"
|
||||||
|
|
||||||
_parser = None
|
_parser = None
|
||||||
|
|
||||||
|
|
|
@ -120,24 +120,25 @@ class PackageSearch:
|
||||||
|
|
||||||
def _search_by_comaintainer(self, keywords: str) -> orm.Query:
|
def _search_by_comaintainer(self, keywords: str) -> orm.Query:
|
||||||
self._join_user()
|
self._join_user()
|
||||||
exists_subq = db.query(PackageComaintainer).join(User).filter(
|
user = db.query(User).filter(User.Username == keywords).first()
|
||||||
and_(PackageComaintainer.PackageBaseID == PackageBase.ID,
|
uid = 0 if not user else user.ID
|
||||||
User.Username == keywords)
|
self.query = self.query.join(
|
||||||
).exists()
|
PackageComaintainer,
|
||||||
self.query = self.query.filter(db.query(exists_subq).scalar_subquery())
|
PackageComaintainer.PackageBaseID == PackageBase.ID
|
||||||
|
).filter(PackageComaintainer.UsersID == uid)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def _search_by_co_or_maintainer(self, keywords: str) -> orm.Query:
|
def _search_by_co_or_maintainer(self, keywords: str) -> orm.Query:
|
||||||
self._join_user()
|
self._join_user()
|
||||||
exists_subq = db.query(PackageComaintainer).join(User).filter(
|
|
||||||
and_(PackageComaintainer.PackageBaseID == PackageBase.ID,
|
user = db.query(User).filter(User.Username == keywords).first()
|
||||||
User.Username == keywords)
|
uid = 0 if not user else user.ID
|
||||||
).exists()
|
self.query = self.query.join(
|
||||||
self.query = self.query.filter(
|
PackageComaintainer,
|
||||||
or_(and_(User.Username == keywords,
|
PackageComaintainer.PackageBaseID == PackageBase.ID,
|
||||||
User.ID == PackageBase.MaintainerUID),
|
isouter=True
|
||||||
db.query(exists_subq).scalar_subquery())
|
).filter(or_(PackageComaintainer.UsersID == uid, User.ID == uid))
|
||||||
)
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def _search_by_submitter(self, keywords: str) -> orm.Query:
|
def _search_by_submitter(self, keywords: str) -> orm.Query:
|
||||||
|
|
|
@ -265,7 +265,7 @@ async def account_register_post(request: Request,
|
||||||
"options", "default_lang")),
|
"options", "default_lang")),
|
||||||
TZ: str = Form(default=aurweb.config.get(
|
TZ: str = Form(default=aurweb.config.get(
|
||||||
"options", "default_timezone")),
|
"options", "default_timezone")),
|
||||||
PK: str = Form(default=None), # SSH PubKey
|
PK: str = Form(default=str()), # SSH PubKey
|
||||||
CN: bool = Form(default=False),
|
CN: bool = Form(default=False),
|
||||||
UN: bool = Form(default=False),
|
UN: bool = Form(default=False),
|
||||||
ON: bool = Form(default=False),
|
ON: bool = Form(default=False),
|
||||||
|
@ -273,6 +273,8 @@ async def account_register_post(request: Request,
|
||||||
captcha_salt: str = Form(...)):
|
captcha_salt: str = Form(...)):
|
||||||
context = await make_variable_context(request, "Register")
|
context = await make_variable_context(request, "Register")
|
||||||
args = dict(await request.form())
|
args = dict(await request.form())
|
||||||
|
args["K"] = args.get("K", str()).replace(" ", "")
|
||||||
|
K = args.get("K")
|
||||||
|
|
||||||
context = make_account_form_context(context, request, None, args)
|
context = make_account_form_context(context, request, None, args)
|
||||||
ok, errors = process_account_form(request, request.user, args)
|
ok, errors = process_account_form(request, request.user, args)
|
||||||
|
@ -399,6 +401,8 @@ async def account_edit_post(request: Request,
|
||||||
context["user"] = db.refresh(user)
|
context["user"] = db.refresh(user)
|
||||||
|
|
||||||
args = dict(await request.form())
|
args = dict(await request.form())
|
||||||
|
args["K"] = args.get("K", str()).replace(" ", "")
|
||||||
|
|
||||||
context = make_account_form_context(context, request, user, args)
|
context = make_account_form_context(context, request, user, args)
|
||||||
ok, errors = process_account_form(request, user, args)
|
ok, errors = process_account_form(request, user, args)
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ from http import HTTPStatus
|
||||||
|
|
||||||
from fastapi import APIRouter, Form, HTTPException, Request
|
from fastapi import APIRouter, Form, HTTPException, Request
|
||||||
from fastapi.responses import HTMLResponse, RedirectResponse
|
from fastapi.responses import HTMLResponse, RedirectResponse
|
||||||
|
from sqlalchemy import or_
|
||||||
|
|
||||||
import aurweb.config
|
import aurweb.config
|
||||||
|
|
||||||
|
@ -43,7 +44,9 @@ async def login_post(request: Request,
|
||||||
raise HTTPException(status_code=HTTPStatus.BAD_REQUEST,
|
raise HTTPException(status_code=HTTPStatus.BAD_REQUEST,
|
||||||
detail=_("Bad Referer header."))
|
detail=_("Bad Referer header."))
|
||||||
|
|
||||||
user = db.query(User).filter(User.Username == user).first()
|
user = db.query(User).filter(
|
||||||
|
or_(User.Username == user, User.Email == user)
|
||||||
|
).first()
|
||||||
if not user:
|
if not user:
|
||||||
return await login_template(request, next,
|
return await login_template(request, next,
|
||||||
errors=["Bad username or password."])
|
errors=["Bad username or password."])
|
||||||
|
|
|
@ -78,7 +78,7 @@ async def pkgbase_voters(request: Request, name: str) -> Response:
|
||||||
async def pkgbase_flag_comment(request: Request, name: str):
|
async def pkgbase_flag_comment(request: Request, name: str):
|
||||||
pkgbase = get_pkg_or_base(name, PackageBase)
|
pkgbase = get_pkg_or_base(name, PackageBase)
|
||||||
|
|
||||||
if pkgbase.Flagger is None:
|
if pkgbase.OutOfDateTS is None:
|
||||||
return RedirectResponse(f"/pkgbase/{name}",
|
return RedirectResponse(f"/pkgbase/{name}",
|
||||||
status_code=HTTPStatus.SEE_OTHER)
|
status_code=HTTPStatus.SEE_OTHER)
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ async def pkgbase_flag_get(request: Request, name: str):
|
||||||
pkgbase = get_pkg_or_base(name, PackageBase)
|
pkgbase = get_pkg_or_base(name, PackageBase)
|
||||||
|
|
||||||
has_cred = request.user.has_credential(creds.PKGBASE_FLAG)
|
has_cred = request.user.has_credential(creds.PKGBASE_FLAG)
|
||||||
if not has_cred or pkgbase.Flagger is not None:
|
if not has_cred or pkgbase.OutOfDateTS is not None:
|
||||||
return RedirectResponse(f"/pkgbase/{name}",
|
return RedirectResponse(f"/pkgbase/{name}",
|
||||||
status_code=HTTPStatus.SEE_OTHER)
|
status_code=HTTPStatus.SEE_OTHER)
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ async def pkgbase_flag_post(request: Request, name: str,
|
||||||
status_code=HTTPStatus.BAD_REQUEST)
|
status_code=HTTPStatus.BAD_REQUEST)
|
||||||
|
|
||||||
has_cred = request.user.has_credential(creds.PKGBASE_FLAG)
|
has_cred = request.user.has_credential(creds.PKGBASE_FLAG)
|
||||||
if has_cred and not pkgbase.Flagger:
|
if has_cred and not pkgbase.OutOfDateTS:
|
||||||
now = time.utcnow()
|
now = time.utcnow()
|
||||||
with db.begin():
|
with db.begin():
|
||||||
pkgbase.OutOfDateTS = now
|
pkgbase.OutOfDateTS = now
|
||||||
|
|
|
@ -7,7 +7,7 @@ import string
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from distutils.util import strtobool as _strtobool
|
from distutils.util import strtobool as _strtobool
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
from typing import Callable, Iterable, Tuple
|
from typing import Callable, Iterable, Tuple, Union
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
import fastapi
|
import fastapi
|
||||||
|
@ -71,7 +71,6 @@ def valid_password(password):
|
||||||
|
|
||||||
|
|
||||||
def valid_pgp_fingerprint(fp):
|
def valid_pgp_fingerprint(fp):
|
||||||
fp = fp.replace(" ", "")
|
|
||||||
try:
|
try:
|
||||||
# Attempt to convert the fingerprint to an int via base16.
|
# Attempt to convert the fingerprint to an int via base16.
|
||||||
# If it can't, it's not a hex string.
|
# If it can't, it's not a hex string.
|
||||||
|
@ -133,9 +132,9 @@ def sanitize_params(offset: str, per_page: str) -> Tuple[int, int]:
|
||||||
return (offset, per_page)
|
return (offset, per_page)
|
||||||
|
|
||||||
|
|
||||||
def strtobool(value: str) -> bool:
|
def strtobool(value: Union[str, bool]) -> bool:
|
||||||
if isinstance(value, str):
|
if isinstance(value, str):
|
||||||
return _strtobool(value)
|
return _strtobool(value or "False")
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -39,10 +39,6 @@ Examples
|
||||||
`/rpc?v=5&type=search&by=makedepends&arg=boost`
|
`/rpc?v=5&type=search&by=makedepends&arg=boost`
|
||||||
`search` with callback::
|
`search` with callback::
|
||||||
`/rpc?v=5&type=search&arg=foobar&callback=jsonp1192244621103`
|
`/rpc?v=5&type=search&arg=foobar&callback=jsonp1192244621103`
|
||||||
`search` with API Version 6 for packages containing `cookie` AND `milk`::
|
|
||||||
`/rpc?v=6&type=search&arg=cookie%20milk`
|
|
||||||
`search` with API Version 6 for packages containing `cookie milk`::
|
|
||||||
`/rpc?v=6&type=search&arg="cookie milk"`
|
|
||||||
`info`::
|
`info`::
|
||||||
`/rpc?v=5&type=info&arg[]=foobar`
|
`/rpc?v=5&type=info&arg[]=foobar`
|
||||||
`info` with multiple packages::
|
`info` with multiple packages::
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#
|
#
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "aurweb"
|
name = "aurweb"
|
||||||
version = "v6.0.6"
|
version = "v6.0.7"
|
||||||
license = "GPL-2.0-only"
|
license = "GPL-2.0-only"
|
||||||
description = "Source code for the Arch User Repository's website"
|
description = "Source code for the Arch User Repository's website"
|
||||||
homepage = "https://aur.archlinux.org"
|
homepage = "https://aur.archlinux.org"
|
||||||
|
|
|
@ -105,7 +105,11 @@
|
||||||
{% trans %}Hide Email Address{% endtrans %}:
|
{% trans %}Hide Email Address{% endtrans %}:
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<input id="id_hide" type="checkbox" name="H" value="{{ H }}">
|
<input id="id_hide" type="checkbox" name="H"
|
||||||
|
{% if hide_email %}
|
||||||
|
checked="checked"
|
||||||
|
{% endif %}
|
||||||
|
>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<em>{{ "If you do not hide your email address, it is "
|
<em>{{ "If you do not hide your email address, it is "
|
||||||
|
|
|
@ -112,8 +112,9 @@
|
||||||
<a href="/account/{{ pkgbase.Maintainer.Username }}">
|
<a href="/account/{{ pkgbase.Maintainer.Username }}">
|
||||||
{{ pkgbase.Maintainer.Username }}
|
{{ pkgbase.Maintainer.Username }}
|
||||||
</a>
|
</a>
|
||||||
|
{% set len = comaintainers | length %}
|
||||||
{% if comaintainers %}
|
{% if comaintainers %}
|
||||||
({% for co in comaintainers %}<a href="{{ co.User | account_url }}">{{ co.User }}</a>{% endfor %})
|
({% for co in comaintainers %}<a href="{{ co.User | account_url }}">{{ co.User }}</a>{% if loop.index < len %}, {% endif %}{% endfor %})
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ pkgbase.Maintainer.Username | default("None" | tr) }}
|
{{ pkgbase.Maintainer.Username | default("None" | tr) }}
|
||||||
|
|
|
@ -79,6 +79,20 @@ def test_login_logout(client: TestClient, user: User):
|
||||||
assert "AURSID" not in response.cookies
|
assert "AURSID" not in response.cookies
|
||||||
|
|
||||||
|
|
||||||
|
def test_login_email(client: TestClient, user: user):
|
||||||
|
post_data = {
|
||||||
|
"user": user.Email,
|
||||||
|
"passwd": "testPassword",
|
||||||
|
"next": "/"
|
||||||
|
}
|
||||||
|
|
||||||
|
with client as request:
|
||||||
|
resp = request.post("/login", data=post_data,
|
||||||
|
allow_redirects=False)
|
||||||
|
assert resp.status_code == int(HTTPStatus.SEE_OTHER)
|
||||||
|
assert "AURSID" in resp.cookies
|
||||||
|
|
||||||
|
|
||||||
def mock_getboolean(a, b):
|
def mock_getboolean(a, b):
|
||||||
if a == "options" and b == "disable_http_login":
|
if a == "options" and b == "disable_http_login":
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -804,7 +804,7 @@ def test_pkgbase_flag(client: TestClient, user: User, maintainer: User,
|
||||||
pkgbase = package.PackageBase
|
pkgbase = package.PackageBase
|
||||||
|
|
||||||
# We shouldn't have flagged the package yet; assert so.
|
# We shouldn't have flagged the package yet; assert so.
|
||||||
assert pkgbase.Flagger is None
|
assert pkgbase.OutOfDateTS is None
|
||||||
|
|
||||||
cookies = {"AURSID": user.login(Request(), "testPassword")}
|
cookies = {"AURSID": user.login(Request(), "testPassword")}
|
||||||
endpoint = f"/pkgbase/{pkgbase.Name}/flag"
|
endpoint = f"/pkgbase/{pkgbase.Name}/flag"
|
||||||
|
|
Loading…
Add table
Reference in a new issue