filesystem.go 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. package vfs
  2. import (
  3. "github.com/sftpgo/sdk"
  4. "github.com/drakkan/sftpgo/v2/kms"
  5. )
  6. // Filesystem defines filesystem details
  7. type Filesystem struct {
  8. RedactedSecret string `json:"-"`
  9. Provider sdk.FilesystemProvider `json:"provider"`
  10. S3Config S3FsConfig `json:"s3config,omitempty"`
  11. GCSConfig GCSFsConfig `json:"gcsconfig,omitempty"`
  12. AzBlobConfig AzBlobFsConfig `json:"azblobconfig,omitempty"`
  13. CryptConfig CryptFsConfig `json:"cryptconfig,omitempty"`
  14. SFTPConfig SFTPFsConfig `json:"sftpconfig,omitempty"`
  15. }
  16. // SetEmptySecrets sets the secrets to empty
  17. func (f *Filesystem) SetEmptySecrets() {
  18. f.S3Config.AccessSecret = kms.NewEmptySecret()
  19. f.GCSConfig.Credentials = kms.NewEmptySecret()
  20. f.AzBlobConfig.AccountKey = kms.NewEmptySecret()
  21. f.AzBlobConfig.SASURL = kms.NewEmptySecret()
  22. f.CryptConfig.Passphrase = kms.NewEmptySecret()
  23. f.SFTPConfig.Password = kms.NewEmptySecret()
  24. f.SFTPConfig.PrivateKey = kms.NewEmptySecret()
  25. }
  26. // SetEmptySecretsIfNil sets the secrets to empty if nil
  27. func (f *Filesystem) SetEmptySecretsIfNil() {
  28. if f.S3Config.AccessSecret == nil {
  29. f.S3Config.AccessSecret = kms.NewEmptySecret()
  30. }
  31. if f.GCSConfig.Credentials == nil {
  32. f.GCSConfig.Credentials = kms.NewEmptySecret()
  33. }
  34. if f.AzBlobConfig.AccountKey == nil {
  35. f.AzBlobConfig.AccountKey = kms.NewEmptySecret()
  36. }
  37. if f.AzBlobConfig.SASURL == nil {
  38. f.AzBlobConfig.SASURL = kms.NewEmptySecret()
  39. }
  40. if f.CryptConfig.Passphrase == nil {
  41. f.CryptConfig.Passphrase = kms.NewEmptySecret()
  42. }
  43. if f.SFTPConfig.Password == nil {
  44. f.SFTPConfig.Password = kms.NewEmptySecret()
  45. }
  46. if f.SFTPConfig.PrivateKey == nil {
  47. f.SFTPConfig.PrivateKey = kms.NewEmptySecret()
  48. }
  49. }
  50. // SetNilSecretsIfEmpty set the secrets to nil if empty.
  51. // This is useful before rendering as JSON so the empty fields
  52. // will not be serialized.
  53. func (f *Filesystem) SetNilSecretsIfEmpty() {
  54. if f.S3Config.AccessSecret != nil && f.S3Config.AccessSecret.IsEmpty() {
  55. f.S3Config.AccessSecret = nil
  56. }
  57. if f.GCSConfig.Credentials != nil && f.GCSConfig.Credentials.IsEmpty() {
  58. f.GCSConfig.Credentials = nil
  59. }
  60. if f.AzBlobConfig.AccountKey != nil && f.AzBlobConfig.AccountKey.IsEmpty() {
  61. f.AzBlobConfig.AccountKey = nil
  62. }
  63. if f.AzBlobConfig.SASURL != nil && f.AzBlobConfig.SASURL.IsEmpty() {
  64. f.AzBlobConfig.SASURL = nil
  65. }
  66. if f.CryptConfig.Passphrase != nil && f.CryptConfig.Passphrase.IsEmpty() {
  67. f.CryptConfig.Passphrase = nil
  68. }
  69. if f.SFTPConfig.Password != nil && f.SFTPConfig.Password.IsEmpty() {
  70. f.SFTPConfig.Password = nil
  71. }
  72. if f.SFTPConfig.PrivateKey != nil && f.SFTPConfig.PrivateKey.IsEmpty() {
  73. f.SFTPConfig.PrivateKey = nil
  74. }
  75. }
  76. // IsEqual returns true if the fs is equal to other
  77. func (f *Filesystem) IsEqual(other *Filesystem) bool {
  78. if f.Provider != other.Provider {
  79. return false
  80. }
  81. switch f.Provider {
  82. case sdk.S3FilesystemProvider:
  83. return f.S3Config.isEqual(&other.S3Config)
  84. case sdk.GCSFilesystemProvider:
  85. return f.GCSConfig.isEqual(&other.GCSConfig)
  86. case sdk.AzureBlobFilesystemProvider:
  87. return f.AzBlobConfig.isEqual(&other.AzBlobConfig)
  88. case sdk.CryptedFilesystemProvider:
  89. return f.CryptConfig.isEqual(&other.CryptConfig)
  90. case sdk.SFTPFilesystemProvider:
  91. return f.SFTPConfig.isEqual(&other.SFTPConfig)
  92. default:
  93. return true
  94. }
  95. }
  96. // Validate verifies the FsConfig matching the configured provider and sets all other
  97. // Filesystem.*Config to their zero value if successful
  98. func (f *Filesystem) Validate(additionalData string) error {
  99. switch f.Provider {
  100. case sdk.S3FilesystemProvider:
  101. if err := f.S3Config.ValidateAndEncryptCredentials(additionalData); err != nil {
  102. return err
  103. }
  104. f.GCSConfig = GCSFsConfig{}
  105. f.AzBlobConfig = AzBlobFsConfig{}
  106. f.CryptConfig = CryptFsConfig{}
  107. f.SFTPConfig = SFTPFsConfig{}
  108. return nil
  109. case sdk.GCSFilesystemProvider:
  110. if err := f.GCSConfig.ValidateAndEncryptCredentials(additionalData); err != nil {
  111. return err
  112. }
  113. f.S3Config = S3FsConfig{}
  114. f.AzBlobConfig = AzBlobFsConfig{}
  115. f.CryptConfig = CryptFsConfig{}
  116. f.SFTPConfig = SFTPFsConfig{}
  117. return nil
  118. case sdk.AzureBlobFilesystemProvider:
  119. if err := f.AzBlobConfig.ValidateAndEncryptCredentials(additionalData); err != nil {
  120. return err
  121. }
  122. f.S3Config = S3FsConfig{}
  123. f.GCSConfig = GCSFsConfig{}
  124. f.CryptConfig = CryptFsConfig{}
  125. f.SFTPConfig = SFTPFsConfig{}
  126. return nil
  127. case sdk.CryptedFilesystemProvider:
  128. if err := f.CryptConfig.ValidateAndEncryptCredentials(additionalData); err != nil {
  129. return err
  130. }
  131. f.S3Config = S3FsConfig{}
  132. f.GCSConfig = GCSFsConfig{}
  133. f.AzBlobConfig = AzBlobFsConfig{}
  134. f.SFTPConfig = SFTPFsConfig{}
  135. return nil
  136. case sdk.SFTPFilesystemProvider:
  137. if err := f.SFTPConfig.ValidateAndEncryptCredentials(additionalData); err != nil {
  138. return err
  139. }
  140. f.S3Config = S3FsConfig{}
  141. f.GCSConfig = GCSFsConfig{}
  142. f.AzBlobConfig = AzBlobFsConfig{}
  143. f.CryptConfig = CryptFsConfig{}
  144. return nil
  145. default:
  146. f.Provider = sdk.LocalFilesystemProvider
  147. f.S3Config = S3FsConfig{}
  148. f.GCSConfig = GCSFsConfig{}
  149. f.AzBlobConfig = AzBlobFsConfig{}
  150. f.CryptConfig = CryptFsConfig{}
  151. f.SFTPConfig = SFTPFsConfig{}
  152. return nil
  153. }
  154. }
  155. // HasRedactedSecret returns true if configured the filesystem configuration has a redacted secret
  156. func (f *Filesystem) HasRedactedSecret() bool {
  157. // TODO move vfs specific code into each *FsConfig struct
  158. switch f.Provider {
  159. case sdk.S3FilesystemProvider:
  160. if f.S3Config.AccessSecret.IsRedacted() {
  161. return true
  162. }
  163. case sdk.GCSFilesystemProvider:
  164. if f.GCSConfig.Credentials.IsRedacted() {
  165. return true
  166. }
  167. case sdk.AzureBlobFilesystemProvider:
  168. if f.AzBlobConfig.AccountKey.IsRedacted() {
  169. return true
  170. }
  171. if f.AzBlobConfig.SASURL.IsRedacted() {
  172. return true
  173. }
  174. case sdk.CryptedFilesystemProvider:
  175. if f.CryptConfig.Passphrase.IsRedacted() {
  176. return true
  177. }
  178. case sdk.SFTPFilesystemProvider:
  179. if f.SFTPConfig.Password.IsRedacted() {
  180. return true
  181. }
  182. if f.SFTPConfig.PrivateKey.IsRedacted() {
  183. return true
  184. }
  185. }
  186. return false
  187. }
  188. // HideConfidentialData hides filesystem confidential data
  189. func (f *Filesystem) HideConfidentialData() {
  190. switch f.Provider {
  191. case sdk.S3FilesystemProvider:
  192. f.S3Config.HideConfidentialData()
  193. case sdk.GCSFilesystemProvider:
  194. f.GCSConfig.HideConfidentialData()
  195. case sdk.AzureBlobFilesystemProvider:
  196. f.AzBlobConfig.HideConfidentialData()
  197. case sdk.CryptedFilesystemProvider:
  198. f.CryptConfig.HideConfidentialData()
  199. case sdk.SFTPFilesystemProvider:
  200. f.SFTPConfig.HideConfidentialData()
  201. }
  202. }
  203. // GetACopy returns a filesystem copy
  204. func (f *Filesystem) GetACopy() Filesystem {
  205. f.SetEmptySecretsIfNil()
  206. fs := Filesystem{
  207. Provider: f.Provider,
  208. S3Config: S3FsConfig{
  209. BaseS3FsConfig: sdk.BaseS3FsConfig{
  210. Bucket: f.S3Config.Bucket,
  211. Region: f.S3Config.Region,
  212. AccessKey: f.S3Config.AccessKey,
  213. RoleARN: f.S3Config.RoleARN,
  214. Endpoint: f.S3Config.Endpoint,
  215. StorageClass: f.S3Config.StorageClass,
  216. ACL: f.S3Config.ACL,
  217. KeyPrefix: f.S3Config.KeyPrefix,
  218. UploadPartSize: f.S3Config.UploadPartSize,
  219. UploadConcurrency: f.S3Config.UploadConcurrency,
  220. DownloadPartSize: f.S3Config.DownloadPartSize,
  221. DownloadConcurrency: f.S3Config.DownloadConcurrency,
  222. DownloadPartMaxTime: f.S3Config.DownloadPartMaxTime,
  223. UploadPartMaxTime: f.S3Config.UploadPartMaxTime,
  224. ForcePathStyle: f.S3Config.ForcePathStyle,
  225. },
  226. AccessSecret: f.S3Config.AccessSecret.Clone(),
  227. },
  228. GCSConfig: GCSFsConfig{
  229. BaseGCSFsConfig: sdk.BaseGCSFsConfig{
  230. Bucket: f.GCSConfig.Bucket,
  231. AutomaticCredentials: f.GCSConfig.AutomaticCredentials,
  232. StorageClass: f.GCSConfig.StorageClass,
  233. ACL: f.GCSConfig.ACL,
  234. KeyPrefix: f.GCSConfig.KeyPrefix,
  235. },
  236. Credentials: f.GCSConfig.Credentials.Clone(),
  237. },
  238. AzBlobConfig: AzBlobFsConfig{
  239. BaseAzBlobFsConfig: sdk.BaseAzBlobFsConfig{
  240. Container: f.AzBlobConfig.Container,
  241. AccountName: f.AzBlobConfig.AccountName,
  242. Endpoint: f.AzBlobConfig.Endpoint,
  243. KeyPrefix: f.AzBlobConfig.KeyPrefix,
  244. UploadPartSize: f.AzBlobConfig.UploadPartSize,
  245. UploadConcurrency: f.AzBlobConfig.UploadConcurrency,
  246. DownloadPartSize: f.AzBlobConfig.DownloadPartSize,
  247. DownloadConcurrency: f.AzBlobConfig.DownloadConcurrency,
  248. UseEmulator: f.AzBlobConfig.UseEmulator,
  249. AccessTier: f.AzBlobConfig.AccessTier,
  250. },
  251. AccountKey: f.AzBlobConfig.AccountKey.Clone(),
  252. SASURL: f.AzBlobConfig.SASURL.Clone(),
  253. },
  254. CryptConfig: CryptFsConfig{
  255. Passphrase: f.CryptConfig.Passphrase.Clone(),
  256. },
  257. SFTPConfig: SFTPFsConfig{
  258. BaseSFTPFsConfig: sdk.BaseSFTPFsConfig{
  259. Endpoint: f.SFTPConfig.Endpoint,
  260. Username: f.SFTPConfig.Username,
  261. Prefix: f.SFTPConfig.Prefix,
  262. DisableCouncurrentReads: f.SFTPConfig.DisableCouncurrentReads,
  263. BufferSize: f.SFTPConfig.BufferSize,
  264. },
  265. Password: f.SFTPConfig.Password.Clone(),
  266. PrivateKey: f.SFTPConfig.PrivateKey.Clone(),
  267. },
  268. }
  269. if len(f.SFTPConfig.Fingerprints) > 0 {
  270. fs.SFTPConfig.Fingerprints = make([]string, len(f.SFTPConfig.Fingerprints))
  271. copy(fs.SFTPConfig.Fingerprints, f.SFTPConfig.Fingerprints)
  272. }
  273. return fs
  274. }