github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/web/files/permissions_test.go (about)

     1  package files
     2  
     3  import (
     4  	"net/url"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/cozy/cozy-stack/pkg/config/config"
     9  	"github.com/cozy/cozy-stack/pkg/consts"
    10  	"github.com/cozy/cozy-stack/tests/testutils"
    11  	"github.com/cozy/cozy-stack/web/errors"
    12  	"github.com/cozy/cozy-stack/web/middlewares"
    13  	"github.com/gavv/httpexpect/v2"
    14  	"github.com/labstack/echo/v4"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  func TestPermissions(t *testing.T) {
    19  	if testing.Short() {
    20  		t.Skip("an instance is required for this test: test skipped due to the use of --short flag")
    21  	}
    22  
    23  	config.UseTestFile(t)
    24  	require.NoError(t, loadLocale(), "Could not load default locale translations")
    25  
    26  	testutils.NeedCouchdb(t)
    27  	setup := testutils.NewSetup(t, t.Name())
    28  
    29  	config.GetConfig().Fs.URL = &url.URL{
    30  		Scheme: "file",
    31  		Host:   "localhost",
    32  		Path:   t.TempDir(),
    33  	}
    34  
    35  	testInstance := setup.GetTestInstance()
    36  	client, token := setup.GetTestClient(consts.Files + " " + consts.CertifiedCarbonCopy + " " + consts.CertifiedElectronicSafe)
    37  
    38  	ts := setup.GetTestServer("/files", Routes, func(r *echo.Echo) *echo.Echo {
    39  		secure := middlewares.Secure(&middlewares.SecureConfig{
    40  			CSPDefaultSrc:     []middlewares.CSPSource{middlewares.CSPSrcSelf},
    41  			CSPFrameAncestors: []middlewares.CSPSource{middlewares.CSPSrcNone},
    42  		})
    43  		r.Use(secure)
    44  		return r
    45  	})
    46  	ts.Config.Handler.(*echo.Echo).HTTPErrorHandler = errors.ErrorHandler
    47  	t.Cleanup(ts.Close)
    48  
    49  	t.Run("CreateDirNoToken", func(t *testing.T) {
    50  		e := testutils.CreateTestClient(t, ts.URL)
    51  
    52  		// Missing the "Authorization" header
    53  		e.POST("/files/").
    54  			WithQuery("Name", "foo").
    55  			WithQuery("Type", "directory").
    56  			Expect().Status(401)
    57  	})
    58  
    59  	t.Run("CreateDirBadType", func(t *testing.T) {
    60  		e := testutils.CreateTestClient(t, ts.URL)
    61  
    62  		badtok, _ := testInstance.MakeJWT(consts.AccessTokenAudience, client.ClientID, "io.cozy.events", "", time.Now())
    63  
    64  		e.POST("/files/").
    65  			WithQuery("Name", "foo").
    66  			WithQuery("Type", "directory").
    67  			WithHeader("Authorization", "Bearer "+badtok).
    68  			Expect().Status(403)
    69  	})
    70  
    71  	t.Run("CreateDirWildCard", func(t *testing.T) {
    72  		e := testutils.CreateTestClient(t, ts.URL)
    73  
    74  		wildTok, _ := testInstance.MakeJWT(consts.AccessTokenAudience, client.ClientID, "io.cozy.files.*", "", time.Now())
    75  
    76  		e.POST("/files/").
    77  			WithQuery("Name", "icancreateyou").
    78  			WithQuery("Type", "directory").
    79  			WithHeader("Authorization", "Bearer "+wildTok).
    80  			Expect().Status(201)
    81  	})
    82  
    83  	t.Run("CreateDirLimitedScope", func(t *testing.T) {
    84  		e := testutils.CreateTestClient(t, ts.URL)
    85  
    86  		// Create dir "/permissionholder"
    87  		dirID := e.POST("/files/").
    88  			WithQuery("Name", "permissionholder").
    89  			WithQuery("Type", "directory").
    90  			WithHeader("Authorization", "Bearer "+token).
    91  			Expect().Status(201).
    92  			JSON(httpexpect.ContentOpts{MediaType: "application/vnd.api+json"}).
    93  			Object().Path("$.data.id").String().NotEmpty().Raw()
    94  
    95  		badtok, _ := testInstance.MakeJWT(consts.AccessTokenAudience, client.ClientID, "io.cozy.files:ALL:"+dirID, "", time.Now())
    96  
    97  		// not in authorized dir
    98  		e.POST("/files/").
    99  			WithQuery("Name", "icantcreateyou").
   100  			WithQuery("Type", "directory").
   101  			WithHeader("Authorization", "Bearer "+badtok).
   102  			Expect().Status(403)
   103  
   104  		// in authorized dir
   105  		e.POST("/files/").
   106  			WithQuery("Name", "icantcreateyou").
   107  			WithQuery("Type", "directory").
   108  			WithHeader("Authorization", "Bearer "+token).
   109  			Expect().Status(201)
   110  	})
   111  
   112  	t.Run("CreateDirBadVerb", func(t *testing.T) {
   113  		e := testutils.CreateTestClient(t, ts.URL)
   114  
   115  		badtok, _ := testInstance.MakeJWT(consts.AccessTokenAudience, client.ClientID, "io.cozy.files:GET", "", time.Now())
   116  
   117  		e.POST("/files/").
   118  			WithQuery("Name", "icantcreateyou").
   119  			WithQuery("Type", "directory").
   120  			WithHeader("Authorization", "Bearer "+badtok).
   121  			Expect().Status(403)
   122  	})
   123  }