# Path: invenio_oauthclient/contrib/cern.py
# OAUTHCLIENT_CERN_SESSION_KEY = 'identity.cern_provides'
# 
# def account_info_rest(remote, resp):
#     """Retrieve remote account information used to find local user."""
#     try:
#         return _account_info(remote, resp)
#     except OAuthCERNRejectedAccountError as e:
#         current_app.logger.warning(e.message, exc_info=True)
#         remote_app_config = current_app.config['OAUTHCLIENT_REST_REMOTE_APPS'][
#             remote.name]
#         return response_handler(
#             remote,
#             remote_app_config['error_redirect_url'],
#             payload=dict(
#                 message='CERN account not allowed.',
#                 code=400)
#         )
# 
# def disconnect_rest_handler(remote, *args, **kwargs):
#     """Handle unlinking of remote account."""
#     _disconnect(remote, *args, **kwargs)
#     redirect_url = current_app.config['OAUTHCLIENT_REST_REMOTE_APPS'][
#         remote.name]['disconnect_redirect_url']
#     return response_handler(remote, redirect_url)
# 
# def fetch_extra_data(resource):
#     """Return a dict with extra data retrieved from cern oauth."""
#     person_id = resource.get('PersonID', [None])[0]
#     identity_class = resource.get('IdentityClass', [None])[0]
#     department = resource.get('Department', [None])[0]
# 
#     return dict(
#         person_id=person_id,
#         identity_class=identity_class,
#         department=department
#     )
# 
# def fetch_groups(groups):
#     """Prepare list of allowed group names.
# 
#     :param groups: The complete list of groups.
#     :returns: A filtered list of groups.
#     """
#     hidden_groups = current_app.config.get(
#         'OAUTHCLIENT_CERN_HIDDEN_GROUPS', OAUTHCLIENT_CERN_HIDDEN_GROUPS)
#     hidden_groups_re = current_app.config.get(
#         'OAUTHCLIENT_CERN_HIDDEN_GROUPS_RE',
#         OAUTHCLIENT_CERN_HIDDEN_GROUPS_RE)
#     groups = [group for group in groups if group not in hidden_groups]
#     filter_groups = []
#     for regexp in hidden_groups_re:
#         for group in groups:
#             if regexp.match(group):
#                 filter_groups.append(group)
#     groups = [group for group in groups if group not in filter_groups]
# 
#     return groups
# 
# def get_dict_from_response(response):
#     """Prepare new mapping with 'Value's groupped by 'Type'."""
#     result = {}
#     if getattr(response, '_resp') and response._resp.code > 400:
#         return result
# 
#     for i in response.data:
#         # strip the schema from the key
#         k = i['Type'].replace(REMOTE_APP_RESOURCE_SCHEMA, '')
#         result.setdefault(k, list())
#         result[k].append(i['Value'])
#     return result


from flask import g, session, url_for
from flask_principal import AnonymousIdentity, Identity, RoleNeed, UserNeed
from flask_security import login_user, logout_user
from flask_security.utils import hash_password
from helpers import check_response_redirect_url_args, get_state, \
    mock_remote_get, mock_response
from six.moves.urllib_parse import parse_qs, urlparse
from invenio_oauthclient.contrib.cern import OAUTHCLIENT_CERN_SESSION_KEY, \
    account_info_rest, disconnect_rest_handler, fetch_extra_data, \
    fetch_groups, get_dict_from_response
    import re
        # simulate login (account_info fetch)
        g.oauth_logged_in_with_remote = ioc.remote_apps['cern']

        login_user(user)
        assert isinstance(g.identity, Identity)
        assert g.identity.provides == set([
            UserNeed(4),
            UserNeed('test.account@cern.ch'),
            RoleNeed('Group1@cern.ch'),
            RoleNeed('Group2@cern.ch'),
            RoleNeed('Group3@cern.ch'),
            RoleNeed('Group4@cern.ch'),
            RoleNeed('Group5@cern.ch'),
        ])

        logout_user()
        assert isinstance(g.identity, AnonymousIdentity)
        # NOTE: Wrong role, g.identity.provides = {Need(['id', 4])} read more
        # https://github.com/inveniosoftware/invenio-access/blob/e28e76d5361a29202b94d498f1968454c24c5c80/tests/test_loaders.py#L47
        assert len(g.identity.provides) == 1

        assert "cern_resource" not in session
        assert OAUTHCLIENT_CERN_SESSION_KEY not in session

        # Login again to test the disconnect handler
        g.oauth_logged_in_with_remote = ioc.remote_apps['cern']
        login_user(user)
        assert isinstance(g.identity, Identity)
        assert len(g.identity.provides) == 7


# Path: invenio_oauthclient/contrib/cern.py
# OAUTHCLIENT_CERN_SESSION_KEY = 'identity.cern_provides'
# 
# def account_info_rest(remote, resp):
#     """Retrieve remote account information used to find local user."""
#     try:
#         return _account_info(remote, resp)
#     except OAuthCERNRejectedAccountError as e:
#         current_app.logger.warning(e.message, exc_info=True)
#         remote_app_config = current_app.config['OAUTHCLIENT_REST_REMOTE_APPS'][
#             remote.name]
#         return response_handler(
#             remote,
#             remote_app_config['error_redirect_url'],
#             payload=dict(
#                 message='CERN account not allowed.',
#                 code=400)
#         )
# 
# def disconnect_rest_handler(remote, *args, **kwargs):
#     """Handle unlinking of remote account."""
#     _disconnect(remote, *args, **kwargs)
#     redirect_url = current_app.config['OAUTHCLIENT_REST_REMOTE_APPS'][
#         remote.name]['disconnect_redirect_url']
#     return response_handler(remote, redirect_url)
# 
# def fetch_extra_data(resource):
#     """Return a dict with extra data retrieved from cern oauth."""
#     person_id = resource.get('PersonID', [None])[0]
#     identity_class = resource.get('IdentityClass', [None])[0]
#     department = resource.get('Department', [None])[0]
# 
#     return dict(
#         person_id=person_id,
#         identity_class=identity_class,
#         department=department
#     )
# 
# def fetch_groups(groups):
#     """Prepare list of allowed group names.
# 
#     :param groups: The complete list of groups.
#     :returns: A filtered list of groups.
#     """
#     hidden_groups = current_app.config.get(
#         'OAUTHCLIENT_CERN_HIDDEN_GROUPS', OAUTHCLIENT_CERN_HIDDEN_GROUPS)
#     hidden_groups_re = current_app.config.get(
#         'OAUTHCLIENT_CERN_HIDDEN_GROUPS_RE',
#         OAUTHCLIENT_CERN_HIDDEN_GROUPS_RE)
#     groups = [group for group in groups if group not in hidden_groups]
#     filter_groups = []
#     for regexp in hidden_groups_re:
#         for group in groups:
#             if regexp.match(group):
#                 filter_groups.append(group)
#     groups = [group for group in groups if group not in filter_groups]
# 
#     return groups
# 
# def get_dict_from_response(response):
#     """Prepare new mapping with 'Value's groupped by 'Type'."""
#     result = {}
#     if getattr(response, '_resp') and response._resp.code > 400:
#         return result
# 
#     for i in response.data:
#         # strip the schema from the key
#         k = i['Type'].replace(REMOTE_APP_RESOURCE_SCHEMA, '')
#         result.setdefault(k, list())
#         result[k].append(i['Value'])
#     return result


# Path: tests/test_contrib_cern_rest.py
from flask import g, session, url_for
from flask_principal import AnonymousIdentity, Identity, RoleNeed, UserNeed
from flask_security import login_user, logout_user
from flask_security.utils import hash_password
from helpers import check_response_redirect_url_args, get_state, \
    mock_remote_get, mock_response
from six.moves.urllib_parse import parse_qs, urlparse
from invenio_oauthclient.contrib.cern import OAUTHCLIENT_CERN_SESSION_KEY, \
    account_info_rest, disconnect_rest_handler, fetch_extra_data, \
    fetch_groups, get_dict_from_response
    import re

        # simulate login (account_info fetch)
        g.oauth_logged_in_with_remote = ioc.remote_apps['cern']

        login_user(user)
        assert isinstance(g.identity, Identity)
        assert g.identity.provides == set([
            UserNeed(4),
            UserNeed('test.account@cern.ch'),
            RoleNeed('Group1@cern.ch'),
            RoleNeed('Group2@cern.ch'),
            RoleNeed('Group3@cern.ch'),
            RoleNeed('Group4@cern.ch'),
            RoleNeed('Group5@cern.ch'),
        ])

        logout_user()
        assert isinstance(g.identity, AnonymousIdentity)
        # NOTE: Wrong role, g.identity.provides = {Need(['id', 4])} read more
        # https://github.com/inveniosoftware/invenio-access/blob/e28e76d5361a29202b94d498f1968454c24c5c80/tests/test_loaders.py#L47
        assert len(g.identity.provides) == 1

        assert "cern_resource" not in session
        assert OAUTHCLIENT_CERN_SESSION_KEY not in session

        # Login again to test the disconnect handler
        g.oauth_logged_in_with_remote = ioc.remote_apps['cern']
        login_user(user)
        assert isinstance(g.identity, Identity)
        assert len(g.identity.provides) == 7


        disconnect_rest_handler(ioc.remote_apps['cern'])