mirror of
				https://github.com/go-gitea/gitea
				synced 2025-10-31 19:38:23 +00:00 
			
		
		
		
	Add API for changing Avatars (#25369)
This adds an API for uploading and Deleting Avatars for of Users, Repos and Organisations. I'm not sure, if this should also be added to the Admin API. Resolves #25344 --------- Co-authored-by: silverwind <me@silverwind.io> Co-authored-by: Giteabot <teabot@gitea.io>
This commit is contained in:
		| @@ -380,3 +380,9 @@ type NewIssuePinsAllowed struct { | ||||
| 	Issues       bool `json:"issues"` | ||||
| 	PullRequests bool `json:"pull_requests"` | ||||
| } | ||||
|  | ||||
| // UpdateRepoAvatarUserOption options when updating the repo avatar | ||||
| type UpdateRepoAvatarOption struct { | ||||
| 	// image must be base64 encoded | ||||
| 	Image string `json:"image" binding:"Required"` | ||||
| } | ||||
|   | ||||
| @@ -102,3 +102,9 @@ type RenameUserOption struct { | ||||
| 	// unique: true | ||||
| 	NewName string `json:"new_username" binding:"Required"` | ||||
| } | ||||
|  | ||||
| // UpdateUserAvatarUserOption options when updating the user avatar | ||||
| type UpdateUserAvatarOption struct { | ||||
| 	// image must be base64 encoded | ||||
| 	Image string `json:"image" binding:"Required"` | ||||
| } | ||||
|   | ||||
| @@ -899,6 +899,11 @@ func Routes() *web.Route { | ||||
| 					Patch(bind(api.EditHookOption{}), user.EditHook). | ||||
| 					Delete(user.DeleteHook) | ||||
| 			}, reqWebhooksEnabled()) | ||||
|  | ||||
| 			m.Group("/avatar", func() { | ||||
| 				m.Post("", bind(api.UpdateUserAvatarOption{}), user.UpdateAvatar) | ||||
| 				m.Delete("", user.DeleteAvatar) | ||||
| 			}, reqToken()) | ||||
| 		}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser), reqToken()) | ||||
|  | ||||
| 		// Repositories (requires repo scope, org scope) | ||||
| @@ -1134,6 +1139,10 @@ func Routes() *web.Route { | ||||
| 				m.Get("/languages", reqRepoReader(unit.TypeCode), repo.GetLanguages) | ||||
| 				m.Get("/activities/feeds", repo.ListRepoActivityFeeds) | ||||
| 				m.Get("/new_pin_allowed", repo.AreNewIssuePinsAllowed) | ||||
| 				m.Group("/avatar", func() { | ||||
| 					m.Post("", bind(api.UpdateRepoAvatarOption{}), repo.UpdateAvatar) | ||||
| 					m.Delete("", repo.DeleteAvatar) | ||||
| 				}, reqAdmin(), reqToken()) | ||||
| 			}, repoAssignment()) | ||||
| 		}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryRepository)) | ||||
|  | ||||
| @@ -1314,6 +1323,10 @@ func Routes() *web.Route { | ||||
| 					Patch(bind(api.EditHookOption{}), org.EditHook). | ||||
| 					Delete(org.DeleteHook) | ||||
| 			}, reqToken(), reqOrgOwnership(), reqWebhooksEnabled()) | ||||
| 			m.Group("/avatar", func() { | ||||
| 				m.Post("", bind(api.UpdateUserAvatarOption{}), org.UpdateAvatar) | ||||
| 				m.Delete("", org.DeleteAvatar) | ||||
| 			}, reqToken(), reqOrgOwnership()) | ||||
| 			m.Get("/activities/feeds", org.ListOrgActivityFeeds) | ||||
| 		}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryOrganization), orgAssignment(true)) | ||||
| 		m.Group("/teams/{teamid}", func() { | ||||
|   | ||||
							
								
								
									
										74
									
								
								routers/api/v1/org/avatar.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								routers/api/v1/org/avatar.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| // Copyright 2023 The Gitea Authors. All rights reserved. | ||||
| // SPDX-License-Identifier: MIT | ||||
|  | ||||
| package org | ||||
|  | ||||
| import ( | ||||
| 	"encoding/base64" | ||||
| 	"net/http" | ||||
|  | ||||
| 	"code.gitea.io/gitea/modules/context" | ||||
| 	api "code.gitea.io/gitea/modules/structs" | ||||
| 	"code.gitea.io/gitea/modules/web" | ||||
| 	user_service "code.gitea.io/gitea/services/user" | ||||
| ) | ||||
|  | ||||
| // UpdateAvatarupdates the Avatar of an Organisation | ||||
| func UpdateAvatar(ctx *context.APIContext) { | ||||
| 	// swagger:operation POST /orgs/{org}/avatar organization orgUpdateAvatar | ||||
| 	// --- | ||||
| 	// summary: Update Avatar | ||||
| 	// produces: | ||||
| 	// - application/json | ||||
| 	// parameters: | ||||
| 	// - name: org | ||||
| 	//   in: path | ||||
| 	//   description: name of the organization | ||||
| 	//   type: string | ||||
| 	//   required: true | ||||
| 	// - name: body | ||||
| 	//   in: body | ||||
| 	//   schema: | ||||
| 	//     "$ref": "#/definitions/UpdateUserAvatarOption" | ||||
| 	// responses: | ||||
| 	//   "204": | ||||
| 	//     "$ref": "#/responses/empty" | ||||
| 	form := web.GetForm(ctx).(*api.UpdateUserAvatarOption) | ||||
|  | ||||
| 	content, err := base64.StdEncoding.DecodeString(form.Image) | ||||
| 	if err != nil { | ||||
| 		ctx.Error(http.StatusBadRequest, "DecodeImage", err) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	err = user_service.UploadAvatar(ctx.Org.Organization.AsUser(), content) | ||||
| 	if err != nil { | ||||
| 		ctx.Error(http.StatusInternalServerError, "UploadAvatar", err) | ||||
| 	} | ||||
|  | ||||
| 	ctx.Status(http.StatusNoContent) | ||||
| } | ||||
|  | ||||
| // DeleteAvatar deletes the Avatar of an Organisation | ||||
| func DeleteAvatar(ctx *context.APIContext) { | ||||
| 	// swagger:operation DELETE /orgs/{org}/avatar organization orgDeleteAvatar | ||||
| 	// --- | ||||
| 	// summary: Delete Avatar | ||||
| 	// produces: | ||||
| 	// - application/json | ||||
| 	// parameters: | ||||
| 	// - name: org | ||||
| 	//   in: path | ||||
| 	//   description: name of the organization | ||||
| 	//   type: string | ||||
| 	//   required: true | ||||
| 	// responses: | ||||
| 	//   "204": | ||||
| 	//     "$ref": "#/responses/empty" | ||||
| 	err := user_service.DeleteAvatar(ctx.Org.Organization.AsUser()) | ||||
| 	if err != nil { | ||||
| 		ctx.Error(http.StatusInternalServerError, "DeleteAvatar", err) | ||||
| 	} | ||||
|  | ||||
| 	ctx.Status(http.StatusNoContent) | ||||
| } | ||||
							
								
								
									
										84
									
								
								routers/api/v1/repo/avatar.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								routers/api/v1/repo/avatar.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | ||||
| // Copyright 2023 The Gitea Authors. All rights reserved. | ||||
| // SPDX-License-Identifier: MIT | ||||
|  | ||||
| package repo | ||||
|  | ||||
| import ( | ||||
| 	"encoding/base64" | ||||
| 	"net/http" | ||||
|  | ||||
| 	"code.gitea.io/gitea/modules/context" | ||||
| 	api "code.gitea.io/gitea/modules/structs" | ||||
| 	"code.gitea.io/gitea/modules/web" | ||||
| 	repo_service "code.gitea.io/gitea/services/repository" | ||||
| ) | ||||
|  | ||||
| // UpdateVatar updates the Avatar of an Repo | ||||
| func UpdateAvatar(ctx *context.APIContext) { | ||||
| 	// swagger:operation POST /repos/{owner}/{repo}/avatar repository repoUpdateAvatar | ||||
| 	// --- | ||||
| 	// summary: Update avatar | ||||
| 	// produces: | ||||
| 	// - application/json | ||||
| 	// parameters: | ||||
| 	// - name: owner | ||||
| 	//   in: path | ||||
| 	//   description: owner of the repo | ||||
| 	//   type: string | ||||
| 	//   required: true | ||||
| 	// - name: repo | ||||
| 	//   in: path | ||||
| 	//   description: name of the repo | ||||
| 	//   type: string | ||||
| 	//   required: true | ||||
| 	// - name: body | ||||
| 	//   in: body | ||||
| 	//   schema: | ||||
| 	//     "$ref": "#/definitions/UpdateRepoAvatarOption" | ||||
| 	// responses: | ||||
| 	//   "204": | ||||
| 	//     "$ref": "#/responses/empty" | ||||
| 	form := web.GetForm(ctx).(*api.UpdateRepoAvatarOption) | ||||
|  | ||||
| 	content, err := base64.StdEncoding.DecodeString(form.Image) | ||||
| 	if err != nil { | ||||
| 		ctx.Error(http.StatusBadRequest, "DecodeImage", err) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	err = repo_service.UploadAvatar(ctx, ctx.Repo.Repository, content) | ||||
| 	if err != nil { | ||||
| 		ctx.Error(http.StatusInternalServerError, "UploadAvatar", err) | ||||
| 	} | ||||
|  | ||||
| 	ctx.Status(http.StatusNoContent) | ||||
| } | ||||
|  | ||||
| // UpdateAvatar deletes the Avatar of an Repo | ||||
| func DeleteAvatar(ctx *context.APIContext) { | ||||
| 	// swagger:operation DELETE /repos/{owner}/{repo}/avatar repository repoDeleteAvatar | ||||
| 	// --- | ||||
| 	// summary: Delete avatar | ||||
| 	// produces: | ||||
| 	// - application/json | ||||
| 	// parameters: | ||||
| 	// - name: owner | ||||
| 	//   in: path | ||||
| 	//   description: owner of the repo | ||||
| 	//   type: string | ||||
| 	//   required: true | ||||
| 	// - name: repo | ||||
| 	//   in: path | ||||
| 	//   description: name of the repo | ||||
| 	//   type: string | ||||
| 	//   required: true | ||||
| 	// responses: | ||||
| 	//   "204": | ||||
| 	//     "$ref": "#/responses/empty" | ||||
| 	err := repo_service.DeleteAvatar(ctx, ctx.Repo.Repository) | ||||
| 	if err != nil { | ||||
| 		ctx.Error(http.StatusInternalServerError, "DeleteAvatar", err) | ||||
| 	} | ||||
|  | ||||
| 	ctx.Status(http.StatusNoContent) | ||||
| } | ||||
| @@ -181,4 +181,10 @@ type swaggerParameterBodies struct { | ||||
|  | ||||
| 	// in:body | ||||
| 	CreatePushMirrorOption api.CreatePushMirrorOption | ||||
|  | ||||
| 	// in:body | ||||
| 	UpdateUserAvatarOptions api.UpdateUserAvatarOption | ||||
|  | ||||
| 	// in:body | ||||
| 	UpdateRepoAvatarOptions api.UpdateRepoAvatarOption | ||||
| } | ||||
|   | ||||
							
								
								
									
										63
									
								
								routers/api/v1/user/avatar.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								routers/api/v1/user/avatar.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | ||||
| // Copyright 2023 The Gitea Authors. All rights reserved. | ||||
| // SPDX-License-Identifier: MIT | ||||
|  | ||||
| package user | ||||
|  | ||||
| import ( | ||||
| 	"encoding/base64" | ||||
| 	"net/http" | ||||
|  | ||||
| 	"code.gitea.io/gitea/modules/context" | ||||
| 	api "code.gitea.io/gitea/modules/structs" | ||||
| 	"code.gitea.io/gitea/modules/web" | ||||
| 	user_service "code.gitea.io/gitea/services/user" | ||||
| ) | ||||
|  | ||||
| // UpdateAvatar updates the Avatar of an User | ||||
| func UpdateAvatar(ctx *context.APIContext) { | ||||
| 	// swagger:operation POST /user/avatar user userUpdateAvatar | ||||
| 	// --- | ||||
| 	// summary: Update Avatar | ||||
| 	// produces: | ||||
| 	// - application/json | ||||
| 	// parameters: | ||||
| 	// - name: body | ||||
| 	//   in: body | ||||
| 	//   schema: | ||||
| 	//     "$ref": "#/definitions/UpdateUserAvatarOption" | ||||
| 	// responses: | ||||
| 	//   "204": | ||||
| 	//     "$ref": "#/responses/empty" | ||||
| 	form := web.GetForm(ctx).(*api.UpdateUserAvatarOption) | ||||
|  | ||||
| 	content, err := base64.StdEncoding.DecodeString(form.Image) | ||||
| 	if err != nil { | ||||
| 		ctx.Error(http.StatusBadRequest, "DecodeImage", err) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	err = user_service.UploadAvatar(ctx.Doer, content) | ||||
| 	if err != nil { | ||||
| 		ctx.Error(http.StatusInternalServerError, "UploadAvatar", err) | ||||
| 	} | ||||
|  | ||||
| 	ctx.Status(http.StatusNoContent) | ||||
| } | ||||
|  | ||||
| // DeleteAvatar deletes the Avatar of an User | ||||
| func DeleteAvatar(ctx *context.APIContext) { | ||||
| 	// swagger:operation DELETE /user/avatar user userDeleteAvatar | ||||
| 	// --- | ||||
| 	// summary: Delete Avatar | ||||
| 	// produces: | ||||
| 	// - application/json | ||||
| 	// responses: | ||||
| 	//   "204": | ||||
| 	//     "$ref": "#/responses/empty" | ||||
| 	err := user_service.DeleteAvatar(ctx.Doer) | ||||
| 	if err != nil { | ||||
| 		ctx.Error(http.StatusInternalServerError, "DeleteAvatar", err) | ||||
| 	} | ||||
|  | ||||
| 	ctx.Status(http.StatusNoContent) | ||||
| } | ||||
							
								
								
									
										195
									
								
								templates/swagger/v1_json.tmpl
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										195
									
								
								templates/swagger/v1_json.tmpl
									
									
									
										generated
									
									
									
								
							| @@ -1595,6 +1595,63 @@ | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "/orgs/{org}/avatar": { | ||||
|       "post": { | ||||
|         "produces": [ | ||||
|           "application/json" | ||||
|         ], | ||||
|         "tags": [ | ||||
|           "organization" | ||||
|         ], | ||||
|         "summary": "Update Avatar", | ||||
|         "operationId": "orgUpdateAvatar", | ||||
|         "parameters": [ | ||||
|           { | ||||
|             "type": "string", | ||||
|             "description": "name of the organization", | ||||
|             "name": "org", | ||||
|             "in": "path", | ||||
|             "required": true | ||||
|           }, | ||||
|           { | ||||
|             "name": "body", | ||||
|             "in": "body", | ||||
|             "schema": { | ||||
|               "$ref": "#/definitions/UpdateUserAvatarOption" | ||||
|             } | ||||
|           } | ||||
|         ], | ||||
|         "responses": { | ||||
|           "204": { | ||||
|             "$ref": "#/responses/empty" | ||||
|           } | ||||
|         } | ||||
|       }, | ||||
|       "delete": { | ||||
|         "produces": [ | ||||
|           "application/json" | ||||
|         ], | ||||
|         "tags": [ | ||||
|           "organization" | ||||
|         ], | ||||
|         "summary": "Delete Avatar", | ||||
|         "operationId": "orgDeleteAvatar", | ||||
|         "parameters": [ | ||||
|           { | ||||
|             "type": "string", | ||||
|             "description": "name of the organization", | ||||
|             "name": "org", | ||||
|             "in": "path", | ||||
|             "required": true | ||||
|           } | ||||
|         ], | ||||
|         "responses": { | ||||
|           "204": { | ||||
|             "$ref": "#/responses/empty" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "/orgs/{org}/hooks": { | ||||
|       "get": { | ||||
|         "produces": [ | ||||
| @@ -3174,6 +3231,77 @@ | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "/repos/{owner}/{repo}/avatar": { | ||||
|       "post": { | ||||
|         "produces": [ | ||||
|           "application/json" | ||||
|         ], | ||||
|         "tags": [ | ||||
|           "repository" | ||||
|         ], | ||||
|         "summary": "Update avatar", | ||||
|         "operationId": "repoUpdateAvatar", | ||||
|         "parameters": [ | ||||
|           { | ||||
|             "type": "string", | ||||
|             "description": "owner of the repo", | ||||
|             "name": "owner", | ||||
|             "in": "path", | ||||
|             "required": true | ||||
|           }, | ||||
|           { | ||||
|             "type": "string", | ||||
|             "description": "name of the repo", | ||||
|             "name": "repo", | ||||
|             "in": "path", | ||||
|             "required": true | ||||
|           }, | ||||
|           { | ||||
|             "name": "body", | ||||
|             "in": "body", | ||||
|             "schema": { | ||||
|               "$ref": "#/definitions/UpdateRepoAvatarOption" | ||||
|             } | ||||
|           } | ||||
|         ], | ||||
|         "responses": { | ||||
|           "204": { | ||||
|             "$ref": "#/responses/empty" | ||||
|           } | ||||
|         } | ||||
|       }, | ||||
|       "delete": { | ||||
|         "produces": [ | ||||
|           "application/json" | ||||
|         ], | ||||
|         "tags": [ | ||||
|           "repository" | ||||
|         ], | ||||
|         "summary": "Delete avatar", | ||||
|         "operationId": "repoDeleteAvatar", | ||||
|         "parameters": [ | ||||
|           { | ||||
|             "type": "string", | ||||
|             "description": "owner of the repo", | ||||
|             "name": "owner", | ||||
|             "in": "path", | ||||
|             "required": true | ||||
|           }, | ||||
|           { | ||||
|             "type": "string", | ||||
|             "description": "name of the repo", | ||||
|             "name": "repo", | ||||
|             "in": "path", | ||||
|             "required": true | ||||
|           } | ||||
|         ], | ||||
|         "responses": { | ||||
|           "204": { | ||||
|             "$ref": "#/responses/empty" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "/repos/{owner}/{repo}/branch_protections": { | ||||
|       "get": { | ||||
|         "produces": [ | ||||
| @@ -13787,6 +13915,47 @@ | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "/user/avatar": { | ||||
|       "post": { | ||||
|         "produces": [ | ||||
|           "application/json" | ||||
|         ], | ||||
|         "tags": [ | ||||
|           "user" | ||||
|         ], | ||||
|         "summary": "Update Avatar", | ||||
|         "operationId": "userUpdateAvatar", | ||||
|         "parameters": [ | ||||
|           { | ||||
|             "name": "body", | ||||
|             "in": "body", | ||||
|             "schema": { | ||||
|               "$ref": "#/definitions/UpdateUserAvatarOption" | ||||
|             } | ||||
|           } | ||||
|         ], | ||||
|         "responses": { | ||||
|           "204": { | ||||
|             "$ref": "#/responses/empty" | ||||
|           } | ||||
|         } | ||||
|       }, | ||||
|       "delete": { | ||||
|         "produces": [ | ||||
|           "application/json" | ||||
|         ], | ||||
|         "tags": [ | ||||
|           "user" | ||||
|         ], | ||||
|         "summary": "Delete Avatar", | ||||
|         "operationId": "userDeleteAvatar", | ||||
|         "responses": { | ||||
|           "204": { | ||||
|             "$ref": "#/responses/empty" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "/user/emails": { | ||||
|       "get": { | ||||
|         "produces": [ | ||||
| @@ -21548,6 +21717,30 @@ | ||||
|       }, | ||||
|       "x-go-package": "code.gitea.io/gitea/modules/structs" | ||||
|     }, | ||||
|     "UpdateRepoAvatarOption": { | ||||
|       "description": "UpdateRepoAvatarUserOption options when updating the repo avatar", | ||||
|       "type": "object", | ||||
|       "properties": { | ||||
|         "image": { | ||||
|           "description": "image must be base64 encoded", | ||||
|           "type": "string", | ||||
|           "x-go-name": "Image" | ||||
|         } | ||||
|       }, | ||||
|       "x-go-package": "code.gitea.io/gitea/modules/structs" | ||||
|     }, | ||||
|     "UpdateUserAvatarOption": { | ||||
|       "description": "UpdateUserAvatarUserOption options when updating the user avatar", | ||||
|       "type": "object", | ||||
|       "properties": { | ||||
|         "image": { | ||||
|           "description": "image must be base64 encoded", | ||||
|           "type": "string", | ||||
|           "x-go-name": "Image" | ||||
|         } | ||||
|       }, | ||||
|       "x-go-package": "code.gitea.io/gitea/modules/structs" | ||||
|     }, | ||||
|     "User": { | ||||
|       "description": "User represents a user", | ||||
|       "type": "object", | ||||
| @@ -22837,7 +23030,7 @@ | ||||
|     "parameterBodies": { | ||||
|       "description": "parameterBodies", | ||||
|       "schema": { | ||||
|         "$ref": "#/definitions/CreatePushMirrorOption" | ||||
|         "$ref": "#/definitions/UpdateRepoAvatarOption" | ||||
|       } | ||||
|     }, | ||||
|     "redirect": { | ||||
|   | ||||
							
								
								
									
										72
									
								
								tests/integration/api_org_avatar_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								tests/integration/api_org_avatar_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| // Copyright 2023 The Gitea Authors. All rights reserved. | ||||
| // SPDX-License-Identifier: MIT | ||||
|  | ||||
| package integration | ||||
|  | ||||
| import ( | ||||
| 	"encoding/base64" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| 	"testing" | ||||
|  | ||||
| 	auth_model "code.gitea.io/gitea/models/auth" | ||||
| 	api "code.gitea.io/gitea/modules/structs" | ||||
| 	"code.gitea.io/gitea/tests" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestAPIUpdateOrgAvatar(t *testing.T) { | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
|  | ||||
| 	session := loginUser(t, "user1") | ||||
|  | ||||
| 	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization) | ||||
|  | ||||
| 	// Test what happens if you use a valid image | ||||
| 	avatar, err := os.ReadFile("tests/integration/avatar.png") | ||||
| 	assert.NoError(t, err) | ||||
| 	if err != nil { | ||||
| 		assert.FailNow(t, "Unable to open avatar.png") | ||||
| 	} | ||||
|  | ||||
| 	opts := api.UpdateUserAvatarOption{ | ||||
| 		Image: base64.StdEncoding.EncodeToString(avatar), | ||||
| 	} | ||||
|  | ||||
| 	req := NewRequestWithJSON(t, "POST", "/api/v1/orgs/user3/avatar?token="+token, &opts) | ||||
| 	MakeRequest(t, req, http.StatusNoContent) | ||||
|  | ||||
| 	// Test what happens if you don't have a valid Base64 string | ||||
| 	opts = api.UpdateUserAvatarOption{ | ||||
| 		Image: "Invalid", | ||||
| 	} | ||||
|  | ||||
| 	req = NewRequestWithJSON(t, "POST", "/api/v1/orgs/user3/avatar?token="+token, &opts) | ||||
| 	MakeRequest(t, req, http.StatusBadRequest) | ||||
|  | ||||
| 	// Test what happens if you use a file that is not an image | ||||
| 	text, err := os.ReadFile("tests/integration/README.md") | ||||
| 	assert.NoError(t, err) | ||||
| 	if err != nil { | ||||
| 		assert.FailNow(t, "Unable to open README.md") | ||||
| 	} | ||||
|  | ||||
| 	opts = api.UpdateUserAvatarOption{ | ||||
| 		Image: base64.StdEncoding.EncodeToString(text), | ||||
| 	} | ||||
|  | ||||
| 	req = NewRequestWithJSON(t, "POST", "/api/v1/orgs/user3/avatar?token="+token, &opts) | ||||
| 	MakeRequest(t, req, http.StatusInternalServerError) | ||||
| } | ||||
|  | ||||
| func TestAPIDeleteOrgAvatar(t *testing.T) { | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
|  | ||||
| 	session := loginUser(t, "user1") | ||||
|  | ||||
| 	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization) | ||||
|  | ||||
| 	req := NewRequest(t, "DELETE", "/api/v1/orgs/user3/avatar?token="+token) | ||||
| 	MakeRequest(t, req, http.StatusNoContent) | ||||
| } | ||||
							
								
								
									
										76
									
								
								tests/integration/api_repo_avatar_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								tests/integration/api_repo_avatar_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| // Copyright 2018 The Gitea Authors. All rights reserved. | ||||
| // SPDX-License-Identifier: MIT | ||||
|  | ||||
| package integration | ||||
|  | ||||
| import ( | ||||
| 	"encoding/base64" | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| 	"testing" | ||||
|  | ||||
| 	auth_model "code.gitea.io/gitea/models/auth" | ||||
| 	repo_model "code.gitea.io/gitea/models/repo" | ||||
| 	"code.gitea.io/gitea/models/unittest" | ||||
| 	user_model "code.gitea.io/gitea/models/user" | ||||
| 	api "code.gitea.io/gitea/modules/structs" | ||||
| 	"code.gitea.io/gitea/tests" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestAPIUpdateRepoAvatar(t *testing.T) { | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
|  | ||||
| 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) | ||||
| 	user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||
| 	token := getUserToken(t, user2.LowerName, auth_model.AccessTokenScopeWriteRepository) | ||||
|  | ||||
| 	// Test what happens if you use a valid image | ||||
| 	avatar, err := os.ReadFile("tests/integration/avatar.png") | ||||
| 	assert.NoError(t, err) | ||||
| 	if err != nil { | ||||
| 		assert.FailNow(t, "Unable to open avatar.png") | ||||
| 	} | ||||
|  | ||||
| 	opts := api.UpdateRepoAvatarOption{ | ||||
| 		Image: base64.StdEncoding.EncodeToString(avatar), | ||||
| 	} | ||||
|  | ||||
| 	req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/avatar?token=%s", repo.OwnerName, repo.Name, token), &opts) | ||||
| 	MakeRequest(t, req, http.StatusNoContent) | ||||
|  | ||||
| 	// Test what happens if you don't have a valid Base64 string | ||||
| 	opts = api.UpdateRepoAvatarOption{ | ||||
| 		Image: "Invalid", | ||||
| 	} | ||||
|  | ||||
| 	req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/avatar?token=%s", repo.OwnerName, repo.Name, token), &opts) | ||||
| 	MakeRequest(t, req, http.StatusBadRequest) | ||||
|  | ||||
| 	// Test what happens if you use a file that is not an image | ||||
| 	text, err := os.ReadFile("tests/integration/README.md") | ||||
| 	assert.NoError(t, err) | ||||
| 	if err != nil { | ||||
| 		assert.FailNow(t, "Unable to open README.md") | ||||
| 	} | ||||
|  | ||||
| 	opts = api.UpdateRepoAvatarOption{ | ||||
| 		Image: base64.StdEncoding.EncodeToString(text), | ||||
| 	} | ||||
|  | ||||
| 	req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/avatar?token=%s", repo.OwnerName, repo.Name, token), &opts) | ||||
| 	MakeRequest(t, req, http.StatusInternalServerError) | ||||
| } | ||||
|  | ||||
| func TestAPIDeleteRepoAvatar(t *testing.T) { | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
|  | ||||
| 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) | ||||
| 	user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||
| 	token := getUserToken(t, user2.LowerName, auth_model.AccessTokenScopeWriteRepository) | ||||
|  | ||||
| 	req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/avatar?token=%s", repo.OwnerName, repo.Name, token)) | ||||
| 	MakeRequest(t, req, http.StatusNoContent) | ||||
| } | ||||
							
								
								
									
										72
									
								
								tests/integration/api_user_avatar_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								tests/integration/api_user_avatar_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| // Copyright 2023 The Gitea Authors. All rights reserved. | ||||
| // SPDX-License-Identifier: MIT | ||||
|  | ||||
| package integration | ||||
|  | ||||
| import ( | ||||
| 	"encoding/base64" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| 	"testing" | ||||
|  | ||||
| 	auth_model "code.gitea.io/gitea/models/auth" | ||||
| 	api "code.gitea.io/gitea/modules/structs" | ||||
| 	"code.gitea.io/gitea/tests" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestAPIUpdateUserAvatar(t *testing.T) { | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
|  | ||||
| 	normalUsername := "user2" | ||||
| 	session := loginUser(t, normalUsername) | ||||
| 	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser) | ||||
|  | ||||
| 	// Test what happens if you use a valid image | ||||
| 	avatar, err := os.ReadFile("tests/integration/avatar.png") | ||||
| 	assert.NoError(t, err) | ||||
| 	if err != nil { | ||||
| 		assert.FailNow(t, "Unable to open avatar.png") | ||||
| 	} | ||||
|  | ||||
| 	// Test what happens if you don't have a valid Base64 string | ||||
| 	opts := api.UpdateUserAvatarOption{ | ||||
| 		Image: base64.StdEncoding.EncodeToString(avatar), | ||||
| 	} | ||||
|  | ||||
| 	req := NewRequestWithJSON(t, "POST", "/api/v1/user/avatar?token="+token, &opts) | ||||
| 	MakeRequest(t, req, http.StatusNoContent) | ||||
|  | ||||
| 	opts = api.UpdateUserAvatarOption{ | ||||
| 		Image: "Invalid", | ||||
| 	} | ||||
|  | ||||
| 	req = NewRequestWithJSON(t, "POST", "/api/v1/user/avatar?token="+token, &opts) | ||||
| 	MakeRequest(t, req, http.StatusBadRequest) | ||||
|  | ||||
| 	// Test what happens if you use a file that is not an image | ||||
| 	text, err := os.ReadFile("tests/integration/README.md") | ||||
| 	assert.NoError(t, err) | ||||
| 	if err != nil { | ||||
| 		assert.FailNow(t, "Unable to open README.md") | ||||
| 	} | ||||
|  | ||||
| 	opts = api.UpdateUserAvatarOption{ | ||||
| 		Image: base64.StdEncoding.EncodeToString(text), | ||||
| 	} | ||||
|  | ||||
| 	req = NewRequestWithJSON(t, "POST", "/api/v1/user/avatar?token="+token, &opts) | ||||
| 	MakeRequest(t, req, http.StatusInternalServerError) | ||||
| } | ||||
|  | ||||
| func TestAPIDeleteUserAvatar(t *testing.T) { | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
|  | ||||
| 	normalUsername := "user2" | ||||
| 	session := loginUser(t, normalUsername) | ||||
| 	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser) | ||||
|  | ||||
| 	req := NewRequest(t, "DELETE", "/api/v1/user/avatar?token="+token) | ||||
| 	MakeRequest(t, req, http.StatusNoContent) | ||||
| } | ||||
							
								
								
									
										
											BIN
										
									
								
								tests/integration/avatar.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								tests/integration/avatar.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 7.6 KiB | 
		Reference in New Issue
	
	Block a user