iOS AWS S3 Transfer Utility not uploading - ios

I've implemented this tutorial exactly, and i'm able to successfully upload an image to a s3 bucket using the uploadData method (the completion handler block runs with error=nil). My problem is that I can't see the file in the bucket when i'm looking through the AWS console, so I'm not sure if the image was uploaded successfully and due to wrong permissions or something like that I can't find it or if the image was not really uploaded.
Any idea what's wrong ?
Edit -
I've added permissions to the S3 bucket in the role policy of the new Cognito pool id that I've created for the client authentication purposes, but still no help.
Edit 2 -
I've also opened permissions on the bucket itself to everyone.

Make sure your bucket was created in the same region as your Cognito pool ids.

Related

Fastlane Match 'Access Denied' with Amazon S3

I am trying to setup match, fastlane's tool for code signing on iOS apps. Out of the three options, I chose to store my certificates in Amazon S3, but my authorization is either not working or I have to change my permissions for the bucket on S3. Does anyone have an idea of the exact permissions I need to set? Or if this is the right way to use the environment variables for S3? I am getting this error:
Aws::S3::Errors::AccessDenied: [!] Access Denied
This is what my match file looks like:
s3_bucket("my-bucket")
s3_region(ENV["AWS_DEFAULT_REGION"])
s3_access_key(ENV["AWS_ACCESS_KEY_ID"])
s3_secret_access_key(ENV["AWS_SECRET_ACCESS_KEY"])
storage_mode("s3")
type("appstore")
app_identifier(["my.app.identifier"])
username("myappleid#icloud.com")
Thanks in advance.
By reading this article, looks like your IAM should have the s3:PutBucketPolicy permission policy.

How to map already uploaded s3 image with ActiveStorage

My workflow
I have created a bucket in s3.
When somebody drops an image over there an SNS notification comes to my rails app in response got the image name.
By the image name, I can get the user info.
Now I need to create an active storage relation with the user which will map that s3 URL in active storage table.
Can the rails app access the file through s3?
You can attach an existing using an IO object as documented here:
https://edgeguides.rubyonrails.org/active_storage_overview.html#attaching-file-io-objects

How to download file from an AWS S3 bucket in Swift with unauthenticated users

I want to download a file that's in my AWS S3 bucket from within my iOS app with Swift. How do I do this?
I've done a lot of research and googling and can only find documentation from AWS about how to do this in Objective-C. I've set up AWS Cognito already and gave unauthenticated users permission to get objects from my bucket. I just need to figure out how to actually download from my bucket now. Can anyone guide me in the right direction here? I would greatly appreciate any help.
You can also use AWS Amplify framework. The Storage related documentation is here: https://aws-amplify.github.io/docs/ios/storage which will guide you through provisioning S3 bucket and installing Amplify using CocoaPods. I'd suggest going over that documentation even if you have your own bucket. If you want to use an existing S3 bucket, it will be clearer how to add it to the amplifyconfiguration.json to configure the Amplify Storage plugin.
The Swift code will then look like this:
Amplify.Storage.downloadData(key: "myKey") { (event) in
switch event {
case .completed(let data):
print("Completed: \(data)")
case .failed(let storageError):
print("Failed: \(storageError.errorDescription). \(storageError.recoverySuggestion)")
case .inProcess(let progress):
print("Progress: \(progress)")
default:
break
}
}
If you are using AWS resources to retrieve the object to down
Then they must be having the role to access data within the S3 bucket
If you are retrieving directly from your devices out side AWS,
Then you have to make the S3 bucket public
But I suggest you to use EC2 or Lambda as a proxy
And using your iOS app will try to retrieve the data,
At that time the EC2 or Lambda will first fetch and share the data with you
So, you don't need to make your bucket public

AWS Cognito Authentication + AWS Mobile Client + API Gateway + S3 Bucket

I built a login screen for my app using AWSCognitoAuth, exactly like in one of the provided examples (https://github.com/awslabs/aws-sdk-ios-samples/tree/master/CognitoAuth-Sample). This works fine - it shows the login screen in an instance of SFSafariViewController where the user just logs in using regular username + passwort, or through Facebook or Google. So after this authentication, I get the access and refresh tokens which I can then use for fetching data from my API, which is routed through AWS API Gateway. The corresponding AWS API Gateway routes are configured to use "User Pools" authorization, instead of "IAM".
But now I need to download some files from a S3 bucket, which is not public. So what needs to be done, is to get temporary AWS Credentials and access the bucket using them. The AWSMobileClient library together with the S3 Transfer Utility are able to do that. But my problem is, I don't know how to tell the AWSMobileClient about the fact, that the user has now signed in .AWSMobileClient is initialized in the appDelegate's didFinishLaunching:withOptions like this:
let serviceConfiguration = AWSServiceConfiguration(
region: .EUWest1,
credentialsProvider: AWSMobileClient.sharedInstance().getCredentialsProvider()
)
//create a pool
let configuration = AWSCognitoIdentityUserPoolConfiguration.init(clientId: CognitoIdentityUserPoolAppClientId, clientSecret: CognitoIdentityUserPoolAppClientSecret, poolId: CognitoIdentityUserPoolId)
AWSCognitoIdentityUserPool.register(with: serviceConfiguration, userPoolConfiguration: configuration, forKey: AWSCognitoUserPoolsSignInProviderKey)
AWSServiceManager.default().defaultServiceConfiguration = serviceConfiguration
AWSFacebookSignInProvider.sharedInstance().setPermissions(["public_profile", "email"])
AWSSignInManager.sharedInstance().register(signInProvider: AWSFacebookSignInProvider.sharedInstance())
return AWSMobileClient.sharedInstance().interceptApplication(
application,
didFinishLaunchingWithOptions: launchOptions)
The thing is, when I completely close the app after doing the AWSCognitoAuth signin and reopen it, the AWSMobileClient somehow finds the session and the credentials are fetched properly and the file from the bucket gets loaded. But I need to somehow trigger this manually after the user signs in, I cannot force the user to quit and reopen the app, not in 2018... I have been debugging this now for a long time and was digging through the AWSMobileClient framework, trying to find how to hook those two together, but with no success. How can I do it?
But now I need to download some files from a S3 bucket, which is not
public. So what needs to be done, is to get temporary AWS Credentials
and access the bucket using them. The AWSMobileClient library together
with the S3 Transfer Utility are able to do that. But my problem is, I
don't know how to tell the AWSMobileClient about the fact, that the
user has now signed in .AWSMobileClient is initialized in the
appDelegate's didFinishLaunching:withOptions
Did you already try to use Pre-signed url? It is meant to cover your requirements. It allows temporary access to aws resources, in your case get access on S3 bucket.
You have samples using iOS sdk here, check the S3TransferUtility-Sample.
S3TransferUtility-Sample (Swift, Objective-C). This is a sample mobile
application that demonstrates how to use the Amazon S3 PreSigned URL
Builder to download / upload files in background. Involved AWS
Services are:
Amazon S3 Amazon
Cognito Identity
Hope it helps!

Amazon Cognito Identity Pool can not be found

I'm making an app that uploads photos to an S3 bucket using the AWS SDK with Amazon Cognito. When I run the function that does this I get an error in the console that says the Identity Pool [the id of my identity pool] can't be found. I've found a few solutions to this issue around the internet. However, none of them seem to work for me. Any ideas?
Assuming you have the correct identity pool id, you may not be connecting to the same region that the pool was created in. The region is the first portion of the identity pool id. Incorrect access policies will not cause this error. I caution against granting blanket access to your resources, if end users will only be reading and writing from s3, only provide that access, don't give them full access.
Make sure your ARN configuration for your Auth and Unauth are the full ARN
Each time I get this issue it is because the IAM role does not have permissions to view the pool OR the pool does not have Unauthenticated Identities
Add AmazonCognitoDeveloperAuthenticatedIdentities OR AmazonCognitoPowerUser to your IAM role
You will need some level of S3 access attached to your policy in the future to access S3.
Also, please add more information to your question. Code used, information about the pool set up, etc. Also, review my answer for Setting up Cognito
Edit:
Per #justderbā€™s comment - removed reference to AmazonS3FullAccess and updated appropriately.

Resources