2023-04-24 13:13:15 -05:00
|
|
|
//go:build userprefs
|
|
|
|
// +build userprefs
|
|
|
|
|
|
|
|
package extensions
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"net/http"
|
|
|
|
|
|
|
|
"github.com/gorilla/mux"
|
|
|
|
|
|
|
|
zerr "zotregistry.io/zot/errors"
|
|
|
|
"zotregistry.io/zot/pkg/api/config"
|
|
|
|
"zotregistry.io/zot/pkg/api/constants"
|
2023-05-10 12:09:53 -05:00
|
|
|
zcommon "zotregistry.io/zot/pkg/common"
|
2023-04-24 13:13:15 -05:00
|
|
|
"zotregistry.io/zot/pkg/log"
|
2023-07-18 12:27:26 -05:00
|
|
|
mTypes "zotregistry.io/zot/pkg/meta/types"
|
2023-04-24 13:13:15 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
ToggleRepoBookmarkAction = "toggleBookmark"
|
|
|
|
ToggleRepoStarAction = "toggleStar"
|
|
|
|
)
|
|
|
|
|
2023-05-25 06:46:52 -05:00
|
|
|
func IsBuiltWithUserPrefsExtension() bool {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2023-08-02 13:58:34 -05:00
|
|
|
func SetupUserPreferencesRoutes(conf *config.Config, router *mux.Router,
|
|
|
|
metaDB mTypes.MetaDB, log log.Logger,
|
2023-04-24 13:13:15 -05:00
|
|
|
) {
|
2023-08-02 13:58:34 -05:00
|
|
|
if !conf.AreUserPrefsEnabled() {
|
|
|
|
log.Info().Msg("skip enabling the user preferences route as the config prerequisites are not met")
|
2023-04-24 13:13:15 -05:00
|
|
|
|
2023-08-02 13:58:34 -05:00
|
|
|
return
|
|
|
|
}
|
2023-04-24 13:13:15 -05:00
|
|
|
|
2023-08-02 13:58:34 -05:00
|
|
|
log.Info().Msg("setting up user preferences routes")
|
2023-07-07 11:27:10 -05:00
|
|
|
|
2023-08-02 13:58:34 -05:00
|
|
|
allowedMethods := zcommon.AllowedMethods(http.MethodPut)
|
|
|
|
|
|
|
|
userPrefsRouter := router.PathPrefix(constants.ExtUserPrefs).Subrouter()
|
|
|
|
userPrefsRouter.Use(zcommon.CORSHeadersMiddleware(conf.HTTP.AllowOrigin))
|
|
|
|
userPrefsRouter.Use(zcommon.AddExtensionSecurityHeaders())
|
|
|
|
userPrefsRouter.Use(zcommon.ACHeadersMiddleware(conf, allowedMethods...))
|
|
|
|
userPrefsRouter.Methods(allowedMethods...).Handler(HandleUserPrefs(metaDB, log))
|
|
|
|
|
|
|
|
log.Info().Msg("finished setting up user preferences routes")
|
2023-05-11 08:05:14 -05:00
|
|
|
}
|
|
|
|
|
2023-08-02 13:58:34 -05:00
|
|
|
// Repo preferences godoc
|
2023-06-19 12:43:25 -05:00
|
|
|
// @Summary Add bookmarks/stars info
|
|
|
|
// @Description Add bookmarks/stars info
|
2023-08-02 13:58:34 -05:00
|
|
|
// @Router /v2/_zot/ext/userprefs [put]
|
2023-06-19 12:43:25 -05:00
|
|
|
// @Accept json
|
|
|
|
// @Produce json
|
2023-08-02 13:58:34 -05:00
|
|
|
// @Param action query string true "specify action" Enums(toggleBookmark, toggleStar)
|
|
|
|
// @Param repo query string true "repository name"
|
|
|
|
// @Success 200 {string} string "ok"
|
|
|
|
// @Failure 404 {string} string "not found"
|
|
|
|
// @Failure 403 {string} string "forbidden"
|
|
|
|
// @Failure 500 {string} string "internal server error"
|
|
|
|
// @Failure 400 {string} string "bad request".
|
|
|
|
func HandleUserPrefs(metaDB mTypes.MetaDB, log log.Logger) http.Handler {
|
|
|
|
return http.HandlerFunc(func(rsp http.ResponseWriter, req *http.Request) {
|
2023-07-10 11:40:14 -05:00
|
|
|
if !zcommon.QueryHasParams(req.URL.Query(), []string{"action"}) {
|
2023-04-24 13:13:15 -05:00
|
|
|
rsp.WriteHeader(http.StatusBadRequest)
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
action := req.URL.Query().Get("action")
|
|
|
|
|
|
|
|
switch action {
|
|
|
|
case ToggleRepoBookmarkAction:
|
2023-07-18 12:27:26 -05:00
|
|
|
PutBookmark(rsp, req, metaDB, log) //nolint:contextcheck
|
2023-04-24 13:13:15 -05:00
|
|
|
|
|
|
|
return
|
|
|
|
case ToggleRepoStarAction:
|
2023-07-18 12:27:26 -05:00
|
|
|
PutStar(rsp, req, metaDB, log) //nolint:contextcheck
|
2023-04-24 13:13:15 -05:00
|
|
|
|
|
|
|
return
|
|
|
|
default:
|
|
|
|
rsp.WriteHeader(http.StatusBadRequest)
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
2023-08-02 13:58:34 -05:00
|
|
|
})
|
2023-04-24 13:13:15 -05:00
|
|
|
}
|
|
|
|
|
2023-07-18 12:27:26 -05:00
|
|
|
func PutStar(rsp http.ResponseWriter, req *http.Request, metaDB mTypes.MetaDB, log log.Logger) {
|
2023-07-10 11:40:14 -05:00
|
|
|
if !zcommon.QueryHasParams(req.URL.Query(), []string{"repo"}) {
|
2023-04-24 13:13:15 -05:00
|
|
|
rsp.WriteHeader(http.StatusBadRequest)
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
repo := req.URL.Query().Get("repo")
|
|
|
|
|
|
|
|
if repo == "" {
|
|
|
|
rsp.WriteHeader(http.StatusNotFound)
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-07-18 12:27:26 -05:00
|
|
|
_, err := metaDB.ToggleStarRepo(req.Context(), repo)
|
2023-04-24 13:13:15 -05:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2023-07-18 12:27:26 -05:00
|
|
|
func PutBookmark(rsp http.ResponseWriter, req *http.Request, metaDB mTypes.MetaDB, log log.Logger) {
|
2023-07-10 11:40:14 -05:00
|
|
|
if !zcommon.QueryHasParams(req.URL.Query(), []string{"repo"}) {
|
2023-04-24 13:13:15 -05:00
|
|
|
rsp.WriteHeader(http.StatusBadRequest)
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
repo := req.URL.Query().Get("repo")
|
|
|
|
|
|
|
|
if repo == "" {
|
|
|
|
rsp.WriteHeader(http.StatusNotFound)
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-07-18 12:27:26 -05:00
|
|
|
_, err := metaDB.ToggleBookmarkRepo(req.Context(), repo)
|
2023-04-24 13:13:15 -05:00
|
|
|
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)
|
|
|
|
}
|