mirror of
				https://github.com/arcan1s/ahriman.git
				synced 2025-11-04 07:43:42 +00:00 
			
		
		
		
	define permissions in views directly
This commit is contained in:
		@ -109,40 +109,6 @@ async def test_check_credentials(auth: Auth, user: User) -> None:
 | 
			
		||||
    assert await auth.check_credentials(None, None)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_is_safe_request(auth: Auth) -> None:
 | 
			
		||||
    """
 | 
			
		||||
    must validate safe request
 | 
			
		||||
    """
 | 
			
		||||
    # login and logout are always safe
 | 
			
		||||
    assert await auth.is_safe_request("/user-api/v1/login", UserAccess.Write)
 | 
			
		||||
    assert await auth.is_safe_request("/user-api/v1/logout", UserAccess.Write)
 | 
			
		||||
 | 
			
		||||
    auth.allowed_paths.add("/safe")
 | 
			
		||||
    auth.allowed_paths_groups.add("/unsafe/safe")
 | 
			
		||||
 | 
			
		||||
    assert await auth.is_safe_request("/safe", UserAccess.Write)
 | 
			
		||||
    assert not await auth.is_safe_request("/unsafe", UserAccess.Write)
 | 
			
		||||
    assert await auth.is_safe_request("/unsafe/safe", UserAccess.Write)
 | 
			
		||||
    assert await auth.is_safe_request("/unsafe/safe/suffix", UserAccess.Write)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_is_safe_request_empty(auth: Auth) -> None:
 | 
			
		||||
    """
 | 
			
		||||
    must not allow requests without path
 | 
			
		||||
    """
 | 
			
		||||
    assert not await auth.is_safe_request(None, UserAccess.Read)
 | 
			
		||||
    assert not await auth.is_safe_request("", UserAccess.Read)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_is_safe_request_read_only(auth: Auth) -> None:
 | 
			
		||||
    """
 | 
			
		||||
    must allow read-only requests if it is set in settings
 | 
			
		||||
    """
 | 
			
		||||
    assert await auth.is_safe_request("/", UserAccess.Read)
 | 
			
		||||
    auth.allow_read_only = True
 | 
			
		||||
    assert await auth.is_safe_request("/unsafe", UserAccess.Read)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_known_username(auth: Auth, user: User) -> None:
 | 
			
		||||
    """
 | 
			
		||||
    must allow any username
 | 
			
		||||
 | 
			
		||||
@ -43,60 +43,74 @@ async def test_permits(authorization_policy: AuthorizationPolicy, user: User) ->
 | 
			
		||||
    assert not await authorization_policy.permits(user.username, user.access, "/endpoint")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_auth_handler_api(auth: Auth, mocker: MockerFixture) -> None:
 | 
			
		||||
async def test_auth_handler_api(mocker: MockerFixture) -> None:
 | 
			
		||||
    """
 | 
			
		||||
    must ask for status permission for api calls
 | 
			
		||||
    """
 | 
			
		||||
    aiohttp_request = pytest.helpers.request("", "/status-api", "GET")
 | 
			
		||||
    request_handler = AsyncMock()
 | 
			
		||||
    mocker.patch("ahriman.core.auth.auth.Auth.is_safe_request", return_value=False)
 | 
			
		||||
    request_handler.get_permission.return_value = UserAccess.Read
 | 
			
		||||
    check_permission_mock = mocker.patch("aiohttp_security.check_permission")
 | 
			
		||||
 | 
			
		||||
    handler = auth_handler(auth)
 | 
			
		||||
    handler = auth_handler()
 | 
			
		||||
    await handler(aiohttp_request, request_handler)
 | 
			
		||||
    check_permission_mock.assert_called_with(aiohttp_request, UserAccess.Read, aiohttp_request.path)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_auth_handler_api_post(auth: Auth, mocker: MockerFixture) -> None:
 | 
			
		||||
async def test_auth_handler_api_no_method(mocker: MockerFixture) -> None:
 | 
			
		||||
    """
 | 
			
		||||
    must ask for write permission if handler does not have get_permission method
 | 
			
		||||
    """
 | 
			
		||||
    aiohttp_request = pytest.helpers.request("", "/status-api", "GET")
 | 
			
		||||
    request_handler = AsyncMock()
 | 
			
		||||
    request_handler.get_permission = None
 | 
			
		||||
    check_permission_mock = mocker.patch("aiohttp_security.check_permission")
 | 
			
		||||
 | 
			
		||||
    handler = auth_handler()
 | 
			
		||||
    await handler(aiohttp_request, request_handler)
 | 
			
		||||
    check_permission_mock.assert_called_with(aiohttp_request, UserAccess.Write, aiohttp_request.path)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_auth_handler_api_post(mocker: MockerFixture) -> None:
 | 
			
		||||
    """
 | 
			
		||||
    must ask for status permission for api calls with POST
 | 
			
		||||
    """
 | 
			
		||||
    aiohttp_request = pytest.helpers.request("", "/status-api", "POST")
 | 
			
		||||
    request_handler = AsyncMock()
 | 
			
		||||
    mocker.patch("ahriman.core.auth.auth.Auth.is_safe_request", return_value=False)
 | 
			
		||||
    request_handler.get_permission.return_value = UserAccess.Write
 | 
			
		||||
    check_permission_mock = mocker.patch("aiohttp_security.check_permission")
 | 
			
		||||
 | 
			
		||||
    handler = auth_handler(auth)
 | 
			
		||||
    handler = auth_handler()
 | 
			
		||||
    await handler(aiohttp_request, request_handler)
 | 
			
		||||
    check_permission_mock.assert_called_with(aiohttp_request, UserAccess.Write, aiohttp_request.path)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_auth_handler_read(auth: Auth, mocker: MockerFixture) -> None:
 | 
			
		||||
async def test_auth_handler_read(mocker: MockerFixture) -> None:
 | 
			
		||||
    """
 | 
			
		||||
    must ask for read permission for api calls with GET
 | 
			
		||||
    """
 | 
			
		||||
    for method in ("GET", "HEAD", "OPTIONS"):
 | 
			
		||||
        aiohttp_request = pytest.helpers.request("", "", method)
 | 
			
		||||
        request_handler = AsyncMock()
 | 
			
		||||
        mocker.patch("ahriman.core.auth.auth.Auth.is_safe_request", return_value=False)
 | 
			
		||||
        request_handler.get_permission.return_value = UserAccess.Read
 | 
			
		||||
        check_permission_mock = mocker.patch("aiohttp_security.check_permission")
 | 
			
		||||
 | 
			
		||||
        handler = auth_handler(auth)
 | 
			
		||||
        handler = auth_handler()
 | 
			
		||||
        await handler(aiohttp_request, request_handler)
 | 
			
		||||
        check_permission_mock.assert_called_with(aiohttp_request, UserAccess.Read, aiohttp_request.path)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_auth_handler_write(auth: Auth, mocker: MockerFixture) -> None:
 | 
			
		||||
async def test_auth_handler_write(mocker: MockerFixture) -> None:
 | 
			
		||||
    """
 | 
			
		||||
    must ask for read permission for api calls with POST
 | 
			
		||||
    """
 | 
			
		||||
    for method in ("CONNECT", "DELETE", "PATCH", "POST", "PUT", "TRACE"):
 | 
			
		||||
        aiohttp_request = pytest.helpers.request("", "", method)
 | 
			
		||||
        request_handler = AsyncMock()
 | 
			
		||||
        mocker.patch("ahriman.core.auth.auth.Auth.is_safe_request", return_value=False)
 | 
			
		||||
        request_handler.get_permission.return_value = UserAccess.Write
 | 
			
		||||
        check_permission_mock = mocker.patch("aiohttp_security.check_permission")
 | 
			
		||||
 | 
			
		||||
        handler = auth_handler(auth)
 | 
			
		||||
        handler = auth_handler()
 | 
			
		||||
        await handler(aiohttp_request, request_handler)
 | 
			
		||||
        check_permission_mock.assert_called_with(aiohttp_request, UserAccess.Write, aiohttp_request.path)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,20 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
from aiohttp.test_utils import TestClient
 | 
			
		||||
from pytest_mock import MockerFixture
 | 
			
		||||
 | 
			
		||||
from ahriman.models.user_access import UserAccess
 | 
			
		||||
from ahriman.web.views.service.add import AddView
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_get_permission() -> None:
 | 
			
		||||
    """
 | 
			
		||||
    must return correct permission for the request
 | 
			
		||||
    """
 | 
			
		||||
    for method in ("POST",):
 | 
			
		||||
        request = pytest.helpers.request("", "", method)
 | 
			
		||||
        assert await AddView.get_permission(request) == UserAccess.Write
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_post(client: TestClient, mocker: MockerFixture) -> None:
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,20 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
from aiohttp.test_utils import TestClient
 | 
			
		||||
from pytest_mock import MockerFixture
 | 
			
		||||
 | 
			
		||||
from ahriman.models.user_access import UserAccess
 | 
			
		||||
from ahriman.web.views.service.reload_auth import ReloadAuthView
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_get_permission() -> None:
 | 
			
		||||
    """
 | 
			
		||||
    must return correct permission for the request
 | 
			
		||||
    """
 | 
			
		||||
    for method in ("POST",):
 | 
			
		||||
        request = pytest.helpers.request("", "", method)
 | 
			
		||||
        assert await ReloadAuthView.get_permission(request) == UserAccess.Write
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_post(client_with_auth: TestClient, mocker: MockerFixture) -> None:
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,20 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
from aiohttp.test_utils import TestClient
 | 
			
		||||
from pytest_mock import MockerFixture
 | 
			
		||||
 | 
			
		||||
from ahriman.models.user_access import UserAccess
 | 
			
		||||
from ahriman.web.views.service.remove import RemoveView
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_get_permission() -> None:
 | 
			
		||||
    """
 | 
			
		||||
    must return correct permission for the request
 | 
			
		||||
    """
 | 
			
		||||
    for method in ("POST",):
 | 
			
		||||
        request = pytest.helpers.request("", "", method)
 | 
			
		||||
        assert await RemoveView.get_permission(request) == UserAccess.Write
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_post(client: TestClient, mocker: MockerFixture) -> None:
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,21 @@
 | 
			
		||||
import aur
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
from aiohttp.test_utils import TestClient
 | 
			
		||||
from pytest_mock import MockerFixture
 | 
			
		||||
 | 
			
		||||
from ahriman.models.user_access import UserAccess
 | 
			
		||||
from ahriman.web.views.service.search import SearchView
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_get_permission() -> None:
 | 
			
		||||
    """
 | 
			
		||||
    must return correct permission for the request
 | 
			
		||||
    """
 | 
			
		||||
    for method in ("GET", "HEAD"):
 | 
			
		||||
        request = pytest.helpers.request("", "", method)
 | 
			
		||||
        assert await SearchView.get_permission(request) == UserAccess.Read
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_get(client: TestClient, aur_package_ahriman: aur.Package, mocker: MockerFixture) -> None:
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,23 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
from aiohttp.test_utils import TestClient
 | 
			
		||||
from pytest_mock import MockerFixture
 | 
			
		||||
 | 
			
		||||
from ahriman.models.build_status import BuildStatus, BuildStatusEnum
 | 
			
		||||
from ahriman.models.user_access import UserAccess
 | 
			
		||||
from ahriman.web.views.status.ahriman import AhrimanView
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_get_permission() -> None:
 | 
			
		||||
    """
 | 
			
		||||
    must return correct permission for the request
 | 
			
		||||
    """
 | 
			
		||||
    for method in ("GET", "HEAD"):
 | 
			
		||||
        request = pytest.helpers.request("", "", method)
 | 
			
		||||
        assert await AhrimanView.get_permission(request) == UserAccess.Read
 | 
			
		||||
    for method in ("POST",):
 | 
			
		||||
        request = pytest.helpers.request("", "", method)
 | 
			
		||||
        assert await AhrimanView.get_permission(request) == UserAccess.Write
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_get(client: TestClient) -> None:
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,23 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
from pytest_aiohttp import TestClient
 | 
			
		||||
 | 
			
		||||
from ahriman.models.build_status import BuildStatus, BuildStatusEnum
 | 
			
		||||
from ahriman.models.package import Package
 | 
			
		||||
from ahriman.models.user_access import UserAccess
 | 
			
		||||
from ahriman.web.views.status.package import PackageView
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_get_permission() -> None:
 | 
			
		||||
    """
 | 
			
		||||
    must return correct permission for the request
 | 
			
		||||
    """
 | 
			
		||||
    for method in ("GET", "HEAD"):
 | 
			
		||||
        request = pytest.helpers.request("", "", method)
 | 
			
		||||
        assert await PackageView.get_permission(request) == UserAccess.Read
 | 
			
		||||
    for method in ("DELETE", "POST"):
 | 
			
		||||
        request = pytest.helpers.request("", "", method)
 | 
			
		||||
        assert await PackageView.get_permission(request) == UserAccess.Write
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_get(client: TestClient, package_ahriman: Package, package_python_schedule: Package) -> None:
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,24 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
from pytest_aiohttp import TestClient
 | 
			
		||||
from pytest_mock import MockerFixture
 | 
			
		||||
 | 
			
		||||
from ahriman.models.build_status import BuildStatusEnum
 | 
			
		||||
from ahriman.models.package import Package
 | 
			
		||||
from ahriman.models.user_access import UserAccess
 | 
			
		||||
from ahriman.web.views.status.packages import PackagesView
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_get_permission() -> None:
 | 
			
		||||
    """
 | 
			
		||||
    must return correct permission for the request
 | 
			
		||||
    """
 | 
			
		||||
    for method in ("GET", "HEAD"):
 | 
			
		||||
        request = pytest.helpers.request("", "", method)
 | 
			
		||||
        assert await PackagesView.get_permission(request) == UserAccess.Read
 | 
			
		||||
    for method in ("POST",):
 | 
			
		||||
        request = pytest.helpers.request("", "", method)
 | 
			
		||||
        assert await PackagesView.get_permission(request) == UserAccess.Write
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_get(client: TestClient, package_ahriman: Package, package_python_schedule: Package) -> None:
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,22 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
from pytest_aiohttp import TestClient
 | 
			
		||||
 | 
			
		||||
import ahriman.version as version
 | 
			
		||||
 | 
			
		||||
from ahriman.models.build_status import BuildStatusEnum
 | 
			
		||||
from ahriman.models.package import Package
 | 
			
		||||
from ahriman.models.user_access import UserAccess
 | 
			
		||||
from ahriman.web.views.status.status import StatusView
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_get_permission() -> None:
 | 
			
		||||
    """
 | 
			
		||||
    must return correct permission for the request
 | 
			
		||||
    """
 | 
			
		||||
    for method in ("GET", "HEAD"):
 | 
			
		||||
        request = pytest.helpers.request("", "", method)
 | 
			
		||||
        assert await StatusView.get_permission(request) == UserAccess.Read
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_get(client: TestClient, package_ahriman: Package) -> None:
 | 
			
		||||
 | 
			
		||||
@ -33,6 +33,16 @@ def test_validator(base: BaseView) -> None:
 | 
			
		||||
    assert base.validator
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_get_permission(base: BaseView) -> None:
 | 
			
		||||
    """
 | 
			
		||||
    must search for permission attribute in class
 | 
			
		||||
    """
 | 
			
		||||
    for method in ("DELETE", "GET", "HEAD", "POST"):
 | 
			
		||||
        request = pytest.helpers.request(base.request.app, "", method)
 | 
			
		||||
        setattr(BaseView, f"{method.upper()}_PERMISSION", "permission")
 | 
			
		||||
        assert await base.get_permission(request) == "permission"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_extract_data_json(base: BaseView) -> None:
 | 
			
		||||
    """
 | 
			
		||||
    must parse and return json
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,19 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
from pytest_aiohttp import TestClient
 | 
			
		||||
 | 
			
		||||
from ahriman.models.user_access import UserAccess
 | 
			
		||||
from ahriman.web.views.index import IndexView
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_get_permission() -> None:
 | 
			
		||||
    """
 | 
			
		||||
    must return correct permission for the request
 | 
			
		||||
    """
 | 
			
		||||
    for method in ("GET", "HEAD"):
 | 
			
		||||
        request = pytest.helpers.request("", "", method)
 | 
			
		||||
        assert await IndexView.get_permission(request) == UserAccess.Safe
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_get(client_with_auth: TestClient) -> None:
 | 
			
		||||
    """
 | 
			
		||||
@ -34,3 +48,11 @@ async def test_get_static(client: TestClient) -> None:
 | 
			
		||||
    """
 | 
			
		||||
    response = await client.get("/static/favicon.ico")
 | 
			
		||||
    assert response.ok
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_get_static_with_auth(client_with_auth: TestClient) -> None:
 | 
			
		||||
    """
 | 
			
		||||
    must return static files
 | 
			
		||||
    """
 | 
			
		||||
    response = await client_with_auth.get("/static/favicon.ico")
 | 
			
		||||
    assert response.ok
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,21 @@
 | 
			
		||||
import pytest
 | 
			
		||||
from aiohttp.test_utils import TestClient
 | 
			
		||||
from pytest_mock import MockerFixture
 | 
			
		||||
from unittest.mock import MagicMock
 | 
			
		||||
 | 
			
		||||
from ahriman.core.auth.oauth import OAuth
 | 
			
		||||
from ahriman.models.user import User
 | 
			
		||||
from ahriman.models.user_access import UserAccess
 | 
			
		||||
from ahriman.web.views.user.login import LoginView
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_get_permission() -> None:
 | 
			
		||||
    """
 | 
			
		||||
    must return correct permission for the request
 | 
			
		||||
    """
 | 
			
		||||
    for method in ("GET", "POST"):
 | 
			
		||||
        request = pytest.helpers.request("", "", method)
 | 
			
		||||
        assert await LoginView.get_permission(request) == UserAccess.Safe
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_get_default_validator(client_with_auth: TestClient) -> None:
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,21 @@
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
from aiohttp.test_utils import TestClient
 | 
			
		||||
from aiohttp.web import HTTPUnauthorized
 | 
			
		||||
from pytest_mock import MockerFixture
 | 
			
		||||
 | 
			
		||||
from ahriman.models.user_access import UserAccess
 | 
			
		||||
from ahriman.web.views.user.logout import LogoutView
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_get_permission() -> None:
 | 
			
		||||
    """
 | 
			
		||||
    must return correct permission for the request
 | 
			
		||||
    """
 | 
			
		||||
    for method in ("POST",):
 | 
			
		||||
        request = pytest.helpers.request("", "", method)
 | 
			
		||||
        assert await LogoutView.get_permission(request) == UserAccess.Safe
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def test_post(client_with_auth: TestClient, mocker: MockerFixture) -> None:
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user