github.com/artpar/rclone@v1.67.3/cmd/serve/restic/restic_privaterepos_test.go (about)

     1  package restic
     2  
     3  import (
     4  	"context"
     5  	"crypto/rand"
     6  	"io"
     7  	"net/http"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/artpar/rclone/cmd"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  // newAuthenticatedRequest returns a new HTTP request with the given params.
    16  func newAuthenticatedRequest(t testing.TB, method, path string, body io.Reader, user, pass string) *http.Request {
    17  	req := newRequest(t, method, path, body)
    18  	req.SetBasicAuth(user, pass)
    19  	req.Header.Add("Accept", resticAPIV2)
    20  	return req
    21  }
    22  
    23  // TestResticPrivateRepositories runs tests on the restic handler code for private repositories
    24  func TestResticPrivateRepositories(t *testing.T) {
    25  	ctx := context.Background()
    26  	buf := make([]byte, 32)
    27  	_, err := io.ReadFull(rand.Reader, buf)
    28  	require.NoError(t, err)
    29  
    30  	// setup rclone with a local backend in a temporary directory
    31  	tempdir := t.TempDir()
    32  
    33  	opt := newOpt()
    34  
    35  	// set private-repos mode & test user
    36  	opt.PrivateRepos = true
    37  	opt.Auth.BasicUser = "test"
    38  	opt.Auth.BasicPass = "password"
    39  
    40  	// make a new file system in the temp dir
    41  	f := cmd.NewFsSrc([]string{tempdir})
    42  	s, err := newServer(ctx, f, &opt)
    43  	require.NoError(t, err)
    44  	router := s.Server.Router()
    45  
    46  	// Requesting /test/ should allow access
    47  	reqs := []*http.Request{
    48  		newAuthenticatedRequest(t, "POST", "/test/?create=true", nil, opt.Auth.BasicUser, opt.Auth.BasicPass),
    49  		newAuthenticatedRequest(t, "POST", "/test/config", strings.NewReader("foobar test config"), opt.Auth.BasicUser, opt.Auth.BasicPass),
    50  		newAuthenticatedRequest(t, "GET", "/test/config", nil, opt.Auth.BasicUser, opt.Auth.BasicPass),
    51  	}
    52  	for _, req := range reqs {
    53  		checkRequest(t, router.ServeHTTP, req, []wantFunc{wantCode(http.StatusOK)})
    54  	}
    55  
    56  	// Requesting with bad credentials should raise unauthorised errors
    57  	reqs = []*http.Request{
    58  		newRequest(t, "GET", "/test/config", nil),
    59  		newAuthenticatedRequest(t, "GET", "/test/config", nil, opt.Auth.BasicUser, ""),
    60  		newAuthenticatedRequest(t, "GET", "/test/config", nil, "", opt.Auth.BasicPass),
    61  		newAuthenticatedRequest(t, "GET", "/test/config", nil, opt.Auth.BasicUser+"x", opt.Auth.BasicPass),
    62  		newAuthenticatedRequest(t, "GET", "/test/config", nil, opt.Auth.BasicUser, opt.Auth.BasicPass+"x"),
    63  	}
    64  	for _, req := range reqs {
    65  		checkRequest(t, router.ServeHTTP, req, []wantFunc{wantCode(http.StatusUnauthorized)})
    66  	}
    67  
    68  	// Requesting everything else should raise forbidden errors
    69  	reqs = []*http.Request{
    70  		newAuthenticatedRequest(t, "GET", "/", nil, opt.Auth.BasicUser, opt.Auth.BasicPass),
    71  		newAuthenticatedRequest(t, "POST", "/other_user", nil, opt.Auth.BasicUser, opt.Auth.BasicPass),
    72  		newAuthenticatedRequest(t, "GET", "/other_user/config", nil, opt.Auth.BasicUser, opt.Auth.BasicPass),
    73  	}
    74  	for _, req := range reqs {
    75  		checkRequest(t, router.ServeHTTP, req, []wantFunc{wantCode(http.StatusForbidden)})
    76  	}
    77  
    78  }