Merge e4a0e888b5 into 1c3fe4da3c
commit
a700792cb8
@ -0,0 +1,44 @@
|
||||
package inventory
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/ent"
|
||||
entuser "github.com/cloudreve/Cloudreve/v4/ent/user"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory/types"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/boolset"
|
||||
)
|
||||
|
||||
func TestIsValidShareChecksCurrentOwnerAccess(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
status entuser.Status
|
||||
canShare bool
|
||||
wantErr bool
|
||||
}{
|
||||
{name: "active owner with share permission", status: entuser.StatusActive, canShare: true},
|
||||
{name: "active owner without share permission", status: entuser.StatusActive, wantErr: true},
|
||||
{name: "manually banned owner", status: entuser.StatusManualBanned, canShare: true, wantErr: true},
|
||||
{name: "system banned owner", status: entuser.StatusSysBanned, canShare: true, wantErr: true},
|
||||
{name: "inactive owner", status: entuser.StatusInactive, canShare: true, wantErr: true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
permissions := &boolset.BooleanSet{}
|
||||
boolset.Set(types.GroupPermissionShare, tt.canShare, permissions)
|
||||
group := &ent.Group{Permissions: permissions}
|
||||
owner := &ent.User{ID: 1, Status: tt.status}
|
||||
owner.SetGroup(group)
|
||||
file := &ent.File{OwnerID: owner.ID, FileChildren: 1}
|
||||
share := &ent.Share{}
|
||||
share.SetUser(owner)
|
||||
share.SetFile(file)
|
||||
|
||||
err := IsValidShare(share)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Fatalf("IsValidShare() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
package dbfs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/ent"
|
||||
entuser "github.com/cloudreve/Cloudreve/v4/ent/user"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory/types"
|
||||
)
|
||||
|
||||
func TestGetFileFromDirectLinkRejectsRestrictedOwner(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
status entuser.Status
|
||||
batchSize int
|
||||
}{
|
||||
{name: "active owner without direct link permission", status: entuser.StatusActive},
|
||||
{name: "manually banned owner", status: entuser.StatusManualBanned, batchSize: 1},
|
||||
{name: "system banned owner", status: entuser.StatusSysBanned, batchSize: 1},
|
||||
{name: "inactive owner", status: entuser.StatusInactive, batchSize: 1},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
owner := &ent.User{Status: tt.status}
|
||||
owner.SetGroup(&ent.Group{Settings: &types.GroupSetting{SourceBatchSize: tt.batchSize}})
|
||||
file := &ent.File{}
|
||||
file.SetOwner(owner)
|
||||
link := &ent.DirectLink{}
|
||||
link.SetFile(file)
|
||||
|
||||
if _, err := (&DBFS{}).GetFileFromDirectLink(context.Background(), link); err == nil {
|
||||
t.Fatal("GetFileFromDirectLink() error = nil, want restricted owner to be rejected")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,105 @@
|
||||
package dbfs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/ent"
|
||||
entuser "github.com/cloudreve/Cloudreve/v4/ent/user"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory/types"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/boolset"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/fs"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/hashid"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/setting"
|
||||
)
|
||||
|
||||
type restoredStateShareClient struct {
|
||||
inventory.ShareClient
|
||||
share *ent.Share
|
||||
}
|
||||
|
||||
func (c *restoredStateShareClient) GetByHashID(context.Context, string) (*ent.Share, error) {
|
||||
return c.share, nil
|
||||
}
|
||||
|
||||
func TestShareNavigatorRestoredStateRevalidatesRequester(t *testing.T) {
|
||||
ownerPermissions := &boolset.BooleanSet{}
|
||||
boolset.Set(types.GroupPermissionShare, true, ownerPermissions)
|
||||
owner := &ent.User{ID: 1, Status: entuser.StatusActive}
|
||||
owner.SetGroup(&ent.Group{Permissions: ownerPermissions})
|
||||
|
||||
file := &ent.File{OwnerID: owner.ID, FileChildren: 1}
|
||||
share := &ent.Share{ID: 1, Props: &types.ShareProps{ShareView: true}}
|
||||
share.SetUser(owner)
|
||||
share.SetFile(file)
|
||||
|
||||
hasher, err := hashid.New("restored-state-test")
|
||||
if err != nil {
|
||||
t.Fatalf("hashid.New() error = %v", err)
|
||||
}
|
||||
path, err := fs.NewUriFromString(fs.NewShareUri(hashid.EncodeShareID(hasher, share.ID), ""))
|
||||
if err != nil {
|
||||
t.Fatalf("fs.NewUriFromString() error = %v", err)
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
canDownload bool
|
||||
wantErr bool
|
||||
}{
|
||||
{name: "permission revoked", wantErr: true},
|
||||
{name: "permission retained", canDownload: true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
requesterPermissions := &boolset.BooleanSet{}
|
||||
boolset.Set(types.GroupPermissionShareDownload, tt.canDownload, requesterPermissions)
|
||||
requester := &ent.User{ID: 2, Status: entuser.StatusActive}
|
||||
requester.SetGroup(&ent.Group{Permissions: requesterPermissions})
|
||||
|
||||
cachedOwner := &ent.User{ID: owner.ID, Status: entuser.StatusActive}
|
||||
root := newFile(nil, file)
|
||||
t.Cleanup(root.Recycle)
|
||||
root.OwnerModel = cachedOwner
|
||||
root.disableView = true
|
||||
root.CapabilitiesBs = &boolset.BooleanSet{0xff}
|
||||
|
||||
navigator := NewShareNavigator(
|
||||
requester,
|
||||
nil,
|
||||
&restoredStateShareClient{share: share},
|
||||
nil,
|
||||
&setting.DBFS{},
|
||||
hasher,
|
||||
).(*shareNavigator)
|
||||
if err := navigator.RestoreState(shareNavigatorState{
|
||||
ShareRoot: root,
|
||||
OwnerRoot: root,
|
||||
Share: share,
|
||||
Owner: cachedOwner,
|
||||
}); err != nil {
|
||||
t.Fatalf("RestoreState() error = %v", err)
|
||||
}
|
||||
|
||||
_, err := navigator.To(context.Background(), path)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Fatalf("To() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
if tt.wantErr {
|
||||
return
|
||||
}
|
||||
|
||||
if root.OwnerModel != owner {
|
||||
t.Fatal("To() did not refresh the cached owner")
|
||||
}
|
||||
if root.disableView {
|
||||
t.Fatal("To() did not refresh the cached share view setting")
|
||||
}
|
||||
if root.CapabilitiesBs != shareNavigatorCapability {
|
||||
t.Fatal("To() did not refresh the cached navigator capabilities")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue