@@ -49,7 +49,11 @@ public class ExternalProviderS3 : ExternalProviderBase, ExternalProvider
4949
5050 bool forcePathStyle = false ;
5151 bool customEndpoint = false ;
52-
52+
53+ bool objectOwnershipEnabled ;
54+ private enum BucketPrivacy { PRIVATE , PUBLIC } ;
55+ private BucketPrivacy ? ownerEnforcedBucketPrivacy ;
56+
5357 public string StorageUri
5458 {
5559 get {
@@ -104,6 +108,12 @@ private void Initialize() {
104108 }
105109 }
106110
111+ string default_storage_privacy = GetPropertyValue ( DEFAULT_ACL , DEFAULT_STORAGE_PRIVACY , "" ) ;
112+ objectOwnershipEnabled = ! default_storage_privacy . Contains ( "Bucket owner enforced" ) ;
113+ ownerEnforcedBucketPrivacy = ( ! objectOwnershipEnabled ?
114+ ( default_storage_privacy . Contains ( "private" ) ? BucketPrivacy . PRIVATE : BucketPrivacy . PUBLIC )
115+ : ( BucketPrivacy ? ) null ) ;
116+
107117#if NETCORE
108118 if ( credentials != null )
109119 {
@@ -227,16 +237,22 @@ public string Upload(string localFile, string objectName, GxFileType fileType)
227237 {
228238 BucketName = Bucket ,
229239 Key = objectName ,
230- FilePath = localFile ,
231- CannedACL = GetCannedACL ( fileType )
240+ FilePath = localFile
232241 } ;
242+ if ( objectOwnershipEnabled )
243+ {
244+ objectRequest . CannedACL = GetCannedACL ( fileType ) ;
245+ }
233246 PutObject ( objectRequest ) ;
234247 return GetUrlImpl ( objectName , fileType ) ;
235248 }
236249
237250 private bool IsPrivateUpload ( GxFileType fileType )
238251 {
239- return GetCannedACL ( fileType ) != S3CannedACL . PublicRead ;
252+ if ( objectOwnershipEnabled && GetCannedACL ( fileType ) != S3CannedACL . PublicRead )
253+ return true ;
254+ else
255+ return ownerEnforcedBucketPrivacy . HasValue && ownerEnforcedBucketPrivacy == BucketPrivacy . PRIVATE ;
240256 }
241257
242258 public string Get ( string objectName , GxFileType fileType , int urlMinutes = 0 )
@@ -257,7 +273,7 @@ public string GetUrl(string objectName, GxFileType fileType, int urlMinutes = 0)
257273 private string GetUrlImpl ( string objectName , GxFileType fileType , int urlMinutes = 0 )
258274 {
259275 bool isPrivate = IsPrivateUpload ( fileType ) ;
260- return ( isPrivate ) ? GetPreSignedUrl ( objectName , ResolveExpiration ( urlMinutes ) . TotalMinutes ) : StorageUri + StorageUtils . EncodeUrlPath ( objectName ) ;
276+ return ( isPrivate ) ? GetPreSignedUrl ( objectName , ResolveExpiration ( urlMinutes ) . TotalMinutes ) : IsPrivateUpload ( fileType ) ? GetPreSignedUrl ( objectName , ResolveExpiration ( urlMinutes ) . TotalMinutes ) : StorageUri + StorageUtils . EncodeUrlPath ( objectName ) ;
261277
262278 }
263279
@@ -316,7 +332,9 @@ public string Rename(string objectName, string newName, GxFileType fileType)
316332 {
317333 Copy ( objectName , fileType , newName , fileType ) ;
318334 Delete ( objectName , fileType ) ;
319- return StorageUri + StorageUtils . EncodeUrlPath ( newName ) ;
335+ if ( objectOwnershipEnabled )
336+ return StorageUri + StorageUtils . EncodeUrlPath ( newName ) ;
337+ return IsPrivateUpload ( fileType ) ? GetPreSignedUrl ( objectName , defaultExpiration . Minutes ) : StorageUri + StorageUtils . EncodeUrlPath ( newName ) ;
320338 }
321339
322340 public string Copy ( string objectName , GxFileType sourceFileType , string newName , GxFileType destFileType )
@@ -327,17 +345,23 @@ public string Copy(string objectName, GxFileType sourceFileType, string newName,
327345 SourceKey = objectName ,
328346 DestinationBucket = Bucket ,
329347 DestinationKey = newName ,
330- CannedACL = GetCannedACL ( destFileType ) ,
331348 MetadataDirective = S3MetadataDirective . REPLACE
332349 } ;
333350
351+ if ( objectOwnershipEnabled )
352+ {
353+ request . CannedACL = GetCannedACL ( destFileType ) ;
354+ }
355+
334356 if ( TryGetContentType ( newName , out string mimeType , DEFAULT_CONTENT_TYPE ) )
335357 {
336358 request . ContentType = mimeType ;
337359 }
338360
339361 CopyObject ( request ) ;
340- return StorageUri + StorageUtils . EncodeUrlPath ( newName ) ;
362+ if ( objectOwnershipEnabled )
363+ return StorageUri + StorageUtils . EncodeUrlPath ( newName ) ;
364+ return IsPrivateUpload ( sourceFileType ) ? GetPreSignedUrl ( objectName , defaultExpiration . Minutes ) : StorageUri + StorageUtils . EncodeUrlPath ( newName ) ;
341365 }
342366
343367 private S3CannedACL GetCannedACL ( GxFileType acl )
@@ -384,10 +408,14 @@ private string UploadMultipart(string fileName, Stream stream, GxFileType destFi
384408 BucketName = Bucket ,
385409 Key = fileName ,
386410 PartSize = MULITIPART_POST_PART_SIZE ,
387- InputStream = stream ,
388- CannedACL = GetCannedACL ( destFileType )
411+ InputStream = stream
389412 } ;
390413
414+ if ( objectOwnershipEnabled )
415+ {
416+ uploadRequest . CannedACL = GetCannedACL ( destFileType ) ;
417+ }
418+
391419 if ( TryGetContentType ( fileName , out string mimeType ) )
392420 {
393421 uploadRequest . ContentType = mimeType ;
@@ -404,9 +432,14 @@ private string UploadSimple(string fileName, Stream stream, GxFileType destFileT
404432 {
405433 BucketName = Bucket ,
406434 Key = fileName ,
407- InputStream = stream ,
408- CannedACL = GetCannedACL ( destFileType )
435+ InputStream = stream
409436 } ;
437+
438+ if ( objectOwnershipEnabled )
439+ {
440+ objectRequest . CannedACL = GetCannedACL ( destFileType ) ;
441+ }
442+
410443 if ( TryGetContentType ( fileName , out string mimeType ) )
411444 {
412445 objectRequest . ContentType = mimeType ;
@@ -430,10 +463,14 @@ public string Copy(string url, string newName, string tableName, string fieldNam
430463 SourceKey = url ,
431464 DestinationBucket = Bucket ,
432465 DestinationKey = resourceKey ,
433- CannedACL = GetCannedACL ( destFileType ) ,
434466 MetadataDirective = S3MetadataDirective . REPLACE
435467 } ;
436468
469+ if ( objectOwnershipEnabled )
470+ {
471+ request . CannedACL = GetCannedACL ( destFileType ) ;
472+ }
473+
437474 if ( TryGetContentType ( newName , out string mimeType , DEFAULT_CONTENT_TYPE ) )
438475 {
439476 request . ContentType = mimeType ;
@@ -442,7 +479,9 @@ public string Copy(string url, string newName, string tableName, string fieldNam
442479 AddObjectMetadata ( request . Metadata , tableName , fieldName , resourceKey ) ;
443480 CopyObject ( request ) ;
444481
445- return StorageUri + StorageUtils . EncodeUrlPath ( resourceKey ) ;
482+ if ( objectOwnershipEnabled )
483+ return StorageUri + StorageUtils . EncodeUrlPath ( resourceKey ) ;
484+ return IsPrivateUpload ( destFileType ) ? GetPreSignedUrl ( resourceKey , defaultExpiration . Minutes ) : StorageUri + StorageUtils . EncodeUrlPath ( resourceKey ) ;
446485 }
447486
448487 public string Save ( Stream fileStream , string fileName , string tableName , string fieldName , GxFileType destFileType )
@@ -455,9 +494,12 @@ public string Save(Stream fileStream, string fileName, string tableName, string
455494 {
456495 BucketName = Bucket ,
457496 Key = resourceKey ,
458- InputStream = fileStream ,
459- CannedACL = GetCannedACL ( destFileType )
497+ InputStream = fileStream
460498 } ;
499+ if ( objectOwnershipEnabled )
500+ {
501+ objectRequest . CannedACL = GetCannedACL ( destFileType ) ;
502+ }
461503 if ( TryGetContentType ( fileName , out string mimeType ) )
462504 {
463505 objectRequest . ContentType = mimeType ;
@@ -466,7 +508,9 @@ public string Save(Stream fileStream, string fileName, string tableName, string
466508 AddObjectMetadata ( objectRequest . Metadata , tableName , fieldName , resourceKey ) ;
467509 PutObjectResponse result = PutObject ( objectRequest ) ;
468510
469- return StorageUri + resourceKey ;
511+ if ( objectOwnershipEnabled )
512+ return StorageUri + resourceKey ;
513+ return IsPrivateUpload ( destFileType ) ? GetPreSignedUrl ( resourceKey , defaultExpiration . Minutes ) : StorageUri + StorageUtils . EncodeUrlPath ( resourceKey ) ;
470514 }
471515 catch ( Exception ex )
472516 {
0 commit comments