@@ -159,7 +159,7 @@ def container_post__exec__mailq__deliver(self, request_json, **kwargs):
159
159
postqueue_r = container .exec_run (["/bin/bash" , "-c" , "/usr/sbin/postqueue " + i ], user = 'postfix' )
160
160
# todo: check each exit code
161
161
res = { 'type' : 'success' , 'msg' : 'Scheduled immediate delivery' }
162
- return Response (content = json .dumps (res , indent = 4 ), media_type = "application/json" )
162
+ return Response (content = json .dumps (res , indent = 4 ), media_type = "application/json" )
163
163
# api call: container_post - post_action: exec - cmd: mailq - task: list
164
164
def container_post__exec__mailq__list (self , request_json , ** kwargs ):
165
165
if 'container_id' in kwargs :
@@ -318,7 +318,7 @@ def container_post__exec__sieve__print(self, request_json, **kwargs):
318
318
319
319
if 'username' in request_json and 'script_name' in request_json :
320
320
for container in self .sync_docker_client .containers .list (filters = filters ):
321
- cmd = ["/bin/bash" , "-c" , "/usr/bin/doveadm sieve get -u '" + request_json ['username' ].replace ("'" , "'\\ ''" ) + "' '" + request_json ['script_name' ].replace ("'" , "'\\ ''" ) + "'" ]
321
+ cmd = ["/bin/bash" , "-c" , "/usr/bin/doveadm sieve get -u '" + request_json ['username' ].replace ("'" , "'\\ ''" ) + "' '" + request_json ['script_name' ].replace ("'" , "'\\ ''" ) + "'" ]
322
322
sieve_return = container .exec_run (cmd )
323
323
return self .exec_run_handler ('utf8_text_only' , sieve_return )
324
324
# api call: container_post - post_action: exec - cmd: maildir - task: cleanup
@@ -342,6 +342,30 @@ def container_post__exec__maildir__cleanup(self, request_json, **kwargs):
342
342
cmd = ["/bin/bash" , "-c" , cmd_vmail ]
343
343
maildir_cleanup = container .exec_run (cmd , user = 'vmail' )
344
344
return self .exec_run_handler ('generic' , maildir_cleanup )
345
+ # api call: container_post - post_action: exec - cmd: maildir - task: move
346
+ def container_post__exec__maildir__move (self , request_json , ** kwargs ):
347
+ if 'container_id' in kwargs :
348
+ filters = {"id" : kwargs ['container_id' ]}
349
+ elif 'container_name' in kwargs :
350
+ filters = {"name" : kwargs ['container_name' ]}
351
+
352
+ if 'old_maildir' in request_json and 'new_maildir' in request_json :
353
+ for container in self .sync_docker_client .containers .list (filters = filters ):
354
+ vmail_name = request_json ['old_maildir' ].replace ("'" , "'\\ ''" )
355
+ new_vmail_name = request_json ['new_maildir' ].replace ("'" , "'\\ ''" )
356
+ cmd_vmail = f"if [[ -d '/var/vmail/{ vmail_name } ' ]]; then /bin/mv '/var/vmail/{ vmail_name } ' '/var/vmail/{ new_vmail_name } '; fi"
357
+
358
+ index_name = request_json ['old_maildir' ].split ("/" )
359
+ new_index_name = request_json ['new_maildir' ].split ("/" )
360
+ if len (index_name ) > 1 and len (new_index_name ) > 1 :
361
+ index_name = index_name [1 ].replace ("'" , "'\\ ''" ) + "@" + index_name [0 ].replace ("'" , "'\\ ''" )
362
+ new_index_name = new_index_name [1 ].replace ("'" , "'\\ ''" ) + "@" + new_index_name [0 ].replace ("'" , "'\\ ''" )
363
+ 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"
364
+ cmd = ["/bin/bash" , "-c" , cmd_vmail + " && " + cmd_vmail_index ]
365
+ else :
366
+ cmd = ["/bin/bash" , "-c" , cmd_vmail ]
367
+ maildir_move = container .exec_run (cmd , user = 'vmail' )
368
+ return self .exec_run_handler ('generic' , maildir_move )
345
369
# api call: container_post - post_action: exec - cmd: rspamd - task: worker_password
346
370
def container_post__exec__rspamd__worker_password (self , request_json , ** kwargs ):
347
371
if 'container_id' in kwargs :
@@ -374,6 +398,121 @@ def container_post__exec__rspamd__worker_password(self, request_json, **kwargs):
374
398
self .logger .error ('failed changing Rspamd password' )
375
399
res = { 'type' : 'danger' , 'msg' : 'command did not complete' }
376
400
return Response (content = json .dumps (res , indent = 4 ), media_type = "application/json" )
401
+ # api call: container_post - post_action: exec - cmd: sogo - task: rename
402
+ def container_post__exec__sogo__rename_user (self , request_json , ** kwargs ):
403
+ if 'container_id' in kwargs :
404
+ filters = {"id" : kwargs ['container_id' ]}
405
+ elif 'container_name' in kwargs :
406
+ filters = {"name" : kwargs ['container_name' ]}
407
+
408
+ if 'old_username' in request_json and 'new_username' in request_json :
409
+ for container in self .sync_docker_client .containers .list (filters = filters ):
410
+ old_username = request_json ['old_username' ].replace ("'" , "'\\ ''" )
411
+ new_username = request_json ['new_username' ].replace ("'" , "'\\ ''" )
412
+
413
+ sogo_return = container .exec_run (["/bin/bash" , "-c" , f"sogo-tool rename-user '{ old_username } ' '{ new_username } '" ], user = 'sogo' )
414
+ return self .exec_run_handler ('generic' , sogo_return )
415
+ # api call: container_post - post_action: exec - cmd: doveadm - task: get_acl
416
+ def container_post__exec__doveadm__get_acl (self , request_json , ** kwargs ):
417
+ if 'container_id' in kwargs :
418
+ filters = {"id" : kwargs ['container_id' ]}
419
+ elif 'container_name' in kwargs :
420
+ filters = {"name" : kwargs ['container_name' ]}
421
+
422
+ for container in self .sync_docker_client .containers .list (filters = filters ):
423
+ id = request_json ['id' ].replace ("'" , "'\\ ''" )
424
+
425
+ shared_folders = container .exec_run (["/bin/bash" , "-c" , f"doveadm mailbox list -u '{ id } '" ])
426
+ shared_folders = shared_folders .output .decode ('utf-8' )
427
+ shared_folders = shared_folders .splitlines ()
428
+
429
+ formatted_acls = []
430
+ mailbox_seen = []
431
+ for shared_folder in shared_folders :
432
+ if "Shared" not in shared_folder :
433
+ mailbox = shared_folder .replace ("'" , "'\\ ''" )
434
+ if mailbox in mailbox_seen :
435
+ continue
436
+
437
+ acls = container .exec_run (["/bin/bash" , "-c" , f"doveadm acl get -u '{ id } ' '{ mailbox } '" ])
438
+ acls = acls .output .decode ('utf-8' ).strip ().splitlines ()
439
+ if len (acls ) >= 2 :
440
+ for acl in acls [1 :]:
441
+ user_id , rights = acl .split (maxsplit = 1 )
442
+ user_id = user_id .split ('=' )[1 ]
443
+ mailbox_seen .append (mailbox )
444
+ formatted_acls .append ({ 'user' : id , 'id' : user_id , 'mailbox' : mailbox , 'rights' : rights .split () })
445
+ elif "Shared" in shared_folder and "/" in shared_folder :
446
+ shared_folder = shared_folder .split ("/" )
447
+ if len (shared_folder ) < 3 :
448
+ continue
449
+
450
+ user = shared_folder [1 ].replace ("'" , "'\\ ''" )
451
+ mailbox = '/' .join (shared_folder [2 :]).replace ("'" , "'\\ ''" )
452
+ if mailbox in mailbox_seen :
453
+ continue
454
+
455
+ acls = container .exec_run (["/bin/bash" , "-c" , f"doveadm acl get -u '{ user } ' '{ mailbox } '" ])
456
+ acls = acls .output .decode ('utf-8' ).strip ().splitlines ()
457
+ if len (acls ) >= 2 :
458
+ for acl in acls [1 :]:
459
+ user_id , rights = acl .split (maxsplit = 1 )
460
+ user_id = user_id .split ('=' )[1 ].replace ("'" , "'\\ ''" )
461
+ if user_id == id and mailbox not in mailbox_seen :
462
+ mailbox_seen .append (mailbox )
463
+ formatted_acls .append ({ 'user' : user , 'id' : id , 'mailbox' : mailbox , 'rights' : rights .split () })
464
+
465
+ return Response (content = json .dumps (formatted_acls , indent = 4 ), media_type = "application/json" )
466
+ # api call: container_post - post_action: exec - cmd: doveadm - task: delete_acl
467
+ def container_post__exec__doveadm__delete_acl (self , request_json , ** kwargs ):
468
+ if 'container_id' in kwargs :
469
+ filters = {"id" : kwargs ['container_id' ]}
470
+ elif 'container_name' in kwargs :
471
+ filters = {"name" : kwargs ['container_name' ]}
472
+
473
+ for container in self .sync_docker_client .containers .list (filters = filters ):
474
+ user = request_json ['user' ].replace ("'" , "'\\ ''" )
475
+ mailbox = request_json ['mailbox' ].replace ("'" , "'\\ ''" )
476
+ id = request_json ['id' ].replace ("'" , "'\\ ''" )
477
+
478
+ if user and mailbox and id :
479
+ acl_delete_return = container .exec_run (["/bin/bash" , "-c" , f"doveadm acl delete -u '{ user } ' '{ mailbox } ' 'user={ id } '" ])
480
+ return self .exec_run_handler ('generic' , acl_delete_return )
481
+ # api call: container_post - post_action: exec - cmd: doveadm - task: set_acl
482
+ def container_post__exec__doveadm__set_acl (self , request_json , ** kwargs ):
483
+ if 'container_id' in kwargs :
484
+ filters = {"id" : kwargs ['container_id' ]}
485
+ elif 'container_name' in kwargs :
486
+ filters = {"name" : kwargs ['container_name' ]}
487
+
488
+ for container in self .sync_docker_client .containers .list (filters = filters ):
489
+ user = request_json ['user' ].replace ("'" , "'\\ ''" )
490
+ mailbox = request_json ['mailbox' ].replace ("'" , "'\\ ''" )
491
+ id = request_json ['id' ].replace ("'" , "'\\ ''" )
492
+ rights = ""
493
+
494
+ available_rights = [
495
+ "admin" ,
496
+ "create" ,
497
+ "delete" ,
498
+ "expunge" ,
499
+ "insert" ,
500
+ "lookup" ,
501
+ "post" ,
502
+ "read" ,
503
+ "write" ,
504
+ "write-deleted" ,
505
+ "write-seen"
506
+ ]
507
+ for right in request_json ['rights' ]:
508
+ right = right .replace ("'" , "'\\ ''" ).lower ()
509
+ if right in available_rights :
510
+ rights += right + " "
511
+
512
+ if user and mailbox and id and rights :
513
+ acl_set_return = container .exec_run (["/bin/bash" , "-c" , f"doveadm acl set -u '{ user } ' '{ mailbox } ' 'user={ id } ' { rights } " ])
514
+ return self .exec_run_handler ('generic' , acl_set_return )
515
+
377
516
378
517
# Collect host stats
379
518
async def get_host_stats (self , wait = 5 ):
@@ -462,7 +601,7 @@ def recv_socket_data(c_socket, timeout):
462
601
except :
463
602
pass
464
603
return '' .join (total_data )
465
-
604
+
466
605
try :
467
606
socket = container .exec_run ([shell_cmd ], stdin = True , socket = True , user = user ).output ._sock
468
607
if not cmd .endswith ("\n " ):
0 commit comments