2023-04-24 21:13:15 +03: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 20:09:53 +03:00
zcommon "zotregistry.io/zot/pkg/common"
2023-04-24 21:13:15 +03:00
"zotregistry.io/zot/pkg/log"
2023-07-18 20:27:26 +03:00
mTypes "zotregistry.io/zot/pkg/meta/types"
2023-04-24 21:13:15 +03:00
)
const (
ToggleRepoBookmarkAction = "toggleBookmark"
ToggleRepoStarAction = "toggleStar"
)
2023-05-25 14:46:52 +03:00
func IsBuiltWithUserPrefsExtension ( ) bool {
return true
}
2023-08-02 21:58:34 +03:00
func SetupUserPreferencesRoutes ( conf * config . Config , router * mux . Router ,
metaDB mTypes . MetaDB , log log . Logger ,
2023-04-24 21:13:15 +03:00
) {
2023-08-02 21:58:34 +03:00
if ! conf . AreUserPrefsEnabled ( ) {
log . Info ( ) . Msg ( "skip enabling the user preferences route as the config prerequisites are not met" )
2023-04-24 21:13:15 +03:00
2023-08-02 21:58:34 +03:00
return
}
2023-04-24 21:13:15 +03:00
2023-08-02 21:58:34 +03:00
log . Info ( ) . Msg ( "setting up user preferences routes" )
2023-07-07 19:27:10 +03:00
2023-08-02 21:58:34 +03: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 16:05:14 +03:00
}
2023-08-02 21:58:34 +03:00
// Repo preferences godoc
2023-06-19 20:43:25 +03:00
// @Summary Add bookmarks/stars info
// @Description Add bookmarks/stars info
2023-08-02 21:58:34 +03:00
// @Router /v2/_zot/ext/userprefs [put]
2023-06-19 20:43:25 +03:00
// @Accept json
// @Produce json
2023-08-02 21:58:34 +03: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 19:40:14 +03:00
if ! zcommon . QueryHasParams ( req . URL . Query ( ) , [ ] string { "action" } ) {
2023-04-24 21:13:15 +03:00
rsp . WriteHeader ( http . StatusBadRequest )
return
}
action := req . URL . Query ( ) . Get ( "action" )
switch action {
case ToggleRepoBookmarkAction :
2023-07-18 20:27:26 +03:00
PutBookmark ( rsp , req , metaDB , log ) //nolint:contextcheck
2023-04-24 21:13:15 +03:00
return
case ToggleRepoStarAction :
2023-07-18 20:27:26 +03:00
PutStar ( rsp , req , metaDB , log ) //nolint:contextcheck
2023-04-24 21:13:15 +03:00
return
default :
rsp . WriteHeader ( http . StatusBadRequest )
return
}
2023-08-02 21:58:34 +03:00
} )
2023-04-24 21:13:15 +03:00
}
2023-07-18 20:27:26 +03:00
func PutStar ( rsp http . ResponseWriter , req * http . Request , metaDB mTypes . MetaDB , log log . Logger ) {
2023-07-10 19:40:14 +03:00
if ! zcommon . QueryHasParams ( req . URL . Query ( ) , [ ] string { "repo" } ) {
2023-04-24 21:13:15 +03:00
rsp . WriteHeader ( http . StatusBadRequest )
return
}
repo := req . URL . Query ( ) . Get ( "repo" )
if repo == "" {
rsp . WriteHeader ( http . StatusNotFound )
return
}
2023-07-18 20:27:26 +03:00
_ , err := metaDB . ToggleStarRepo ( req . Context ( ) , repo )
2023-04-24 21:13:15 +03: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 20:27:26 +03:00
func PutBookmark ( rsp http . ResponseWriter , req * http . Request , metaDB mTypes . MetaDB , log log . Logger ) {
2023-07-10 19:40:14 +03:00
if ! zcommon . QueryHasParams ( req . URL . Query ( ) , [ ] string { "repo" } ) {
2023-04-24 21:13:15 +03:00
rsp . WriteHeader ( http . StatusBadRequest )
return
}
repo := req . URL . Query ( ) . Get ( "repo" )
if repo == "" {
rsp . WriteHeader ( http . StatusNotFound )
return
}
2023-07-18 20:27:26 +03:00
_ , err := metaDB . ToggleBookmarkRepo ( req . Context ( ) , repo )
2023-04-24 21:13:15 +03: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 )
}