from connector.generated import (
AccountStatus,
FindEntitlementAssociationsRequest,
FindEntitlementAssociationsResponse,
FoundAccountData,
FoundEntitlementAssociation,
FoundEntitlementData,
FoundResourceData,
GetLastActivityRequest,
GetLastActivityResponse,
LastActivityData,
ListAccountsRequest,
ListAccountsResponse,
ListEntitlementsRequest,
ListEntitlementsResponse,
ListResourcesRequest,
ListResourcesResponse,
Page,
ValidateCredentialsRequest,
ValidateCredentialsResponse,
ValidatedCredentials,
ActivityEventType,
)
from connector.oai.capability import get_page
from connector.oai.errors import ConnectorError, ErrorCode
from mockapp_connector.pagination import DEFAULT_PAGE_SIZE, NextPageToken, Pagination
from mockapp_connector.client import MockappClient
async def validate_credentials(
args: ValidateCredentialsRequest,
) -> ValidateCredentialsResponse:
"""Validate credentials for MockApp API."""
async with MockappClient(args) as client:
try:
# Test the API with a simple call
await client.get_users(limit=1)
return ValidateCredentialsResponse(
response=ValidatedCredentials(
unique_tenant_id="mockapp-tenant-id",
valid=True,
),
)
except Exception as e:
raise ConnectorError(
message=f"Exception occured: {str(e)}",
error_code=ErrorCode.API_ERROR,
) from e
async def list_accounts(args: ListAccountsRequest) -> ListAccountsResponse:
"""List user accounts from MockApp."""
endpoint = "/api/users"
try:
current_pagination = NextPageToken(get_page(args).token).paginations()[0]
except IndexError:
current_pagination = Pagination.default(endpoint)
page_size = get_page(args).size or DEFAULT_PAGE_SIZE
async with MockappClient(args) as client:
response = await client.get_users(
limit=page_size,
offset=current_pagination.offset,
)
# Transform API response to Lumos account format
accounts = []
for user in response.get("items", []):
status = AccountStatus.ACTIVE
if user.get("status") == "inactive":
status = AccountStatus.INACTIVE
elif user.get("status") == "deleted":
status = AccountStatus.SUSPENDED
accounts.append(FoundAccountData(
integration_specific_id=user["id"],
email=user.get("email", ""),
username=user.get("name", ""),
user_status=status,
))
# Handle pagination
has_more = response.get("has_more", False)
next_pagination = []
if has_more:
next_pagination.append(
Pagination(
endpoint=endpoint,
offset=current_pagination.offset + len(accounts),
)
)
next_page_token = NextPageToken.from_paginations(next_pagination).token if next_pagination else None
return ListAccountsResponse(
response=accounts,
page=Page(
token=next_page_token,
size=page_size,
) if next_page_token else None,
)
async def list_resources(args: ListResourcesRequest) -> ListResourcesResponse:
"""List resources from MockApp."""
async with MockappClient(args) as client:
resources_data = await client.get_resources()
# Transform API response to Lumos resource format
resources = []
for resource in resources_data:
resources.append(FoundResourceData(
integration_specific_id=resource["id"],
resource_type=resource["type"],
label=resource["name"],
))
return ListResourcesResponse(
response=resources,
)
async def list_entitlements(args: ListEntitlementsRequest) -> ListEntitlementsResponse:
"""List entitlements from MockApp."""
async with MockappClient(args) as client:
entitlements_data = await client.get_entitlements()
# Transform API response to Lumos entitlement format
entitlements = []
for entitlement in entitlements_data:
entitlements.append(FoundEntitlementData(
integration_specific_id=entitlement["id"],
entitlement_type=entitlement["type"],
integration_specific_resource_id=entitlement["resource_id"],
label=entitlement["name"],
))
return ListEntitlementsResponse(
response=entitlements,
)
async def find_entitlement_associations(
args: FindEntitlementAssociationsRequest,
) -> FindEntitlementAssociationsResponse:
"""Find entitlement associations in MockApp."""
async with MockappClient(args) as client:
associations_data = await client.get_associations()
# Transform API response to Lumos association format
associations = []
for assoc in associations_data:
associations.append(FoundEntitlementAssociation(
account_id=assoc["user_id"],
integration_specific_entitlement_id=assoc["entitlement_id"],
integration_specific_resource_id=assoc["resource_id"],
))
return FindEntitlementAssociationsResponse(
response=associations,
)
async def get_last_activity(args: GetLastActivityRequest) -> GetLastActivityResponse:
"""Get last activity for users in MockApp."""
account_ids = args.request.account_ids
async with MockappClient(args) as client:
# For each requested user, get their details to check last login
activities = []
for account_id in account_ids:
try:
user_data = await client._http_client.get(f"/api/users/{account_id}")
user = user_data.json()
if user.get("last_login"):
activities.append(LastActivityData(
account_id=account_id,
event_type=ActivityEventType.LAST_LOGIN,
happened_at=user["last_login"],
))
except Exception:
# Skip users that can't be found
pass
return GetLastActivityResponse(
response=activities,
)