# -*- coding: iso-8859-15 -*-

import sys
import unittest

glasnostPythonDir = '/usr/local/lib/glasnost-tests'
sys.path.insert(0, glasnostPythonDir)

from GlasnostTestCase import MinimalTestCase

import glasnost.common.context as context
import glasnost.common.faults as faults
import glasnost.common.system as system
import glasnost.common.tools_new as commonTools

from glasnost.proxy.tools import getProxyForServerRole


authenticationProxy = getProxyForServerRole('authentication')
authenticationLPProxy = getProxyForServerRole('authentication-login-password')
peopleProxy = getProxyForServerRole('people')

class AuthenticationLoginPasswordTestCase(MinimalTestCase):
    pass


class AddAccountTestCase(AuthenticationLoginPasswordTestCase):
    def setUp(self):
        AuthenticationLoginPasswordTestCase.setUp(self)
        user = commonTools.newThing('object', 'people.Person')
        user.firstName = 'test'
        user.lastName = 'user'
        user.email = 'test@example.com'
        self.userId = peopleProxy.addObject(user)

    def tearDown(self):
        peopleProxy.deleteObject(self.userId)

        admin = authenticationLPProxy.getAdmin()
        admin.userCanChoosePassword = 0
        authenticationLPProxy.modifyAdmin(admin)

        AuthenticationLoginPasswordTestCase.tearDown(self)

    def test01_withValidUser(self):
        '''Add an account for a valid user'''
        authObject = authenticationLPProxy.newAuthenticationObject()
        authObject.login = 'test'
        authObject.password = 'test'
        authenticationLPProxy.addAccount(self.userId, authObject)
        
        authenticationLPProxy.deleteAccount(authObject)

    def test02_withMissingUser(self):
        '''Add an account for a missing user'''
        authObject = authenticationLPProxy.newAuthenticationObject()
        authObject.login = 'test'
        authObject.password = 'test'
        try:
            authenticationLPProxy.addAccount(self.userId + '00', authObject)
            authenticationLPProxy.deleteAccount(authObject)
        except faults.MissingItem:
            return
        self.fail('Server accepted a missing user')

    def test03_withoutPassword(self):
        '''Add an account without password'''
        authObject = authenticationLPProxy.newAuthenticationObject()
        authObject.login = 'test'

        try:
            authenticationLPProxy.addAccount(self.userId, authObject)
        except:
            self.fail('Server didn\'t accept an account without password')
        authenticationLPProxy.deleteAccount(authObject)

    def test04_withoutLogin(self):
        '''Add an account without login'''
        authObject = authenticationLPProxy.newAuthenticationObject()
        authObject.password = 'test'

        try:
            authenticationLPProxy.addAccount(self.userId, authObject)
        except faults.MissingSlotValue:
            return
        self.fail('Server accepted an account without login')

    def test05_withoutLoginNorPassword(self):
        '''Add an account without login and password'''
        authObject = authenticationLPProxy.newAuthenticationObject()

        try:
            authenticationLPProxy.addAccount(self.userId, authObject)
        except faults.MissingSlotValue:
            return
        self.fail('Server accepted an account without login and password')


class DeleteAccountTestCase(AuthenticationLoginPasswordTestCase):
    def setUp(self):
        AuthenticationLoginPasswordTestCase.setUp(self)

        user = commonTools.newThing('object', 'people.Person')
        user.firstName = 'test'
        user.lastName = 'user'
        user.email = 'test@example.com'
        self.userId = peopleProxy.addObject(user)

        authObject = authenticationLPProxy.newAuthenticationObject()
        authObject.login = 'test'
        authObject.password = 'test'
        authenticationLPProxy.addAccount(self.userId, authObject)

    def tearDown(self):
        peopleProxy.deleteObject(self.userId)

        admin = authenticationLPProxy.getAdmin()
        admin.userCanChoosePassword = 0
        authenticationLPProxy.modifyAdmin(admin)

        authObject = authenticationLPProxy.newAuthenticationObject()
        authObject.login = 'test'
        try:
            authenticationLPProxy.deleteAccount(authObject)
        except faults.WrongLogin:
            pass

        AuthenticationLoginPasswordTestCase.tearDown(self)
    
    def test01_correctAccount(self):
        '''Delete an account'''
        authObject = authenticationLPProxy.newAuthenticationObject()
        authObject.login = 'test'

        authenticationLPProxy.deleteAccount(authObject)

    def test02_missingAccount(self):
        '''Delete a missing account'''
        authObject = authenticationLPProxy.newAuthenticationObject()
        authObject.login = 'not-there'

        try:
            authenticationLPProxy.deleteAccount(authObject)
        except faults.WrongLogin:
            return
        self.fail('Server accepted to delete a missing account')


class CheckAuthenticationTestCase(AuthenticationLoginPasswordTestCase):
    def setUp(self):
        AuthenticationLoginPasswordTestCase.setUp(self)

        user = commonTools.newThing('object', 'people.Person')
        user.firstName = 'test'
        user.lastName = 'user'
        user.email = 'test@example.com'
        self.userId = peopleProxy.addObject(user)

        admin = authenticationLPProxy.getAdmin()
        admin.userCanChoosePassword = 1
        authenticationLPProxy.modifyAdmin(admin)
        
        authObject = authenticationLPProxy.newAuthenticationObject()
        authObject.login = 'test'
        authObject.password = 'test'
        authenticationLPProxy.addAccount(self.userId, authObject)

    def tearDown(self):
        peopleProxy.deleteObject(self.userId)

        admin = authenticationLPProxy.getAdmin()
        admin.userCanChoosePassword = 0
        authenticationLPProxy.modifyAdmin(admin)
        
        authObject = authenticationLPProxy.newAuthenticationObject()
        authObject.login = 'test'
        authenticationLPProxy.deleteAccount(authObject)

        AuthenticationLoginPasswordTestCase.tearDown(self)
    
    def test01_correctLoginPassword(self):
        '''Authenticate with correct login and password'''
        authObject = authenticationLPProxy.newAuthenticationObject()
        authObject.login = 'test'
        authObject.password = 'test'

        result = authenticationLPProxy.checkAuthentication(
                authObject.exportToXmlRpc())
        self.failUnless(result == self.userId)

    def test02_badLogin(self):
        '''Authenticate with wrong login'''
        authObject = authenticationLPProxy.newAuthenticationObject()
        authObject.login = 'wrong login'
        authObject.password = 'test'

        try:
            authenticationLPProxy.checkAuthentication(
                    authObject.exportToXmlRpc())
        except faults.WrongLogin:
            return
        self.fail('Logged in with wrong login')

    def test03_badPassword(self):
        '''Authenticate with wrong password'''
        authObject = authenticationLPProxy.newAuthenticationObject()
        authObject.login = 'test'
        authObject.password = 'wrong password'

        try:
            authenticationLPProxy.checkAuthentication(
                    authObject.exportToXmlRpc())
        except faults.WrongPassword:
            return
        self.fail('Logged in with wrong password')

        
suite1 = unittest.makeSuite(AddAccountTestCase, 'test')
suite2 = unittest.makeSuite(DeleteAccountTestCase, 'test')
suite3 = unittest.makeSuite(CheckAuthenticationTestCase, 'test')

allTests = unittest.TestSuite((suite1, suite2, suite3))

if __name__ == '__main__':
    unittest.TextTestRunner(verbosity=2).run(allTests)

