# Copyright (c) 2015, JINGROW and Contributors
# License: MIT. See LICENSE
import time

import jingrow
from jingrow.auth import CookieManager, LoginManager
from jingrow.tests.utils import JingrowTestCase


class TestSystemLog(JingrowTestCase):
	def setUp(self) -> None:
		jingrow.set_user("Administrator")

	def test_system_log(self):
		# test user login log
		jingrow.local.form_dict = jingrow._dict(
			{
				"cmd": "login",
				"sid": "Guest",
				"pwd": self.ADMIN_PASSWORD or "admin",
				"usr": "Administrator",
			}
		)

		jingrow.local.request_ip = "127.0.0.1"
		jingrow.local.cookie_manager = CookieManager()
		jingrow.local.login_manager = LoginManager()

		auth_log = self.get_auth_log()
		self.assertFalse(jingrow.form_dict.pwd)
		self.assertEqual(auth_log.status, "Success")

		# test user logout log
		jingrow.local.login_manager.logout()
		auth_log = self.get_auth_log(operation="Logout")
		self.assertEqual(auth_log.status, "Success")

		# test invalid login
		jingrow.form_dict.update({"pwd": "password"})
		self.assertRaises(jingrow.AuthenticationError, LoginManager)
		auth_log = self.get_auth_log()
		self.assertEqual(auth_log.status, "Failed")

		jingrow.local.form_dict = jingrow._dict()

	def get_auth_log(self, operation="Login"):
		names = jingrow.get_all(
			"System Log",
			filters={
				"user": "Administrator",
				"operation": operation,
			},
			order_by="`creation` DESC",
		)

		name = names[0]
		return jingrow.get_pg("System Log", name)

	def test_brute_security(self):
		update_system_settings({"allow_consecutive_login_attempts": 3, "allow_login_after_fail": 5})

		jingrow.local.form_dict = jingrow._dict(
			{"cmd": "login", "sid": "Guest", "pwd": self.ADMIN_PASSWORD, "usr": "Administrator"}
		)

		jingrow.local.request_ip = "127.0.0.1"
		jingrow.local.cookie_manager = CookieManager()
		jingrow.local.login_manager = LoginManager()

		auth_log = self.get_auth_log()
		self.assertEqual(auth_log.status, "Success")

		# test user logout log
		jingrow.local.login_manager.logout()
		auth_log = self.get_auth_log(operation="Logout")
		self.assertEqual(auth_log.status, "Success")

		# test invalid login
		jingrow.form_dict.update({"pwd": "password"})
		self.assertRaises(jingrow.AuthenticationError, LoginManager)
		self.assertRaises(jingrow.AuthenticationError, LoginManager)
		self.assertRaises(jingrow.AuthenticationError, LoginManager)

		# REMOVE ME: current logic allows allow_consecutive_login_attempts+1 attempts
		# before raising security exception, remove below line when that is fixed.
		self.assertRaises(jingrow.AuthenticationError, LoginManager)
		self.assertRaises(jingrow.SecurityException, LoginManager)
		time.sleep(5)
		self.assertRaises(jingrow.AuthenticationError, LoginManager)

		jingrow.local.form_dict = jingrow._dict()


def update_system_settings(args):
	pg = jingrow.get_pg("System Settings")
	pg.update(args)
	pg.flags.ignore_mandatory = 1
	pg.save()
