def provider_info(login_details):
    '\n    Args:\n        login_details (dict):\n        { name, desc, idp, fence_idp, shib_idps, secondary }\n        - "idp": a configured provider.\n        Multiple options can be configured with the same idp.\n        - if provider_id is "fence", "fence_idp" can be any of the\n        providers supported by the other Fence. If not specified, will\n        default to NIH login.\n        - if provider_id is "fence" and fence_idp is "shibboleth", a\n        list of "shib_idps" can be configured for InCommon login. If\n        not specified, will default to NIH login.\n        - Optional parameters: "desc" (description) and "secondary"\n        (boolean - can be used by the frontend to display secondary\n        buttons differently).\n\n    Returns:\n        dict: { name, desc, idp, urls, secondary }\n        - urls: list of { name, url } dictionaries\n    '
    info = {'id': login_details['idp'], 'idp': login_details['idp'], 'name': login_details['name'], 'url': absolute_login_url(login_details['idp']), 'desc': login_details.get('desc', None), 'secondary': login_details.get('secondary', False)}
    fence_idp = None
    if (login_details['idp'] == 'fence'):
        fence_idp = login_details.get('fence_idp')
    if (((login_details['idp'] == 'shibboleth') or (fence_idp == 'shibboleth')) and ('shib_idps' in login_details)):
        if (not hasattr(flask.current_app, 'all_shib_idps')):
            flask.current_app.all_shib_idps = get_all_shib_idps()
        requested_shib_idps = login_details['shib_idps']
        if (requested_shib_idps == '*'):
            shib_idps = flask.current_app.all_shib_idps
        elif isinstance(requested_shib_idps, list):
            shib_idps = []
            for requested_shib_idp in requested_shib_idps:
                shib_idp = next((available_shib_idp for available_shib_idp in flask.current_app.all_shib_idps if (available_shib_idp['idp'] == requested_shib_idp)), None)
                if (not shib_idp):
                    raise InternalError('Requested shib_idp "{}" does not exist'.format(requested_shib_idp))
                shib_idps.append(shib_idp)
        else:
            raise InternalError('fence provider misconfigured: "shib_idps" must be a list or "*", got {}'.format(requested_shib_idps))
        info['urls'] = [{'name': shib_idp['name'], 'url': absolute_login_url(login_details['idp'], fence_idp, shib_idp['idp'])} for shib_idp in shib_idps]
    else:
        info['urls'] = [{'name': login_details['name'], 'url': absolute_login_url(login_details['idp'], fence_idp)}]
    return info
Args:
    login_details (dict):
    { name, desc, idp, fence_idp, shib_idps, secondary }
    - "idp": a configured provider.
    Multiple options can be configured with the same idp.
    - if provider_id is "fence", "fence_idp" can be any of the
    providers supported by the other Fence. If not specified, will
    default to NIH login.
    - if provider_id is "fence" and fence_idp is "shibboleth", a
    list of "shib_idps" can be configured for InCommon login. If
    not specified, will default to NIH login.
    - Optional parameters: "desc" (description) and "secondary"
    (boolean - can be used by the frontend to display secondary
    buttons differently).

Returns:
    dict: { name, desc, idp, urls, secondary }
    - urls: list of { name, url } dictionaries
def provider_info(login_details):
    '\n    Args:\n        login_details (dict):\n        { name, desc, idp, fence_idp, shib_idps, secondary }\n        - "idp": a configured provider.\n        Multiple options can be configured with the same idp.\n        - if provider_id is "fence", "fence_idp" can be any of the\n        providers supported by the other Fence. If not specified, will\n        default to NIH login.\n        - if provider_id is "fence" and fence_idp is "shibboleth", a\n        list of "shib_idps" can be configured for InCommon login. If\n        not specified, will default to NIH login.\n        - Optional parameters: "desc" (description) and "secondary"\n        (boolean - can be used by the frontend to display secondary\n        buttons differently).\n\n    Returns:\n        dict: { name, desc, idp, urls, secondary }\n        - urls: list of { name, url } dictionaries\n    '
    info = {'id': login_details['idp'], 'idp': login_details['idp'], 'name': login_details['name'], 'url': absolute_login_url(login_details['idp']), 'desc': login_details.get('desc', None), 'secondary': login_details.get('secondary', False)}
    fence_idp = None
    if (login_details['idp'] == 'fence'):
        fence_idp = login_details.get('fence_idp')
    if (((login_details['idp'] == 'shibboleth') or (fence_idp == 'shibboleth')) and ('shib_idps' in login_details)):
        if (not hasattr(flask.current_app, 'all_shib_idps')):
            flask.current_app.all_shib_idps = get_all_shib_idps()
        requested_shib_idps = login_details['shib_idps']
        if (requested_shib_idps == '*'):
            shib_idps = flask.current_app.all_shib_idps
        elif isinstance(requested_shib_idps, list):
            shib_idps = []
            for requested_shib_idp in requested_shib_idps:
                shib_idp = next((available_shib_idp for available_shib_idp in flask.current_app.all_shib_idps if (available_shib_idp['idp'] == requested_shib_idp)), None)
                if (not shib_idp):
                    raise InternalError('Requested shib_idp "{}" does not exist'.format(requested_shib_idp))
                shib_idps.append(shib_idp)
        else:
            raise InternalError('fence provider misconfigured: "shib_idps" must be a list or "*", got {}'.format(requested_shib_idps))
        info['urls'] = [{'name': shib_idp['name'], 'url': absolute_login_url(login_details['idp'], fence_idp, shib_idp['idp'])} for shib_idp in shib_idps]
    else:
        info['urls'] = [{'name': login_details['name'], 'url': absolute_login_url(login_details['idp'], fence_idp)}]
    return info