From 1237e42906779c8376f84bde1d37868daa98f600 Mon Sep 17 00:00:00 2001 From: Eric Hare Date: Thu, 14 May 2026 11:51:23 -0700 Subject: [PATCH] chore: Consolidate migrations into a single file --- .../c5d6e7f8g9h0_add_rbac_plugin_tables.py | 171 ++++++++++++------ ..._rename_rbac_tables_and_add_new_columns.py | 144 --------------- 2 files changed, 113 insertions(+), 202 deletions(-) delete mode 100644 src/backend/base/langflow/alembic/versions/e2c8539167b1_rename_rbac_tables_and_add_new_columns.py diff --git a/src/backend/base/langflow/alembic/versions/c5d6e7f8g9h0_add_rbac_plugin_tables.py b/src/backend/base/langflow/alembic/versions/c5d6e7f8g9h0_add_rbac_plugin_tables.py index 27c6d16568..bfe3b770ac 100644 --- a/src/backend/base/langflow/alembic/versions/c5d6e7f8g9h0_add_rbac_plugin_tables.py +++ b/src/backend/base/langflow/alembic/versions/c5d6e7f8g9h0_add_rbac_plugin_tables.py @@ -1,4 +1,4 @@ -"""add RBAC plugin tables role, user_role, resource_permission, audit_log +"""add RBAC plugin tables rbac_role, rbac_user_role, rbac_resource_permission, rbac_audit_log Revision ID: c5d6e7f8g9h0 Revises: mb01b2c3d4e5 @@ -23,46 +23,77 @@ depends_on: str | Sequence[str] | None = None def upgrade() -> None: conn = op.get_bind() - if not migration.table_exists("role", conn): + if not migration.table_exists("rbac_role", conn): op.create_table( - "role", + "rbac_role", sa.Column("id", sa.Uuid(), nullable=False), sa.Column("name", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("description", sqlmodel.sql.sqltypes.AutoString(), nullable=True), sa.Column("is_system", sa.Boolean(), nullable=False), sa.Column("permissions", sa.JSON(), nullable=False), # Stores list[str] + sa.Column("parent_role_id", sa.Uuid(), nullable=True), + sa.Column("workspace_id", sa.Uuid(), nullable=True), sa.Column("created_at", sa.DateTime(), nullable=False), sa.Column("updated_at", sa.DateTime(), nullable=False), + sa.Column("created_by", sa.Uuid(), nullable=True), + sa.ForeignKeyConstraint( + ["parent_role_id"], + ["rbac_role.id"], + name="fk_rbac_role_parent_role_id_rbac_role", + ondelete="SET NULL", + ), + sa.ForeignKeyConstraint( + ["created_by"], + ["user.id"], + name="fk_rbac_role_created_by_user", + ondelete="SET NULL", + ), sa.PrimaryKeyConstraint("id"), ) - with op.batch_alter_table("role", schema=None) as batch_op: - batch_op.create_index(batch_op.f("ix_role_name"), ["name"], unique=True) + with op.batch_alter_table("rbac_role", schema=None) as batch_op: + batch_op.create_index(batch_op.f("ix_rbac_role_name"), ["name"], unique=True) + batch_op.create_index("ix_rbac_role_workspace_id", ["workspace_id"], unique=False) - if not migration.table_exists("user_role", conn): + if not migration.table_exists("rbac_user_role", conn): op.create_table( - "user_role", + "rbac_user_role", sa.Column("id", sa.Uuid(), nullable=False), sa.Column("user_id", sa.Uuid(), nullable=False), sa.Column("role_id", sa.Uuid(), nullable=False), sa.Column("assigned_at", sa.DateTime(), nullable=False), sa.Column("assigned_by", sa.Uuid(), nullable=True), - sa.ForeignKeyConstraint(["user_id"], ["user.id"], ondelete="CASCADE"), - sa.ForeignKeyConstraint(["role_id"], ["role.id"], ondelete="CASCADE"), - sa.ForeignKeyConstraint(["assigned_by"], ["user.id"], ondelete="SET NULL"), + sa.ForeignKeyConstraint( + ["user_id"], + ["user.id"], + name="fk_rbac_user_role_user_id_user", + ondelete="CASCADE", + ), + sa.ForeignKeyConstraint( + ["role_id"], + ["rbac_role.id"], + name="fk_rbac_user_role_role_id_rbac_role", + ondelete="CASCADE", + ), + sa.ForeignKeyConstraint( + ["assigned_by"], + ["user.id"], + name="fk_rbac_user_role_assigned_by_user", + ondelete="SET NULL", + ), sa.PrimaryKeyConstraint("id"), ) - with op.batch_alter_table("user_role", schema=None) as batch_op: - batch_op.create_index(batch_op.f("ix_user_role_user_id"), ["user_id"], unique=False) - batch_op.create_index(batch_op.f("ix_user_role_role_id"), ["role_id"], unique=False) + with op.batch_alter_table("rbac_user_role", schema=None) as batch_op: + batch_op.create_index(batch_op.f("ix_rbac_user_role_user_id"), ["user_id"], unique=False) + batch_op.create_index(batch_op.f("ix_rbac_user_role_role_id"), ["role_id"], unique=False) batch_op.create_index( - batch_op.f("uq_user_role_user_role"), + "uq_rbac_user_role_user_role", ["user_id", "role_id"], unique=True, ) - if not migration.table_exists("resource_permission", conn): + if not migration.table_exists("rbac_resource_permission", conn): op.create_table( - "resource_permission", + "rbac_resource_permission", sa.Column("id", sa.Uuid(), nullable=False), sa.Column("user_id", sa.Uuid(), nullable=False), sa.Column("resource_type", sqlmodel.sql.sqltypes.AutoString(), nullable=False), @@ -70,23 +101,41 @@ def upgrade() -> None: sa.Column("permission", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("granted_at", sa.DateTime(), nullable=False), sa.Column("granted_by", sa.Uuid(), nullable=True), - sa.ForeignKeyConstraint(["user_id"], ["user.id"], ondelete="CASCADE"), - sa.ForeignKeyConstraint(["granted_by"], ["user.id"], ondelete="SET NULL"), + sa.ForeignKeyConstraint( + ["user_id"], + ["user.id"], + name="fk_rbac_resource_permission_user_id_user", + ondelete="CASCADE", + ), + sa.ForeignKeyConstraint( + ["granted_by"], + ["user.id"], + name="fk_rbac_resource_permission_granted_by_user", + ondelete="SET NULL", + ), sa.PrimaryKeyConstraint("id"), ) - with op.batch_alter_table("resource_permission", schema=None) as batch_op: - batch_op.create_index(batch_op.f("ix_resource_permission_user_id"), ["user_id"], unique=False) - batch_op.create_index(batch_op.f("ix_resource_permission_resource_type"), ["resource_type"], unique=False) - batch_op.create_index(batch_op.f("ix_resource_permission_resource_id"), ["resource_id"], unique=False) + with op.batch_alter_table("rbac_resource_permission", schema=None) as batch_op: + batch_op.create_index(batch_op.f("ix_rbac_resource_permission_user_id"), ["user_id"], unique=False) batch_op.create_index( - batch_op.f("ix_resource_permission_user_resource"), - ["user_id", "resource_type", "resource_id"], + batch_op.f("ix_rbac_resource_permission_resource_type"), + ["resource_type"], unique=False, ) + batch_op.create_index( + batch_op.f("ix_rbac_resource_permission_resource_id"), + ["resource_id"], + unique=False, + ) + batch_op.create_index( + "uq_rbac_resource_permission_user_resource_perm", + ["user_id", "resource_type", "resource_id", "permission"], + unique=True, + ) - if not migration.table_exists("audit_log", conn): + if not migration.table_exists("rbac_audit_log", conn): op.create_table( - "audit_log", + "rbac_audit_log", sa.Column("id", sa.Uuid(), nullable=False), sa.Column("user_id", sa.Uuid(), nullable=True), sa.Column("action", sqlmodel.sql.sqltypes.AutoString(), nullable=False), @@ -95,20 +144,25 @@ def upgrade() -> None: sa.Column("result", sqlmodel.sql.sqltypes.AutoString(), nullable=False), sa.Column("details", sa.JSON(), nullable=True), sa.Column("timestamp", sa.DateTime(), nullable=False), - sa.ForeignKeyConstraint(["user_id"], ["user.id"], ondelete="SET NULL"), + sa.ForeignKeyConstraint( + ["user_id"], + ["user.id"], + name="fk_rbac_audit_log_user_id_user", + ondelete="SET NULL", + ), sa.PrimaryKeyConstraint("id"), ) - with op.batch_alter_table("audit_log", schema=None) as batch_op: - batch_op.create_index(batch_op.f("ix_audit_log_user_id"), ["user_id"], unique=False) - batch_op.create_index(batch_op.f("ix_audit_log_action"), ["action"], unique=False) - batch_op.create_index(batch_op.f("ix_audit_log_timestamp"), ["timestamp"], unique=False) + with op.batch_alter_table("rbac_audit_log", schema=None) as batch_op: + batch_op.create_index(batch_op.f("ix_rbac_audit_log_user_id"), ["user_id"], unique=False) + batch_op.create_index(batch_op.f("ix_rbac_audit_log_action"), ["action"], unique=False) + batch_op.create_index(batch_op.f("ix_rbac_audit_log_timestamp"), ["timestamp"], unique=False) batch_op.create_index( - batch_op.f("ix_audit_log_user_timestamp"), + "ix_rbac_audit_log_user_timestamp", ["user_id", "timestamp"], unique=False, ) batch_op.create_index( - batch_op.f("ix_audit_log_resource"), + "ix_rbac_audit_log_resource", ["resource_type", "resource_id"], unique=False, ) @@ -117,31 +171,32 @@ def upgrade() -> None: def downgrade() -> None: conn = op.get_bind() - if migration.table_exists("audit_log", conn): - with op.batch_alter_table("audit_log", schema=None) as batch_op: - batch_op.drop_index(batch_op.f("ix_audit_log_resource")) - batch_op.drop_index(batch_op.f("ix_audit_log_user_timestamp")) - batch_op.drop_index(batch_op.f("ix_audit_log_timestamp")) - batch_op.drop_index(batch_op.f("ix_audit_log_action")) - batch_op.drop_index(batch_op.f("ix_audit_log_user_id")) - op.drop_table("audit_log") + if migration.table_exists("rbac_audit_log", conn): + with op.batch_alter_table("rbac_audit_log", schema=None) as batch_op: + batch_op.drop_index("ix_rbac_audit_log_resource") + batch_op.drop_index("ix_rbac_audit_log_user_timestamp") + batch_op.drop_index(batch_op.f("ix_rbac_audit_log_timestamp")) + batch_op.drop_index(batch_op.f("ix_rbac_audit_log_action")) + batch_op.drop_index(batch_op.f("ix_rbac_audit_log_user_id")) + op.drop_table("rbac_audit_log") - if migration.table_exists("resource_permission", conn): - with op.batch_alter_table("resource_permission", schema=None) as batch_op: - batch_op.drop_index(batch_op.f("ix_resource_permission_user_resource")) - batch_op.drop_index(batch_op.f("ix_resource_permission_resource_id")) - batch_op.drop_index(batch_op.f("ix_resource_permission_resource_type")) - batch_op.drop_index(batch_op.f("ix_resource_permission_user_id")) - op.drop_table("resource_permission") + if migration.table_exists("rbac_resource_permission", conn): + with op.batch_alter_table("rbac_resource_permission", schema=None) as batch_op: + batch_op.drop_index("uq_rbac_resource_permission_user_resource_perm") + batch_op.drop_index(batch_op.f("ix_rbac_resource_permission_resource_id")) + batch_op.drop_index(batch_op.f("ix_rbac_resource_permission_resource_type")) + batch_op.drop_index(batch_op.f("ix_rbac_resource_permission_user_id")) + op.drop_table("rbac_resource_permission") - if migration.table_exists("user_role", conn): - with op.batch_alter_table("user_role", schema=None) as batch_op: - batch_op.drop_index(batch_op.f("uq_user_role_user_role")) - batch_op.drop_index(batch_op.f("ix_user_role_role_id")) - batch_op.drop_index(batch_op.f("ix_user_role_user_id")) - op.drop_table("user_role") + if migration.table_exists("rbac_user_role", conn): + with op.batch_alter_table("rbac_user_role", schema=None) as batch_op: + batch_op.drop_index("uq_rbac_user_role_user_role") + batch_op.drop_index(batch_op.f("ix_rbac_user_role_role_id")) + batch_op.drop_index(batch_op.f("ix_rbac_user_role_user_id")) + op.drop_table("rbac_user_role") - if migration.table_exists("role", conn): - with op.batch_alter_table("role", schema=None) as batch_op: - batch_op.drop_index(batch_op.f("ix_role_name")) - op.drop_table("role") + if migration.table_exists("rbac_role", conn): + with op.batch_alter_table("rbac_role", schema=None) as batch_op: + batch_op.drop_index("ix_rbac_role_workspace_id") + batch_op.drop_index(batch_op.f("ix_rbac_role_name")) + op.drop_table("rbac_role") diff --git a/src/backend/base/langflow/alembic/versions/e2c8539167b1_rename_rbac_tables_and_add_new_columns.py b/src/backend/base/langflow/alembic/versions/e2c8539167b1_rename_rbac_tables_and_add_new_columns.py deleted file mode 100644 index f4df361da0..0000000000 --- a/src/backend/base/langflow/alembic/versions/e2c8539167b1_rename_rbac_tables_and_add_new_columns.py +++ /dev/null @@ -1,144 +0,0 @@ -"""rename rbac tables and add new columns - -Revision ID: e2c8539167b1 -Revises: c5d6e7f8g9h0 -Create Date: 2026-05-14 11:37:32.663086 - -""" -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa -import sqlmodel -from langflow.utils import migration - -# revision identifiers, used by Alembic. -revision: str = 'e2c8539167b1' -down_revision: Union[str, None] = 'c5d6e7f8g9h0' -branch_labels: Union[str, Sequence[str], None] = None -depends_on: Union[str, Sequence[str], None] = None - - -def upgrade() -> None: - conn = op.get_bind() - - # Rename tables (preserves data) - if migration.table_exists("role", conn): - op.rename_table("role", "rbac_role") - - if migration.table_exists("user_role", conn): - op.rename_table("user_role", "rbac_user_role") - - if migration.table_exists("resource_permission", conn): - op.rename_table("resource_permission", "rbac_resource_permission") - - if migration.table_exists("audit_log", conn): - op.rename_table("audit_log", "rbac_audit_log") - - # Add new columns to rbac_role - if migration.table_exists("rbac_role", conn): - with op.batch_alter_table("rbac_role", schema=None) as batch_op: - # Add parent_role_id for role inheritance - batch_op.add_column(sa.Column("parent_role_id", sa.Uuid(), nullable=True)) - batch_op.create_foreign_key( - "fk_rbac_role_parent_role_id_rbac_role", - "rbac_role", - ["parent_role_id"], - ["id"], - ondelete="SET NULL" - ) - - # Add workspace_id for future workspace isolation - batch_op.add_column(sa.Column("workspace_id", sa.Uuid(), nullable=True)) - batch_op.create_index("ix_rbac_role_workspace_id", ["workspace_id"], unique=False) - - # Add created_by for audit trail - batch_op.add_column(sa.Column("created_by", sa.Uuid(), nullable=True)) - batch_op.create_foreign_key( - "fk_rbac_role_created_by_user", - "user", - ["created_by"], - ["id"], - ondelete="SET NULL" - ) - - # Update rbac_resource_permission: change index to unique constraint - if migration.table_exists("rbac_resource_permission", conn): - with op.batch_alter_table("rbac_resource_permission", schema=None) as batch_op: - # Drop old non-unique index - batch_op.drop_index("ix_resource_permission_user_resource") - - # Create new unique index - batch_op.create_index( - "uq_rbac_resource_permission_user_resource_perm", - ["user_id", "resource_type", "resource_id", "permission"], - unique=True - ) - - # Update foreign key references in rbac_user_role - if migration.table_exists("rbac_user_role", conn): - with op.batch_alter_table("rbac_user_role", schema=None) as batch_op: - # Drop old foreign key to role table - batch_op.drop_constraint("fk_user_role_role_id_role", type_="foreignkey") - - # Create new foreign key to rbac_role table - batch_op.create_foreign_key( - "fk_rbac_user_role_role_id_rbac_role", - "rbac_role", - ["role_id"], - ["id"], - ondelete="CASCADE" - ) - - -def downgrade() -> None: - conn = op.get_bind() - - # Remove new columns from rbac_role - if migration.table_exists("rbac_role", conn): - with op.batch_alter_table("rbac_role", schema=None) as batch_op: - batch_op.drop_constraint("fk_rbac_role_created_by_user", type_="foreignkey") - batch_op.drop_column("created_by") - - batch_op.drop_index("ix_rbac_role_workspace_id") - batch_op.drop_column("workspace_id") - - batch_op.drop_constraint("fk_rbac_role_parent_role_id_rbac_role", type_="foreignkey") - batch_op.drop_column("parent_role_id") - - # Revert rbac_resource_permission index changes - if migration.table_exists("rbac_resource_permission", conn): - with op.batch_alter_table("rbac_resource_permission", schema=None) as batch_op: - batch_op.drop_index("uq_rbac_resource_permission_user_resource_perm") - batch_op.create_index( - "ix_resource_permission_user_resource", - ["user_id", "resource_type", "resource_id"], - unique=False - ) - - # Revert foreign key in rbac_user_role - if migration.table_exists("rbac_user_role", conn): - with op.batch_alter_table("rbac_user_role", schema=None) as batch_op: - batch_op.drop_constraint("fk_rbac_user_role_role_id_rbac_role", type_="foreignkey") - batch_op.create_foreign_key( - "fk_user_role_role_id_role", - "role", - ["role_id"], - ["id"], - ondelete="CASCADE" - ) - - # Rename tables back - if migration.table_exists("rbac_audit_log", conn): - op.rename_table("rbac_audit_log", "audit_log") - - if migration.table_exists("rbac_resource_permission", conn): - op.rename_table("rbac_resource_permission", "resource_permission") - - if migration.table_exists("rbac_user_role", conn): - op.rename_table("rbac_user_role", "user_role") - - if migration.table_exists("rbac_role", conn): - op.rename_table("rbac_role", "role") - -# Made with Bob