Files
zrok/controller/deleteShareName.go

93 lines
3.5 KiB
Go

package controller
import (
"github.com/go-openapi/runtime/middleware"
"github.com/michaelquigley/df/dl"
"github.com/openziti/zrok/v2/rest_model_zrok"
"github.com/openziti/zrok/v2/rest_server_zrok/operations/share"
)
type deleteShareNameHandler struct{}
func newDeleteShareNameHandler() *deleteShareNameHandler {
return &deleteShareNameHandler{}
}
func (h *deleteShareNameHandler) Handle(params share.DeleteShareNameParams, principal *rest_model_zrok.Principal) middleware.Responder {
trx, err := str.Begin()
if err != nil {
dl.Errorf("error starting transaction: %v", err)
return share.NewDeleteShareNameInternalServerError()
}
defer func() { _ = trx.Rollback() }()
// find namespace
ns, err := str.FindNamespaceWithToken(params.Body.NamespaceToken, trx)
if err != nil {
dl.Errorf("error finding namespace with token '%v': %v", params.Body.NamespaceToken, err)
return share.NewDeleteShareNameNotFound()
}
if !ns.Open {
// check namespace grant
granted, err := str.CheckNamespaceGrant(ns.Id, int(principal.ID), trx)
if err != nil {
dl.Errorf("error checking namespace grant for account '%v' and namespace '%v': %v", principal.Email, ns.Token, err)
return share.NewDeleteShareNameInternalServerError()
}
if !granted {
dl.Errorf("account '%v' is not granted access to namespace '%v'", principal.Email, ns.Token)
return share.NewDeleteShareNameUnauthorized()
}
}
// find allocated name
an, err := str.FindNameByNamespaceAndName(ns.Id, params.Body.Name, trx)
if err != nil {
dl.Errorf("error finding allocated name '%v' in namespace '%v': %v", params.Body.Name, ns.Token, err)
return share.NewDeleteShareNameNotFound()
}
// verify ownership
if an.AccountId != int(principal.ID) {
dl.Errorf("account '%v' does not own name '%v' in namespace '%v'", principal.Email, params.Body.Name, ns.Token)
return share.NewDeleteShareNameUnauthorized()
}
// do not allow deleting names that are still attached to a live share
mappings, err := str.FindShareNameMappingsByNameIdWithShare(an.Id, trx)
if err != nil {
dl.Errorf("error finding share name mappings for name '%v' in namespace '%v': %v", params.Body.Name, ns.Token, err)
return share.NewDeleteShareNameInternalServerError()
}
for _, mapping := range mappings {
if !mapping.ShareDeleted {
msg := rest_model_zrok.ErrorMessage("name '" + params.Body.Name + "' in namespace '" + ns.Token + "' is still attached to share '" + mapping.ShareToken + "'; unshare it before deleting the name")
dl.Errorf("%v", msg)
return share.NewDeleteShareNameConflict().WithPayload(msg)
}
}
// clean up any stale mappings from already deleted shares before deleting the name
for _, mapping := range mappings {
if err := str.DeleteShareNameMapping(mapping.Id, trx); err != nil {
dl.Errorf("error deleting stale share name mapping '%v' for name '%v' in namespace '%v': %v", mapping.Id, params.Body.Name, ns.Token, err)
return share.NewDeleteShareNameInternalServerError()
}
}
// delete allocated name
if err := str.DeleteName(an.Id, trx); err != nil {
dl.Errorf("error deleting allocated name '%v' in namespace '%v' for account '%v': %v", params.Body.Name, ns.Token, principal.Email, err)
return share.NewDeleteShareNameInternalServerError()
}
if err := trx.Commit(); err != nil {
dl.Errorf("error committing transaction: %v", err)
return share.NewDeleteShareNameInternalServerError()
}
dl.Infof("deleted allocated name '%v' in namespace '%v' for account '%v'", params.Body.Name, ns.Token, principal.Email)
return share.NewDeleteShareNameOK()
}