package drive import ( "bytes" "context" "errors" "io" "path" "strings" "github.com/ultisuite/ulti-backend/internal/filescan" "github.com/ultisuite/ulti-backend/internal/nextcloud" ) func (s *Service) UploadPublicShare(ctx context.Context, token, filePath, password string, body io.Reader, contentType string) error { perms, err := s.GetPublicSharePermissions(ctx, token, password) if err != nil { return err } if !nextcloud.PublicShareCanCreate(perms) && !nextcloud.PublicShareCanUpdate(perms) { return ErrForbidden } reader := body if s.scanner != nil { data, _, err := s.scanner.ScanReader(ctx, filePath, body, -1) if err != nil { if errors.Is(err, filescan.ErrMalicious) { return ErrMalware } return err } reader = bytes.NewReader(data) } if err := mapPublicShareError(s.nc.UploadPublicShare(ctx, token, filePath, password, reader, contentType)); err != nil { return err } s.recordPublicShareAccess(ctx, token) return nil } func (s *Service) CreatePublicShareFolder(ctx context.Context, token, folderPath, password string) error { if err := s.requirePublicSharePerm(ctx, token, password, nextcloud.PublicShareCanCreate); err != nil { return err } return mapPublicShareError(s.nc.CreatePublicShareFolder(ctx, token, folderPath, password)) } func (s *Service) DeletePublicShareItem(ctx context.Context, token, filePath, password string) error { if err := s.requirePublicSharePerm(ctx, token, password, nextcloud.PublicShareCanDelete); err != nil { return err } return mapPublicShareError(s.nc.DeletePublicShare(ctx, token, filePath, password)) } func (s *Service) RenamePublicShareItem(ctx context.Context, token, filePath, newName, password string) error { if strings.Contains(newName, "/") { return ErrInvalid } if err := s.requirePublicSharePathPerm(ctx, token, filePath, password, nextcloud.PublicShareCanUpdate); err != nil { return err } filePath = nextcloud.NormalizeClientPath(filePath) dir := path.Dir("/" + strings.TrimPrefix(filePath, "/")) destination := path.Join(dir, newName) return mapPublicShareError(s.nc.MovePublicShare(ctx, token, filePath, destination, password)) } func (s *Service) GetPublicSharePermissions(ctx context.Context, token, password string) (int, error) { perms, err := s.nc.GetPublicSharePermissions(ctx, token, password) if err != nil { return 0, mapPublicShareError(err) } return perms, nil } func (s *Service) GetPublicSharePathPermissions(ctx context.Context, token, path, password string) (int, error) { perms, err := s.nc.GetPublicSharePathPermissions(ctx, token, path, password) if err != nil { return 0, mapPublicShareError(err) } return perms, nil } func (s *Service) requirePublicSharePerm(ctx context.Context, token, password string, check func(int) bool) error { perms, err := s.GetPublicSharePermissions(ctx, token, password) if err != nil { return err } if !check(perms) { return ErrForbidden } return nil } func (s *Service) requirePublicSharePathPerm(ctx context.Context, token, path, password string, check func(int) bool) error { perms, err := s.GetPublicSharePathPermissions(ctx, token, path, password) if err != nil { return err } if !check(perms) { return ErrForbidden } return nil }