filesystem.go 11 KB

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