raise 404 in case if repository is unknown

This commit is contained in:
Evgenii Alekseev 2023-10-16 15:13:13 +03:00
parent c5bd862ae9
commit 2b207e1a89
18 changed files with 43 additions and 16 deletions

View File

@ -202,6 +202,7 @@ Again, the most checks can be performed by `make check` command, though some add
400: {"description": "Bad data is supplied", "schema": ErrorSchema}, # exception raised by this method
401: {"description": "Authorization required", "schema": ErrorSchema}, # should be always presented
403: {"description": "Access is forbidden", "schema": ErrorSchema}, # should be always presented
404: {"description": "Repository is unknown", "schema": ErrorSchema}, # include if BaseView.service() method is called
500: {"description": "Internal server error", "schema": ErrorSchema}, # should be always presented
},
security=[{"token": [POST_PERMISSION]}],

View File

@ -70,9 +70,8 @@ class Lock(LazyLogging):
repository_id(RepositoryId): repository unique identifier
configuration(Configuration): configuration instance
"""
lock_suffix = f"{repository_id.name}_{repository_id.architecture}"
self.path: Path | None = \
args.lock.with_stem(f"{args.lock.stem}_{lock_suffix}") if args.lock is not None else None
args.lock.with_stem(f"{args.lock.stem}_{repository_id.id}") if args.lock is not None else None
self.force: bool = args.force
self.unsafe: bool = args.unsafe

View File

@ -18,7 +18,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from aiohttp_cors import CorsViewMixin # type: ignore[import-untyped]
from aiohttp.web import HTTPBadRequest, Request, StreamResponse, View
from aiohttp.web import HTTPBadRequest, HTTPNotFound, Request, StreamResponse, View
from collections.abc import Awaitable, Callable
from typing import Any, TypeVar
@ -245,10 +245,16 @@ class BaseView(View, CorsViewMixin):
Returns:
Watcher: build status watcher instance. If no repository provided, it will return the first one
Raises:
HTTPNotFound: if no repository found
"""
if repository_id is None:
repository_id = self.repository_id()
return self.services[repository_id]
try:
return self.services[repository_id]
except KeyError:
raise HTTPNotFound(reason=f"Repository {repository_id.id} is unknown")
async def username(self) -> str | None:
"""

View File

@ -46,6 +46,7 @@ class AddView(BaseView):
400: {"description": "Bad data is supplied", "schema": ErrorSchema},
401: {"description": "Authorization required", "schema": ErrorSchema},
403: {"description": "Access is forbidden", "schema": ErrorSchema},
404: {"description": "Repository is unknown", "schema": ErrorSchema},
500: {"description": "Internal server error", "schema": ErrorSchema},
},
security=[{"token": [POST_PERMISSION]}],

View File

@ -48,7 +48,7 @@ class PGPView(BaseView):
400: {"description": "Bad data is supplied", "schema": ErrorSchema},
401: {"description": "Authorization required", "schema": ErrorSchema},
403: {"description": "Access is forbidden", "schema": ErrorSchema},
404: {"description": "Package base is unknown", "schema": ErrorSchema},
404: {"description": "PGP key is unknown", "schema": ErrorSchema},
500: {"description": "Internal server error", "schema": ErrorSchema},
},
security=[{"token": [GET_PERMISSION]}],
@ -75,7 +75,7 @@ class PGPView(BaseView):
try:
key = self.sign.key_download(server, key)
except Exception:
raise HTTPNotFound
raise HTTPNotFound(reason=f"Key {key} is unknown")
return json_response({"key": key})

View File

@ -45,7 +45,7 @@ class ProcessView(BaseView):
200: {"description": "Success response", "schema": ProcessSchema},
401: {"description": "Authorization required", "schema": ErrorSchema},
403: {"description": "Access is forbidden", "schema": ErrorSchema},
404: {"description": "Not found", "schema": ErrorSchema},
404: {"description": "Process is unknown", "schema": ErrorSchema},
500: {"description": "Internal server error", "schema": ErrorSchema},
},
security=[{"token": [GET_PERMISSION]}],

View File

@ -46,6 +46,7 @@ class RebuildView(BaseView):
400: {"description": "Bad data is supplied", "schema": ErrorSchema},
401: {"description": "Authorization required", "schema": ErrorSchema},
403: {"description": "Access is forbidden", "schema": ErrorSchema},
404: {"description": "Repository is unknown", "schema": ErrorSchema},
500: {"description": "Internal server error", "schema": ErrorSchema},
},
security=[{"token": [POST_PERMISSION]}],

View File

@ -46,6 +46,7 @@ class RemoveView(BaseView):
400: {"description": "Bad data is supplied", "schema": ErrorSchema},
401: {"description": "Authorization required", "schema": ErrorSchema},
403: {"description": "Access is forbidden", "schema": ErrorSchema},
404: {"description": "Repository is unknown", "schema": ErrorSchema},
500: {"description": "Internal server error", "schema": ErrorSchema},
},
security=[{"token": [POST_PERMISSION]}],

View File

@ -46,6 +46,7 @@ class RequestView(BaseView):
400: {"description": "Bad data is supplied", "schema": ErrorSchema},
401: {"description": "Authorization required", "schema": ErrorSchema},
403: {"description": "Access is forbidden", "schema": ErrorSchema},
404: {"description": "Repository is unknown", "schema": ErrorSchema},
500: {"description": "Internal server error", "schema": ErrorSchema},
},
security=[{"token": [POST_PERMISSION]}],

View File

@ -46,6 +46,7 @@ class UpdateView(BaseView):
400: {"description": "Bad data is supplied", "schema": ErrorSchema},
401: {"description": "Authorization required", "schema": ErrorSchema},
403: {"description": "Access is forbidden", "schema": ErrorSchema},
404: {"description": "Repository is unknown", "schema": ErrorSchema},
500: {"description": "Internal server error", "schema": ErrorSchema},
},
security=[{"token": [POST_PERMISSION]}],

View File

@ -101,7 +101,7 @@ class UploadView(BaseView):
400: {"description": "Bad data is supplied", "schema": ErrorSchema},
401: {"description": "Authorization required", "schema": ErrorSchema},
403: {"description": "Access is forbidden", "schema": ErrorSchema},
404: {"description": "Not found", "schema": ErrorSchema},
404: {"description": "Repository is unknown or endpoint is disabled", "schema": ErrorSchema},
500: {"description": "Internal server error", "schema": ErrorSchema},
},
security=[{"token": [POST_PERMISSION]}],

View File

@ -51,6 +51,7 @@ class LogsView(BaseView):
204: {"description": "Success response"},
401: {"description": "Authorization required", "schema": ErrorSchema},
403: {"description": "Access is forbidden", "schema": ErrorSchema},
404: {"description": "Repository is unknown", "schema": ErrorSchema},
500: {"description": "Internal server error", "schema": ErrorSchema},
},
security=[{"token": [DELETE_PERMISSION]}],
@ -78,7 +79,7 @@ class LogsView(BaseView):
200: {"description": "Success response", "schema": LogsSchema},
401: {"description": "Authorization required", "schema": ErrorSchema},
403: {"description": "Access is forbidden", "schema": ErrorSchema},
404: {"description": "Package base is unknown", "schema": ErrorSchema},
404: {"description": "Package base and/or repository are unknown", "schema": ErrorSchema},
500: {"description": "Internal server error", "schema": ErrorSchema},
},
security=[{"token": [GET_PERMISSION]}],
@ -101,7 +102,7 @@ class LogsView(BaseView):
try:
_, status = self.service().package_get(package_base)
except UnknownPackageError:
raise HTTPNotFound
raise HTTPNotFound(reason=f"Package {package_base} is unknown")
logs = self.service().logs_get(package_base)
response = {
@ -120,6 +121,7 @@ class LogsView(BaseView):
400: {"description": "Bad data is supplied", "schema": ErrorSchema},
401: {"description": "Authorization required", "schema": ErrorSchema},
403: {"description": "Access is forbidden", "schema": ErrorSchema},
404: {"description": "Repository is unknown", "schema": ErrorSchema},
500: {"description": "Internal server error", "schema": ErrorSchema},
},
security=[{"token": [POST_PERMISSION]}],

View File

@ -52,6 +52,7 @@ class PackageView(BaseView):
204: {"description": "Success response"},
401: {"description": "Authorization required", "schema": ErrorSchema},
403: {"description": "Access is forbidden", "schema": ErrorSchema},
404: {"description": "Repository is unknown", "schema": ErrorSchema},
500: {"description": "Internal server error", "schema": ErrorSchema},
},
security=[{"token": [DELETE_PERMISSION]}],
@ -79,7 +80,7 @@ class PackageView(BaseView):
200: {"description": "Success response", "schema": PackageStatusSchema(many=True)},
401: {"description": "Authorization required", "schema": ErrorSchema},
403: {"description": "Access is forbidden", "schema": ErrorSchema},
404: {"description": "Package base is unknown", "schema": ErrorSchema},
404: {"description": "Package base and/or repository are unknown", "schema": ErrorSchema},
500: {"description": "Internal server error", "schema": ErrorSchema},
},
security=[{"token": [GET_PERMISSION]}],
@ -103,7 +104,7 @@ class PackageView(BaseView):
try:
package, status = self.service(repository_id).package_get(package_base)
except UnknownPackageError:
raise HTTPNotFound
raise HTTPNotFound(reason=f"Package {package_base} is unknown")
response = [
{
@ -123,6 +124,7 @@ class PackageView(BaseView):
400: {"description": "Bad data is supplied", "schema": ErrorSchema},
401: {"description": "Authorization required", "schema": ErrorSchema},
403: {"description": "Access is forbidden", "schema": ErrorSchema},
404: {"description": "Repository is unknown", "schema": ErrorSchema},
500: {"description": "Internal server error", "schema": ErrorSchema},
},
security=[{"token": [POST_PERMISSION]}],

View File

@ -52,6 +52,7 @@ class PackagesView(BaseView):
400: {"description": "Bad data is supplied", "schema": ErrorSchema},
401: {"description": "Authorization required", "schema": ErrorSchema},
403: {"description": "Access is forbidden", "schema": ErrorSchema},
404: {"description": "Repository is unknown", "schema": ErrorSchema},
500: {"description": "Internal server error", "schema": ErrorSchema},
},
security=[{"token": [GET_PERMISSION]}],
@ -90,6 +91,7 @@ class PackagesView(BaseView):
204: {"description": "Success response"},
401: {"description": "Authorization required", "schema": ErrorSchema},
403: {"description": "Access is forbidden", "schema": ErrorSchema},
404: {"description": "Repository is unknown", "schema": ErrorSchema},
500: {"description": "Internal server error", "schema": ErrorSchema},
},
security=[{"token": [POST_PERMISSION]}],

View File

@ -51,6 +51,7 @@ class StatusView(BaseView):
200: {"description": "Success response", "schema": InternalStatusSchema},
401: {"description": "Authorization required", "schema": ErrorSchema},
403: {"description": "Access is forbidden", "schema": ErrorSchema},
404: {"description": "Repository is unknown", "schema": ErrorSchema},
500: {"description": "Internal server error", "schema": ErrorSchema},
},
security=[{"token": [GET_PERMISSION]}],
@ -84,6 +85,7 @@ class StatusView(BaseView):
400: {"description": "Bad data is supplied", "schema": ErrorSchema},
401: {"description": "Authorization required", "schema": ErrorSchema},
403: {"description": "Access is forbidden", "schema": ErrorSchema},
404: {"description": "Repository is unknown", "schema": ErrorSchema},
500: {"description": "Internal server error", "schema": ErrorSchema},
},
security=[{"token": [POST_PERMISSION]}],

View File

@ -47,7 +47,7 @@ class LogsView(BaseView):
400: {"description": "Bad data is supplied", "schema": ErrorSchema},
401: {"description": "Authorization required", "schema": ErrorSchema},
403: {"description": "Access is forbidden", "schema": ErrorSchema},
404: {"description": "Package base is unknown", "schema": ErrorSchema},
404: {"description": "Package base and/or repository are unknown", "schema": ErrorSchema},
500: {"description": "Internal server error", "schema": ErrorSchema},
},
security=[{"token": [GET_PERMISSION]}],
@ -71,7 +71,7 @@ class LogsView(BaseView):
try:
_, status = self.service().package_get(package_base)
except UnknownPackageError:
raise HTTPNotFound
raise HTTPNotFound(reason=f"Package {package_base} is unknown")
logs = self.service().logs_get(package_base, limit, offset)
response = {

View File

@ -23,7 +23,7 @@ def test_path(args: argparse.Namespace, configuration: Configuration) -> None:
assert Lock(args, repository_id, configuration).path is None
args.lock = Path("/run/ahriman.lock")
assert Lock(args, repository_id, configuration).path == Path("/run/ahriman_aur-clone_x86_64.lock")
assert Lock(args, repository_id, configuration).path == Path("/run/ahriman_x86_64-aur-clone.lock")
with pytest.raises(ValueError):
args.lock = Path("/")

View File

@ -2,7 +2,7 @@ import pytest
from multidict import MultiDict
from aiohttp.test_utils import TestClient
from aiohttp.web import HTTPBadRequest
from aiohttp.web import HTTPBadRequest, HTTPNotFound
from pytest_mock import MockerFixture
from unittest.mock import AsyncMock
@ -240,6 +240,14 @@ def test_service_auto(base: BaseView, repository_id: RepositoryId, mocker: Mocke
assert base.service() == base.services[repository_id]
def test_service_not_found(base: BaseView) -> None:
"""
must raise HTTPNotFound if no repository found
"""
with pytest.raises(HTTPNotFound):
base.service(RepositoryId("", ""))
async def test_username(base: BaseView, mocker: MockerFixture) -> None:
"""
must return identity of logged-in user