github.com/cs3org/reva/v2@v2.27.7/pkg/storage/utils/eosfs/eosfs_test.go (about)

     1  // Copyright 2018-2021 CERN
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  // In applying this license, CERN does not waive the privileges and immunities
    16  // granted to it by virtue of its status as an Intergovernmental Organization
    17  // or submit itself to any jurisdiction.
    18  
    19  //go:build eos
    20  // +build eos
    21  
    22  package eosfs
    23  
    24  import (
    25  	"context"
    26  	"os/exec"
    27  	"path"
    28  	"reflect"
    29  	"testing"
    30  
    31  	userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
    32  	provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
    33  	ctxpkg "github.com/cs3org/reva/v2/pkg/ctx"
    34  	"github.com/cs3org/reva/v2/pkg/eosclient"
    35  	"github.com/gdexlab/go-render/render"
    36  	"github.com/thanhpk/randstr"
    37  )
    38  
    39  const (
    40  	uid     string = "0"
    41  	gid     string = "0"
    42  	rootDir string = "/eos/homecanary/opstest/testacl/grants"
    43  )
    44  
    45  func createTempDirectory(ctx context.Context, t *testing.T, eos *eosfs, rootDir string) (string, func()) {
    46  	path := path.Join(rootDir, randstr.String(8))
    47  	err := eos.c.CreateDir(ctx, uid, gid, path)
    48  	if err != nil {
    49  		t.Fatalf("error creating temp folder %s: %v", path, err)
    50  	}
    51  	cleanup := func() {
    52  		err := eos.c.Remove(ctx, uid, gid, path)
    53  		if err != nil {
    54  			t.Fatalf("error deleting folder %s: %v", path, err)
    55  		}
    56  	}
    57  	return path, cleanup
    58  }
    59  
    60  func createTempFile(ctx context.Context, t *testing.T, eos *eosfs, dir string) (string, func()) {
    61  	path := path.Join(dir, randstr.String(8))
    62  	err := eos.c.Touch(ctx, uid, gid, path)
    63  	if err != nil {
    64  		t.Fatalf("error creating new file %s: %v", path, err)
    65  	}
    66  	cleanup := func() {
    67  		err := eos.c.Remove(ctx, uid, gid, path)
    68  		if err != nil {
    69  			t.Fatalf("error deleting folder %s: %v", path, err)
    70  		}
    71  	}
    72  	return path, cleanup
    73  }
    74  
    75  // return true if the command exist
    76  func commandExists(path string) bool {
    77  	_, err := exec.LookPath(path)
    78  	return err == nil
    79  }
    80  
    81  func TestAddGrant(t *testing.T) {
    82  
    83  	if !commandExists("/usr/bin/eos") {
    84  		t.Skip("/usr/bin/eos does not exist")
    85  	}
    86  
    87  	fs, err := NewEOSFS(&Config{
    88  		MasterURL:           "root://eoshomecanary.cern.ch",
    89  		UseGRPC:             false,
    90  		ForceSingleUserMode: true,
    91  	})
    92  
    93  	if err != nil {
    94  		t.Fatal("error creating a new EOS client:", err)
    95  	}
    96  
    97  	eos, ok := fs.(*eosfs)
    98  	if !ok {
    99  		t.Fatal("error creating a new EOS client:", err)
   100  	}
   101  
   102  	testCases := []struct {
   103  		description string
   104  		initial     string
   105  		grant       *provider.Grant
   106  		expected    []*provider.Grant
   107  	}{
   108  		{
   109  			description: "all-positive",
   110  			initial:     "u:1:r,u:2:w,u:3:rw",
   111  			grant: &provider.Grant{
   112  				Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "9"}}},
   113  				Permissions: &provider.ResourcePermissions{Stat: true, InitiateFileDownload: true},
   114  			},
   115  			expected: []*provider.Grant{
   116  				{
   117  					Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "9"}}},
   118  					Permissions: &provider.ResourcePermissions{Stat: true, InitiateFileDownload: true},
   119  				},
   120  				{
   121  					Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "1"}}},
   122  					Permissions: &provider.ResourcePermissions{Stat: true, InitiateFileDownload: true},
   123  				},
   124  				{
   125  					Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "2"}}},
   126  					Permissions: &provider.ResourcePermissions{CreateContainer: true, InitiateFileUpload: true, Delete: true, Move: true},
   127  				},
   128  				{
   129  					Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "3"}}},
   130  					Permissions: &provider.ResourcePermissions{Stat: true, InitiateFileDownload: true, CreateContainer: true, InitiateFileUpload: true, Delete: true, Move: true},
   131  				},
   132  			},
   133  		},
   134  		{
   135  			description: "all-negative",
   136  			initial:     "u:1:!r!w!x!m!u!d,u:2:!r!w!x!m!u!d,u:3:!r!w!x!m!u!d",
   137  			grant: &provider.Grant{
   138  				Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "9"}}},
   139  				Permissions: &provider.ResourcePermissions{},
   140  			},
   141  			expected: []*provider.Grant{
   142  				{
   143  					Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "1"}}},
   144  					Permissions: &provider.ResourcePermissions{},
   145  				},
   146  				{
   147  					Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "2"}}},
   148  					Permissions: &provider.ResourcePermissions{},
   149  				},
   150  				{
   151  					Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "3"}}},
   152  					Permissions: &provider.ResourcePermissions{},
   153  				},
   154  				{
   155  					Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "9"}}},
   156  					Permissions: &provider.ResourcePermissions{},
   157  				},
   158  			},
   159  		},
   160  		{
   161  			description: "user-not-in-grant-list-add-positive",
   162  			initial:     "u:1:rw,u:2:r,u:3:!r!w!x!m!u!d",
   163  			grant: &provider.Grant{
   164  				Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "9"}}},
   165  				Permissions: &provider.ResourcePermissions{Stat: true, InitiateFileDownload: true},
   166  			},
   167  			expected: []*provider.Grant{
   168  				{
   169  					Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "9"}}},
   170  					Permissions: &provider.ResourcePermissions{Stat: true, InitiateFileDownload: true},
   171  				},
   172  				{
   173  					Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "1"}}},
   174  					Permissions: &provider.ResourcePermissions{Stat: true, InitiateFileDownload: true, CreateContainer: true, InitiateFileUpload: true, Delete: true, Move: true},
   175  				},
   176  				{
   177  					Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "2"}}},
   178  					Permissions: &provider.ResourcePermissions{Stat: true, InitiateFileDownload: true},
   179  				},
   180  				{
   181  					Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "3"}}},
   182  					Permissions: &provider.ResourcePermissions{},
   183  				},
   184  			},
   185  		},
   186  		{
   187  			description: "user-not-in-grant-list-add-negative",
   188  			initial:     "u:1:rw,u:2:r,u:3:!r!w!x!m!u!d",
   189  			grant: &provider.Grant{
   190  				Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "9"}}},
   191  				Permissions: &provider.ResourcePermissions{},
   192  			},
   193  			expected: []*provider.Grant{
   194  				{
   195  					Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "1"}}},
   196  					Permissions: &provider.ResourcePermissions{Stat: true, InitiateFileDownload: true, CreateContainer: true, InitiateFileUpload: true, Delete: true, Move: true},
   197  				},
   198  				{
   199  					Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "2"}}},
   200  					Permissions: &provider.ResourcePermissions{Stat: true, InitiateFileDownload: true},
   201  				},
   202  				{
   203  					Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "3"}}},
   204  					Permissions: &provider.ResourcePermissions{},
   205  				},
   206  				{
   207  					Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "9"}}},
   208  					Permissions: &provider.ResourcePermissions{},
   209  				},
   210  			},
   211  		},
   212  		{
   213  			description: "user-in-grant-list-add-positive",
   214  			initial:     "u:1:r,u:2:r,u:3:!r!w!x!m!u!d",
   215  			grant: &provider.Grant{
   216  				Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "2"}}},
   217  				Permissions: &provider.ResourcePermissions{Stat: true, InitiateFileDownload: true, CreateContainer: true, InitiateFileUpload: true, Delete: true, Move: true},
   218  			},
   219  			expected: []*provider.Grant{
   220  				{
   221  					Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "1"}}},
   222  					Permissions: &provider.ResourcePermissions{Stat: true, InitiateFileDownload: true},
   223  				},
   224  				{
   225  					Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "2"}}},
   226  					Permissions: &provider.ResourcePermissions{Stat: true, InitiateFileDownload: true, CreateContainer: true, InitiateFileUpload: true, Delete: true, Move: true},
   227  				},
   228  				{
   229  					Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "3"}}},
   230  					Permissions: &provider.ResourcePermissions{},
   231  				},
   232  			},
   233  		},
   234  		{
   235  			description: "user-in-grant-list-add-negative",
   236  			initial:     "u:1:r,u:2:r,u:3:!r!w!x!m!u!d",
   237  			grant: &provider.Grant{
   238  				Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "1"}}},
   239  				Permissions: &provider.ResourcePermissions{},
   240  			},
   241  			expected: []*provider.Grant{
   242  				{
   243  					Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "2"}}},
   244  					Permissions: &provider.ResourcePermissions{Stat: true, InitiateFileDownload: true},
   245  				},
   246  				{
   247  					Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "3"}}},
   248  					Permissions: &provider.ResourcePermissions{},
   249  				},
   250  				{
   251  					Grantee:     &provider.Grantee{Id: &provider.Grantee_UserId{UserId: &userv1beta1.UserId{OpaqueId: "1"}}},
   252  					Permissions: &provider.ResourcePermissions{},
   253  				},
   254  			},
   255  		},
   256  	}
   257  
   258  	for _, test := range testCases {
   259  
   260  		t.Run(test.description, func(t *testing.T) {
   261  			ctx := ctxpkg.ContextSetUser(context.TODO(), &userv1beta1.User{
   262  				UidNumber: 138406,
   263  				GidNumber: 2763,
   264  			})
   265  
   266  			// test grants for a folder
   267  			dir, cleanupDir := createTempDirectory(ctx, t, eos, rootDir)
   268  			defer cleanupDir()
   269  
   270  			// set initial acls
   271  			err := eos.c.SetAttr(ctx, uid, gid, &eosclient.Attribute{Type: SystemAttr, Key: "acl", Val: test.initial}, true, dir)
   272  			if err != nil {
   273  				t.Fatal("error setting initial attributes:", err)
   274  			}
   275  
   276  			dirRef := &provider.Reference{Path: dir}
   277  
   278  			// set new grant
   279  			err = eos.AddGrant(ctx, dirRef, test.grant)
   280  			if err != nil {
   281  				t.Fatal("error adding grant:", err)
   282  			}
   283  
   284  			// check that the new grants list corresponds to expected result
   285  			grants, err := eos.ListGrants(ctx, dirRef)
   286  			if err != nil {
   287  				t.Fatal("error getting grants:", err)
   288  			}
   289  
   290  			if !reflect.DeepEqual(grants, test.expected) {
   291  				t.Fatalf("grants do not correspond in folder %s: got=%v expected=%v", dir, render.AsCode(grants), render.AsCode(test.expected))
   292  			}
   293  
   294  			// test grants for a file
   295  			file, cleanupFile := createTempFile(ctx, t, eos, rootDir)
   296  			defer cleanupFile()
   297  
   298  			// set initial acls
   299  			err = eos.c.SetAttr(ctx, uid, gid, &eosclient.Attribute{Type: UserAttr, Key: "acl", Val: test.initial}, true, dir)
   300  			if err != nil {
   301  				t.Fatal("error setting initial attributes:", err)
   302  			}
   303  
   304  			fileRef := &provider.Reference{Path: file}
   305  
   306  			// set new grant
   307  			err = eos.AddGrant(ctx, fileRef, test.grant)
   308  			if err != nil {
   309  				t.Fatal("error adding grant:", err)
   310  			}
   311  
   312  			// check that the new grants list corresponds to expected result
   313  			grants, err = eos.ListGrants(ctx, fileRef)
   314  			if err != nil {
   315  				t.Fatal("error getting grants:", err)
   316  			}
   317  
   318  			if !reflect.DeepEqual(grants, test.expected) {
   319  				t.Fatalf("grants do not correspond in file %s: got=%v expected=%v", file, render.AsCode(grants), render.AsCode(test.expected))
   320  			}
   321  		})
   322  
   323  	}
   324  
   325  }