mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	Fix token endpoints ignore specified account (#27080)
Fix #26234 close #26323 close #27040 --------- Co-authored-by: silverwind <me@silverwind.io>
This commit is contained in:
		@@ -367,6 +367,16 @@ func reqOwner() func(ctx *context.APIContext) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// reqSelfOrAdmin doer should be the same as the contextUser or site admin
 | 
			
		||||
func reqSelfOrAdmin() func(ctx *context.APIContext) {
 | 
			
		||||
	return func(ctx *context.APIContext) {
 | 
			
		||||
		if !ctx.IsUserSiteAdmin() && ctx.ContextUser != ctx.Doer {
 | 
			
		||||
			ctx.Error(http.StatusForbidden, "reqSelfOrAdmin", "doer should be the site admin or be same as the contextUser")
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// reqAdmin user should be an owner or a collaborator with admin write of a repository, or site admin
 | 
			
		||||
func reqAdmin() func(ctx *context.APIContext) {
 | 
			
		||||
	return func(ctx *context.APIContext) {
 | 
			
		||||
@@ -910,7 +920,7 @@ func Routes() *web.Route {
 | 
			
		||||
					m.Combo("").Get(user.ListAccessTokens).
 | 
			
		||||
						Post(bind(api.CreateAccessTokenOption{}), reqToken(), user.CreateAccessToken)
 | 
			
		||||
					m.Combo("/{id}").Delete(reqToken(), user.DeleteAccessToken)
 | 
			
		||||
				}, reqBasicOrRevProxyAuth())
 | 
			
		||||
				}, reqSelfOrAdmin(), reqBasicOrRevProxyAuth())
 | 
			
		||||
 | 
			
		||||
				m.Get("/activities/feeds", user.ListUserActivityFeeds)
 | 
			
		||||
			}, context_service.UserAssignmentAPI())
 | 
			
		||||
 
 | 
			
		||||
@@ -43,8 +43,10 @@ func ListAccessTokens(ctx *context.APIContext) {
 | 
			
		||||
	// responses:
 | 
			
		||||
	//   "200":
 | 
			
		||||
	//     "$ref": "#/responses/AccessTokenList"
 | 
			
		||||
	//   "403":
 | 
			
		||||
	//     "$ref": "#/responses/forbidden"
 | 
			
		||||
 | 
			
		||||
	opts := auth_model.ListAccessTokensOptions{UserID: ctx.Doer.ID, ListOptions: utils.GetListOptions(ctx)}
 | 
			
		||||
	opts := auth_model.ListAccessTokensOptions{UserID: ctx.ContextUser.ID, ListOptions: utils.GetListOptions(ctx)}
 | 
			
		||||
 | 
			
		||||
	count, err := auth_model.CountAccessTokens(ctx, opts)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@@ -95,11 +97,13 @@ func CreateAccessToken(ctx *context.APIContext) {
 | 
			
		||||
	//     "$ref": "#/responses/AccessToken"
 | 
			
		||||
	//   "400":
 | 
			
		||||
	//     "$ref": "#/responses/error"
 | 
			
		||||
	//   "403":
 | 
			
		||||
	//     "$ref": "#/responses/forbidden"
 | 
			
		||||
 | 
			
		||||
	form := web.GetForm(ctx).(*api.CreateAccessTokenOption)
 | 
			
		||||
 | 
			
		||||
	t := &auth_model.AccessToken{
 | 
			
		||||
		UID:  ctx.Doer.ID,
 | 
			
		||||
		UID:  ctx.ContextUser.ID,
 | 
			
		||||
		Name: form.Name,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -153,6 +157,8 @@ func DeleteAccessToken(ctx *context.APIContext) {
 | 
			
		||||
	// responses:
 | 
			
		||||
	//   "204":
 | 
			
		||||
	//     "$ref": "#/responses/empty"
 | 
			
		||||
	//   "403":
 | 
			
		||||
	//     "$ref": "#/responses/forbidden"
 | 
			
		||||
	//   "404":
 | 
			
		||||
	//     "$ref": "#/responses/notFound"
 | 
			
		||||
	//   "422":
 | 
			
		||||
@@ -164,7 +170,7 @@ func DeleteAccessToken(ctx *context.APIContext) {
 | 
			
		||||
	if tokenID == 0 {
 | 
			
		||||
		tokens, err := auth_model.ListAccessTokens(ctx, auth_model.ListAccessTokensOptions{
 | 
			
		||||
			Name:   token,
 | 
			
		||||
			UserID: ctx.Doer.ID,
 | 
			
		||||
			UserID: ctx.ContextUser.ID,
 | 
			
		||||
		})
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			ctx.Error(http.StatusInternalServerError, "ListAccessTokens", err)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								templates/swagger/v1_json.tmpl
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										9
									
								
								templates/swagger/v1_json.tmpl
									
									
									
										generated
									
									
									
								
							@@ -16359,6 +16359,9 @@
 | 
			
		||||
        "responses": {
 | 
			
		||||
          "200": {
 | 
			
		||||
            "$ref": "#/responses/AccessTokenList"
 | 
			
		||||
          },
 | 
			
		||||
          "403": {
 | 
			
		||||
            "$ref": "#/responses/forbidden"
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
@@ -16396,6 +16399,9 @@
 | 
			
		||||
          },
 | 
			
		||||
          "400": {
 | 
			
		||||
            "$ref": "#/responses/error"
 | 
			
		||||
          },
 | 
			
		||||
          "403": {
 | 
			
		||||
            "$ref": "#/responses/forbidden"
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
@@ -16430,6 +16436,9 @@
 | 
			
		||||
          "204": {
 | 
			
		||||
            "$ref": "#/responses/empty"
 | 
			
		||||
          },
 | 
			
		||||
          "403": {
 | 
			
		||||
            "$ref": "#/responses/forbidden"
 | 
			
		||||
          },
 | 
			
		||||
          "404": {
 | 
			
		||||
            "$ref": "#/responses/notFound"
 | 
			
		||||
          },
 | 
			
		||||
 
 | 
			
		||||
@@ -40,6 +40,29 @@ func TestAPIDeleteMissingToken(t *testing.T) {
 | 
			
		||||
	MakeRequest(t, req, http.StatusNotFound)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TestAPIGetTokensPermission ensures that only the admin can get tokens from other users
 | 
			
		||||
func TestAPIGetTokensPermission(t *testing.T) {
 | 
			
		||||
	defer tests.PrepareTestEnv(t)()
 | 
			
		||||
 | 
			
		||||
	// admin can get tokens for other users
 | 
			
		||||
	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
 | 
			
		||||
	req := NewRequestf(t, "GET", "/api/v1/users/user2/tokens")
 | 
			
		||||
	req = AddBasicAuthHeader(req, user.Name)
 | 
			
		||||
	MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
 | 
			
		||||
	// non-admin can get tokens for himself
 | 
			
		||||
	user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
 | 
			
		||||
	req = NewRequestf(t, "GET", "/api/v1/users/user2/tokens")
 | 
			
		||||
	req = AddBasicAuthHeader(req, user.Name)
 | 
			
		||||
	MakeRequest(t, req, http.StatusOK)
 | 
			
		||||
 | 
			
		||||
	// non-admin can't get tokens for other users
 | 
			
		||||
	user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
 | 
			
		||||
	req = NewRequestf(t, "GET", "/api/v1/users/user2/tokens")
 | 
			
		||||
	req = AddBasicAuthHeader(req, user.Name)
 | 
			
		||||
	MakeRequest(t, req, http.StatusForbidden)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type permission struct {
 | 
			
		||||
	category auth_model.AccessTokenScopeCategory
 | 
			
		||||
	level    auth_model.AccessTokenScopeLevel
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user