Merge pull request #222 from simple-login/directory-mailboxes
Directory mailboxes
This commit is contained in:
commit
4eef620e3c
|
@ -18,6 +18,7 @@ from app.models import (
|
|||
User,
|
||||
DeletedAlias,
|
||||
DomainDeletedAlias,
|
||||
AliasMailbox,
|
||||
)
|
||||
|
||||
|
||||
|
@ -65,12 +66,19 @@ def try_auto_create_directory(address: str) -> Optional[Alias]:
|
|||
try:
|
||||
LOG.d("create alias %s for directory %s", address, directory)
|
||||
|
||||
mailboxes = directory.mailboxes
|
||||
|
||||
alias = Alias.create(
|
||||
email=address,
|
||||
user_id=directory.user_id,
|
||||
directory_id=directory.id,
|
||||
mailbox_id=dir_user.default_mailbox_id,
|
||||
mailbox_id=mailboxes[0].id,
|
||||
)
|
||||
db.session.flush()
|
||||
for i in range(1, len(mailboxes)):
|
||||
AliasMailbox.create(
|
||||
alias_id=alias.id, mailbox_id=mailboxes[i].id,
|
||||
)
|
||||
|
||||
db.session.commit()
|
||||
return alias
|
||||
|
|
|
@ -66,6 +66,29 @@
|
|||
<h6 class="card-subtitle mb-2 text-muted">
|
||||
Created {{ dir.created_at | dt }} <br>
|
||||
<span class="font-weight-bold">{{ dir.nb_alias() }}</span> aliases.
|
||||
|
||||
<br><br>
|
||||
|
||||
<b>Mailboxes:</b> <i class="fe fe-info" data-toggle="tooltip"
|
||||
title="Aliases created with this directory are automatically owned by these mailboxes"></i>
|
||||
<br>
|
||||
|
||||
{% set dir_mailboxes=dir.mailboxes %}
|
||||
<form method="post" class="mt-2">
|
||||
<input type="hidden" name="form-name" value="update">
|
||||
<input type="hidden" name="dir-id" value="{{ dir.id }}">
|
||||
|
||||
<select data-width="100%" required
|
||||
class="mailbox-select" multiple name="mailbox_ids">
|
||||
{% for mailbox in mailboxes %}
|
||||
<option value="{{ mailbox.id }}" {% if mailbox in dir_mailboxes %}
|
||||
selected {% endif %}>
|
||||
{{ mailbox.email }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<button class="mt-2 btn btn-outline-primary btn-sm">Update</button>
|
||||
</form>
|
||||
</h6>
|
||||
</div>
|
||||
|
||||
|
@ -105,7 +128,24 @@
|
|||
Only lowercase letters, numbers, dashes (-) and underscores (_) are currently supported.
|
||||
</div>
|
||||
|
||||
<button class="btn btn-lg btn-success mt-2">Create</button>
|
||||
<div class="mt-3 small-text alert alert-info">
|
||||
By default, aliases created with directory are "owned" by your default
|
||||
mailbox <b>{{ current_user.default_mailbox.email }}</b>. <br>
|
||||
You can however choose the mailbox(es) that new alias automatically belongs to by setting this below option.
|
||||
|
||||
</div>
|
||||
|
||||
<select data-width="100%"
|
||||
class="mailbox-select" multiple name="mailbox_ids">
|
||||
{% for mailbox in mailboxes %}
|
||||
<option value="{{ mailbox.id }}" {% if mailbox.id == current_user.default_mailbox_id %}
|
||||
selected {% endif %}>
|
||||
{{ mailbox.email }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
||||
<button id="btn-create-directory" class="btn btn-lg btn-success mt-2">Create</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
@ -142,5 +182,8 @@
|
|||
})
|
||||
|
||||
});
|
||||
|
||||
$('.mailbox-select').multipleSelect();
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -6,7 +6,7 @@ from wtforms import StringField, validators
|
|||
from app.config import EMAIL_DOMAIN, ALIAS_DOMAINS, MAX_NB_DIRECTORY
|
||||
from app.dashboard.base import dashboard_bp
|
||||
from app.extensions import db
|
||||
from app.models import Directory
|
||||
from app.models import Directory, Mailbox, DirectoryMailbox
|
||||
|
||||
|
||||
class NewDirForm(FlaskForm):
|
||||
|
@ -24,6 +24,8 @@ def directory():
|
|||
.all()
|
||||
)
|
||||
|
||||
mailboxes = current_user.mailboxes()
|
||||
|
||||
new_dir_form = NewDirForm()
|
||||
|
||||
if request.method == "POST":
|
||||
|
@ -44,7 +46,46 @@ def directory():
|
|||
flash(f"Directory {name} has been deleted", "success")
|
||||
|
||||
return redirect(url_for("dashboard.directory"))
|
||||
elif request.form.get("form-name") == "update":
|
||||
dir_id = request.form.get("dir-id")
|
||||
dir = Directory.get(dir_id)
|
||||
|
||||
if not dir:
|
||||
flash("Unknown error. Refresh the page", "warning")
|
||||
return redirect(url_for("dashboard.directory"))
|
||||
elif dir.user_id != current_user.id:
|
||||
flash("You cannot delete this directory", "warning")
|
||||
return redirect(url_for("dashboard.directory"))
|
||||
|
||||
mailbox_ids = request.form.getlist("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)
|
||||
|
||||
if not mailboxes:
|
||||
flash("You must select at least 1 mailbox", "warning")
|
||||
return redirect(url_for("dashboard.directory"))
|
||||
|
||||
# first remove all existing alias-mailboxes links
|
||||
DirectoryMailbox.query.filter_by(directory_id=dir.id).delete()
|
||||
db.session.flush()
|
||||
|
||||
for mailbox in mailboxes:
|
||||
DirectoryMailbox.create(directory_id=dir.id, mailbox_id=mailbox.id)
|
||||
|
||||
db.session.commit()
|
||||
flash(f"Directory {dir.name} has been updated", "success")
|
||||
|
||||
return redirect(url_for("dashboard.directory"))
|
||||
elif request.form.get("form-name") == "create":
|
||||
if not current_user.is_premium():
|
||||
flash("Only premium plan can add directory", "warning")
|
||||
|
@ -72,6 +113,27 @@ def directory():
|
|||
name=new_dir_name, user_id=current_user.id
|
||||
)
|
||||
db.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.custom_alias"))
|
||||
mailboxes.append(mailbox)
|
||||
|
||||
for mailbox in mailboxes:
|
||||
DirectoryMailbox.create(
|
||||
directory_id=new_dir.id, mailbox_id=mailbox.id
|
||||
)
|
||||
|
||||
db.session.commit()
|
||||
|
||||
flash(f"Directory {new_dir.name} is created", "success")
|
||||
|
||||
|
@ -81,6 +143,7 @@ def directory():
|
|||
"dashboard/directory.html",
|
||||
dirs=dirs,
|
||||
new_dir_form=new_dir_form,
|
||||
mailboxes=mailboxes,
|
||||
EMAIL_DOMAIN=EMAIL_DOMAIN,
|
||||
ALIAS_DOMAINS=ALIAS_DOMAINS,
|
||||
)
|
||||
|
|
|
@ -1272,6 +1272,17 @@ class Directory(db.Model, ModelMixin):
|
|||
|
||||
user = db.relationship(User)
|
||||
|
||||
_mailboxes = db.relationship(
|
||||
"Mailbox", secondary="directory_mailbox", lazy="joined"
|
||||
)
|
||||
|
||||
@property
|
||||
def mailboxes(self):
|
||||
if self._mailboxes:
|
||||
return self._mailboxes
|
||||
else:
|
||||
return [self.user.default_mailbox]
|
||||
|
||||
def nb_alias(self):
|
||||
return Alias.filter_by(directory_id=self.id).count()
|
||||
|
||||
|
@ -1446,6 +1457,19 @@ class AliasMailbox(db.Model, ModelMixin):
|
|||
)
|
||||
|
||||
|
||||
class DirectoryMailbox(db.Model, ModelMixin):
|
||||
__table_args__ = (
|
||||
db.UniqueConstraint("directory_id", "mailbox_id", name="uq_directory_mailbox"),
|
||||
)
|
||||
|
||||
directory_id = db.Column(
|
||||
db.ForeignKey(Directory.id, ondelete="cascade"), nullable=False
|
||||
)
|
||||
mailbox_id = db.Column(
|
||||
db.ForeignKey(Mailbox.id, ondelete="cascade"), nullable=False
|
||||
)
|
||||
|
||||
|
||||
_NB_RECOVERY_CODE = 8
|
||||
_RECOVERY_CODE_LENGTH = 8
|
||||
|
||||
|
|
Loading…
Reference in a new issue