package restic import ( "context" "crypto/rand" "io" "net/http" "strings" "testing" "github.com/rclone/rclone/cmd" "github.com/stretchr/testify/require" ) // newAuthenticatedRequest returns a new HTTP request with the given params. func newAuthenticatedRequest(t testing.TB, method, path string, body io.Reader, user, pass string) *http.Request { req := newRequest(t, method, path, body) req.SetBasicAuth(user, pass) req.Header.Add("Accept", resticAPIV2) return req } // TestResticPrivateRepositories runs tests on the restic handler code for private repositories func TestResticPrivateRepositories(t *testing.T) { ctx := context.Background() buf := make([]byte, 32) _, err := io.ReadFull(rand.Reader, buf) require.NoError(t, err) // setup rclone with a local backend in a temporary directory tempdir := t.TempDir() opt := newOpt() // set private-repos mode & test user opt.PrivateRepos = true opt.Auth.BasicUser = "test" opt.Auth.BasicPass = "password" // make a new file system in the temp dir f := cmd.NewFsSrc([]string{tempdir}) s, err := newServer(ctx, f, &opt) require.NoError(t, err) router := s.Server.Router() // Requesting /test/ should allow access reqs := []*http.Request{ newAuthenticatedRequest(t, "POST", "/test/?create=true", nil, opt.Auth.BasicUser, opt.Auth.BasicPass), newAuthenticatedRequest(t, "POST", "/test/config", strings.NewReader("foobar test config"), opt.Auth.BasicUser, opt.Auth.BasicPass), newAuthenticatedRequest(t, "GET", "/test/config", nil, opt.Auth.BasicUser, opt.Auth.BasicPass), } for _, req := range reqs { checkRequest(t, router.ServeHTTP, req, []wantFunc{wantCode(http.StatusOK)}) } // Requesting with bad credentials should raise unauthorised errors reqs = []*http.Request{ newRequest(t, "GET", "/test/config", nil), newAuthenticatedRequest(t, "GET", "/test/config", nil, opt.Auth.BasicUser, ""), newAuthenticatedRequest(t, "GET", "/test/config", nil, "", opt.Auth.BasicPass), newAuthenticatedRequest(t, "GET", "/test/config", nil, opt.Auth.BasicUser+"x", opt.Auth.BasicPass), newAuthenticatedRequest(t, "GET", "/test/config", nil, opt.Auth.BasicUser, opt.Auth.BasicPass+"x"), } for _, req := range reqs { checkRequest(t, router.ServeHTTP, req, []wantFunc{wantCode(http.StatusUnauthorized)}) } // Requesting everything else should raise forbidden errors reqs = []*http.Request{ newAuthenticatedRequest(t, "GET", "/", nil, opt.Auth.BasicUser, opt.Auth.BasicPass), newAuthenticatedRequest(t, "POST", "/other_user", nil, opt.Auth.BasicUser, opt.Auth.BasicPass), newAuthenticatedRequest(t, "GET", "/other_user/config", nil, opt.Auth.BasicUser, opt.Auth.BasicPass), } for _, req := range reqs { checkRequest(t, router.ServeHTTP, req, []wantFunc{wantCode(http.StatusForbidden)}) } }