From 80e6a7376224e9253e8d8701c0f2707eb7eba73c Mon Sep 17 00:00:00 2001 From: Rajat Bajaj Date: Mon, 9 Dec 2024 10:49:29 +0530 Subject: [PATCH] Added test recordings --- authentication/authentication_test.go | 14 +-- authentication/ciba.go | 12 +- authentication/ciba/ciba.go | 6 +- authentication/ciba_test.go | 103 ++++++++++-------- authentication/oauth_test.go | 8 +- ...hould_throw_error_for_invalid_User_ID.yaml | 46 ++++++++ ..._missing_LoginHint_and_BindingMessage.yaml | 3 + ...ld_throw_error_if_scope_is_not_openid.yaml | 46 ++++++++ .../authentication/TestCIBA_Initiate.yaml | 4 +- 9 files changed, 177 insertions(+), 65 deletions(-) create mode 100644 test/data/recordings/authentication/TestCIBANegative_Initiate/Should_throw_error_for_invalid_User_ID.yaml create mode 100644 test/data/recordings/authentication/TestCIBANegative_Initiate/Should_throw_error_for_missing_LoginHint_and_BindingMessage.yaml create mode 100644 test/data/recordings/authentication/TestCIBANegative_Initiate/Should_throw_error_if_scope_is_not_openid.yaml diff --git a/authentication/authentication_test.go b/authentication/authentication_test.go index 63f654f7..f19e1134 100644 --- a/authentication/authentication_test.go +++ b/authentication/authentication_test.go @@ -527,7 +527,7 @@ func usingRecordingResponses(t *testing.T) bool { return httpRecordingsEnabled && domain == "go-auth0-dev.eu.auth0.com" } -func givenAUser(t *testing.T) *management.User { +func givenAUser(t *testing.T) userDetails { t.Helper() if !usingRecordingResponses(t) { @@ -547,14 +547,12 @@ func givenAUser(t *testing.T) *management.User { err := mgmtAPI.User.Delete(context.Background(), user.GetID()) require.NoError(t, err) }) - - return user } - return &management.User{ - Connection: auth0.String("Username-Password-Authentication"), - Email: auth0.String("chuck@example.com"), - Password: auth0.String("Testpassword123!"), - Username: auth0.String("test-user"), + return userDetails{ + connection: "Username-Password-Authentication", + email: "chuck@example.com", + password: "Testpassword123!", + username: "test-user", } } diff --git a/authentication/ciba.go b/authentication/ciba.go index f785c9f9..9e1083e8 100644 --- a/authentication/ciba.go +++ b/authentication/ciba.go @@ -2,6 +2,7 @@ package authentication import ( "context" + "encoding/json" "fmt" "github.com/auth0/go-auth0/authentication/ciba" "net/url" @@ -26,7 +27,7 @@ func (c *CIBA) Initiate(ctx context.Context, body ciba.Request, opts ...RequestO var missing []string check(&missing, "ClientID", body.ClientID != "" || c.authentication.clientID != "") check(&missing, "ClientSecret", body.ClientSecret != "" || c.authentication.clientSecret != "") - check(&missing, "LoginHint", body.LoginHint != "") + check(&missing, "LoginHint", len(body.LoginHint) != 0) check(&missing, "Scope", body.Scope != "") check(&missing, "BindingMessage", body.BindingMessage != "") @@ -37,11 +38,18 @@ func (c *CIBA) Initiate(ctx context.Context, body ciba.Request, opts ...RequestO data := url.Values{ "client_id": []string{body.ClientID}, "client_secret": []string{body.ClientSecret}, - "login_hint": []string{body.LoginHint}, "scope": []string{body.Scope}, "binding_message": []string{body.BindingMessage}, } + jsonBytes, err := json.Marshal(body.LoginHint) + if err != nil { + fmt.Println("Error marshaling map to JSON:", err) + return + } + + data.Set("login_hint", string(jsonBytes)) + // Perform the request err = c.authentication.Request(ctx, "POST", c.authentication.URI("bc-authorize"), data, &r, opts...) if err != nil { diff --git a/authentication/ciba/ciba.go b/authentication/ciba/ciba.go index f52860be..ebab84e0 100644 --- a/authentication/ciba/ciba.go +++ b/authentication/ciba/ciba.go @@ -2,13 +2,13 @@ package ciba // Request defines the request body for calling the bc-authorize endpoint type Request struct { - //ClientAuthentication // The client_id of your client. ClientID string `json:"client_id,omitempty"` // The client_secret of your client. ClientSecret string `json:"client_secret,omitempty"` - - LoginHint string `json:"login_hint,omitempty"` + // This is a required field containing format, iss and sub + LoginHint map[string]string `json:"login_hint,omitempty"` + // The scope for the flow Scope string `json:"scope,omitempty"` Audience string `json:"audience,omitempty"` BindingMessage string `json:"binding_message,omitempty"` diff --git a/authentication/ciba_test.go b/authentication/ciba_test.go index f398afc7..65c0ec58 100644 --- a/authentication/ciba_test.go +++ b/authentication/ciba_test.go @@ -2,7 +2,6 @@ package authentication import ( "context" - "fmt" "github.com/auth0/go-auth0/authentication/ciba" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -12,14 +11,16 @@ import ( func TestCIBA_Initiate(t *testing.T) { configureHTTPTestRecordings(t, authAPI) - user := givenAUser(t) - // Call the Initiate method of the CIBA manager resp, err := authAPI.CIBA.Initiate(context.Background(), ciba.Request{ - ClientID: mgmtClientID, - ClientSecret: mgmtClientSecret, - Scope: "openid", - LoginHint: fmt.Sprintf(`{"format":"iss_sub","iss":"https://witty-silver-sailfish-sus1-staging-20240704.sus.auth0.com/","sub":"%s"}`, user.GetID()), + ClientID: mgmtClientID, + ClientSecret: mgmtClientSecret, + Scope: "openid", + LoginHint: map[string]string{ + "format": "iss_sub", + "iss": "https://witty-silver-sailfish-sus1-staging-20240704.sus.auth0.com/", + "sub": "auth0|6707939cad3d8bec47ecfa2e", + }, BindingMessage: "TEST-BINDING-MESSAGE", }) @@ -31,42 +32,52 @@ func TestCIBA_Initiate(t *testing.T) { assert.Greater(t, resp.Interval, int64(0), "interval should be greater than 0") } -//func givenAUser(t *testing.T) *management.User { -// t.Helper() -// -// userMetadata := map[string]interface{}{ -// "favourite_attack": "roundhouse_kick", -// } -// appMetadata := map[string]interface{}{ -// "facts": []string{ -// "count_to_infinity_twice", -// "kill_two_stones_with_one_bird", -// "can_hear_sign_language", -// }, -// } -// user := &management.User{ -// Connection: auth0.String("Username-Password-Authentication"), -// Email: auth0.String(fmt.Sprintf("chuck%d@example.com", rand.Intn(999))), -// Password: auth0.String("Passwords hide their chuck"), -// Username: auth0.String(fmt.Sprintf("test-user%d", rand.Intn(999))), -// GivenName: auth0.String("Chuck"), -// FamilyName: auth0.String("Sanchez"), -// Nickname: auth0.String("Chucky"), -// UserMetadata: &userMetadata, -// EmailVerified: auth0.Bool(true), -// VerifyEmail: auth0.Bool(false), -// AppMetadata: &appMetadata, -// Picture: auth0.String("https://example-picture-url.jpg"), -// Blocked: auth0.Bool(false), -// } -// -// err := mgmtAPI.User.Create(context.Background(), user) -// require.NoError(t, err) -// -// t.Cleanup(func() { -// err := mgmtAPI.User.Delete(context.Background(), user.GetID()) -// require.NoError(t, err) -// }) -// -// return user -//} +func TestCIBANegative_Initiate(t *testing.T) { + t.Run("Should throw error for missing LoginHint and BindingMessage", func(t *testing.T) { + configureHTTPTestRecordings(t, authAPI) + + _, err := authAPI.CIBA.Initiate(context.Background(), ciba.Request{ + ClientID: mgmtClientID, + ClientSecret: mgmtClientSecret, + Scope: "openid", + }) + + assert.ErrorContains(t, err, "missing required fields: LoginHint, BindingMessage") + }) + + t.Run("Should throw error for invalid User ID", func(t *testing.T) { + configureHTTPTestRecordings(t, authAPI) + + _, err := authAPI.CIBA.Initiate(context.Background(), ciba.Request{ + ClientID: mgmtClientID, + ClientSecret: mgmtClientSecret, + Scope: "openid", + LoginHint: map[string]string{ + "format": "iss_sub", + "iss": "https://witty-silver-sailfish-sus1-staging-20240704.sus.auth0.com/", + "sub": "auth0|Random-ID", + }, + BindingMessage: "TEST-BINDING-MESSAGE", + }) + + assert.ErrorContains(t, err, "User ID is malformed or unknown") + }) + + t.Run("Should throw error if scope is not openid", func(t *testing.T) { + configureHTTPTestRecordings(t, authAPI) + + _, err := authAPI.CIBA.Initiate(context.Background(), ciba.Request{ + ClientID: mgmtClientID, + ClientSecret: mgmtClientSecret, + Scope: "tempID", + LoginHint: map[string]string{ + "format": "iss_sub", + "iss": "https://witty-silver-sailfish-sus1-staging-20240704.sus.auth0.com/", + "sub": "auth0|6707939cad3d8bec47ecfa2e", + }, + BindingMessage: "TEST-BINDING-MESSAGE", + }) + + assert.ErrorContains(t, err, "openid scope must be requested") + }) +} diff --git a/authentication/oauth_test.go b/authentication/oauth_test.go index f5f8f4ab..ef0fa9b6 100644 --- a/authentication/oauth_test.go +++ b/authentication/oauth_test.go @@ -30,8 +30,8 @@ func TestOAuthLoginWithPassword(t *testing.T) { user := givenAUser(t) tokenSet, err := auth.OAuth.LoginWithPassword(context.Background(), oauth.LoginWithPasswordRequest{ - Username: user.GetUsername(), - Password: user.GetPassword(), + Username: user.username, + Password: user.password, }, oauth.IDTokenValidationOptions{}) require.NoError(t, err) assert.NotEmpty(t, tokenSet.AccessToken) @@ -43,8 +43,8 @@ func TestOAuthLoginWithPassword(t *testing.T) { user := givenAUser(t) tokenSet, err := auth.OAuth.LoginWithPassword(context.Background(), oauth.LoginWithPasswordRequest{ - Username: user.GetUsername(), - Password: user.GetPassword(), + Username: user.username, + Password: user.password, Scope: "extra-scope", ExtraParameters: map[string]string{ "extra": "value", diff --git a/test/data/recordings/authentication/TestCIBANegative_Initiate/Should_throw_error_for_invalid_User_ID.yaml b/test/data/recordings/authentication/TestCIBANegative_Initiate/Should_throw_error_for_invalid_User_ID.yaml new file mode 100644 index 00000000..3f610af1 --- /dev/null +++ b/test/data/recordings/authentication/TestCIBANegative_Initiate/Should_throw_error_for_invalid_User_ID.yaml @@ -0,0 +1,46 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 350 + transfer_encoding: [] + trailer: {} + host: go-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: binding_message=TEST-BINDING-MESSAGE&client_id=test-client_id&client_secret=test-client_secret&login_hint=%7B%22format%22%3A%22iss_sub%22%2C%22iss%22%3A%22https%3A%2F%2Fgo-auth0-dev.eu.auth0.com.sus.auth0.com%2F%22%2C%22sub%22%3A%22auth0%7CRandom-ID%22%7D&scope=openid + form: + binding_message: + - TEST-BINDING-MESSAGE + client_id: + - test-client_id + client_secret: + - test-client_secret + login_hint: + - '{"format":"iss_sub","iss":"https://witty-silver-sailfish-sus1-staging-20240704.sus.auth0.com/","sub":"auth0|Random-ID"}' + scope: + - openid + headers: + Content-Type: + - application/x-www-form-urlencoded + url: https://go-auth0-dev.eu.auth0.com/bc-authorize + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 81 + uncompressed: false + body: '{"error":"unknown_user_id","error_description":"User ID is malformed or unknown"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 400 Bad Request + code: 400 + duration: 394.13825ms diff --git a/test/data/recordings/authentication/TestCIBANegative_Initiate/Should_throw_error_for_missing_LoginHint_and_BindingMessage.yaml b/test/data/recordings/authentication/TestCIBANegative_Initiate/Should_throw_error_for_missing_LoginHint_and_BindingMessage.yaml new file mode 100644 index 00000000..2797c38e --- /dev/null +++ b/test/data/recordings/authentication/TestCIBANegative_Initiate/Should_throw_error_for_missing_LoginHint_and_BindingMessage.yaml @@ -0,0 +1,3 @@ +--- +version: 2 +interactions: [] diff --git a/test/data/recordings/authentication/TestCIBANegative_Initiate/Should_throw_error_if_scope_is_not_openid.yaml b/test/data/recordings/authentication/TestCIBANegative_Initiate/Should_throw_error_if_scope_is_not_openid.yaml new file mode 100644 index 00000000..920bab4f --- /dev/null +++ b/test/data/recordings/authentication/TestCIBANegative_Initiate/Should_throw_error_if_scope_is_not_openid.yaml @@ -0,0 +1,46 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 365 + transfer_encoding: [] + trailer: {} + host: go-auth0-dev.eu.auth0.com + remote_addr: "" + request_uri: "" + body: binding_message=TEST-BINDING-MESSAGE&client_id=test-client_id&client_secret=test-client_secret&login_hint=%7B%22format%22%3A%22iss_sub%22%2C%22iss%22%3A%22https%3A%2F%2Fgo-auth0-dev.eu.auth0.com.sus.auth0.com%2F%22%2C%22sub%22%3A%22auth0%7C6707939cad3d8bec47ecfa2e%22%7D&scope=tempID + form: + binding_message: + - TEST-BINDING-MESSAGE + client_id: + - test-client_id + client_secret: + - test-client_secret + login_hint: + - '{"format":"iss_sub","iss":"https://witty-silver-sailfish-sus1-staging-20240704.sus.auth0.com/","sub":"auth0|6707939cad3d8bec47ecfa2e"}' + scope: + - tempID + headers: + Content-Type: + - application/x-www-form-urlencoded + url: https://go-auth0-dev.eu.auth0.com/bc-authorize + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 80 + uncompressed: false + body: '{"error":"invalid_request","error_description":"openid scope must be requested"}' + headers: + Content-Type: + - application/json; charset=utf-8 + status: 400 Bad Request + code: 400 + duration: 340.789875ms diff --git a/test/data/recordings/authentication/TestCIBA_Initiate.yaml b/test/data/recordings/authentication/TestCIBA_Initiate.yaml index 10230761..a1aaaa92 100644 --- a/test/data/recordings/authentication/TestCIBA_Initiate.yaml +++ b/test/data/recordings/authentication/TestCIBA_Initiate.yaml @@ -37,10 +37,10 @@ interactions: trailer: {} content_length: -1 uncompressed: true - body: '{"auth_req_id":"7rL9DmKgR6BdVVwrIGk4PlP-3gdQ60W6Iq8FhhXRybHMXyQVz3r6f3NwSkBaNqqC","expires_in":300,"interval":5}' + body: '{"auth_req_id":"WQJQFbnCpBr8qHEDxQT4jFBq5ceTei2t9Kfas1CFAEe19odPJYOUCJvZcFy4A2Ki","expires_in":300,"interval":5}' headers: Content-Type: - application/json; charset=utf-8 status: 200 OK code: 200 - duration: 606.440209ms + duration: 798.216458ms