#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# Univention Mail Dovecot - reapply shared folder ACLs
#
# Like what you see? Join us!
# https://www.univention.com/about-us/careers/vacancies/
#
# Copyright 2015-2023 Univention GmbH
#
# https://www.univention.de/
#
# All rights reserved.
#
# The source code of this program is made available
# under the terms of the GNU Affero General Public License version 3
# (GNU AGPL V3) as published by the Free Software Foundation.
#
# Binary versions of this program provided by Univention to you as
# well as other copyrighted, protected or trademarked materials like
# Logos, graphics, fonts, specific documentations and configurations,
# cryptographic keys etc. are subject to a license agreement between
# you and Univention and not subject to the GNU AGPL V3.
#
# In the case you use this program under the terms of the GNU AGPL V3,
# the program is provided in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License with the Debian GNU/Linux or Univention distribution in file
# /usr/share/common-licenses/AGPL-3; if not, see
# <https://www.gnu.org/licenses/>.

import copy
import argparse

import ldap.filter

import univention.debug as ud
from univention.config_registry import ConfigRegistry
from univention.uldap import getMachineConnection
from univention.mail.dovecot_shared_folder import DovecotSharedFolderListener


class ListenerMockup(object):

	def __init__(self, ucr):
		self.configRegistry = ucr

	def unsetuid(self):
		pass

	def setuid(self, uid):
		pass


def main():
	parser = argparse.ArgumentParser(description='Reapplies the ACLs to all shared IMAP folder on this system.')
	parser.add_argument("-v", "--verbose", action="store_true", help="show verbose output additionally on stdout")
	parser.add_argument("-n", "--dry-run", action="store_true", help="perform dry run without changes")
	options = parser.parse_args()

	# open log file
	ud.init('/var/log/univention/reapply_shared_folder_acls.log', ud.NO_FLUSH, ud.NO_FUNCTION)
	ud.set_level(ud.MAIN, ud.ALL)
	ud.set_level(ud.LISTENER, ud.ALL)

	def log(level, msg):
		ud.debug(ud.MAIN, level, msg)
		if options.verbose:
			print(msg)

	ucr = ConfigRegistry()
	ucr.load()

	ldapfilter = ldap.filter.filter_format('(&(objectClass=univentionMailSharedFolder)(univentionMailHomeServer=%s.%s))', (
		ucr['hostname'],
		ucr['domainname'],
	))

	log(ud.INFO, 'Initialising reapply_shared_folder_acls...')
	lm = ListenerMockup(ucr)
	dl = DovecotSharedFolderListener(lm, 'reapply_shared_folder_acls')

	# get ldap connection
	lo = getMachineConnection()
	log(ud.INFO, 'Looking for objects matching to following LDAP filter:\n   %s' % (ldapfilter,))
	for dn, attrs_new in lo.search(filter=ldapfilter):
		log(ud.PROCESS, 'DN: %r' % (dn,))
		attrs_old = copy.deepcopy(attrs_new)
		attrs_old[dl.acl_key] = []
		if not options.dry_run:
			dl.mod_shared_folder(attrs_old, attrs_new)
			log(ud.PROCESS, 'ACLs updated')
		else:
			log(ud.PROCESS, 'dry-run: skipping object')
	log(ud.PROCESS, 'Done')


if __name__ == '__main__':
	main()
