azblob: store SAS URL as kms.Secret

This commit is contained in:
Nicola Murino
2021-06-11 22:27:36 +02:00
parent 8607788975
commit 9d3d7db29c
26 changed files with 1026 additions and 72 deletions

View File

@@ -75,13 +75,16 @@ func NewAzBlobFs(connectionID, localTempDir, mountPath string, config AzBlobFsCo
if err := fs.config.AccountKey.TryDecrypt(); err != nil {
return fs, err
}
if err := fs.config.SASURL.TryDecrypt(); err != nil {
return fs, err
}
fs.setConfigDefaults()
version := version.Get()
telemetryValue := fmt.Sprintf("SFTPGo-%v_%v", version.Version, version.CommitHash)
if fs.config.SASURL != "" {
u, err := url.Parse(fs.config.SASURL)
if fs.config.SASURL.GetPayload() != "" {
u, err := url.Parse(fs.config.SASURL.GetPayload())
if err != nil {
return fs, fmt.Errorf("invalid credentials: %v", err)
}
@@ -144,8 +147,8 @@ func NewAzBlobFs(connectionID, localTempDir, mountPath string, config AzBlobFsCo
// Name returns the name for the Fs implementation
func (fs *AzureBlobFs) Name() string {
if fs.config.SASURL != "" {
return fmt.Sprintf("Azure Blob SAS URL %#v", fs.config.Container)
if !fs.config.SASURL.IsEmpty() {
return fmt.Sprintf("Azure Blob with SAS URL, container %#v", fs.config.Container)
}
return fmt.Sprintf("Azure Blob container %#v", fs.config.Container)
}

View File

@@ -37,6 +37,9 @@ func (f *Filesystem) SetEmptySecretsIfNil() {
if f.AzBlobConfig.AccountKey == nil {
f.AzBlobConfig.AccountKey = kms.NewEmptySecret()
}
if f.AzBlobConfig.SASURL == nil {
f.AzBlobConfig.SASURL = kms.NewEmptySecret()
}
if f.CryptConfig.Passphrase == nil {
f.CryptConfig.Passphrase = kms.NewEmptySecret()
}
@@ -61,6 +64,9 @@ func (f *Filesystem) SetNilSecretsIfEmpty() {
if f.AzBlobConfig.AccountKey != nil && f.AzBlobConfig.AccountKey.IsEmpty() {
f.AzBlobConfig.AccountKey = nil
}
if f.AzBlobConfig.SASURL != nil && f.AzBlobConfig.SASURL.IsEmpty() {
f.AzBlobConfig.SASURL = nil
}
if f.CryptConfig.Passphrase != nil && f.CryptConfig.Passphrase.IsEmpty() {
f.CryptConfig.Passphrase = nil
}
@@ -122,7 +128,7 @@ func (f *Filesystem) GetACopy() Filesystem {
AccountName: f.AzBlobConfig.AccountName,
AccountKey: f.AzBlobConfig.AccountKey.Clone(),
Endpoint: f.AzBlobConfig.Endpoint,
SASURL: f.AzBlobConfig.SASURL,
SASURL: f.AzBlobConfig.SASURL.Clone(),
KeyPrefix: f.AzBlobConfig.KeyPrefix,
UploadPartSize: f.AzBlobConfig.UploadPartSize,
UploadConcurrency: f.AzBlobConfig.UploadConcurrency,

View File

@@ -108,6 +108,7 @@ func (v *BaseVirtualFolder) hideConfidentialData() {
v.FsConfig.GCSConfig.Credentials.Hide()
case AzureBlobFilesystemProvider:
v.FsConfig.AzBlobConfig.AccountKey.Hide()
v.FsConfig.AzBlobConfig.SASURL.Hide()
case CryptedFilesystemProvider:
v.FsConfig.CryptConfig.Passphrase.Hide()
case SFTPFilesystemProvider:
@@ -139,6 +140,9 @@ func (v *BaseVirtualFolder) HasRedactedSecret() bool {
if v.FsConfig.AzBlobConfig.AccountKey.IsRedacted() {
return true
}
if v.FsConfig.AzBlobConfig.SASURL.IsRedacted() {
return true
}
case CryptedFilesystemProvider:
if v.FsConfig.CryptConfig.Passphrase.IsRedacted() {
return true

View File

@@ -342,9 +342,9 @@ type AzBlobFsConfig struct {
// for example "http://127.0.0.1:10000"
Endpoint string `json:"endpoint,omitempty"`
// Shared access signature URL, leave blank if using account/key
SASURL string `json:"sas_url,omitempty"`
SASURL *kms.Secret `json:"sas_url,omitempty"`
// KeyPrefix is similar to a chroot directory for local filesystem.
// If specified then the SFTPGo userd will only see objects that starts
// If specified then the SFTPGo user will only see objects that starts
// with this prefix and so you can restrict access to a specific
// folder. The prefix, if not empty, must not start with "/" and must
// end with "/".
@@ -376,7 +376,13 @@ func (c *AzBlobFsConfig) isEqual(other *AzBlobFsConfig) bool {
if c.Endpoint != other.Endpoint {
return false
}
if c.SASURL != other.SASURL {
if c.SASURL.IsEmpty() {
c.SASURL = kms.NewEmptySecret()
}
if other.SASURL.IsEmpty() {
other.SASURL = kms.NewEmptySecret()
}
if !c.SASURL.IsEqual(other.SASURL) {
return false
}
if c.KeyPrefix != other.KeyPrefix {
@@ -411,10 +417,26 @@ func (c *AzBlobFsConfig) EncryptCredentials(additionalData string) error {
return err
}
}
if c.SASURL.IsPlain() {
c.SASURL.SetAdditionalData(additionalData)
if err := c.SASURL.Encrypt(); err != nil {
return err
}
}
return nil
}
func (c *AzBlobFsConfig) checkCredentials() error {
if c.SASURL.IsPlain() {
_, err := url.Parse(c.SASURL.GetPayload())
return err
}
if c.SASURL.IsEncrypted() && !c.SASURL.IsValid() {
return errors.New("invalid encrypted sas_url")
}
if !c.SASURL.IsEmpty() {
return nil
}
if c.AccountName == "" || !c.AccountKey.IsValidInput() {
return errors.New("credentials cannot be empty or invalid")
}
@@ -429,11 +451,11 @@ func (c *AzBlobFsConfig) Validate() error {
if c.AccountKey == nil {
c.AccountKey = kms.NewEmptySecret()
}
if c.SASURL != "" {
_, err := url.Parse(c.SASURL)
return err
if c.SASURL == nil {
c.SASURL = kms.NewEmptySecret()
}
if c.Container == "" {
// container could be embedded within SAS URL we check this at runtime
if c.SASURL.IsEmpty() && c.Container == "" {
return errors.New("container cannot be empty")
}
if err := c.checkCredentials(); err != nil {