# Copyright (C) 2009, 2010 Canonical Ltd
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import os
from unittest import TestCase

from apache_openid import get_action_path
from apache_openid.handlers.openid.authenticator import Authenticator
from apache_openid.handlers.openidteams.authenticator import TeamsAuthenticator
from apache_openid.utils.mock import ApacheMockRequest, Options, Session
from apache_openid.request import Request

__all__ = ['AuthenticatorTest', 'TeamsAuthenticatorTest']


class AuthenticatorTestCase(TestCase):

    def setUp(self):
        self.apache_request = ApacheMockRequest()
        self.overrides = {
            'authorized-teams': "canonical-isd-hackers bzr-core",
            'action-path': "/openid",
        }
        self.options = Options(self.overrides)
        self.action_path = get_action_path(self.options, self.apache_request)
        self.session = Session()
        self.request = Request(
            self.apache_request, self.action_path, self.session)


class AuthenticatorTest(AuthenticatorTestCase):

    def setUp(self):
        super(AuthenticatorTest, self).setUp()
        self.authenticator = Authenticator(self.request, self.options)

    def test_authenticate(self):
        self.assertEqual(self.authenticator.authenticate(None), False)
        self.assertEqual(
            self.authenticator.authenticate('https://login.launchpad.net/+id/1234567'),
            False)
        self.overrides['authorized-users'] = "https://login.launchpad.net/+id/1234567\n"
        self.options = Options(self.overrides)
        self.authenticator = Authenticator(self.request, self.options)
        self.assertEqual(
            self.authenticator.authenticate('https://login.launchpad.net/+id/1234567'),
            True)

    def test_authorized_urls(self):
        self.overrides['authorized-users'] = "https://login.launchpad.net/+id/abcdefg "\
            "https://login.launchpad.net/+id/gfedcba"
        self.overrides['authorized-users-list-url'] = "file://%s" % os.path.abspath(os.path.join(os.path.dirname(__file__), 'authorized-users.txt'))
        self.options = Options(self.overrides)
        self.authenticator = Authenticator(self.request, self.options)
        self.assertEqual(
            self.authenticator.authorized_urls,
            [
                'https://login.launchpad.net/+id/abcdefg',
                'https://login.launchpad.net/+id/gfedcba',
                'https://login.launchpad.net/+id/1234567',
                'https://login.launchpad.net/+id/7654321',
            ])

    def test_get_authorized_urls_from_options(self):
        self.overrides['authorized-users'] = "https://login.launchpad.net/+id/1234567 "\
            "https://login.launchpad.net/+id/7654321"
        self.options = Options(self.overrides)
        self.authenticator = Authenticator(self.request, self.options)
        self.assertEqual(
            self.authenticator.get_authorized_urls_from_options(),
            [
                'https://login.launchpad.net/+id/1234567',
                'https://login.launchpad.net/+id/7654321',
            ])

    def test_get_authorized_urls_from_url(self):
        url = "file://%s" % os.path.abspath(os.path.join(os.path.dirname(__file__), 'authorized-users.txt'))
        self.assertEqual(
            self.authenticator.get_authorized_urls_from_url(url),
            [
                'https://login.launchpad.net/+id/1234567',
                'https://login.launchpad.net/+id/7654321',
            ])

    def test_get_authorized_urls_from_url_error(self):
        url = 'http://www.non-existing-host.com/this/page/doesnt/exist/'
        self.assertEqual(
            self.authenticator.get_authorized_urls_from_url(url),
            [])

    def test_parse_authorized_urls(self):
        data = """https://login.launchpad.net/+id/1234567
#https://login.launchpad.net/+id/7654321
https://login.launchpad.net/+id/abcdefg
"""
        self.assertEqual(
            self.authenticator.parse_authorized_urls(data),
            [
                'https://login.launchpad.net/+id/1234567',
                'https://login.launchpad.net/+id/abcdefg',
            ])


class TeamsAuthenticatorTest(AuthenticatorTestCase):

    def setUp(self):
        super(TeamsAuthenticatorTest, self).setUp()
        self.session = Session()
        self.authenticator = TeamsAuthenticator(
            self.request, self.options, self.session)

    def test_check_team_entitlement(self):
        self.assertEqual(
            self.authenticator.check_team_entitlement([], []),
            False)
        self.assertEqual(
            self.authenticator.check_team_entitlement(
                ['test-team'],
                ['another-team']),
            False)
        self.assertEqual(
            self.authenticator.check_team_entitlement(
                ['test-team', 'another-team'],
                ['another-team']),
            True)

    def test_authenticate(self):
        self.assertEqual(self.authenticator.authenticate(None), False)
        self.authenticator.cookied_teams = ['ubuntumembers']
        self.assertEqual(
            self.authenticator.authenticate(
                'https://login.launchpad.net/+id/1234567'),
            False)
        self.authenticator.cookied_teams = ['bzr-core', 'motu']
        self.assertEqual(
            self.authenticator.authenticate(
                'https://login.launchpad.net/+id/1234567'),
            True)
        self.options = Options({})
        self.authenticator = TeamsAuthenticator(
            self.request, self.options, self.session)
        self.assertEqual(
            self.authenticator.authenticate(
                'https://login.launchpad.net/+id/1234567'),
            False)
