| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350 |
- package dataprovider
- import (
- "encoding/json"
- "fmt"
- "io/ioutil"
- "path/filepath"
- "github.com/drakkan/sftpgo/logger"
- "github.com/drakkan/sftpgo/utils"
- "github.com/drakkan/sftpgo/vfs"
- )
- type compatUserV2 struct {
- ID int64 `json:"id"`
- Username string `json:"username"`
- Password string `json:"password,omitempty"`
- PublicKeys []string `json:"public_keys,omitempty"`
- HomeDir string `json:"home_dir"`
- UID int `json:"uid"`
- GID int `json:"gid"`
- MaxSessions int `json:"max_sessions"`
- QuotaSize int64 `json:"quota_size"`
- QuotaFiles int `json:"quota_files"`
- Permissions []string `json:"permissions"`
- UsedQuotaSize int64 `json:"used_quota_size"`
- UsedQuotaFiles int `json:"used_quota_files"`
- LastQuotaUpdate int64 `json:"last_quota_update"`
- UploadBandwidth int64 `json:"upload_bandwidth"`
- DownloadBandwidth int64 `json:"download_bandwidth"`
- ExpirationDate int64 `json:"expiration_date"`
- LastLogin int64 `json:"last_login"`
- Status int `json:"status"`
- }
- type compatS3FsConfigV4 struct {
- Bucket string `json:"bucket,omitempty"`
- KeyPrefix string `json:"key_prefix,omitempty"`
- Region string `json:"region,omitempty"`
- AccessKey string `json:"access_key,omitempty"`
- AccessSecret string `json:"access_secret,omitempty"`
- Endpoint string `json:"endpoint,omitempty"`
- StorageClass string `json:"storage_class,omitempty"`
- UploadPartSize int64 `json:"upload_part_size,omitempty"`
- UploadConcurrency int `json:"upload_concurrency,omitempty"`
- }
- type compatGCSFsConfigV4 struct {
- Bucket string `json:"bucket,omitempty"`
- KeyPrefix string `json:"key_prefix,omitempty"`
- CredentialFile string `json:"-"`
- Credentials []byte `json:"credentials,omitempty"`
- AutomaticCredentials int `json:"automatic_credentials,omitempty"`
- StorageClass string `json:"storage_class,omitempty"`
- }
- type compatAzBlobFsConfigV4 struct {
- Container string `json:"container,omitempty"`
- AccountName string `json:"account_name,omitempty"`
- AccountKey string `json:"account_key,omitempty"`
- Endpoint string `json:"endpoint,omitempty"`
- SASURL string `json:"sas_url,omitempty"`
- KeyPrefix string `json:"key_prefix,omitempty"`
- UploadPartSize int64 `json:"upload_part_size,omitempty"`
- UploadConcurrency int `json:"upload_concurrency,omitempty"`
- UseEmulator bool `json:"use_emulator,omitempty"`
- AccessTier string `json:"access_tier,omitempty"`
- }
- type compatFilesystemV4 struct {
- Provider FilesystemProvider `json:"provider"`
- S3Config compatS3FsConfigV4 `json:"s3config,omitempty"`
- GCSConfig compatGCSFsConfigV4 `json:"gcsconfig,omitempty"`
- AzBlobConfig compatAzBlobFsConfigV4 `json:"azblobconfig,omitempty"`
- }
- type compatUserV4 struct {
- ID int64 `json:"id"`
- Status int `json:"status"`
- Username string `json:"username"`
- ExpirationDate int64 `json:"expiration_date"`
- Password string `json:"password,omitempty"`
- PublicKeys []string `json:"public_keys,omitempty"`
- HomeDir string `json:"home_dir"`
- VirtualFolders []vfs.VirtualFolder `json:"virtual_folders,omitempty"`
- UID int `json:"uid"`
- GID int `json:"gid"`
- MaxSessions int `json:"max_sessions"`
- QuotaSize int64 `json:"quota_size"`
- QuotaFiles int `json:"quota_files"`
- Permissions map[string][]string `json:"permissions"`
- UsedQuotaSize int64 `json:"used_quota_size"`
- UsedQuotaFiles int `json:"used_quota_files"`
- LastQuotaUpdate int64 `json:"last_quota_update"`
- UploadBandwidth int64 `json:"upload_bandwidth"`
- DownloadBandwidth int64 `json:"download_bandwidth"`
- LastLogin int64 `json:"last_login"`
- Filters UserFilters `json:"filters"`
- FsConfig compatFilesystemV4 `json:"filesystem"`
- }
- type backupDataV4Compat struct {
- Users []compatUserV4 `json:"users"`
- Folders []vfs.BaseVirtualFolder `json:"folders"`
- }
- func createUserFromV4(u compatUserV4, fsConfig Filesystem) User {
- user := User{
- ID: u.ID,
- Status: u.Status,
- Username: u.Username,
- ExpirationDate: u.ExpirationDate,
- Password: u.Password,
- PublicKeys: u.PublicKeys,
- HomeDir: u.HomeDir,
- VirtualFolders: u.VirtualFolders,
- UID: u.UID,
- GID: u.GID,
- MaxSessions: u.MaxSessions,
- QuotaSize: u.QuotaSize,
- QuotaFiles: u.QuotaFiles,
- Permissions: u.Permissions,
- UsedQuotaSize: u.UsedQuotaSize,
- UsedQuotaFiles: u.UsedQuotaFiles,
- LastQuotaUpdate: u.LastQuotaUpdate,
- UploadBandwidth: u.UploadBandwidth,
- DownloadBandwidth: u.DownloadBandwidth,
- LastLogin: u.LastLogin,
- Filters: u.Filters,
- }
- user.FsConfig = fsConfig
- return user
- }
- func convertUserToV4(u User, fsConfig compatFilesystemV4) compatUserV4 {
- user := compatUserV4{
- ID: u.ID,
- Status: u.Status,
- Username: u.Username,
- ExpirationDate: u.ExpirationDate,
- Password: u.Password,
- PublicKeys: u.PublicKeys,
- HomeDir: u.HomeDir,
- VirtualFolders: u.VirtualFolders,
- UID: u.UID,
- GID: u.GID,
- MaxSessions: u.MaxSessions,
- QuotaSize: u.QuotaSize,
- QuotaFiles: u.QuotaFiles,
- Permissions: u.Permissions,
- UsedQuotaSize: u.UsedQuotaSize,
- UsedQuotaFiles: u.UsedQuotaFiles,
- LastQuotaUpdate: u.LastQuotaUpdate,
- UploadBandwidth: u.UploadBandwidth,
- DownloadBandwidth: u.DownloadBandwidth,
- LastLogin: u.LastLogin,
- Filters: u.Filters,
- }
- user.FsConfig = fsConfig
- return user
- }
- func getCGSCredentialsFromV4(config compatGCSFsConfigV4) (vfs.Secret, error) {
- var secret vfs.Secret
- var err error
- if len(config.Credentials) > 0 {
- secret.Status = vfs.SecretStatusPlain
- secret.Payload = string(config.Credentials)
- return secret, nil
- }
- if config.CredentialFile != "" {
- creds, err := ioutil.ReadFile(config.CredentialFile)
- if err != nil {
- return secret, err
- }
- secret.Status = vfs.SecretStatusPlain
- secret.Payload = string(creds)
- return secret, nil
- }
- return secret, err
- }
- func getCGSCredentialsFromV6(config vfs.GCSFsConfig, username string) (string, error) {
- if config.Credentials.IsEmpty() {
- config.CredentialFile = filepath.Join(credentialsDirPath, fmt.Sprintf("%v_gcs_credentials.json",
- username))
- creds, err := ioutil.ReadFile(config.CredentialFile)
- if err != nil {
- return "", err
- }
- err = json.Unmarshal(creds, &config.Credentials)
- if err != nil {
- return "", err
- }
- }
- if config.Credentials.IsEncrypted() {
- err := config.Credentials.Decrypt()
- if err != nil {
- return "", err
- }
- // in V4 GCS credentials were not encrypted
- return config.Credentials.Payload, nil
- }
- return "", nil
- }
- func convertFsConfigToV4(fs Filesystem, username string) (compatFilesystemV4, error) {
- fsV4 := compatFilesystemV4{
- Provider: fs.Provider,
- S3Config: compatS3FsConfigV4{},
- AzBlobConfig: compatAzBlobFsConfigV4{},
- GCSConfig: compatGCSFsConfigV4{},
- }
- switch fs.Provider {
- case S3FilesystemProvider:
- fsV4.S3Config = compatS3FsConfigV4{
- Bucket: fs.S3Config.Bucket,
- KeyPrefix: fs.S3Config.KeyPrefix,
- Region: fs.S3Config.Region,
- AccessKey: fs.S3Config.AccessKey,
- AccessSecret: "",
- Endpoint: fs.S3Config.Endpoint,
- StorageClass: fs.S3Config.StorageClass,
- UploadPartSize: fs.S3Config.UploadPartSize,
- UploadConcurrency: fs.S3Config.UploadConcurrency,
- }
- if fs.S3Config.AccessSecret.IsEncrypted() {
- err := fs.S3Config.AccessSecret.Decrypt()
- if err != nil {
- return fsV4, err
- }
- secretV4, err := utils.EncryptData(fs.S3Config.AccessSecret.Payload)
- if err != nil {
- return fsV4, err
- }
- fsV4.S3Config.AccessSecret = secretV4
- }
- case AzureBlobFilesystemProvider:
- fsV4.AzBlobConfig = compatAzBlobFsConfigV4{
- Container: fs.AzBlobConfig.Container,
- AccountName: fs.AzBlobConfig.AccountName,
- AccountKey: "",
- Endpoint: fs.AzBlobConfig.Endpoint,
- SASURL: fs.AzBlobConfig.SASURL,
- KeyPrefix: fs.AzBlobConfig.KeyPrefix,
- UploadPartSize: fs.AzBlobConfig.UploadPartSize,
- UploadConcurrency: fs.AzBlobConfig.UploadConcurrency,
- UseEmulator: fs.AzBlobConfig.UseEmulator,
- AccessTier: fs.AzBlobConfig.AccessTier,
- }
- if fs.AzBlobConfig.AccountKey.IsEncrypted() {
- err := fs.AzBlobConfig.AccountKey.Decrypt()
- if err != nil {
- return fsV4, err
- }
- secretV4, err := utils.EncryptData(fs.AzBlobConfig.AccountKey.Payload)
- if err != nil {
- return fsV4, err
- }
- fsV4.AzBlobConfig.AccountKey = secretV4
- }
- case GCSFilesystemProvider:
- fsV4.GCSConfig = compatGCSFsConfigV4{
- Bucket: fs.GCSConfig.Bucket,
- KeyPrefix: fs.GCSConfig.KeyPrefix,
- CredentialFile: fs.GCSConfig.CredentialFile,
- AutomaticCredentials: fs.GCSConfig.AutomaticCredentials,
- StorageClass: fs.GCSConfig.StorageClass,
- }
- if fs.GCSConfig.AutomaticCredentials == 0 {
- creds, err := getCGSCredentialsFromV6(fs.GCSConfig, username)
- if err != nil {
- return fsV4, err
- }
- fsV4.GCSConfig.Credentials = []byte(creds)
- }
- }
- return fsV4, nil
- }
- func convertFsConfigFromV4(compatFs compatFilesystemV4, username string) (Filesystem, error) {
- fsConfig := Filesystem{
- Provider: compatFs.Provider,
- S3Config: vfs.S3FsConfig{},
- AzBlobConfig: vfs.AzBlobFsConfig{},
- GCSConfig: vfs.GCSFsConfig{},
- }
- switch compatFs.Provider {
- case S3FilesystemProvider:
- fsConfig.S3Config = vfs.S3FsConfig{
- Bucket: compatFs.S3Config.Bucket,
- KeyPrefix: compatFs.S3Config.KeyPrefix,
- Region: compatFs.S3Config.Region,
- AccessKey: compatFs.S3Config.AccessKey,
- AccessSecret: vfs.Secret{},
- Endpoint: compatFs.S3Config.Endpoint,
- StorageClass: compatFs.S3Config.StorageClass,
- UploadPartSize: compatFs.S3Config.UploadPartSize,
- UploadConcurrency: compatFs.S3Config.UploadConcurrency,
- }
- if compatFs.S3Config.AccessSecret != "" {
- secret, err := vfs.GetSecretFromCompatString(compatFs.S3Config.AccessSecret)
- if err != nil {
- providerLog(logger.LevelError, "unable to convert v4 filesystem for user %#v: %v", username, err)
- return fsConfig, err
- }
- fsConfig.S3Config.AccessSecret = secret
- }
- case AzureBlobFilesystemProvider:
- fsConfig.AzBlobConfig = vfs.AzBlobFsConfig{
- Container: compatFs.AzBlobConfig.Container,
- AccountName: compatFs.AzBlobConfig.AccountName,
- AccountKey: vfs.Secret{},
- Endpoint: compatFs.AzBlobConfig.Endpoint,
- SASURL: compatFs.AzBlobConfig.SASURL,
- KeyPrefix: compatFs.AzBlobConfig.KeyPrefix,
- UploadPartSize: compatFs.AzBlobConfig.UploadPartSize,
- UploadConcurrency: compatFs.AzBlobConfig.UploadConcurrency,
- UseEmulator: compatFs.AzBlobConfig.UseEmulator,
- AccessTier: compatFs.AzBlobConfig.AccessTier,
- }
- if compatFs.AzBlobConfig.AccountKey != "" {
- secret, err := vfs.GetSecretFromCompatString(compatFs.AzBlobConfig.AccountKey)
- if err != nil {
- providerLog(logger.LevelError, "unable to convert v4 filesystem for user %#v: %v", username, err)
- return fsConfig, err
- }
- fsConfig.AzBlobConfig.AccountKey = secret
- }
- case GCSFilesystemProvider:
- fsConfig.GCSConfig = vfs.GCSFsConfig{
- Bucket: compatFs.GCSConfig.Bucket,
- KeyPrefix: compatFs.GCSConfig.KeyPrefix,
- CredentialFile: compatFs.GCSConfig.CredentialFile,
- AutomaticCredentials: compatFs.GCSConfig.AutomaticCredentials,
- StorageClass: compatFs.GCSConfig.StorageClass,
- }
- if compatFs.GCSConfig.AutomaticCredentials == 0 {
- compatFs.GCSConfig.CredentialFile = filepath.Join(credentialsDirPath, fmt.Sprintf("%v_gcs_credentials.json",
- username))
- }
- secret, err := getCGSCredentialsFromV4(compatFs.GCSConfig)
- if err != nil {
- providerLog(logger.LevelError, "unable to convert v4 filesystem for user %#v: %v", username, err)
- return fsConfig, err
- }
- fsConfig.GCSConfig.Credentials = secret
- }
- return fsConfig, nil
- }
|