mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-07-24 03:09:56 +00:00
port part of settings to database (#54)
This commit is contained in:
@ -8,6 +8,7 @@ from typing import Any
|
||||
import ahriman.core.auth.helpers
|
||||
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.database.sqlite import SQLite
|
||||
from ahriman.core.spawn import Spawn
|
||||
from ahriman.models.user import User
|
||||
from ahriman.web.web import setup_service
|
||||
@ -31,53 +32,60 @@ def request(app: web.Application, path: str, method: str, json: Any = None, data
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def application(configuration: Configuration, spawner: Spawn, mocker: MockerFixture) -> web.Application:
|
||||
def application(configuration: Configuration, spawner: Spawn, database: SQLite,
|
||||
mocker: MockerFixture) -> web.Application:
|
||||
"""
|
||||
application fixture
|
||||
:param configuration: configuration fixture
|
||||
:param spawner: spawner fixture
|
||||
:param database: database fixture
|
||||
:param mocker: mocker object
|
||||
:return: application test instance
|
||||
"""
|
||||
mocker.patch("ahriman.core.database.sqlite.SQLite.load", return_value=database)
|
||||
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
|
||||
mocker.patch.object(ahriman.core.auth.helpers, "_has_aiohttp_security", False)
|
||||
return setup_service("x86_64", configuration, spawner)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def application_with_auth(configuration: Configuration, user: User, spawner: Spawn,
|
||||
def application_with_auth(configuration: Configuration, user: User, spawner: Spawn, database: SQLite,
|
||||
mocker: MockerFixture) -> web.Application:
|
||||
"""
|
||||
application fixture with auth enabled
|
||||
:param configuration: configuration fixture
|
||||
:param user: user descriptor fixture
|
||||
:param spawner: spawner fixture
|
||||
:param database: database fixture
|
||||
:param mocker: mocker object
|
||||
:return: application test instance
|
||||
"""
|
||||
configuration.set_option("auth", "target", "configuration")
|
||||
mocker.patch("ahriman.core.database.sqlite.SQLite.load", return_value=database)
|
||||
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
|
||||
mocker.patch.object(ahriman.core.auth.helpers, "_has_aiohttp_security", True)
|
||||
application = setup_service("x86_64", configuration, spawner)
|
||||
|
||||
generated = User(user.username, user.hash_password(application["validator"].salt), user.access)
|
||||
application["validator"]._users[generated.username] = generated
|
||||
generated = user.hash_password(application["validator"].salt)
|
||||
mocker.patch("ahriman.core.database.sqlite.SQLite.user_get", return_value=generated)
|
||||
|
||||
return application
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def application_with_debug(configuration: Configuration, user: User, spawner: Spawn,
|
||||
def application_with_debug(configuration: Configuration, user: User, spawner: Spawn, database: SQLite,
|
||||
mocker: MockerFixture) -> web.Application:
|
||||
"""
|
||||
application fixture with debug enabled
|
||||
:param configuration: configuration fixture
|
||||
:param user: user descriptor fixture
|
||||
:param spawner: spawner fixture
|
||||
:param database: database fixture
|
||||
:param mocker: mocker object
|
||||
:return: application test instance
|
||||
"""
|
||||
configuration.set_option("web", "debug", "yes")
|
||||
mocker.patch("ahriman.core.database.sqlite.SQLite.load", return_value=database)
|
||||
mocker.patch("ahriman.models.repository_paths.RepositoryPaths.tree_create")
|
||||
mocker.patch.object(ahriman.core.auth.helpers, "_has_aiohttp_security", False)
|
||||
return setup_service("x86_64", configuration, spawner)
|
||||
|
@ -2,18 +2,18 @@ import pytest
|
||||
|
||||
from ahriman.core.auth.auth import Auth
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.database.sqlite import SQLite
|
||||
from ahriman.models.user import User
|
||||
from ahriman.web.middlewares.auth_handler import AuthorizationPolicy
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def authorization_policy(configuration: Configuration, user: User) -> AuthorizationPolicy:
|
||||
def authorization_policy(configuration: Configuration, database: SQLite, user: User) -> AuthorizationPolicy:
|
||||
"""
|
||||
fixture for authorization policy
|
||||
:return: authorization policy fixture
|
||||
"""
|
||||
configuration.set_option("auth", "target", "configuration")
|
||||
validator = Auth.load(configuration)
|
||||
validator = Auth.load(configuration, database)
|
||||
policy = AuthorizationPolicy(validator)
|
||||
policy.validator._users = {user.username: user}
|
||||
return policy
|
||||
|
@ -20,11 +20,18 @@ def _identity(username: str) -> str:
|
||||
return f"{username} {UserIdentity.expire_when(60)}"
|
||||
|
||||
|
||||
async def test_authorized_userid(authorization_policy: AuthorizationPolicy, user: User) -> None:
|
||||
async def test_authorized_userid(authorization_policy: AuthorizationPolicy, user: User, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must return authorized user id
|
||||
"""
|
||||
mocker.patch("ahriman.core.database.sqlite.SQLite.user_get", return_value=user)
|
||||
assert await authorization_policy.authorized_userid(_identity(user.username)) == user.username
|
||||
|
||||
|
||||
async def test_authorized_userid_unknown(authorization_policy: AuthorizationPolicy, user: User) -> None:
|
||||
"""
|
||||
must not allow unknown user id for authorization
|
||||
"""
|
||||
assert await authorization_policy.authorized_userid(_identity("somerandomname")) is None
|
||||
assert await authorization_policy.authorized_userid("somerandomname") is None
|
||||
|
||||
|
@ -2,11 +2,12 @@ import pytest
|
||||
|
||||
from aiohttp import web
|
||||
from asyncio import BaseEventLoop
|
||||
|
||||
from aiohttp.test_utils import TestClient
|
||||
from pytest_mock import MockerFixture
|
||||
from typing import Any
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from ahriman.core.auth.oauth import OAuth
|
||||
from ahriman.web.views.base import BaseView
|
||||
|
||||
|
||||
@ -21,30 +22,46 @@ def base(application: web.Application) -> BaseView:
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def client(application: web.Application, loop: BaseEventLoop,
|
||||
def client(application: web.Application, event_loop: BaseEventLoop,
|
||||
aiohttp_client: Any, mocker: MockerFixture) -> TestClient:
|
||||
"""
|
||||
web client fixture
|
||||
:param application: application fixture
|
||||
:param loop: context event loop
|
||||
:param event_loop: context event loop
|
||||
:param aiohttp_client: aiohttp client fixture
|
||||
:param mocker: mocker object
|
||||
:return: web client test instance
|
||||
"""
|
||||
mocker.patch("pathlib.Path.iterdir", return_value=[])
|
||||
return loop.run_until_complete(aiohttp_client(application))
|
||||
return event_loop.run_until_complete(aiohttp_client(application))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def client_with_auth(application_with_auth: web.Application, loop: BaseEventLoop,
|
||||
def client_with_auth(application_with_auth: web.Application, event_loop: BaseEventLoop,
|
||||
aiohttp_client: Any, mocker: MockerFixture) -> TestClient:
|
||||
"""
|
||||
web client fixture with full authorization functions
|
||||
:param application_with_auth: application fixture
|
||||
:param loop: context event loop
|
||||
:param event_loop: context event loop
|
||||
:param aiohttp_client: aiohttp client fixture
|
||||
:param mocker: mocker object
|
||||
:return: web client test instance
|
||||
"""
|
||||
mocker.patch("pathlib.Path.iterdir", return_value=[])
|
||||
return loop.run_until_complete(aiohttp_client(application_with_auth))
|
||||
return event_loop.run_until_complete(aiohttp_client(application_with_auth))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def client_with_oauth_auth(application_with_auth: web.Application, event_loop: BaseEventLoop,
|
||||
aiohttp_client: Any, mocker: MockerFixture) -> TestClient:
|
||||
"""
|
||||
web client fixture with full authorization functions
|
||||
:param application_with_auth: application fixture
|
||||
:param event_loop: context event loop
|
||||
:param aiohttp_client: aiohttp client fixture
|
||||
:param mocker: mocker object
|
||||
:return: web client test instance
|
||||
"""
|
||||
mocker.patch("pathlib.Path.iterdir", return_value=[])
|
||||
application_with_auth["validator"] = MagicMock(spec=OAuth)
|
||||
return event_loop.run_until_complete(aiohttp_client(application_with_auth))
|
||||
|
@ -1,41 +0,0 @@
|
||||
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:
|
||||
"""
|
||||
must call post request correctly
|
||||
"""
|
||||
mocker.patch("aiohttp_security.check_permission", return_value=True)
|
||||
reload_mock = mocker.patch("ahriman.core.configuration.Configuration.reload")
|
||||
load_mock = mocker.patch("ahriman.core.auth.auth.Auth.load")
|
||||
response = await client_with_auth.post("/service-api/v1/reload-auth")
|
||||
|
||||
assert response.ok
|
||||
reload_mock.assert_called_once_with()
|
||||
load_mock.assert_called_once_with(client_with_auth.app["configuration"])
|
||||
|
||||
|
||||
async def test_post_no_auth(client: TestClient, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must call return 500 if no authorization module loaded
|
||||
"""
|
||||
reload_mock = mocker.patch("ahriman.core.configuration.Configuration.reload")
|
||||
response = await client.post("/service-api/v1/reload-auth")
|
||||
|
||||
assert response.status == 500
|
||||
reload_mock.assert_called_once_with()
|
@ -12,6 +12,13 @@ def test_configuration(base: BaseView) -> None:
|
||||
assert base.configuration
|
||||
|
||||
|
||||
def test_database(base: BaseView) -> None:
|
||||
"""
|
||||
must return database
|
||||
"""
|
||||
assert base.database
|
||||
|
||||
|
||||
def test_service(base: BaseView) -> None:
|
||||
"""
|
||||
must return service
|
||||
|
@ -52,7 +52,7 @@ async def test_get_static(client: TestClient) -> None:
|
||||
|
||||
async def test_get_static_with_auth(client_with_auth: TestClient) -> None:
|
||||
"""
|
||||
must return static files
|
||||
must return static files with authorization enabled
|
||||
"""
|
||||
response = await client_with_auth.get("/static/favicon.ico")
|
||||
assert response.ok
|
||||
|
@ -27,42 +27,42 @@ async def test_get_default_validator(client_with_auth: TestClient) -> None:
|
||||
assert get_response.status == 405
|
||||
|
||||
|
||||
async def test_get_redirect_to_oauth(client_with_auth: TestClient) -> None:
|
||||
async def test_get_redirect_to_oauth(client_with_oauth_auth: TestClient) -> None:
|
||||
"""
|
||||
must redirect to OAuth service provider in case if no code is supplied
|
||||
"""
|
||||
oauth = client_with_auth.app["validator"] = MagicMock(spec=OAuth)
|
||||
oauth = client_with_oauth_auth.app["validator"]
|
||||
oauth.get_oauth_url.return_value = "https://httpbin.org"
|
||||
|
||||
get_response = await client_with_auth.get("/user-api/v1/login")
|
||||
get_response = await client_with_oauth_auth.get("/user-api/v1/login")
|
||||
assert get_response.ok
|
||||
oauth.get_oauth_url.assert_called_once_with()
|
||||
|
||||
|
||||
async def test_get_redirect_to_oauth_empty_code(client_with_auth: TestClient) -> None:
|
||||
async def test_get_redirect_to_oauth_empty_code(client_with_oauth_auth: TestClient) -> None:
|
||||
"""
|
||||
must redirect to OAuth service provider in case if empty code is supplied
|
||||
"""
|
||||
oauth = client_with_auth.app["validator"] = MagicMock(spec=OAuth)
|
||||
oauth = client_with_oauth_auth.app["validator"]
|
||||
oauth.get_oauth_url.return_value = "https://httpbin.org"
|
||||
|
||||
get_response = await client_with_auth.get("/user-api/v1/login", params={"code": ""})
|
||||
get_response = await client_with_oauth_auth.get("/user-api/v1/login", params={"code": ""})
|
||||
assert get_response.ok
|
||||
oauth.get_oauth_url.assert_called_once_with()
|
||||
|
||||
|
||||
async def test_get(client_with_auth: TestClient, mocker: MockerFixture) -> None:
|
||||
async def test_get(client_with_oauth_auth: TestClient, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must login user correctly from OAuth
|
||||
"""
|
||||
oauth = client_with_auth.app["validator"] = MagicMock(spec=OAuth)
|
||||
oauth = client_with_oauth_auth.app["validator"]
|
||||
oauth.get_oauth_username.return_value = "user"
|
||||
oauth.known_username.return_value = True
|
||||
oauth.enabled = False # lol
|
||||
oauth.max_age = 60
|
||||
remember_mock = mocker.patch("aiohttp_security.remember")
|
||||
|
||||
get_response = await client_with_auth.get("/user-api/v1/login", params={"code": "code"})
|
||||
get_response = await client_with_oauth_auth.get("/user-api/v1/login", params={"code": "code"})
|
||||
|
||||
assert get_response.ok
|
||||
oauth.get_oauth_username.assert_called_once_with("code")
|
||||
@ -71,16 +71,16 @@ async def test_get(client_with_auth: TestClient, mocker: MockerFixture) -> None:
|
||||
pytest.helpers.anyvar(int), pytest.helpers.anyvar(int), pytest.helpers.anyvar(int))
|
||||
|
||||
|
||||
async def test_get_unauthorized(client_with_auth: TestClient, mocker: MockerFixture) -> None:
|
||||
async def test_get_unauthorized(client_with_oauth_auth: TestClient, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must return unauthorized from OAuth
|
||||
"""
|
||||
oauth = client_with_auth.app["validator"] = MagicMock(spec=OAuth)
|
||||
oauth = client_with_oauth_auth.app["validator"]
|
||||
oauth.known_username.return_value = False
|
||||
oauth.max_age = 60
|
||||
remember_mock = mocker.patch("aiohttp_security.remember")
|
||||
|
||||
get_response = await client_with_auth.get("/user-api/v1/login", params={"code": "code"})
|
||||
get_response = await client_with_oauth_auth.get("/user-api/v1/login", params={"code": "code"})
|
||||
|
||||
assert get_response.status == 401
|
||||
remember_mock.assert_not_called()
|
||||
|
Reference in New Issue
Block a user