mirror of
https://github.com/danswer-ai/danswer.git
synced 2025-06-20 13:01:34 +02:00
Lowercase multi tenant email mapping (#4141)
This commit is contained in:
parent
aaced6d551
commit
a7ba0da8cc
@ -0,0 +1,36 @@
|
|||||||
|
"""force lowercase all users
|
||||||
|
|
||||||
|
Revision ID: f11b408e39d3
|
||||||
|
Revises: 3bd4c84fe72f
|
||||||
|
Create Date: 2025-02-26 17:04:55.683500
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = "f11b408e39d3"
|
||||||
|
down_revision = "3bd4c84fe72f"
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
# 1) Convert all existing user emails to lowercase
|
||||||
|
from alembic import op
|
||||||
|
|
||||||
|
op.execute(
|
||||||
|
"""
|
||||||
|
UPDATE "user"
|
||||||
|
SET email = LOWER(email)
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
# 2) Add a check constraint to ensure emails are always lowercase
|
||||||
|
op.create_check_constraint("ensure_lowercase_email", "user", "email = LOWER(email)")
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
# Drop the check constraint
|
||||||
|
from alembic import op
|
||||||
|
|
||||||
|
op.drop_constraint("ensure_lowercase_email", "user", type_="check")
|
@ -0,0 +1,42 @@
|
|||||||
|
"""lowercase multi-tenant user auth
|
||||||
|
|
||||||
|
Revision ID: 34e3630c7f32
|
||||||
|
Revises: a4f6ee863c47
|
||||||
|
Create Date: 2025-02-26 15:03:01.211894
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = "34e3630c7f32"
|
||||||
|
down_revision = "a4f6ee863c47"
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
# 1) Convert all existing rows to lowercase
|
||||||
|
op.execute(
|
||||||
|
"""
|
||||||
|
UPDATE user_tenant_mapping
|
||||||
|
SET email = LOWER(email)
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
# 2) Add a check constraint so that emails cannot be written in uppercase
|
||||||
|
op.create_check_constraint(
|
||||||
|
"ensure_lowercase_email",
|
||||||
|
"user_tenant_mapping",
|
||||||
|
"email = LOWER(email)",
|
||||||
|
schema="public",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
# Drop the check constraint
|
||||||
|
op.drop_constraint(
|
||||||
|
"ensure_lowercase_email",
|
||||||
|
"user_tenant_mapping",
|
||||||
|
schema="public",
|
||||||
|
type_="check",
|
||||||
|
)
|
@ -7,6 +7,7 @@ from typing import Optional
|
|||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
from sqlalchemy.orm import validates
|
||||||
from typing_extensions import TypedDict # noreorder
|
from typing_extensions import TypedDict # noreorder
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
@ -206,6 +207,10 @@ class User(SQLAlchemyBaseUserTableUUID, Base):
|
|||||||
primaryjoin="User.id == foreign(ConnectorCredentialPair.creator_id)",
|
primaryjoin="User.id == foreign(ConnectorCredentialPair.creator_id)",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@validates("email")
|
||||||
|
def validate_email(self, key: str, value: str) -> str:
|
||||||
|
return value.lower() if value else value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def password_configured(self) -> bool:
|
def password_configured(self) -> bool:
|
||||||
"""
|
"""
|
||||||
@ -2270,6 +2275,10 @@ class UserTenantMapping(Base):
|
|||||||
email: Mapped[str] = mapped_column(String, nullable=False, primary_key=True)
|
email: Mapped[str] = mapped_column(String, nullable=False, primary_key=True)
|
||||||
tenant_id: Mapped[str] = mapped_column(String, nullable=False)
|
tenant_id: Mapped[str] = mapped_column(String, nullable=False)
|
||||||
|
|
||||||
|
@validates("email")
|
||||||
|
def validate_email(self, key: str, value: str) -> str:
|
||||||
|
return value.lower() if value else value
|
||||||
|
|
||||||
|
|
||||||
# This is a mapping from tenant IDs to anonymous user paths
|
# This is a mapping from tenant IDs to anonymous user paths
|
||||||
class TenantAnonymousUserPath(Base):
|
class TenantAnonymousUserPath(Base):
|
||||||
|
@ -36,11 +36,14 @@ export function EmailPasswordForm({
|
|||||||
{popup}
|
{popup}
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={{
|
initialValues={{
|
||||||
email: defaultEmail || "",
|
email: defaultEmail ? defaultEmail.toLowerCase() : "",
|
||||||
password: "",
|
password: "",
|
||||||
}}
|
}}
|
||||||
validationSchema={Yup.object().shape({
|
validationSchema={Yup.object().shape({
|
||||||
email: Yup.string().email().required(),
|
email: Yup.string()
|
||||||
|
.email()
|
||||||
|
.required()
|
||||||
|
.transform((value) => value.toLowerCase()),
|
||||||
password: Yup.string().required(),
|
password: Yup.string().required(),
|
||||||
})}
|
})}
|
||||||
onSubmit={async (values) => {
|
onSubmit={async (values) => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user