-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Add image upload/download endpoints with authentication - Create object storage client for file handling - Integrate storage functionality with user system - Update API config and database schema - Add environment variables for storage configuration
- Loading branch information
Showing
13 changed files
with
365 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package api | ||
|
||
import ( | ||
"net/http" | ||
|
||
"github.com/go-chi/chi/v5" | ||
) | ||
|
||
func (a *API) uploadImageWithFormHandler(w http.ResponseWriter, r *http.Request) { | ||
// check if the user is authenticated | ||
// get the user from the request context | ||
user, ok := userFromContext(r.Context()) | ||
if !ok { | ||
ErrUnauthorized.Write(w) | ||
return | ||
} | ||
|
||
// 32 MB is the default used by FormFile() function | ||
if err := r.ParseMultipartForm(32 << 20); err != nil { | ||
ErrGenericInternalServerError.With("could not parse form").Write(w) | ||
return | ||
} | ||
|
||
// Get a reference to the fileHeaders. | ||
// They are accessible only after ParseMultipartForm is called | ||
files := r.MultipartForm.File["file"] | ||
var returnURLs []string | ||
for _, fileHeader := range files { | ||
// Open the file | ||
file, err := fileHeader.Open() | ||
if err != nil { | ||
ErrGenericInternalServerError.Withf("cannot open file %s", err.Error()).Write(w) | ||
break | ||
} | ||
defer func() { | ||
if err := file.Close(); err != nil { | ||
ErrGenericInternalServerError.Withf("cannot close file %s", err.Error()).Write(w) | ||
return | ||
} | ||
}() | ||
// upload the file using the object storage client | ||
// and get the URL of the uploaded file | ||
url, err := a.objectStorage.Put(file, fileHeader.Size, user.Email) | ||
if err != nil { | ||
ErrGenericInternalServerError.Withf("cannot upload file %s", err.Error()).Write(w) | ||
break | ||
} | ||
returnURLs = append(returnURLs, url) | ||
} | ||
httpWriteJSON(w, map[string][]string{"urls": returnURLs}) | ||
} | ||
|
||
func (a *API) downloadImageInlineHandler(w http.ResponseWriter, r *http.Request) { | ||
objectID := chi.URLParam(r, "objectName") | ||
if objectID == "" { | ||
ErrMalformedURLParam.With("objectID is required").Write(w) | ||
return | ||
} | ||
// get the object from the object storage client | ||
object, err := a.objectStorage.Get(objectID) | ||
if err != nil { | ||
ErrGenericInternalServerError.Withf("cannot get object %s", err.Error()).Write(w) | ||
return | ||
} | ||
// write the object to the response | ||
w.Header().Set("Content-Type", object.ContentType) | ||
// w.Header().Set("Content-Length", fmt.Sprintf("%d", len(data))) | ||
w.Header().Set("Content-Disposition", "inline") | ||
if _, err := w.Write(object.Data); err != nil { | ||
ErrGenericInternalServerError.Withf("cannot write object %s", err.Error()).Write(w) | ||
return | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package db | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"time" | ||
|
||
"go.mongodb.org/mongo-driver/bson" | ||
"go.mongodb.org/mongo-driver/mongo" | ||
"go.mongodb.org/mongo-driver/mongo/options" | ||
) | ||
|
||
func (ms *MongoStorage) Object(id string) (*Object, error) { | ||
ms.keysLock.RLock() | ||
defer ms.keysLock.RUnlock() | ||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) | ||
defer cancel() | ||
|
||
// find the object in the database | ||
result := ms.objects.FindOne(ctx, bson.M{"_id": id}) | ||
obj := &Object{} | ||
if err := result.Decode(obj); err != nil { | ||
if err == mongo.ErrNoDocuments { | ||
return nil, ErrNotFound | ||
} | ||
return nil, err | ||
} | ||
return obj, nil | ||
} | ||
|
||
// SetObject sets the object data for the given objectID. If the | ||
// object does not exist, it will be created with the given data, otherwise it | ||
// will be updated. | ||
func (ms *MongoStorage) SetObject(objectID, userID, contentType string, data []byte) error { | ||
object := &Object{ | ||
ID: objectID, | ||
Data: data, | ||
CreatedAt: time.Now(), | ||
UserID: userID, | ||
ContentType: contentType, | ||
} | ||
ms.keysLock.Lock() | ||
defer ms.keysLock.Unlock() | ||
return ms.setObject(object) | ||
} | ||
|
||
// RemoveObject removes the object data for the given objectID. | ||
func (ms *MongoStorage) RemoveObject(objectID string) error { | ||
ms.keysLock.Lock() | ||
defer ms.keysLock.Unlock() | ||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) | ||
defer cancel() | ||
_, err := ms.objects.DeleteOne(ctx, bson.M{"_id": objectID}) | ||
return err | ||
} | ||
|
||
func (ms *MongoStorage) setObject(object *Object) error { | ||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) | ||
defer cancel() | ||
opts := options.ReplaceOptions{} | ||
opts.Upsert = new(bool) | ||
*opts.Upsert = true | ||
_, err := ms.objects.ReplaceOne(ctx, bson.M{"_id": object.ID}, object, &opts) | ||
if err != nil { | ||
return fmt.Errorf("cannot update object: %w", err) | ||
} | ||
return err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
VOCDONI_SERVERURL=http://localhost:8080 | ||
VOCDONI_PORT=8080 | ||
VOCDONI_SECRET=supersecret | ||
VOCDONI_PRIVATEKEY=vochain-private-key | ||
|
@@ -6,5 +7,6 @@ VOCDONI_SMTPUSERNAME=admin | |
VOCDONI_SMTPPASSWORD=password | ||
VOCDONI_EMAILFROMADDRESS=[email protected] | ||
VOCDONI_EMAILFROMADDRESS=[email protected] | ||
STRIPE_API_SECRET=stripe_key | ||
STRIPE_WEBHOOK_SECRET=stripe_webhook_key | ||
VOCDONI_STRIPEAPISECRET=test | ||
VOCDONI_STRIPEWEBHOOKSEC=test | ||
VOCDONI_WEBURL=test |
Oops, something went wrong.