# Copyright 2014 Google Inc.
#
# 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 datetime
import json
import os

import mock
import pytest

from google.auth import _helpers
from google.auth import crypt
from google.auth import exceptions
from google.auth import jwt


DATA_DIR = os.path.join(os.path.dirname(__file__), "data")

with open(os.path.join(DATA_DIR, "privatekey.pem"), "rb") as fh:
    PRIVATE_KEY_BYTES = fh.read()

with open(os.path.join(DATA_DIR, "public_cert.pem"), "rb") as fh:
    PUBLIC_CERT_BYTES = fh.read()

with open(os.path.join(DATA_DIR, "other_cert.pem"), "rb") as fh:
    OTHER_CERT_BYTES = fh.read()

with open(os.path.join(DATA_DIR, "es256_privatekey.pem"), "rb") as fh:
    EC_PRIVATE_KEY_BYTES = fh.read()

with open(os.path.join(DATA_DIR, "es256_public_cert.pem"), "rb") as fh:
    EC_PUBLIC_CERT_BYTES = fh.read()

SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, "service_account.json")

with open(SERVICE_ACCOUNT_JSON_FILE, "r") as fh:
    SERVICE_ACCOUNT_INFO = json.load(fh)


@pytest.fixture
def signer():
    return crypt.RSASigner.from_string(PRIVATE_KEY_BYTES, "1")


def test_encode_basic(signer):
    test_payload = {"test": "value"}
    encoded = jwt.encode(signer, test_payload)
    header, payload, _, _ = jwt._unverified_decode(encoded)
    assert payload == test_payload
    assert header == {"typ": "JWT", "alg": "RS256", "kid": signer.key_id}


def test_encode_extra_headers(signer):
    encoded = jwt.encode(signer, {}, header={"extra": "value"})
    header = jwt.decode_header(encoded)
    assert header == {
        "typ": "JWT",
        "alg": "RS256",
        "kid": signer.key_id,
        "extra": "value",
    }


@pytest.fixture
def es256_signer():
    return crypt.ES256Signer.from_string(EC_PRIVATE_KEY_BYTES, "1")


def test_encode_basic_es256(es256_signer):
    test_payload = {"test": "value"}
    encoded = jwt.encode(es256_signer, test_payload)
    header, payload, _, _ = jwt._unverified_decode(encoded)
    assert payload == test_payload
    assert header == {"typ": "JWT", "alg": "ES256", "kid": es256_signer.key_id}


@pytest.fixture
def token_factory(signer, es256_signer):
    def factory(claims=None, key_id=None, use_es256_signer=False):
        now = _helpers.datetime_to_secs(_helpers.utcnow())
        payload = {
            "aud": "audience@example.com",
            "iat": now,
            "exp": now + 300,
            "user": "billy bob",
            "metadata": {"meta": "data"},
        }
        payload.update(claims or {})

        # False is specified to remove the signer's key id for testing
        # headers without key ids.
        if key_id is False:
            signer._key_id = None
            key_id = None

        if use_es256_signer:
            return jwt.encode(es256_signer, payload, key_id=key_id)
        else:
            return jwt.encode(signer, payload, key_id=key_id)

    return factory


def test_decode_valid(token_factory):
    payload = jwt.decode(token_factory(), certs=PUBLIC_CERT_BYTES)
    assert payload["aud"] == "audience@example.com"
    assert payload["user"] == "billy bob"
    assert payload["metadata"]["meta"] == "data"


def test_decode_valid_es256(token_factory):
    payload = jwt.decode(
        token_factory(use_es256_signer=True), certs=EC_PUBLIC_CERT_BYTES
    )
    assert payload["aud"] == "audience@example.com"
    assert payload["user"] == "billy bob"
    assert payload["metadata"]["meta"] == "data"


def test_decode_valid_with_audience(token_factory):
    payload = jwt.decode(
        token_factory(), certs=PUBLIC_CERT_BYTES, audience="audience@example.com"
    )
    assert payload["aud"] == "audience@example.com"
    assert payload["user"] == "billy bob"
    assert payload["metadata"]["meta"] == "data"


def test_decode_valid_unverified(token_factory):
    payload = jwt.decode(token_factory(), certs=OTHER_CERT_BYTES, verify=False)
    assert payload["aud"] == "audience@example.com"
    assert payload["user"] == "billy bob"
    assert payload["metadata"]["meta"] == "data"


def test_decode_bad_token_wrong_number_of_segments():
    with pytest.raises(ValueError) as excinfo:
        jwt.decode("1.2", PUBLIC_CERT_BYTES)
    assert excinfo.match(r"Wrong number of segments")


def test_decode_bad_token_not_base64():
    with pytest.raises((ValueError, TypeError)) as excinfo:
        jwt.decode("1.2.3", PUBLIC_CERT_BYTES)
    assert excinfo.match(r"Incorrect padding|more than a multiple of 4")


def test_decode_bad_token_not_json():
    token = b".".join([base64.urlsafe_b64encode(b"123!")] * 3)
    with pytest.raises(ValueError) as excinfo:
        jwt.decode(token, PUBLIC_CERT_BYTES)
    assert excinfo.match(r"Can\'t parse segment")


def test_decode_bad_token_no_iat_or_exp(signer):
    token = jwt.encode(signer, {"test": "value"})
    with pytest.raises(ValueError) as excinfo:
        jwt.decode(token, PUBLIC_CERT_BYTES)
    assert excinfo.match(r"Token does not contain required claim")


def test_decode_bad_token_too_early(token_factory):
    token = token_factory(
        claims={
            "iat": _helpers.datetime_to_secs(
                _helpers.utcnow() + datetime.timedelta(hours=1)
            )
        }
    )
    with pytest.raises(ValueError) as excinfo:
        jwt.decode(token, PUBLIC_CERT_BYTES)
    assert excinfo.match(r"Token used too early")


def test_decode_bad_token_expired(token_factory):
    token = token_factory(
        claims={
            "exp": _helpers.datetime_to_secs(
                _helpers.utcnow() - datetime.timedelta(hours=1)
            )
        }
    )
    with pytest.raises(ValueError) as excinfo:
        jwt.decode(token, PUBLIC_CERT_BYTES)
    assert excinfo.match(r"Token expired")


def test_decode_bad_token_wrong_audience(token_factory):
    token = token_factory()
    audience = "audience2@example.com"
    with pytest.raises(ValueError) as excinfo:
        jwt.decode(token, PUBLIC_CERT_BYTES, audience=audience)
    assert excinfo.match(r"Token has wrong audience")


def test_decode_wrong_cert(token_factory):
    with pytest.raises(ValueError) as excinfo:
        jwt.decode(token_factory(), OTHER_CERT_BYTES)
    assert excinfo.match(r"Could not verify token signature")


def test_decode_multicert_bad_cert(token_factory):
    certs = {"1": OTHER_CERT_BYTES, "2": PUBLIC_CERT_BYTES}
    with pytest.raises(ValueError) as excinfo:
        jwt.decode(token_factory(), certs)
    assert excinfo.match(r"Could not verify token signature")


def test_decode_no_cert(token_factory):
    certs = {"2": PUBLIC_CERT_BYTES}
    with pytest.raises(ValueError) as excinfo:
        jwt.decode(token_factory(), certs)
    assert excinfo.match(r"Certificate for key id 1 not found")


def test_decode_no_key_id(token_factory):
    token = token_factory(key_id=False)
    certs = {"2": PUBLIC_CERT_BYTES}
    payload = jwt.decode(token, certs)
    assert payload["user"] == "billy bob"


def test_decode_unknown_alg():
    headers = json.dumps({u"kid": u"1", u"alg": u"fakealg"})
    token = b".".join(
        map(lambda seg: base64.b64encode(seg.encode("utf-8")), [headers, u"{}", u"sig"])
    )

    with pytest.raises(ValueError) as excinfo:
        jwt.decode(token)
    assert excinfo.match(r"fakealg")


def test_decode_missing_crytography_alg(monkeypatch):
    monkeypatch.delitem(jwt._ALGORITHM_TO_VERIFIER_CLASS, "ES256")
    headers = json.dumps({u"kid": u"1", u"alg": u"ES256"})
    token = b".".join(
        map(lambda seg: base64.b64encode(seg.encode("utf-8")), [headers, u"{}", u"sig"])
    )

    with pytest.raises(ValueError) as excinfo:
        jwt.decode(token)
    assert excinfo.match(r"cryptography")


def test_roundtrip_explicit_key_id(token_factory):
    token = token_factory(key_id="3")
    certs = {"2": OTHER_CERT_BYTES, "3": PUBLIC_CERT_BYTES}
    payload = jwt.decode(token, certs)
    assert payload["user"] == "billy bob"


class TestCredentials(object):
    SERVICE_ACCOUNT_EMAIL = "service-account@example.com"
    SUBJECT = "subject"
    AUDIENCE = "audience"
    ADDITIONAL_CLAIMS = {"meta": "data"}
    credentials = None

    @pytest.fixture(autouse=True)
    def credentials_fixture(self, signer):
        self.credentials = jwt.Credentials(
            signer,
            self.SERVICE_ACCOUNT_EMAIL,
            self.SERVICE_ACCOUNT_EMAIL,
            self.AUDIENCE,
        )

    def test_from_service_account_info(self):
        with open(SERVICE_ACCOUNT_JSON_FILE, "r") as fh:
            info = json.load(fh)

        credentials = jwt.Credentials.from_service_account_info(
            info, audience=self.AUDIENCE
        )

        assert credentials._signer.key_id == info["private_key_id"]
        assert credentials._issuer == info["client_email"]
        assert credentials._subject == info["client_email"]
        assert credentials._audience == self.AUDIENCE

    def test_from_service_account_info_args(self):
        info = SERVICE_ACCOUNT_INFO.copy()

        credentials = jwt.Credentials.from_service_account_info(
            info,
            subject=self.SUBJECT,
            audience=self.AUDIENCE,
            additional_claims=self.ADDITIONAL_CLAIMS,
        )

        assert credentials._signer.key_id == info["private_key_id"]
        assert credentials._issuer == info["client_email"]
        assert credentials._subject == self.SUBJECT
        assert credentials._audience == self.AUDIENCE
        assert credentials._additional_claims == self.ADDITIONAL_CLAIMS

    def test_from_service_account_file(self):
        info = SERVICE_ACCOUNT_INFO.copy()

        credentials = jwt.Credentials.from_service_account_file(
            SERVICE_ACCOUNT_JSON_FILE, audience=self.AUDIENCE
        )

        assert credentials._signer.key_id == info["private_key_id"]
        assert credentials._issuer == info["client_email"]
        assert credentials._subject == info["client_email"]
        assert credentials._audience == self.AUDIENCE

    def test_from_service_account_file_args(self):
        info = SERVICE_ACCOUNT_INFO.copy()

        credentials = jwt.Credentials.from_service_account_file(
            SERVICE_ACCOUNT_JSON_FILE,
            subject=self.SUBJECT,
            audience=self.AUDIENCE,
            additional_claims=self.ADDITIONAL_CLAIMS,
        )

        assert credentials._signer.key_id == info["private_key_id"]
        assert credentials._issuer == info["client_email"]
        assert credentials._subject == self.SUBJECT
        assert credentials._audience == self.AUDIENCE
        assert credentials._additional_claims == self.ADDITIONAL_CLAIMS

    def test_from_signing_credentials(self):
        jwt_from_signing = self.credentials.from_signing_credentials(
            self.credentials, audience=mock.sentinel.new_audience
        )
        jwt_from_info = jwt.Credentials.from_service_account_info(
            SERVICE_ACCOUNT_INFO, audience=mock.sentinel.new_audience
        )

        assert isinstance(jwt_from_signing, jwt.Credentials)
        assert jwt_from_signing._signer.key_id == jwt_from_info._signer.key_id
        assert jwt_from_signing._issuer == jwt_from_info._issuer
        assert jwt_from_signing._subject == jwt_from_info._subject
        assert jwt_from_signing._audience == jwt_from_info._audience

    def test_default_state(self):
        assert not self.credentials.valid
        # Expiration hasn't been set yet
        assert not self.credentials.expired

    def test_with_claims(self):
        new_audience = "new_audience"
        new_credentials = self.credentials.with_claims(audience=new_audience)

        assert new_credentials._signer == self.credentials._signer
        assert new_credentials._issuer == self.credentials._issuer
        assert new_credentials._subject == self.credentials._subject
        assert new_credentials._audience == new_audience
        assert new_credentials._additional_claims == self.credentials._additional_claims
        assert new_credentials._quota_project_id == self.credentials._quota_project_id

    def test_with_quota_project(self):
        quota_project_id = "project-foo"

        new_credentials = self.credentials.with_quota_project(quota_project_id)
        assert new_credentials._signer == self.credentials._signer
        assert new_credentials._issuer == self.credentials._issuer
        assert new_credentials._subject == self.credentials._subject
        assert new_credentials._audience == self.credentials._audience
        assert new_credentials._additional_claims == self.credentials._additional_claims
        assert new_credentials._quota_project_id == quota_project_id

    def test_sign_bytes(self):
        to_sign = b"123"
        signature = self.credentials.sign_bytes(to_sign)
        assert crypt.verify_signature(to_sign, signature, PUBLIC_CERT_BYTES)

    def test_signer(self):
        assert isinstance(self.credentials.signer, crypt.RSASigner)

    def test_signer_email(self):
        assert self.credentials.signer_email == SERVICE_ACCOUNT_INFO["client_email"]

    def _verify_token(self, token):
        payload = jwt.decode(token, PUBLIC_CERT_BYTES)
        assert payload["iss"] == self.SERVICE_ACCOUNT_EMAIL
        return payload

    def test_refresh(self):
        self.credentials.refresh(None)
        assert self.credentials.valid
        assert not self.credentials.expired

    def test_expired(self):
        assert not self.credentials.expired

        self.credentials.refresh(None)
        assert not self.credentials.expired

        with mock.patch("google.auth._helpers.utcnow") as now:
            one_day = datetime.timedelta(days=1)
            now.return_value = self.credentials.expiry + one_day
            assert self.credentials.expired

    def test_before_request(self):
        headers = {}

        self.credentials.refresh(None)
        self.credentials.before_request(
            None, "GET", "http://example.com?a=1#3", headers
        )

        header_value = headers["authorization"]
        _, token = header_value.split(" ")

        # Since the audience is set, it should use the existing token.
        assert token.encode("utf-8") == self.credentials.token

        payload = self._verify_token(token)
        assert payload["aud"] == self.AUDIENCE

    def test_before_request_refreshes(self):
        assert not self.credentials.valid
        self.credentials.before_request(None, "GET", "http://example.com?a=1#3", {})
        assert self.credentials.valid


class TestOnDemandCredentials(object):
    SERVICE_ACCOUNT_EMAIL = "service-account@example.com"
    SUBJECT = "subject"
    ADDITIONAL_CLAIMS = {"meta": "data"}
    credentials = None

    @pytest.fixture(autouse=True)
    def credentials_fixture(self, signer):
        self.credentials = jwt.OnDemandCredentials(
            signer,
            self.SERVICE_ACCOUNT_EMAIL,
            self.SERVICE_ACCOUNT_EMAIL,
            max_cache_size=2,
        )

    def test_from_service_account_info(self):
        with open(SERVICE_ACCOUNT_JSON_FILE, "r") as fh:
            info = json.load(fh)

        credentials = jwt.OnDemandCredentials.from_service_account_info(info)

        assert credentials._signer.key_id == info["private_key_id"]
        assert credentials._issuer == info["client_email"]
        assert credentials._subject == info["client_email"]

    def test_from_service_account_info_args(self):
        info = SERVICE_ACCOUNT_INFO.copy()

        credentials = jwt.OnDemandCredentials.from_service_account_info(
            info, subject=self.SUBJECT, additional_claims=self.ADDITIONAL_CLAIMS
        )

        assert credentials._signer.key_id == info["private_key_id"]
        assert credentials._issuer == info["client_email"]
        assert credentials._subject == self.SUBJECT
        assert credentials._additional_claims == self.ADDITIONAL_CLAIMS

    def test_from_service_account_file(self):
        info = SERVICE_ACCOUNT_INFO.copy()

        credentials = jwt.OnDemandCredentials.from_service_account_file(
            SERVICE_ACCOUNT_JSON_FILE
        )

        assert credentials._signer.key_id == info["private_key_id"]
        assert credentials._issuer == info["client_email"]
        assert credentials._subject == info["client_email"]

    def test_from_service_account_file_args(self):
        info = SERVICE_ACCOUNT_INFO.copy()

        credentials = jwt.OnDemandCredentials.from_service_account_file(
            SERVICE_ACCOUNT_JSON_FILE,
            subject=self.SUBJECT,
            additional_claims=self.ADDITIONAL_CLAIMS,
        )

        assert credentials._signer.key_id == info["private_key_id"]
        assert credentials._issuer == info["client_email"]
        assert credentials._subject == self.SUBJECT
        assert credentials._additional_claims == self.ADDITIONAL_CLAIMS

    def test_from_signing_credentials(self):
        jwt_from_signing = self.credentials.from_signing_credentials(self.credentials)
        jwt_from_info = jwt.OnDemandCredentials.from_service_account_info(
            SERVICE_ACCOUNT_INFO
        )

        assert isinstance(jwt_from_signing, jwt.OnDemandCredentials)
        assert jwt_from_signing._signer.key_id == jwt_from_info._signer.key_id
        assert jwt_from_signing._issuer == jwt_from_info._issuer
        assert jwt_from_signing._subject == jwt_from_info._subject

    def test_default_state(self):
        # Credentials are *always* valid.
        assert self.credentials.valid
        # Credentials *never* expire.
        assert not self.credentials.expired

    def test_with_claims(self):
        new_claims = {"meep": "moop"}
        new_credentials = self.credentials.with_claims(additional_claims=new_claims)

        assert new_credentials._signer == self.credentials._signer
        assert new_credentials._issuer == self.credentials._issuer
        assert new_credentials._subject == self.credentials._subject
        assert new_credentials._additional_claims == new_claims

    def test_with_quota_project(self):
        quota_project_id = "project-foo"
        new_credentials = self.credentials.with_quota_project(quota_project_id)

        assert new_credentials._signer == self.credentials._signer
        assert new_credentials._issuer == self.credentials._issuer
        assert new_credentials._subject == self.credentials._subject
        assert new_credentials._additional_claims == self.credentials._additional_claims
        assert new_credentials._quota_project_id == quota_project_id

    def test_sign_bytes(self):
        to_sign = b"123"
        signature = self.credentials.sign_bytes(to_sign)
        assert crypt.verify_signature(to_sign, signature, PUBLIC_CERT_BYTES)

    def test_signer(self):
        assert isinstance(self.credentials.signer, crypt.RSASigner)

    def test_signer_email(self):
        assert self.credentials.signer_email == SERVICE_ACCOUNT_INFO["client_email"]

    def _verify_token(self, token):
        payload = jwt.decode(token, PUBLIC_CERT_BYTES)
        assert payload["iss"] == self.SERVICE_ACCOUNT_EMAIL
        return payload

    def test_refresh(self):
        with pytest.raises(exceptions.RefreshError):
            self.credentials.refresh(None)

    def test_before_request(self):
        headers = {}

        self.credentials.before_request(
            None, "GET", "http://example.com?a=1#3", headers
        )

        _, token = headers["authorization"].split(" ")
        payload = self._verify_token(token)

        assert payload["aud"] == "http://example.com"

        # Making another request should re-use the same token.
        self.credentials.before_request(None, "GET", "http://example.com?b=2", headers)

        _, new_token = headers["authorization"].split(" ")

        assert new_token == token

    def test_expired_token(self):
        self.credentials._cache["audience"] = (
            mock.sentinel.token,
            datetime.datetime.min,
        )

        token = self.credentials._get_jwt_for_audience("audience")

        assert token != mock.sentinel.token
