diff --git a/account/account.go b/account/account.go index 22df65d..917d62d 100644 --- a/account/account.go +++ b/account/account.go @@ -157,3 +157,30 @@ func (s AccountServiceImpl) DeletePinByHash(hash string, accountID uint) error { return nil } +func (s AccountServiceImpl) PinByHash(hash string, accountID uint) error { + // Define a struct for the query condition + uploadQuery := models.Upload{Hash: hash} + + // Retrieve the upload ID for the given hash + var uploadID uint + result := s.portal.Database(). + Model(&models.Upload{}). + Where(&uploadQuery). + First(&uploadID) + + if result.Error != nil { + return result.Error + } + + // Create a pin with the retrieved upload ID and matching account ID + pinQuery := models.Pin{UploadID: uploadID, UserID: accountID} + result = s.portal.Database(). + Where(&pinQuery). + First(&models.Pin{}) + + if result.Error != nil { + return result.Error + } + + return nil +} diff --git a/api/s5.go b/api/s5.go index 3514133..49ddf09 100644 --- a/api/s5.go +++ b/api/s5.go @@ -41,6 +41,7 @@ func getRoutes(h *s5.HttpHandler, portal interfaces.Portal) map[string]jape.Hand "POST /s5/upload": s5.AuthMiddleware(h.SmallFileUpload, portal), // Pins API + "POST /s5/pin/:cid": s5.AuthMiddleware(h.AccountPin, portal), "DELETE /s5/delete/:cid": s5.AuthMiddleware(h.AccountPinDelete, portal), } } diff --git a/api/s5/http.go b/api/s5/http.go index 0967349..552693d 100644 --- a/api/s5/http.go +++ b/api/s5/http.go @@ -35,6 +35,7 @@ const ( errAccountLogin = "Error logging in account" errFailedToGetPins = "Failed to get pins" errFailedToDelPin = "Failed to delete pin" + errFailedToAddPin = "Failed to add pin" ) var ( @@ -52,6 +53,7 @@ var ( errAccountLoginErr = errors.New(errAccountLogin) errFailedToGetPinsErr = errors.New(errFailedToGetPins) errFailedToDelPinErr = errors.New(errFailedToDelPin) + errFailedToAddPinErr = errors.New(errFailedToAddPin) ) type HttpHandler struct { @@ -643,7 +645,36 @@ func (h *HttpHandler) AccountPinDelete(jc jape.Context) { } jc.ResponseWriter.WriteHeader(http.StatusNoContent) +} +func (h *HttpHandler) AccountPin(jc jape.Context) { + var cid string + if jc.DecodeParam("cid", &cid) != nil { + return + } + + errored := func(err error) { + _ = jc.Error(errFailedToAddPinErr, http.StatusInternalServerError) + h.portal.Logger().Error(errFailedToAddPin, zap.Error(err)) + } + + decodedCid, err := encoding.CIDFromString(cid) + + if err != nil { + errored(err) + return + } + + hash := hex.EncodeToString(decodedCid.Hash.HashBytes()) + + err = h.portal.Accounts().PinByHash(hash, uint(jc.Request.Context().Value(AuthUserIDKey).(uint64))) + + if err != nil { + errored(err) + return + } + + jc.ResponseWriter.WriteHeader(http.StatusNoContent) } func setAuthCookie(jwt string, jc jape.Context) { diff --git a/interfaces/account.go b/interfaces/account.go index 2d18d16..66304f0 100644 --- a/interfaces/account.go +++ b/interfaces/account.go @@ -12,4 +12,5 @@ type AccountService interface { LoginPubkey(pubkey string) (string, error) AccountPins(id uint64, createdAfter uint64) ([]models.Pin, error) DeletePinByHash(hash string, accountID uint) error + PinByHash(hash string, accountID uint) error }