[sso-admin] Generate script for NC mail accounts

This must be executed from cron on dd-apps-nextcloud-app.
merge-requests/7/head
Evilham 2022-08-01 14:32:51 +02:00
parent da52d322af
commit df29999e62
No known key found for this signature in database
GPG Key ID: AE3EE30D970886BF
4 changed files with 44 additions and 10 deletions

View File

@ -33,6 +33,7 @@ services:
- /etc/localtime:/etc/localtime:ro
- ${SRC_FOLDER}/nextcloud:/var/www/html
- ${DATA_FOLDER}/nextcloud:/var/www/html/data
- ${DATA_FOLDER}/nc-mail-queue:/nc-mail-queue:rw
environment:
- NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER}
- NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD}

View File

@ -22,6 +22,8 @@ import json
import logging as log
import os
import traceback
from datetime import datetime
from pathlib import Path
from pprint import pprint
from time import sleep
@ -60,7 +62,7 @@ from .helpers import (
rand_password,
)
from typing import TYPE_CHECKING, cast, Any, Dict, Iterable, List, Optional
from typing import TYPE_CHECKING, cast, Any, Dict, Iterable, List, Optional, Tuple
if TYPE_CHECKING:
from admin.flaskapp import AdminFlaskApp
from admin.lib.callbacks import ThirdPartyCallbacks
@ -130,12 +132,41 @@ class Admin:
res = res and tp.delete_user(user_id)
return res
def nextcloud_mail_set(self, users : List[DDUser], extra_data : Dict) -> Dict:
# TODO: implement
return {}
def _nextcloud_mail_set_cmd(self, user : DDUser, kw : Dict) -> Tuple[str, str]:
account_name = 'DD' # Treating this as a constant
update_cmd = f"""mail:account:update \
--imap-host '{ kw['inbound_host'] }' --imap-port '{ kw['inbound_port'] }' --imap-ssl-mode '{ kw['inbound_ssl_mode'] }' \\
--imap-user '{ user['email'] }' --imap-password '{ user['password'] }' \\
--smtp-host '{ kw['outbound_host'] }' --smtp-port'{ kw['outbound_port'] }' --smtp-ssl-mode '{ kw['outbound_ssl_mode'] }' \\
--smtp-user '{ user['email'] }' --smtp-password '{ user['password'] }' \\
-- '{ user['user_id'] }' '{ user['email']}'"""
create_cmd = f"""mail:account:create '{ user['user_id'] }' '{ account_name }' '{ user['email'] }' \\
'{ kw['inbound_host'] }' '{ kw['inbound_port'] }' '{ kw['inbound_ssl_mode'] }' \\
'{ user['email'] }' '{ user['password'] }' \\
'{ kw['outbound_host'] }' '{ kw['outbound_port'] }' '{ kw['outbound_ssl_mode'] }' \\
'{ user['email'] }' '{ user['password'] }'"""
return (update_cmd, create_cmd)
def nextcloud_mail_delete(self, users : List[DDUser], extra_data : Dict) -> Dict:
# TODO: implement
def _nextcloud_mail_set_sh(self, users : List[DDUser], extra_data : Dict) -> str:
cmds = '\n'.join((f"./occ {u} || ./occ {c}" for u, c in (self._nextcloud_mail_set_cmd(u, extra_data) for u in users)))
return f"""#!/bin/sh -eu
{cmds}
"""
def nextcloud_mail_set(self, users : List[DDUser], extra_data : Dict) -> Dict:
# TODO: this could (and should) be nicer.
# Ideally we'd use the database as a queue instead of creating the
# shell scripts here.
d = Path(os.environ.get("NC_MAIL_QUEUE_FOLDER", "/nc-mail-queue"))
fn = datetime.utcnow().isoformat() + secrets.token_hex(4)
sh = d.joinpath(fn + '.sh')
tmp = d.joinpath(fn + '.tmp')
# Create executable file
tmp.touch(mode=0o750)
# Write script
tmp.write_text(self._nextcloud_mail_set_sh(users, extra_data))
# Put it in-place
tmp.rename(sh)
return {}
def check_connections(self, app : "AdminFlaskApp") -> None:

View File

@ -46,7 +46,7 @@ def setup_mail_views(app: "AdminFlaskApp") -> None:
key = json.dumps(mail_3p.our_pubkey_jwk)
return key, 200, {"Content-Type": "application/json"}
@app.route("/ddapi/mailusers", methods=["GET", "POST", "PUT", "DELETE"])
@app.route("/ddapi/mailusers", methods=["GET", "POST", "PUT"])
@has_jws_token(app)
def ddapi_mail_users() -> JsonResponse:
users: List[Dict[str, Any]] = []
@ -66,8 +66,10 @@ def setup_mail_views(app: "AdminFlaskApp") -> None:
raise Error(
"internal_server", "Failure sending users", traceback.format_exc()
)
if request.method not in ["POST", "PUT", "DELETE"]:
if request.method not in ["POST", "PUT"]:
# Unsupported method
# Note we do not support DELETE as it is taken care of when the
# full Nextcloud user is deleted.
return json.dumps({}), 400, JsonHeaders
try:
@ -86,8 +88,6 @@ def setup_mail_views(app: "AdminFlaskApp") -> None:
res: Dict
if request.method in ["POST", "PUT"]:
res = app.admin.nextcloud_mail_set(users, dec_data)
elif request.method == "DELETE":
res = app.admin.nextcloud_mail_delete(users, dec_data)
return (
json.dumps(res),
200,

View File

@ -38,6 +38,7 @@ services:
- ${DATA_FOLDER}/saml_certs:/admin/saml_certs:rw
- ${DATA_FOLDER}/legal:/admin/admin/static/templates/pages/legal:rw
- ${DATA_FOLDER}/dd-admin:/data:rw
- ${DATA_FOLDER}/nc-mail-queue:/nc-mail-queue:rw
env_file:
- .env
environment:
@ -46,4 +47,5 @@ services:
- MANAGED_EMAIL_DOMAIN=${MANAGED_EMAIL_DOMAIN}
- DATA_FOLDER=/data
- CUSTOM_FOLDER=/admin/custom
- NC_MAIL_QUEUE_FOLDER=/nc-mail-queue
- LEGAL_PATH=/admin/admin/static/templates/pages/legal