Skip to content

Commit

Permalink
api: respect DISABLE_STARS config option
Browse files Browse the repository at this point in the history
- 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)
  • Loading branch information
HeCorr committed Jan 10, 2025
1 parent 5c150ce commit c49823c
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 0 deletions.
16 changes: 16 additions & 0 deletions models/repo/star.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand All @@ -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
Expand Down Expand Up @@ -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 {
Expand Down
8 changes: 8 additions & 0 deletions routers/api/v1/repo/star.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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 {
Expand Down
36 changes: 36 additions & 0 deletions routers/api/v1/user/star.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down
4 changes: 4 additions & 0 deletions routers/web/repo/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
6 changes: 6 additions & 0 deletions services/context/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{}
Expand Down
29 changes: 29 additions & 0 deletions templates/swagger/v1_json.tmpl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit c49823c

Please sign in to comment.