From 99b18f8a7b0987e15c325efae989d65977784ec2 Mon Sep 17 00:00:00 2001 From: Evan Tobin Date: Sat, 14 Oct 2023 03:04:44 -0500 Subject: [PATCH] Fix permissions for Token DELETE endpoint to match GET and POST (#27610) Fixes #27598 In #27080, the logic for the tokens endpoints were updated to allow admins to create and view tokens in other accounts. However, the same functionality was not added to the DELETE endpoint. This PR makes the DELETE endpoint function the same as the other token endpoints and adds unit tests --- routers/api/v1/user/app.go | 2 +- tests/integration/api_token_test.go | 31 +++++++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/routers/api/v1/user/app.go b/routers/api/v1/user/app.go index 6972931abc69f..cdec69be57814 100644 --- a/routers/api/v1/user/app.go +++ b/routers/api/v1/user/app.go @@ -193,7 +193,7 @@ func DeleteAccessToken(ctx *context.APIContext) { return } - if err := auth_model.DeleteAccessTokenByID(ctx, tokenID, ctx.Doer.ID); err != nil { + if err := auth_model.DeleteAccessTokenByID(ctx, tokenID, ctx.ContextUser.ID); err != nil { if auth_model.IsErrAccessTokenNotExist(err) { ctx.NotFound() } else { diff --git a/tests/integration/api_token_test.go b/tests/integration/api_token_test.go index a713922982300..6c7882fe30a4d 100644 --- a/tests/integration/api_token_test.go +++ b/tests/integration/api_token_test.go @@ -63,6 +63,33 @@ func TestAPIGetTokensPermission(t *testing.T) { MakeRequest(t, req, http.StatusForbidden) } +// TestAPIDeleteTokensPermission ensures that only the admin can delete tokens from other users +func TestAPIDeleteTokensPermission(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) + + // admin can delete tokens for other users + createAPIAccessTokenWithoutCleanUp(t, "test-key-1", user2, nil) + req := NewRequestf(t, "DELETE", "/api/v1/users/"+user2.LoginName+"/tokens/test-key-1") + req = AddBasicAuthHeader(req, admin.Name) + MakeRequest(t, req, http.StatusNoContent) + + // non-admin can delete tokens for himself + createAPIAccessTokenWithoutCleanUp(t, "test-key-2", user2, nil) + req = NewRequestf(t, "DELETE", "/api/v1/users/"+user2.LoginName+"/tokens/test-key-2") + req = AddBasicAuthHeader(req, user2.Name) + MakeRequest(t, req, http.StatusNoContent) + + // non-admin can't delete tokens for other users + createAPIAccessTokenWithoutCleanUp(t, "test-key-3", user2, nil) + req = NewRequestf(t, "DELETE", "/api/v1/users/"+user2.LoginName+"/tokens/test-key-3") + req = AddBasicAuthHeader(req, user4.Name) + MakeRequest(t, req, http.StatusForbidden) +} + type permission struct { category auth_model.AccessTokenScopeCategory level auth_model.AccessTokenScopeLevel @@ -526,7 +553,7 @@ func createAPIAccessTokenWithoutCleanUp(t *testing.T, tokenName string, user *us } } log.Debug("Requesting creation of token with scopes: %v", scopes) - req := NewRequestWithJSON(t, "POST", "/api/v1/users/user1/tokens", payload) + req := NewRequestWithJSON(t, "POST", "/api/v1/users/"+user.LoginName+"/tokens", payload) req = AddBasicAuthHeader(req, user.Name) resp := MakeRequest(t, req, http.StatusCreated) @@ -546,7 +573,7 @@ func createAPIAccessTokenWithoutCleanUp(t *testing.T, tokenName string, user *us // createAPIAccessTokenWithoutCleanUp Delete an API access token and assert that // deletion succeeded. func deleteAPIAccessToken(t *testing.T, accessToken api.AccessToken, user *user_model.User) { - req := NewRequestf(t, "DELETE", "/api/v1/users/user1/tokens/%d", accessToken.ID) + req := NewRequestf(t, "DELETE", "/api/v1/users/"+user.LoginName+"/tokens/%d", accessToken.ID) req = AddBasicAuthHeader(req, user.Name) MakeRequest(t, req, http.StatusNoContent)