1389: Prefer specific alias over wildcard, regardless of case r=mergify[bot] a=Nebukadneza

## What type of PR?
bug-fix

## What does this PR do?
Since direct addresses (not aliases) are case-insensitive since a while,
it makes sense for aliases to behave the same. Up until now, a wildcard
alias could trump a alias not-matching-the-case of the incoming address.
This clarifies this behavior.

## Notes
I realize that the if-hell down there isn’t nice. What it is, however, is quite clear and easy to read. I’m hoping that if anyone ever gets confused in the future, this will make the current behavior transparent. For me, that was more important than a minimal amount of statements/branches …

### Related issue(s)
closes #1387

## Prerequistes
- [x] Unless it's docs or a minor change: add [changelog](https://mailu.io/master/contributors/guide.html#changelog) entry file.


Co-authored-by: Dario Ernst <github@kanojo.de>
master
bors[bot] 5 years ago committed by GitHub
commit 60b9a3e2f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -451,25 +451,34 @@ class Alias(Base, Email):
) )
) )
).order_by(cls.wildcard, sqlalchemy.func.char_length(cls.localpart).desc()).first() ).order_by(cls.wildcard, sqlalchemy.func.char_length(cls.localpart).desc()).first()
if alias_preserve_case:
return alias_preserve_case
if localpart: localpart_lower = localpart.lower() if localpart else None
localpart = localpart.lower() alias_lower_case = cls.query.filter(
return cls.query.filter(
sqlalchemy.and_(cls.domain_name == domain_name, sqlalchemy.and_(cls.domain_name == domain_name,
sqlalchemy.or_( sqlalchemy.or_(
sqlalchemy.and_( sqlalchemy.and_(
cls.wildcard == False, cls.wildcard == False,
sqlalchemy.func.lower(cls.localpart) == localpart sqlalchemy.func.lower(cls.localpart) == localpart_lower
), sqlalchemy.and_( ), sqlalchemy.and_(
cls.wildcard == True, cls.wildcard == True,
sqlalchemy.bindparam("l", localpart).like(sqlalchemy.func.lower(cls.localpart)) sqlalchemy.bindparam("l", localpart_lower).like(sqlalchemy.func.lower(cls.localpart))
) )
) )
) )
).order_by(cls.wildcard, sqlalchemy.func.char_length(sqlalchemy.func.lower(cls.localpart)).desc()).first() ).order_by(cls.wildcard, sqlalchemy.func.char_length(sqlalchemy.func.lower(cls.localpart)).desc()).first()
if alias_preserve_case and alias_lower_case:
if alias_preserve_case.wildcard:
return alias_lower_case
else:
return alias_preserve_case
elif alias_preserve_case and not alias_lower_case:
return alias_preserve_case
elif alias_lower_case and not alias_preserve_case:
return alias_lower_case
else:
return None
class Token(Base): class Token(Base):
""" A token is an application password for a given user. """ A token is an application password for a given user.
""" """

@ -0,0 +1 @@
Fix alias resolution in regard to case: A specifically matching alias of wrong case is now preferred over a wildcard alias that might have »eaten« it previously.
Loading…
Cancel
Save