1
0
mirror of https://github.com/mailcow/mailcow-dockerized.git synced 2025-01-20 04:59:27 +02:00

[Web][DockerApi] migrate imap acl on mbox rename

This commit is contained in:
FreddleSpl0it 2024-08-22 10:10:05 +02:00
parent 10dfd0a443
commit be5a181be5
No known key found for this signature in database
GPG Key ID: 00E14E7634F4BEC5
3 changed files with 115 additions and 6 deletions

View File

@ -90,7 +90,7 @@ async def get_container(container_id : str):
if container._id == container_id:
container_info = await container.show()
return Response(content=json.dumps(container_info, indent=4), media_type="application/json")
res = {
"type": "danger",
"msg": "no container found"
@ -130,7 +130,7 @@ async def get_containers():
async def post_containers(container_id : str, post_action : str, request: Request):
global dockerapi
try :
try:
request_json = await request.json()
except Exception as err:
request_json = {}
@ -191,7 +191,7 @@ async def post_container_update_stats(container_id : str):
stats = json.loads(await dockerapi.redis_client.get(container_id + '_stats'))
return Response(content=json.dumps(stats, indent=4), media_type="application/json")
# PubSub Handler
async def handle_pubsub_messages(channel: aioredis.client.PubSub):
@ -244,7 +244,7 @@ async def handle_pubsub_messages(channel: aioredis.client.PubSub):
dockerapi.logger.error("Unknwon PubSub recieved - %s" % json.dumps(data_json))
else:
dockerapi.logger.error("Unknwon PubSub recieved - %s" % json.dumps(data_json))
await asyncio.sleep(0.0)
except asyncio.TimeoutError:
pass

View File

@ -353,14 +353,14 @@ class DockerApi:
for container in self.sync_docker_client.containers.list(filters=filters):
vmail_name = request_json['old_maildir'].replace("'", "'\\''")
new_vmail_name = request_json['new_maildir'].replace("'", "'\\''")
cmd_vmail = "if [[ -d '/var/vmail/" + vmail_name + "' ]]; then /bin/mv '/var/vmail/" + vmail_name + "' '/var/vmail/" + new_vmail_name + "'; fi"
cmd_vmail = f"if [[ -d '/var/vmail/{vmail_name}' ]]; then /bin/mv '/var/vmail/{vmail_name}' '/var/vmail/{new_vmail_name}'; fi"
index_name = request_json['old_maildir'].split("/")
new_index_name = request_json['new_maildir'].split("/")
if len(index_name) > 1 and len(new_index_name) > 1:
index_name = index_name[1].replace("'", "'\\''") + "@" + index_name[0].replace("'", "'\\''")
new_index_name = new_index_name[1].replace("'", "'\\''") + "@" + new_index_name[0].replace("'", "'\\''")
cmd_vmail_index = "if [[ -d '/var/vmail_index/" + index_name + "' ]]; then /bin/mv '/var/vmail_index/" + index_name + "' '/var/vmail_index/" + new_index_name + "_index'; fi"
cmd_vmail_index = f"if [[ -d '/var/vmail_index/{index_name}' ]]; then /bin/mv '/var/vmail_index/{index_name}' '/var/vmail_index/{new_index_name}_index'; fi"
cmd = ["/bin/bash", "-c", cmd_vmail + " && " + cmd_vmail_index]
else:
cmd = ["/bin/bash", "-c", cmd_vmail]
@ -412,6 +412,83 @@ class DockerApi:
sogo_return = container.exec_run(['sogo-tool', 'rename-user', old_username, new_username], user='sogo')
return self.exec_run_handler('generic', sogo_return)
# api call: container_post - post_action: exec - cmd: dovecot - task: get_acl
def container_post__exec__dovecot__get_acl(self, request_json, **kwargs):
if 'container_id' in kwargs:
filters = {"id": kwargs['container_id']}
elif 'container_name' in kwargs:
filters = {"name": kwargs['container_name']}
for container in self.sync_docker_client.containers.list(filters=filters):
vmail_name = request_json['maildir'].replace("'", "'\\''")
shared_folders = container.exec_run(["/bin/bash", "-c", f"find /var/vmail/{vmail_name}/Maildir/Shared -mindepth 2 -type d | sed 's:^/var/vmail/{vmail_name}/Maildir/Shared/::' | tr '/' '\\\\'"])
shared_folders = shared_folders.output.decode('utf-8')
formatted_acls = []
if shared_folders:
shared_folders = shared_folders.splitlines()
for shared_folder in shared_folders:
if "\\." not in shared_folder:
continue
shared_folder = shared_folder.split("\\.")
acls = container.exec_run(["/bin/bash", "-c", f"doveadm acl get -u {shared_folder[0]} {shared_folder[1]}"])
acls = acls.output.decode('utf-8').strip().splitlines()
if len(acls) >= 2:
for acl in acls[1:]:
id, rights = acls[1].split(maxsplit=1)
id = id.replace("user=", "")
formatted_acls.append({ 'user': shared_folder[0], 'id': id, 'mailbox': shared_folder[1], 'rights': rights.split() })
return Response(content=json.dumps(formatted_acls, indent=4), media_type="application/json")
# api call: container_post - post_action: exec - cmd: dovecot - task: delete_acl
def container_post__exec__dovecot__delete_acl(self, request_json, **kwargs):
if 'container_id' in kwargs:
filters = {"id": kwargs['container_id']}
elif 'container_name' in kwargs:
filters = {"name": kwargs['container_name']}
for container in self.sync_docker_client.containers.list(filters=filters):
user = request_json['user'].replace("'", "'\\''")
mailbox = request_json['mailbox'].replace("'", "'\\''")
id = request_json['id'].replace("'", "'\\''")
if user and mailbox and id:
acl_delete_return = container.exec_run(["/bin/bash", "-c", f'doveadm acl delete -u {user} {mailbox} "user={id}"'])
return self.exec_run_handler('generic', acl_delete_return)
# api call: container_post - post_action: exec - cmd: dovecot - task: set_acl
def container_post__exec__dovecot__set_acl(self, request_json, **kwargs):
if 'container_id' in kwargs:
filters = {"id": kwargs['container_id']}
elif 'container_name' in kwargs:
filters = {"name": kwargs['container_name']}
for container in self.sync_docker_client.containers.list(filters=filters):
user = request_json['user'].replace("'", "'\\''")
mailbox = request_json['mailbox'].replace("'", "'\\''")
id = request_json['id'].replace("'", "'\\''")
rights = ""
available_rights = [
"admin",
"create",
"delete",
"expunge",
"insert",
"lookup",
"post",
"read",
"write",
"write-deleted",
"write-seen"
]
for right in request_json['rights']:
right = right.replace("'", "'\\''").lower()
if right in available_rights:
rights += right + " "
if user and mailbox and id and rights:
acl_set_return = container.exec_run(["/bin/bash", "-c", f'doveadm acl set -u {user} {mailbox} "user={id}" {rights}'])
return self.exec_run_handler('generic', acl_set_return)
# Collect host stats
async def get_host_stats(self, wait=5):

View File

@ -3247,6 +3247,25 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
return false;
}
// get imap acls
$exec_fields = array(
'cmd' => 'dovecot',
'task' => 'get_acl',
'maildir' => $domain . '/' . $old_local_part,
);
$imap_acls = json_decode(docker('post', 'dovecot-mailcow', 'exec', $exec_fields), true);
// delete imap acls
foreach ($imap_acls as $imap_acl) {
$exec_fields = array(
'cmd' => 'dovecot',
'task' => 'delete_acl',
'user' => $imap_acl['user'],
'mailbox' => $imap_acl['mailbox'],
'id' => $imap_acl['id']
);
docker('post', 'dovecot-mailcow', 'exec', $exec_fields);
}
// rename username in sql
try {
$pdo->beginTransaction();
@ -3326,6 +3345,19 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
);
docker('post', 'sogo-mailcow', 'exec', $exec_fields);
// set imap acls
foreach ($imap_acls as $imap_acl) {
$exec_fields = array(
'cmd' => 'dovecot',
'task' => 'set_acl',
'user' => $imap_acl['user'],
'mailbox' => $imap_acl['mailbox'],
'id' => $new_username,
'rights' => $imap_acl['rights']
);
docker('post', 'dovecot-mailcow', 'exec', $exec_fields);
}
// create alias
if ($create_alias == 1) {
mailbox("add", "alias", array(