I was wondering if someone can help me with the following concept in android. I want users to create an account and login on my application, using amazon cognito, to identify their identity. Once a user is logged in this user can download a personal file from Amazon S3.
I implemented the code provided by the AWS Mobile Hub regarding the login and everything seems to work nicely: I was able to create a test account through my app and login without errors. Obviously I cannot test the backend because the S3 part is causing me troubles. The code for the login is very basic and looks like this:
public class AuthenticatorActivity_old extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AWSMobileClient.getInstance().initialize(this, new AWSStartupHandler() {
SignInUI signin = (SignInUI) AWSMobileClient.getInstance().getClient(AuthenticatorActivity_old.this, SignInUI.class);
signin.login(AuthenticatorActivity_old.this, home.class).execute();
}).execute();
}
}
This code works with a bunch of Amazon libraries and the awsconfiguration.json file, and I assume it declares the credentialsProvider
Regarding the personal file that user can download, every user gets their own file in the application's bucket (only one bucket, because I do not want to create a separate bucket for every user), and only this logged in user has the rights to download this file. I have written (adopted and adapted from someone else) an IAM policy which looks like this, which if I understand correctly, only allows users to download a file which has a name [bucket]/cognito/[username]/fixedfilename.jpg :
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": ["arn:aws:s3:::<BUCKET-NAME>"],
"Condition": {"StringLike": {"s3:prefix": ["cognito/<APPLICATION-NAME>/"]}}
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::<BUCKET-NAME>/cognito/<APPLICATION-NAME>/${cognito-identity.amazonaws.com:sub}",
"arn:aws:s3:::<BUCKET-NAME>/cognito/<APPLICATION-NAME>/${cognito-identity.amazonaws.com:sub}/*"
]
}
]
}
I think I am so far so good (have not been able to test it all, so I am not sure). But now comes the tricky part. To download a file from S3 the following steps need to be taken:
- You first create AWS Credentials for accessing S3 using BasicAWSCredentails class
- Pass AWS Credentials to AmazonS3 instance
- You then pass AmazonS3 object to TransferUtility class
So if I understand correctly, the signing in process mentioned before should save AWS Credentials. This credential file is tailored to my bucket and to the credentials of the signed in user.
The AWS Mobile Hub simply tells me to go to https://docs.aws.amazon.com/aws-mobile/latest/developerguide/add-aws-mobile-user-data-storage.html#add-aws-mobile-user-data-storage-app and implement this. Even though I use the exact code provided, I still get the error: AmazonS3 client is required please set using .s3Client(yourClient).
It seems Amazon provides a broken code. Looking at what this AmazonS3client is, AmazonS3 s3 = new AmazonS3Client(credentialsProvider);, I again see the credentialsProvider. The one that is created (I assume) during the login process but which I cannot extract because it is hidden in Amazon's libraries and awsconfiguration.json (again I assume. There are many black boxes here for me).
I get lost in the many many many documentation/tutorials/sample apps provided by Amazon, and it seems they recently did an update making some texts online irrelevant.
Is there anyone who can help me with this???
-------------------------------- UPDATE ---------------------------
some additional information for the people not too familiar with this topic but still wanting to help me out :)
This is the code that is provided by Amazon for the upload to S3 (in combination with the awsconfiguration.json file):
public class YourActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
uploadData();
}
public void uploadData() {
TransferUtility transferUtility =
TransferUtility.builder()
.context(getApplicationContext())
.awsConfiguration(awsConfig)
.build();
TransferObserver uploadObserver =
transferUtility.upload(
"s3Folder/s3Key.txt",
new File("/path/to/file/localFile.txt"));
uploadObserver.setTransferListener(new TransferListener() {
..... some more code
The error occurs in Transferutility.builder, and I expect to change it as follows:
AmazonS3 s3Client = new AmazonS3Client(credentialsProvider);
TransferUtility.builder()
.s3Client(s3Client) <------------this one
.context(getApplicationContext())
.awsConfiguration(AWSMobileClient.getInstance().getConfiguration())
.build();
The point is that I cannot have a S3Client (or can I???) using the credentials of the user login (without having to build the sign in activity from the ground up, rather than using Amazon's code, because that is a bit out of my league!)