migrations

This commit is contained in:
2026-01-28 14:20:48 +10:30
parent ae2421763a
commit 7637d7df45
6 changed files with 737 additions and 0 deletions
+122
View File
@@ -0,0 +1,122 @@
"""empty message
Revision ID: 5d99e6d4cdc6
Revises: 003
Create Date: 2026-01-16 15:31:36.288933
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '004'
down_revision = '003'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('mfa_policy_compliance',
sa.Column('user_id', sa.String(length=36), nullable=False),
sa.Column('organization_id', sa.String(length=36), nullable=False),
sa.Column('status', sa.Enum('NOT_APPLICABLE', 'PENDING', 'IN_GRACE', 'COMPLIANT', 'PAST_DUE', 'SUSPENDED', name='mfacompliancestatus'), nullable=False),
sa.Column('policy_version', sa.Integer(), nullable=False),
sa.Column('applied_at', sa.DateTime(), nullable=True),
sa.Column('deadline_at', sa.DateTime(), nullable=True),
sa.Column('compliant_at', sa.DateTime(), nullable=True),
sa.Column('suspended_at', sa.DateTime(), nullable=True),
sa.Column('last_notified_at', sa.DateTime(), nullable=True),
sa.Column('notification_count', sa.Integer(), nullable=False),
sa.Column('id', sa.String(length=36), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.Column('updated_at', sa.DateTime(), nullable=False),
sa.Column('deleted_at', sa.DateTime(), nullable=True),
sa.ForeignKeyConstraint(['organization_id'], ['organizations.id'], ),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('id'),
sa.UniqueConstraint('user_id', 'organization_id', name='uix_user_org_compliance')
)
op.create_index(op.f('ix_mfa_policy_compliance_organization_id'), 'mfa_policy_compliance', ['organization_id'], unique=False)
op.create_index(op.f('ix_mfa_policy_compliance_user_id'), 'mfa_policy_compliance', ['user_id'], unique=False)
op.create_table('organization_security_policies',
sa.Column('organization_id', sa.String(length=36), nullable=False),
sa.Column('mfa_policy_mode', sa.Enum('DISABLED', 'OPTIONAL', 'REQUIRE_TOTP', 'REQUIRE_WEBAUTHN', 'REQUIRE_TOTP_OR_WEBAUTHN', name='mfapolicymode'), nullable=False),
sa.Column('mfa_grace_period_days', sa.Integer(), nullable=False),
sa.Column('notify_days_before', sa.Integer(), nullable=False),
sa.Column('policy_version', sa.Integer(), nullable=False),
sa.Column('updated_by_user_id', sa.String(length=36), nullable=True),
sa.Column('id', sa.String(length=36), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.Column('updated_at', sa.DateTime(), nullable=False),
sa.Column('deleted_at', sa.DateTime(), nullable=True),
sa.ForeignKeyConstraint(['organization_id'], ['organizations.id'], ),
sa.ForeignKeyConstraint(['updated_by_user_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('id')
)
op.create_index(op.f('ix_organization_security_policies_organization_id'), 'organization_security_policies', ['organization_id'], unique=True)
op.create_table('user_security_policies',
sa.Column('user_id', sa.String(length=36), nullable=False),
sa.Column('organization_id', sa.String(length=36), nullable=False),
sa.Column('mfa_override_mode', sa.Enum('INHERIT', 'REQUIRED', 'EXEMPT', name='mfarequirementoverride'), nullable=False),
sa.Column('force_totp', sa.Boolean(), nullable=False),
sa.Column('force_webauthn', sa.Boolean(), nullable=False),
sa.Column('id', sa.String(length=36), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.Column('updated_at', sa.DateTime(), nullable=False),
sa.Column('deleted_at', sa.DateTime(), nullable=True),
sa.ForeignKeyConstraint(['organization_id'], ['organizations.id'], ),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('id'),
sa.UniqueConstraint('user_id', 'organization_id', name='uix_user_org_policy')
)
op.create_index(op.f('ix_user_security_policies_organization_id'), 'user_security_policies', ['organization_id'], unique=False)
op.create_index(op.f('ix_user_security_policies_user_id'), 'user_security_policies', ['user_id'], unique=False)
# Use batch operations for SQLite-compatible column type changes
with op.batch_alter_table('audit_logs', schema=None) as batch_op:
batch_op.alter_column('action',
existing_type=sa.VARCHAR(length=22),
type_=sa.Enum('USER_LOGIN', 'USER_LOGOUT', 'USER_REGISTER', 'USER_UPDATE', 'USER_DELETE', 'PASSWORD_CHANGE', 'PASSWORD_RESET', 'ORG_CREATE', 'ORG_UPDATE', 'ORG_DELETE', 'ORG_MEMBER_ADD', 'ORG_MEMBER_REMOVE', 'ORG_MEMBER_ROLE_CHANGE', 'SESSION_CREATE', 'SESSION_REVOKE', 'AUTH_METHOD_ADD', 'AUTH_METHOD_REMOVE', 'TOTP_ENROLL_INITIATED', 'TOTP_ENROLL_COMPLETED', 'TOTP_VERIFY_SUCCESS', 'TOTP_VERIFY_FAILED', 'TOTP_DISABLED', 'TOTP_BACKUP_CODE_USED', 'TOTP_BACKUP_CODES_REGENERATED', 'WEBAUTHN_REGISTER_INITIATED', 'WEBAUTHN_REGISTER_COMPLETED', 'WEBAUTHN_REGISTER_FAILED', 'WEBAUTHN_LOGIN_INITIATED', 'WEBAUTHN_LOGIN_SUCCESS', 'WEBAUTHN_LOGIN_FAILED', 'WEBAUTHN_CREDENTIAL_DELETED', 'WEBAUTHN_CREDENTIAL_RENAMED', 'ORG_SECURITY_POLICY_UPDATE', 'USER_SECURITY_POLICY_OVERRIDE_UPDATE', 'MFA_POLICY_USER_SUSPENDED', 'MFA_POLICY_USER_COMPLIANT', name='auditaction'),
existing_nullable=False)
op.drop_index(op.f('ix_oidc_jwks_keys_is_active'), table_name='oidc_jwks_keys')
op.add_column('sessions', sa.Column('is_compliance_only', sa.Boolean(), nullable=False))
with op.batch_alter_table('users', schema=None) as batch_op:
batch_op.alter_column('status',
existing_type=sa.VARCHAR(length=9),
type_=sa.Enum('ACTIVE', 'INACTIVE', 'SUSPENDED', 'PENDING', 'COMPLIANCE_SUSPENDED', name='userstatus'),
existing_nullable=False)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('users', schema=None) as batch_op:
batch_op.alter_column('status',
existing_type=sa.Enum('ACTIVE', 'INACTIVE', 'SUSPENDED', 'PENDING', 'COMPLIANCE_SUSPENDED', name='userstatus'),
type_=sa.VARCHAR(length=9),
existing_nullable=False)
op.drop_column('sessions', 'is_compliance_only')
op.create_index(op.f('ix_oidc_jwks_keys_is_active'), 'oidc_jwks_keys', ['is_active'], unique=False)
with op.batch_alter_table('audit_logs', schema=None) as batch_op:
batch_op.alter_column('action',
existing_type=sa.Enum('USER_LOGIN', 'USER_LOGOUT', 'USER_REGISTER', 'USER_UPDATE', 'USER_DELETE', 'PASSWORD_CHANGE', 'PASSWORD_RESET', 'ORG_CREATE', 'ORG_UPDATE', 'ORG_DELETE', 'ORG_MEMBER_ADD', 'ORG_MEMBER_REMOVE', 'ORG_MEMBER_ROLE_CHANGE', 'SESSION_CREATE', 'SESSION_REVOKE', 'AUTH_METHOD_ADD', 'AUTH_METHOD_REMOVE', 'TOTP_ENROLL_INITIATED', 'TOTP_ENROLL_COMPLETED', 'TOTP_VERIFY_SUCCESS', 'TOTP_VERIFY_FAILED', 'TOTP_DISABLED', 'TOTP_BACKUP_CODE_USED', 'TOTP_BACKUP_CODES_REGENERATED', 'WEBAUTHN_REGISTER_INITIATED', 'WEBAUTHN_REGISTER_COMPLETED', 'WEBAUTHN_REGISTER_FAILED', 'WEBAUTHN_LOGIN_INITIATED', 'WEBAUTHN_LOGIN_SUCCESS', 'WEBAUTHN_LOGIN_FAILED', 'WEBAUTHN_CREDENTIAL_DELETED', 'WEBAUTHN_CREDENTIAL_RENAMED', 'ORG_SECURITY_POLICY_UPDATE', 'USER_SECURITY_POLICY_OVERRIDE_UPDATE', 'MFA_POLICY_USER_SUSPENDED', 'MFA_POLICY_USER_COMPLIANT', name='auditaction'),
type_=sa.VARCHAR(length=22),
existing_nullable=False)
op.drop_index(op.f('ix_user_security_policies_user_id'), table_name='user_security_policies')
op.drop_index(op.f('ix_user_security_policies_organization_id'), table_name='user_security_policies')
op.drop_table('user_security_policies')
op.drop_index(op.f('ix_organization_security_policies_organization_id'), table_name='organization_security_policies')
op.drop_table('organization_security_policies')
op.drop_index(op.f('ix_mfa_policy_compliance_user_id'), table_name='mfa_policy_compliance')
op.drop_index(op.f('ix_mfa_policy_compliance_organization_id'), table_name='mfa_policy_compliance')
op.drop_table('mfa_policy_compliance')
# ### end Alembic commands ###