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)

[((314, 328), 'webssh.handler.MixinHandler', 'MixinHandler', ([], {}), '()\n', (326, 328), False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((355, 381), 'tornado.httputil.HTTPServerRequest', 'HTTPServerRequest', ([], {'uri': '"""/"""'}), "(uri='/')\n", (372, 381), False, 'from tornado.httputil import HTTPServerRequest\n'), ((1330, 1376), 'webssh.handler.IndexHandler.get_specific_pkey', 'IndexHandler.get_specific_pkey', (['cls', 'key', 'None'], {}), '(cls, key, None)\n', (1360, 1376), False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((1433, 1485), 'webssh.handler.IndexHandler.get_specific_pkey', 'IndexHandler.get_specific_pkey', (['cls', 'key', '"""iginored"""'], {}), "(cls, key, 'iginored')\n", (1463, 1485), False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((1542, 1594), 'webssh.handler.IndexHandler.get_specific_pkey', 'IndexHandler.get_specific_pkey', (['cls', "('x' + key)", 'None'], {}), "(cls, 'x' + key, None)\n", (1572, 1594), False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((1854, 1904), 'webssh.handler.IndexHandler.get_specific_pkey', 'IndexHandler.get_specific_pkey', (['cls', 'key', 'password'], {}), '(cls, key, password)\n', (1884, 1904), False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((1961, 2013), 'webssh.handler.IndexHandler.get_specific_pkey', 'IndexHandler.get_specific_pkey', (['cls', "('x' + key)", 'None'], {}), "(cls, 'x' + key, None)\n", (1991, 2013), False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((2365, 2408), 'webssh.handler.IndexHandler.get_pkey_obj', 'IndexHandler.get_pkey_obj', (['key', 'None', 'fname'], {}), '(key, None, fname)\n', (2390, 2408), False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((2465, 2514), 'webssh.handler.IndexHandler.get_pkey_obj', 'IndexHandler.get_pkey_obj', (['key', '"""iginored"""', 'fname'], {}), "(key, 'iginored', fname)\n", (2490, 2514), False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((2967, 3014), 'webssh.handler.IndexHandler.get_pkey_obj', 'IndexHandler.get_pkey_obj', (['key', 'password', 'fname'], {}), '(key, password, fname)\n', (2992, 3014), False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((1286, 1313), 'tests.utils.make_tests_data_path', 'make_tests_data_path', (['fname'], {}), '(fname)\n', (1306, 1313), False, 'from tests.utils import read_file, make_tests_data_path\n'), ((1810, 1837), 'tests.utils.make_tests_data_path', 'make_tests_data_path', (['fname'], {}), '(fname)\n', (1830, 1837), False, 'from tests.utils import read_file, make_tests_data_path\n'), ((2132, 2178), 'webssh.handler.IndexHandler.get_specific_pkey', 'IndexHandler.get_specific_pkey', (['cls', 'key', 'None'], {}), '(cls, key, None)\n', (2162, 2178), False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((2321, 2348), 'tests.utils.make_tests_data_path', 'make_tests_data_path', (['fname'], {}), '(fname)\n', (2341, 2348), False, 'from tests.utils import read_file, make_tests_data_path\n'), ((2633, 2682), 'webssh.handler.IndexHandler.get_pkey_obj', 'IndexHandler.get_pkey_obj', (["('x' + key)", 'None', 'fname'], {}), "('x' + key, None, fname)\n", (2658, 2682), False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((2923, 2950), 'tests.utils.make_tests_data_path', 'make_tests_data_path', (['fname'], {}), '(fname)\n', (2943, 2950), False, 'from tests.utils import read_file, make_tests_data_path\n'), ((3133, 3183), 'webssh.handler.IndexHandler.get_pkey_obj', 'IndexHandler.get_pkey_obj', (['key', '"""wrongpass"""', 'fname'], {}), "(key, 'wrongpass', fname)\n", (3158, 3183), False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((3315, 3368), 'webssh.handler.IndexHandler.get_pkey_obj', 'IndexHandler.get_pkey_obj', (["('x' + key)", 'password', 'fname'], {}), "('x' + key, password, fname)\n", (3340, 3368), False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n'), ((3513, 3554), 'webssh.handler.IndexHandler.get_pkey_obj', 'IndexHandler.get_pkey_obj', (['key', '""""""', 'fname'], {}), "(key, '', fname)\n", (3538, 3554), False, 'from webssh.handler import MixinHandler, IndexHandler, InvalidValueError\n')]