mirror of
https://github.com/project-zot/zot.git
synced 2024-12-30 22:34:13 -05:00
9cc990d7ca
Initial code was contributed by Bogdan BIVOLARU <104334+bogdanbiv@users.noreply.github.com> Moved implementation from a separate db to repodb by Andrei Aaron <aaaron@luxoft.com> Not done yet: - run/test dynamodb implementation, only boltdb was tested - add additional coverage for existing functionality - add web-based APIs to toggle the stars/bookmarks on/off Initially graphql mutation was discussed for the missing API but we decided REST endpoints would be better suited for configuration feat(userdb): complete functionality for userdb integration - dynamodb rollback changes to user starred repos in case increasing the total star count fails - dynamodb increment/decrement repostars in repometa when user stars/unstars a repo - dynamodb check anonymous user permissions are working as intendend - common test handle anonymous users - RepoMeta2RepoSummary set IsStarred and IsBookmarked feat(userdb): rest api calls for toggling stars/bookmarks on/off test(userdb): blackbox tests test(userdb): move preferences tests in a different file with specific build tags feat(repodb): add is-starred and is-bookmarked fields to repo-meta - removed duplicated logic for determining if a repo is starred/bookmarked Signed-off-by: Laurentiu Niculae <niculae.laurentiu1@gmail.com> Co-authored-by: Andrei Aaron <aaaron@luxoft.com>
143 lines
3 KiB
Go
143 lines
3 KiB
Go
//go:build userprefs
|
|
// +build userprefs
|
|
|
|
package extensions
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
"net/url"
|
|
|
|
"github.com/gorilla/mux"
|
|
|
|
zerr "zotregistry.io/zot/errors"
|
|
"zotregistry.io/zot/pkg/api/config"
|
|
"zotregistry.io/zot/pkg/api/constants"
|
|
"zotregistry.io/zot/pkg/log"
|
|
"zotregistry.io/zot/pkg/meta/repodb"
|
|
"zotregistry.io/zot/pkg/storage"
|
|
)
|
|
|
|
const (
|
|
ToggleRepoBookmarkAction = "toggleBookmark"
|
|
ToggleRepoStarAction = "toggleStar"
|
|
)
|
|
|
|
func SetupUserPreferencesRoutes(config *config.Config, router *mux.Router, storeController storage.StoreController,
|
|
repoDB repodb.RepoDB, cveInfo CveInfo, log log.Logger,
|
|
) {
|
|
if config.Extensions.Search != nil && *config.Extensions.Search.Enable {
|
|
log.Info().Msg("setting up user preferences routes")
|
|
|
|
userprefsRouter := router.PathPrefix(constants.ExtUserPreferencesPrefix).Subrouter()
|
|
|
|
userprefsRouter.HandleFunc("", HandleUserPrefs(repoDB, log)).Methods(http.MethodPut)
|
|
}
|
|
}
|
|
|
|
func HandleUserPrefs(repoDB repodb.RepoDB, log log.Logger) func(w http.ResponseWriter, r *http.Request) {
|
|
return func(rsp http.ResponseWriter, req *http.Request) {
|
|
if !queryHasParams(req.URL.Query(), []string{"action"}) {
|
|
rsp.WriteHeader(http.StatusBadRequest)
|
|
|
|
return
|
|
}
|
|
|
|
action := req.URL.Query().Get("action")
|
|
|
|
switch action {
|
|
case ToggleRepoBookmarkAction:
|
|
PutBookmark(rsp, req, repoDB, log) //nolint:contextcheck
|
|
|
|
return
|
|
case ToggleRepoStarAction:
|
|
PutStar(rsp, req, repoDB, log) //nolint:contextcheck
|
|
|
|
return
|
|
default:
|
|
rsp.WriteHeader(http.StatusBadRequest)
|
|
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func PutStar(rsp http.ResponseWriter, req *http.Request, repoDB repodb.RepoDB, log log.Logger) {
|
|
if !queryHasParams(req.URL.Query(), []string{"repo"}) {
|
|
rsp.WriteHeader(http.StatusBadRequest)
|
|
|
|
return
|
|
}
|
|
|
|
repo := req.URL.Query().Get("repo")
|
|
|
|
if repo == "" {
|
|
rsp.WriteHeader(http.StatusNotFound)
|
|
|
|
return
|
|
}
|
|
|
|
_, err := repoDB.ToggleStarRepo(req.Context(), repo)
|
|
if err != nil {
|
|
if errors.Is(err, zerr.ErrRepoMetaNotFound) {
|
|
rsp.WriteHeader(http.StatusNotFound)
|
|
|
|
return
|
|
} else if errors.Is(err, zerr.ErrUserDataNotAllowed) {
|
|
rsp.WriteHeader(http.StatusForbidden)
|
|
|
|
return
|
|
}
|
|
|
|
rsp.WriteHeader(http.StatusInternalServerError)
|
|
|
|
return
|
|
}
|
|
|
|
rsp.WriteHeader(http.StatusOK)
|
|
}
|
|
|
|
func PutBookmark(rsp http.ResponseWriter, req *http.Request, repoDB repodb.RepoDB, log log.Logger) {
|
|
if !queryHasParams(req.URL.Query(), []string{"repo"}) {
|
|
rsp.WriteHeader(http.StatusBadRequest)
|
|
|
|
return
|
|
}
|
|
|
|
repo := req.URL.Query().Get("repo")
|
|
|
|
if repo == "" {
|
|
rsp.WriteHeader(http.StatusNotFound)
|
|
|
|
return
|
|
}
|
|
|
|
_, err := repoDB.ToggleBookmarkRepo(req.Context(), repo)
|
|
if err != nil {
|
|
if errors.Is(err, zerr.ErrRepoMetaNotFound) {
|
|
rsp.WriteHeader(http.StatusNotFound)
|
|
|
|
return
|
|
} else if errors.Is(err, zerr.ErrUserDataNotAllowed) {
|
|
rsp.WriteHeader(http.StatusForbidden)
|
|
|
|
return
|
|
}
|
|
|
|
rsp.WriteHeader(http.StatusInternalServerError)
|
|
|
|
return
|
|
}
|
|
|
|
rsp.WriteHeader(http.StatusOK)
|
|
}
|
|
|
|
func queryHasParams(values url.Values, params []string) bool {
|
|
for _, param := range params {
|
|
if !values.Has(param) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|