class InvenioOAuthClient(object):
    """Invenio Oauthclient extension."""

    def __init__(self, app=None):
        """Extension initialization."""
        if app:
            self._state = self.init_app(app)

    def init_app(self, app):
        """Flask application initialization."""
        self.init_config(app)
        state = _OAuthClientState(
            app, 'OAUTHCLIENT_REMOTE_APPS',
            handlers.disconnect_handler,
            handlers.authorized_default_handler)
        app.extensions['invenio-oauthclient'] = state
        return state

    def init_config(self, app):
        """Initialize configuration."""
        @app.before_first_request
        def override_template_configuration():
            """Override template configuration."""
            template_key = app.config.get(
                'OAUTHCLIENT_TEMPLATE_KEY',
                'SECURITY_LOGIN_USER_TEMPLATE'  # default template key
            )
            if template_key is not None:
                template = app.config[template_key]  # keep the old value
                app.config['OAUTHCLIENT_LOGIN_USER_TEMPLATE_PARENT'] = template
                app.config[template_key] = app.config.get(
                    'OAUTHCLIENT_LOGIN_USER_TEMPLATE',
                    'invenio_oauthclient/login_user.html'
                ) class InvenioOAuthClientREST(object):
    """Invenio Oauthclient extension."""

    def __init__(self, app=None):
        """Extension initialization."""
        if app:
            self._state = self.init_app(app)

    def init_app(self, app):
        """Flask application initialization."""
        _default_response_handler = obj_or_import_string(
            app.config.get("OAUTHCLIENT_REST_DEFAULT_RESPONSE_HANDLER"),
            handlers.rest.default_response_handler
        )
        _default_remote_handler = handlers.rest.default_remote_response_handler
        state = _OAuthClientState(
            app, 'OAUTHCLIENT_REST_REMOTE_APPS',
            handlers.rest.disconnect_handler,
            handlers.rest.authorized_default_handler,
            default_remote_app_response_handler=_default_remote_handler,
            default_response_handler=_default_response_handler
        )

        app.extensions['invenio-oauthclient'] = state
        return state REMOTE_APP = dict(BASE_APP) REMOTE_REST_APP = dict(BASE_APP) REMOTE_APP = dict(BASE_APP) REMOTE_REST_APP = dict(BASE_APP) REMOTE_APP = _github_app.remote_app REMOTE_REST_APP = _github_app.remote_rest_app REMOTE_APP = _globus_app.remote_app REMOTE_REST_APP = _globus_app.remote_rest_app class KeycloakSettingsHelper(OAuthSettingsHelper):
    """Helper for creating REMOTE_APP configuration dictionaries for Keycloak.

    This class can be used to easily create a base configuration with sensible
    defaults for a default-ish Keycloak setup.
    It requires knowledge about the base URL of the Keycloak instance and the
    realm on which the Invenio client application is configured.
    Because the default endpoint URLs follow a simple schema, this information
    can be used to create a simple base configuration.

    The methods ``remote_app()`` and ``remote_rest_app()`` create and return
    a dictionary in the form expected by Invenio-OAuthClient.
    The latter can be used for providing SSO capabilities to SPAs communicating
    with Invenio via the REST API.

    Further, the helper provides some properties for commonly used default
    endpoint URLs.
    """

    def __init__(self, title, description, base_url, realm, app_key=None,
                 icon=None, **kwargs):
        """The constructor takes two arguments.

        :param base_url: The base URL on which Keycloak is running
                            (e.g. "http://localhost:8080")
        :param realm: Realm in which the invenio client application is defined
        """
        app_key = app_key or "KEYCLOAK_APP_CREDENTIALS"
        base_url = "{}/".format(base_url.rstrip("/"))  # add leading `/`

        self._realm_url = "{}auth/realms/{}".format(base_url, realm)

        access_token_url = self.make_url(self._realm_url, "token")
        authorize_url = self.make_url(self._realm_url, "auth")
        self._user_info_url = self.make_url(self._realm_url, "userinfo")

        super().__init__(title, description, base_url, app_key, icon=icon,
                         request_token_params={"scope": "openid"},
                         access_token_url=access_token_url,
                         authorize_url=authorize_url,
                         **kwargs)

    @property
    def user_info_url(self):
        """URL for the user info endpoint."""
        return self._user_info_url

    @property
    def realm_url(self):
        """URL for the realm's endpoint."""
        return self._realm_url

    @staticmethod
    def make_url(realm_url, endpoint):
        """Create an endpoint URL following the default Keycloak URL schema.

        :param realm_url: The realm base URL
        :param endpoint: The endpoint to use (e.g. "auth", "token", ...)
        """
        return "{}/protocol/openid-connect/{}".format(realm_url, endpoint)

    def get_handlers(self):
        """Return a dict with the auth handlers."""
        return dict(
            authorized_handler="invenio_oauthclient.handlers"
                               ":authorized_signup_handler",
            disconnect_handler="invenio_oauthclient.contrib.keycloak.handlers"
                               ":disconnect_handler",
            signup_handler=dict(
                info="invenio_oauthclient.contrib.keycloak.handlers"
                     ":info_handler",
                setup="invenio_oauthclient.contrib.keycloak.handlers"
                     ":setup_handler",
                view="invenio_oauthclient.handlers:signup_handler"
            ),
        )

    def get_rest_handlers(self):
        """Return a dict with the auth REST handlers."""
        return dict(
            authorized_handler="invenio_oauthclient.handlers.rest"
                               ":authorized_signup_handler",
            disconnect_handler="invenio_oauthclient.contrib.keycloak.handlers"
                               ":disconnect_rest_handler",
            signup_handler=dict(
                info="invenio_oauthclient.contrib.keycloak.handlers"
                     ":info_handler",
                setup="invenio_oauthclient.contrib.keycloak.handlers"
                      ":setup_handler",
                view="invenio_oauthclient.handlers.rest:signup_handler"
            ),

            response_handler=(
                "invenio_oauthclient.handlers.rest"
                ":default_remote_response_handler"
            ),

            authorized_redirect_url="/",
            disconnect_redirect_url="/",
            signup_redirect_url="/",
            error_redirect_url="/"
        ) REMOTE_APP = _orcid_app.remote_app REMOTE_REST_APP = _orcid_app.remote_rest_app def _create_registrationform(*args, **kwargs):
    """Default registration form after external auth success."""
    class RegistrationForm(_security.confirm_register_form):
        password = None
        recaptcha = None
        submit = None  # defined in the template
    return RegistrationForm(*args, **kwargs) def post_ext_init(state):
def auto_redirect_login(*args, **kwargs):
def _login(remote_app, authorized_view_name):
def login(remote_app):
def rest_login(remote_app):
def _authorized(remote_app=None):
def authorized(remote_app=None):
def rest_authorized(remote_app=None):
def _signup(remote_app):
def signup(remote_app):
def rest_signup(remote_app):
def _disconnect(remote_app):
def disconnect(remote_app):
def rest_disconnect(remote_app): def post_ext_init(state):
def auto_redirect_login(*args, **kwargs):
def _login(remote_app, authorized_view_name):
def login(remote_app):
def rest_login(remote_app):
def _authorized(remote_app=None):
def authorized(remote_app=None):
def rest_authorized(remote_app=None):
def _signup(remote_app):
def signup(remote_app):
def rest_signup(remote_app):
def _disconnect(remote_app):
def disconnect(remote_app):
def rest_disconnect(remote_app): def index(): def monkey_patch_werkzeug():
    """Patch top level removed modules."""
    try:
        from werkzeug import cached_property
    except ImportError:
        werkzeug.cached_property = werkzeug.utils.cached_property
        werkzeug.parse_options_header = werkzeug.http.parse_options_header
        werkzeug.url_quote = werkzeug.urls.url_quote
        werkzeug.url_decode = werkzeug.urls.url_decode
        werkzeug.url_encode = werkzeug.urls.url_encode
import json
import os
import shutil
import tempfile
import pytest
from flask import Flask
from flask_babelex import Babel
from flask_mail import Mail
from flask_menu import Menu as FlaskMenu
from invenio_accounts import InvenioAccounts
from invenio_db import InvenioDB, db
from invenio_userprofiles import InvenioUserProfiles, UserProfile
from invenio_userprofiles.views import blueprint_ui_init
from sqlalchemy_utils.functions import create_database, database_exists, \
    drop_database
from invenio_oauthclient import InvenioOAuthClient, InvenioOAuthClientREST
from invenio_oauthclient.contrib.cern import REMOTE_APP as CERN_REMOTE_APP
from invenio_oauthclient.contrib.cern import \
    REMOTE_REST_APP as CERN_REMOTE_REST_APP
from invenio_oauthclient.contrib.cern_openid import \
    REMOTE_APP as CERN_OPENID_REMOTE_APP
from invenio_oauthclient.contrib.cern_openid import \
    REMOTE_REST_APP as CERN_OPENID_REMOTE_REST_APP
from invenio_oauthclient.contrib.github import REMOTE_APP as GITHUB_REMOTE_APP
from invenio_oauthclient.contrib.github import \
    REMOTE_REST_APP as GITHUB_REMOTE_REST_APP
from invenio_oauthclient.contrib.globus import REMOTE_APP as GLOBUS_REMOTE_APP
from invenio_oauthclient.contrib.globus import \
    REMOTE_REST_APP as GLOBUS_REMOTE_REST_APP
from invenio_oauthclient.contrib.keycloak import KeycloakSettingsHelper
from invenio_oauthclient.contrib.orcid import REMOTE_APP as ORCID_REMOTE_APP
from invenio_oauthclient.contrib.orcid import \
    REMOTE_REST_APP as ORCID_REMOTE_REST_APP
from invenio_oauthclient.utils import _create_registrationform
from invenio_oauthclient.views.client import blueprint as blueprint_client
from invenio_oauthclient.views.client import rest_blueprint
from invenio_oauthclient.views.settings import blueprint as blueprint_settings
from invenio_oauthclient._compat import monkey_patch_werkzeug  # noqa isort:skip
    from werkzeug.middleware.dispatcher import DispatcherMiddleware
    from werkzeug.wsgi import DispatcherMiddleware
from flask_oauthlib.client import OAuth as FlaskOAuth  # noqa isort:skip
from flask_oauthlib.client import OAuthResponse  # noqa isort:skip
# -*- coding: utf-8 -*-
#
# This file is part of Invenio.
# Copyright (C) 2015-2018 CERN.
# Copyright (C) 2018 University of Chicago.
#
# Invenio is free software; you can redistribute it and/or modify it
# under the terms of the MIT License; see LICENSE file for more details.

"""Pytest configuration."""





try:
except ImportError:



@pytest.fixture
def base_app(request):
    """Flask application fixture without OAuthClient initialized."""
    # allow HTTP for keycloak tests, and create the KEYCLOAK_REMOTE_APP
    os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
    base_url, realm = "http://localhost:8080", "test"
    helper = KeycloakSettingsHelper(title="Keycloak", description="",
                                    base_url=base_url, realm=realm)
    KEYCLOAK_REMOTE_APP = helper.remote_app

    instance_path = tempfile.mkdtemp()
    base_app = Flask('testapp')
    base_app.config.update(
        ACCOUNTS_LOCAL_LOGIN_ENABLED=True,
        TESTING=True,
        WTF_CSRF_ENABLED=False,
        LOGIN_DISABLED=False,
        CACHE_TYPE='simple',
        OAUTHCLIENT_SIGNUP_FORM=_create_registrationform,
        OAUTHCLIENT_REMOTE_APPS=dict(
            cern=CERN_REMOTE_APP,
            cern_openid=CERN_OPENID_REMOTE_APP,
            orcid=ORCID_REMOTE_APP,
            github=GITHUB_REMOTE_APP,
            globus=GLOBUS_REMOTE_APP,
            keycloak=KEYCLOAK_REMOTE_APP,
        ),
        OAUTHCLIENT_REST_REMOTE_APPS=dict(
            cern=CERN_REMOTE_REST_APP,

            cern_openid=CERN_OPENID_REMOTE_REST_APP,