From 60b6414a50896fe1aca95b0754c1099067ad44ce Mon Sep 17 00:00:00 2001 From: Evan Goode Date: Fri, 22 Nov 2024 15:35:36 -0500 Subject: [PATCH] Test for AllowTextureFromURL --- account_test.go | 4 +- api_test.go | 30 ++++++------ auth_test.go | 4 +- authlib_injector_test.go | 2 +- front_test.go | 101 +++++++++++++++++++++++++-------------- services_test.go | 8 ++-- session_test.go | 2 +- test_suite_test.go | 4 +- 8 files changed, 93 insertions(+), 62 deletions(-) diff --git a/account_test.go b/account_test.go index 8f4f01f..7d78551 100644 --- a/account_test.go +++ b/account_test.go @@ -15,7 +15,7 @@ func TestAccount(t *testing.T) { ts.Setup(config) defer ts.Teardown() - ts.CreateTestUser(ts.Server, TEST_USERNAME) + ts.CreateTestUser(ts.App, ts.Server, TEST_USERNAME) t.Run("Test /users/profiles/minecraft/:playerName", ts.testAccountPlayerNameToID) t.Run("Test /profiles/minecraft", ts.makeTestAccountPlayerNamesToIDs("/profiles/minecraft")) @@ -32,7 +32,7 @@ func TestAccount(t *testing.T) { ts.Setup(config) defer ts.Teardown() - ts.CreateTestUser(ts.AuxServer, TEST_USERNAME) + ts.CreateTestUser(ts.AuxApp, ts.AuxServer, TEST_USERNAME) t.Run("Test /users/profiles/minecraft/:playerName, fallback API server", ts.testAccountPlayerNameToIDFallback) t.Run("Test /profile/minecraft, fallback API server", ts.testAccountPlayerNamesToIDsFallback) diff --git a/api_test.go b/api_test.go index 4d44e3a..5952277 100644 --- a/api_test.go +++ b/api_test.go @@ -34,9 +34,9 @@ func TestAPI(t *testing.T) { func (ts *TestSuite) testAPIGetUsers(t *testing.T) { username1 := "admin" - admin, _ := ts.CreateTestUser(ts.Server, username1) + admin, _ := ts.CreateTestUser(ts.App, ts.Server, username1) username2 := "user2" - user2, _ := ts.CreateTestUser(ts.Server, username2) + user2, _ := ts.CreateTestUser(ts.App, ts.Server, username2) // admin should get a response rec := ts.Get(t, ts.Server, "/drasl/api/v1/users", nil, &admin.APIToken) @@ -57,9 +57,9 @@ func (ts *TestSuite) testAPIGetUsers(t *testing.T) { func (ts *TestSuite) testAPIGetUser(t *testing.T) { username1 := "admin" - admin, _ := ts.CreateTestUser(ts.Server, username1) + admin, _ := ts.CreateTestUser(ts.App, ts.Server, username1) username2 := "user2" - user2, _ := ts.CreateTestUser(ts.Server, username2) + user2, _ := ts.CreateTestUser(ts.App, ts.Server, username2) // admin should get a response rec := ts.Get(t, ts.Server, "/drasl/api/v1/users/"+user2.UUID, nil, &admin.APIToken) @@ -80,9 +80,9 @@ func (ts *TestSuite) testAPIGetUser(t *testing.T) { func (ts *TestSuite) testAPIDeleteUser(t *testing.T) { username1 := "admin" - admin, _ := ts.CreateTestUser(ts.Server, username1) + admin, _ := ts.CreateTestUser(ts.App, ts.Server, username1) username2 := "user2" - user2, _ := ts.CreateTestUser(ts.Server, username2) + user2, _ := ts.CreateTestUser(ts.App, ts.Server, username2) // user2 (not admin) should get a StatusForbidden rec := ts.Get(t, ts.Server, "/drasl/api/v1/users/"+admin.UUID, nil, &user2.APIToken) @@ -104,7 +104,7 @@ func (ts *TestSuite) testAPIDeleteUser(t *testing.T) { func (ts *TestSuite) testAPIDeleteSelf(t *testing.T) { username := "user" - user, _ := ts.CreateTestUser(ts.Server, username) + user, _ := ts.CreateTestUser(ts.App, ts.Server, username) rec := ts.Delete(t, ts.Server, "/drasl/api/v1/user", nil, &user.APIToken) assert.Equal(t, http.StatusNoContent, rec.Code) @@ -117,10 +117,10 @@ func (ts *TestSuite) testAPIDeleteSelf(t *testing.T) { func (ts *TestSuite) testAPIGetSelf(t *testing.T) { adminUsername := "admin" - admin, _ := ts.CreateTestUser(ts.Server, adminUsername) + admin, _ := ts.CreateTestUser(ts.App, ts.Server, adminUsername) assert.True(t, admin.IsAdmin) username2 := "user2" - user2, _ := ts.CreateTestUser(ts.Server, username2) + user2, _ := ts.CreateTestUser(ts.App, ts.Server, username2) // admin (admin) should get a response rec := ts.Get(t, ts.Server, "/drasl/api/v1/user", nil, &admin.APIToken) @@ -141,7 +141,7 @@ func (ts *TestSuite) testAPIGetSelf(t *testing.T) { func (ts *TestSuite) testAPICreateUser(t *testing.T) { adminUsername := "admin" - admin, _ := ts.CreateTestUser(ts.Server, adminUsername) + admin, _ := ts.CreateTestUser(ts.App, ts.Server, adminUsername) user2Username := "user2" @@ -185,7 +185,7 @@ func (ts *TestSuite) testAPICreateUser(t *testing.T) { func (ts *TestSuite) testAPIGetChallengeSkin(t *testing.T) { username := "user" - user, _ := ts.CreateTestUser(ts.Server, username) + user, _ := ts.CreateTestUser(ts.App, ts.Server, username) ts.Get(t, ts.Server, "/drasl/api/v1/challenge-skin", nil, &user.APIToken) req := httptest.NewRequest(http.MethodGet, "/drasl/api/v1/challenge-skin", nil) @@ -203,9 +203,9 @@ func (ts *TestSuite) testAPIGetChallengeSkin(t *testing.T) { func (ts *TestSuite) testAPIGetInvites(t *testing.T) { username1 := "admin" - admin, _ := ts.CreateTestUser(ts.Server, username1) + admin, _ := ts.CreateTestUser(ts.App, ts.Server, username1) username2 := "user2" - user2, _ := ts.CreateTestUser(ts.Server, username2) + user2, _ := ts.CreateTestUser(ts.App, ts.Server, username2) _, err := ts.App.CreateInvite() assert.Nil(t, err) @@ -242,9 +242,9 @@ func (ts *TestSuite) testAPIGetInvites(t *testing.T) { func (ts *TestSuite) testAPICreateInvite(t *testing.T) { username1 := "admin" - admin, _ := ts.CreateTestUser(ts.Server, username1) + admin, _ := ts.CreateTestUser(ts.App, ts.Server, username1) username2 := "user2" - user2, _ := ts.CreateTestUser(ts.Server, username2) + user2, _ := ts.CreateTestUser(ts.App, ts.Server, username2) var invites []Invite result := ts.App.DB.Find(&invites) diff --git a/auth_test.go b/auth_test.go index 4037ddc..549e705 100644 --- a/auth_test.go +++ b/auth_test.go @@ -15,8 +15,8 @@ func TestAuth(t *testing.T) { ts.Setup(config) defer ts.Teardown() - ts.CreateTestUser(ts.Server, TEST_USERNAME) - ts.CreateTestUser(ts.Server, TEST_OTHER_USERNAME) + ts.CreateTestUser(ts.App, ts.Server, TEST_USERNAME) + ts.CreateTestUser(ts.App, ts.Server, TEST_OTHER_USERNAME) t.Run("Test /", ts.testGetServerInfo) t.Run("Test /authenticate", ts.testAuthenticate) diff --git a/authlib_injector_test.go b/authlib_injector_test.go index 1785cd0..d97bea5 100644 --- a/authlib_injector_test.go +++ b/authlib_injector_test.go @@ -23,7 +23,7 @@ func TestAuthlibInjector(t *testing.T) { ts.Setup(config) defer ts.Teardown() - ts.CreateTestUser(ts.Server, TEST_USERNAME) + ts.CreateTestUser(ts.App, ts.Server, TEST_USERNAME) t.Run("Test /authlib-injector", ts.testAuthlibInjectorRoot) } diff --git a/front_test.go b/front_test.go index 07d2210..77407db 100644 --- a/front_test.go +++ b/front_test.go @@ -48,7 +48,7 @@ func setupRegistrationExistingPlayerTS(requireSkinVerification bool, requireInvi } ts.Setup(config) - ts.CreateTestUser(ts.AuxServer, EXISTING_USERNAME) + ts.CreateTestUser(ts.AuxApp, ts.AuxServer, EXISTING_USERNAME) return ts } @@ -125,7 +125,6 @@ func TestFront(t *testing.T) { ts := &TestSuite{} config := testConfig() - config.RegistrationExistingPlayer.Allow = false config.DefaultAdmins = []string{"registrationNewA"} ts.Setup(config) defer ts.Teardown() @@ -143,7 +142,6 @@ func TestFront(t *testing.T) { ts := &TestSuite{} config := testConfig() - config.RegistrationExistingPlayer.Allow = false config.AllowSkins = false config.AllowCapes = false ts.Setup(config) @@ -197,6 +195,21 @@ func TestFront(t *testing.T) { t.Run("Test body size limiting", ts.testBodyLimit) } + { + // Set skin texture from URL + ts := &TestSuite{} + + auxConfig := testConfig() + ts.SetupAux(auxConfig) + ts.CreateTestUser(ts.AuxApp, ts.AuxServer, EXISTING_USERNAME) + + config := testConfig() + config.AllowTextureFromURL = true + ts.Setup(config) + defer ts.Teardown() + + t.Run("Test setting texture from URL", ts.testTextureFromURL) + } { // Registration as existing player allowed, skin verification not required ts := setupRegistrationExistingPlayerTS(false, false) @@ -402,7 +415,7 @@ func (ts *TestSuite) testRegistrationNewPlayer(t *testing.T) { func (ts *TestSuite) testRegistrationNewPlayerChosenUUIDNotAllowed(t *testing.T) { username := "noChosenUUID" - ts.CreateTestUser(ts.Server, username) + ts.CreateTestUser(ts.App, ts.Server, username) uuid := "11111111-2222-3333-4444-555555555555" @@ -652,7 +665,7 @@ func (ts *TestSuite) testRegistrationExistingPlayerInvite(t *testing.T) { func (ts *TestSuite) testLoginLogout(t *testing.T) { username := "loginLogout" - ts.CreateTestUser(ts.Server, username) + ts.CreateTestUser(ts.App, ts.Server, username) { // Login @@ -723,7 +736,6 @@ func (ts *TestSuite) testRegistrationExistingPlayerNoVerification(t *testing.T) form.Set("returnUrl", returnURL) rec := ts.PostForm(t, ts.Server, "/web/register", form, nil, nil) ts.registrationShouldSucceed(t, rec) - browserTokenCookie := getCookie(rec, "browserToken") // Check that the user has been created with the same UUID var auxUser User @@ -733,26 +745,6 @@ func (ts *TestSuite) testRegistrationExistingPlayerNoVerification(t *testing.T) result = ts.App.DB.First(&user, "username = ?", username) assert.Nil(t, result.Error) assert.Equal(t, auxUser.UUID, user.UUID) - { - // Test setting skin from URL - body := &bytes.Buffer{} - writer := multipart.NewWriter(body) - - // Set a skin on the existing account - assert.Nil(t, ts.AuxApp.SetSkinAndSave(&auxUser, bytes.NewReader(BLUE_SKIN))) - skinHash := *UnmakeNullString(&auxUser.SkinHash) - skinURL, err := ts.AuxApp.SkinURL(skinHash) - assert.Nil(t, err) - - assert.Nil(t, writer.WriteField("skinUrl", skinURL)) - assert.Nil(t, writer.WriteField("returnUrl", ts.App.FrontEndURL+"/web/profile")) - assert.Nil(t, writer.Close()) - rec := ts.PostMultipart(t, ts.Server, "/web/update", body, writer, []http.Cookie{*browserTokenCookie}, nil) - ts.updateShouldSucceed(t, rec) - - assert.Nil(t, ts.App.DB.First(&user, "username = ?", username).Error) - assert.Equal(t, skinHash, *UnmakeNullString(&user.SkinHash)) - } { // Registration as a new user should fail form := url.Values{} @@ -837,7 +829,7 @@ func (ts *TestSuite) testRegistrationExistingPlayerWithVerification(t *testing.T func (ts *TestSuite) testNewInviteDeleteInvite(t *testing.T) { username := "inviteAdmin" - user, browserTokenCookie := ts.CreateTestUser(ts.Server, username) + user, browserTokenCookie := ts.CreateTestUser(ts.App, ts.Server, username) user.IsAdmin = true result := ts.App.DB.Save(&user) @@ -878,8 +870,8 @@ func (ts *TestSuite) testNewInviteDeleteInvite(t *testing.T) { func (ts *TestSuite) testUpdate(t *testing.T) { username := "testUpdate" takenUsername := "testUpdateTaken" - user, browserTokenCookie := ts.CreateTestUser(ts.Server, username) - takenUser, takenBrowserTokenCookie := ts.CreateTestUser(ts.Server, takenUsername) + user, browserTokenCookie := ts.CreateTestUser(ts.App, ts.Server, username) + takenUser, takenBrowserTokenCookie := ts.CreateTestUser(ts.App, ts.Server, takenUsername) sum := blake3.Sum256(RED_SKIN) redSkinHash := hex.EncodeToString(sum[:]) @@ -997,6 +989,17 @@ func (ts *TestSuite) testUpdate(t *testing.T) { rec := ts.PostMultipart(t, ts.Server, "/web/update", body, writer, []http.Cookie{*browserTokenCookie}, nil) ts.updateShouldFail(t, rec, "Invalid player name: can't be longer than 16 characters", ts.App.FrontEndURL+"/web/profile") } + { + // Setting a skin from URL should fail for non-admin (config.AllowTextureFromURL is false by default) + body := &bytes.Buffer{} + writer := multipart.NewWriter(body) + + assert.Nil(t, writer.WriteField("skinUrl", "https://example.com/skin.png")) + assert.Nil(t, writer.WriteField("returnUrl", ts.App.FrontEndURL+"/web/profile")) + assert.Nil(t, writer.Close()) + rec := ts.PostMultipart(t, ts.Server, "/web/update", body, writer, []http.Cookie{*takenBrowserTokenCookie}, nil) + ts.updateShouldFail(t, rec, "Setting a skin from a URL is not allowed.", ts.App.FrontEndURL+"/web/profile") + } { // Invalid fallback player should fail body := &bytes.Buffer{} @@ -1041,7 +1044,7 @@ func (ts *TestSuite) testUpdate(t *testing.T) { func (ts *TestSuite) testUpdateSkinsCapesNotAllowed(t *testing.T) { username := "updateNoSkinCape" - _, browserTokenCookie := ts.CreateTestUser(ts.Server, username) + _, browserTokenCookie := ts.CreateTestUser(ts.App, ts.Server, username) { body := &bytes.Buffer{} writer := multipart.NewWriter(body) @@ -1083,11 +1086,39 @@ func (ts *TestSuite) testUpdateSkinsCapesNotAllowed(t *testing.T) { } } +func (ts *TestSuite) testTextureFromURL(t *testing.T) { + // Test setting skin from URL + username := "textureFromURL" + user, browserTokenCookie := ts.CreateTestUser(ts.App, ts.Server, username) + + var auxUser User + result := ts.AuxApp.DB.First(&auxUser, "username = ?", EXISTING_USERNAME) + assert.Nil(t, result.Error) + + body := &bytes.Buffer{} + writer := multipart.NewWriter(body) + + // Set a skin on the existing account + assert.Nil(t, ts.AuxApp.SetSkinAndSave(&auxUser, bytes.NewReader(BLUE_SKIN))) + skinHash := *UnmakeNullString(&auxUser.SkinHash) + skinURL, err := ts.AuxApp.SkinURL(skinHash) + assert.Nil(t, err) + + assert.Nil(t, writer.WriteField("skinUrl", skinURL)) + assert.Nil(t, writer.WriteField("returnUrl", ts.App.FrontEndURL+"/web/profile")) + assert.Nil(t, writer.Close()) + rec := ts.PostMultipart(t, ts.Server, "/web/update", body, writer, []http.Cookie{*browserTokenCookie}, nil) + ts.updateShouldSucceed(t, rec) + + assert.Nil(t, ts.App.DB.First(&user, "username = ?", username).Error) + assert.Equal(t, skinHash, *UnmakeNullString(&user.SkinHash)) +} + func (ts *TestSuite) testDeleteAccount(t *testing.T) { usernameA := "deleteA" usernameB := "deleteB" - ts.CreateTestUser(ts.Server, usernameA) + ts.CreateTestUser(ts.App, ts.Server, usernameA) { var user User result := ts.App.DB.First(&user, "username = ?", usernameA) @@ -1102,7 +1133,7 @@ func (ts *TestSuite) testDeleteAccount(t *testing.T) { assert.Nil(t, err) // Register usernameB - _, browserTokenCookie := ts.CreateTestUser(ts.Server, usernameB) + _, browserTokenCookie := ts.CreateTestUser(ts.App, ts.Server, usernameB) // Check that usernameB has been created var otherUser User @@ -1184,13 +1215,13 @@ func (ts *TestSuite) testAdmin(t *testing.T) { returnURL := ts.App.FrontEndURL + "/web/admin" username := "admin" - user, browserTokenCookie := ts.CreateTestUser(ts.Server, username) + user, browserTokenCookie := ts.CreateTestUser(ts.App, ts.Server, username) otherUsername := "adminOther" - _, otherBrowserTokenCookie := ts.CreateTestUser(ts.Server, otherUsername) + _, otherBrowserTokenCookie := ts.CreateTestUser(ts.App, ts.Server, otherUsername) anotherUsername := "adminAnother" - _, _ = ts.CreateTestUser(ts.Server, anotherUsername) + _, _ = ts.CreateTestUser(ts.App, ts.Server, anotherUsername) // Make `username` an admin user.IsAdmin = true diff --git a/services_test.go b/services_test.go index 8443012..ee5b071 100644 --- a/services_test.go +++ b/services_test.go @@ -37,9 +37,9 @@ func TestServices(t *testing.T) { ts.Setup(config) defer ts.Teardown() - ts.CreateTestUser(ts.Server, TEST_USERNAME) - ts.CreateTestUser(ts.Server, SERVICES_EXISTING_USERNAME) - ts.CreateTestUser(ts.AuxServer, TEST_USERNAME) + ts.CreateTestUser(ts.App, ts.Server, TEST_USERNAME) + ts.CreateTestUser(ts.App, ts.Server, SERVICES_EXISTING_USERNAME) + ts.CreateTestUser(ts.AuxApp, ts.AuxServer, TEST_USERNAME) // Set the red skin on the aux user var user User @@ -68,7 +68,7 @@ func TestServices(t *testing.T) { ts.Setup(config) defer ts.Teardown() - ts.CreateTestUser(ts.Server, TEST_USERNAME) + ts.CreateTestUser(ts.App, ts.Server, TEST_USERNAME) t.Run("Test POST /minecraft/profile/skins, skins not allowed", ts.testServicesUploadSkinSkinsNotAllowed) } diff --git a/session_test.go b/session_test.go index c64efce..070b0af 100644 --- a/session_test.go +++ b/session_test.go @@ -15,7 +15,7 @@ func TestSession(t *testing.T) { ts.Setup(config) defer ts.Teardown() - ts.CreateTestUser(ts.Server, TEST_USERNAME) + ts.CreateTestUser(ts.App, ts.Server, TEST_USERNAME) t.Run("Test /session/minecraft/hasJoined", ts.testSessionHasJoined) t.Run("Test /session/minecraft/join", ts.testSessionJoin) diff --git a/test_suite_test.go b/test_suite_test.go index b277042..2993e8b 100644 --- a/test_suite_test.go +++ b/test_suite_test.go @@ -142,7 +142,7 @@ func (ts *TestSuite) Teardown() { Check(err) } -func (ts *TestSuite) CreateTestUser(server *echo.Echo, username string) (*User, *http.Cookie) { +func (ts *TestSuite) CreateTestUser(app *App, server *echo.Echo, username string) (*User, *http.Cookie) { form := url.Values{} form.Set("username", username) form.Set("password", TEST_PASSWORD) @@ -153,7 +153,7 @@ func (ts *TestSuite) CreateTestUser(server *echo.Echo, username string) (*User, server.ServeHTTP(rec, req) var user User - ts.App.DB.First(&user, "username = ?", username) + app.DB.First(&user, "username = ?", username) browserToken := getCookie(rec, "browserToken")