0
0
mirror of https://github.com/go-gitea/gitea.git synced 2025-01-20 10:54:32 +01:00

api: respect DISABLE_STARS config option

- add APIGone response type
- re-generate Swagger spec

if stars are disabled:
  - render 404 page on /repo/stars
  - return 410 error on star-related API endpoints and actions
  - return empty value on star model functions (StarRepo, IsStaring, GetStargazers)
This commit is contained in:
HeCorr 2025-01-10 20:01:33 -03:00
parent 5c150ce9b0
commit c49823c2b6
No known key found for this signature in database
GPG Key ID: 9333B03459C34098
6 changed files with 99 additions and 0 deletions

View File

@ -8,6 +8,7 @@ import (
"code.gitea.io/gitea/models/db"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
)
@ -24,7 +25,12 @@ func init() {
}
// StarRepo or unstar repository.
//
// Will do nothing if stars are disabled.
func StarRepo(ctx context.Context, doer *user_model.User, repo *Repository, star bool) error {
if setting.Repository.DisableStars {
return nil
}
ctx, committer, err := db.TxContext(ctx)
if err != nil {
return err
@ -70,13 +76,23 @@ func StarRepo(ctx context.Context, doer *user_model.User, repo *Repository, star
}
// IsStaring checks if user has starred given repository.
//
// Will always return false if stars are disabled.
func IsStaring(ctx context.Context, userID, repoID int64) bool {
if setting.Repository.DisableStars {
return false
}
has, _ := db.GetEngine(ctx).Get(&Star{UID: userID, RepoID: repoID})
return has
}
// GetStargazers returns the users that starred the repo.
//
// Will always return an empty slice if stars are disabled.
func GetStargazers(ctx context.Context, repo *Repository, opts db.ListOptions) ([]*user_model.User, error) {
if setting.Repository.DisableStars {
return make([]*user_model.User, 0), nil
}
sess := db.GetEngine(ctx).Where("star.repo_id = ?", repo.ID).
Join("LEFT", "star", "`user`.id = star.uid")
if opts.Page > 0 {

View File

@ -7,6 +7,7 @@ import (
"net/http"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/utils"
"code.gitea.io/gitea/services/context"
@ -44,6 +45,13 @@ func ListStargazers(ctx *context.APIContext) {
// "$ref": "#/responses/UserList"
// "404":
// "$ref": "#/responses/notFound"
// "410":
// "$ref": "#/responses/gone"
if setting.Repository.DisableStars {
ctx.Error(http.StatusGone, "StarsDisabled", "Stars are disabled.")
return
}
stargazers, err := repo_model.GetStargazers(ctx, ctx.Repo.Repository, utils.GetListOptions(ctx))
if err != nil {

View File

@ -11,6 +11,7 @@ import (
access_model "code.gitea.io/gitea/models/perm/access"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/utils"
"code.gitea.io/gitea/services/context"
@ -66,6 +67,13 @@ func GetStarredRepos(ctx *context.APIContext) {
// "$ref": "#/responses/RepositoryList"
// "404":
// "$ref": "#/responses/notFound"
// "410":
// "$ref": "#/responses/gone"
if setting.Repository.DisableStars {
ctx.Error(http.StatusGone, "StarsDisabled", "Stars are disabled.")
return
}
private := ctx.ContextUser.ID == ctx.Doer.ID
repos, err := getStarredRepos(ctx, ctx.ContextUser, private)
@ -97,6 +105,13 @@ func GetMyStarredRepos(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/RepositoryList"
// "410":
// "$ref": "#/responses/gone"
if setting.Repository.DisableStars {
ctx.Error(http.StatusGone, "StarsDisabled", "Stars are disabled.")
return
}
repos, err := getStarredRepos(ctx, ctx.Doer, true)
if err != nil {
@ -128,6 +143,13 @@ func IsStarring(ctx *context.APIContext) {
// "$ref": "#/responses/empty"
// "404":
// "$ref": "#/responses/notFound"
// "410":
// "$ref": "#/responses/gone"
if setting.Repository.DisableStars {
ctx.Error(http.StatusGone, "StarsDisabled", "Stars are disabled.")
return
}
if repo_model.IsStaring(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID) {
ctx.Status(http.StatusNoContent)
@ -159,6 +181,13 @@ func Star(ctx *context.APIContext) {
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
// "410":
// "$ref": "#/responses/gone"
if setting.Repository.DisableStars {
ctx.Error(http.StatusGone, "StarsDisabled", "Stars are disabled.")
return
}
err := repo_model.StarRepo(ctx, ctx.Doer, ctx.Repo.Repository, true)
if err != nil {
@ -193,6 +222,13 @@ func Unstar(ctx *context.APIContext) {
// "$ref": "#/responses/empty"
// "404":
// "$ref": "#/responses/notFound"
// "410":
// "$ref": "#/responses/gone"
if setting.Repository.DisableStars {
ctx.Error(http.StatusGone, "StarsDisabled", "Stars are disabled.")
return
}
err := repo_model.StarRepo(ctx, ctx.Doer, ctx.Repo.Repository, false)
if err != nil {

View File

@ -346,6 +346,10 @@ func Watchers(ctx *context.Context) {
// Stars render repository's starred users
func Stars(ctx *context.Context) {
if setting.Repository.DisableStars {
ctx.NotFound("Stars disabled", nil)
return
}
ctx.Data["Title"] = ctx.Tr("repo.stargazers")
ctx.Data["CardsTitle"] = ctx.Tr("repo.stargazers")
RenderUserCards(ctx, ctx.Repo.Repository.NumStars, func(opts db.ListOptions) ([]*user_model.User, error) {

View File

@ -89,6 +89,12 @@ type APINotFound struct{}
// swagger:response conflict
type APIConflict struct{}
// APIGone means the functionality has been disabled
// swagger:response gone
type APIGone struct {
APIError
}
// APIRedirect is a redirect response
// swagger:response redirect
type APIRedirect struct{}

View File

@ -13758,6 +13758,9 @@
},
"404": {
"$ref": "#/responses/notFound"
},
"410": {
"$ref": "#/responses/gone"
}
}
}
@ -17494,6 +17497,9 @@
"responses": {
"200": {
"$ref": "#/responses/RepositoryList"
},
"410": {
"$ref": "#/responses/gone"
}
}
}
@ -17527,6 +17533,9 @@
},
"404": {
"$ref": "#/responses/notFound"
},
"410": {
"$ref": "#/responses/gone"
}
}
},
@ -17561,6 +17570,9 @@
},
"404": {
"$ref": "#/responses/notFound"
},
"410": {
"$ref": "#/responses/gone"
}
}
},
@ -17592,6 +17604,9 @@
},
"404": {
"$ref": "#/responses/notFound"
},
"410": {
"$ref": "#/responses/gone"
}
}
}
@ -18268,6 +18283,9 @@
},
"404": {
"$ref": "#/responses/notFound"
},
"410": {
"$ref": "#/responses/gone"
}
}
}
@ -26599,6 +26617,17 @@
}
}
},
"gone": {
"description": "APIGone means the functionality has been disabled",
"headers": {
"message": {
"type": "string"
},
"url": {
"type": "string"
}
}
},
"invalidTopicsError": {
"description": "APIInvalidTopicsError is error format response to invalid topics",
"headers": {