Chore: Refractor Models into organized file/folder

This commit is contained in:
2026-03-01 12:40:48 +05:45
parent 58432da1c8
commit 07193a2d2e
35 changed files with 1475 additions and 932 deletions
+12
View File
@@ -0,0 +1,12 @@
"""Security subpackage — organization and user security policies, MFA compliance."""
from gatehouse_app.models.security.organization_security_policy import (
OrganizationSecurityPolicy,
)
from gatehouse_app.models.security.user_security_policy import UserSecurityPolicy
from gatehouse_app.models.security.mfa_policy_compliance import MfaPolicyCompliance
__all__ = [
"OrganizationSecurityPolicy",
"UserSecurityPolicy",
"MfaPolicyCompliance",
]
@@ -0,0 +1,67 @@
"""MfaPolicyCompliance model — per-user per-organization MFA compliance tracking."""
from gatehouse_app.extensions import db
from gatehouse_app.models.base import BaseModel
from gatehouse_app.utils.constants import MfaComplianceStatus
class MfaPolicyCompliance(BaseModel):
"""MFA policy compliance tracking per user per organization.
Tracks each user's MFA compliance state separately for each organization
membership. One row per (user, org) pair.
"""
__tablename__ = "mfa_policy_compliance"
user_id = db.Column(
db.String(36), db.ForeignKey("users.id"), nullable=False, index=True
)
organization_id = db.Column(
db.String(36), db.ForeignKey("organizations.id"), nullable=False, index=True
)
status = db.Column(
db.Enum(MfaComplianceStatus),
nullable=False,
default=MfaComplianceStatus.NOT_APPLICABLE,
)
# Snapshot of org policy version when this record became active
policy_version = db.Column(db.Integer, nullable=False)
# When policy started applying to this user
applied_at = db.Column(db.DateTime, nullable=True)
# Final deadline for this user to comply
deadline_at = db.Column(db.DateTime, nullable=True)
# When they became compliant under this policy_version
compliant_at = db.Column(db.DateTime, nullable=True)
# When suspended enforcement started for this user
suspended_at = db.Column(db.DateTime, nullable=True)
# Notification tracking
last_notified_at = db.Column(db.DateTime, nullable=True)
notification_count = db.Column(db.Integer, nullable=False, default=0)
__table_args__ = (
db.UniqueConstraint("user_id", "organization_id", name="uix_user_org_compliance"),
)
# Relationships
user = db.relationship(
"User", back_populates="mfa_compliance", foreign_keys=[user_id]
)
organization = db.relationship("Organization", foreign_keys=[organization_id])
def __repr__(self):
"""String representation of MfaPolicyCompliance."""
return (
f"<MfaPolicyCompliance user={self.user_id} "
f"org={self.organization_id} status={self.status}>"
)
def to_dict(self, exclude=None):
"""Convert to dictionary."""
return super().to_dict(exclude=exclude or [])
@@ -0,0 +1,57 @@
"""OrganizationSecurityPolicy model."""
from gatehouse_app.extensions import db
from gatehouse_app.models.base import BaseModel
from gatehouse_app.utils.constants import MfaPolicyMode
class OrganizationSecurityPolicy(BaseModel):
"""Organization security policy model for MFA configuration.
One row per organization capturing its current security requirements.
"""
__tablename__ = "organization_security_policies"
organization_id = db.Column(
db.String(36),
db.ForeignKey("organizations.id"),
nullable=False,
index=True,
unique=True,
)
# MFA policy configuration
mfa_policy_mode = db.Column(
db.Enum(MfaPolicyMode), nullable=False, default=MfaPolicyMode.OPTIONAL
)
# Grace period for members in days
mfa_grace_period_days = db.Column(db.Integer, nullable=False, default=14)
# Notification settings (in days before individual user deadline)
notify_days_before = db.Column(db.Integer, nullable=False, default=7)
# Versioning for compatibility tracking
policy_version = db.Column(db.Integer, nullable=False, default=1)
# Audit metadata
updated_by_user_id = db.Column(db.String(36), db.ForeignKey("users.id"), nullable=True)
# Relationships
organization = db.relationship(
"Organization",
back_populates="security_policy",
foreign_keys=[organization_id],
)
updated_by_user = db.relationship("User", foreign_keys=[updated_by_user_id])
def __repr__(self):
"""String representation of OrganizationSecurityPolicy."""
return (
f"<OrganizationSecurityPolicy "
f"org={self.organization_id} mode={self.mfa_policy_mode}>"
)
def to_dict(self, exclude=None):
"""Convert to dictionary."""
return super().to_dict(exclude=exclude or [])
@@ -0,0 +1,51 @@
"""UserSecurityPolicy model — per-user MFA overrides."""
from gatehouse_app.extensions import db
from gatehouse_app.models.base import BaseModel
from gatehouse_app.utils.constants import MfaRequirementOverride
class UserSecurityPolicy(BaseModel):
"""User security policy model for per-user MFA overrides.
Stores per-user overrides of organization-level MFA requirements.
"""
__tablename__ = "user_security_policies"
user_id = db.Column(
db.String(36), db.ForeignKey("users.id"), nullable=False, index=True
)
organization_id = db.Column(
db.String(36), db.ForeignKey("organizations.id"), nullable=False, index=True
)
mfa_override_mode = db.Column(
db.Enum(MfaRequirementOverride),
nullable=False,
default=MfaRequirementOverride.INHERIT,
)
# If override is REQUIRED, optionally force a specific factor set
force_totp = db.Column(db.Boolean, nullable=False, default=False)
force_webauthn = db.Column(db.Boolean, nullable=False, default=False)
__table_args__ = (
db.UniqueConstraint("user_id", "organization_id", name="uix_user_org_policy"),
)
# Relationships
user = db.relationship(
"User", back_populates="security_policies", foreign_keys=[user_id]
)
organization = db.relationship("Organization", foreign_keys=[organization_id])
def __repr__(self):
"""String representation of UserSecurityPolicy."""
return (
f"<UserSecurityPolicy user={self.user_id} "
f"org={self.organization_id} mode={self.mfa_override_mode}>"
)
def to_dict(self, exclude=None):
"""Convert to dictionary."""
return super().to_dict(exclude=exclude or [])