def test_should_return_invalid_grant_if_duplicate_access_token_request_with_same_authorization_grant():
    code = request_authorization_code("client-id")
    url = build_access_token_url({"grant_type": "authorization_code", "code": code, "redirect_uri": "http://callback"})
    valid_headers = {
        "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
        "Authorization": build_basic_authorization_header("client-id", code),
    }

    resp = requests.post(url, headers=valid_headers)
    assert 200 == resp.status_code
    # performs a new POST to get the access token, but it has already been taken
    assert_invalid_grant(url, "Authorization grant already used", "POST", valid_headers)
def test_should_return_invalid_grant_error_if_redirect_uri_is_invalid():
    # the redirect uri informed on body is not the same informed when the code
    # was created
    code = request_authorization_code("client-id", redirect_uri="http://example.com")
    url = build_access_token_url(
        {"grant_type": "authorization_code", "code": code, "redirect_uri": "http://callback"}
    )  # different uri
    valid_headers = {
        "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
        "Authorization": build_basic_authorization_header("client-id", code),
    }
    assert_invalid_grant(url, "redirect_uri does not match", "POST", valid_headers)
def test_should_return_400_with_invalid_grant_error_if_code_from_body_was_not_found():
    # there is a code for this client and the authorization header is valid, but
    # the code informed on body is not the correct code
    code = request_authorization_code("client-id")
    url = build_access_token_url(
        {"grant_type": "authorization_code", "code": "INVALID-CODE", "redirect_uri": "http://callback"}
    )
    valid_headers = {
        "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
        "Authorization": build_basic_authorization_header("client-id", code),
    }
    assert_invalid_grant(url, "Invalid code for this client", "POST", valid_headers)
def test_should_allow_json_response_customization_via_plugin():
    client_id = "client-id-from-access-token-tests"
    code = request_authorization_code(client_id)
    url = build_access_token_url({"grant_type": "authorization_code", "code": code, "redirect_uri": "http://callback"})
    valid_headers = {
        "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
        "Authorization": build_basic_authorization_header(client_id, code),
    }

    resp = requests.post(url, headers=valid_headers)
    body = parse_json_response(resp)

    assert 200 == resp.status_code
    assert "Igor Sobreira" == body.get("user_name", "")
def check_multiple_users_with_client_ids(bob_client_id, ted_client_id):
    bob_code = request_authorization_code(bob_client_id)
    ted_code = request_authorization_code(ted_client_id)

    bob_url = build_access_token_url(
        {"grant_type": "authorization_code", "code": bob_code, "redirect_uri": "http://callback"}
    )
    ted_url = build_access_token_url(
        {"grant_type": "authorization_code", "code": ted_code, "redirect_uri": "http://callback"}
    )

    bob_response = requests.post(
        bob_url,
        headers={
            "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
            "Authorization": build_basic_authorization_header(bob_client_id, bob_code),
        },
    )
    ted_response = requests.post(
        ted_url,
        headers={
            "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
            "Authorization": build_basic_authorization_header(ted_client_id, ted_code),
        },
    )

    assert 200 == bob_response.status_code
    assert 200 == ted_response.status_code

    bob_json = parse_json_response(bob_response)
    ted_json = parse_json_response(ted_response)

    assert ["access_token", "token_type", "expires_in"] == bob_json.keys()
    assert ["access_token", "token_type", "expires_in"] == ted_json.keys()

    assert bob_json["access_token"] != ted_json["access_token"]
def test_should_return_401_with_invalid_client_error_if_invalid_code_on_Authorization_header():
    code = request_authorization_code("client-id")
    url = build_access_token_url({"grant_type": "authorization_code", "code": code, "redirect_uri": "http://callback"})
    valid_headers = {
        "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
        "Authorization": build_basic_authorization_header("client-id", "INVALIDCODE"),
    }
    resp = requests.post(url, headers=valid_headers)
    expected_response = {
        "error": "invalid_client",
        "error_description": "Invalid client_id or code on Authorization header",
    }

    assert expected_response == parse_json_response(resp)
    assert 401 == resp.status_code
    assert 'Basic realm="OAuth 2.0 Secure Area"' == resp.headers.get("WWW-Authenticate")
def test_happy_path_should_return_access_token_if_valid_authorization_code():
    # tokens generation is stubbed in tests/helpers.py
    client_id = "client1"
    code = request_authorization_code(client_id)

    url = build_access_token_url({"grant_type": "authorization_code", "code": code, "redirect_uri": "http://callback"})

    valid_headers = {
        "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
        "Authorization": build_basic_authorization_header(client_id, code),
    }

    resp = requests.post(url, headers=valid_headers)
    body = parse_json_response(resp)

    assert 200 == resp.status_code
    assert ["access_token", "token_type", "expires_in"] == body.keys()
    assert body["access_token"].startswith("access-token-")
    assert "bearer" == body["token_type"]