import unittest
import paramiko

from tornado.httputil import HTTPServerRequest
from tests.utils import read_file, make_tests_data_path
from webssh.handler import MixinHandler, IndexHandler, InvalidValueError


class TestMixinHandler(unittest.TestCase):

    def test_get_real_client_addr(self):
        handler = MixinHandler()
        handler.request = HTTPServerRequest(uri='/')
        self.assertIsNone(handler.get_real_client_addr())

        ip = '127.0.0.1'
        handler.request.headers.add('X-Real-Ip', ip)
        self.assertEqual(handler.get_real_client_addr(), False)

        handler.request.headers.add('X-Real-Port', '12345x')
        self.assertEqual(handler.get_real_client_addr(), False)

        handler.request.headers.update({'X-Real-Port': '12345'})
        self.assertEqual(handler.get_real_client_addr(), (ip, 12345))

        handler.request.headers.update({'X-Real-ip': None})
        self.assertEqual(handler.get_real_client_addr(), False)

        handler.request.headers.update({'X-Real-Port': '12345x'})
        self.assertEqual(handler.get_real_client_addr(), False)


class TestIndexHandler(unittest.TestCase):

    def test_get_specific_pkey_with_plain_key(self):

        fname = 'test_rsa.key'
        cls = paramiko.RSAKey
        key = read_file(make_tests_data_path(fname))
        pkey = IndexHandler.get_specific_pkey(cls, key, None)
        self.assertIsInstance(pkey, cls)
        pkey = IndexHandler.get_specific_pkey(cls, key, 'iginored')
        self.assertIsInstance(pkey, cls)
        pkey = IndexHandler.get_specific_pkey(cls, 'x'+key, None)
        self.assertIsNone(pkey)

    def test_get_specific_pkey_with_encrypted_key(self):
        fname = 'test_rsa_password.key'
        cls = paramiko.RSAKey
        password = 'television'

        key = read_file(make_tests_data_path(fname))
        pkey = IndexHandler.get_specific_pkey(cls, key, password)
        self.assertIsInstance(pkey, cls)
        pkey = IndexHandler.get_specific_pkey(cls, 'x'+key, None)
        self.assertIsNone(pkey)

        with self.assertRaises(paramiko.PasswordRequiredException):
            pkey = IndexHandler.get_specific_pkey(cls, key, None)

    def test_get_pkey_obj_with_plain_key(self):
        fname = 'test_ed25519.key'
        cls = paramiko.Ed25519Key
        key = read_file(make_tests_data_path(fname))
        pkey = IndexHandler.get_pkey_obj(key, None, fname)
        self.assertIsInstance(pkey, cls)
        pkey = IndexHandler.get_pkey_obj(key, 'iginored', fname)
        self.assertIsInstance(pkey, cls)
        with self.assertRaises(InvalidValueError) as exc:
            pkey = IndexHandler.get_pkey_obj('x'+key, None, fname)
            self.assertIn('Invalid private key', str(exc))

    def test_get_pkey_obj_with_encrypted_key(self):
        fname = 'test_ed25519_password.key'
        password = 'abc123'
        cls = paramiko.Ed25519Key
        key = read_file(make_tests_data_path(fname))
        pkey = IndexHandler.get_pkey_obj(key, password, fname)
        self.assertIsInstance(pkey, cls)
        with self.assertRaises(InvalidValueError) as exc:
            pkey = IndexHandler.get_pkey_obj(key, 'wrongpass', fname)
            self.assertIn('Wrong password', str(exc))
        with self.assertRaises(InvalidValueError) as exc:
            pkey = IndexHandler.get_pkey_obj('x'+key, password, fname)
            self.assertIn('Invalid private key', str(exc))
        with self.assertRaises(paramiko.PasswordRequiredException):
            pkey = IndexHandler.get_pkey_obj(key, '', fname)

[((12, 18, 12, 32), 'webssh.handler.MixinHandler', 'MixinHandler', ({}, {}), '()', False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((13, 26, 13, 52), 'tornado.httputil.HTTPServerRequest', 'HTTPServerRequest', (), '', False, 'from tornado.httputil import HTTPServerRequest\n'), ((40, 15, 40, 61), 'webssh.handler.IndexHandler.get_specific_pkey', 'IndexHandler.get_specific_pkey', ({(40, 46, 40, 49): 'cls', (40, 51, 40, 54): 'key', (40, 56, 40, 60): 'None'}, {}), '(cls, key, None)', False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((42, 15, 42, 67), 'webssh.handler.IndexHandler.get_specific_pkey', 'IndexHandler.get_specific_pkey', ({(42, 46, 42, 49): 'cls', (42, 51, 42, 54): 'key', (42, 56, 42, 66): '"""iginored"""'}, {}), "(cls, key, 'iginored')", False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((44, 15, 44, 65), 'webssh.handler.IndexHandler.get_specific_pkey', 'IndexHandler.get_specific_pkey', ({(44, 46, 44, 49): 'cls', (44, 51, 44, 58): "'x' + key", (44, 60, 44, 64): 'None'}, {}), "(cls, 'x' + key, None)", False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((53, 15, 53, 65), 'webssh.handler.IndexHandler.get_specific_pkey', 'IndexHandler.get_specific_pkey', ({(53, 46, 53, 49): 'cls', (53, 51, 53, 54): 'key', (53, 56, 53, 64): 'password'}, {}), '(cls, key, password)', False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((55, 15, 55, 65), 'webssh.handler.IndexHandler.get_specific_pkey', 'IndexHandler.get_specific_pkey', ({(55, 46, 55, 49): 'cls', (55, 51, 55, 58): "'x' + key", (55, 60, 55, 64): 'None'}, {}), "(cls, 'x' + key, None)", False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((65, 15, 65, 58), 'webssh.handler.IndexHandler.get_pkey_obj', 'IndexHandler.get_pkey_obj', ({(65, 41, 65, 44): 'key', (65, 46, 65, 50): 'None', (65, 52, 65, 57): 'fname'}, {}), '(key, None, fname)', False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((67, 15, 67, 64), 'webssh.handler.IndexHandler.get_pkey_obj', 'IndexHandler.get_pkey_obj', ({(67, 41, 67, 44): 'key', (67, 46, 67, 56): '"""iginored"""', (67, 58, 67, 63): 'fname'}, {}), "(key, 'iginored', fname)", False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((78, 15, 78, 62), 'webssh.handler.IndexHandler.get_pkey_obj', 'IndexHandler.get_pkey_obj', ({(78, 41, 78, 44): 'key', (78, 46, 78, 54): 'password', (78, 56, 78, 61): 'fname'}, {}), '(key, password, fname)', False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((39, 24, 39, 51), 'tests.utils.make_tests_data_path', 'make_tests_data_path', ({(39, 45, 39, 50): 'fname'}, {}), '(fname)', False, 'from tests.utils import read_file, make_tests_data_path\n'), ((52, 24, 52, 51), 'tests.utils.make_tests_data_path', 'make_tests_data_path', ({(52, 45, 52, 50): 'fname'}, {}), '(fname)', False, 'from tests.utils import read_file, make_tests_data_path\n'), ((59, 19, 59, 65), 'webssh.handler.IndexHandler.get_specific_pkey', 'IndexHandler.get_specific_pkey', ({(59, 50, 59, 53): 'cls', (59, 55, 59, 58): 'key', (59, 60, 59, 64): 'None'}, {}), '(cls, key, None)', False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((64, 24, 64, 51), 'tests.utils.make_tests_data_path', 'make_tests_data_path', ({(64, 45, 64, 50): 'fname'}, {}), '(fname)', False, 'from tests.utils import read_file, make_tests_data_path\n'), ((70, 19, 70, 66), 'webssh.handler.IndexHandler.get_pkey_obj', 'IndexHandler.get_pkey_obj', ({(70, 45, 70, 52): "'x' + key", (70, 54, 70, 58): 'None', (70, 60, 70, 65): 'fname'}, {}), "('x' + key, None, fname)", False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((77, 24, 77, 51), 'tests.utils.make_tests_data_path', 'make_tests_data_path', ({(77, 45, 77, 50): 'fname'}, {}), '(fname)', False, 'from tests.utils import read_file, make_tests_data_path\n'), ((81, 19, 81, 69), 'webssh.handler.IndexHandler.get_pkey_obj', 'IndexHandler.get_pkey_obj', ({(81, 45, 81, 48): 'key', (81, 50, 81, 61): '"""wrongpass"""', (81, 63, 81, 68): 'fname'}, {}), "(key, 'wrongpass', fname)", False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((84, 19, 84, 70), 'webssh.handler.IndexHandler.get_pkey_obj', 'IndexHandler.get_pkey_obj', ({(84, 45, 84, 52): "'x' + key", (84, 54, 84, 62): 'password', (84, 64, 84, 69): 'fname'}, {}), "('x' + key, password, fname)", False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((87, 19, 87, 60), 'webssh.handler.IndexHandler.get_pkey_obj', 'IndexHandler.get_pkey_obj', ({(87, 45, 87, 48): 'key', (87, 50, 87, 52): '""""""', (87, 54, 87, 59): 'fname'}, {}), "(key, '', fname)", False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n')]