""" Basic unit tests for AuthManager
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import unittest

from diraccfg import CFG
from DIRAC import gConfig
from DIRAC.Core.DISET.AuthManager import AuthManager

__RCSID__ = "$Id$"

testSystemsCFG = """
Systems
{
  Service
  {
    Authorization
    {
      Method = NormalUser
      MethodAll = Any
      MethodAuth = Authenticated
      MethodGroup = NormalUser,group:group_test
      MethodGroupOther = NormalUser,group:group_test_other
      MethodAllGroup = Any,group:group_test
      MethodAllGroupOther = Any,group:group_test_other
      MethodAuthGroup = Authenticated,group:group_test
      MethodAuthGroupOther = Authenticated,group:group_test_other
      MethodVO = NormalUser,vo:testVO
      MethodAllVO = Any,vo:testVO
      MethodAuthVO = Authenticated,vo:testVO
      MethodHost = group:hosts
      MethodTrustedHost = TrustedHost,group:hosts
    }
  }
}
"""

testRegistryCFG = """
Registry
{
  VO
  {
    testVO
    {
      VOAdmin = userA
    }
    testVOBad
    {
      VOAdmin = userB
    }
    testVOOther
    {
      VOAdmin = userA
    }
  }
  Users
  {
    userA
    {
      DN = /User/test/DN/CN=userA
    }
    userB
    {
      DN = /User/test/DN/CN=userB
    }
    userS
    {
      DN = /User/test/DN/CN=userS
      Suspended = testVO
    }
  }
  Hosts
  {
    test.hostA.ch
    {
      DN = /User/test/DN/CN=test.hostA.ch
      Properties = TrustedHost
    }
    test.hostB.ch
    {
      DN = /User/test/DN/CN=test.hostB.ch
      Properties = NoTrustedHost
    }
  }
  Groups
  {
    group_test
    {
      Users = userA, userS
      VO = testVO
      Properties = NormalUser
    }
    group_test_other
    {
      Users = userS
      VO = testVOOther
      Properties = NormalUser
    }
    group_bad
    {
      Users = userB
      VO = testVOBad
      Properties = NoProperties
    }
  }
}
"""


class AuthManagerTest(unittest.TestCase):
    """Base class for the Modules test cases"""

    def setUp(self):
        self.authMgr = AuthManager("/Systems/Service/Authorization")
        cfg = CFG()
        cfg.loadFromBuffer(testSystemsCFG)
        gConfig.loadCFG(cfg)
        cfg.loadFromBuffer(testRegistryCFG)
        gConfig.loadCFG(cfg)

        self.noAuthCredDict = {"group": "group_test"}

        self.userCredDict = {"DN": "/User/test/DN/CN=userA", "group": "group_test"}
        self.suspendedOtherVOUserCredDict = {"DN": "/User/test/DN/CN=userS", "group": "group_test_other"}
        self.badUserCredDict = {"DN": "/User/test/DN/CN=userB", "group": "group_bad"}
        self.suspendedUserCredDict = {"DN": "/User/test/DN/CN=userS", "group": "group_test"}
        self.hostCredDict = {"DN": "/User/test/DN/CN=test.hostA.ch", "group": "hosts"}
        self.badHostCredDict = {"DN": "/User/test/DN/CN=test.hostB.ch", "group": "hosts"}

    def tearDown(self):
        pass

    def test_userProperties(self):

        # MethodAll accepts everybody
        result = self.authMgr.authQuery("MethodAll", self.userCredDict)
        self.assertTrue(result)
        result = self.authMgr.authQuery("MethodAll", self.noAuthCredDict)
        self.assertTrue(result)
        result = self.authMgr.authQuery("MethodAll", self.badUserCredDict)
        self.assertTrue(result)
        result = self.authMgr.authQuery("MethodAll", self.suspendedUserCredDict)
        self.assertTrue(result)
        result = self.authMgr.authQuery("MethodAll", self.suspendedOtherVOUserCredDict)
        self.assertTrue(result)

        # MethodAuth requires DN to be identified
        result = self.authMgr.authQuery("MethodAuth", self.userCredDict)
        self.assertTrue(result)
        result = self.authMgr.authQuery("MethodAuth", self.noAuthCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodAuth", self.badUserCredDict)
        self.assertTrue(result)
        result = self.authMgr.authQuery("MethodAuth", self.suspendedUserCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodAuth", self.suspendedOtherVOUserCredDict)
        self.assertTrue(result)

        # Method requires NormalUser property
        result = self.authMgr.authQuery("Method", self.userCredDict)
        self.assertTrue(result)
        result = self.authMgr.authQuery("Method", self.badUserCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("Method", self.noAuthCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("Method", self.suspendedUserCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("Method", self.suspendedOtherVOUserCredDict)
        self.assertTrue(result)

    def test_userGroup(self):

        # MethodAllGroup accepts everybody from the right group
        result = self.authMgr.authQuery("MethodAllGroup", self.userCredDict)
        self.assertTrue(result)
        result = self.authMgr.authQuery("MethodAllGroup", self.noAuthCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodAllGroup", self.badUserCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodAllGroup", self.suspendedUserCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodAllGroup", self.suspendedOtherVOUserCredDict)
        self.assertFalse(result)

        # MethodAllGroupOther accepts everybody from the right group
        result = self.authMgr.authQuery("MethodAllGroupOther", self.userCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodAllGroupOther", self.noAuthCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodAllGroupOther", self.badUserCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodAllGroupOther", self.suspendedUserCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodAllGroupOther", self.suspendedOtherVOUserCredDict)
        self.assertTrue(result)

        # MethodAuthGroup requires DN to be identified from the right group
        result = self.authMgr.authQuery("MethodAuthGroup", self.userCredDict)
        self.assertTrue(result)
        result = self.authMgr.authQuery("MethodAuthGroup", self.noAuthCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodAuthGroup", self.badUserCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodAuthGroup", self.suspendedUserCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodAuthGroup", self.suspendedOtherVOUserCredDict)
        self.assertFalse(result)

        # MethodAuthGroupOther requires DN to be identified from the right group
        result = self.authMgr.authQuery("MethodAuthGroupOther", self.userCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodAuthGroupOther", self.noAuthCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodAuthGroupOther", self.badUserCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodAuthGroupOther", self.suspendedUserCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodAuthGroupOther", self.suspendedOtherVOUserCredDict)
        self.assertTrue(result)

        # MethodGroup requires NormalUser property and the right group
        result = self.authMgr.authQuery("MethodGroup", self.userCredDict)
        self.assertTrue(result)
        result = self.authMgr.authQuery("MethodGroup", self.badUserCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodGroup", self.noAuthCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodGroup", self.suspendedUserCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodGroup", self.suspendedOtherVOUserCredDict)
        self.assertFalse(result)

        # MethodGroupOther requires NormalUser property and the right group
        result = self.authMgr.authQuery("MethodGroupOther", self.userCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodGroupOther", self.badUserCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodGroupOther", self.noAuthCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodGroupOther", self.suspendedUserCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodGroupOther", self.suspendedOtherVOUserCredDict)
        self.assertTrue(result)

    def test_userVO(self):

        # MethodAllGroup accepts everybody from the right group
        result = self.authMgr.authQuery("MethodAllVO", self.userCredDict)
        self.assertTrue(result)
        result = self.authMgr.authQuery("MethodAllVO", self.noAuthCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodAllVO", self.badUserCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodAllVO", self.suspendedUserCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodAllVO", self.suspendedOtherVOUserCredDict)
        self.assertFalse(result)

        # MethodAuthGroup requires DN to be identified from the right group
        result = self.authMgr.authQuery("MethodAuthVO", self.userCredDict)
        self.assertTrue(result)
        result = self.authMgr.authQuery("MethodAuthVO", self.noAuthCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodAuthVO", self.badUserCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodAuthVO", self.suspendedUserCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodAuthVO", self.suspendedOtherVOUserCredDict)
        self.assertFalse(result)

        # Method requires NormalUser property and the right group
        result = self.authMgr.authQuery("MethodVO", self.userCredDict)
        self.assertTrue(result)
        result = self.authMgr.authQuery("MethodVO", self.badUserCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodVO", self.noAuthCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodVO", self.suspendedUserCredDict)
        self.assertFalse(result)
        result = self.authMgr.authQuery("MethodVO", self.suspendedOtherVOUserCredDict)
        self.assertFalse(result)

    def test_hostProperties(self):

        # MethodAll accepts everybody
        result = self.authMgr.authQuery("MethodAll", self.hostCredDict)
        self.assertTrue(result)
        result = self.authMgr.authQuery("MethodAll", self.badHostCredDict)
        self.assertTrue(result)

        # MethodAuth requires DN to be identified
        result = self.authMgr.authQuery("MethodAuth", self.hostCredDict)
        self.assertTrue(result)
        result = self.authMgr.authQuery("MethodAuth", self.badHostCredDict)
        self.assertTrue(result)

        # Method requires NormalUser property
        result = self.authMgr.authQuery("Method", self.hostCredDict)
        self.assertFalse(result)

        # MethodHost requires hosts group
        result = self.authMgr.authQuery("MethodHost", self.hostCredDict)
        self.assertTrue(result)
        result = self.authMgr.authQuery("MethodHost", self.badHostCredDict)
        self.assertTrue(result)

        # MethodTrustedHost requires hosts group and TrustedHost property
        result = self.authMgr.authQuery("MethodTrustedHost", self.hostCredDict)
        self.assertTrue(result)
        result = self.authMgr.authQuery("MethodTrustedHost", self.badHostCredDict)
        self.assertFalse(result)


if __name__ == "__main__":
    suite = unittest.defaultTestLoader.loadTestsFromTestCase(AuthManagerTest)
    testResult = unittest.TextTestRunner(verbosity=2).run(suite)
