You've already forked Mailu
mirror of
https://github.com/Mailu/Mailu.git
synced 2026-05-22 10:15:19 +02:00
Merge #4023
4023: enhancement: checks for anonmail access and ensure no wildcard collisions r=nextgens a=lhw ## What type of PR? Enhancement to resolve remaining comments from #3968 ## What does this PR do? - Simplifies the anonmail has_access checks (removed some duplicate checks for global admin - Fixes the alias generation check to avoid collisions with wildcard aliases Two Notes: The `Alias.resolve` would make domains that have catch alls with `%`@domain`` essentially non-functional for anonmail generation, even if allowed as it would return an alias for every single call. Aliases are matched by length with explicit matches first and then by length of match if got this right: ``` .order_by(cls.wildcard, sqlalchemy.func.char_length(cls.localpart).desc()) ``` Question is if that is what we want here. Second note. Right now the match with `Alias.resolve` requires the extra check against the alias db anyhow due to disabled aliases not being listed by `Alias.resolve` and causing a collision. An optional change would be to introduce a form of `Alias.resolve_any` or an optional parameter to `Alias.resolve(cls, localpart, domain_name, list_disabled=False)` e.g. ### Related issue(s) - #3968 ## Prerequisites Before we can consider review and merge, please make sure the following list is done and checked. If an entry in not applicable, you can check it or remove it from the list. - [ ] In case of feature or enhancement: documentation updated accordingly - [ ] Unless it's docs or a minor change: add [changelog](https://mailu.io/master/contributors/workflow.html#changelog) entry file. Co-authored-by: Lennart Weller <lhw@ring0.de>
This commit is contained in:
@@ -65,7 +65,7 @@ class RandomAlias(Resource):
|
||||
# Find all domains with anonmail access
|
||||
accessible_domains = []
|
||||
for d in models.Domain.query.all():
|
||||
if (g.user.global_admin or models.has_domain_access(d.name, user=g.user) or
|
||||
if (models.has_domain_access(d.name, user=g.user) or
|
||||
(d.anonmail_enabled and g.user.domain and d.name == g.user.domain.name)):
|
||||
accessible_domains.append(d.name)
|
||||
|
||||
@@ -83,7 +83,11 @@ class RandomAlias(Resource):
|
||||
for _ in range(flask.current_app.config.get('ANONMAIL_MAX_RETRIES', 10)):
|
||||
candidate = utils.generate_anonymous_alias_localpart(hostname=hostname)
|
||||
email_candidate = f"{candidate}@{domain_name}"
|
||||
if not models.Alias.query.filter_by(email=email_candidate).first() and not models.User.query.filter_by(email=email_candidate).first():
|
||||
if (
|
||||
not models.Alias.resolve(candidate, domain_name) # Specifically check for SQL-like wildcard aliases.
|
||||
and not models.Alias.query.filter_by(email=email_candidate).first() # Still need to check for exact match to prevent collision with disabled aliases
|
||||
and not models.User.query.filter_by(email=email_candidate).first()
|
||||
):
|
||||
localpart = candidate
|
||||
break
|
||||
|
||||
|
||||
@@ -72,12 +72,10 @@ def alias_delete(alias):
|
||||
@access.authenticated
|
||||
def anonalias_list():
|
||||
user = flask_login.current_user
|
||||
has_access = user.global_admin
|
||||
if not has_access:
|
||||
for d in models.Domain.query.all():
|
||||
if models.has_domain_access(d.name, user=user) or (d.anonmail_enabled and user.domain and d.name == user.domain.name):
|
||||
has_access = True
|
||||
break
|
||||
has_access = any(
|
||||
models.has_domain_access(d.name, user=user) or (d.anonmail_enabled and user.domain and d.name == user.domain.name)
|
||||
for d in models.Domain.query.all()
|
||||
)
|
||||
|
||||
# Query user's anonymous aliases, standard aliases do not have an owner_email
|
||||
aliases = models.Alias.query.filter_by(owner_email=user.email).all()
|
||||
@@ -94,7 +92,7 @@ def anonalias_create():
|
||||
# Populate domain choices
|
||||
available_domains = []
|
||||
for d in models.Domain.query.all():
|
||||
if user.global_admin or models.has_domain_access(d.name, user=user) or (d.anonmail_enabled and user.domain and d.name == user.domain.name):
|
||||
if models.has_domain_access(d.name, user=user) or (d.anonmail_enabled and user.domain and d.name == user.domain.name):
|
||||
available_domains.append((d.name, d.name))
|
||||
|
||||
form.domain.choices = available_domains
|
||||
@@ -114,7 +112,11 @@ def anonalias_create():
|
||||
for _ in range(max_retries):
|
||||
candidate = utils.generate_anonymous_alias_localpart(hostname=hostname)
|
||||
email_candidate = f"{candidate}@{domain_name}"
|
||||
if not models.Alias.query.filter_by(email=email_candidate).first() and not models.User.query.filter_by(email=email_candidate).first():
|
||||
if (
|
||||
not models.Alias.resolve(candidate, domain_name) # Specifically check for SQL-like wildcard aliases.
|
||||
and not models.Alias.query.filter_by(email=email_candidate).first() # Still need to check for exact match to prevent collision with disabled aliases
|
||||
and not models.User.query.filter_by(email=email_candidate).first()
|
||||
):
|
||||
localpart = candidate
|
||||
break
|
||||
|
||||
|
||||
Reference in New Issue
Block a user