mirror of
https://github.com/simple-login/app.git
synced 2024-11-10 21:27:10 +01:00
chore: QOL improvements on alias delete due to cascade FKs (#2144)
This commit is contained in:
parent
2d841e9bc0
commit
f05f01bf77
@ -34,6 +34,7 @@ from app.events.generated.event_pb2 import (
|
||||
from app.log import LOG
|
||||
from app.models import (
|
||||
Alias,
|
||||
AliasDeleteReason,
|
||||
CustomDomain,
|
||||
Directory,
|
||||
User,
|
||||
@ -309,7 +310,9 @@ def try_auto_create_via_domain(address: str) -> Optional[Alias]:
|
||||
return None
|
||||
|
||||
|
||||
def delete_alias(alias: Alias, user: User):
|
||||
def delete_alias(
|
||||
alias: Alias, user: User, reason: AliasDeleteReason = AliasDeleteReason.Unspecified
|
||||
):
|
||||
"""
|
||||
Delete an alias and add it to either global or domain trash
|
||||
Should be used instead of Alias.delete, DomainDeletedAlias.create, DeletedAlias.create
|
||||
@ -324,6 +327,7 @@ def delete_alias(alias: Alias, user: User):
|
||||
user_id=user.id,
|
||||
email=alias.email,
|
||||
domain_id=alias.custom_domain_id,
|
||||
reason=reason,
|
||||
)
|
||||
Session.add(domain_deleted_alias)
|
||||
Session.commit()
|
||||
@ -332,7 +336,7 @@ def delete_alias(alias: Alias, user: User):
|
||||
)
|
||||
else:
|
||||
if not DeletedAlias.get_by(email=alias.email):
|
||||
deleted_alias = DeletedAlias(email=alias.email)
|
||||
deleted_alias = DeletedAlias(email=alias.email, reason=reason)
|
||||
Session.add(deleted_alias)
|
||||
Session.commit()
|
||||
LOG.i(f"Moving {alias} to global trash {deleted_alias}")
|
||||
|
@ -26,7 +26,7 @@ from app.errors import (
|
||||
)
|
||||
from app.extensions import limiter
|
||||
from app.log import LOG
|
||||
from app.models import Alias, Contact, Mailbox, AliasMailbox
|
||||
from app.models import Alias, Contact, Mailbox, AliasMailbox, AliasDeleteReason
|
||||
|
||||
|
||||
@deprecated
|
||||
@ -161,7 +161,7 @@ def delete_alias(alias_id):
|
||||
if not alias or alias.user_id != user.id:
|
||||
return jsonify(error="Forbidden"), 403
|
||||
|
||||
alias_utils.delete_alias(alias, user)
|
||||
alias_utils.delete_alias(alias, user, AliasDeleteReason.ManualAction)
|
||||
|
||||
return jsonify(deleted=True), 200
|
||||
|
||||
|
@ -12,6 +12,7 @@ from app.extensions import limiter
|
||||
from app.log import LOG
|
||||
from app.models import (
|
||||
Alias,
|
||||
AliasDeleteReason,
|
||||
AliasGeneratorEnum,
|
||||
User,
|
||||
EmailLog,
|
||||
@ -143,7 +144,9 @@ def index():
|
||||
if request.form.get("form-name") == "delete-alias":
|
||||
LOG.i(f"User {current_user} requested deletion of alias {alias}")
|
||||
email = alias.email
|
||||
alias_utils.delete_alias(alias, current_user)
|
||||
alias_utils.delete_alias(
|
||||
alias, current_user, AliasDeleteReason.ManualAction
|
||||
)
|
||||
flash(f"Alias {email} has been deleted", "success")
|
||||
elif request.form.get("form-name") == "disable-alias":
|
||||
alias_utils.change_alias_status(alias, enabled=False)
|
||||
|
@ -263,6 +263,15 @@ class UnsubscribeBehaviourEnum(EnumE):
|
||||
PreserveOriginal = 2
|
||||
|
||||
|
||||
class AliasDeleteReason(EnumE):
|
||||
Unspecified = 0
|
||||
UserHasBeenDeleted = 1
|
||||
ManualAction = 2
|
||||
DirectoryDeleted = 3
|
||||
MailboxDeleted = 4
|
||||
CustomDomainDeleted = 5
|
||||
|
||||
|
||||
class IntEnumType(sa.types.TypeDecorator):
|
||||
impl = sa.Integer
|
||||
|
||||
@ -667,6 +676,12 @@ class User(Base, ModelMixin, UserMixin, PasswordOracle):
|
||||
user: User = cls.get(obj_id)
|
||||
EventDispatcher.send_event(user, EventContent(user_deleted=UserDeleted()))
|
||||
|
||||
# Manually delete all aliases for the user that is about to be deleted
|
||||
from app.alias_utils import delete_alias
|
||||
|
||||
for alias in Alias.filter_by(user_id=user.id):
|
||||
delete_alias(alias, user, AliasDeleteReason.UserHasBeenDeleted)
|
||||
|
||||
res = super(User, cls).delete(obj_id)
|
||||
if commit:
|
||||
Session.commit()
|
||||
@ -2261,6 +2276,12 @@ class DeletedAlias(Base, ModelMixin):
|
||||
__tablename__ = "deleted_alias"
|
||||
|
||||
email = sa.Column(sa.String(256), unique=True, nullable=False)
|
||||
reason = sa.Column(
|
||||
IntEnumType(AliasDeleteReason),
|
||||
nullable=False,
|
||||
default=AliasDeleteReason.Unspecified,
|
||||
server_default=str(AliasDeleteReason.Unspecified.value),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def create(cls, **kw):
|
||||
@ -2448,6 +2469,13 @@ class CustomDomain(Base, ModelMixin):
|
||||
if obj.is_sl_subdomain:
|
||||
DeletedSubdomain.create(domain=obj.domain)
|
||||
|
||||
from app import alias_utils
|
||||
|
||||
for alias in Alias.filter_by(custom_domain_id=obj_id):
|
||||
alias_utils.delete_alias(
|
||||
alias, obj.user, AliasDeleteReason.CustomDomainDeleted
|
||||
)
|
||||
|
||||
return super(CustomDomain, cls).delete(obj_id)
|
||||
|
||||
@property
|
||||
@ -2520,6 +2548,12 @@ class DomainDeletedAlias(Base, ModelMixin):
|
||||
|
||||
domain = orm.relationship(CustomDomain)
|
||||
user = orm.relationship(User, foreign_keys=[user_id])
|
||||
reason = sa.Column(
|
||||
IntEnumType(AliasDeleteReason),
|
||||
nullable=False,
|
||||
default=AliasDeleteReason.Unspecified,
|
||||
server_default=str(AliasDeleteReason.Unspecified.value),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def create(cls, **kw):
|
||||
@ -2611,7 +2645,7 @@ class Directory(Base, ModelMixin):
|
||||
for alias in Alias.filter_by(directory_id=obj_id):
|
||||
from app import alias_utils
|
||||
|
||||
alias_utils.delete_alias(alias, user)
|
||||
alias_utils.delete_alias(alias, user, AliasDeleteReason.DirectoryDeleted)
|
||||
|
||||
DeletedDirectory.create(name=obj.name)
|
||||
cls.filter(cls.id == obj_id).delete()
|
||||
@ -2739,7 +2773,7 @@ class Mailbox(Base, ModelMixin):
|
||||
from app import alias_utils
|
||||
|
||||
# only put aliases that have mailbox as a single mailbox into trash
|
||||
alias_utils.delete_alias(alias, user)
|
||||
alias_utils.delete_alias(alias, user, AliasDeleteReason.MailboxDeleted)
|
||||
Session.commit()
|
||||
|
||||
cls.filter(cls.id == obj_id).delete()
|
||||
|
31
migrations/versions/2024_070516_d608b8e48082_.py
Normal file
31
migrations/versions/2024_070516_d608b8e48082_.py
Normal file
@ -0,0 +1,31 @@
|
||||
"""empty message
|
||||
|
||||
Revision ID: d608b8e48082
|
||||
Revises: 06a9a7133445
|
||||
Create Date: 2024-07-05 16:56:04.220173
|
||||
|
||||
"""
|
||||
import sqlalchemy_utils
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'd608b8e48082'
|
||||
down_revision = '06a9a7133445'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('deleted_alias', sa.Column('reason', sa.Integer(), default=0, server_default='0', nullable=False))
|
||||
op.add_column('domain_deleted_alias', sa.Column('reason', sa.Integer(), default=0, server_default='0', nullable=False))
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('domain_deleted_alias', 'reason')
|
||||
op.drop_column('deleted_alias', 'reason')
|
||||
# ### end Alembic commands ###
|
Loading…
Reference in New Issue
Block a user