fails when user exists

main
Philipp Rothmann 2022-04-29 16:55:23 +02:00
parent 23bdcc7957
commit bbf81e143e
8 changed files with 39 additions and 27 deletions

View File

@ -5,7 +5,7 @@ from requests import Request
import structlog
from app.authentik.settings import AuthentikSettings
from .models import User
from .models import AuthentikUser
logging = structlog.get_logger()
@ -147,13 +147,13 @@ class Authentik:
return r.json()
raise Exception(r.status_code, r.url, r.text)
def get_user_by_pk(self, pk: str) -> Optional[User]:
def get_user_by_pk(self, pk: str) -> Optional[AuthentikUser]:
r = self.get(f"core/users/{pk}").json()
if "pk" in r:
return User(**r)
return AuthentikUser(**r)
raise Exception(r)
def get_user(self, user: User) -> Optional[User]:
def get_user(self, user: AuthentikUser) -> Optional[AuthentikUser]:
if user.pk:
r = self.get(f"core/users/{user.pk}").json()
else:
@ -165,16 +165,16 @@ class Authentik:
r = r["results"][0]
if "pk" in r:
return User(**r)
return AuthentikUser(**r)
raise Exception(r)
def create_user(self, user: User) -> User:
def create_user(self, user: AuthentikUser) -> AuthentikUser:
r = self.post("core/users/", user.dict()).json()
if "pk" in r:
return User(**r)
return AuthentikUser(**r)
raise Exception(r)
def delete_user(self, user: User) -> bool:
def delete_user(self, user: AuthentikUser) -> bool:
if user == None or user.pk == None:
raise Exception("Not a valid user")

View File

@ -28,7 +28,7 @@ class GroupsObjItem(BaseModel):
attributes: Dict[str, Any]
users_obj: List[UsersObjItem]
class User(BaseUser):
class AuthentikUser(BaseUser):
pk: Optional[str]
username: str
name: str

View File

@ -3,7 +3,7 @@ import logging
from app.authentik.settings import AuthentikSettings
from .api import Authentik
from .models import User
from .models import AuthentikUser
import pytest
@pytest.fixture()
@ -34,7 +34,7 @@ def test_create_event_rule_already_exists(api: Authentik):
assert not exception == None # TODO create exception types
def test_get_user_by_username(api: Authentik):
u = User(username="akadmin",
u = AuthentikUser(username="akadmin",
name="",
groups=[],
email="",
@ -47,7 +47,7 @@ def test_get_user_by_username(api: Authentik):
def test_create_user(api: Authentik):
u = User(username="banane",
u = AuthentikUser(username="banane",
name="banane",
groups=[],
email="foo@example.org",

View File

@ -3,7 +3,7 @@ from typing import List
from pydantic import BaseModel
from fastapi import FastAPI, Depends
from app.authentik.api import Authentik
from app.authentik.models import User
from app.authentik.models import AuthentikUser
from app.consumer.baseConsumer import Consumer
from app.consumer.wekan.api import WekanApi
from app.consumer.wekan.main import WekanConsumer
@ -32,6 +32,7 @@ class EventController:
# try:
self._authentik = authentik_api
self._sinks = []
self._exceptions = []
for sc in Consumer.__subclasses__():
obj = sc()
self._sinks.append(obj)
@ -47,11 +48,12 @@ class EventController:
self._sinks = sinks
def handle_model_created_event(self, model: Authentik_Hook_Model):
user: User = self._authentik.get_user_by_pk(model.pk)
user: AuthentikUser = self._authentik.get_user_by_pk(model.pk)
for sink in self._sinks: # TODO this could run async
logging.info(f"Creating User {user.username} in {sink.__class__}")
try:
sink.create_user(user)
except Exception as e:
logging.error("create user", exception=str(e), sink=sink, user=user)
self._exceptions.append(str(e))
return True

View File

@ -5,7 +5,7 @@ from fastapi import Depends, FastAPI, Request, BackgroundTasks
from pydantic import BaseModel
from app.consumer.baseConsumer import BaseUser, Consumer
from app.authentik.api import Authentik
from app.authentik.models import User
from app.authentik.models import AuthentikUser
from app.event_controller import Authentik_Hook_Model, EventController, Http_request
from app.authentik.settings import AuthentikSettings
from .consumer.wekan.api import WekanApi
@ -42,7 +42,7 @@ async def create_demo_user(request: Request):
a = Authentik(base="http://localhost:9000/", token="foobar123")
try:
user = a.create_user(
User(username="demo", name="dmeo", email="foo@example.org"))
AuthentikUser(username="demo", name="dmeo", email="foo@example.org"))
except Exception as e: # TODO
return e
logging.info(user)

View File

@ -7,6 +7,7 @@ from app.authentik.settings import AuthentikSettings
router = APIRouter()
ec = EventController(Authentik(AuthentikSettings()))
@router.post("/authentik/hook/")
async def hook(model: Authentik_Hook_Model,
@ -15,7 +16,10 @@ async def hook(model: Authentik_Hook_Model,
):
logging.info(model)
logging.info(http_request)
ec = EventController(Authentik(AuthentikSettings()))
if http_request.path == "/api/v3/core/users/":
background_tasks.add_task(ec.handle_model_created_event, model)
return 200
@router.get("/authentik/errors/")
async def errors():
return ec._exceptions

View File

@ -1,14 +1,14 @@
from app.authentik.models import User
from app.authentik.models import AuthentikUser
from pytest_mock import MockerFixture
from .event_controller import Authentik_Hook_Model, EventController
import pytest
@pytest.fixture()
def mock_user():
return User(pk="5", username="asd", name="asd", email="asd@example.org")
return AuthentikUser(pk="5", username="asd", name="asd", email="asd@example.org")
def test_handle_model_created_event(mocker: MockerFixture, mock_user: User):
def test_handle_model_created_event(mocker: MockerFixture, mock_user: AuthentikUser):
wekan_mock = mocker.MagicMock()
wekan_mock.get_user.return_value = None
nextcloud_mock = mocker.MagicMock()

View File

@ -7,7 +7,7 @@ from fastapi.testclient import TestClient
from .main import app
from app.authentik.api import Authentik
from app.authentik.models import User
from app.authentik.models import AuthentikUser
from app.authentik.settings import AuthentikSettings
from app.consumer.wekan.models import User as WekanUser
from app.consumer.wekan.api import WekanApi
@ -42,13 +42,13 @@ def authentik(settings: AuthentikSettings):
@pytest.fixture()
def authentik_user(authentik):
user = authentik.create_user(User(username="foobar", name="Foo Bar", email="foo@bar.com"))
user = authentik.create_user(AuthentikUser(username="foobar", name="Foo Bar", email="foo@bar.com"))
yield user
authentik.delete_user(user)
def test_create_user(mocker, authentik_user: WekanUser, wekan: WekanApi):
def test_create_user(mocker, authentik_user: AuthentikUser, wekan: WekanApi):
# Actually authentik user creation should already trigger the hook, but in authentik it doesn't trigger when come from api
# mock = mocker.patch("app.event_controller.EventController.handle_model_created_event")
authentik_message = {"model": {"pk": authentik_user.pk, "app": "authentik_core", "name": authentik_user.name,
@ -68,7 +68,13 @@ def test_create_user_with_same_email(wekan_api, authentik_api):
"authentik notifcation rule doesn't work with api?? , create two user with identical email in authentik")
assert False
@pytest.mark.skip()
def test_user_already_exists_excepts():
assert False
def test_user_already_exists_excepts(authentik_user: AuthentikUser, wekan: WekanApi):
authentik_message = {"model": {"pk": authentik_user.pk, "app": "authentik_core", "name": authentik_user.name,
"model_name": "user"}, "http_request": {"args": {}, "path": "/api/v3/core/users/", "method": "POST"}}
response = client.post("/authentik/hook/", json=authentik_message)
response = client.post("/authentik/hook/", json=authentik_message)
assert response.status_code == 200
errors = client.get("/authentik/errors/")
assert errors.status_code == 200
assert errors.json() == ["[Wekan] User already exists"] # TODO introduce error models
wekan.delete_user(wekan.get_user(authentik_user.username).id)