diff --git a/gatehouse_app/api/v1/departments.py b/gatehouse_app/api/v1/departments.py index 4ced781..117db75 100644 --- a/gatehouse_app/api/v1/departments.py +++ b/gatehouse_app/api/v1/departments.py @@ -10,6 +10,8 @@ from gatehouse_app.models import Department, DepartmentMembership from gatehouse_app.services.organization_service import OrganizationService from gatehouse_app.services.user_service import UserService from gatehouse_app.extensions import db +from gatehouse_app.utils.constants import AuditAction +from gatehouse_app.services.audit_service import AuditService class DepartmentCreateSchema(Schema): @@ -127,6 +129,15 @@ def create_department(org_id): db.session.add(dept) db.session.commit() + AuditService.log_action( + action=AuditAction.DEPARTMENT_CREATED, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="department", + resource_id=str(dept.id), + description=f"Department '{dept.name}' created", + ) + return api_response( data={"department": dept.to_dict()}, message="Department created successfully", @@ -255,6 +266,15 @@ def update_department(org_id, dept_id): db.session.commit() + AuditService.log_action( + action=AuditAction.DEPARTMENT_UPDATED, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="department", + resource_id=str(dept.id), + description=f"Department '{dept.name}' updated", + ) + return api_response( data={"department": dept.to_dict()}, message="Department updated successfully", @@ -308,6 +328,15 @@ def delete_department(org_id, dept_id): dept.deleted_at = db.func.now() db.session.commit() + AuditService.log_action( + action=AuditAction.DEPARTMENT_DELETED, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="department", + resource_id=str(dept.id), + description=f"Department '{dept.name}' deleted", + ) + return api_response( message="Department deleted successfully", ) @@ -461,6 +490,15 @@ def add_department_member(org_id, dept_id): db.session.commit() + AuditService.log_action( + action=AuditAction.DEPARTMENT_MEMBER_ADDED, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="user", + resource_id=str(user.id), + description=f"Added user {user.email} to department '{dept.name}'", + ) + member_dict = membership.to_dict() member_dict["user"] = user.to_dict() @@ -533,6 +571,15 @@ def remove_department_member(org_id, dept_id, user_id): membership.deleted_at = db.func.now() db.session.commit() + AuditService.log_action( + action=AuditAction.DEPARTMENT_MEMBER_REMOVED, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="user", + resource_id=str(user_id), + description=f"Removed user from department '{dept.name}'", + ) + return api_response( message="Member removed successfully", ) @@ -699,5 +746,14 @@ def set_dept_cert_policy(org_id, dept_id): db.session.commit() + AuditService.log_action( + action=AuditAction.DEPARTMENT_CERT_POLICY_UPDATED, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="department", + resource_id=str(dept_id), + description=f"Certificate policy updated for department '{dept.name}'", + ) + return api_response(data={"cert_policy": policy.to_dict()}, message="Certificate policy saved") diff --git a/gatehouse_app/api/v1/external_auth/admin.py b/gatehouse_app/api/v1/external_auth/admin.py index d1149b3..1a9de57 100644 --- a/gatehouse_app/api/v1/external_auth/admin.py +++ b/gatehouse_app/api/v1/external_auth/admin.py @@ -3,6 +3,8 @@ from flask import g, request from gatehouse_app.api.v1 import api_v1_bp from gatehouse_app.utils.response import api_response from gatehouse_app.utils.decorators import login_required +from gatehouse_app.utils.constants import AuditAction +from gatehouse_app.services.audit_service import AuditService @api_v1_bp.route("/admin/oauth/providers", methods=["GET"]) @@ -78,6 +80,14 @@ def admin_configure_app_provider(provider: str): db.session.add(cfg) db.session.commit() + AuditService.log_action( + action=AuditAction.EXTERNAL_AUTH_CONFIG_UPDATE if cfg else AuditAction.EXTERNAL_AUTH_CONFIG_CREATE, + user_id=g.current_user.id, + resource_type="oauth_provider", + resource_id=provider, + description=f"OAuth provider '{provider}' configured (enabled={cfg.is_enabled})", + ) + return api_response( data={"provider": {"id": provider, "client_id": cfg.client_id, "is_enabled": cfg.is_enabled}}, message=f"{provider.capitalize()} OAuth provider configured successfully", @@ -104,4 +114,13 @@ def admin_delete_app_provider(provider: str): return api_response(success=False, message=f"Provider '{provider}' is not configured", status=404, error_type="NOT_FOUND") cfg.delete() + + AuditService.log_action( + action=AuditAction.EXTERNAL_AUTH_CONFIG_DELETE, + user_id=g.current_user.id, + resource_type="oauth_provider", + resource_id=provider, + description=f"OAuth provider '{provider}' configuration removed", + ) + return api_response(message=f"{provider.capitalize()} OAuth provider configuration removed") diff --git a/gatehouse_app/api/v1/oidc.py b/gatehouse_app/api/v1/oidc.py index 07a9366..e4f01f4 100644 --- a/gatehouse_app/api/v1/oidc.py +++ b/gatehouse_app/api/v1/oidc.py @@ -26,6 +26,9 @@ from gatehouse_app.exceptions.auth_exceptions import ( AccountSuspendedError, AccountInactiveError, ) +from gatehouse_app.utils.constants import AuditAction +from gatehouse_app.services.audit_service import AuditService +from gatehouse_app.services.oidc_audit_service import OIDCAuditService logger = logging.getLogger(__name__) @@ -849,6 +852,18 @@ def oidc_register(): ) client.save() + OIDCAuditService.log_event( + event_type="client_registration", + client_id=client_id, + user_id=g.current_user.id if hasattr(g, "current_user") else None, + success=True, + metadata={ + "client_name": client_name, + "redirect_uris": redirect_uris, + "organization_id": str(organization.id), + }, + ) + response = jsonify({ "client_id": client_id, "client_secret": client_secret, diff --git a/gatehouse_app/api/v1/organizations/api_keys.py b/gatehouse_app/api/v1/organizations/api_keys.py index 90d83ee..878c180 100644 --- a/gatehouse_app/api/v1/organizations/api_keys.py +++ b/gatehouse_app/api/v1/organizations/api_keys.py @@ -8,6 +8,8 @@ from gatehouse_app.utils.decorators import login_required, require_admin, full_a from gatehouse_app.models.organization import OrganizationApiKey from gatehouse_app.services.organization_service import OrganizationService from gatehouse_app.extensions import db +from gatehouse_app.utils.constants import AuditAction +from gatehouse_app.services.audit_service import AuditService class ApiKeyCreateSchema(Schema): @@ -130,7 +132,16 @@ def create_api_key(org_id): name=data["name"], description=data.get("description"), ) - + + AuditService.log_action( + action=AuditAction.ORG_API_KEY_CREATED, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="api_key", + resource_id=str(api_key.id), + description=f"API key '{api_key.name}' created", + ) + # Return the key data with the plain text key (only on creation) key_dict = api_key.to_dict() key_dict["key"] = plain_key # Include plain text only on creation @@ -219,9 +230,18 @@ def update_api_key(org_id, key_id): api_key.name = data["name"] if "description" in data: api_key.description = data["description"] - + api_key.save() - + + AuditService.log_action( + action=AuditAction.ORG_API_KEY_UPDATED, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="api_key", + resource_id=str(api_key.id), + description=f"API key '{api_key.name}' updated", + ) + return api_response( data={"api_key": api_key.to_dict()}, message="API key updated successfully", @@ -293,7 +313,16 @@ def delete_api_key(org_id, key_id): # Soft delete the API key api_key.delete(soft=True) - + + AuditService.log_action( + action=AuditAction.ORG_API_KEY_DELETED, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="api_key", + resource_id=str(api_key.id), + description=f"API key '{api_key.name}' deleted", + ) + return api_response( message="API key deleted successfully", ) diff --git a/gatehouse_app/api/v1/organizations/cas.py b/gatehouse_app/api/v1/organizations/cas.py index ad1ac71..d1567b4 100644 --- a/gatehouse_app/api/v1/organizations/cas.py +++ b/gatehouse_app/api/v1/organizations/cas.py @@ -6,6 +6,8 @@ from gatehouse_app.utils.response import api_response from gatehouse_app.utils.decorators import login_required, require_admin from gatehouse_app.extensions import db from gatehouse_app.api.v1.organizations._helpers import _get_system_ca_dict +from gatehouse_app.utils.constants import AuditAction +from gatehouse_app.services.audit_service import AuditService @api_v1_bp.route("/organizations//cas", methods=["GET"]) @@ -66,6 +68,16 @@ def update_org_ca(org_id, ca_id): ca.max_cert_validity_hours = data["max_cert_validity_hours"] db.session.commit() + + AuditService.log_action( + action=AuditAction.CA_UPDATED, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="CA", + resource_id=ca_id, + description=f"CA '{ca.name}' updated", + ) + return api_response(data={"ca": ca.to_dict()}, message="CA updated successfully") except ValidationError as e: return api_response(success=False, message="Validation failed", status=400, error_type="VALIDATION_ERROR", error_details=e.messages) @@ -150,6 +162,15 @@ def create_org_ca(org_id): return api_response(success=False, message="A CA with that name already exists in this organization (it may have been recently deleted — choose a different name).", status=400, error_type="DUPLICATE_NAME") raise + AuditService.log_action( + action=AuditAction.CA_CREATED, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="CA", + resource_id=str(ca.id), + description=f"CA '{ca.name}' created", + ) + return api_response(data={"ca": ca.to_dict()}, message="CA created successfully", status=201) except MaValidationError as e: return api_response(success=False, message="Validation failed", status=400, error_type="VALIDATION_ERROR", error_details=e.messages) diff --git a/gatehouse_app/api/v1/organizations/clients.py b/gatehouse_app/api/v1/organizations/clients.py index 3cbbaba..8fb7334 100644 --- a/gatehouse_app/api/v1/organizations/clients.py +++ b/gatehouse_app/api/v1/organizations/clients.py @@ -5,6 +5,8 @@ from gatehouse_app.api.v1 import api_v1_bp from gatehouse_app.utils.response import api_response from gatehouse_app.utils.decorators import login_required, require_admin, full_access_required from gatehouse_app.extensions import db, bcrypt +from gatehouse_app.utils.constants import AuditAction +from gatehouse_app.services.audit_service import AuditService @api_v1_bp.route("/organizations//clients", methods=["GET"]) @@ -79,6 +81,15 @@ def create_org_client(org_id): db.session.add(client) db.session.commit() + AuditService.log_action( + action=AuditAction.ORG_CLIENT_CREATED, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="oidc_client", + resource_id=str(client.id), + description=f"OIDC client '{client.name}' created", + ) + return api_response( data={ "client": { @@ -126,6 +137,15 @@ def update_org_client(org_id, client_id): db.session.commit() + AuditService.log_action( + action=AuditAction.ORG_CLIENT_UPDATED, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="oidc_client", + resource_id=str(client.id), + description=f"OIDC client '{client.name}' updated", + ) + return api_response( data={ "client": { @@ -155,4 +175,14 @@ def delete_org_client(org_id, client_id): client.is_active = False db.session.commit() + + AuditService.log_action( + action=AuditAction.ORG_CLIENT_DEACTIVATED, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="oidc_client", + resource_id=str(client.id), + description=f"OIDC client '{client.name}' deactivated", + ) + return api_response(data={}, message="Client deactivated successfully") diff --git a/gatehouse_app/api/v1/organizations/core.py b/gatehouse_app/api/v1/organizations/core.py index 940c089..6c785b9 100644 --- a/gatehouse_app/api/v1/organizations/core.py +++ b/gatehouse_app/api/v1/organizations/core.py @@ -7,6 +7,8 @@ from gatehouse_app.utils.response import api_response from gatehouse_app.utils.decorators import login_required, require_admin, full_access_required from gatehouse_app.schemas.organization_schema import OrganizationCreateSchema, OrganizationUpdateSchema from gatehouse_app.services.organization_service import OrganizationService +from gatehouse_app.utils.constants import AuditAction +from gatehouse_app.services.audit_service import AuditService @api_v1_bp.route("/organizations", methods=["POST"]) @@ -32,6 +34,14 @@ def create_organization(): description=data.get("description"), logo_url=data.get("logo_url"), ) + AuditService.log_action( + action=AuditAction.ORG_CREATE, + user_id=g.current_user.id, + organization_id=org.id, + resource_type="organization", + resource_id=str(org.id), + description=f"Organization '{org.name}' created", + ) return api_response(data={"organization": org.to_dict()}, message="Organization created successfully", status=201) except ValidationError as e: return api_response(success=False, message="Validation failed", status=400, error_type="VALIDATION_ERROR", error_details=e.messages) @@ -60,6 +70,14 @@ def update_organization(org_id): data = schema.load(request.json) org = OrganizationService.get_organization_by_id(org_id) org = OrganizationService.update_organization(org=org, user_id=g.current_user.id, **data) + AuditService.log_action( + action=AuditAction.ORG_UPDATE, + user_id=g.current_user.id, + organization_id=org.id, + resource_type="organization", + resource_id=str(org.id), + description=f"Organization '{org.name}' updated", + ) return api_response(data={"organization": org.to_dict()}, message="Organization updated successfully") except ValidationError as e: return api_response(success=False, message="Validation failed", status=400, error_type="VALIDATION_ERROR", error_details=e.messages) @@ -92,4 +110,12 @@ def delete_organization(org_id): ) OrganizationService.force_delete_organization(org=org, user_id=caller.id) + AuditService.log_action( + action=AuditAction.ORG_DELETE, + user_id=caller.id, + organization_id=org.id, + resource_type="organization", + resource_id=str(org.id), + description=f"Organization '{org.name}' deleted", + ) return api_response(message="Organization deleted successfully") diff --git a/gatehouse_app/api/v1/organizations/invites.py b/gatehouse_app/api/v1/organizations/invites.py index 1ac718a..b5b7ea8 100644 --- a/gatehouse_app/api/v1/organizations/invites.py +++ b/gatehouse_app/api/v1/organizations/invites.py @@ -136,6 +136,15 @@ def cancel_org_invite(org_id, invite_id): return api_response(success=False, message="Invite not found", status=404) invite.delete(soft=True) + AuditService.log_action( + action=AuditAction.ORG_INVITE_CANCELLED, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="org_invite", + resource_id=invite.id, + metadata={"invited_email": invite.email, "role": invite.role}, + description=f"Invitation for {invite.email} cancelled", + ) return api_response(data={}, message="Invite cancelled") diff --git a/gatehouse_app/api/v1/organizations/members.py b/gatehouse_app/api/v1/organizations/members.py index b42a99c..4ebe750 100644 --- a/gatehouse_app/api/v1/organizations/members.py +++ b/gatehouse_app/api/v1/organizations/members.py @@ -7,7 +7,8 @@ from gatehouse_app.utils.decorators import login_required, require_admin, full_a from gatehouse_app.schemas.organization_schema import InviteMemberSchema, UpdateMemberRoleSchema from gatehouse_app.services.organization_service import OrganizationService from gatehouse_app.services.user_service import UserService -from gatehouse_app.utils.constants import OrganizationRole +from gatehouse_app.utils.constants import AuditAction, OrganizationRole +from gatehouse_app.services.audit_service import AuditService @api_v1_bp.route("/organizations//members", methods=["GET"]) @@ -43,6 +44,14 @@ def add_organization_member(org_id): role = OrganizationRole(data["role"]) member = OrganizationService.add_member(org=org, user_id=user.id, role=role, inviter_id=g.current_user.id) + AuditService.log_action( + action=AuditAction.ORG_MEMBER_ADD, + user_id=g.current_user.id, + organization_id=org.id, + resource_type="user", + resource_id=str(user.id), + description=f"Added user {user.email} to organization with role {role.value}", + ) member_dict = member.to_dict() member_dict["user"] = user.to_dict() return api_response(data={"member": member_dict}, message="Member added successfully", status=201) @@ -60,6 +69,14 @@ def remove_organization_member(org_id, user_id): OrganizationService.remove_member(org=org, user_id=user_id, remover_id=g.current_user.id) except ValueError as e: return api_response(success=False, message=str(e), status=403, error_type="OWNER_PROTECTION") + AuditService.log_action( + action=AuditAction.ORG_MEMBER_REMOVE, + user_id=g.current_user.id, + organization_id=org.id, + resource_type="user", + resource_id=str(user_id), + description=f"Removed user {user_id} from organization", + ) return api_response(message="Member removed successfully") @@ -74,6 +91,14 @@ def update_member_role(org_id, user_id): org = OrganizationService.get_organization_by_id(org_id) new_role = OrganizationRole(data["role"]) member = OrganizationService.update_member_role(org=org, user_id=user_id, new_role=new_role, updater_id=g.current_user.id) + AuditService.log_action( + action=AuditAction.ORG_MEMBER_ROLE_CHANGE, + user_id=g.current_user.id, + organization_id=org.id, + resource_type="user", + resource_id=str(user_id), + description=f"Changed role for user {user_id} to {new_role.value}", + ) member_dict = member.to_dict() member_dict["user"] = member.user.to_dict() return api_response(data={"member": member_dict}, message="Member role updated successfully") @@ -180,4 +205,13 @@ def send_mfa_reminder(org_id, user_id): html_body=html_body, ) + AuditService.log_action( + action=AuditAction.ORG_MFA_REMINDER_SENT, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="user", + resource_id=str(user_id), + description=f"MFA reminder sent to {user.email}", + ) + return api_response(data={}, message="Reminder sent successfully") diff --git a/gatehouse_app/api/v1/organizations/roles.py b/gatehouse_app/api/v1/organizations/roles.py index 3c982e9..2f8451e 100644 --- a/gatehouse_app/api/v1/organizations/roles.py +++ b/gatehouse_app/api/v1/organizations/roles.py @@ -3,8 +3,9 @@ from flask import g, request from gatehouse_app.api.v1 import api_v1_bp from gatehouse_app.utils.response import api_response from gatehouse_app.utils.decorators import login_required, require_admin, full_access_required -from gatehouse_app.utils.constants import OrganizationRole +from gatehouse_app.utils.constants import AuditAction, OrganizationRole from gatehouse_app.extensions import db +from gatehouse_app.services.audit_service import AuditService @api_v1_bp.route("/organizations//roles", methods=["GET"]) @@ -59,6 +60,16 @@ def assign_role_to_member(org_id, role_name): membership.role = new_role db.session.commit() + + AuditService.log_action( + action=AuditAction.ORG_MEMBER_ROLE_CHANGE, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="user", + resource_id=str(target_user_id), + description=f"Role changed to {new_role.value} for user {target_user_id}", + ) + return api_response(data={"user_id": target_user_id, "role": new_role.value}, message=f"Role updated to {new_role.value}") @@ -82,4 +93,14 @@ def remove_role_from_member(org_id, role_name, user_id): org = OrganizationService.get_organization_by_id(org_id) OrganizationService.remove_member(org=org, user_id=user_id, remover_id=g.current_user.id) + + AuditService.log_action( + action=AuditAction.ORG_MEMBER_REMOVE, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="user", + resource_id=str(user_id), + description=f"Member {user_id} removed from organization via role removal", + ) + return api_response(data={"user_id": user_id}, message="Member removed from organization") diff --git a/gatehouse_app/api/v1/principals.py b/gatehouse_app/api/v1/principals.py index 0da8315..3a71667 100644 --- a/gatehouse_app/api/v1/principals.py +++ b/gatehouse_app/api/v1/principals.py @@ -10,6 +10,8 @@ from gatehouse_app.services.organization_service import OrganizationService from gatehouse_app.services.user_service import UserService from gatehouse_app.exceptions import OrganizationNotFoundError from gatehouse_app.extensions import db +from gatehouse_app.utils.constants import AuditAction +from gatehouse_app.services.audit_service import AuditService class PrincipalCreateSchema(Schema): @@ -127,6 +129,15 @@ def create_principal(org_id): db.session.add(principal) db.session.commit() + AuditService.log_action( + action=AuditAction.PRINCIPAL_CREATED, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="principal", + resource_id=str(principal.id), + description=f"Principal '{principal.name}' created", + ) + return api_response( data={"principal": principal.to_dict()}, message="Principal created successfully", @@ -255,6 +266,15 @@ def update_principal(org_id, principal_id): db.session.commit() + AuditService.log_action( + action=AuditAction.PRINCIPAL_UPDATED, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="principal", + resource_id=str(principal.id), + description=f"Principal '{principal.name}' updated", + ) + return api_response( data={"principal": principal.to_dict()}, message="Principal updated successfully", @@ -308,6 +328,15 @@ def delete_principal(org_id, principal_id): principal.deleted_at = db.func.now() db.session.commit() + AuditService.log_action( + action=AuditAction.PRINCIPAL_DELETED, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="principal", + resource_id=str(principal.id), + description=f"Principal '{principal.name}' deleted", + ) + return api_response( message="Principal deleted successfully", ) @@ -476,6 +505,15 @@ def add_principal_member(org_id, principal_id): db.session.commit() + AuditService.log_action( + action=AuditAction.PRINCIPAL_MEMBER_ADDED, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="user", + resource_id=str(user.id), + description=f"Added user {user.email} to principal '{principal.name}'", + ) + member_dict = membership.to_dict() member_dict["user"] = user.to_dict() @@ -548,6 +586,15 @@ def remove_principal_member(org_id, principal_id, user_id): membership.deleted_at = db.func.now() db.session.commit() + AuditService.log_action( + action=AuditAction.PRINCIPAL_MEMBER_REMOVED, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="user", + resource_id=str(user_id), + description=f"Removed user from principal '{principal.name}'", + ) + return api_response( message="Member removed successfully", ) @@ -697,6 +744,15 @@ def link_principal_to_department(org_id, principal_id, dept_id): error_type="SERVER_ERROR", ) + AuditService.log_action( + action=AuditAction.PRINCIPAL_DEPARTMENT_LINKED, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="principal", + resource_id=str(principal_id), + description=f"Principal '{principal.name}' linked to department '{dept.name}'", + ) + return api_response( data={ "principal": principal.to_dict(), @@ -774,6 +830,15 @@ def unlink_principal_from_department(org_id, principal_id, dept_id): link.deleted_at = db.func.now() db.session.commit() + AuditService.log_action( + action=AuditAction.PRINCIPAL_DEPARTMENT_UNLINKED, + user_id=g.current_user.id, + organization_id=org_id, + resource_type="principal", + resource_id=str(principal_id), + description=f"Principal '{principal.name}' unlinked from department '{dept.name}'", + ) + return api_response( message="Principal unlinked from department successfully", ) diff --git a/gatehouse_app/api/v1/superadmin/auth.py b/gatehouse_app/api/v1/superadmin/auth.py index e45e63c..48fac09 100644 --- a/gatehouse_app/api/v1/superadmin/auth.py +++ b/gatehouse_app/api/v1/superadmin/auth.py @@ -9,6 +9,7 @@ from gatehouse_app.utils.response import api_response from gatehouse_app.services.superadmin_auth_service import SuperadminAuthService from gatehouse_app.decorators.superadmin import superadmin_required, superadmin_audit_log from gatehouse_app.exceptions.auth_exceptions import InvalidCredentialsError +from gatehouse_app.utils.constants import AuditAction logger = logging.getLogger(__name__) @@ -105,6 +106,7 @@ def login(): @superadmin_bp.route("/auth/logout", methods=["POST"]) @superadmin_required +@superadmin_audit_log(action=AuditAction.USER_LOGOUT, resource_type="session") def logout(): """Superadmin logout endpoint. diff --git a/gatehouse_app/utils/constants.py b/gatehouse_app/utils/constants.py index 1d600b7..e31bcab 100644 --- a/gatehouse_app/utils/constants.py +++ b/gatehouse_app/utils/constants.py @@ -154,6 +154,27 @@ class AuditAction(str, Enum): DEPARTMENT_DELETED = "department.deleted" DEPARTMENT_MEMBER_ADDED = "department.member.added" DEPARTMENT_MEMBER_REMOVED = "department.member.removed" + DEPARTMENT_CERT_POLICY_UPDATED = "department.cert_policy.updated" + + # Organization invite actions + ORG_INVITE_CANCELLED = "org.invite.cancelled" + + # MFA reminder + ORG_MFA_REMINDER_SENT = "org.mfa_reminder.sent" + + # API key actions + ORG_API_KEY_CREATED = "org.api_key.created" + ORG_API_KEY_UPDATED = "org.api_key.updated" + ORG_API_KEY_DELETED = "org.api_key.deleted" + + # OIDC client actions + ORG_CLIENT_CREATED = "org.client.created" + ORG_CLIENT_UPDATED = "org.client.updated" + ORG_CLIENT_DEACTIVATED = "org.client.deactivated" + + # Principal department link actions + PRINCIPAL_DEPARTMENT_LINKED = "principal.department.linked" + PRINCIPAL_DEPARTMENT_UNLINKED = "principal.department.unlinked" class OIDCGrantType(str, Enum):