make sure a deleted directory can't be recreated
This commit is contained in:
parent
482aa8614c
commit
417f7b92b0
|
@ -11,6 +11,7 @@ from app.config import (
|
||||||
)
|
)
|
||||||
from app.dashboard.base import dashboard_bp
|
from app.dashboard.base import dashboard_bp
|
||||||
from app.db import Session
|
from app.db import Session
|
||||||
|
from app.errors import DirectoryInTrashError
|
||||||
from app.models import Directory, Mailbox, DirectoryMailbox
|
from app.models import Directory, Mailbox, DirectoryMailbox
|
||||||
|
|
||||||
|
|
||||||
|
@ -138,33 +139,42 @@ def directory():
|
||||||
"warning",
|
"warning",
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
new_dir = Directory.create(
|
try:
|
||||||
name=new_dir_name, user_id=current_user.id
|
new_dir = Directory.create(
|
||||||
)
|
name=new_dir_name, user_id=current_user.id
|
||||||
Session.commit()
|
)
|
||||||
mailbox_ids = request.form.getlist("mailbox_ids")
|
except DirectoryInTrashError:
|
||||||
if mailbox_ids:
|
flash(
|
||||||
# check if mailbox is not tempered with
|
f"{new_dir_name} has been used before and cannot be reused",
|
||||||
mailboxes = []
|
"error",
|
||||||
for mailbox_id in mailbox_ids:
|
)
|
||||||
mailbox = Mailbox.get(mailbox_id)
|
else:
|
||||||
if (
|
|
||||||
not mailbox
|
|
||||||
or mailbox.user_id != current_user.id
|
|
||||||
or not mailbox.verified
|
|
||||||
):
|
|
||||||
flash("Something went wrong, please retry", "warning")
|
|
||||||
return redirect(url_for("dashboard.directory"))
|
|
||||||
mailboxes.append(mailbox)
|
|
||||||
|
|
||||||
for mailbox in mailboxes:
|
|
||||||
DirectoryMailbox.create(
|
|
||||||
directory_id=new_dir.id, mailbox_id=mailbox.id
|
|
||||||
)
|
|
||||||
|
|
||||||
Session.commit()
|
Session.commit()
|
||||||
|
mailbox_ids = request.form.getlist("mailbox_ids")
|
||||||
|
if mailbox_ids:
|
||||||
|
# check if mailbox is not tempered with
|
||||||
|
mailboxes = []
|
||||||
|
for mailbox_id in mailbox_ids:
|
||||||
|
mailbox = Mailbox.get(mailbox_id)
|
||||||
|
if (
|
||||||
|
not mailbox
|
||||||
|
or mailbox.user_id != current_user.id
|
||||||
|
or not mailbox.verified
|
||||||
|
):
|
||||||
|
flash(
|
||||||
|
"Something went wrong, please retry", "warning"
|
||||||
|
)
|
||||||
|
return redirect(url_for("dashboard.directory"))
|
||||||
|
mailboxes.append(mailbox)
|
||||||
|
|
||||||
flash(f"Directory {new_dir.name} is created", "success")
|
for mailbox in mailboxes:
|
||||||
|
DirectoryMailbox.create(
|
||||||
|
directory_id=new_dir.id, mailbox_id=mailbox.id
|
||||||
|
)
|
||||||
|
|
||||||
|
Session.commit()
|
||||||
|
|
||||||
|
flash(f"Directory {new_dir.name} is created", "success")
|
||||||
|
|
||||||
return redirect(url_for("dashboard.directory"))
|
return redirect(url_for("dashboard.directory"))
|
||||||
|
|
||||||
|
|
|
@ -2,3 +2,9 @@ class AliasInTrashError(Exception):
|
||||||
"""raised when alias is deleted before """
|
"""raised when alias is deleted before """
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class DirectoryInTrashError(Exception):
|
||||||
|
"""raised when a directory is deleted before """
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
|
@ -32,7 +32,7 @@ from app.config import (
|
||||||
ALIAS_RANDOM_SUFFIX_LENGTH,
|
ALIAS_RANDOM_SUFFIX_LENGTH,
|
||||||
)
|
)
|
||||||
from app.db import Session
|
from app.db import Session
|
||||||
from app.errors import AliasInTrashError
|
from app.errors import AliasInTrashError, DirectoryInTrashError
|
||||||
from app.log import LOG
|
from app.log import LOG
|
||||||
from app.oauth_models import Scope
|
from app.oauth_models import Scope
|
||||||
from app.pw_models import PasswordOracle
|
from app.pw_models import PasswordOracle
|
||||||
|
@ -2123,6 +2123,14 @@ class Directory(Base, ModelMixin):
|
||||||
def nb_alias(self):
|
def nb_alias(self):
|
||||||
return Alias.filter_by(directory_id=self.id).count()
|
return Alias.filter_by(directory_id=self.id).count()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(cls, *args, **kwargs):
|
||||||
|
name = kwargs.get("name")
|
||||||
|
if DeletedDirectory.get_by(name=name):
|
||||||
|
raise DirectoryInTrashError
|
||||||
|
|
||||||
|
return super(Directory, cls).create(*args, **kwargs)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def delete(cls, obj_id):
|
def delete(cls, obj_id):
|
||||||
obj: Directory = cls.get(obj_id)
|
obj: Directory = cls.get(obj_id)
|
||||||
|
@ -2133,6 +2141,7 @@ class Directory(Base, ModelMixin):
|
||||||
|
|
||||||
alias_utils.delete_alias(alias, user)
|
alias_utils.delete_alias(alias, user)
|
||||||
|
|
||||||
|
DeletedDirectory.create(name=obj.name)
|
||||||
cls.filter(cls.id == obj_id).delete()
|
cls.filter(cls.id == obj_id).delete()
|
||||||
Session.commit()
|
Session.commit()
|
||||||
|
|
||||||
|
|
58
tests/dashboard/test_directory.py
Normal file
58
tests/dashboard/test_directory.py
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
from flask import url_for
|
||||||
|
|
||||||
|
from app.models import Directory
|
||||||
|
from tests.utils import login
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_directory(flask_client):
|
||||||
|
login(flask_client)
|
||||||
|
|
||||||
|
r = flask_client.post(
|
||||||
|
url_for("dashboard.directory"),
|
||||||
|
data={"form-name": "create", "name": "test"},
|
||||||
|
follow_redirects=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert f"Directory test is created" in r.data.decode()
|
||||||
|
assert Directory.get_by(name="test") is not None
|
||||||
|
|
||||||
|
|
||||||
|
def test_delete_directory(flask_client):
|
||||||
|
"""cannot add domain if user personal email uses this domain"""
|
||||||
|
user = login(flask_client)
|
||||||
|
directory = Directory.create(name="test", user_id=user.id, commit=True)
|
||||||
|
|
||||||
|
r = flask_client.post(
|
||||||
|
url_for("dashboard.directory"),
|
||||||
|
data={"form-name": "delete", "dir-id": directory.id},
|
||||||
|
follow_redirects=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert f"Directory test has been deleted" in r.data.decode()
|
||||||
|
assert Directory.get_by(name="test") is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_directory_in_trash(flask_client):
|
||||||
|
user = login(flask_client)
|
||||||
|
|
||||||
|
directory = Directory.create(name="test", user_id=user.id, commit=True)
|
||||||
|
|
||||||
|
# delete the directory
|
||||||
|
r = flask_client.post(
|
||||||
|
url_for("dashboard.directory"),
|
||||||
|
data={"form-name": "delete", "dir-id": directory.id},
|
||||||
|
follow_redirects=True,
|
||||||
|
)
|
||||||
|
assert Directory.get_by(name="test") is None
|
||||||
|
|
||||||
|
# try to recreate the directory
|
||||||
|
r = flask_client.post(
|
||||||
|
url_for("dashboard.directory"),
|
||||||
|
data={"form-name": "create", "name": "test"},
|
||||||
|
follow_redirects=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert r.status_code == 200
|
||||||
|
assert "test has been used before and cannot be reused" in r.data.decode()
|
Loading…
Reference in a new issue