#!/usr/share/ucs-test/runner python
## desc: ucs-school-reset-password-check
## roles: [domaincontroller_master]
## tags: [apptest]
## exposure: dangerous
## packages: [ucs-school-umc-users]

from univention.lib.umc_connection import UMCConnection
import sys
import univention.testing.strings as uts
import univention.testing.ucr as ucr_test
import univention.testing.ucsschool as utu
import univention.testing.utils as utils

# test the authentication of the user name, password and return response status,
# else fails with an exception
def auth(host, username, password):
	connection = UMCConnection(host)
	data = connection.build_data({
		'username' : username,
		'password' : password
	})
	co = connection.get_connection()
	try:
		co.request('POST', '/umcp/auth', data)
		response = co.getresponse()
		return response.status
	except Exception as e:
		utils.fail("Auth exception: '%s' '%s' '%r'" % (str(e), type(e), e))

def test_pwd_reset(host, acting_user, flavor, target_user,	target_userdn,chg_pwd_on_next_login,
				   expected_reset_result, expected_auth_for_old_password,expected_auth_for_new_password):
	newpassword = uts.random_string()
	options = {
			'userDN': target_userdn,
			'newPassword': newpassword,
			'nextLogin': chg_pwd_on_next_login
			}
	connection = UMCConnection(host)
	connection.auth(acting_user, 'univention')
	try:
		resetResult = connection.request('schoolusers/password/reset', options, flavor)
		if str(resetResult) != expected_reset_result:
			utils.fail('umcp command schoolusers/password/reset was unexpectedly successful')
		utils.wait_for_replication()
		utils.wait_for_connector_replication()
	except Exception as e:
		if expected_reset_result in str(e):
			print 'Caught expected exception'
		else:
			utils.fail('Caught unexpected exception: %s' % e)
	# test if old password does NOT work
	authResult = auth(host, target_user, 'univention')
	if authResult != expected_auth_for_old_password:
		utils.fail('unexpected authentication result (%s)' % authResult)
	# test if new password does work
	authResult = auth(host, target_user, newpassword)
	if authResult != expected_auth_for_new_password:
		utils.fail('unexpected authentication result (%s)' % authResult)

def main():
	ucr =  ucr_test.UCSTestConfigRegistry()
	ucr.load()
	host = ucr.get('hostname')
	with utu.UCSTestSchool()  as schoolenv:
		school, oudn = schoolenv.create_ou(name_edudc=host)

		school_admin_dn, school_admin = schoolenv.create_school_admin(school)

		tea1, tea1_dn = schoolenv.create_user(school, is_teacher=True)
		stu1, stu1_dn = schoolenv.create_user(school)

		tea2, tea2_dn = schoolenv.create_user(school, is_teacher=True)
		stu2, stu2_dn = schoolenv.create_user(school)

		tea3, tea3_dn = schoolenv.create_user(school, is_teacher=True)
		stu3, stu3_dn = schoolenv.create_user(school)

		tea4, tea4_dn = schoolenv.create_user(school, is_teacher=True)
		stu4, stu4_dn = schoolenv.create_user(school)

		utils.wait_for_replication_and_postrun()

		# test if school admin is able to reset teacher password (chgPwdNextLogin=True)
		test_pwd_reset(host, school_admin, 'teacher', tea1, tea1_dn, True, 'True', 411, 415)
		test_pwd_reset(host, school_admin, 'student', tea3, tea3_dn, True, 'True', 411, 415)

		# test if school admin is able to reset student password (chgPwdNextLogin=True)
		test_pwd_reset(host, school_admin, 'teacher', stu1, stu1_dn, True, 'True', 411, 415)
		test_pwd_reset(host, school_admin, 'student', stu3, stu3_dn, True, 'True', 411, 415)

		# test if school admin is able to reset teacher password (chgPwdNextLogin=False)
		test_pwd_reset(host, school_admin, 'student', tea2, tea2_dn, False, 'True', 411, 200)
		test_pwd_reset(host, school_admin, 'teacher', tea4, tea4_dn, False, 'True', 411, 200)

		# test if school admin is able to reset student password (chgPwdNextLogin=False)
		test_pwd_reset(host, school_admin, 'student', stu2, stu2_dn, False, 'True', 411, 200)
		test_pwd_reset(host, school_admin, 'teacher', stu4, stu4_dn, False, 'True', 411, 200)

if __name__ == '__main__':
	sys.exit(main())
