# authentic2 - versatile identity manager
# Copyright (C) 2010-2021 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import datetime

from django.utils.timezone import now

from authentic2_idp_oidc.models import OIDCAccessToken

from .. import utils
from .conftest import bearer_authentication_headers


def test_user_info(app, client, freezer, simple_user):
    access_token = OIDCAccessToken.objects.create(
        client=client,
        user=simple_user,
        scopes='openid profile email',
        expired=now() + datetime.timedelta(seconds=3600),
    )

    def get_user_info(**kwargs):
        return app.get(
            '/idp/oidc/user_info/', headers=bearer_authentication_headers(access_token.uuid), **kwargs
        )

    response = app.get('/idp/oidc/user_info/', status=401)
    assert (
        response['WWW-Authenticate']
        == 'Bearer error="invalid_request", error_description="Bearer authentication is mandatory"'
    )

    response = app.get('/idp/oidc/user_info/', headers={'Authorization': 'Bearer'}, status=401)
    assert (
        response['WWW-Authenticate']
        == 'Bearer error="invalid_request", error_description="Invalid Bearer authentication"'
    )

    response = get_user_info(status=200)
    assert dict(response.json, sub='') == {
        'email': 'user@example.net',
        'email_verified': False,
        'family_name': 'Dôe',
        'family_name_verified': True,
        'given_name': 'Jôhn',
        'given_name_verified': True,
        'preferred_username': 'user',
        'sub': '',
    }

    # token is expired
    access_token.expired = now() - datetime.timedelta(seconds=1)
    access_token.save()
    response = get_user_info(status=401)
    assert (
        response['WWW-Authenticate']
        == 'Bearer error="invalid_token", error_description="Token expired or user disconnected"'
    )

    # token is unknown
    access_token.delete()
    response = get_user_info(status=401)
    assert response['WWW-Authenticate'] == 'Bearer error="invalid_token", error_description="Token unknown"'

    utils.login(app, access_token.user)
    access_token.expired = now() + datetime.timedelta(seconds=1)
    access_token.session_key = app.session.session_key
    access_token.save()

    get_user_info(status=200)

    app.session.flush()
    response = get_user_info(status=401)
    assert (
        response['WWW-Authenticate']
        == 'Bearer error="invalid_token", error_description="Token expired or user disconnected"'
    )
