Skip to content

Commit

Permalink
Fix permissions for Token DELETE endpoint to match GET and POST (#27610
Browse files Browse the repository at this point in the history
…) (#28099)

Backport #27610 by @evantobin

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

Co-authored-by: Evan Tobin <[email protected]>
  • Loading branch information
GiteaBot and evantobin authored Nov 17, 2023
1 parent 9f63d27 commit 93ede4b
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 3 deletions.
2 changes: 1 addition & 1 deletion routers/api/v1/user/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
31 changes: 29 additions & 2 deletions tests/integration/api_token_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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)

Expand Down

0 comments on commit 93ede4b

Please sign in to comment.