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:
parent
9fd63aaad1
commit
254a82842a
12 changed files with 666 additions and 1 deletions
|
@ -380,3 +380,9 @@ type NewIssuePinsAllowed struct {
|
||||||
Issues bool `json:"issues"`
|
Issues bool `json:"issues"`
|
||||||
PullRequests bool `json:"pull_requests"`
|
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
|
// unique: true
|
||||||
NewName string `json:"new_username" binding:"Required"`
|
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).
|
Patch(bind(api.EditHookOption{}), user.EditHook).
|
||||||
Delete(user.DeleteHook)
|
Delete(user.DeleteHook)
|
||||||
}, reqWebhooksEnabled())
|
}, reqWebhooksEnabled())
|
||||||
|
|
||||||
|
m.Group("/avatar", func() {
|
||||||
|
m.Post("", bind(api.UpdateUserAvatarOption{}), user.UpdateAvatar)
|
||||||
|
m.Delete("", user.DeleteAvatar)
|
||||||
|
}, reqToken())
|
||||||
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser), reqToken())
|
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser), reqToken())
|
||||||
|
|
||||||
// Repositories (requires repo scope, org scope)
|
// Repositories (requires repo scope, org scope)
|
||||||
|
@ -1134,6 +1139,10 @@ func Routes() *web.Route {
|
||||||
m.Get("/languages", reqRepoReader(unit.TypeCode), repo.GetLanguages)
|
m.Get("/languages", reqRepoReader(unit.TypeCode), repo.GetLanguages)
|
||||||
m.Get("/activities/feeds", repo.ListRepoActivityFeeds)
|
m.Get("/activities/feeds", repo.ListRepoActivityFeeds)
|
||||||
m.Get("/new_pin_allowed", repo.AreNewIssuePinsAllowed)
|
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())
|
}, repoAssignment())
|
||||||
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryRepository))
|
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryRepository))
|
||||||
|
|
||||||
|
@ -1314,6 +1323,10 @@ func Routes() *web.Route {
|
||||||
Patch(bind(api.EditHookOption{}), org.EditHook).
|
Patch(bind(api.EditHookOption{}), org.EditHook).
|
||||||
Delete(org.DeleteHook)
|
Delete(org.DeleteHook)
|
||||||
}, reqToken(), reqOrgOwnership(), reqWebhooksEnabled())
|
}, 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)
|
m.Get("/activities/feeds", org.ListOrgActivityFeeds)
|
||||||
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryOrganization), orgAssignment(true))
|
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryOrganization), orgAssignment(true))
|
||||||
m.Group("/teams/{teamid}", func() {
|
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
|
// in:body
|
||||||
CreatePushMirrorOption api.CreatePushMirrorOption
|
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": {
|
"/orgs/{org}/hooks": {
|
||||||
"get": {
|
"get": {
|
||||||
"produces": [
|
"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": {
|
"/repos/{owner}/{repo}/branch_protections": {
|
||||||
"get": {
|
"get": {
|
||||||
"produces": [
|
"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": {
|
"/user/emails": {
|
||||||
"get": {
|
"get": {
|
||||||
"produces": [
|
"produces": [
|
||||||
|
@ -21548,6 +21717,30 @@
|
||||||
},
|
},
|
||||||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
"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": {
|
"User": {
|
||||||
"description": "User represents a user",
|
"description": "User represents a user",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
@ -22837,7 +23030,7 @@
|
||||||
"parameterBodies": {
|
"parameterBodies": {
|
||||||
"description": "parameterBodies",
|
"description": "parameterBodies",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/CreatePushMirrorOption"
|
"$ref": "#/definitions/UpdateRepoAvatarOption"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"redirect": {
|
"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 |
Loading…
Reference in a new issue