diff --git a/openrag/routers/users.py b/openrag/routers/users.py index dadc76a4..d0573ac6 100644 --- a/openrag/routers/users.py +++ b/openrag/routers/users.py @@ -223,10 +223,19 @@ async def delete_user(user_id: int, vectordb=Depends(get_vectordb), admin_user=D **Note:** Store the new token securely - the old token is now invalid. """, ) -async def regenerate_user_token(user_id: int, vectordb=Depends(get_vectordb)): +async def regenerate_user_token( + user_id: int, + current=Depends(current_user), + vectordb=Depends(get_vectordb), +): """ - Regenerate a user's token. + Regenerate a user's token. Caller must be admin or the target user themselves. """ + if not current.get("is_admin") and current.get("id") != user_id: + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="You can only regenerate your own token", + ) user = await vectordb.regenerate_user_token.remote(user_id) logger.info("Regenerated user token", user_id=user_id) return JSONResponse(status_code=status.HTTP_200_OK, content=user) diff --git a/tests/api/users.robot b/tests/api/users.robot index 7976444b..deef3b71 100644 --- a/tests/api/users.robot +++ b/tests/api/users.robot @@ -31,6 +31,22 @@ Get Created User Should Be Equal As Strings ${json}[id] ${USER_ID} Dictionary Should Not Contain Key ${json} token +Non-Admin Can Regenerate Own Token + Skip If Auth Disabled + &{user_headers}= Create Dictionary Authorization=Bearer ${USER_TOKEN} + ${response}= POST ${USERS_ENDPOINT}/${USER_ID}/regenerate_token headers=${user_headers} expected_status=200 + ${json}= Set Variable ${response.json()} + Dictionary Should Contain Key ${json} token + Should Not Be Equal As Strings ${json}[token] ${USER_TOKEN} + Set Suite Variable ${USER_TOKEN} ${json}[token] + +Non-Admin Cannot Regenerate Other User Token + Skip If Auth Disabled + &{user_headers}= Create Dictionary Authorization=Bearer ${USER_TOKEN} + ${response}= POST ${USERS_ENDPOINT}/1/regenerate_token headers=${user_headers} expected_status=403 + ${json}= Set Variable ${response.json()} + Should Contain ${json}[detail] You can only regenerate your own token + Regenerate Token ${response}= POST ${USERS_ENDPOINT}/${USER_ID}/regenerate_token headers=${HEADERS} expected_status=200 ${json}= Set Variable ${response.json()}