Skip to content

Commit

Permalink
Add logout actions and session store (fixes #1041, fixes #1022) (#1059)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomchop authored Mar 30, 2024
1 parent 51935b7 commit 7835eb9
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
12 changes: 11 additions & 1 deletion core/web/apiv2/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
YETI_WEBROOT = yeti_config.get("system", "webroot")

AUTH_MODULE = yeti_config.get("auth", "module")

SESSION_STORE = set()

if AUTH_MODULE == "oidc":
if (
not yeti_config.get("auth", "oidc_client_id")
Expand Down Expand Up @@ -82,6 +85,10 @@ async def get_current_user(
if not token and not cookie:
raise credentials_exception

# When dealing with cookies, check that we haven't logged out the user.
if cookie and cookie not in SESSION_STORE:
raise credentials_exception

token = token or cookie

try:
Expand Down Expand Up @@ -169,6 +176,7 @@ async def oidc_callback(request: Request) -> RedirectResponse:
)
response = RedirectResponse(url="/")
response.set_cookie(key="yeti_session", value=access_token, httponly=True)
SESSION_STORE.add(access_token)
return response


Expand Down Expand Up @@ -205,6 +213,7 @@ async def login(
expires_delta=ACCESS_TOKEN_EXPIRE_MINUTES,
)
response.set_cookie(key="yeti_session", value=access_token, httponly=True)
SESSION_STORE.add(access_token)
return {"access_token": access_token, "token_type": "bearer"}


Expand Down Expand Up @@ -238,6 +247,7 @@ async def me(current_user: User = Depends(get_current_user)) -> User:


@router.post("/logout")
async def logout(response: Response):
async def logout(response: Response, cookie: str = Security(cookie_scheme)):
response.delete_cookie(key="yeti_session")
SESSION_STORE.remove(cookie)
return {"message": "Logged out"}
17 changes: 17 additions & 0 deletions tests/apiv2/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,23 @@ def test_cookie_auth(self) -> None:
self.assertEqual(response.status_code, 200)
self.assertEqual(data["username"], "tomchop")

def test_logout(self) -> None:
response = client.post(
"/api/v2/auth/token", data={"username": "tomchop", "password": "test"}
)
data = response.json()
token = data["access_token"]

response = client.post(
"/api/v2/auth/logout", headers={"cookie": "yeti_session=" + token}
)

response = client.get(
"/api/v2/auth/me", headers={"cookie": "yeti_session=" + token}
)
data = response.json()
self.assertEqual(response.status_code, 401)

def test_api_not_auth(self) -> None:
response = client.get("/api/v2/auth/me")
self.assertEqual(response.status_code, 401)
Expand Down

0 comments on commit 7835eb9

Please sign in to comment.