diff --git a/.gitignore b/.gitignore index 56cc642..2fc6ec6 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,7 @@ captures/ .idea/assetWizardSettings.xml .idea/dictionaries .idea/libraries +*.idea* # Android Studio 3 in .gitignore file. .idea/caches .idea/modules.xml @@ -83,3 +84,4 @@ lint/generated/ lint/outputs/ lint/tmp/ # lint/reports/ +Lambdas/Lists/src/main/resources/dbProperties.json diff --git a/Lambdas/Lists/pom.xml b/Lambdas/Lists/pom.xml new file mode 100644 index 0000000..9442b49 --- /dev/null +++ b/Lambdas/Lists/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + + groupId + Lists + 1.0-SNAPSHOT + + + + com.amazonaws + aws-lambda-java-core + 1.2.1 + + + com.amazonaws + aws-lambda-java-events + 3.1.0 + + + com.amazonaws + aws-lambda-java-log4j2 + 1.2.0 + + + org.json + json + 20200518 + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + + 1.11 + 1.11 + + \ No newline at end of file diff --git a/Lambdas/Lists/src/main/java/DBConnector.java b/Lambdas/Lists/src/main/java/DBConnector.java new file mode 100644 index 0000000..c4f85b9 --- /dev/null +++ b/Lambdas/Lists/src/main/java/DBConnector.java @@ -0,0 +1,32 @@ +import org.json.JSONObject; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.Properties; + +public class DBConnector { + + Connection connection; + + DBConnector() throws IOException, SQLException { + this(loadProperties("dbProperties.json")); + } + + DBConnector(Properties dbProperties) throws SQLException { + System.out.println(dbProperties); + connection = DriverManager.getConnection(dbProperties.get("url").toString(), dbProperties); + + } + + public static Properties loadProperties(String path) throws IOException { + Properties toReturn = new Properties(); + String propertiesJSONString = Files.readString(Path.of(path)); + JSONObject propertiesJSON = new JSONObject(propertiesJSONString); + propertiesJSON.keys().forEachRemaining(key -> toReturn.setProperty(key, propertiesJSON.get(key).toString())); + return toReturn; + } +} diff --git a/Lambdas/Lists/src/main/java/InputUtils.java b/Lambdas/Lists/src/main/java/InputUtils.java new file mode 100644 index 0000000..0457585 --- /dev/null +++ b/Lambdas/Lists/src/main/java/InputUtils.java @@ -0,0 +1,16 @@ +import java.util.Map; + +public class InputUtils { + public static String getCognitoIDFromBody(Map inputMap) { + System.out.println(inputMap.keySet()); + System.out.println(inputMap.entrySet()); + Map contextMap; + if ((inputMap.get("context") != null) && (inputMap.get("context") instanceof Map)) { + contextMap = ((Map) inputMap.get("context")); + } else { + throw new IllegalArgumentException("The key \"Context\" must exist and be a map"); + } + System.out.println(inputMap.get("context")); + System.out.println(contextMap.get("sub")); + } +} diff --git a/Lambdas/Lists/src/main/java/ListAdder.java b/Lambdas/Lists/src/main/java/ListAdder.java new file mode 100644 index 0000000..413b7db --- /dev/null +++ b/Lambdas/Lists/src/main/java/ListAdder.java @@ -0,0 +1,4 @@ +public class ListAdder { + + +} diff --git a/Lambdas/Lists/src/main/java/ListsPOST.java b/Lambdas/Lists/src/main/java/ListsPOST.java new file mode 100644 index 0000000..a4588a0 --- /dev/null +++ b/Lambdas/Lists/src/main/java/ListsPOST.java @@ -0,0 +1,22 @@ +import java.io.IOException; +import java.sql.SQLException; +import java.util.Map; + +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.RequestHandler; + +public class ListsPOST implements RequestHandler, String>{ + + + public String handleRequest(Map inputMap, Context unfilled) { + String cognitoID = InputUtils.getCognitoIDFromBody(inputMap); + try { + System.out.println(new DBConnector()); + } catch (IOException e) { + e.printStackTrace(); + } catch (SQLException e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/Lambdas/Lists/target/classes/dbProperties.json b/Lambdas/Lists/target/classes/dbProperties.json new file mode 100644 index 0000000..ba1352b --- /dev/null +++ b/Lambdas/Lists/target/classes/dbProperties.json @@ -0,0 +1,5 @@ +{ + "url": "http://aws.com/something", + "user": "aUser", + "password": "aPassword" +} \ No newline at end of file diff --git a/Listify/.gitignore b/Listify/.gitignore index 603b140..49b1255 100644 --- a/Listify/.gitignore +++ b/Listify/.gitignore @@ -12,3 +12,19 @@ /captures .externalNativeBuild .cxx + +#amplify +amplify/\#current-cloud-backend +amplify/.config/local-* +amplify/mock-data +amplify/backend/amplify-meta.json +amplify/backend/awscloudformation +build/ +dist/ +node_modules/ +aws-exports.js +awsconfiguration.json +amplifyconfiguration.json +amplify-build-config.json +amplify-gradle-config.json +amplifytools.xcconfig \ No newline at end of file diff --git a/Listify/.idea/misc.xml b/Listify/.idea/misc.xml index 892046b..fdae1d0 100644 --- a/Listify/.idea/misc.xml +++ b/Listify/.idea/misc.xml @@ -1,6 +1,6 @@ - + diff --git a/Listify/Pipfile b/Listify/Pipfile new file mode 100644 index 0000000..b5846df --- /dev/null +++ b/Listify/Pipfile @@ -0,0 +1,11 @@ +[[source]] +name = "pypi" +url = "https://pypi.org/simple" +verify_ssl = true + +[dev-packages] + +[packages] + +[requires] +python_version = "3.8" diff --git a/Listify/amplify/.config/project-config.json b/Listify/amplify/.config/project-config.json new file mode 100644 index 0000000..a201d20 --- /dev/null +++ b/Listify/amplify/.config/project-config.json @@ -0,0 +1,13 @@ +{ + "projectName": "Listify", + "version": "3.0", + "frontend": "android", + "android": { + "config": { + "ResDir": "app/src/main/res" + } + }, + "providers": [ + "awscloudformation" + ] +} \ No newline at end of file diff --git a/Listify/amplify/backend/auth/listifyf4fad454/listifyf4fad454-cloudformation-template.yml b/Listify/amplify/backend/auth/listifyf4fad454/listifyf4fad454-cloudformation-template.yml new file mode 100644 index 0000000..8560fdb --- /dev/null +++ b/Listify/amplify/backend/auth/listifyf4fad454/listifyf4fad454-cloudformation-template.yml @@ -0,0 +1,396 @@ +AWSTemplateFormatVersion: 2010-09-09 + +Parameters: + env: + Type: String + authRoleArn: + Type: String + unauthRoleArn: + Type: String + + + + + identityPoolName: + Type: String + + allowUnauthenticatedIdentities: + Type: String + + resourceNameTruncated: + Type: String + + userPoolName: + Type: String + + autoVerifiedAttributes: + Type: CommaDelimitedList + + mfaConfiguration: + Type: String + + mfaTypes: + Type: CommaDelimitedList + + smsAuthenticationMessage: + Type: String + + smsVerificationMessage: + Type: String + + emailVerificationSubject: + Type: String + + emailVerificationMessage: + Type: String + + defaultPasswordPolicy: + Type: String + + passwordPolicyMinLength: + Type: Number + + passwordPolicyCharacters: + Type: CommaDelimitedList + + requiredAttributes: + Type: CommaDelimitedList + + userpoolClientGenerateSecret: + Type: String + + userpoolClientRefreshTokenValidity: + Type: Number + + userpoolClientWriteAttributes: + Type: CommaDelimitedList + + userpoolClientReadAttributes: + Type: CommaDelimitedList + + userpoolClientLambdaRole: + Type: String + + userpoolClientSetAttributes: + Type: String + + sharedId: + Type: String + + resourceName: + Type: String + + authSelections: + Type: String + + useDefault: + Type: String + + usernameAttributes: + Type: CommaDelimitedList + + triggers: + Type: String + + userPoolGroupList: + Type: CommaDelimitedList + + serviceName: + Type: String + + parentStack: + Type: String + + permissions: + Type: CommaDelimitedList + + dependsOn: + Type: CommaDelimitedList + +Conditions: + ShouldNotCreateEnvResources: !Equals [ !Ref env, NONE ] + +Resources: + + + # BEGIN SNS ROLE RESOURCE + SNSRole: + # Created to allow the UserPool SMS Config to publish via the Simple Notification Service during MFA Process + Type: AWS::IAM::Role + Properties: + RoleName: !If [ShouldNotCreateEnvResources, 'listiff4fad454_sns-role', !Join ['',[ 'sns', 'f4fad454', !Select [3, !Split ['-', !Ref 'AWS::StackName']], '-', !Ref env]]] + AssumeRolePolicyDocument: + Version: "2012-10-17" + Statement: + - Sid: "" + Effect: "Allow" + Principal: + Service: "cognito-idp.amazonaws.com" + Action: + - "sts:AssumeRole" + Condition: + StringEquals: + sts:ExternalId: listiff4fad454_role_external_id + Policies: + - + PolicyName: listiff4fad454-sns-policy + PolicyDocument: + Version: "2012-10-17" + Statement: + - + Effect: "Allow" + Action: + - "sns:Publish" + Resource: "*" + # BEGIN USER POOL RESOURCES + UserPool: + # Created upon user selection + # Depends on SNS Role for Arn if MFA is enabled + Type: AWS::Cognito::UserPool + UpdateReplacePolicy: Retain + Properties: + UserPoolName: !If [ShouldNotCreateEnvResources, !Ref userPoolName, !Join ['',[!Ref userPoolName, '-', !Ref env]]] + + Schema: + + - + Name: email + Required: true + Mutable: true + + + + + AutoVerifiedAttributes: !Ref autoVerifiedAttributes + + + EmailVerificationMessage: !Ref emailVerificationMessage + EmailVerificationSubject: !Ref emailVerificationSubject + + Policies: + PasswordPolicy: + MinimumLength: !Ref passwordPolicyMinLength + RequireLowercase: false + RequireNumbers: false + RequireSymbols: false + RequireUppercase: false + + UsernameAttributes: !Ref usernameAttributes + + MfaConfiguration: !Ref mfaConfiguration + SmsVerificationMessage: !Ref smsVerificationMessage + SmsConfiguration: + SnsCallerArn: !GetAtt SNSRole.Arn + ExternalId: listiff4fad454_role_external_id + + + + + + + + + + + + # Updating lambda role with permissions to Cognito + + + UserPoolClientWeb: + # Created provide application access to user pool + # Depends on UserPool for ID reference + Type: "AWS::Cognito::UserPoolClient" + Properties: + ClientName: listiff4fad454_app_clientWeb + + RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity + UserPoolId: !Ref UserPool + DependsOn: UserPool + UserPoolClient: + # Created provide application access to user pool + # Depends on UserPool for ID reference + Type: "AWS::Cognito::UserPoolClient" + Properties: + ClientName: listiff4fad454_app_client + + GenerateSecret: !Ref userpoolClientGenerateSecret + RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity + UserPoolId: !Ref UserPool + DependsOn: UserPool + # BEGIN USER POOL LAMBDA RESOURCES + UserPoolClientRole: + # Created to execute Lambda which gets userpool app client config values + Type: 'AWS::IAM::Role' + Properties: + RoleName: !If [ShouldNotCreateEnvResources, !Ref userpoolClientLambdaRole, !Join ['',['upClientLambdaRole', 'f4fad454', !Select [3, !Split ['-', !Ref 'AWS::StackName']], '-', !Ref env]]] + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - 'sts:AssumeRole' + DependsOn: UserPoolClient + UserPoolClientLambda: + # Lambda which gets userpool app client config values + # Depends on UserPool for id + # Depends on UserPoolClientRole for role ARN + Type: 'AWS::Lambda::Function' + Properties: + Code: + ZipFile: !Join + - |+ + - - 'const response = require(''cfn-response'');' + - 'const aws = require(''aws-sdk'');' + - 'const identity = new aws.CognitoIdentityServiceProvider();' + - 'exports.handler = (event, context, callback) => {' + - ' if (event.RequestType == ''Delete'') { ' + - ' response.send(event, context, response.SUCCESS, {})' + - ' }' + - ' if (event.RequestType == ''Update'' || event.RequestType == ''Create'') {' + - ' const params = {' + - ' ClientId: event.ResourceProperties.clientId,' + - ' UserPoolId: event.ResourceProperties.userpoolId' + - ' };' + - ' identity.describeUserPoolClient(params).promise()' + - ' .then((res) => {' + - ' response.send(event, context, response.SUCCESS, {''appSecret'': res.UserPoolClient.ClientSecret});' + - ' })' + - ' .catch((err) => {' + - ' response.send(event, context, response.FAILED, {err});' + - ' });' + - ' }' + - '};' + Handler: index.handler + Runtime: nodejs10.x + Timeout: '300' + Role: !GetAtt + - UserPoolClientRole + - Arn + DependsOn: UserPoolClientRole + UserPoolClientLambdaPolicy: + # Sets userpool policy for the role that executes the Userpool Client Lambda + # Depends on UserPool for Arn + # Marked as depending on UserPoolClientRole for easier to understand CFN sequencing + Type: 'AWS::IAM::Policy' + Properties: + PolicyName: listiff4fad454_userpoolclient_lambda_iam_policy + Roles: + - !Ref UserPoolClientRole + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - 'cognito-idp:DescribeUserPoolClient' + Resource: !GetAtt UserPool.Arn + DependsOn: UserPoolClientLambda + UserPoolClientLogPolicy: + # Sets log policy for the role that executes the Userpool Client Lambda + # Depends on UserPool for Arn + # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing + Type: 'AWS::IAM::Policy' + Properties: + PolicyName: listiff4fad454_userpoolclient_lambda_log_policy + Roles: + - !Ref UserPoolClientRole + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - 'logs:CreateLogGroup' + - 'logs:CreateLogStream' + - 'logs:PutLogEvents' + Resource: !Sub + - arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:* + - { region: !Ref "AWS::Region", account: !Ref "AWS::AccountId", lambda: !Ref UserPoolClientLambda} + DependsOn: UserPoolClientLambdaPolicy + UserPoolClientInputs: + # Values passed to Userpool client Lambda + # Depends on UserPool for Id + # Depends on UserPoolClient for Id + # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing + Type: 'Custom::LambdaCallout' + Properties: + ServiceToken: !GetAtt UserPoolClientLambda.Arn + clientId: !Ref UserPoolClient + userpoolId: !Ref UserPool + DependsOn: UserPoolClientLogPolicy + + + + + + + + # BEGIN IDENTITY POOL RESOURCES + + + IdentityPool: + # Always created + Type: AWS::Cognito::IdentityPool + Properties: + IdentityPoolName: !If [ShouldNotCreateEnvResources, 'listifyf4fad454_identitypool_f4fad454', !Join ['',['listifyf4fad454_identitypool_f4fad454', '__', !Ref env]]] + + CognitoIdentityProviders: + - ClientId: !Ref UserPoolClient + ProviderName: !Sub + - cognito-idp.${region}.amazonaws.com/${client} + - { region: !Ref "AWS::Region", client: !Ref UserPool} + - ClientId: !Ref UserPoolClientWeb + ProviderName: !Sub + - cognito-idp.${region}.amazonaws.com/${client} + - { region: !Ref "AWS::Region", client: !Ref UserPool} + + AllowUnauthenticatedIdentities: !Ref allowUnauthenticatedIdentities + + + DependsOn: UserPoolClientInputs + + + IdentityPoolRoleMap: + # Created to map Auth and Unauth roles to the identity pool + # Depends on Identity Pool for ID ref + Type: AWS::Cognito::IdentityPoolRoleAttachment + Properties: + IdentityPoolId: !Ref IdentityPool + Roles: + unauthenticated: !Ref unauthRoleArn + authenticated: !Ref authRoleArn + DependsOn: IdentityPool + + +Outputs : + + IdentityPoolId: + Value: !Ref 'IdentityPool' + Description: Id for the identity pool + IdentityPoolName: + Value: !GetAtt IdentityPool.Name + + + + + UserPoolId: + Value: !Ref 'UserPool' + Description: Id for the user pool + UserPoolName: + Value: !Ref userPoolName + AppClientIDWeb: + Value: !Ref 'UserPoolClientWeb' + Description: The user pool app client id for web + AppClientID: + Value: !Ref 'UserPoolClient' + Description: The user pool app client id + AppClientSecret: + Value: !GetAtt UserPoolClientInputs.appSecret + + + + + + + diff --git a/Listify/amplify/backend/auth/listifyf4fad454/parameters.json b/Listify/amplify/backend/auth/listifyf4fad454/parameters.json new file mode 100644 index 0000000..8c6f1d6 --- /dev/null +++ b/Listify/amplify/backend/auth/listifyf4fad454/parameters.json @@ -0,0 +1,60 @@ +{ + "identityPoolName": "listifyf4fad454_identitypool_f4fad454", + "allowUnauthenticatedIdentities": true, + "resourceNameTruncated": "listiff4fad454", + "userPoolName": "listifyf4fad454_userpool_f4fad454", + "autoVerifiedAttributes": [ + "email" + ], + "mfaConfiguration": "OFF", + "mfaTypes": [ + "SMS Text Message" + ], + "smsAuthenticationMessage": "Your authentication code is {####}", + "smsVerificationMessage": "Your verification code is {####}", + "emailVerificationSubject": "Your verification code", + "emailVerificationMessage": "Your verification code is {####}", + "defaultPasswordPolicy": false, + "passwordPolicyMinLength": 8, + "passwordPolicyCharacters": [], + "requiredAttributes": [ + "email" + ], + "userpoolClientGenerateSecret": true, + "userpoolClientRefreshTokenValidity": 30, + "userpoolClientWriteAttributes": [ + "email" + ], + "userpoolClientReadAttributes": [ + "email" + ], + "userpoolClientLambdaRole": "listiff4fad454_userpoolclient_lambda_role", + "userpoolClientSetAttributes": false, + "sharedId": "f4fad454", + "resourceName": "listifyf4fad454", + "authSelections": "identityPoolAndUserPool", + "authRoleArn": { + "Fn::GetAtt": [ + "AuthRole", + "Arn" + ] + }, + "unauthRoleArn": { + "Fn::GetAtt": [ + "UnauthRole", + "Arn" + ] + }, + "useDefault": "default", + "usernameAttributes": [ + "email" + ], + "triggers": "{}", + "userPoolGroupList": [], + "serviceName": "Cognito", + "parentStack": { + "Ref": "AWS::StackId" + }, + "permissions": [], + "dependsOn": [] +} \ No newline at end of file diff --git a/Listify/amplify/backend/backend-config.json b/Listify/amplify/backend/backend-config.json new file mode 100644 index 0000000..771cac6 --- /dev/null +++ b/Listify/amplify/backend/backend-config.json @@ -0,0 +1,12 @@ +{ + "auth": { + "listifyf4fad454": { + "service": "Cognito", + "providerPlugin": "awscloudformation", + "dependsOn": [], + "customAuth": false + } + }, + "function": {}, + "api": {} +} \ No newline at end of file diff --git a/Listify/amplify/backend/tags.json b/Listify/amplify/backend/tags.json new file mode 100644 index 0000000..b9321d7 --- /dev/null +++ b/Listify/amplify/backend/tags.json @@ -0,0 +1,10 @@ +[ + { + "Key": "user:Stack", + "Value": "{project-env}" + }, + { + "Key": "user:Application", + "Value": "{project-name}" + } +] \ No newline at end of file diff --git a/Listify/amplify/cli.json b/Listify/amplify/cli.json new file mode 100644 index 0000000..876a6e2 --- /dev/null +++ b/Listify/amplify/cli.json @@ -0,0 +1,3 @@ +{ + "features": {} +} \ No newline at end of file diff --git a/Listify/amplify/team-provider-info.json b/Listify/amplify/team-provider-info.json new file mode 100644 index 0000000..2ff66cd --- /dev/null +++ b/Listify/amplify/team-provider-info.json @@ -0,0 +1,20 @@ +{ + "dev": { + "awscloudformation": { + "AuthRoleName": "amplify-listify-dev-134836-authRole", + "UnauthRoleArn": "arn:aws:iam::569815541706:role/amplify-listify-dev-134836-unauthRole", + "AuthRoleArn": "arn:aws:iam::569815541706:role/amplify-listify-dev-134836-authRole", + "Region": "us-east-2", + "DeploymentBucketName": "amplify-listify-dev-134836-deployment", + "UnauthRoleName": "amplify-listify-dev-134836-unauthRole", + "StackName": "amplify-listify-dev-134836", + "StackId": "arn:aws:cloudformation:us-east-2:569815541706:stack/amplify-listify-dev-134836/5980b520-faa0-11ea-a89c-0650659cf0f8", + "AmplifyAppId": "dbnznhwtkbqz6" + }, + "categories": { + "auth": { + "listifyf4fad454": {} + } + } + } +} \ No newline at end of file diff --git a/Listify/app/build.gradle b/Listify/app/build.gradle index f56ecf1..4e13596 100644 --- a/Listify/app/build.gradle +++ b/Listify/app/build.gradle @@ -14,6 +14,13 @@ android { testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } + compileOptions { + // Support for Java 8 features + coreLibraryDesugaringEnabled true + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + buildTypes { release { minifyEnabled false @@ -34,5 +41,8 @@ dependencies { testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' + implementation 'com.amplifyframework:core:1.3.2' + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10' + implementation 'com.amplifyframework:aws-auth-cognito:1.3.2' } \ No newline at end of file diff --git a/Listify/app/src/main/AndroidManifest.xml b/Listify/app/src/main/AndroidManifest.xml index b459a6e..c26ea17 100644 --- a/Listify/app/src/main/AndroidManifest.xml +++ b/Listify/app/src/main/AndroidManifest.xml @@ -3,6 +3,7 @@ package="com.example.listify"> setAuthSession(result), + error -> setAuthError(error) + ); + throwIfAuthError(); + } + + public AWSCognitoAuthSession getAuthSession() throws AuthException { + if (authSession == null) { + fetchAuthSession(); + } + + return authSession; + } + + public String getUserToken() { + return authSession.getUserPoolTokens().getValue().getIdToken(); + } + + + public void setAuthSession(AuthSession toSet) { + authSession = (AWSCognitoAuthSession) toSet; + waiting = false; + } + + public void setAuthError(AuthException newError) { + authError = newError; + waiting = false; + } + + public void throwIfAuthError() throws AuthException{ + while (waiting); + if (authError == null) { + return; + } + AuthException toThrow = authError; + authError = null; + throw toThrow; + } + + public void setAuthSignUpResult(AuthSignUpResult toSet) { + authSignUpResult = toSet; + } + + public void setAuthSignInResult(AuthSignInResult toSet) { + authSignInResult = toSet; + waiting = false; + } + + public void startSignUp(String email, String password) throws AuthException { + this.email = email; + this.password = password; + waiting = true; + Amplify.Auth.signUp( + email, + password, + AuthSignUpOptions.builder().build(), + result -> setAuthSignUpResult(result), + error -> setAuthError(error) + ); + throwIfAuthError(); + + } + + public void confirmSignUp(String confirmationCode) throws AuthException { + waiting = true; + Amplify.Auth.confirmSignUp( + email, + confirmationCode, + result -> setAuthSignUpResult(result), + error -> setAuthError(error) + ); + throwIfAuthError(); + } + + public void signIn(String email, String password) throws AuthException{ + this.email = email; + this.password = password; + waiting = true; + Amplify.Auth.signIn( + email, + password, + result -> setAuthSignInResult(result), + error -> setAuthError(error) + ); + throwIfAuthError(); + } + + + + +} diff --git a/Listify/app/src/main/java/com/example/listify/Listify.java b/Listify/app/src/main/java/com/example/listify/Listify.java new file mode 100644 index 0000000..20e6d11 --- /dev/null +++ b/Listify/app/src/main/java/com/example/listify/Listify.java @@ -0,0 +1,20 @@ +package com.example.listify; + +import android.util.Log; +import com.amplifyframework.AmplifyException; +import com.amplifyframework.auth.cognito.AWSCognitoAuthPlugin; +import com.amplifyframework.core.Amplify; + +public class Listify extends android.app.Application { + public void onCreate() { + super.onCreate(); + + try { + Amplify.addPlugin(new AWSCognitoAuthPlugin()); + Amplify.configure(getApplicationContext()); + Log.i("MyAmplifyApp", "Initialized Amplify"); + } catch (AmplifyException error) { + Log.e("MyAmplifyApp", "Could not initialize Amplify", error); + } + } +} diff --git a/Listify/app/src/main/java/com/example/listify/MainActivity.java b/Listify/app/src/main/java/com/example/listify/MainActivity.java index b300e26..c13d07e 100644 --- a/Listify/app/src/main/java/com/example/listify/MainActivity.java +++ b/Listify/app/src/main/java/com/example/listify/MainActivity.java @@ -1,9 +1,15 @@ package com.example.listify; import android.os.Bundle; +import android.util.Log; import android.view.View; import android.view.Menu; +import com.amazonaws.mobileconnectors.cognitoauth.Auth; +import com.amplifyframework.auth.AuthException; +import com.amplifyframework.auth.AuthUserAttributeKey; +import com.amplifyframework.auth.options.AuthSignUpOptions; +import com.amplifyframework.core.Amplify; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.snackbar.Snackbar; import com.google.android.material.navigation.NavigationView; @@ -22,6 +28,26 @@ public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + //------------------------------Auth Testing---------------------------------------------// + + AuthManager authManager = new AuthManager(); + try { + authManager.signIn("merzn@purdue.edu", "Password123"); + Log.i("Authentication", authManager.getAuthSession().toString()); + Log.i("Token", authManager.getAuthSession().getUserPoolTokens().getValue().getIdToken()); + } catch (AuthException e) { + Log.i("Authentication", "Login failed. User probably needs to register. Exact error: " + e.getMessage()); + try { + authManager.startSignUp("merzn@purdue.edu", "Password123"); + authManager.confirmSignUp("######"); + } catch (AuthException signUpError) { + Log.e("Authentication", "SignUp error: " + signUpError.getMessage()); + } + } + + + + //------------------------------------------------------------------------------------------// setContentView(R.layout.activity_main); Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); diff --git a/Tooling/EndpointSetup.sh b/Tooling/EndpointSetup.sh new file mode 100644 index 0000000..6f2bf00 --- /dev/null +++ b/Tooling/EndpointSetup.sh @@ -0,0 +1,71 @@ +#!/bin/bash +#Base script from: https://github.com/NMerz/DoctorsNote/blob/master/AWS%20Setup/Lambda-GatewayInitialization.sh + +#NOTE: This has been tested and works; however, the apigateway does not properly show as a trigger in AWS's web UI +#NOTE2: This assumes that the root Gateway and Lambda role have been set up previously (one-time setup) and their values are stored in the constants below + +#constants +APIID=datoh7woc9 #rest-api-id is tied to the apigateway while resource-id seems tied to the specific url extension +ROOTRESOURCEID=6xrzhzidxh #gateway root should have a consistent resource id which will serve as parent for many apis +LAMBDAROLE=arn:aws:iam::569815541706:role/LambdaBasic +LANGUAGE=java11 +DEPLOYSTAGE=Development + +DEBUGFILE=/dev/null + +echo -n "Please enter function/endpoint name: " +read functionName +echo -n "Please enter method(GET, POST, etc.): " +read method + +jarPath=$(find .. -name "${functionName}.jar") +if [[ "$jarPath" == "" ]]; then + echo "Unable to find file ${functionName}.jar" >&2 + exit 1 +fi +functionPath=${jarPath%/${functionName}.jar} +zipPath=${functionPath}.zip + +zip ${zipPath} ${jarPath} + +RAWLAMBDA=$(aws lambda create-function --function-name ${functionName}${method} --zip-file fileb://${zipPath} --runtime ${LANGUAGE} --role ${LAMBDAROLE} --handler ${functionName}${method}.lambda_handler 2>${DEBUGFILE}) + +if [[ $? -ne 0 ]]; then + echo "Unable to create Lamba" >&2 + exit 1 +fi + +LAMBDAARN=$(echo $RAWLAMBDA | head -n 3 | tail -n 1 | cut -d \" -f 8) + +echo ${LAMBDAARN} > ${DEBUGFILE} + +RAWRESOURCEID=$(aws apigateway create-resource --rest-api-id ${APIID} --parent-id ${ROOTRESOURCEID} --path-part ${functionName} 2>${DEBUGFILE}) + +if [[ $? -ne 0 ]]; then + echo "Unable to create resource." > ${DEBUGFILE} + RAWRESOURCEID=$(aws apigateway get-resources --rest-api-id datoh7woc9 --query "items[?pathPart==\`${functionName}\`].{id:id}" | head -n 3 | tail -n 1) + if [[ $RAWRESOURCEID == "[]" ]]; then + echo "Unable to create or find API Gateway resource." >&2 + exit 1 + fi +fi + +RESOURCEID=$(echo ${RAWRESOURCEID} | head -n 2 | tail -n 1 | cut -d \" -f 4) + +echo ${RESOURCEID} > ${DEBUGFILE} + +aws apigateway put-method --rest-api-id ${APIID} --resource-id ${RESOURCEID} --http-method ${method} --authorization-type COGNITO_USER_POOLS --authorizer-id awt4cs --api-key-required > ${DEBUGFILE} + + + +aws apigateway put-integration --rest-api-id ${APIID} --resource-id ${RESOURCEID} --http-method ${method} --type AWS --integration-http-method POST --uri arn:aws:apigateway:us-east-2:lambda:path/2015-03-31/functions/${LAMBDAARN}/invocations --request-templates 'file://body_and_auth_mapping.json' > ${DEBUGFILE} + +aws lambda add-permission --function-name ${functionName}${method} --statement-id ${functionName}API --action lambda:InvokeFunction --principal apigateway.amazonaws.com > ${DEBUGFILE} + +aws apigateway put-method-response --rest-api-id ${APIID} --resource-id ${RESOURCEID} --http-method ${method} --status-code 200 > ${DEBUGFILE} + +aws apigateway put-integration-response --rest-api-id ${APIID} --resource-id ${RESOURCEID} --http-method ${method} --status-code 200 --selection-pattern "" > ${DEBUGFILE} + +aws apigateway create-deployment --rest-api-id ${APIID} --stage-name ${DEPLOYSTAGE} --description "Deployment by creation script for function ${functionName}${method}" > ${DEBUGFILE} + + diff --git a/Tooling/body_and_auth_mapping.json b/Tooling/body_and_auth_mapping.json new file mode 100644 index 0000000..600bc4b --- /dev/null +++ b/Tooling/body_and_auth_mapping.json @@ -0,0 +1,3 @@ +{ + "application/json": "{\"body\": \"$input.json('$')\",\"context\" : {\"sub\" : \"$context.authorizer.claims.sub\",\"email\" : \"$context.authorizer.claims.email\"}}" +} \ No newline at end of file