diff --git a/api/v2/api.go b/api/v2/api.go index fd95fa6c7..65f4242fd 100644 --- a/api/v2/api.go +++ b/api/v2/api.go @@ -586,6 +586,7 @@ func (api *API) setupRoutes(debug bool) error { { pin.POST("/:hash", api.pinToHostedIPFSNetwork) pin.GET("/check/:hash/:networkName", api.checkLocalNodeForPinForHostedIPFSNetwork) + pin.DELETE("/remove/:hash", api.removePin) } // file upload routes file := private.Group("/file") diff --git a/api/v2/routes_rtfs.go b/api/v2/routes_rtfs.go index 5823ebe5f..8a4b83351 100644 --- a/api/v2/routes_rtfs.go +++ b/api/v2/routes_rtfs.go @@ -3,6 +3,7 @@ package v2 import ( "bytes" "errors" + "fmt" "html" "io" "io/ioutil" @@ -394,3 +395,22 @@ func (api *API) extendPin(c *gin.Context) { // return Respond(c, http.StatusOK, gin.H{"response": "pin time successfully extended"}) } + +func (api *API) removePin(c *gin.Context) { + username, err := GetAuthenticatedUserFromContext(c) + if err != nil { + api.LogError(c, err, eh.NoAPITokenError)(http.StatusBadRequest) + return + } + // validate hash + hash := c.Param("hash") + if _, err := gocid.Decode(hash); err != nil { + Fail(c, err) + return + } + if err := api.upm.RemovePin(username, hash, "public"); err != nil { + api.LogError(c, err, fmt.Sprint(eh.PinRemovalError+"hash: "+hash))(http.StatusBadRequest) + return + } + Respond(c, http.StatusOK, gin.H{"response": "pin successfuly removed with partial cost refunded"}) +} diff --git a/eh/errors.go b/eh/errors.go index 65dcd9ab2..a53256a95 100644 --- a/eh/errors.go +++ b/eh/errors.go @@ -134,4 +134,6 @@ const ( MaxHoldTimeError = "a hold time of this long would result in a longer maximum pin time than what your account allow, please reduce your hold time and try again" // HostNameNotFoundError is an error message when api server has not hostname HostNameNotFoundError = "an api host has not hostname, please set hostname" + // PinRemovalError is an error message when we failed to remove a pin + PinRemovalError = "failed to remove pin and refund partial cost" )