From 63d06b46c250ecba53b9548bd4ecc8f30c363370 Mon Sep 17 00:00:00 2001 From: NMerz Date: Sat, 19 Sep 2020 15:01:21 -0400 Subject: [PATCH 01/14] auth skeleton Include Amplify SDK, test basic auth functions, and setup framework for internal, synchronous interface. --- Listify/.gitignore | 16 + Listify/.idea/misc.xml | 2 +- Listify/amplify/.config/project-config.json | 13 + ...istifyf4fad454-cloudformation-template.yml | 396 ++++++++++++++++++ .../auth/listifyf4fad454/parameters.json | 60 +++ Listify/amplify/backend/backend-config.json | 10 + Listify/amplify/backend/tags.json | 10 + Listify/amplify/cli.json | 3 + Listify/amplify/team-provider-info.json | 20 + Listify/app/build.gradle | 10 + Listify/app/src/main/AndroidManifest.xml | 1 + .../java/com/example/listify/AuthManager.java | 88 ++++ .../java/com/example/listify/Listify.java | 20 + .../com/example/listify/MainActivity.java | 10 + 14 files changed, 658 insertions(+), 1 deletion(-) create mode 100644 Listify/amplify/.config/project-config.json create mode 100644 Listify/amplify/backend/auth/listifyf4fad454/listifyf4fad454-cloudformation-template.yml create mode 100644 Listify/amplify/backend/auth/listifyf4fad454/parameters.json create mode 100644 Listify/amplify/backend/backend-config.json create mode 100644 Listify/amplify/backend/tags.json create mode 100644 Listify/amplify/cli.json create mode 100644 Listify/amplify/team-provider-info.json create mode 100644 Listify/app/src/main/java/com/example/listify/AuthManager.java create mode 100644 Listify/app/src/main/java/com/example/listify/Listify.java 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/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..95c418b --- /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..1118f10 --- /dev/null +++ b/Listify/amplify/backend/auth/listifyf4fad454/parameters.json @@ -0,0 +1,60 @@ +{ + "identityPoolName": "listifyf4fad454_identitypool_f4fad454", + "allowUnauthenticatedIdentities": false, + "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..8b34cae --- /dev/null +++ b/Listify/amplify/backend/backend-config.json @@ -0,0 +1,10 @@ +{ + "auth": { + "listifyf4fad454": { + "service": "Cognito", + "providerPlugin": "awscloudformation", + "dependsOn": [], + "customAuth": false + } + } +} \ 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 7672ac7..3c75eac 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 void setAuthSession(AuthSession toSet) { + authSession = toSet; + } + + 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 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) { + Amplify.Auth.confirmSignUp( + email, + confirmationCode, + result -> Log.i("AuthQuickstart", result.isSignUpComplete() ? "Confirm signUp succeeded" : "Confirm sign up not complete"), + error -> Log.e("AuthQuickstart", error.toString()) + ); + } + + public void signIn(String email, String password) { + Amplify.Auth.signIn( + email, + password, + result -> Log.i("AuthQuickstart", result.isSignInComplete() ? "Sign in succeeded" : "Sign in not complete"), + error -> Log.e("AuthQuickstart", error.toString()) + ); + } + + + + +} 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 f63de5b..3145a02 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,13 @@ package com.example.listify; import android.os.Bundle; +import android.util.Log; import android.view.View; import android.view.Menu; +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; @@ -23,6 +27,12 @@ public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + //------------------------------Auth Testing---------------------------------------------// + + + + + //------------------------------------------------------------------------------------------// setContentView(R.layout.activity_main); Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); From 2b1ecbadef925832c333602e8c8c786f6ccfbaf7 Mon Sep 17 00:00:00 2001 From: NMerz Date: Sun, 20 Sep 2020 10:38:08 -0400 Subject: [PATCH 02/14] Finish conversion to synchronized methods Finished setting callbacks and made waiting volatile so cached value is not used across threads. --- .../java/com/example/listify/AuthManager.java | 37 ++++++++++++++----- .../com/example/listify/MainActivity.java | 15 ++++++++ 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/Listify/app/src/main/java/com/example/listify/AuthManager.java b/Listify/app/src/main/java/com/example/listify/AuthManager.java index 0a0c443..5ac6563 100644 --- a/Listify/app/src/main/java/com/example/listify/AuthManager.java +++ b/Listify/app/src/main/java/com/example/listify/AuthManager.java @@ -4,19 +4,21 @@ import android.util.Log; import com.amplifyframework.auth.AuthException; import com.amplifyframework.auth.AuthSession; import com.amplifyframework.auth.options.AuthSignUpOptions; +import com.amplifyframework.auth.result.AuthSignInResult; import com.amplifyframework.auth.result.AuthSignUpResult; import com.amplifyframework.core.Amplify; public class AuthManager { AuthSession authSession = null; AuthSignUpResult authSignUpResult = null; + AuthSignInResult authSignInResult = null; AuthException authError = null; String email = null; String password = null; - boolean waiting = false; + volatile boolean waiting = false; - public void fetchAuthSession() throws AuthException { + void fetchAuthSession() throws AuthException { waiting = true; Amplify.Auth.fetchAuthSession( result -> setAuthSession(result), @@ -25,9 +27,15 @@ public class AuthManager { throwIfAuthError(); } + public AuthSession getAuthSession() throws AuthException { + fetchAuthSession(); + return authSession; + } + public void setAuthSession(AuthSession toSet) { authSession = toSet; + waiting = false; } public void setAuthError(AuthException newError) { @@ -49,7 +57,12 @@ public class AuthManager { authSignUpResult = toSet; } - public void startSignup(String email, String password) throws AuthException { + 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; @@ -64,22 +77,28 @@ public class AuthManager { } - public void confirmSignUp(String confirmationCode) { + public void confirmSignUp(String confirmationCode) throws AuthException { + waiting = true; Amplify.Auth.confirmSignUp( email, confirmationCode, - result -> Log.i("AuthQuickstart", result.isSignUpComplete() ? "Confirm signUp succeeded" : "Confirm sign up not complete"), - error -> Log.e("AuthQuickstart", error.toString()) + result -> setAuthSignUpResult(result), + error -> setAuthError(error) ); + throwIfAuthError(); } - public void signIn(String email, String password) { + public void signIn(String email, String password) throws AuthException{ + this.email = email; + this.password = password; + waiting = true; Amplify.Auth.signIn( email, password, - result -> Log.i("AuthQuickstart", result.isSignInComplete() ? "Sign in succeeded" : "Sign in not complete"), - error -> Log.e("AuthQuickstart", error.toString()) + result -> setAuthSignInResult(result), + error -> setAuthError(error) ); + throwIfAuthError(); } 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 3145a02..12e7312 100644 --- a/Listify/app/src/main/java/com/example/listify/MainActivity.java +++ b/Listify/app/src/main/java/com/example/listify/MainActivity.java @@ -5,6 +5,8 @@ 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; @@ -29,6 +31,19 @@ public class MainActivity extends AppCompatActivity { super.onCreate(savedInstanceState); //------------------------------Auth Testing---------------------------------------------// + AuthManager authManager = new AuthManager(); + try { + authManager.signIn("merzn@purdue.edu", "Password123"); + Log.i("Authentication", authManager.getAuthSession().toString()); + } 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()); + } + } From f576307e0a112ef2bdee7b650e2ba580d9288473 Mon Sep 17 00:00:00 2001 From: NMerz Date: Sun, 20 Sep 2020 16:26:13 -0400 Subject: [PATCH 03/14] Set up initial Lambda sturucture with Cognito Create demo Lambda/Gateway pair with Cognito integration --- .gitignore | 1 + Lambdas/Lists/pom.xml | 28 +++++++++++++ Lambdas/Lists/src/main/java/ListAdd.java | 22 ++++++++++ Listify/Pipfile | 11 +++++ ...istifyf4fad454-cloudformation-template.yml | 2 +- .../auth/listifyf4fad454/parameters.json | 2 +- Listify/amplify/backend/backend-config.json | 4 +- .../java/com/example/listify/AuthManager.java | 17 +++++--- .../com/example/listify/MainActivity.java | 1 + Tooling/EndpointSetup.sh | 42 +++++++++++++++++++ Tooling/aws_method_request_passthrough.json | 7 ++++ 11 files changed, 129 insertions(+), 8 deletions(-) create mode 100644 Lambdas/Lists/pom.xml create mode 100644 Lambdas/Lists/src/main/java/ListAdd.java create mode 100644 Listify/Pipfile create mode 100644 Tooling/EndpointSetup.sh create mode 100644 Tooling/aws_method_request_passthrough.json diff --git a/.gitignore b/.gitignore index 56cc642..f0a7210 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 diff --git a/Lambdas/Lists/pom.xml b/Lambdas/Lists/pom.xml new file mode 100644 index 0000000..2c6ea85 --- /dev/null +++ b/Lambdas/Lists/pom.xml @@ -0,0 +1,28 @@ + + + 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 + + + \ No newline at end of file diff --git a/Lambdas/Lists/src/main/java/ListAdd.java b/Lambdas/Lists/src/main/java/ListAdd.java new file mode 100644 index 0000000..fe0354b --- /dev/null +++ b/Lambdas/Lists/src/main/java/ListAdd.java @@ -0,0 +1,22 @@ +import java.util.Map; + +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.RequestHandler; + +public class ListAdd implements RequestHandler, String>{ + + + public String handleRequest(Map inputMap, Context unfilled) { + 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")); + return null; + } +} 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/backend/auth/listifyf4fad454/listifyf4fad454-cloudformation-template.yml b/Listify/amplify/backend/auth/listifyf4fad454/listifyf4fad454-cloudformation-template.yml index 95c418b..8560fdb 100644 --- a/Listify/amplify/backend/auth/listifyf4fad454/listifyf4fad454-cloudformation-template.yml +++ b/Listify/amplify/backend/auth/listifyf4fad454/listifyf4fad454-cloudformation-template.yml @@ -94,7 +94,7 @@ Parameters: userPoolGroupList: Type: CommaDelimitedList - + serviceName: Type: String diff --git a/Listify/amplify/backend/auth/listifyf4fad454/parameters.json b/Listify/amplify/backend/auth/listifyf4fad454/parameters.json index 1118f10..8c6f1d6 100644 --- a/Listify/amplify/backend/auth/listifyf4fad454/parameters.json +++ b/Listify/amplify/backend/auth/listifyf4fad454/parameters.json @@ -1,6 +1,6 @@ { "identityPoolName": "listifyf4fad454_identitypool_f4fad454", - "allowUnauthenticatedIdentities": false, + "allowUnauthenticatedIdentities": true, "resourceNameTruncated": "listiff4fad454", "userPoolName": "listifyf4fad454_userpool_f4fad454", "autoVerifiedAttributes": [ diff --git a/Listify/amplify/backend/backend-config.json b/Listify/amplify/backend/backend-config.json index 8b34cae..771cac6 100644 --- a/Listify/amplify/backend/backend-config.json +++ b/Listify/amplify/backend/backend-config.json @@ -6,5 +6,7 @@ "dependsOn": [], "customAuth": false } - } + }, + "function": {}, + "api": {} } \ No newline at end of file diff --git a/Listify/app/src/main/java/com/example/listify/AuthManager.java b/Listify/app/src/main/java/com/example/listify/AuthManager.java index 5ac6563..637cb3c 100644 --- a/Listify/app/src/main/java/com/example/listify/AuthManager.java +++ b/Listify/app/src/main/java/com/example/listify/AuthManager.java @@ -1,15 +1,15 @@ package com.example.listify; -import android.util.Log; import com.amplifyframework.auth.AuthException; import com.amplifyframework.auth.AuthSession; +import com.amplifyframework.auth.cognito.AWSCognitoAuthSession; import com.amplifyframework.auth.options.AuthSignUpOptions; import com.amplifyframework.auth.result.AuthSignInResult; import com.amplifyframework.auth.result.AuthSignUpResult; import com.amplifyframework.core.Amplify; public class AuthManager { - AuthSession authSession = null; + AWSCognitoAuthSession authSession = null; AuthSignUpResult authSignUpResult = null; AuthSignInResult authSignInResult = null; AuthException authError = null; @@ -27,14 +27,21 @@ public class AuthManager { throwIfAuthError(); } - public AuthSession getAuthSession() throws AuthException { - fetchAuthSession(); + 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 = toSet; + authSession = (AWSCognitoAuthSession) toSet; waiting = false; } 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 12e7312..a24c00a 100644 --- a/Listify/app/src/main/java/com/example/listify/MainActivity.java +++ b/Listify/app/src/main/java/com/example/listify/MainActivity.java @@ -35,6 +35,7 @@ public class MainActivity extends AppCompatActivity { 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 { diff --git a/Tooling/EndpointSetup.sh b/Tooling/EndpointSetup.sh new file mode 100644 index 0000000..4588a3f --- /dev/null +++ b/Tooling/EndpointSetup.sh @@ -0,0 +1,42 @@ +#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 store 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 name: " +read functionName +echo -n "Please enter path to zip of function code: " +read functionPath +echo -n "Please enter url extension: " +read partName + +LAMBDAARN=$(aws lambda create-function --function-name ${functionName} --zip-file fileb://${functionPath} --runtime ${LANGUAGE} --role ${LAMBDAROLE} --handler ${functionName}.lambda_handler | head -n 3 | tail -n 1 | cut -d \" -f 4) + +echo ${LAMBDAARN} > ${DEBUGFILE} + +RESOURCEID=$(aws apigateway create-resource --rest-api-id ${APIID} --parent-id ${ROOTRESOURCEID} --path-part ${partName} | 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 POST --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 POST --type AWS --integration-http-method POST --uri arn:aws:apigateway:us-east-2:lambda:path/2015-03-31/functions/${LAMBDAARN}/invocations > ${DEBUGFILE} + +aws lambda add-permission --function-name ${functionName} --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 POST --status-code 200 > ${DEBUGFILE} + +aws apigateway put-integration-response --rest-api-id ${APIID} --resource-id ${RESOURCEID} --http-method POST --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}" > ${DEBUGFILE} + + diff --git a/Tooling/aws_method_request_passthrough.json b/Tooling/aws_method_request_passthrough.json new file mode 100644 index 0000000..efea7ce --- /dev/null +++ b/Tooling/aws_method_request_passthrough.json @@ -0,0 +1,7 @@ +{ + "body": $input.json('$'), + "context" : { + "sub" : "$context.authorizer.claims.sub", + "email" : "$context.authorizer.claims.email" + } +} \ No newline at end of file From 74eeb2a09dbc85be8efa1cf0a6e4327873b5c596 Mon Sep 17 00:00:00 2001 From: NMerz Date: Sun, 20 Sep 2020 23:33:36 -0400 Subject: [PATCH 04/14] Start Lambda connection infrastructure --- .gitignore | 1 + Lambdas/Lists/pom.xml | 14 ++++++++ Lambdas/Lists/src/main/java/DBConnector.java | 32 +++++++++++++++++++ Lambdas/Lists/src/main/java/ListAdd.java | 9 ++++++ Lambdas/Lists/src/main/java/ListAdder.java | 4 +++ .../Lists/target/classes/dbProperties.json | 5 +++ 6 files changed, 65 insertions(+) create mode 100644 Lambdas/Lists/src/main/java/DBConnector.java create mode 100644 Lambdas/Lists/src/main/java/ListAdder.java create mode 100644 Lambdas/Lists/target/classes/dbProperties.json diff --git a/.gitignore b/.gitignore index f0a7210..2fc6ec6 100644 --- a/.gitignore +++ b/.gitignore @@ -84,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 index 2c6ea85..9442b49 100644 --- a/Lambdas/Lists/pom.xml +++ b/Lambdas/Lists/pom.xml @@ -24,5 +24,19 @@ 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/ListAdd.java b/Lambdas/Lists/src/main/java/ListAdd.java index fe0354b..d5a698b 100644 --- a/Lambdas/Lists/src/main/java/ListAdd.java +++ b/Lambdas/Lists/src/main/java/ListAdd.java @@ -1,3 +1,5 @@ +import java.io.IOException; +import java.sql.SQLException; import java.util.Map; import com.amazonaws.services.lambda.runtime.Context; @@ -17,6 +19,13 @@ public class ListAdd implements RequestHandler, String>{ } System.out.println(inputMap.get("context")); System.out.println(contextMap.get("sub")); + try { + System.out.println(new DBConnector()); + } catch (IOException e) { + e.printStackTrace(); + } catch (SQLException e) { + e.printStackTrace(); + } return null; } } 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/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 From 34ed7358c5df0c2242525d9c7568063315d50b01 Mon Sep 17 00:00:00 2001 From: NMerz Date: Sun, 20 Sep 2020 23:33:55 -0400 Subject: [PATCH 05/14] Port tooling and increase durability --- Tooling/EndpointSetup.sh | 63 ++++++++++++++------- Tooling/aws_method_request_passthrough.json | 7 --- Tooling/body_and_auth_mapping.json | 3 + 3 files changed, 47 insertions(+), 26 deletions(-) delete mode 100644 Tooling/aws_method_request_passthrough.json create mode 100644 Tooling/body_and_auth_mapping.json diff --git a/Tooling/EndpointSetup.sh b/Tooling/EndpointSetup.sh index 4588a3f..81c2d08 100644 --- a/Tooling/EndpointSetup.sh +++ b/Tooling/EndpointSetup.sh @@ -1,7 +1,8 @@ +#!/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 store in the constants below +#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 @@ -12,31 +13,55 @@ DEPLOYSTAGE=Development DEBUGFILE=/dev/null -echo -n "Please enter function name: " +echo -n "Please enter function/endpoint name: " read functionName -echo -n "Please enter path to zip of function code: " -read functionPath -echo -n "Please enter url extension: " -read partName +echo -n "Please enter method(GET, POST, etc.): " +read method -LAMBDAARN=$(aws lambda create-function --function-name ${functionName} --zip-file fileb://${functionPath} --runtime ${LANGUAGE} --role ${LAMBDAROLE} --handler ${functionName}.lambda_handler | head -n 3 | tail -n 1 | cut -d \" -f 4) +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}.lambda_handler) + +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} -RESOURCEID=$(aws apigateway create-resource --rest-api-id ${APIID} --parent-id ${ROOTRESOURCEID} --path-part ${partName} | head -n 2 | tail -n 1 | cut -d \" -f 4) +RAWRESOURCEID=$(aws apigateway create-resource --rest-api-id ${APIID} --parent-id ${ROOTRESOURCEID} --path-part ${functionName}) + +if [[ $? -ne 0 ]]; then + echo "Unable to create Resource. This needs to be handled at some future point" >&2 + exit 1 +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 POST --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 POST --type AWS --integration-http-method POST --uri arn:aws:apigateway:us-east-2:lambda:path/2015-03-31/functions/${LAMBDAARN}/invocations > ${DEBUGFILE} - -aws lambda add-permission --function-name ${functionName} --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 POST --status-code 200 > ${DEBUGFILE} - -aws apigateway put-integration-response --rest-api-id ${APIID} --resource-id ${RESOURCEID} --http-method POST --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}" > ${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/aws_method_request_passthrough.json b/Tooling/aws_method_request_passthrough.json deleted file mode 100644 index efea7ce..0000000 --- a/Tooling/aws_method_request_passthrough.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "body": $input.json('$'), - "context" : { - "sub" : "$context.authorizer.claims.sub", - "email" : "$context.authorizer.claims.email" - } -} \ No newline at end of file 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 From c948444f731ec6cbc1aa21a1766bd662a32ef58e Mon Sep 17 00:00:00 2001 From: Clayton Wilson Date: Thu, 24 Sep 2020 13:03:40 -0400 Subject: [PATCH 06/14] Search button layout --- Listify/.idea/codeStyles/Project.xml | 116 ++++++++++++++++++ Listify/.idea/gradle.xml | 12 +- Listify/.idea/jarRepositories.xml | 30 +++++ Listify/app/src/main/AndroidManifest.xml | 23 ++++ .../com/example/listify/First2Fragment.java | 34 +++++ .../com/example/listify/FirstFragment.java | 34 +++++ .../com/example/listify/MainActivity.java | 46 ++++--- .../com/example/listify/SearchResults.java | 53 ++++++++ .../example/listify/SearchableActivity.java | 49 ++++++++ .../com/example/listify/Second2Fragment.java | 34 +++++ .../com/example/listify/SecondFragment.java | 34 +++++ .../app/src/main/res/anim/enter_from_left.xml | 8 ++ .../src/main/res/anim/enter_from_right.xml | 8 ++ .../app/src/main/res/anim/exit_from_left.xml | 8 ++ .../app/src/main/res/anim/exit_from_right.xml | 8 ++ .../app/src/main/res/layout/activity_main.xml | 7 +- .../res/layout/activity_search_results.xml | 54 ++++++++ .../main/res/layout/activity_searchable.xml | 33 +++++ .../app/src/main/res/layout/app_bar_home.xml | 46 +++++++ .../src/main/res/layout/content_search.xml | 6 + .../res/layout/content_search_results.xml | 6 + .../src/main/res/layout/fragment_first.xml | 28 +++++ .../src/main/res/layout/fragment_first2.xml | 28 +++++ .../src/main/res/layout/fragment_second.xml | 27 ++++ .../src/main/res/layout/fragment_second2.xml | 27 ++++ Listify/app/src/main/res/menu/main.xml | 9 +- .../app/src/main/res/navigation/nav_graph.xml | 48 ++++++++ Listify/app/src/main/res/values/strings.xml | 15 +++ Listify/app/src/main/res/xml/searchable.xml | 5 + ListifyFrontend/.idea/.gitignore | 2 + .../.idea/caches/build_file_checksums.ser | Bin 0 -> 539 bytes ListifyFrontend/.idea/codeStyles/Project.xml | 116 ++++++++++++++++++ ListifyFrontend/.idea/gradle.xml | 4 + ...__androidx_activity_activity_1_0_0_aar.xml | 13 ++ ...droidx_annotation_annotation_1_1_0_jar.xml | 13 ++ ...androidx_appcompat_appcompat_1_2_0_aar.xml | 16 +++ ...ppcompat_appcompat_resources_1_2_0_aar.xml | 13 ++ ...droidx_arch_core_core_common_2_1_0_jar.xml | 11 ++ ...roidx_arch_core_core_runtime_2_1_0_aar.xml | 13 ++ ...inflater_asynclayoutinflater_1_0_0_aar.xml | 13 ++ ...__androidx_cardview_cardview_1_0_0_aar.xml | 13 ++ ...droidx_collection_collection_1_1_0_jar.xml | 11 ++ ...raintlayout_constraintlayout_1_1_3_aar.xml | 11 ++ ...yout_constraintlayout_solver_1_1_3_jar.xml | 9 ++ ...atorlayout_coordinatorlayout_1_0_0_aar.xml | 16 +++ .../Gradle__androidx_core_core_1_3_0_aar.xml | 16 +++ ..._cursoradapter_cursoradapter_1_0_0_aar.xml | 13 ++ ...droidx_customview_customview_1_0_0_aar.xml | 13 ++ ...dx_documentfile_documentfile_1_0_0_aar.xml | 13 ++ ...dx_drawerlayout_drawerlayout_1_0_0_aar.xml | 16 +++ ...__androidx_fragment_fragment_1_1_0_aar.xml | 16 +++ ...dx_interpolator_interpolator_1_0_0_aar.xml | 13 ++ ...egacy_legacy_support_core_ui_1_0_0_aar.xml | 13 ++ ...cy_legacy_support_core_utils_1_0_0_aar.xml | 13 ++ ...idx_legacy_legacy_support_v4_1_0_0_aar.xml | 13 ++ ...x_lifecycle_lifecycle_common_2_1_0_jar.xml | 11 ++ ...fecycle_lifecycle_extensions_2_1_0_aar.xml | 13 ++ ...lifecycle_lifecycle_livedata_2_1_0_aar.xml | 13 ++ ...ycle_lifecycle_livedata_core_2_1_0_aar.xml | 13 ++ ..._lifecycle_lifecycle_process_2_1_0_aar.xml | 13 ++ ..._lifecycle_lifecycle_runtime_2_1_0_aar.xml | 13 ++ ..._lifecycle_lifecycle_service_2_1_0_aar.xml | 13 ++ ...ifecycle_lifecycle_viewmodel_2_1_0_aar.xml | 13 ++ ...adle__androidx_loader_loader_1_0_0_aar.xml | 13 ++ ...anager_localbroadcastmanager_1_0_0_aar.xml | 13 ++ ...Gradle__androidx_media_media_1_0_0_aar.xml | 16 +++ ...navigation_navigation_common_2_1_0_aar.xml | 13 ++ ...vigation_navigation_fragment_2_1_0_aar.xml | 13 ++ ...avigation_navigation_runtime_2_1_0_aar.xml | 13 ++ ...idx_navigation_navigation_ui_2_1_0_aar.xml | 13 ++ ...Gradle__androidx_print_print_1_0_0_aar.xml | 16 +++ ...dx_recyclerview_recyclerview_1_0_0_aar.xml | 16 +++ ...droidx_savedstate_savedstate_1_0_0_aar.xml | 13 ++ ...panelayout_slidingpanelayout_1_0_0_aar.xml | 13 ++ ...eshlayout_swiperefreshlayout_1_0_0_aar.xml | 16 +++ .../Gradle__androidx_test_core_1_3_0_aar.xml | 15 +++ ..._test_espresso_espresso_core_3_3_0_aar.xml | 15 +++ ...sso_espresso_idling_resource_3_3_0_aar.xml | 15 +++ ...dle__androidx_test_ext_junit_1_1_2_aar.xml | 15 +++ ...radle__androidx_test_monitor_1_3_0_aar.xml | 15 +++ ...Gradle__androidx_test_runner_1_3_0_aar.xml | 15 +++ ...droidx_transition_transition_1_0_1_aar.xml | 16 +++ ...ectordrawable_vectordrawable_1_1_0_aar.xml | 13 ++ ...able_vectordrawable_animated_1_1_0_aar.xml | 13 ++ ...rcelable_versionedparcelable_1_1_0_aar.xml | 13 ++ ...androidx_viewpager_viewpager_1_0_0_aar.xml | 13 ++ ...le_android_material_material_1_0_0_aar.xml | 14 +++ ..._google_code_findbugs_jsr305_2_0_1_jar.xml | 9 ++ ...dle__com_squareup_javawriter_2_1_1_jar.xml | 13 ++ ...radle__javax_inject_javax_inject_1_jar.xml | 13 ++ .../Gradle__junit_junit_4_12_jar.xml | 13 ++ ...le__org_hamcrest_hamcrest_core_1_3_jar.xml | 13 ++ ..._hamcrest_hamcrest_integration_1_3_jar.xml | 13 ++ ..._org_hamcrest_hamcrest_library_1_3_jar.xml | 13 ++ ListifyFrontend/.idea/misc.xml | 6 + ListifyFrontend/.idea/navEditor.xml | 55 +++++++++ 96 files changed, 1819 insertions(+), 20 deletions(-) create mode 100644 Listify/.idea/codeStyles/Project.xml create mode 100644 Listify/.idea/jarRepositories.xml create mode 100644 Listify/app/src/main/java/com/example/listify/First2Fragment.java create mode 100644 Listify/app/src/main/java/com/example/listify/FirstFragment.java create mode 100644 Listify/app/src/main/java/com/example/listify/SearchResults.java create mode 100644 Listify/app/src/main/java/com/example/listify/SearchableActivity.java create mode 100644 Listify/app/src/main/java/com/example/listify/Second2Fragment.java create mode 100644 Listify/app/src/main/java/com/example/listify/SecondFragment.java create mode 100644 Listify/app/src/main/res/anim/enter_from_left.xml create mode 100644 Listify/app/src/main/res/anim/enter_from_right.xml create mode 100644 Listify/app/src/main/res/anim/exit_from_left.xml create mode 100644 Listify/app/src/main/res/anim/exit_from_right.xml create mode 100644 Listify/app/src/main/res/layout/activity_search_results.xml create mode 100644 Listify/app/src/main/res/layout/activity_searchable.xml create mode 100644 Listify/app/src/main/res/layout/app_bar_home.xml create mode 100644 Listify/app/src/main/res/layout/content_search.xml create mode 100644 Listify/app/src/main/res/layout/content_search_results.xml create mode 100644 Listify/app/src/main/res/layout/fragment_first.xml create mode 100644 Listify/app/src/main/res/layout/fragment_first2.xml create mode 100644 Listify/app/src/main/res/layout/fragment_second.xml create mode 100644 Listify/app/src/main/res/layout/fragment_second2.xml create mode 100644 Listify/app/src/main/res/navigation/nav_graph.xml create mode 100644 Listify/app/src/main/res/xml/searchable.xml create mode 100644 ListifyFrontend/.idea/.gitignore create mode 100644 ListifyFrontend/.idea/caches/build_file_checksums.ser create mode 100644 ListifyFrontend/.idea/codeStyles/Project.xml create mode 100644 ListifyFrontend/.idea/gradle.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_activity_activity_1_0_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_annotation_annotation_1_1_0_jar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_appcompat_appcompat_1_2_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_appcompat_appcompat_resources_1_2_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_arch_core_core_common_2_1_0_jar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_arch_core_core_runtime_2_1_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_asynclayoutinflater_asynclayoutinflater_1_0_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_cardview_cardview_1_0_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_collection_collection_1_1_0_jar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_constraintlayout_constraintlayout_1_1_3_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_constraintlayout_constraintlayout_solver_1_1_3_jar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_coordinatorlayout_coordinatorlayout_1_0_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_core_core_1_3_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_cursoradapter_cursoradapter_1_0_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_customview_customview_1_0_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_documentfile_documentfile_1_0_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_drawerlayout_drawerlayout_1_0_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_fragment_fragment_1_1_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_interpolator_interpolator_1_0_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_legacy_legacy_support_core_ui_1_0_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_legacy_legacy_support_core_utils_1_0_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_legacy_legacy_support_v4_1_0_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_common_2_1_0_jar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_extensions_2_1_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_livedata_2_1_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_livedata_core_2_1_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_process_2_1_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_runtime_2_1_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_service_2_1_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_viewmodel_2_1_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_loader_loader_1_0_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_localbroadcastmanager_localbroadcastmanager_1_0_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_media_media_1_0_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_navigation_navigation_common_2_1_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_navigation_navigation_fragment_2_1_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_navigation_navigation_runtime_2_1_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_navigation_navigation_ui_2_1_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_print_print_1_0_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_recyclerview_recyclerview_1_0_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_savedstate_savedstate_1_0_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_slidingpanelayout_slidingpanelayout_1_0_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_swiperefreshlayout_swiperefreshlayout_1_0_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_test_core_1_3_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_test_espresso_espresso_core_3_3_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_test_espresso_espresso_idling_resource_3_3_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_test_ext_junit_1_1_2_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_test_monitor_1_3_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_test_runner_1_3_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_transition_transition_1_0_1_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_vectordrawable_vectordrawable_1_1_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_vectordrawable_vectordrawable_animated_1_1_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_versionedparcelable_versionedparcelable_1_1_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__androidx_viewpager_viewpager_1_0_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__com_google_android_material_material_1_0_0_aar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__com_google_code_findbugs_jsr305_2_0_1_jar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__com_squareup_javawriter_2_1_1_jar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__javax_inject_javax_inject_1_jar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__junit_junit_4_12_jar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3_jar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__org_hamcrest_hamcrest_integration_1_3_jar.xml create mode 100644 ListifyFrontend/.idea/libraries/Gradle__org_hamcrest_hamcrest_library_1_3_jar.xml create mode 100644 ListifyFrontend/.idea/misc.xml create mode 100644 ListifyFrontend/.idea/navEditor.xml diff --git a/Listify/.idea/codeStyles/Project.xml b/Listify/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/Listify/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/Listify/.idea/gradle.xml b/Listify/.idea/gradle.xml index 7b5f1f4..5cd135a 100644 --- a/Listify/.idea/gradle.xml +++ b/Listify/.idea/gradle.xml @@ -1,13 +1,19 @@ + diff --git a/Listify/.idea/jarRepositories.xml b/Listify/.idea/jarRepositories.xml new file mode 100644 index 0000000..0380d8d --- /dev/null +++ b/Listify/.idea/jarRepositories.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Listify/app/src/main/AndroidManifest.xml b/Listify/app/src/main/AndroidManifest.xml index 7672ac7..49bc532 100644 --- a/Listify/app/src/main/AndroidManifest.xml +++ b/Listify/app/src/main/AndroidManifest.xml @@ -18,7 +18,30 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/Listify/app/src/main/java/com/example/listify/First2Fragment.java b/Listify/app/src/main/java/com/example/listify/First2Fragment.java new file mode 100644 index 0000000..3ca48ef --- /dev/null +++ b/Listify/app/src/main/java/com/example/listify/First2Fragment.java @@ -0,0 +1,34 @@ +package com.example.listify; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.navigation.fragment.NavHostFragment; + +public class First2Fragment extends Fragment { + + @Override + public View onCreateView( + LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState + ) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_first2, container, false); + } + + public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + view.findViewById(R.id.button_first).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + NavHostFragment.findNavController(First2Fragment.this) + .navigate(R.id.action_First2Fragment_to_Second2Fragment); + } + }); + } +} \ No newline at end of file diff --git a/Listify/app/src/main/java/com/example/listify/FirstFragment.java b/Listify/app/src/main/java/com/example/listify/FirstFragment.java new file mode 100644 index 0000000..653c343 --- /dev/null +++ b/Listify/app/src/main/java/com/example/listify/FirstFragment.java @@ -0,0 +1,34 @@ +package com.example.listify; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.navigation.fragment.NavHostFragment; + +public class FirstFragment extends Fragment { + + @Override + public View onCreateView( + LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState + ) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_first, container, false); + } + + public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + view.findViewById(R.id.button_first).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + NavHostFragment.findNavController(FirstFragment.this) + .navigate(R.id.action_FirstFragment_to_SecondFragment); + } + }); + } +} \ No newline at end of file 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 f63de5b..525325a 100644 --- a/Listify/app/src/main/java/com/example/listify/MainActivity.java +++ b/Listify/app/src/main/java/com/example/listify/MainActivity.java @@ -1,5 +1,7 @@ package com.example.listify; +import android.app.Activity; +import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.Menu; @@ -15,6 +17,7 @@ import androidx.navigation.ui.NavigationUI; import androidx.drawerlayout.widget.DrawerLayout; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; +import android.widget.ImageButton; public class MainActivity extends AppCompatActivity { @@ -26,14 +29,14 @@ public class MainActivity extends AppCompatActivity { setContentView(R.layout.activity_main); Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); - FloatingActionButton fab = findViewById(R.id.fab); - fab.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) - .setAction("Action", null).show(); - } - }); +// FloatingActionButton fab = findViewById(R.id.fab); +// fab.setOnClickListener(new View.OnClickListener() { +// @Override +// public void onClick(View view) { +// Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) +// .setAction("Action", null).show(); +// } +// }); DrawerLayout drawer = findViewById(R.id.drawer_layout); NavigationView navigationView = findViewById(R.id.nav_view); // Passing each menu ID as a set of Ids because each @@ -45,14 +48,29 @@ public class MainActivity extends AppCompatActivity { NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment); NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration); NavigationUI.setupWithNavController(navigationView, navController); + + // Handle search button click + ImageButton searchButton = (ImageButton) findViewById(R.id.searchButton); + searchButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { +// onSearchRequested(); + Intent intent = new Intent(MainActivity.this, SearchResults.class); + startActivity(intent); + overridePendingTransition(R.anim.enter_from_left, R.anim.exit_from_left); + + + } + }); } - @Override - public boolean onCreateOptionsMenu(Menu menu) { - // Inflate the menu; this adds items to the action bar if it is present. - getMenuInflater().inflate(R.menu.main, menu); - return true; - } +// @Override +// public boolean onCreateOptionsMenu(Menu menu) { +// // Inflate the menu; this adds items to the action bar if it is present. +// getMenuInflater().inflate(R.menu.main, menu); +// return true; +// } + @Override public boolean onSupportNavigateUp() { diff --git a/Listify/app/src/main/java/com/example/listify/SearchResults.java b/Listify/app/src/main/java/com/example/listify/SearchResults.java new file mode 100644 index 0000000..0bff7d5 --- /dev/null +++ b/Listify/app/src/main/java/com/example/listify/SearchResults.java @@ -0,0 +1,53 @@ +package com.example.listify; + +import android.content.Intent; +import android.os.Bundle; + +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.google.android.material.snackbar.Snackbar; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; + +import android.view.View; +import android.widget.ImageButton; +import android.widget.SearchView; + +public class SearchResults extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_search_results); + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + ImageButton backButton = (ImageButton) findViewById(R.id.backToHomeButton); + backButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + overridePendingTransition(R.anim.enter_from_right, R.anim.exit_from_right); + } + }); + + + SearchView searchView = (SearchView) findViewById(R.id.searchBar); +// searchView.requestFocus(); + searchView.setIconified(false); +// FloatingActionButton fab = findViewById(R.id.fab); +// fab.setOnClickListener(new View.OnClickListener() { +// @Override +// public void onClick(View view) { +// Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) +// .setAction("Action", null).show(); +// } +// }); + } + + @Override + public void onBackPressed() { + super.onBackPressed(); + overridePendingTransition(R.anim.enter_from_right, R.anim.exit_from_right); + } +} \ No newline at end of file diff --git a/Listify/app/src/main/java/com/example/listify/SearchableActivity.java b/Listify/app/src/main/java/com/example/listify/SearchableActivity.java new file mode 100644 index 0000000..40e1527 --- /dev/null +++ b/Listify/app/src/main/java/com/example/listify/SearchableActivity.java @@ -0,0 +1,49 @@ +package com.example.listify; + +//import android.app.ListActivity; +import android.app.SearchManager; +import android.content.Intent; +import android.os.Bundle; + +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.google.android.material.snackbar.Snackbar; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; + +import android.view.View; +import android.widget.ImageButton; + +public class SearchableActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_searchable); + +// Toolbar toolbar = findViewById(R.id.toolbar); +// setSupportActionBar(toolbar); +// +// FloatingActionButton fab = findViewById(R.id.fab); +// fab.setOnClickListener(new View.OnClickListener() { +// @Override +// public void onClick(View view) { +// Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) +// .setAction("Action", null).show(); +// } +// }); + + // Get search query and send it to doSearch() + Intent intent = getIntent(); + if (Intent.ACTION_SEARCH.equals(intent.getAction())) { + String query = intent.getStringExtra(SearchManager.QUERY); + doSearch(query); + } + } + + // TODO: Implement database search and return results + // https://developer.android.com/guide/topics/search/search-dialog#SearchingYourData + public void doSearch(String query) { + return; + } +} \ No newline at end of file diff --git a/Listify/app/src/main/java/com/example/listify/Second2Fragment.java b/Listify/app/src/main/java/com/example/listify/Second2Fragment.java new file mode 100644 index 0000000..6e17432 --- /dev/null +++ b/Listify/app/src/main/java/com/example/listify/Second2Fragment.java @@ -0,0 +1,34 @@ +package com.example.listify; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.navigation.fragment.NavHostFragment; + +public class Second2Fragment extends Fragment { + + @Override + public View onCreateView( + LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState + ) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_second2, container, false); + } + + public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + view.findViewById(R.id.button_second).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + NavHostFragment.findNavController(Second2Fragment.this) + .navigate(R.id.action_Second2Fragment_to_First2Fragment); + } + }); + } +} \ No newline at end of file diff --git a/Listify/app/src/main/java/com/example/listify/SecondFragment.java b/Listify/app/src/main/java/com/example/listify/SecondFragment.java new file mode 100644 index 0000000..609a036 --- /dev/null +++ b/Listify/app/src/main/java/com/example/listify/SecondFragment.java @@ -0,0 +1,34 @@ +package com.example.listify; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.navigation.fragment.NavHostFragment; + +public class SecondFragment extends Fragment { + + @Override + public View onCreateView( + LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState + ) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_second, container, false); + } + + public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + view.findViewById(R.id.button_second).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + NavHostFragment.findNavController(SecondFragment.this) + .navigate(R.id.action_SecondFragment_to_FirstFragment); + } + }); + } +} \ No newline at end of file diff --git a/Listify/app/src/main/res/anim/enter_from_left.xml b/Listify/app/src/main/res/anim/enter_from_left.xml new file mode 100644 index 0000000..0840bbb --- /dev/null +++ b/Listify/app/src/main/res/anim/enter_from_left.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/Listify/app/src/main/res/anim/enter_from_right.xml b/Listify/app/src/main/res/anim/enter_from_right.xml new file mode 100644 index 0000000..d974522 --- /dev/null +++ b/Listify/app/src/main/res/anim/enter_from_right.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/Listify/app/src/main/res/anim/exit_from_left.xml b/Listify/app/src/main/res/anim/exit_from_left.xml new file mode 100644 index 0000000..f58d54d --- /dev/null +++ b/Listify/app/src/main/res/anim/exit_from_left.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/Listify/app/src/main/res/anim/exit_from_right.xml b/Listify/app/src/main/res/anim/exit_from_right.xml new file mode 100644 index 0000000..2134fe7 --- /dev/null +++ b/Listify/app/src/main/res/anim/exit_from_right.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/Listify/app/src/main/res/layout/activity_main.xml b/Listify/app/src/main/res/layout/activity_main.xml index 01e2945..1bcfaa6 100644 --- a/Listify/app/src/main/res/layout/activity_main.xml +++ b/Listify/app/src/main/res/layout/activity_main.xml @@ -8,8 +8,13 @@ android:fitsSystemWindows="true" tools:openDrawer="start"> + + + + + diff --git a/Listify/app/src/main/res/layout/activity_search_results.xml b/Listify/app/src/main/res/layout/activity_search_results.xml new file mode 100644 index 0000000..c40ef26 --- /dev/null +++ b/Listify/app/src/main/res/layout/activity_search_results.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Listify/app/src/main/res/layout/activity_searchable.xml b/Listify/app/src/main/res/layout/activity_searchable.xml new file mode 100644 index 0000000..bf5cae6 --- /dev/null +++ b/Listify/app/src/main/res/layout/activity_searchable.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Listify/app/src/main/res/layout/app_bar_home.xml b/Listify/app/src/main/res/layout/app_bar_home.xml new file mode 100644 index 0000000..41992e1 --- /dev/null +++ b/Listify/app/src/main/res/layout/app_bar_home.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Listify/app/src/main/res/layout/content_search.xml b/Listify/app/src/main/res/layout/content_search.xml new file mode 100644 index 0000000..3691469 --- /dev/null +++ b/Listify/app/src/main/res/layout/content_search.xml @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/Listify/app/src/main/res/layout/content_search_results.xml b/Listify/app/src/main/res/layout/content_search_results.xml new file mode 100644 index 0000000..3691469 --- /dev/null +++ b/Listify/app/src/main/res/layout/content_search_results.xml @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/Listify/app/src/main/res/layout/fragment_first.xml b/Listify/app/src/main/res/layout/fragment_first.xml new file mode 100644 index 0000000..fb44a3d --- /dev/null +++ b/Listify/app/src/main/res/layout/fragment_first.xml @@ -0,0 +1,28 @@ + + + + + +