From 500d2f709ced2ea2284b55db1e475482908ff09f Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Tue, 24 Oct 2023 12:12:15 +0200 Subject: [PATCH 1/3] Add "Repair all" button --- server/api/repo.go | 149 +++++++++++------- server/router/api.go | 1 + web/src/assets/locales/en.json | 6 +- .../admin/settings/AdminReposTab.vue | 17 ++ web/src/lib/api/index.ts | 4 + 5 files changed, 118 insertions(+), 59 deletions(-) diff --git a/server/api/repo.go b/server/api/repo.go index e4ea4322c3..34a4258505 100644 --- a/server/api/repo.go +++ b/server/api/repo.go @@ -401,70 +401,15 @@ func DeleteRepo(c *gin.Context) { // @Summary Repair a repository // @Router /repos/{repo_id}/repair [post] // @Produce plain -// @Success 200 +// @Success 204 // @Tags Repositories // @Param Authorization header string true "Insert your personal access token" default(Bearer ) // @Param repo_id path int true "the repository id" func RepairRepo(c *gin.Context) { - forge := server.Config.Services.Forge - _store := store.FromContext(c) repo := session.Repo(c) - user := session.User(c) - - // creates the jwt token used to verify the repository - t := token.New(token.HookToken, repo.FullName) - sig, err := t.Sign(repo.Hash) - if err != nil { - c.String(http.StatusInternalServerError, err.Error()) - return - } - - // reconstruct the link - host := server.Config.Server.WebhookHost - link := fmt.Sprintf( - "%s/api/hook?access_token=%s", - host, - sig, - ) - - from, err := forge.Repo(c, user, repo.ForgeRemoteID, repo.Owner, repo.Name) - if err != nil { - log.Error().Err(err).Msgf("get repo '%s/%s' from forge", repo.Owner, repo.Name) - c.AbortWithStatus(http.StatusInternalServerError) - return - } + repairRepo(c, repo, true) - if repo.FullName != from.FullName { - // create a redirection - err = _store.CreateRedirection(&model.Redirection{RepoID: repo.ID, FullName: repo.FullName}) - if err != nil { - _ = c.AbortWithError(http.StatusInternalServerError, err) - return - } - } - - repo.Update(from) - if err := _store.UpdateRepo(repo); err != nil { - _ = c.AbortWithError(http.StatusInternalServerError, err) - return - } - repo.Perm.Pull = from.Perm.Pull - repo.Perm.Push = from.Perm.Push - repo.Perm.Admin = from.Perm.Admin - if err := _store.PermUpsert(repo.Perm); err != nil { - _ = c.AbortWithError(http.StatusInternalServerError, err) - return - } - - if err := forge.Deactivate(c, user, repo, host); err != nil { - log.Trace().Err(err).Msgf("deactivate repo '%s' to repair failed", repo.FullName) - } - if err := forge.Activate(c, user, repo, link); err != nil { - c.String(http.StatusInternalServerError, err.Error()) - return - } - - c.Status(http.StatusOK) + c.Status(http.StatusNoContent) } // MoveRepo @@ -575,3 +520,91 @@ func GetAllRepos(c *gin.Context) { c.JSON(http.StatusOK, repos) } + +// RepairAllRepos +// +// @Summary Repair all repositories on the server. Requires admin rights. +// @Router /repos/repair [post] +// @Produce plain +// @Success 204 +// @Tags Repositories +// @Param Authorization header string true "Insert your personal access token" default(Bearer ) +func RepairAllRepos(c *gin.Context) { + _store := store.FromContext(c) + + repos, err := _store.RepoListAll(true, &model.ListOptions{All: true}) + if err != nil { + c.String(http.StatusInternalServerError, "Error fetching repository list. %s", err) + return + } + + for _, r := range repos { + repairRepo(c, r, false) + if c.Writer.Written() { + return + } + } + + c.Status(http.StatusNoContent) +} + +func repairRepo(c *gin.Context, repo *model.Repo, withPerms bool) { + forge := server.Config.Services.Forge + _store := store.FromContext(c) + user := session.User(c) + + // creates the jwt token used to verify the repository + t := token.New(token.HookToken, repo.FullName) + sig, err := t.Sign(repo.Hash) + if err != nil { + c.String(http.StatusInternalServerError, err.Error()) + return + } + + // reconstruct the link + host := server.Config.Server.WebhookHost + link := fmt.Sprintf( + "%s/api/hook?access_token=%s", + host, + sig, + ) + + from, err := forge.Repo(c, user, repo.ForgeRemoteID, repo.Owner, repo.Name) + if err != nil { + log.Error().Err(err).Msgf("get repo '%s/%s' from forge", repo.Owner, repo.Name) + c.AbortWithStatus(http.StatusInternalServerError) + return + } + + if repo.FullName != from.FullName { + // create a redirection + err = _store.CreateRedirection(&model.Redirection{RepoID: repo.ID, FullName: repo.FullName}) + if err != nil { + _ = c.AbortWithError(http.StatusInternalServerError, err) + return + } + } + + repo.Update(from) + if err := _store.UpdateRepo(repo); err != nil { + _ = c.AbortWithError(http.StatusInternalServerError, err) + return + } + if withPerms { + repo.Perm.Pull = from.Perm.Pull + repo.Perm.Push = from.Perm.Push + repo.Perm.Admin = from.Perm.Admin + if err := _store.PermUpsert(repo.Perm); err != nil { + _ = c.AbortWithError(http.StatusInternalServerError, err) + return + } + } + + if err := forge.Deactivate(c, user, repo, host); err != nil { + log.Trace().Err(err).Msgf("deactivate repo '%s' to repair failed", repo.FullName) + } + if err := forge.Activate(c, user, repo, link); err != nil { + c.String(http.StatusInternalServerError, err.Error()) + return + } +} diff --git a/server/router/api.go b/server/router/api.go index dbec95cce4..0a22f9e9c1 100644 --- a/server/router/api.go +++ b/server/router/api.go @@ -73,6 +73,7 @@ func apiRoutes(e *gin.RouterGroup) { repo.GET("/lookup/*repo_full_name", session.SetRepo(), session.SetPerm(), session.MustPull, api.LookupRepo) repo.POST("", session.MustUser(), api.PostRepo) repo.GET("", session.MustAdmin(), api.GetAllRepos) + repo.POST("/repair", session.MustAdmin(), api.RepairAllRepos) repoBase := repo.Group("/:repo_id") { repoBase.Use(session.SetRepo()) diff --git a/web/src/assets/locales/en.json b/web/src/assets/locales/en.json index 03ff4bde08..8ede8d2ee9 100644 --- a/web/src/assets/locales/en.json +++ b/web/src/assets/locales/en.json @@ -440,7 +440,11 @@ "none": "There are no repositories yet.", "view": "View repository", "settings": "Repository settings", - "disabled": "Disabled" + "disabled": "Disabled", + "repair": { + "repair": "Repair all", + "success": "Repositories repaired", + } } } }, diff --git a/web/src/components/admin/settings/AdminReposTab.vue b/web/src/components/admin/settings/AdminReposTab.vue index 757e7ffd39..7aabc0c126 100644 --- a/web/src/components/admin/settings/AdminReposTab.vue +++ b/web/src/components/admin/settings/AdminReposTab.vue @@ -1,5 +1,14 @@