feat/security
All checks were successful
Build and Publish Docker Image / deploy (push) Successful in 1m44s
All checks were successful
Build and Publish Docker Image / deploy (push) Successful in 1m44s
Reviewed-on: #2
This commit was merged in pull request #2.
This commit is contained in:
60
lib/boxstore/cleanup.go
Normal file
60
lib/boxstore/cleanup.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package boxstore
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
type CleanupExpiredResult struct {
|
||||
Scanned int
|
||||
Deleted int
|
||||
Skipped int
|
||||
DeletedIDs []string
|
||||
Warnings []string
|
||||
}
|
||||
|
||||
func CleanupExpiredBoxes() (CleanupExpiredResult, error) {
|
||||
entries, err := os.ReadDir(uploadRoot)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return CleanupExpiredResult{}, nil
|
||||
}
|
||||
return CleanupExpiredResult{}, err
|
||||
}
|
||||
|
||||
result := CleanupExpiredResult{
|
||||
DeletedIDs: make([]string, 0),
|
||||
Warnings: make([]string, 0),
|
||||
}
|
||||
for _, entry := range entries {
|
||||
if !entry.IsDir() {
|
||||
continue
|
||||
}
|
||||
boxID := entry.Name()
|
||||
if !ValidBoxID(boxID) {
|
||||
continue
|
||||
}
|
||||
result.Scanned++
|
||||
|
||||
manifest, err := ReadManifest(boxID)
|
||||
if err != nil {
|
||||
result.Skipped++
|
||||
if !os.IsNotExist(err) {
|
||||
result.Warnings = append(result.Warnings, fmt.Sprintf("%s: %v", boxID, err))
|
||||
}
|
||||
continue
|
||||
}
|
||||
if !IsExpired(manifest) {
|
||||
continue
|
||||
}
|
||||
if err := DeleteBox(boxID); err != nil {
|
||||
result.Skipped++
|
||||
result.Warnings = append(result.Warnings, fmt.Sprintf("%s: %v", boxID, err))
|
||||
continue
|
||||
}
|
||||
result.Deleted++
|
||||
result.DeletedIDs = append(result.DeletedIDs, boxID)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
58
lib/boxstore/cleanup_test.go
Normal file
58
lib/boxstore/cleanup_test.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package boxstore
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"warpbox/lib/models"
|
||||
)
|
||||
|
||||
func TestCleanupExpiredBoxesDeletesOnlyExpiredManifestBoxes(t *testing.T) {
|
||||
root := filepath.Join(t.TempDir(), "uploads")
|
||||
previousRoot := UploadRoot()
|
||||
t.Cleanup(func() { SetUploadRoot(previousRoot) })
|
||||
SetUploadRoot(root)
|
||||
|
||||
expiredID := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
activeID := "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
|
||||
legacyID := "cccccccccccccccccccccccccccccccc"
|
||||
|
||||
if err := os.MkdirAll(BoxPath(expiredID), 0755); err != nil {
|
||||
t.Fatalf("mkdir expired: %v", err)
|
||||
}
|
||||
if err := os.MkdirAll(BoxPath(activeID), 0755); err != nil {
|
||||
t.Fatalf("mkdir active: %v", err)
|
||||
}
|
||||
if err := os.MkdirAll(BoxPath(legacyID), 0755); err != nil {
|
||||
t.Fatalf("mkdir legacy: %v", err)
|
||||
}
|
||||
|
||||
if err := WriteManifest(expiredID, models.BoxManifest{CreatedAt: time.Now().UTC().Add(-2 * time.Hour), ExpiresAt: time.Now().UTC().Add(-time.Minute)}); err != nil {
|
||||
t.Fatalf("write expired manifest: %v", err)
|
||||
}
|
||||
if err := WriteManifest(activeID, models.BoxManifest{CreatedAt: time.Now().UTC(), ExpiresAt: time.Now().UTC().Add(time.Hour)}); err != nil {
|
||||
t.Fatalf("write active manifest: %v", err)
|
||||
}
|
||||
|
||||
result, err := CleanupExpiredBoxes()
|
||||
if err != nil {
|
||||
t.Fatalf("cleanup failed: %v", err)
|
||||
}
|
||||
if result.Deleted != 1 {
|
||||
t.Fatalf("expected 1 deleted box, got %d", result.Deleted)
|
||||
}
|
||||
if len(result.DeletedIDs) != 1 || result.DeletedIDs[0] != expiredID {
|
||||
t.Fatalf("expected deleted id %s, got %#v", expiredID, result.DeletedIDs)
|
||||
}
|
||||
if _, err := os.Stat(BoxPath(expiredID)); !os.IsNotExist(err) {
|
||||
t.Fatalf("expected expired box dir removed, stat err=%v", err)
|
||||
}
|
||||
if _, err := os.Stat(BoxPath(activeID)); err != nil {
|
||||
t.Fatalf("expected active box to remain, stat err=%v", err)
|
||||
}
|
||||
if _, err := os.Stat(BoxPath(legacyID)); err != nil {
|
||||
t.Fatalf("expected legacy box to remain, stat err=%v", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user