Fix user emails use userout (#2511)
Follow-up to #2495, actually ensure org subscription data is in included in admin email response --------- Co-authored-by: Tessa Walsh <tessa@bitarchivist.net>
This commit is contained in:
parent
46be6a0cf6
commit
21a372057b
@ -212,28 +212,6 @@ class UserOrgInfoOut(BaseModel):
|
|||||||
role: UserRole
|
role: UserRole
|
||||||
|
|
||||||
|
|
||||||
# ============================================================================
|
|
||||||
class UserOut(BaseModel):
|
|
||||||
"""Output User model"""
|
|
||||||
|
|
||||||
id: UUID
|
|
||||||
|
|
||||||
name: str = ""
|
|
||||||
email: EmailStr
|
|
||||||
is_superuser: bool = False
|
|
||||||
is_verified: bool = False
|
|
||||||
|
|
||||||
orgs: List[UserOrgInfoOut]
|
|
||||||
|
|
||||||
|
|
||||||
# ============================================================================
|
|
||||||
class UserEmailWithOrgInfo(BaseModel):
|
|
||||||
"""Output model for getting user email list with org info for each"""
|
|
||||||
|
|
||||||
email: EmailStr
|
|
||||||
orgs: List[UserOrgInfoOut]
|
|
||||||
|
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
||||||
### CRAWL STATES
|
### CRAWL STATES
|
||||||
@ -1833,6 +1811,8 @@ class SubscriptionCanceledResponse(BaseModel):
|
|||||||
canceled: bool
|
canceled: bool
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# User Org Info With Subs
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
class UserOrgInfoOutWithSubs(UserOrgInfoOut):
|
class UserOrgInfoOutWithSubs(UserOrgInfoOut):
|
||||||
"""org per user with sub info"""
|
"""org per user with sub info"""
|
||||||
@ -1843,6 +1823,24 @@ class UserOrgInfoOutWithSubs(UserOrgInfoOut):
|
|||||||
subscription: Optional[Subscription] = None
|
subscription: Optional[Subscription] = None
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
class UserOutNoId(BaseModel):
|
||||||
|
"""Output User Model, no ID"""
|
||||||
|
|
||||||
|
name: str = ""
|
||||||
|
email: EmailStr
|
||||||
|
orgs: List[UserOrgInfoOut | UserOrgInfoOutWithSubs]
|
||||||
|
is_verified: bool = False
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
class UserOut(UserOutNoId):
|
||||||
|
"""Output User Model"""
|
||||||
|
|
||||||
|
id: UUID
|
||||||
|
is_superuser: bool = False
|
||||||
|
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# ORGS
|
# ORGS
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
@ -2890,10 +2888,10 @@ class PaginatedCrawlErrorResponse(PaginatedResponse):
|
|||||||
|
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
class PaginatedUserEmailsResponse(PaginatedResponse):
|
class PaginatedUserOutResponse(PaginatedResponse):
|
||||||
"""Response model for user emails with org info"""
|
"""Response model for user emails with org info"""
|
||||||
|
|
||||||
items: List[UserEmailWithOrgInfo]
|
items: List[UserOutNoId]
|
||||||
|
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
@ -28,6 +28,7 @@ from .models import (
|
|||||||
UserOrgInfoOut,
|
UserOrgInfoOut,
|
||||||
UserOrgInfoOutWithSubs,
|
UserOrgInfoOutWithSubs,
|
||||||
UserOut,
|
UserOut,
|
||||||
|
UserOutNoId,
|
||||||
UserRole,
|
UserRole,
|
||||||
InvitePending,
|
InvitePending,
|
||||||
InviteOut,
|
InviteOut,
|
||||||
@ -35,8 +36,7 @@ from .models import (
|
|||||||
FailedLogin,
|
FailedLogin,
|
||||||
UpdatedResponse,
|
UpdatedResponse,
|
||||||
SuccessResponse,
|
SuccessResponse,
|
||||||
UserEmailWithOrgInfo,
|
PaginatedUserOutResponse,
|
||||||
PaginatedUserEmailsResponse,
|
|
||||||
)
|
)
|
||||||
from .pagination import DEFAULT_PAGE_SIZE, paginated_format
|
from .pagination import DEFAULT_PAGE_SIZE, paginated_format
|
||||||
from .utils import is_bool, dt_now
|
from .utils import is_bool, dt_now
|
||||||
@ -166,8 +166,11 @@ class UserManager:
|
|||||||
return user
|
return user
|
||||||
|
|
||||||
async def get_user_info_with_orgs(
|
async def get_user_info_with_orgs(
|
||||||
self, user: User, info_out_cls: Type[UserOrgInfoOut] = UserOrgInfoOut
|
self,
|
||||||
) -> UserOut:
|
user: User,
|
||||||
|
info_out_cls: Type[UserOrgInfoOut | UserOrgInfoOutWithSubs] = UserOrgInfoOut,
|
||||||
|
user_out_cls: Type[UserOut | UserOutNoId] = UserOut,
|
||||||
|
) -> UserOut | UserOutNoId:
|
||||||
"""return User info"""
|
"""return User info"""
|
||||||
user_orgs, _ = await self.org_ops.get_orgs_for_user(
|
user_orgs, _ = await self.org_ops.get_orgs_for_user(
|
||||||
user,
|
user,
|
||||||
@ -196,7 +199,7 @@ class UserManager:
|
|||||||
else:
|
else:
|
||||||
orgs = []
|
orgs = []
|
||||||
|
|
||||||
return UserOut(
|
return user_out_cls(
|
||||||
id=user.id,
|
id=user.id,
|
||||||
email=user.email,
|
email=user.email,
|
||||||
name=user.name,
|
name=user.name,
|
||||||
@ -558,23 +561,23 @@ class UserManager:
|
|||||||
self,
|
self,
|
||||||
page_size: int = DEFAULT_PAGE_SIZE,
|
page_size: int = DEFAULT_PAGE_SIZE,
|
||||||
page: int = 1,
|
page: int = 1,
|
||||||
) -> Tuple[List[UserEmailWithOrgInfo], int]:
|
) -> Tuple[List[UserOutNoId], int]:
|
||||||
"""Get user emails with org info for each for paginated endpoint"""
|
"""Get user emails with org info for each for paginated endpoint"""
|
||||||
# Zero-index page for query
|
# Zero-index page for query
|
||||||
page = page - 1
|
page = page - 1
|
||||||
skip = page_size * page
|
skip = page_size * page
|
||||||
|
|
||||||
emails: List[UserEmailWithOrgInfo] = []
|
emails: List[UserOutNoId] = []
|
||||||
|
|
||||||
total = await self.users.count_documents({"is_superuser": False})
|
total = await self.users.count_documents({"is_superuser": False})
|
||||||
async for res in self.users.find(
|
async for res in self.users.find(
|
||||||
{"is_superuser": False}, skip=skip, limit=page_size
|
{"is_superuser": False}, skip=skip, limit=page_size
|
||||||
):
|
):
|
||||||
user = User(**res)
|
user = User(**res)
|
||||||
user_out = await self.get_user_info_with_orgs(user, UserOrgInfoOutWithSubs)
|
user_out = await self.get_user_info_with_orgs(
|
||||||
emails.append(
|
user, UserOrgInfoOutWithSubs, UserOutNoId
|
||||||
UserEmailWithOrgInfo(email=user_out.email, orgs=user_out.orgs)
|
|
||||||
)
|
)
|
||||||
|
emails.append(user_out)
|
||||||
|
|
||||||
return emails, total
|
return emails, total
|
||||||
|
|
||||||
@ -739,7 +742,7 @@ def init_users_router(
|
|||||||
return paginated_format(pending_invites, total, page, pageSize)
|
return paginated_format(pending_invites, total, page, pageSize)
|
||||||
|
|
||||||
@users_router.get(
|
@users_router.get(
|
||||||
"/emails", tags=["users"], response_model=PaginatedUserEmailsResponse
|
"/emails", tags=["users"], response_model=PaginatedUserOutResponse
|
||||||
)
|
)
|
||||||
async def get_user_emails(
|
async def get_user_emails(
|
||||||
user: User = Depends(current_active_user),
|
user: User = Depends(current_active_user),
|
||||||
|
@ -59,7 +59,6 @@ def test_me_with_orgs(crawler_auth_headers, default_org_id):
|
|||||||
data = r.json()
|
data = r.json()
|
||||||
assert data["email"] == CRAWLER_USERNAME_LOWERCASE
|
assert data["email"] == CRAWLER_USERNAME_LOWERCASE
|
||||||
assert data["id"]
|
assert data["id"]
|
||||||
# assert data["is_active"]
|
|
||||||
assert data["is_superuser"] is False
|
assert data["is_superuser"] is False
|
||||||
assert data["is_verified"] is True
|
assert data["is_verified"] is True
|
||||||
assert data["name"] == "new-crawler"
|
assert data["name"] == "new-crawler"
|
||||||
@ -801,6 +800,9 @@ def test_user_emails_endpoint_superuser(admin_auth_headers, default_org_id):
|
|||||||
|
|
||||||
for user in user_emails:
|
for user in user_emails:
|
||||||
assert user["email"]
|
assert user["email"]
|
||||||
|
assert "id" not in user
|
||||||
|
assert "is_superuser" not in user
|
||||||
|
assert user["is_verified"] == True
|
||||||
orgs = user.get("orgs")
|
orgs = user.get("orgs")
|
||||||
if orgs == []:
|
if orgs == []:
|
||||||
continue
|
continue
|
||||||
@ -810,6 +812,9 @@ def test_user_emails_endpoint_superuser(admin_auth_headers, default_org_id):
|
|||||||
assert org["name"]
|
assert org["name"]
|
||||||
assert org["slug"]
|
assert org["slug"]
|
||||||
assert org["default"] in (True, False)
|
assert org["default"] in (True, False)
|
||||||
|
assert "readOnly" in org
|
||||||
|
assert "readOnlyReason" in org
|
||||||
|
assert "subscription" in org
|
||||||
role = org["role"]
|
role = org["role"]
|
||||||
assert role
|
assert role
|
||||||
assert isinstance(role, int)
|
assert isinstance(role, int)
|
||||||
|
Loading…
Reference in New Issue
Block a user