Repository: Significant-Gravitas/Auto-GPT
File: rnd/autogpt_server/autogpt_server/server/integrations.py (Python)

Code before:
        raise HTTPException(status_code=400, detail=str(e))

    store.add_creds(user_id, credentials)
    return CredentialsMetaResponse(
        credentials_id=credentials.id,
        credentials_type=credentials.type,
    )


class CredentialsResponse(CredentialsMetaResponse):
    user_email: str
    scopes: list[str] | None


@integrations_api_router.get("/{provider}/credentials")
async def list_credentials(
    provider: Annotated[str, Path(title="The provider to list credentials for")],
    auth: Annotated[dict[str, Any], Depends(auth_middleware)],
    store: Annotated[SupabaseIntegrationCredentialsStore, Depends(get_store)],
) -> list[CredentialsMetaResponse]:
    credentials = store.get_creds_by_provider(auth["sub"], provider)
    return [
        CredentialsResponse(
            credentials_id=cred.id,
            credentials_type=cred.type,
            user_email=auth["email"],
            scopes=cred.scopes if isinstance(cred, OAuth2Credentials) else None,
        )
        for cred in credentials
    ]


@integrations_api_router.get("/{provider}/credentials/{cred_id}")
async def get_credential(
    provider: Annotated[str, Path(title="The provider to retrieve credentials for")],
    cred_id: Annotated[str, Path(title="The ID of the credentials to retrieve")],
    user_id: Annotated[str, Depends(get_user_id)],
    store: Annotated[SupabaseIntegrationCredentialsStore, Depends(get_store)],
) -> Credentials:
    credential = store.get_creds_by_id(user_id, cred_id)
    if not credential:
        raise HTTPException(status_code=404, detail="Credentials not found")
    if credential.provider != provider:
        raise HTTPException(
            status_code=400, detail="Credentials do not match the specified provider"
        )
    return credential


# -------- UTILITIES --------- #


Review comment (security):
I meant the e-mail linked to the credentials, not the application user e-mail. Getting such metadata for credentials is different for every service, but for e.g. Notion it's stored in the credentials' metadata.

Code after:
    except Exception as e:
        logger.warning(f"Code->Token exchange failed for provider {provider}: {e}")
        raise HTTPException(status_code=400, detail=str(e))

    # TODO: Allow specifying `title` to set on `credentials`
    store.add_creds(user_id, credentials)
    return CredentialsMetaResponse(
        id=credentials.id,
        type=credentials.type,
        title=credentials.title,
        scopes=credentials.scopes,
        username=credentials.username,
    )


@integrations_api_router.get("/{provider}/credentials")
async def list_credentials(
    provider: Annotated[str, Path(title="The provider to list credentials for")],
    user_id: Annotated[str, Depends(get_user_id)],
    store: Annotated[SupabaseIntegrationCredentialsStore, Depends(get_store)],
) -> list[CredentialsMetaResponse]:
    credentials = store.get_creds_by_provider(user_id, provider)
    return [
        CredentialsMetaResponse(
            id=cred.id,
            type=cred.type,
            title=cred.title,
            scopes=cred.scopes if isinstance(cred, OAuth2Credentials) else None,
            username=cred.username if isinstance(cred, OAuth2Credentials) else None,
        )
        for cred in credentials
    ]


@integrations_api_router.get("/{provider}/credentials/{cred_id}")
async def get_credential(
    provider: Annotated[str, Path(title="The provider to retrieve credentials for")],
    cred_id: Annotated[str, Path(title="The ID of the credentials to retrieve")],
    user_id: Annotated[str, Depends(get_user_id)],
    store: Annotated[SupabaseIntegrationCredentialsStore, Depends(get_store)],
) -> Credentials:
    credential = store.get_creds_by_id(user_id, cred_id)
    if not credential:
        raise HTTPException(status_code=404, detail="Credentials not found")
    if credential.provider != provider:
        raise HTTPException(
            status_code=404, detail="Credentials do not match the specified provider"
        )
    return credential