Initial commit
This commit is contained in:
commit
530fbab51c
9 changed files with 297 additions and 0 deletions
3
README.md
Normal file
3
README.md
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# E-Mail Autodiscovery
|
||||||
|
|
||||||
|
Based on https://github.com/Monogramm/autodiscover-email-settings (MIT)
|
||||||
19
defaults/main.yml
Normal file
19
defaults/main.yml
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
mail_autodiscover:
|
||||||
|
info:
|
||||||
|
name: Example Org
|
||||||
|
url: https://autodiscover.example.com
|
||||||
|
domain: example.com
|
||||||
|
imap:
|
||||||
|
host: imap.example.com
|
||||||
|
port: 993
|
||||||
|
socket: SSL # plain/SSL/STARTTLS
|
||||||
|
smtp:
|
||||||
|
host: smtp.example.com
|
||||||
|
port: 587
|
||||||
|
socket: STARTTLS # plain/SSL/STARTTLS
|
||||||
|
# Apple mobile config identifiers
|
||||||
|
mobile:
|
||||||
|
identifier: com.example.autodiscover # Replace with reverse of your domain
|
||||||
|
uuid: 92943D26-CAB3-4086-897D-DC6C0D8B1E86 # Replace with random UUID
|
||||||
|
mail:
|
||||||
|
uuid: 7A981A9E-D5D0-4EF8-87FE-39FD6A506FAC # Replace with random UUID
|
||||||
52
files/app/__init__.py
Normal file
52
files/app/__init__.py
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
import json
|
||||||
|
|
||||||
|
from flask import Flask, request, Response, abort, render_template
|
||||||
|
from defusedxml import ElementTree as ET
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
with open('/etc/mail-autodiscover.json') as f:
|
||||||
|
settings = json.load(f)
|
||||||
|
|
||||||
|
@app.route('/autodiscover/autodiscover.xml', methods=['GET', 'POST'])
|
||||||
|
@app.route('/Autodiscover/Autodiscover.xml', methods=['GET', 'POST'])
|
||||||
|
def outlook_autodiscover():
|
||||||
|
data = request.get_data()
|
||||||
|
try:
|
||||||
|
root = ET.fromstring(data)
|
||||||
|
schema = root.find('./{*}Request/{*}AcceptableResponseSchema').text
|
||||||
|
email = root.find('./{*}Request/{*}EMailAddress').text
|
||||||
|
email_username = email.rsplit('@', 1)[0]
|
||||||
|
email_domain = email.rsplit('@', 1)[-1]
|
||||||
|
except (SyntaxError, ValueError):
|
||||||
|
schema = 'http://schemas.microsoft.com/exchange/autodiscover/responseschema/2006'
|
||||||
|
email = ''
|
||||||
|
email_username = ''
|
||||||
|
email_domain = ''
|
||||||
|
ctx = settings.copy()
|
||||||
|
ctx['email'] = email
|
||||||
|
ctx['email_username'] = email_username
|
||||||
|
ctx['email_domain'] = email_domain
|
||||||
|
return Response(
|
||||||
|
render_template('autodiscover.xml', **ctx),
|
||||||
|
content_type='application/xml',
|
||||||
|
)
|
||||||
|
|
||||||
|
@app.route('/mail/config-v1.1.xml')
|
||||||
|
def thunderbird_autoconfig():
|
||||||
|
ctx = settings.copy()
|
||||||
|
ctx['email'] = request.args.get('email', '')
|
||||||
|
return Response(
|
||||||
|
render_template('autoconfig.xml', **ctx),
|
||||||
|
content_type='application/xml',
|
||||||
|
)
|
||||||
|
|
||||||
|
@app.route('/email.mobileconfig')
|
||||||
|
def apple_mobileconfig():
|
||||||
|
ctx = settings.copy()
|
||||||
|
ctx['email'] = request.args['email']
|
||||||
|
return Response(
|
||||||
|
render_template('mobileconfig.xml', **ctx),
|
||||||
|
content_type='application/x-apple-aspen-config; charset=utf-8',
|
||||||
|
headers={'Content-Disposition': 'attachment; filename="email.mobileconfig"'},
|
||||||
|
)
|
||||||
37
files/app/templates/autoconfig.xml
Normal file
37
files/app/templates/autoconfig.xml
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<clientConfig version="1.1">
|
||||||
|
<emailProvider id="{{domain}}">
|
||||||
|
<domain>{{domain}}</domain>
|
||||||
|
|
||||||
|
<displayName>{{info.name}} Email</displayName>
|
||||||
|
<displayShortName>%EMAILLOCALPART%</displayShortName>
|
||||||
|
|
||||||
|
{%- if imap.host %}
|
||||||
|
<incomingServer type="imap">
|
||||||
|
<hostname>{{imap.host}}</hostname>
|
||||||
|
<port>{{imap.port}}</port>
|
||||||
|
<socketType>{{imap.socket}}</socketType>
|
||||||
|
<authentication>password-cleartext</authentication>
|
||||||
|
<username>%EMAILADDRESS%</username>
|
||||||
|
</incomingServer>
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
|
{%- if smtp.host %}
|
||||||
|
<outgoingServer type="smtp">
|
||||||
|
<hostname>{{smtp.host}}</hostname>
|
||||||
|
<port>{{smtp.port}}</port>
|
||||||
|
<socketType>{{smtp.socket}}</socketType>
|
||||||
|
<authentication>password-cleartext</authentication>
|
||||||
|
<username>%EMAILADDRESS%</username>
|
||||||
|
</outgoingServer>
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
|
<documentation url="{{info.url}}">
|
||||||
|
<descr lang="en">Generic settings page</descr>
|
||||||
|
<descr lang="fr">Paramètres généraux</descr>
|
||||||
|
<descr lang="es">Configuraciones genéricas</descr>
|
||||||
|
<descr lang="de">Allgemeine Beschreibung der Einstellungen</descr>
|
||||||
|
<descr lang="ru">Страница общих настроек</descr>
|
||||||
|
</documentation>
|
||||||
|
</emailProvider>
|
||||||
|
</clientConfig>
|
||||||
48
files/app/templates/autodiscover.xml
Normal file
48
files/app/templates/autodiscover.xml
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<Autodiscover
|
||||||
|
xmlns="http://schemas.microsoft.com/exchange/autodiscover/responseschema/2006">
|
||||||
|
<Response
|
||||||
|
xmlns="{{schema}}">
|
||||||
|
<User>
|
||||||
|
<DisplayName>{{info.name}}</DisplayName>
|
||||||
|
</User>
|
||||||
|
<Account>
|
||||||
|
<AccountType>email</AccountType>
|
||||||
|
<Action>settings</Action>
|
||||||
|
<ServiceHome>{{info.url}}</ServiceHome>
|
||||||
|
{%- if imap.host %}
|
||||||
|
<Protocol>
|
||||||
|
<Type>IMAP</Type>
|
||||||
|
<Server>{{imap.host}}</Server>
|
||||||
|
<Port>{{imap.port}}</Port>
|
||||||
|
{%- if email %}
|
||||||
|
<LoginName>{{email}}</LoginName>
|
||||||
|
{% endif -%}
|
||||||
|
<DomainRequired>on</DomainRequired>
|
||||||
|
<DomainName>{{domain}}</DomainName>
|
||||||
|
<SPA>on</SPA>
|
||||||
|
<SSL>{{ 'on' if imap.socket in ('SSL', 'STARTTLS') else 'off' }}</SSL>
|
||||||
|
<Encryption>{{ 'TLS' if imap.socket == 'STARTTLS' else imap.socket }}</Encryption>
|
||||||
|
<AuthRequired>on</AuthRequired>
|
||||||
|
</Protocol>
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
|
{%- if smtp.host %}
|
||||||
|
<Protocol>
|
||||||
|
<Type>SMTP</Type>
|
||||||
|
<Server>{{smtp.host}}</Server>
|
||||||
|
<Port>{{smtp.port}}</Port>
|
||||||
|
{%- if email %}
|
||||||
|
<LoginName>{{email}}</LoginName>
|
||||||
|
{% endif -%}
|
||||||
|
<DomainRequired>on</DomainRequired>
|
||||||
|
<DomainName>{{domain}}</DomainName>
|
||||||
|
<SPA>on</SPA>
|
||||||
|
<SSL>{{ 'on' if smtp.socket in ('SSL', 'STARTTLS') else 'off' }}</SSL>
|
||||||
|
<Encryption>{{ 'TLS' if imap.socket == 'STARTTLS' else imap.socket }}</Encryption>
|
||||||
|
<AuthRequired>on</AuthRequired>
|
||||||
|
</Protocol>
|
||||||
|
{% endif -%}
|
||||||
|
</Account>
|
||||||
|
</Response>
|
||||||
|
</Autodiscover>
|
||||||
81
files/app/templates/mobileconfig.xml
Normal file
81
files/app/templates/mobileconfig.xml
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>HasRemovalPasscode</key>
|
||||||
|
<false/>
|
||||||
|
<key>PayloadContent</key>
|
||||||
|
<array>
|
||||||
|
{% if imap.host %}
|
||||||
|
<dict>
|
||||||
|
<key>EmailAccountDescription</key>
|
||||||
|
<string>{{email}}</string>
|
||||||
|
<key>EmailAccountName</key>
|
||||||
|
<string>{{email}}</string>
|
||||||
|
<key>EmailAccountType</key>
|
||||||
|
<string>{% if imap.host %}EmailTypeIMAP{% else %}EmailTypePOP{% endif %}</string>
|
||||||
|
<key>EmailAddress</key>
|
||||||
|
<string>{{email}}</string>
|
||||||
|
<key>IncomingMailServerAuthentication</key>
|
||||||
|
<string>EmailAuthPassword</string>
|
||||||
|
<key>IncomingMailServerHostName</key>
|
||||||
|
<string>{{imap.host}}</string>
|
||||||
|
<key>IncomingMailServerPortNumber</key>
|
||||||
|
<integer>{{imap.port}}</integer>
|
||||||
|
<key>IncomingMailServerUseSSL</key>
|
||||||
|
<{{ 'true' if imap.socket in ['SSL', 'STARTTLS'] else 'false' }}/>
|
||||||
|
<key>IncomingMailServerUsername</key>
|
||||||
|
<string>{{email}}</string>
|
||||||
|
<key>OutgoingPasswordSameAsIncomingPassword</key>
|
||||||
|
<true/>
|
||||||
|
<key>OutgoingMailServerAuthentication</key>
|
||||||
|
<string>EmailAuthPassword</string>
|
||||||
|
<key>OutgoingMailServerHostName</key>
|
||||||
|
<string>{{smtp.host}}</string>
|
||||||
|
<key>OutgoingMailServerPortNumber</key>
|
||||||
|
<integer>{{smtp.port}}</integer>
|
||||||
|
<key>OutgoingMailServerUseSSL</key>
|
||||||
|
<{{ 'true' if smtp.socket in ['SSL', 'STARTTLS'] else 'false' }}/>
|
||||||
|
<key>OutgoingMailServerUsername</key>
|
||||||
|
<string>{{email}}</string>
|
||||||
|
<key>SMIMEEnabled</key>
|
||||||
|
<false/>
|
||||||
|
<key>SMIMEEnablePerMessageSwitch</key>
|
||||||
|
<false/>
|
||||||
|
<key>SMIMEEnableEncryptionPerMessageSwitch</key>
|
||||||
|
<false/>
|
||||||
|
<key>disableMailRecentsSyncing</key>
|
||||||
|
<false/>
|
||||||
|
<key>PayloadDescription</key>
|
||||||
|
<string>{{info.name}} Email</string>
|
||||||
|
<key>PayloadDisplayName</key>
|
||||||
|
<string>{{email}}</string>
|
||||||
|
<key>PayloadIdentifier</key>
|
||||||
|
<string>{{mobile.identifier}}.com.apple.mail.managed.{{mobile.mail.uuid}}</string>
|
||||||
|
<key>PayloadType</key>
|
||||||
|
<string>com.apple.mail.managed</string>
|
||||||
|
<key>PayloadUUID</key>
|
||||||
|
<string>{{mobile.mail.uuid}}</string>
|
||||||
|
<key>PayloadVersion</key>
|
||||||
|
<real>1</real>
|
||||||
|
</dict>
|
||||||
|
{% endif %}
|
||||||
|
</array>
|
||||||
|
<key>PayloadDescription</key>
|
||||||
|
<string>{{info.name}}</string>
|
||||||
|
<key>PayloadDisplayName</key>
|
||||||
|
<string>{{email}}</string>
|
||||||
|
<key>PayloadIdentifier</key>
|
||||||
|
<string>{{mobile.identifier}}</string>
|
||||||
|
<key>PayloadOrganization</key>
|
||||||
|
<string>{{domain}}</string>
|
||||||
|
<key>PayloadRemovalDisallowed</key>
|
||||||
|
<false/>
|
||||||
|
<key>PayloadType</key>
|
||||||
|
<string>Configuration</string>
|
||||||
|
<key>PayloadUUID</key>
|
||||||
|
<string>{{mobile.uuid}}</string>
|
||||||
|
<key>PayloadVersion</key>
|
||||||
|
<integer>2</integer>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
20
files/mail-autodiscover.service
Normal file
20
files/mail-autodiscover.service
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Mail Autodiscover Service
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=notify
|
||||||
|
DynamicUser=true
|
||||||
|
WorkingDirectory=/usr/local/lib/mail-autodiscover
|
||||||
|
Environment="PYTHONUNBUFFERED=1"
|
||||||
|
ExecStart=/usr/bin/gunicorn --workers=2 --log-level=info -b 127.0.0.1:8749 app:app
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=30
|
||||||
|
PrivateTmp=true
|
||||||
|
ProtectSystem=strict
|
||||||
|
StandardOutput=journal
|
||||||
|
StandardError=journal
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
5
handlers/main.yml
Normal file
5
handlers/main.yml
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
- name: Restart mail-autodiscover.service
|
||||||
|
ansible.builtin.systemd_service:
|
||||||
|
name: mail-autodiscover.service
|
||||||
|
state: restarted
|
||||||
|
daemon_reload: yes
|
||||||
32
tasks/main.yml
Normal file
32
tasks/main.yml
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
- name: Install server dependencies
|
||||||
|
ansible.builtin.apt:
|
||||||
|
pkg:
|
||||||
|
- python3-flask
|
||||||
|
- python3-defusedxml
|
||||||
|
- gunicorn
|
||||||
|
|
||||||
|
- name: Create directory for app
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /usr/local/lib/mail-autodiscover
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
- name: Install app
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: app
|
||||||
|
dest: /usr/local/lib/mail-autodiscover/
|
||||||
|
notify: Restart mail-autodiscover.service
|
||||||
|
|
||||||
|
- name: Install config
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: '{{ mail_autodiscover|tojson }}'
|
||||||
|
dest: /etc/mail-autodiscover.json
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: 0644
|
||||||
|
notify: Restart mail-autodiscover.service
|
||||||
|
|
||||||
|
- name: Install systemd units
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: mail-autodiscover.service
|
||||||
|
dest: /etc/systemd/system/mail-autodiscover.service
|
||||||
|
notify: Restart mail-autodiscover.service
|
||||||
Loading…
Add table
Add a link
Reference in a new issue