# Copyright 2014 Google Inc. All rights reserved.
#
# Licensed 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.

import base64
import os

import mock
import unittest2

from oauth2client import _helpers
from oauth2client import client
from oauth2client import crypt
from oauth2client import service_account


def data_filename(filename):
    return os.path.join(os.path.dirname(__file__), 'data', filename)


def datafile(filename):
    with open(data_filename(filename), 'rb') as file_obj:
        return file_obj.read()


class Test__bad_pkcs12_key_as_pem(unittest2.TestCase):

    def test_fails(self):
        with self.assertRaises(NotImplementedError):
            crypt._bad_pkcs12_key_as_pem()


class Test_pkcs12_key_as_pem(unittest2.TestCase):

    def _make_svc_account_creds(self, private_key_file='privatekey.p12'):
        filename = data_filename(private_key_file)
        credentials = (
            service_account.ServiceAccountCredentials.from_p12_keyfile(
                'some_account@example.com', filename,
                scopes='read+write'))
        credentials._kwargs['sub'] = 'joe@example.org'
        return credentials

    def _succeeds_helper(self, password=None):
        self.assertEqual(True, client.HAS_OPENSSL)

        credentials = self._make_svc_account_creds()
        if password is None:
            password = credentials._private_key_password
        pem_contents = crypt.pkcs12_key_as_pem(
            credentials._private_key_pkcs12, password)
        pkcs12_key_as_pem = datafile('pem_from_pkcs12.pem')
        pkcs12_key_as_pem = _helpers._parse_pem_key(pkcs12_key_as_pem)
        alternate_pem = datafile('pem_from_pkcs12_alternate.pem')
        self.assertTrue(pem_contents in [pkcs12_key_as_pem, alternate_pem])

    def test_succeeds(self):
        self._succeeds_helper()

    def test_succeeds_with_unicode_password(self):
        password = u'notasecret'
        self._succeeds_helper(password)


class Test__verify_signature(unittest2.TestCase):

    def test_success_single_cert(self):
        cert_value = 'cert-value'
        certs = [cert_value]
        message = object()
        signature = object()

        verifier = mock.MagicMock()
        verifier.verify = mock.MagicMock(name='verify', return_value=True)
        with mock.patch('oauth2client.crypt.Verifier') as Verifier:
            Verifier.from_string = mock.MagicMock(name='from_string',
                                                  return_value=verifier)
            result = crypt._verify_signature(message, signature, certs)
            self.assertEqual(result, None)

            # Make sure our mocks were called as expected.
            Verifier.from_string.assert_called_once_with(cert_value,
                                                         is_x509_cert=True)
            verifier.verify.assert_called_once_with(message, signature)

    def test_success_multiple_certs(self):
        cert_value1 = 'cert-value1'
        cert_value2 = 'cert-value2'
        cert_value3 = 'cert-value3'
        certs = [cert_value1, cert_value2, cert_value3]
        message = object()
        signature = object()

        verifier = mock.MagicMock()
        # Use side_effect to force all 3 cert values to be used by failing
        # to verify on the first two.
        verifier.verify = mock.MagicMock(name='verify',
                                         side_effect=[False, False, True])
        with mock.patch('oauth2client.crypt.Verifier') as Verifier:
            Verifier.from_string = mock.MagicMock(name='from_string',
                                                  return_value=verifier)
            result = crypt._verify_signature(message, signature, certs)
            self.assertEqual(result, None)

            # Make sure our mocks were called three times.
            expected_from_string_calls = [
                mock.call(cert_value1, is_x509_cert=True),
                mock.call(cert_value2, is_x509_cert=True),
                mock.call(cert_value3, is_x509_cert=True),
            ]
            self.assertEqual(Verifier.from_string.mock_calls,
                             expected_from_string_calls)
            expected_verify_calls = [mock.call(message, signature)] * 3
            self.assertEqual(verifier.verify.mock_calls,
                             expected_verify_calls)

    def test_failure(self):
        cert_value = 'cert-value'
        certs = [cert_value]
        message = object()
        signature = object()

        verifier = mock.MagicMock()
        verifier.verify = mock.MagicMock(name='verify', return_value=False)
        with mock.patch('oauth2client.crypt.Verifier') as Verifier:
            Verifier.from_string = mock.MagicMock(name='from_string',
                                                  return_value=verifier)
            with self.assertRaises(crypt.AppIdentityError):
                crypt._verify_signature(message, signature, certs)

            # Make sure our mocks were called as expected.
            Verifier.from_string.assert_called_once_with(cert_value,
                                                         is_x509_cert=True)
            verifier.verify.assert_called_once_with(message, signature)


class Test__check_audience(unittest2.TestCase):

    def test_null_audience(self):
        result = crypt._check_audience(None, None)
        self.assertEqual(result, None)

    def test_success(self):
        audience = 'audience'
        payload_dict = {'aud': audience}
        result = crypt._check_audience(payload_dict, audience)
        # No exception and no result.
        self.assertEqual(result, None)

    def test_missing_aud(self):
        audience = 'audience'
        payload_dict = {}
        with self.assertRaises(crypt.AppIdentityError):
            crypt._check_audience(payload_dict, audience)

    def test_wrong_aud(self):
        audience1 = 'audience1'
        audience2 = 'audience2'
        self.assertNotEqual(audience1, audience2)
        payload_dict = {'aud': audience1}
        with self.assertRaises(crypt.AppIdentityError):
            crypt._check_audience(payload_dict, audience2)


class Test__verify_time_range(unittest2.TestCase):

    def _exception_helper(self, payload_dict):
        exception_caught = None
        try:
            crypt._verify_time_range(payload_dict)
        except crypt.AppIdentityError as exc:
            exception_caught = exc

        return exception_caught

    def test_without_issued_at(self):
        payload_dict = {}
        exception_caught = self._exception_helper(payload_dict)
        self.assertNotEqual(exception_caught, None)
        self.assertTrue(str(exception_caught).startswith(
            'No iat field in token'))

    def test_without_expiration(self):
        payload_dict = {'iat': 'iat'}
        exception_caught = self._exception_helper(payload_dict)
        self.assertNotEqual(exception_caught, None)
        self.assertTrue(str(exception_caught).startswith(
            'No exp field in token'))

    def test_with_bad_token_lifetime(self):
        current_time = 123456
        payload_dict = {
            'iat': 'iat',
            'exp': current_time + crypt.MAX_TOKEN_LIFETIME_SECS + 1,
        }
        with mock.patch('oauth2client.crypt.time') as time:
            time.time = mock.MagicMock(name='time',
                                       return_value=current_time)

            exception_caught = self._exception_helper(payload_dict)
            self.assertNotEqual(exception_caught, None)
            self.assertTrue(str(exception_caught).startswith(
                'exp field too far in future'))

    def test_with_issued_at_in_future(self):
        current_time = 123456
        payload_dict = {
            'iat': current_time + crypt.CLOCK_SKEW_SECS + 1,
            'exp': current_time + crypt.MAX_TOKEN_LIFETIME_SECS - 1,
        }
        with mock.patch('oauth2client.crypt.time') as time:
            time.time = mock.MagicMock(name='time',
                                       return_value=current_time)

            exception_caught = self._exception_helper(payload_dict)
            self.assertNotEqual(exception_caught, None)
            self.assertTrue(str(exception_caught).startswith(
                'Token used too early'))

    def test_with_expiration_in_the_past(self):
        current_time = 123456
        payload_dict = {
            'iat': current_time,
            'exp': current_time - crypt.CLOCK_SKEW_SECS - 1,
        }
        with mock.patch('oauth2client.crypt.time') as time:
            time.time = mock.MagicMock(name='time',
                                       return_value=current_time)

            exception_caught = self._exception_helper(payload_dict)
            self.assertNotEqual(exception_caught, None)
            self.assertTrue(str(exception_caught).startswith(
                'Token used too late'))

    def test_success(self):
        current_time = 123456
        payload_dict = {
            'iat': current_time,
            'exp': current_time + crypt.MAX_TOKEN_LIFETIME_SECS - 1,
        }
        with mock.patch('oauth2client.crypt.time') as time:
            time.time = mock.MagicMock(name='time',
                                       return_value=current_time)

            exception_caught = self._exception_helper(payload_dict)
            self.assertEqual(exception_caught, None)


class Test_verify_signed_jwt_with_certs(unittest2.TestCase):

    def test_jwt_no_segments(self):
        exception_caught = None
        try:
            crypt.verify_signed_jwt_with_certs(b'', None)
        except crypt.AppIdentityError as exc:
            exception_caught = exc

        self.assertNotEqual(exception_caught, None)
        self.assertTrue(str(exception_caught).startswith(
            'Wrong number of segments in token'))

    def test_jwt_payload_bad_json(self):
        header = signature = b''
        payload = base64.b64encode(b'{BADJSON')
        jwt = b'.'.join([header, payload, signature])

        exception_caught = None
        try:
            crypt.verify_signed_jwt_with_certs(jwt, None)
        except crypt.AppIdentityError as exc:
            exception_caught = exc

        self.assertNotEqual(exception_caught, None)
        self.assertTrue(str(exception_caught).startswith(
            'Can\'t parse token'))

    @mock.patch('oauth2client.crypt._check_audience')
    @mock.patch('oauth2client.crypt._verify_time_range')
    @mock.patch('oauth2client.crypt._verify_signature')
    def test_success(self, verify_sig, verify_time, check_aud):
        certs = mock.MagicMock()
        cert_values = object()
        certs.values = mock.MagicMock(name='values',
                                      return_value=cert_values)
        audience = object()

        header = b'header'
        signature_bytes = b'signature'
        signature = base64.b64encode(signature_bytes)
        payload_dict = {'a': 'b'}
        payload = base64.b64encode(b'{"a": "b"}')
        jwt = b'.'.join([header, payload, signature])

        result = crypt.verify_signed_jwt_with_certs(
            jwt, certs, audience=audience)
        self.assertEqual(result, payload_dict)

        message_to_sign = header + b'.' + payload
        verify_sig.assert_called_once_with(
            message_to_sign, signature_bytes, cert_values)
        verify_time.assert_called_once_with(payload_dict)
        check_aud.assert_called_once_with(payload_dict, audience)
        certs.values.assert_called_once_with()
