mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-27 06:49:07 +01:00
Require a signed URL to write to the local
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
@@ -20,8 +21,9 @@ const (
|
||||
)
|
||||
|
||||
type local struct {
|
||||
url string
|
||||
dir string
|
||||
url string
|
||||
dir string
|
||||
signer *signer
|
||||
}
|
||||
|
||||
func configureLocalHandlers(mux *http.ServeMux) error {
|
||||
@@ -44,9 +46,15 @@ func configureLocalHandlers(mux *http.ServeMux) error {
|
||||
dir = envDir
|
||||
}
|
||||
|
||||
uploadSigner, err := newSigner()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
l := &local{
|
||||
url: envURL,
|
||||
dir: dir,
|
||||
url: envURL,
|
||||
dir: dir,
|
||||
signer: uploadSigner,
|
||||
}
|
||||
mux.HandleFunc(types.GetURLPath, l.handlerGetUploadURL)
|
||||
mux.HandleFunc(putURLPath+putHandler, l.handlePutRequest)
|
||||
@@ -80,6 +88,7 @@ func (l *local) getUploadURL(objectKey string) (string, error) {
|
||||
return "", fmt.Errorf("failed to parse upload URL: %w", err)
|
||||
}
|
||||
newURL := parsedUploadURL.JoinPath(parsedUploadURL.Path, putURLPath, objectKey)
|
||||
newURL.RawQuery = l.signer.sign(objectKey, time.Now()).Encode()
|
||||
return newURL.String(), nil
|
||||
}
|
||||
|
||||
@@ -91,13 +100,6 @@ func (l *local) handlePutRequest(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxUploadSize)
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
http.Error(w, "request body too large or failed to read", http.StatusRequestEntityTooLarge)
|
||||
return
|
||||
}
|
||||
|
||||
uploadDir := r.PathValue("dir")
|
||||
if uploadDir == "" {
|
||||
http.Error(w, "missing dir path", http.StatusBadRequest)
|
||||
@@ -109,6 +111,19 @@ func (l *local) handlePutRequest(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := l.signer.verify(uploadDir+"/"+uploadFile, r.URL.Query(), time.Now()); err != nil {
|
||||
http.Error(w, "unauthorized", http.StatusUnauthorized)
|
||||
log.Warnf("Rejected upload of %s/%s: %v", uploadDir, uploadFile, err)
|
||||
return
|
||||
}
|
||||
|
||||
r.Body = http.MaxBytesReader(w, r.Body, maxUploadSize)
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
http.Error(w, "request body too large or failed to read", http.StatusRequestEntityTooLarge)
|
||||
return
|
||||
}
|
||||
|
||||
cleanBase := filepath.Clean(l.dir) + string(filepath.Separator)
|
||||
|
||||
dirPath := filepath.Clean(filepath.Join(l.dir, uploadDir))
|
||||
@@ -125,14 +140,14 @@ func (l *local) handlePutRequest(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = os.MkdirAll(dirPath, 0750); err != nil {
|
||||
if err = os.MkdirAll(dirPath, 0o750); err != nil {
|
||||
http.Error(w, "failed to create upload dir", http.StatusInternalServerError)
|
||||
log.Errorf("Failed to create upload dir: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
flags := os.O_WRONLY | os.O_CREATE | os.O_EXCL
|
||||
f, err := os.OpenFile(filePath, flags, 0600)
|
||||
f, err := os.OpenFile(filePath, flags, 0o600)
|
||||
if err != nil {
|
||||
if os.IsExist(err) {
|
||||
http.Error(w, "file already exists", http.StatusConflict)
|
||||
|
||||
Reference in New Issue
Block a user