diff --git a/models/repo/star.go b/models/repo/star.go index 4c66855525fa6..6f649a95dacb4 100644 --- a/models/repo/star.go +++ b/models/repo/star.go @@ -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 { diff --git a/routers/api/v1/repo/star.go b/routers/api/v1/repo/star.go index 99676de119c1f..89cfefcad3069 100644 --- a/routers/api/v1/repo/star.go +++ b/routers/api/v1/repo/star.go @@ -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 { diff --git a/routers/api/v1/user/star.go b/routers/api/v1/user/star.go index ad9ed9548d091..848c109fa5f1b 100644 --- a/routers/api/v1/user/star.go +++ b/routers/api/v1/user/star.go @@ -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 { diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index 9fe2b58ebc66d..aec16565a04ad 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -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) { diff --git a/services/context/api.go b/services/context/api.go index 3a3cbe670e4fa..b1612903c6750 100644 --- a/services/context/api.go +++ b/services/context/api.go @@ -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{} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index fb37d45ce8de2..1ea90df1edd18 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -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": {