#!/usr/share/ucs-test/runner python
## desc: ucs-school-reset-password-check
## roles: [domaincontroller_master, domaincontroller_slave]
## tags: [apptest,ucsschool]
## 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:
		schoolName, oudn = schoolenv.create_ou(name_edudc=host)
		teachers = []
		teachersDn = []
		students = []
		studentsDn = []
		for i in [0,1]:
			tea, teadn = schoolenv.create_user(schoolName, is_teacher=True)
			teachers.append(tea)
			teachersDn.append(teadn)
			stu, studn = schoolenv.create_user(schoolName)
			students.append(stu)
			studentsDn.append(studn)

		utils.wait_for_replication_and_postrun()

		# test if teacher is unable to reset teacher password (chgPwdNextLogin=True)
		test_pwd_reset(host, teachers[0], 'teacher', teachers[1] ,teachersDn[1], True, 'command forbidden', 200, 411)

		# test if student is unable to reset teacher password (chgPwdNextLogin=True)
		test_pwd_reset(host, students[0], 'teacher', teachers[1] , teachersDn[1], True, 'command forbidden', 200, 411)

		# test if student is unable to reset student password (chgPwdNextLogin=True)
		test_pwd_reset(host, students[0], 'student', students[1] , studentsDn[1], True, 'command forbidden', 200, 411)

		# test if teacher is unable to reset teacher password (chgPwdNextLogin=False)
		test_pwd_reset(host, teachers[0], 'teacher', teachers[1] , teachersDn[1], False, 'command forbidden', 200, 411)

		# test if student is unable to reset teacher password (chgPwdNextLogin=False)
		test_pwd_reset(host, students[0], 'teacher', teachers[1] , teachersDn[1], False, 'command forbidden', 200, 411)

		# test if student is unable to reset student password (chgPwdNextLogin=False)
		test_pwd_reset(host, students[0], 'student', students[1] , studentsDn[1], False, 'command forbidden', 200, 411)

		# test if teacher is able to reset student password (chgPwdNextLogin=True)
		test_pwd_reset(host, teachers[0], 'student', students[1], studentsDn[1], True, 'True', 411, 415)

		# test if teacher is able to reset student password (chgPwdNextLogin=False)
		test_pwd_reset(host, teachers[0], 'student', students[0] , studentsDn[0], False, 'True', 411, 200)

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