#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#

from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import
from __future__ import print_function


import os
from subprocess import PIPE, Popen
from system_test import TestCase, Qdrouterd, main_module, SkipIfNeeded
from system_test import unittest
from proton import SASL
from proton.handlers import MessagingHandler
from proton.reactor import Container


class AuthServicePluginTest(TestCase):
    @classmethod
    def createSaslFiles(cls):
        # Create a sasl database.
        p = Popen(['saslpasswd2', '-c', '-p', '-f', 'qdrouterd.sasldb', '-u', 'domain.com', 'test'],
                  stdin=PIPE, stdout=PIPE, stderr=PIPE, universal_newlines=True)
        result = p.communicate('password')
        assert p.returncode == 0, \
            "saslpasswd2 exit status %s, output:\n%s" % (p.returncode, result)

        # Create a SASL configuration file.
        with open('tests-mech-PLAIN.conf', 'w') as sasl_conf:
            sasl_conf.write("""
pwcheck_method: auxprop
auxprop_plugin: sasldb
sasldb_path: qdrouterd.sasldb
mech_list: SCRAM-SHA1 PLAIN
# The following line stops spurious 'sql_select option missing' errors when cyrus-sql-sasl plugin is installed
sql_select: dummy select
""")

    @classmethod
    def setUpClass(cls):
        """
        Tests the delegation of sasl auth to an external auth service.

        Creates two routers, one acts as the authe service, the other configures the auth service plugin
        to point at this auth service.

        """
        super(AuthServicePluginTest, cls).setUpClass()

        if not SASL.extended():
            return

        cls.createSaslFiles()

        print('launching auth service...')
        auth_service_port = cls.tester.get_port()
        cls.tester.qdrouterd('auth_service', Qdrouterd.Config([
                     ('listener', {'host': '0.0.0.0', 'role': 'normal', 'port': auth_service_port,
                                   'saslMechanisms':'PLAIN', 'authenticatePeer': 'yes'}),
                     ('router', {'workerThreads': 1,
                                 'id': 'auth_service',
                                 'mode': 'standalone',
                                 'saslConfigName': 'tests-mech-PLAIN',
                                 'saslConfigPath': os.getcwd()})
        ])).wait_ready()

        cls.router_port = cls.tester.get_port()
        cls.tester.qdrouterd('router', Qdrouterd.Config([
                     ('authServicePlugin', {'name':'myauth', 'host': '127.0.0.1', 'port': auth_service_port}),
                     ('listener', {'host': '0.0.0.0', 'port': cls.router_port, 'role': 'normal', 'saslPlugin':'myauth', 'saslMechanisms':'PLAIN'}),
                     ('router', {'mode': 'standalone', 'id': 'router'})
        ])).wait_ready()

    @SkipIfNeeded(not SASL.extended(), "Cyrus library not available. skipping test")
    def test_valid_credentials(self):
        """
        Check authentication succeeds when valid credentials are presented.

        """
        test = SimpleConnect("127.0.0.1:%d" % self.router_port, 'test@domain.com', 'password')
        test.run()
        self.assertEqual(True, test.connected)
        self.assertEqual(None, test.error)

    @SkipIfNeeded(not SASL.extended(), "Cyrus library not available. skipping test")
    def test_invalid_credentials(self):
        """
        Check authentication fails when invalid credentials are presented.

        """
        test = SimpleConnect("127.0.0.1:%d" % self.router_port, 'test@domain.com', 'foo')
        test.run()
        self.assertEqual(False, test.connected)
        self.assertEqual('amqp:unauthorized-access', test.error.name)
        self.assertEqual(test.error.description.startswith('Authentication failed'), True)


class AuthServicePluginDeprecatedTest(AuthServicePluginTest):
    @classmethod
    def setUpClass(cls):
        """
        Tests the delegation of sasl auth to an external auth service.

        Creates two routers, one acts as the authe service, the other configures the auth service plugin
        to point at this auth service.

        """
        super(AuthServicePluginTest, cls).setUpClass()

        if not SASL.extended():
            return

        cls.createSaslFiles()

        print('launching auth service...')
        auth_service_port = cls.tester.get_port()
        cls.tester.qdrouterd('auth_service', Qdrouterd.Config([
                     ('listener', {'host': '0.0.0.0', 'role': 'normal', 'port': auth_service_port,
                                   'saslMechanisms':'PLAIN', 'authenticatePeer': 'yes'}),
                     ('router', {'workerThreads': 1,
                                 'id': 'auth_service',
                                 'mode': 'standalone',
                                 'saslConfigName': 'tests-mech-PLAIN',
                                 'saslConfigPath': os.getcwd()})
        ])).wait_ready()

        cls.router_port = cls.tester.get_port()
        cls.tester.qdrouterd('router', Qdrouterd.Config([
                     ('authServicePlugin', {'name':'myauth', 'authService': '127.0.0.1:%d' % auth_service_port}),
                     ('listener', {'host': '0.0.0.0', 'port': cls.router_port, 'role': 'normal',
                                   'saslPlugin':'myauth', 'saslMechanisms':'PLAIN'}),
                     ('router', {'mode': 'standalone', 'id': 'router'})
        ])).wait_ready()


class SimpleConnect(MessagingHandler):
    def __init__(self, url, username, password):
        super(SimpleConnect, self).__init__()
        self.url = url
        self.username = username
        self.password = password
        self.connected = False
        self.error = None

    def on_start(self, event):
        event.container.user = self.username
        event.container.password = self.password
        conn = event.container.connect(self.url)

    def on_connection_opened(self, event):
        self.connected = True
        event.connection.close()

    def on_transport_error(self, event):
        self.error = event.transport.condition
        if event.connection:
            event.connection.close()
        else:
            print("ERROR: %s" % self.error)

    def run(self):
        Container(self).run()


if __name__ == '__main__':
    unittest.main(main_module())

