219 lines
6.0 KiB
Go
219 lines
6.0 KiB
Go
/*
|
|
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
|
|
*
|
|
* This work is published and licensed under a Creative Commons
|
|
* Attribution-NonCommercial-NoDerivatives 4.0 International License.
|
|
*
|
|
* Distribution of this work is permitted, but commercial use and
|
|
* modifications are strictly prohibited.
|
|
*/
|
|
package handler
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"mstore/app/operator"
|
|
"mstore/app/router"
|
|
"mstore/pkg/terms"
|
|
)
|
|
|
|
func (hand *Handler) ManifestExists(rctx *router.Context) {
|
|
name, _ := rctx.GetSubpath("name")
|
|
reference, _ := rctx.GetSubpath("reference")
|
|
|
|
//hand.DumpHeaders("ManigestExists:\n", rctx)
|
|
|
|
params := &operator.ManifestExistsParams{
|
|
Name: name,
|
|
Reference: reference,
|
|
}
|
|
// Rigth checking
|
|
operatorID, _ := rctx.GetString(userTag)
|
|
opEnable, err := hand.CheckRight(rctx.Ctx, operatorID, terms.RightReadImages, params.Name)
|
|
if err != nil {
|
|
rctx.SetStatus(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
if !opEnable {
|
|
rctx.SetStatus(http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
// Execution of the operation
|
|
ctx := rctx.GetContext()
|
|
res, code, err := hand.oper.ManifestExists(ctx, params)
|
|
if err != nil {
|
|
hand.logg.Errorf("ManifestExist error: %v", err)
|
|
} else if code == http.StatusOK {
|
|
rctx.SetHeader("Content-Length", res.ContentLength)
|
|
rctx.SetHeader("Content-Type", res.ContentType)
|
|
rctx.SetHeader("Docker-Content-Digest", res.DockerContentDigest)
|
|
}
|
|
rctx.SetStatus(code)
|
|
}
|
|
|
|
// PUT /v2/<name>/manifests/<reference> 201 404
|
|
func (hand *Handler) PutManifest(rctx *router.Context) {
|
|
|
|
//hand.DumpHeaders("PutManifest headers", rctx)
|
|
|
|
contentType := rctx.GetHeader("Content-Type")
|
|
contentLength := rctx.GetHeader("Content-Length")
|
|
|
|
name, _ := rctx.GetSubpath("name")
|
|
reference, _ := rctx.GetSubpath("reference")
|
|
|
|
params := &operator.PutManifestParams{
|
|
ContentType: contentType,
|
|
ContentLength: contentLength,
|
|
Name: name,
|
|
Reference: reference,
|
|
Reader: rctx.Request.Body,
|
|
}
|
|
// Rigth checking
|
|
operatorID, _ := rctx.GetString(userTag)
|
|
opEnable, err := hand.CheckRight(rctx.Ctx, operatorID, terms.RightWriteImages, params.Name)
|
|
if err != nil {
|
|
rctx.SetStatus(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
if !opEnable {
|
|
rctx.SetStatus(http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
// Execution of the operation
|
|
ctx := rctx.GetContext()
|
|
res, code, err := hand.oper.PutManifest(ctx, params)
|
|
if err != nil {
|
|
hand.logg.Errorf("PutManifest error: %v", err)
|
|
} else {
|
|
rctx.SetHeader("Location", res.Location)
|
|
}
|
|
rctx.SetStatus(code)
|
|
}
|
|
|
|
// GET /v2/<name>/manifests/<reference> 200 404
|
|
func (hand *Handler) GetManifest(rctx *router.Context) {
|
|
name, _ := rctx.GetSubpath("name")
|
|
reference, _ := rctx.GetSubpath("reference")
|
|
|
|
//hand.DumpHeaders("GetManigest", rctx)
|
|
|
|
params := &operator.GetManifestParams{
|
|
Name: name,
|
|
Reference: reference,
|
|
}
|
|
// Rigth checking
|
|
operatorID, _ := rctx.GetString(userTag)
|
|
opEnable, err := hand.CheckRight(rctx.Ctx, operatorID, terms.RightReadImages, params.Name)
|
|
if err != nil {
|
|
rctx.SetStatus(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
if !opEnable {
|
|
rctx.SetStatus(http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
// Execution of the operation
|
|
ctx := rctx.GetContext()
|
|
res, code, err := hand.oper.GetManifest(ctx, params)
|
|
if err != nil {
|
|
hand.logg.Errorf("GetManifest error: %v", err)
|
|
rctx.SetStatus(code)
|
|
return
|
|
}
|
|
if code == http.StatusOK {
|
|
//hand.logg.Debugf("GetManifest type: %s", res.ContentType)
|
|
//hand.logg.Debugf("GetManifest payload: %s", res.Payload)
|
|
rctx.SetHeader("Content-Length", res.ContentLength)
|
|
//rctx.SetHeader("Content-Type", res.ContentType)
|
|
rctx.SetHeader("Docker-Content-Digest", res.DockerContentDigest)
|
|
rctx.SendBytes(code, res.ContentType, []byte(res.Payload))
|
|
return
|
|
}
|
|
rctx.SetStatus(code)
|
|
}
|
|
|
|
// DELETE /v2/<name>/manifests/<reference> 200 404
|
|
func (hand *Handler) DeleteManifest(rctx *router.Context) {
|
|
name, _ := rctx.GetSubpath("name")
|
|
reference, _ := rctx.GetSubpath("reference")
|
|
|
|
params := &operator.DeleteManifestParams{
|
|
Name: name,
|
|
Reference: reference,
|
|
}
|
|
// Rigth checking
|
|
operatorID, _ := rctx.GetString(userTag)
|
|
opEnable, err := hand.CheckRight(rctx.Ctx, operatorID, terms.RightWriteImages, params.Name)
|
|
if err != nil {
|
|
rctx.SetStatus(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
if !opEnable {
|
|
rctx.SetStatus(http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
// Execution of the operation
|
|
ctx := rctx.GetContext()
|
|
_, code, err := hand.oper.DeleteManifest(ctx, params)
|
|
if err != nil {
|
|
hand.logg.Errorf("DeleteManifest error: %v", err)
|
|
}
|
|
rctx.SetStatus(code)
|
|
}
|
|
|
|
// GET /v2/<name>/referrers/<digest> 200 404/400
|
|
// GET /v2/<name>/referrers/<digest>?artifactType=<artifactType> 200 404/400
|
|
func (hand *Handler) GetReferer(rctx *router.Context) {
|
|
name, _ := rctx.GetSubpath("name")
|
|
digest, _ := rctx.GetSubpath("digest")
|
|
params := &operator.GetRefererParams{
|
|
Name: name,
|
|
Digest: digest,
|
|
}
|
|
// Rigth checking
|
|
operatorID, _ := rctx.GetString(userTag)
|
|
opEnable, err := hand.CheckRight(rctx.Ctx, operatorID, terms.RightReadImages, params.Name)
|
|
if err != nil {
|
|
rctx.SetStatus(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
if !opEnable {
|
|
rctx.SetStatus(http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
// Execution of the operation
|
|
res, code, err := hand.oper.GetReferer(rctx.Ctx, params)
|
|
if err != nil {
|
|
hand.logg.Errorf("GetReferer error: %v", err)
|
|
}
|
|
rctx.SendText(code, res.Reference)
|
|
}
|
|
|
|
// GET /v2/<name>/tags/list 200 404
|
|
// GET /v2/<name>/tags/list?n=<integer>&last=<integer>
|
|
func (hand *Handler) GetTags(rctx *router.Context) {
|
|
name, _ := rctx.GetSubpath("name")
|
|
params := &operator.GetTagsParams{
|
|
Name: name,
|
|
}
|
|
// Rigth checking
|
|
operatorID, _ := rctx.GetString(userTag)
|
|
opEnable, err := hand.CheckRight(rctx.Ctx, operatorID, terms.RightReadImages, params.Name)
|
|
if err != nil {
|
|
rctx.SetStatus(http.StatusInternalServerError)
|
|
return
|
|
}
|
|
if !opEnable {
|
|
rctx.SetStatus(http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
// Execution of the operation
|
|
ctx := rctx.GetContext()
|
|
res, code, err := hand.oper.GetTags(ctx, params)
|
|
if err != nil {
|
|
hand.logg.Errorf("GetTags error: %v", err)
|
|
}
|
|
rctx.SendJSON(code, res.TagDescr)
|
|
}
|