extend virtual folders support to all storage backends

Fixes #241
This commit is contained in:
Nicola Murino
2021-03-21 19:15:47 +01:00
parent 0286da2356
commit d6dc3a507e
70 changed files with 6825 additions and 3740 deletions

View File

@@ -2,6 +2,7 @@ package vfs
import (
"fmt"
"path/filepath"
"strconv"
"strings"
@@ -23,6 +24,18 @@ type BaseVirtualFolder struct {
LastQuotaUpdate int64 `json:"last_quota_update"`
// list of usernames associated with this virtual folder
Users []string `json:"users,omitempty"`
// Filesystem configuration details
FsConfig Filesystem `json:"filesystem"`
}
// GetEncrytionAdditionalData returns the additional data to use for AEAD
func (v *BaseVirtualFolder) GetEncrytionAdditionalData() string {
return fmt.Sprintf("folder_%v", v.Name)
}
// GetGCSCredentialsFilePath returns the path for GCS credentials
func (v *BaseVirtualFolder) GetGCSCredentialsFilePath() string {
return filepath.Join(credentialsDirPath, "folders", fmt.Sprintf("%v_gcs_credentials.json", v.Name))
}
// GetACopy returns a copy
@@ -38,6 +51,7 @@ func (v *BaseVirtualFolder) GetACopy() BaseVirtualFolder {
UsedQuotaFiles: v.UsedQuotaFiles,
LastQuotaUpdate: v.LastQuotaUpdate,
Users: users,
FsConfig: v.FsConfig.GetACopy(),
}
}
@@ -60,6 +74,58 @@ func (v *BaseVirtualFolder) GetQuotaSummary() string {
return result
}
// IsLocalOrLocalCrypted returns true if the folder provider is local or local encrypted
func (v *BaseVirtualFolder) IsLocalOrLocalCrypted() bool {
return v.FsConfig.Provider == LocalFilesystemProvider || v.FsConfig.Provider == CryptedFilesystemProvider
}
// HideConfidentialData hides folder confidential data
func (v *BaseVirtualFolder) HideConfidentialData() {
switch v.FsConfig.Provider {
case S3FilesystemProvider:
v.FsConfig.S3Config.AccessSecret.Hide()
case GCSFilesystemProvider:
v.FsConfig.GCSConfig.Credentials.Hide()
case AzureBlobFilesystemProvider:
v.FsConfig.AzBlobConfig.AccountKey.Hide()
case CryptedFilesystemProvider:
v.FsConfig.CryptConfig.Passphrase.Hide()
case SFTPFilesystemProvider:
v.FsConfig.SFTPConfig.Password.Hide()
v.FsConfig.SFTPConfig.PrivateKey.Hide()
}
}
// HasRedactedSecret returns true if the folder has a redacted secret
func (v *BaseVirtualFolder) HasRedactedSecret() bool {
switch v.FsConfig.Provider {
case S3FilesystemProvider:
if v.FsConfig.S3Config.AccessSecret.IsRedacted() {
return true
}
case GCSFilesystemProvider:
if v.FsConfig.GCSConfig.Credentials.IsRedacted() {
return true
}
case AzureBlobFilesystemProvider:
if v.FsConfig.AzBlobConfig.AccountKey.IsRedacted() {
return true
}
case CryptedFilesystemProvider:
if v.FsConfig.CryptConfig.Passphrase.IsRedacted() {
return true
}
case SFTPFilesystemProvider:
if v.FsConfig.SFTPConfig.Password.IsRedacted() {
return true
}
if v.FsConfig.SFTPConfig.PrivateKey.IsRedacted() {
return true
}
}
return false
}
// VirtualFolder defines a mapping between an SFTPGo exposed virtual path and a
// filesystem path outside the user home directory.
// The specified paths must be absolute and the virtual path cannot be "/",
@@ -75,6 +141,36 @@ type VirtualFolder struct {
QuotaFiles int `json:"quota_files"`
}
func (v *VirtualFolder) GetFilesystem(connectionID string) (Fs, error) {
switch v.FsConfig.Provider {
case S3FilesystemProvider:
return NewS3Fs(connectionID, v.MappedPath, v.VirtualPath, v.FsConfig.S3Config)
case GCSFilesystemProvider:
config := v.FsConfig.GCSConfig
config.CredentialFile = v.GetGCSCredentialsFilePath()
return NewGCSFs(connectionID, v.MappedPath, v.VirtualPath, config)
case AzureBlobFilesystemProvider:
return NewAzBlobFs(connectionID, v.MappedPath, v.VirtualPath, v.FsConfig.AzBlobConfig)
case CryptedFilesystemProvider:
return NewCryptFs(connectionID, v.MappedPath, v.VirtualPath, v.FsConfig.CryptConfig)
case SFTPFilesystemProvider:
return NewSFTPFs(connectionID, v.VirtualPath, v.FsConfig.SFTPConfig)
default:
return NewOsFs(connectionID, v.MappedPath, v.VirtualPath), nil
}
}
// ScanQuota scans the folder and returns the number of files and their size
func (v *VirtualFolder) ScanQuota() (int, int64, error) {
fs, err := v.GetFilesystem("")
if err != nil {
return 0, 0, err
}
defer fs.Close()
return fs.ScanRootDirContents()
}
// IsIncludedInUserQuota returns true if the virtual folder is included in user quota
func (v *VirtualFolder) IsIncludedInUserQuota() bool {
return v.QuotaFiles == -1 && v.QuotaSize == -1
@@ -87,3 +183,13 @@ func (v *VirtualFolder) HasNoQuotaRestrictions(checkFiles bool) bool {
}
return false
}
// GetACopy returns a copy
func (v *VirtualFolder) GetACopy() VirtualFolder {
return VirtualFolder{
BaseVirtualFolder: v.BaseVirtualFolder.GetACopy(),
VirtualPath: v.VirtualPath,
QuotaSize: v.QuotaSize,
QuotaFiles: v.QuotaFiles,
}
}