# Lab9 ![](https://i.imgur.com/vSfRvve.png) ## Lab9-1 : Add authentication to the App 1. Run this command from the root of your app directory * **Replace the name for the project into CP[student ID]** ``` amplify init ``` ![](https://i.imgur.com/jg3367q.png) 2. Run this command from the root of your app directory ``` amplify add auth ``` ![](https://i.imgur.com/XszBqHt.png) 3. Run this command from the root of your app directory ``` amplify push ``` ![](https://i.imgur.com/dFaQAtx.png) 4. Add the following imports to the top of the **app/java/com.cloudprog.example/ui/AuthenticatorActivity.java** ``` java import android.app.Activity; import android.content.Intent; import android.widget.Toast; import com.amazonaws.mobile.auth.core.IdentityManager; import com.amazonaws.mobile.auth.core.DefaultSignInResultHandler; import com.amazonaws.mobile.auth.core.IdentityProvider; import com.amazonaws.mobile.auth.ui.AuthUIConfiguration; import com.amazonaws.mobile.auth.ui.SignInActivity; import com.example.cloudprog.viewmodels.Injection; ``` 5. Edit the **onCreate()** method of **app/java/com.cloudprog.example/ui/AuthenticatorActivity.java** as follows: ``` java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_authenticator); //Todo : Handle cognito signin Injection.initialize(getApplicationContext()); final IdentityManager identityManager = Injection.getAWSService().getIdentityManager(); // Set up the callbacks to handle the authentication response identityManager.login(this, new DefaultSignInResultHandler() { @Override public void onSuccess(Activity activity, IdentityProvider identityProvider) { Toast.makeText(AuthenticatorActivity.this, String.format("Logged in as %s", identityManager.getCachedUserID()), Toast.LENGTH_LONG).show(); // Go to the main activity final Intent intent = new Intent(activity, MainActivity.class) .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); activity.startActivity(intent); activity.finish(); } @Override public boolean onCancel(Activity activity) { return false; } }); // Start the authentication UI AuthUIConfiguration config = new AuthUIConfiguration.Builder() .userPools(true) .build(); SignInActivity.startSignInActivity(this, config); AuthenticatorActivity.this.finish(); } ``` 6. Compile and Run app on Emulator ![](https://i.imgur.com/djEZVGj.png) 7. Create a new account and Confirm your account ![](https://i.imgur.com/QP6i2q3.png) ![](https://i.imgur.com/ZAIiAd1.png) 8. Done! Show TA the validation results of Step 6 and 7 ## Lab9-2 Create a S3 bucket 1. Add the following imports to the top of the **app/java/com.cloudprog.example/ui/MainActivity.java** ``` java //lab9-2 import import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.AccessControlList; import com.amazonaws.services.s3.model.CannedAccessControlList; import com.amazonaws.services.s3.model.CreateBucketRequest; import com.amazonaws.services.s3.model.GroupGrantee; import com.amazonaws.services.s3.model.Permission; import com.amazonaws.auth.CognitoCachingCredentialsProvider; import com.amazonaws.regions.Regions; import android.os.StrictMode; ``` 2. Replace "studentID" with your student ID in **app/res/values/strings.xml** ![](https://i.imgur.com/JPW1Qm9.png) 3. Get Identity pool AWS Credentials * AWS Console > Cognito > Federated Identities > Choose the pool of your app > Sample code in menu bar * Copy the **Identitiy pool ID** ![](https://i.imgur.com/5ycTClk.png) 4. Add the Credentials and the code below to top of **onCreate()** of **app/java/com.cloudprog.example/ui/MainActivity.java** * Remember use your **Identitiy pool ID**. ```java super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //network policy StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); // Initialize the Amazon Cognito credentials provider CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider( getApplicationContext(), "", // Use your Identity pool ID Regions.US_EAST_1 // Region ); // Initialize s3Client final AmazonS3Client s3Client = new AmazonS3Client(credentialsProvider.getCredentials()); ``` 5. Add the code below to **button2.setOnClickListener()** * Use **alt+enter** to import Toast automatically. * If you encounter the error: "**InvalidBucketAclWithObjectOwnership**", replace "s3Client.createBucket(**createBucketRequest**);" into "s3Client.createBucket(**getString(R.string.bucket_name)**);" ``` java button2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Todo : create a s3 bucket & add permission try{ //Check bucket name in app/res/values/string.xml AccessControlList acl = new AccessControlList(); acl.grantPermission(GroupGrantee.AllUsers, Permission.FullControl); CreateBucketRequest createBucketRequest = new CreateBucketRequest(getString(R.string.bucket_name)) .withAccessControlList(acl).withCannedAcl(CannedAccessControlList.PublicReadWrite); s3Client.createBucket(createBucketRequest); Toast.makeText(MainActivity.this, "Create success", Toast.LENGTH_LONG).show(); }catch(Exception e){ e.printStackTrace(); Toast.makeText(MainActivity.this, "Create fail", Toast.LENGTH_LONG).show(); } } }); ``` 6. Add **S3FullAccess** policy to **amplify-CP[student ID]-env-XXXXXXX-authRole** ![](https://i.imgur.com/SJtd3Im.png) 7. Done! Compile, Run, Click button and Check the bucket you created in S3. ![](https://i.imgur.com/hRU2WGc.png) ## Lab9-3 : Upload a Object to S3 Note : * Make sure you have finished lab9-1 and 9-2, or you may get some error in lab9-3. * If camera on virtual device doesn't work, just close the camera and reopen it. 1. Add the following imports to the top of the **app/java/ui/CameraActivity.java** ``` java import com.amazonaws.auth.CognitoCachingCredentialsProvider; import com.amazonaws.regions.Regions; import com.amazonaws.services.s3.AmazonS3Client; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; ``` 2. Add the Credentials and the code below to top of **onCreate()** of **app/java/com.cloudprog.example/ui/CameraActivity.java** * Use **alt+enter** to import StrictMode automatically. * Use your **Identitiy pool ID**. ``` java super.onCreate(savedInstanceState); setContentView(R.layout.activity_camera); this.imageView = (ImageView)this.findViewById(R.id.image_view); //network policy StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); //CredentialsProvider initialization CognitoCachingCredentialsProvider credentialsProvider; credentialsProvider = new CognitoCachingCredentialsProvider( getApplicationContext(), "", // Use your Identity Pool ID Regions.US_EAST_1 // Region ); //s3client initialization final AmazonS3Client s3Client = new AmazonS3Client(credentialsProvider.getCredentials()); ``` 3.Add the code below to **uploadbutton.setOnClickListener()** ``` java uploadButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Todo : Upload a picture to S3 //create a file to write bitmap data File f = new File(getCacheDir(), "test1.jpg"); try { f.createNewFile(); } catch (IOException e) { e.printStackTrace(); } //Convert bitmap to byte array Bitmap bitmap = upload_image; ByteArrayOutputStream bos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 0 /*ignored for PNG*/, bos); byte[] bitmapdata = bos.toByteArray(); //write the bytes in file && send image to s3-bucket FileOutputStream fos = null; try { fos = new FileOutputStream(f); fos.write(bitmapdata); fos.flush(); fos.close(); s3Client.putObject(getString(R.string.bucket_name), "upload_image.jpg", f); Toast.makeText(CameraActivity.this, "Upload success", Toast.LENGTH_LONG).show(); } catch (Exception e) { e.printStackTrace(); Toast.makeText(CameraActivity.this, "Upload fail", Toast.LENGTH_LONG).show(); } } }); ``` 4. Done! Take a picture and upload to S3 * Open camera ![](https://i.imgur.com/iwbF4a6.png) * Upload Image ![](https://i.imgur.com/mz8H3sZ.png) <!-- ## Lab9-4 Third party login 1. Follow the Lab9 slides to setup cognito and FB application 2. Add application ID and protocol_scheme in res/values/strings protocol shceme is fb+app_id ``` java <resources> <string name="app_name">CloudProg</string> <string name="bucket_name">cloudprog-hw3-studentID</string> <string name="queue_name">cloudprog-hw3</string> <string name="facebook_app_id">280920040359127</string> <string name="fb_login_protocol_scheme">fb280920040359127</string> </resources> ``` 3. Add fb activities to AndroidManifest.xml ``` java <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id" /> <activity android:name=".ui.AuthenticatorActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.facebook.FacebookActivity" android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation" android:label="@string/app_name" /> <activity android:name="com.facebook.CustomTabActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="@string/fb_login_protocol_scheme" /> </intent-filter> </activity> <activity android:name=".ui.CameraActivity" /> <activity android:name=".ui.MainActivity"> </activity> </application> ``` 4. Add dependencies to build.gradle ``` java // FB implementation 'com.facebook.android:facebook-login:[5,6)' implementation 'com.amazonaws:aws-android-sdk-auth-facebook:2.15.+@aar' ``` 5. Change codes in AuthenticatorActivity.java ``` java package com.example.cloudprog.ui; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; import com.amazonaws.mobile.config.AWSConfiguration; import com.example.cloudprog.R; import android.app.Activity; import android.content.Intent; import android.widget.Toast; import com.facebook.AccessToken; import com.amazonaws.mobile.auth.facebook.FacebookButton; import com.amazonaws.mobile.auth.facebook.FacebookSignInProvider; import com.amazonaws.mobile.auth.core.IdentityManager; import com.amazonaws.mobile.auth.core.DefaultSignInResultHandler; import com.amazonaws.mobile.auth.core.IdentityProvider; import com.amazonaws.mobile.auth.ui.AuthUIConfiguration; import com.amazonaws.mobile.auth.ui.SignInActivity; import com.example.cloudprog.viewmodels.Injection; import java.util.HashMap; import java.util.Map; public class AuthenticatorActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Todo : Handle cognito signin Injection.initialize(getApplicationContext()); initializeApplication(); final IdentityManager identityAWSManager = Injection.getAWSService().getIdentityManager(); final IdentityManager identityFBManager = IdentityManager.getDefaultIdentityManager(); // FacebookSdk.sdkInitialize(getApplicationContext()); // AppEventsLogger.activateApp(this); // AWS: Set up the callbacks to handle the authentication response identityAWSManager.login(this, new DefaultSignInResultHandler() { @Override public void onSuccess(Activity activity, IdentityProvider identityProvider) { Toast.makeText(AuthenticatorActivity.this, String.format("Logged in as %s", identityAWSManager.getCachedUserID()), Toast.LENGTH_LONG).show(); // Go to the function activity final Intent intent = new Intent(activity, MainActivity.class) //MainActivity .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); activity.startActivity(intent); activity.finish(); } @Override public boolean onCancel(Activity activity) { return false; } } ); // FB: Set up the callbacks to handle the authentication response identityFBManager.login(this, new DefaultSignInResultHandler() { @Override public void onSuccess(Activity activity, IdentityProvider identityProvider) { Map<String, String> logins = new HashMap<String, String>(); logins.put("graph.facebook.com", AccessToken.getCurrentAccessToken().getToken()); AccessToken accessToken = AccessToken.getCurrentAccessToken(); boolean isLoggedIn = accessToken != null && !accessToken.isExpired(); Toast.makeText(AuthenticatorActivity.this, String.format("Signed in with %s", identityProvider.getDisplayName()), Toast.LENGTH_LONG).show(); // Go to the function activity final Intent intent = new Intent(activity, MainActivity.class) .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); activity.startActivity(intent); activity.finish(); } @Override public boolean onCancel(Activity activity) { return false; } } ); // Start the authentication UI AuthUIConfiguration config = new AuthUIConfiguration.Builder() .userPools(true) .signInButton(FacebookButton.class) // Show Facebook button .build(); SignInActivity.startSignInActivity(this, config); AuthenticatorActivity.this.finish(); } private void initializeApplication() { AWSConfiguration awsConfiguration = new AWSConfiguration(getApplicationContext()); // If IdentityManager is not created, create it if(IdentityManager.getDefaultIdentityManager() == null){ IdentityManager identityFBManager = new IdentityManager(getApplicationContext(),awsConfiguration); IdentityManager.setDefaultIdentityManager(identityFBManager); } // Add Facebook as Identity Provider IdentityManager.getDefaultIdentityManager().addSignInProvider( FacebookSignInProvider.class); FacebookSignInProvider.setPermissions("public_profile"); } } ``` 7. Build and run ![](https://i.imgur.com/O8UCFIp.png) ![](https://i.imgur.com/7oln36F.png) -->