diff --git a/apis/backup.go b/apis/backup.go index 2e0401e0..6de91a55 100644 --- a/apis/backup.go +++ b/apis/backup.go @@ -4,7 +4,6 @@ import ( "context" "log" "net/http" - "net/url" "path/filepath" "time" @@ -132,8 +131,7 @@ func (api *backupApi) restore(c echo.Context) error { return NewBadRequestError("Try again later - another backup/restore process has already been started.", nil) } - // @todo remove the extra unescape after https://github.com/labstack/echo/issues/2447 - key, _ := url.PathUnescape(c.PathParam("key")) + key := c.PathParam("key") existsCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() diff --git a/apis/backup_test.go b/apis/backup_test.go index 926547ab..9f4fca05 100644 --- a/apis/backup_test.go +++ b/apis/backup_test.go @@ -300,7 +300,7 @@ func TestBackupsDownload(t *testing.T) { { Name: "with valid admin file token but missing backup name", Method: http.MethodGet, - Url: "/api/backups/mizzing?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsImV4cCI6MTg5MzQ1MjQ2MSwidHlwZSI6ImFkbWluIn0.LyAMpSfaHVsuUqIlqqEbhDQSdFzoPz_EIDcb2VJMBsU", + Url: "/api/backups/missing?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsImV4cCI6MTg5MzQ1MjQ2MSwidHlwZSI6ImFkbWluIn0.LyAMpSfaHVsuUqIlqqEbhDQSdFzoPz_EIDcb2VJMBsU", BeforeTestFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) { if err := createTestBackups(app); err != nil { t.Fatal(err) @@ -325,6 +325,22 @@ func TestBackupsDownload(t *testing.T) { `logs.db`, }, }, + { + Name: "with valid admin file token and backup name with escaped char", + Method: http.MethodGet, + Url: "/api/backups/%40test4.zip?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsImV4cCI6MTg5MzQ1MjQ2MSwidHlwZSI6ImFkbWluIn0.LyAMpSfaHVsuUqIlqqEbhDQSdFzoPz_EIDcb2VJMBsU", + BeforeTestFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) { + if err := createTestBackups(app); err != nil { + t.Fatal(err) + } + }, + ExpectedStatus: 200, + ExpectedContent: []string{ + `storage/`, + `data.db`, + `logs.db`, + }, + }, } for _, scenario := range scenarios { @@ -339,7 +355,7 @@ func TestBackupsDelete(t *testing.T) { t.Fatal(err) } - expected := 3 + expected := 4 if total := len(files); total != expected { t.Fatalf("Expected %d backup(s), got %d", expected, total) } @@ -440,8 +456,8 @@ func TestBackupsDelete(t *testing.T) { t.Fatal(err) } - if total := len(files); total != 2 { - t.Fatalf("Expected 2 backup files, got %d", total) + if total := len(files); total != 3 { + t.Fatalf("Expected %d backup files, got %d", 3, total) } deletedFile := "test1.zip" @@ -454,6 +470,38 @@ func TestBackupsDelete(t *testing.T) { }, ExpectedStatus: 204, }, + { + Name: "authorized as admin (backup with escaped character)", + Method: http.MethodDelete, + Url: "/api/backups/%40test4.zip", + RequestHeaders: map[string]string{ + "Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhZG1pbiIsImV4cCI6MjIwODk4NTI2MX0.M1m--VOqGyv0d23eeUc0r9xE8ZzHaYVmVFw1VZW6gT8", + }, + BeforeTestFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) { + if err := createTestBackups(app); err != nil { + t.Fatal(err) + } + }, + AfterTestFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) { + files, err := getBackupFiles(app) + if err != nil { + t.Fatal(err) + } + + if total := len(files); total != 3 { + t.Fatalf("Expected %d backup files, got %d", 3, total) + } + + deletedFile := "@test4.zip" + + for _, f := range files { + if f.Key == deletedFile { + t.Fatalf("Expected backup %q to be deleted", deletedFile) + } + } + }, + ExpectedStatus: 204, + }, } for _, scenario := range scenarios { @@ -546,6 +594,10 @@ func createTestBackups(app core.App) error { return err } + if err := app.CreateBackup(ctx, "@test4.zip"); err != nil { + return err + } + return nil } diff --git a/go.mod b/go.mod index b0905893..8a3e7829 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.18 require ( github.com/AlecAivazis/survey/v2 v2.3.7 - github.com/aws/aws-sdk-go v1.44.306 + github.com/aws/aws-sdk-go v1.44.307 github.com/disintegration/imaging v1.6.2 github.com/domodwyer/mailyak/v3 v3.6.0 github.com/dop251/goja v0.0.0-20230707174833-636fdf960de1 @@ -15,7 +15,7 @@ require ( github.com/ganigeorgiev/fexpr v0.3.0 github.com/go-ozzo/ozzo-validation/v4 v4.3.0 github.com/golang-jwt/jwt/v4 v4.5.0 - github.com/labstack/echo/v5 v5.0.0-20220201181537-ed2888cfa198 + github.com/labstack/echo/v5 v5.0.0-20230722203903-ec5b858dab61 github.com/mattn/go-sqlite3 v1.14.17 github.com/pocketbase/dbx v1.10.0 github.com/pocketbase/tygoja v0.0.0-20230618203136-2f8d57768be1 diff --git a/go.sum b/go.sum index 09edd0dc..f0693b74 100644 --- a/go.sum +++ b/go.sum @@ -14,6 +14,8 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3d github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go v1.44.306 h1:H487V/1N09BDxeGR7oR+LloC2uUpmf4atmqJaBgQOIs= github.com/aws/aws-sdk-go v1.44.306/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.44.307 h1:2R0/EPgpZcFSUwZhYImq/srjaOrOfLv5MNRzrFyAM38= +github.com/aws/aws-sdk-go v1.44.307/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v1.19.0 h1:klAT+y3pGFBU/qVf1uzwttpBbiuozJYWzNLHioyDJ+k= github.com/aws/aws-sdk-go-v2 v1.19.0/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 h1:dK82zF6kkPeCo8J1e+tGx4JdvDIQzj7ygIoLg8WMuGs= @@ -168,6 +170,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/labstack/echo/v5 v5.0.0-20220201181537-ed2888cfa198 h1:lFz33AOOXwTpqOiHvrN8nmTdkxSfuNLHLPjgQ1muPpU= github.com/labstack/echo/v5 v5.0.0-20220201181537-ed2888cfa198/go.mod h1:uh3YlzsEJj7OG57rDWj6c3WEkOF1ZHGBQkDuUZw3rE8= +github.com/labstack/echo/v5 v5.0.0-20230722203903-ec5b858dab61 h1:FwuzbVh87iLiUQj1+uQUsuw9x5t9m5n5g7rG7o4svW4= +github.com/labstack/echo/v5 v5.0.0-20230722203903-ec5b858dab61/go.mod h1:paQfF1YtHe+GrGg5fOgjsjoCX/UKDr9bc1DoWpZfns8= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= @@ -208,6 +212,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=