enable policies
This commit is contained in:
@@ -9,6 +9,7 @@ class UserStatus(str, Enum):
|
||||
INACTIVE = "inactive"
|
||||
SUSPENDED = "suspended"
|
||||
PENDING = "pending"
|
||||
COMPLIANCE_SUSPENDED = "compliance_suspended"
|
||||
|
||||
|
||||
class OrganizationRole(str, Enum):
|
||||
@@ -86,6 +87,12 @@ class AuditAction(str, Enum):
|
||||
WEBAUTHN_CREDENTIAL_DELETED = "webauthn.credential.deleted"
|
||||
WEBAUTHN_CREDENTIAL_RENAMED = "webauthn.credential.renamed"
|
||||
|
||||
# Security policy actions
|
||||
ORG_SECURITY_POLICY_UPDATE = "org.security_policy.update"
|
||||
USER_SECURITY_POLICY_OVERRIDE_UPDATE = "user.security_policy.override_update"
|
||||
MFA_POLICY_USER_SUSPENDED = "mfa.policy.user_suspended"
|
||||
MFA_POLICY_USER_COMPLIANT = "mfa.policy.user_compliant"
|
||||
|
||||
|
||||
class OIDCGrantType(str, Enum):
|
||||
"""OIDC grant types."""
|
||||
@@ -116,3 +123,32 @@ class ErrorType:
|
||||
RATE_LIMIT_EXCEEDED = "RATE_LIMIT_EXCEEDED"
|
||||
INTERNAL_ERROR = "INTERNAL_ERROR"
|
||||
BAD_REQUEST = "BAD_REQUEST"
|
||||
|
||||
|
||||
class MfaPolicyMode(str, Enum):
|
||||
"""MFA policy mode for organizations."""
|
||||
|
||||
DISABLED = "disabled"
|
||||
OPTIONAL = "optional"
|
||||
REQUIRE_TOTP = "require_totp"
|
||||
REQUIRE_WEBAUTHN = "require_webauthn"
|
||||
REQUIRE_TOTP_OR_WEBAUTHN = "require_totp_or_webauthn"
|
||||
|
||||
|
||||
class MfaComplianceStatus(str, Enum):
|
||||
"""MFA compliance status for users per organization."""
|
||||
|
||||
NOT_APPLICABLE = "not_applicable"
|
||||
PENDING = "pending"
|
||||
IN_GRACE = "in_grace"
|
||||
COMPLIANT = "compliant"
|
||||
PAST_DUE = "past_due"
|
||||
SUSPENDED = "suspended"
|
||||
|
||||
|
||||
class MfaRequirementOverride(str, Enum):
|
||||
"""User override for organization MFA requirements."""
|
||||
|
||||
INHERIT = "inherit"
|
||||
REQUIRED = "required"
|
||||
EXEMPT = "exempt"
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
from functools import wraps
|
||||
from flask import request, g
|
||||
from gatehouse_app.utils.response import api_response
|
||||
from gatehouse_app.utils.constants import OrganizationRole
|
||||
from gatehouse_app.utils.constants import OrganizationRole, UserStatus
|
||||
from gatehouse_app.exceptions.auth_exceptions import UnauthorizedError, ForbiddenError
|
||||
|
||||
|
||||
def login_required(f):
|
||||
@@ -127,3 +128,41 @@ def require_owner(f):
|
||||
def require_admin(f):
|
||||
"""Decorator to require organization admin or owner role."""
|
||||
return require_role(OrganizationRole.OWNER, OrganizationRole.ADMIN)(f)
|
||||
|
||||
|
||||
def full_access_required(f):
|
||||
"""Decorator to require full access session (not compliance-only).
|
||||
|
||||
This decorator checks if the user has a compliance-only session or
|
||||
is in COMPLIANCE_SUSPENDED status. If so, it returns a 403 error
|
||||
with error_type "MFA_COMPLIANCE_REQUIRED".
|
||||
|
||||
Use this decorator on endpoints that require full MFA compliance.
|
||||
Endpoints for MFA enrollment, status, and logout should NOT use this decorator.
|
||||
"""
|
||||
@wraps(f)
|
||||
def decorated_function(*args, **kwargs):
|
||||
user = getattr(g, "current_user", None)
|
||||
session = getattr(g, "current_session", None)
|
||||
|
||||
if not user or not session:
|
||||
return api_response(
|
||||
success=False,
|
||||
message="Authentication required",
|
||||
status=401,
|
||||
error_type="AUTH_REQUIRED",
|
||||
)
|
||||
|
||||
# Check for compliance-only session or compliance suspended status
|
||||
if session.is_compliance_only or user.status == UserStatus.COMPLIANCE_SUSPENDED:
|
||||
return api_response(
|
||||
success=False,
|
||||
message="MFA compliance required to access this resource",
|
||||
status=403,
|
||||
error_type="MFA_COMPLIANCE_REQUIRED",
|
||||
error_details={"overall_status": "suspended"},
|
||||
)
|
||||
|
||||
return f(*args, **kwargs)
|
||||
|
||||
return decorated_function
|
||||
|
||||
Reference in New Issue
Block a user