"""Encapsulates all post-commit user notifications (Auth0 invites + permission updates).""" from typing import Optional from pythonfeatures import pythonfeatures from pythonfeatures.constants import split as split_constants from permissions.connectors import mysql from permissions.constants import constants from permissions.logic import auth0_invite, vend_contact as vend_contact_logic from permissions.models import ( ows_notifications as notifications, owsusers as users, vend_contact as vend_contact_model, ) from permissions.types import ( AdminIdentity, Identity, IdentityWithAuth0, TenantRolesInput, ) def notify_user_of_changes( admin: AdminIdentity, assignee: Identity, new_user: bool, tenant_roles_input: TenantRolesInput, brand: str, send_invite: bool, vend_contact: Optional[vend_contact_model.VendContact] = None, ) -> None: """Single entry point for all post-commit user notifications. Handles three cases: 1. New user (IdentityInput) -> Auth0 org invitation email 2. Existing pending user -> Auth0 org invitation email 3. Existing active user -> Add to org (if needed) + permissions-updated email """ if new_user: if send_invite: auth0_invite.send_auth0_invite( admin_identity=admin, assignee_identity=assignee, user_auth0_id=None, tenant_roles_input=tenant_roles_input, brand=brand, vend_contact=vend_contact, ) return # Existing identity from here on if assignee.is_pending(): if send_invite: auth0_invite.send_auth0_invite( admin_identity=admin, assignee_identity=assignee, user_auth0_id=assignee.auth0_user_id, tenant_roles_input=tenant_roles_input, brand=brand, vend_contact=vend_contact, ) return # Active user — add to org if needed if brand not in assignee.auth0_context.organizations: users.create_auth0_org_member( brand=brand, auth0_user_id=assignee.auth0_context.auth0_user_id, admin=admin, ) if vend_contact: with mysql.db_session() as session: vend_contact_logic.set_new_auth0_vend_contact_id( session=session, identity=assignee, admin_id=admin.id, admin_profile_id=admin.settings_profile.profile_id, ) if send_invite and _should_send_permissions_notification(assignee.id): notifications.send_user_permissions_updated( identity_id=assignee.id, tenant=tenant_roles_input.tenant, brand=brand, admin=admin, ) def notify_employee_created( admin: AdminIdentity, assignee: IdentityWithAuth0, tenant_roles_input: TenantRolesInput, brand: str, ) -> None: """Post-commit notifications for newly created employee. Always sends Auth0 invite on create. """ auth0_invite.send_auth0_invite( admin_identity=admin, assignee_identity=assignee, user_auth0_id=assignee.auth0_user_id, tenant_roles_input=tenant_roles_input, brand=brand, # Employees never have vend_contacts vend_contact=None, ) def notify_employee_updated( admin: AdminIdentity, assignee: IdentityWithAuth0, tenant_roles_input: TenantRolesInput, brand: str, ) -> None: """Post-commit notifications for employee permission updates.""" if _should_send_permissions_notification(assignee.id): notifications.send_user_permissions_updated( identity_id=assignee.id, tenant=tenant_roles_input.tenant, brand=brand, admin=admin, ) def _should_send_permissions_notification(identity_id: str) -> bool: return ( pythonfeatures.get_single_feature_by_attributes( constants.USER_UPDATED_PERMISSIONS_EMAIL, {'identity_id': identity_id} ).message == split_constants.FEATURE_ENABLED )