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)
pull/33208/head
HeCorr 4 weeks ago
parent 5c150ce9b0
commit c49823c2b6
No known key found for this signature in database
GPG Key ID: 9333B03459C34098
  1. 16
      models/repo/star.go
  2. 8
      routers/api/v1/repo/star.go
  3. 36
      routers/api/v1/user/star.go
  4. 4
      routers/web/repo/view.go
  5. 6
      services/context/api.go
  6. 29
      templates/swagger/v1_json.tmpl

@ -8,6 +8,7 @@ import (
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
) )
@ -24,7 +25,12 @@ func init() {
} }
// StarRepo or unstar repository. // 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 { 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) ctx, committer, err := db.TxContext(ctx)
if err != nil { if err != nil {
return err 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. // 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 { 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}) has, _ := db.GetEngine(ctx).Get(&Star{UID: userID, RepoID: repoID})
return has return has
} }
// GetStargazers returns the users that starred the repo. // 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) { 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). sess := db.GetEngine(ctx).Where("star.repo_id = ?", repo.ID).
Join("LEFT", "star", "`user`.id = star.uid") Join("LEFT", "star", "`user`.id = star.uid")
if opts.Page > 0 { if opts.Page > 0 {

@ -7,6 +7,7 @@ import (
"net/http" "net/http"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/utils" "code.gitea.io/gitea/routers/api/v1/utils"
"code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/context"
@ -44,6 +45,13 @@ func ListStargazers(ctx *context.APIContext) {
// "$ref": "#/responses/UserList" // "$ref": "#/responses/UserList"
// "404": // "404":
// "$ref": "#/responses/notFound" // "$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)) stargazers, err := repo_model.GetStargazers(ctx, ctx.Repo.Repository, utils.GetListOptions(ctx))
if err != nil { if err != nil {

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

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

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

@ -13758,6 +13758,9 @@
}, },
"404": { "404": {
"$ref": "#/responses/notFound" "$ref": "#/responses/notFound"
},
"410": {
"$ref": "#/responses/gone"
} }
} }
} }
@ -17494,6 +17497,9 @@
"responses": { "responses": {
"200": { "200": {
"$ref": "#/responses/RepositoryList" "$ref": "#/responses/RepositoryList"
},
"410": {
"$ref": "#/responses/gone"
} }
} }
} }
@ -17527,6 +17533,9 @@
}, },
"404": { "404": {
"$ref": "#/responses/notFound" "$ref": "#/responses/notFound"
},
"410": {
"$ref": "#/responses/gone"
} }
} }
}, },
@ -17561,6 +17570,9 @@
}, },
"404": { "404": {
"$ref": "#/responses/notFound" "$ref": "#/responses/notFound"
},
"410": {
"$ref": "#/responses/gone"
} }
} }
}, },
@ -17592,6 +17604,9 @@
}, },
"404": { "404": {
"$ref": "#/responses/notFound" "$ref": "#/responses/notFound"
},
"410": {
"$ref": "#/responses/gone"
} }
} }
} }
@ -18268,6 +18283,9 @@
}, },
"404": { "404": {
"$ref": "#/responses/notFound" "$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": { "invalidTopicsError": {
"description": "APIInvalidTopicsError is error format response to invalid topics", "description": "APIInvalidTopicsError is error format response to invalid topics",
"headers": { "headers": {

Loading…
Cancel
Save