aws-amplify / amplify-swift

A declarative library for application development using cloud services.
Apache License 2.0
447 stars 194 forks source link

iOS: Unable to set ACL's for files being uploaded to S3 #1625

Open mazhigbee-pb opened 2 years ago

mazhigbee-pb commented 2 years ago

Describe the bug

I am unable to set the ACL public-read from my iOS application while uploading a photo using Amplify.Storage.uploadData. This S3 bucket is an existing resource and therefor I cannot use the Amplify CLI to configure the bucket.

All images that are uploaded using the accessLevels guest public & private are un-viewable publicly.

Similarly our web client uses the S3 SDK and has an option to set the ACL during upload:

s3.upload({
          Key: filename,
          Body: file,
          ContentType: file.type,
          ACL: "public-read"
        })

Is there a way to obtain this result using the Amplify SDK? Or any other options I could try that don't involve changing permissions on the bucket?

Steps To Reproduce

Attempt to upload an image that requires a public ACL from the iOS Amplify SDK.

Expected behavior

I should be able to set the ACL of a file to 'public-read' or whatever the required permission is from the Amplify SDK.

Amplify Framework Version

1.19.2

Amplify Categories

Storage

Dependency manager

Swift PM

Swift version

5.2

CLI version

4.4

Xcode version

13.3

Is this a regression?

Yes

Device

iPhone 13 Simulator

iOS Version

iOS 13.2

mazhigbee-pb commented 2 years ago

@lawmicha I saw your response here but I think I need a more flexible solution in the long run. Is this something that's posible? https://github.com/aws-amplify/aws-sdk-ios/issues/2233

mazhigbee-pb commented 2 years ago

For others who might have similar issues, accessing the escape hatch was the only option. I was able to use the AWSS3StoragePlugin putObject method to upload an image and set the public_read ACL. There's no documentation on this beyond how to actually access the escape hatch https://docs.amplify.aws/lib/storage/escapehatch/q/platform/ios/. It would be very helpful if the escape hatch was documented beyond the one example in the docs.


 func uploadToS3(data: Data, bucketName: String, uploadKeyName: String, contentType: String, completion: @escaping (String) -> Void) {
            do {
                let plugin = try Amplify.Storage.getPlugin(for: "awsS3StoragePlugin") as? AWSS3StoragePlugin

                if let escapedPlugin = plugin {
                    let awsS3 = escapedPlugin.getEscapeHatch()
                    let request = AWSS3PutObjectRequest()

                    if let req = request {
                        req.body = data
                        req.contentType = contentType
                        req.contentLength = NSNumber(integerLiteral: NSData(data: data).length) 
                        req.bucket = bucketName
                        req.key = uploadKeyName
                        req.acl = .publicRead

                        awsS3.putObject(req).continueWith { (task) -> AnyObject? in
                            if let error = task.error {
                                print("There was an error with image upload - \(error)")
                            }

                            if task.result != nil {
                                let s3URL = NSURL(string: "\(Environment.awsS3UserUploadBaseUrl)/\(uploadKeyName)")

                                if let url = s3URL?.absoluteString {
                                    print("Image uploaded to:  \(url)")
                                    completion(url)
                                }
                            }

                            return nil
                        }
                    }
                }

            } catch {
                print("Get S3 escape hatch failed with error - \(error)")
            }
        }
mazhigbee-pb commented 1 year ago

Any update on this? Would it make more sense if I migrated my usage to the TransferUtility? @atierian @lawmicha?

lawmicha commented 1 year ago

Thanks for the example in https://github.com/aws-amplify/amplify-swift/issues/1625#issuecomment-1048004274 I believe this should live in the documentation under the escape hatch.

In terms of the feature request, this seems possible. One way is to pass it in AWSS3PluginOptions https://github.com/aws-amplify/amplify-swift/blob/main/AmplifyPlugins/Storage/Sources/AWSS3StoragePlugin/Configuration/AWSS3PluginOptions.swift#L32 since it's AWS specific.