Skip to content

Commit

Permalink
Include user and user org info in login response (#2014)
Browse files Browse the repository at this point in the history
Fixes #2013 

Adds the `/users/me` response data to the API login endpoint response
under the key `user_info` and adds a test.
  • Loading branch information
tw4l authored Aug 13, 2024
1 parent 1a68925 commit 916813a
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 5 deletions.
15 changes: 10 additions & 5 deletions backend/btrixcloud/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm

from .models import User
from .models import User, UserOut
from .utils import dt_now


Expand Down Expand Up @@ -57,6 +57,7 @@ class BearerResponse(BaseModel):

access_token: str
token_type: str
user_info: UserOut


# ============================================================================
Expand Down Expand Up @@ -181,10 +182,12 @@ async def shared_secret_or_active_user(

auth_jwt_router = APIRouter()

def get_bearer_response(user: User):
def get_bearer_response(user: User, user_info: UserOut):
"""get token, return bearer response for user"""
token = create_access_token(user)
return BearerResponse(access_token=token, token_type="bearer")
return BearerResponse(
access_token=token, token_type="bearer", user_info=user_info
)

@auth_jwt_router.post("/login", response_model=BearerResponse)
async def login(
Expand Down Expand Up @@ -246,10 +249,12 @@ async def send_reset_if_needed():

# successfully logged in, reset failed logins, return user
await user_manager.reset_failed_logins(login_email)
return get_bearer_response(user)
user_info = await user_manager.get_user_info_with_orgs(user)
return get_bearer_response(user, user_info)

@auth_jwt_router.post("/refresh", response_model=BearerResponse)
async def refresh_jwt(user=Depends(current_active_user)):
return get_bearer_response(user)
user_info = await user_manager.get_user_info_with_orgs(user)
return get_bearer_response(user, user_info)

return auth_jwt_router, current_active_user, shared_secret_or_active_user
39 changes: 39 additions & 0 deletions backend/test/test_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,45 @@ def test_me_id(admin_auth_headers, default_org_id):
assert r.status_code == 404


def test_login_user_info(admin_auth_headers, crawler_userid, default_org_id):
# Get default org info for comparison
r = requests.get(f"{API_PREFIX}/orgs", headers=admin_auth_headers)
default_org = [org for org in r.json()["items"] if org["default"]][0]

# Log in and check response
r = requests.post(
f"{API_PREFIX}/auth/jwt/login",
data={
"username": CRAWLER_USERNAME,
"password": CRAWLER_PW,
"grant_type": "password",
},
)
data = r.json()
assert r.status_code == 200
assert data["access_token"]
assert data["token_type"] == "bearer"

user_info = data["user_info"]
assert user_info

assert user_info["id"] == crawler_userid
assert user_info["name"] == "new-crawler"
assert user_info["email"] == CRAWLER_USERNAME
assert user_info["is_superuser"] is False
assert user_info["is_verified"]

user_orgs = user_info["orgs"]
assert len(user_orgs) == 1
org = user_orgs[0]

assert org["id"] == default_org_id
assert org["name"] == default_org["name"]
assert org["slug"] == default_org["slug"]
assert org["default"]
assert org["role"] == 20


def test_login_case_insensitive_email():
r = requests.post(
f"{API_PREFIX}/auth/jwt/login",
Expand Down

0 comments on commit 916813a

Please sign in to comment.