Domain wildcard for authorized emails
Usecase / situation
For each account it’s possible to authorize specific email addresses which can be searched and are listed under “Emails” in “Settings”. In my setup I’m using IMAP authentication which a special authentication hook to query the mailcow API for all alias email addresses and domain aliases.
There are basically two types of aliases:
- Single email addresses. Like
team@example.com
topatrik@example.com
- Domain alias. Like
example2.com
toexample.com
After logging in Mailpiler with patrik@example.com
also mails from/to team@example.com
can be seen, just as expected. However, unfortunately, domain aliases doesn’t work out.
Research
I’m not a sphinx-expert at all, but as far as I was able to research wildcards seem not to be possible at the beginning and the end, therefore something like *@example2.com
won’t work out and won’t list any mails sent to/from example2.com
.
Therefore I’ve checked:
- https://www.wyeworks.com/blog/2009/04/20/wildcard-search-with-thinking-sphinx/
- http://sphinxsearch.com/blog/2014/03/05/wildcarding-performance/
Based (mostly) on that, my idea might be using:
infix_fields = from, to;
…to enable wildcard-support on from
and to
fields to get this working.
I also couldn’t find an easier way when searching through the source code of mailpiler for days.
In the end…
Any other ideas how to get this solved or workaround'ed? Thanks for any feedback/help!
Comments (12)
-
repo owner -
reporter Now I know what I’ve forgot to mention… Sorry, my fault!
The referenced domain
example2.com
is a domain alias in this scenario, already being returned as@example2.com
when quering the API. But as the alias is a catch-all domain, there’s no way getting each possible combination.That’s the reason I’m thinking about to use
*@example2.com
with a wildcard to workaround this. However not sure if there’s a more elegant solution… -
repo owner Perhaps I misunderstand, but perhaps such fix might work out:
function query_mailcow_for_email_access($username = '') { global $config; $session = Registry::get('session'); $data = $session->get("auth_data"); $aliases = []; $local_parts = []; foreach($data['emails'] as $email) { $a = explode('@', $email); if(count($a) == 2) { $local_parts[] = $a[0]; } } // get emails where user has access to. $emails = mailcow_get_aliases($username); foreach ($emails as $i => $email) { if (substr($email, 0, 1) === '@') { for($i=0; $i<count($local_parts); $i++) { array_push($aliases, $local_parts[$i] . '@' . $email); } } else { array_push($aliases, $email); } } $data['emails'] = array_merge($data['emails'] , $aliases); ... $session->set("auth_data", $data); }
-
reporter The mailcow API returns back all kind of aliases: (this works as intended)
- “Normal” email aliases, like
team@example.com
. - Catch-all aliases, like
example2.com
.
Described in a different way:
- Let’s assume you have an alias like
@example2.com
topatrik@example1.com
. - In this case
@example2.com
is a catchall. - Meaning: You can use
whateverYouCanImagine>@example2.com
as an email address. Evensdofjhpiuosdhyg9usghesughsrg@example2.com
will work and forward the mail topatrik@example1.com
. - So the email addresses are NOT defined somewhere in a database, as it’s a catchall. So you can’t know what the local part is, because it can everything which is RFC-confirm for a valid email address.
I hope this makes sense!
- “Normal” email aliases, like
-
repo owner Now, I understand it, and it’s indeed a tough one to solve. The problem lies at two levels:
- add example2.com to the sphinx query
- check if the user actually has access to the given email based on the From/To/Cc addresses
Unfortunately currently there’s no better solution than to let this user be an auditor to see all emails.
-
reporter For user being auditor I see two problems:
- Users shouldn’t be auditors.
- IMAP authentication and the hook doesn’t allow to set “being auditor” on the fly, I guess?
Beside that:
- Adding
*@example2.com
to$data[“emails”]
isn’t really a problem (which adds it to the sphinx query just fine, I’ve checked that), - Also checking if user does have access to the mail domain works in the code I’ve linked earlier (for my scenario)
IMHO the possibility to use wildcards in the local parts of the email address would solve this specific scenario, and also might be handy for different scenarios:
*@example2.com
for a catchall domainadmin-*@example2.com
to allow someone accessing wildcard email addresses this way (some random example)
In this case wildcard support might only be required for the
to
andfrom
fields in sphinx. -
repo owner I’ll try to come up with a solution to this issue soon.
-
reporter Thanks a lot @Janos SUTO ! If I can help in any way, please just let me know!
-
repo owner So, finally I’ve got something for you. Check out this commit: https://bitbucket.org/jsuto/piler/commits/bfeef2669e07b53cf8878a0a425b4bdd47a25567
Then try the following custom post auth function to test it:
$config['CUSTOM_EMAIL_QUERY_FUNCTION'] = 'wildcards'; function wildcards($username = '') { global $session; if($username == "user@example.com") { $session->set("wildcard_domains", ["example2.com", "example3.com"]); } }
The above example gives access to user@example.com to all emails in domain example2.com and example3.com.
Let me know how it goes.
-
reporter Amazing! Thank you so much, Janos!
I’ve pulled the raw commit, patched my piler 1.3.9 installation manually and it works brilliant! That were my changes with my integration: https://github.com/patschi/mailpiler-mailcow-integration/commit/0dd2795c10c1d20f440c89c77ea7c25125bb318b.
If someone is interested:
$ cd /var/piler $ curl https://bitbucket.org/jsuto/piler/commits/bfeef2669e07b53cf8878a0a425b4bdd47a25567/raw -o wildcard.patch $ sed -e "s|webui/|www/|g" -i wildcard.patch $ patch -p1 < wildcard.patch
Just one note: Personally I’d prefer listing “Email addresses”, “Wildcard domains” and then “Groups”.
Thank you again!
-
repo owner OK, it can be arranged. See this commit: https://bitbucket.org/jsuto/piler/commits/8877285302f47c09ee963174b87c75a7658cc55d
-
repo owner - changed status to resolved
You are welcome, thanks for being patient with me.
- Log in to comment
The piler GUI usually reads external databases to figure out the given user has what email addresses. In a nutshell all you need to do is to return all email addresses including the domain aliases. So extend the query_mailcow_for_email_access function to query the domain aliases as well. Then iterate over all addresses in example.com (using your example), then append example2.com to all local parts.
Let me know how it goes.