def exchange_for_access_token(
    code, redirect_uri, client_id, secret, access_token_url=None, verify_cert=True
):
    """
    Exchanges authorization code for access token.

    :param code:
    :param redirect_uri:
    :param client_id:
    :param secret:
    :param access_token_url:
    :param verify_cert:
    :return:
    :return:
    """
    # take the information we have received from the provider to create a new request
    params = {
        "grant_type": "authorization_code",
        "scope": "openid email profile address",
        "code": code,
        "redirect_uri": redirect_uri,
        "client_id": client_id,
    }

    # the secret and cliendId will be given to you when you signup for the provider
    token = f"{client_id}:{secret}"

    basic = base64.b64encode(bytes(token, "utf-8"))
    headers = {
        "Content-Type": "application/x-www-form-urlencoded"
    }

    if current_app.config.get("TOKEN_AUTH_HEADER_CASE_SENSITIVE"):
        headers["Authorization"] = "Basic {}".format(basic.decode("utf-8"))
    else:
        headers["authorization"] = "basic {}".format(basic.decode("utf-8"))

    # exchange authorization code for access token.
    r = requests.post(
        access_token_url, headers=headers, params=params, verify=verify_cert
    )
    if r.status_code == 400:
        r = requests.post(
            access_token_url, headers=headers, data=params, verify=verify_cert
        )

    response = r.json()

    if not r.ok or "error" in response:
        raise TokenExchangeFailed(response.get("error", "Unknown error"), response.get("error_description", ""))

    id_token = response.get("id_token")
    access_token = response.get("access_token")

    if id_token is None or access_token is None:
        error = "missing tokens"
        missing_tokens = []
        if id_token is None:
            missing_tokens.append("id_token is missing")
        if access_token is None:
            missing_tokens.append("access_token is missing")
        description = " and ".join(missing_tokens)
        raise TokenExchangeFailed(error, description)

    return id_token, access_token

    Exchanges authorization code for access token.

    :param code:
    :param redirect_uri:
    :param client_id:
    :param secret:
    :param access_token_url:
    :param verify_cert:
    :return:
    :return:
    
lemur/auth/views.py