mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-03 20:36:07 +01: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
 | 
					// reqAdmin user should be an owner or a collaborator with admin write of a repository, or site admin
 | 
				
			||||||
func reqAdmin() func(ctx *context.APIContext) {
 | 
					func reqAdmin() func(ctx *context.APIContext) {
 | 
				
			||||||
	return func(ctx *context.APIContext) {
 | 
						return func(ctx *context.APIContext) {
 | 
				
			||||||
@@ -910,7 +920,7 @@ func Routes() *web.Route {
 | 
				
			|||||||
					m.Combo("").Get(user.ListAccessTokens).
 | 
										m.Combo("").Get(user.ListAccessTokens).
 | 
				
			||||||
						Post(bind(api.CreateAccessTokenOption{}), reqToken(), user.CreateAccessToken)
 | 
											Post(bind(api.CreateAccessTokenOption{}), reqToken(), user.CreateAccessToken)
 | 
				
			||||||
					m.Combo("/{id}").Delete(reqToken(), user.DeleteAccessToken)
 | 
										m.Combo("/{id}").Delete(reqToken(), user.DeleteAccessToken)
 | 
				
			||||||
				}, reqBasicOrRevProxyAuth())
 | 
									}, reqSelfOrAdmin(), reqBasicOrRevProxyAuth())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				m.Get("/activities/feeds", user.ListUserActivityFeeds)
 | 
									m.Get("/activities/feeds", user.ListUserActivityFeeds)
 | 
				
			||||||
			}, context_service.UserAssignmentAPI())
 | 
								}, context_service.UserAssignmentAPI())
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,8 +43,10 @@ func ListAccessTokens(ctx *context.APIContext) {
 | 
				
			|||||||
	// responses:
 | 
						// responses:
 | 
				
			||||||
	//   "200":
 | 
						//   "200":
 | 
				
			||||||
	//     "$ref": "#/responses/AccessTokenList"
 | 
						//     "$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)
 | 
						count, err := auth_model.CountAccessTokens(ctx, opts)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -95,11 +97,13 @@ func CreateAccessToken(ctx *context.APIContext) {
 | 
				
			|||||||
	//     "$ref": "#/responses/AccessToken"
 | 
						//     "$ref": "#/responses/AccessToken"
 | 
				
			||||||
	//   "400":
 | 
						//   "400":
 | 
				
			||||||
	//     "$ref": "#/responses/error"
 | 
						//     "$ref": "#/responses/error"
 | 
				
			||||||
 | 
						//   "403":
 | 
				
			||||||
 | 
						//     "$ref": "#/responses/forbidden"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	form := web.GetForm(ctx).(*api.CreateAccessTokenOption)
 | 
						form := web.GetForm(ctx).(*api.CreateAccessTokenOption)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	t := &auth_model.AccessToken{
 | 
						t := &auth_model.AccessToken{
 | 
				
			||||||
		UID:  ctx.Doer.ID,
 | 
							UID:  ctx.ContextUser.ID,
 | 
				
			||||||
		Name: form.Name,
 | 
							Name: form.Name,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -153,6 +157,8 @@ func DeleteAccessToken(ctx *context.APIContext) {
 | 
				
			|||||||
	// responses:
 | 
						// responses:
 | 
				
			||||||
	//   "204":
 | 
						//   "204":
 | 
				
			||||||
	//     "$ref": "#/responses/empty"
 | 
						//     "$ref": "#/responses/empty"
 | 
				
			||||||
 | 
						//   "403":
 | 
				
			||||||
 | 
						//     "$ref": "#/responses/forbidden"
 | 
				
			||||||
	//   "404":
 | 
						//   "404":
 | 
				
			||||||
	//     "$ref": "#/responses/notFound"
 | 
						//     "$ref": "#/responses/notFound"
 | 
				
			||||||
	//   "422":
 | 
						//   "422":
 | 
				
			||||||
@@ -164,7 +170,7 @@ func DeleteAccessToken(ctx *context.APIContext) {
 | 
				
			|||||||
	if tokenID == 0 {
 | 
						if tokenID == 0 {
 | 
				
			||||||
		tokens, err := auth_model.ListAccessTokens(ctx, auth_model.ListAccessTokensOptions{
 | 
							tokens, err := auth_model.ListAccessTokens(ctx, auth_model.ListAccessTokensOptions{
 | 
				
			||||||
			Name:   token,
 | 
								Name:   token,
 | 
				
			||||||
			UserID: ctx.Doer.ID,
 | 
								UserID: ctx.ContextUser.ID,
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			ctx.Error(http.StatusInternalServerError, "ListAccessTokens", err)
 | 
								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": {
 | 
					        "responses": {
 | 
				
			||||||
          "200": {
 | 
					          "200": {
 | 
				
			||||||
            "$ref": "#/responses/AccessTokenList"
 | 
					            "$ref": "#/responses/AccessTokenList"
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          "403": {
 | 
				
			||||||
 | 
					            "$ref": "#/responses/forbidden"
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
@@ -16396,6 +16399,9 @@
 | 
				
			|||||||
          },
 | 
					          },
 | 
				
			||||||
          "400": {
 | 
					          "400": {
 | 
				
			||||||
            "$ref": "#/responses/error"
 | 
					            "$ref": "#/responses/error"
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          "403": {
 | 
				
			||||||
 | 
					            "$ref": "#/responses/forbidden"
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -16430,6 +16436,9 @@
 | 
				
			|||||||
          "204": {
 | 
					          "204": {
 | 
				
			||||||
            "$ref": "#/responses/empty"
 | 
					            "$ref": "#/responses/empty"
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
 | 
					          "403": {
 | 
				
			||||||
 | 
					            "$ref": "#/responses/forbidden"
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
          "404": {
 | 
					          "404": {
 | 
				
			||||||
            "$ref": "#/responses/notFound"
 | 
					            "$ref": "#/responses/notFound"
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,6 +40,29 @@ func TestAPIDeleteMissingToken(t *testing.T) {
 | 
				
			|||||||
	MakeRequest(t, req, http.StatusNotFound)
 | 
						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 {
 | 
					type permission struct {
 | 
				
			||||||
	category auth_model.AccessTokenScopeCategory
 | 
						category auth_model.AccessTokenScopeCategory
 | 
				
			||||||
	level    auth_model.AccessTokenScopeLevel
 | 
						level    auth_model.AccessTokenScopeLevel
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user