#!/usr/share/ucs-test/runner python
## -*- coding: utf-8 -*-
## desc: run UDM hook oxUserDefaults, not havng root permissions
## tags: [apptest]
## exposure: dangerous
## packages:
##   - univention-ox
## bugs: [44197]

import os
import pwd
import univention.admin.uldap
import univention.admin.objects
import univention.testing.udm as testing_udm
import univention.testing.ucr as testing_ucr
import univention.testing.strings as uts
import univention.testing.utils as utils


MACHINE_SECRET_FILE = '/etc/machine.secret'


def read_machine_secret():
	return open(MACHINE_SECRET_FILE).read().rstrip('\n')


def get_ldap_connection(ucr):
	"""
	Get lo and po, allows this class to be used outside listener by root.
	:return: tuple (lo, po)
	"""
	print('*** Reading machine secret as current user (rUID={} eUID={})...'.format(os.getuid(), os.geteuid()))
	bind_pw = read_machine_secret()

	lo = univention.admin.uldap.access(
		host=ucr['ldap/server/name'],
		base=ucr['ldap/base'],
		binddn=ucr['ldap/hostdn'],
		bindpw=bind_pw)
	po = univention.admin.uldap.position(ucr['ldap/base'])
	return lo, po


def get_udm_user(userdn, lo, po):
	univention.admin.modules.update()
	usersmod = univention.admin.modules.get("users/user")
	univention.admin.modules.init(lo, po, usersmod)
	user = usersmod.object(None, lo, po, userdn)
	user.open()
	return user


def main():
	with testing_udm.UCSTestUDM() as udm, testing_ucr.UCSTestConfigRegistry() as ucr:
		mail_domain = ucr['mail/hosteddomains'].split()[0]

		print('*** Current process\'s real UID: {}'.format(os.getuid()))
		print('*** Current process\'s effective UID: {}'.format(os.geteuid()))

		lo, po = get_ldap_connection(ucr)

		print('*** Creating OX user...')
		ox_user_password = uts.random_string()
		ox_user_dn, ox_username = udm.create_user(
			mailPrimaryAddress='{}@{}'.format(uts.random_username(), mail_domain),
			password=ox_user_password,
			isOxUser='OK')

		print('*** Changing user to "listener"...')
		listener_uid = pwd.getpwnam("listener").pw_uid
		os.seteuid(listener_uid)
		print('*** Current process\'s real UID: {}'.format(os.getuid()))
		print('*** Current process\'s effective UID: {}'.format(os.geteuid()))

		print('*** Reading machine secret as current user (rUID={} eUID={})...'.format(os.getuid(), os.geteuid()))
		try:
			read_machine_secret()
			utils.fail('Could read {}.'.format(MACHINE_SECRET_FILE))
		except IOError as exc:
			print(exc)
			print('*** OK: cannot read {}.'.format(MACHINE_SECRET_FILE))

		print('*** Reading UDM user with current user (rUID={} eUID={})...'.format(os.getuid(), os.geteuid()))
		udm_user = get_udm_user(ox_user_dn, lo, po)
		if udm_user['username'] != ox_username:
			utils.fail('Got wrong user object:\n{!r}'.format(udm_user.__dict__))
		print('*** OK: udm_user[username]={!r}'.format(udm_user['username']))

		print('*** Changing user back to "root", so ucs-test cleanup can run...')
		os.seteuid(0)

if __name__ == '__main__':
	main()
