#!/usr/share/ucs-test/runner python
## desc: http-proxy-basic-auth-check
## roles: [domaincontroller_master, domaincontroller_backup, domaincontroller_slave, memberserver]
## tags: [apptest,ucsschool]
## exposure: dangerous
## packages: [ucs-school-webproxy]

from essential.internetrule import InternetRule
from essential.klasse import Klasse
from essential.simplecurl import SimpleCurl
from essential.workgroup import Workgroup
from univention.lib.umc_connection import UMCConnection
import univention.testing.ucr as ucr_test
import univention.testing.ucsschool as utu
import univention.testing.utils as utils

# Checks a list of rules defined and return the active rule
# for a specific user
def ruleInControl(user, ruleList, host, banPage):
	inCtrl = []
	localCurl = SimpleCurl(proxy=host, username=user)
	ruleList = [rule for rule in ruleList if rule is not None]
	for rule in ruleList:
		if rule.typ == 'blacklist':
			if all(localCurl.getPage(dom) == banPage for dom in rule.domains):
				inCtrl.append(rule)
		elif rule.typ == 'whitelist':
			if all(localCurl.getPage(dom) != banPage for dom in rule.domains):
				inCtrl.append(rule)
	localCurl.close()
	# return the bigger rule 
	# in case one rule is contained in another
	result = [
			x.name for x in inCtrl if len(x.domains) == max(
				len(y.domains) for y in inCtrl)
			]
	print 'Rule in control =', result
	return result[0]

# Perform the whole check steps for a user and two rules
def doCheck(
		host,
		banPage,
		user,
		rulesType,
		ruleWithHigherPrio,
		ruleWithLowerPrio=None):
	ruleInCtrl = ruleInControl(
			user,
			[ruleWithLowerPrio,	ruleWithHigherPrio],
			host,
			banPage)
	if ruleInCtrl != ruleWithHigherPrio.name:
		utils.fail('rule in Ctrl for user (%s): expected (%s), current (%s)' %(
			user, ruleWithHigherPrio.name, ruleInCtrl))
	else:
		print 'TEST PASSED: rule in Ctrl for user (%s) is (%s)' % (
				user, ruleInCtrl)


def main():
	with utu.UCSTestSchool()  as schoolenv:
		with ucr_test.UCSTestConfigRegistry() as ucr:
			host = ucr.get('hostname')
			connection = UMCConnection(host)
			account = utils.UCSTestDomainAdminCredentials()
			admin = account.username
			passwd = account.bindpw
			connection.auth(admin, passwd)

			# create ou
			school, oudn = schoolenv.create_ou(name_edudc=host)
			# create class
			newClass = Klasse(school, ucr=ucr)
			newClass.create()

			# create user in that class student/teacher
			tea, teadn = schoolenv.create_user(school,	classes='%s-%s' % (
				school, newClass.name), is_teacher=True)
			stu, studn = schoolenv.create_user(school,	classes='%s-%s' % (
				school, newClass.name))

			# Getting the redirection page when blocked
			adminCurl = SimpleCurl(proxy=host)
			redirUri = ucr.get('proxy/filter/redirecttarget')
			banPage = adminCurl.getPage(redirUri)
			adminCurl.close()

			# define whitelist internet rule
			rule1 = InternetRule(
					ucr=ucr,
					umcConnection=connection,
					typ='whitelist',
					domains=['univention.de'],
					priority=3)
			rule1.define()

			# assign whitelist rule1 to the class
			rule1.assign(school, newClass.name, 'class')

			utils.wait_for_replication_and_postrun()
			# Check for whitelist and student
			# for one rule
			doCheck(host, banPage, stu,'whitelist', rule1)
			# Check for whitelist and teacher
			# for one rule
			doCheck(host, banPage, tea,'whitelist', rule1)

			# create a workgroup
			newWorkgroup = Workgroup(
				school,
				ucr=ucr,
				members=[teadn, studn])
			newWorkgroup.create()

			# define different rule with higher priority
			rule2 = InternetRule(
					ucr=ucr,
					umcConnection=connection,
					typ='whitelist',
					domains=['google.de', 'gmx.net'],
					priority=4)
			rule2.define()

			# Assign whitelist rule to the new Workgroup
			rule2.assign(school, newWorkgroup.name, 'workgroup')
			utils.wait_for_replication_and_postrun()

			# Check for whitelist and student
			# for two rules with different priotities
			doCheck(host, banPage, stu,'whitelist', rule2, rule1)

			# Check for whitelist and teacher
			# for two rules with different priotities
			doCheck(host, banPage, tea,'whitelist', rule2, rule1)

			# switch rule1 to be 'blacklist' with higher proirity
			rule1.put(new_type='blacklist', new_priority=5)
			
			# Check for blacklist and student
			# for one rule
			doCheck(host, banPage, stu,'blacklist', rule1)

			# Check for blacklist and teacher
			# for one rule
			doCheck(host, banPage, tea,'blacklist', rule1)

			# switch rule2 to be 'blacklist' with higher proirity
			rule2.put(new_type='blacklist', new_priority=6)

			# Check for blacklist and student
			# for two rules with different priotities
			doCheck(host, banPage, stu,'blacklist', rule2, rule1)

			# Check for blacklist and teacher
			# for two rules with different priotities
			doCheck(host, banPage, tea,'blacklist', rule2, rule1)


if __name__ == '__main__':
	main()
