amplify-android icon indicating copy to clipboard operation
amplify-android copied to clipboard

Add authentication support for SimpleGraphQLRequest.

Open SureshkumarKV opened this issue 3 years ago • 0 comments

Before opening, please confirm:

Language and Async Model

Java

Amplify Categories

GraphQL API

Gradle script dependencies

// Put output below this line
    implementation 'com.amplifyframework:core:2.1.0'
    implementation 'com.amplifyframework:aws-auth-cognito:2.1.0'
    implementation 'com.amplifyframework:aws-api:2.1.0'

Environment information

# Put output below this line
------------------------------------------------------------
Gradle 7.5.1
------------------------------------------------------------

Build time:   2022-08-05 21:17:56 UTC
Revision:     d1daa0cbf1a0103000b71484e1dbfe096e095918

Kotlin:       1.6.21
Groovy:       3.0.10
Ant:          Apache Ant(TM) version 1.10.11 compiled on July 10 2021
JVM:          11.0.17 (Amazon.com Inc. 11.0.17+8-LTS)
OS:           Mac OS X 12.6.2 x86_64


Please include any relevant guides or documentation you're referencing

https://docs.amplify.aws/lib/graphqlapi/advanced-workflows/q/platform/android/#combining-multiple-operations

Describe the feature request

Although SimpleGraphQLRequest is the Amplify recommended method to work with custom/raw GraphQL queries(https://docs.amplify.aws/lib/graphqlapi/advanced-workflows/q/platform/android/#combining-multiple-operations), it falls short on the critical capability to express the authorization type. As of now, it always uses the default autherization mode for the API and totally ignores the additional authorization modes defined in the API. This is such a fundamental capability that is missing today and gave me a real trouble to work around using OkHttp interceptor(Works only under a specific combination of primary and secondary auth) and I promised my customer to work with Amplify team to solve this.

I had also investigated the Amplify Java SDK source code and saw some implementation which in my opinon has room for improvement. In soing so, it can solve my current problem as well. I have forked the repo and have created a commit at https://github.com/aws-amplify/amplify-android/compare/main...SureshkumarKV:amplify-android:main that will add this capability as well as improve the implementation by avoiding the explicit typeof check against a concrete class and using an interface instead.

I have tested the above implementation, and would like to raise a pull request referring this issue as well. Among all the GraphQL client libraries I tried for Java on Android, I felt Amplify was the easiest to work with, and would sincerely like to contribute to it.

Initialization steps (if applicable)

  1. Install Nothing to do
  2. Configure Use the new class RawAppSyncGraphQLRequest instead of SimpleGraphQLRequest and specify AuthorizationType in the constructor.
  3. Initialize Nothing to do
  4. Output The GraphQL request will be able to use the specified AuthorizationType and successfully complete.

Code Snippet

// Put your code below this line.

// Sample usage. This is tested and is working fine.
Amplify.API.query("sampleappwithissue", new RawAppSyncGraphQLRequest<String>(
                                        "query getByUser {\n" +
                                                "  getByUser\n" +
                                                "}",
                                        new HashMap(),
                                        String.class,
                                        SERIALIZER,
                                        AuthorizationType.AMAZON_COGNITO_USER_POOLS
                                ),
                                data ->  Log.v(TAG, "getByUser success: "+data),
                                error -> Log.e(TAG, "getByUser failed: "+error)
                        );

amplifyconfiguration.json

{
    "UserAgent": "aws-amplify-cli/2.0",
    "Version": "1.0",
    "api": {
        "plugins": {
            "awsAPIPlugin": {
                "sampleappwithissue": {
                    "endpointType": "GraphQL",
                    "endpoint": "https://xxx.appsync-api.ap-south-1.amazonaws.com/graphql",
                    "region": "ap-south-1",
                    "authorizationType": "API_KEY",
                    "apiKey": "da2-xxx"
                }
            }
        }
    },
    "auth": {
        "plugins": {
            "awsCognitoAuthPlugin": {
                "UserAgent": "aws-amplify-cli/0.1.0",
                "Version": "0.1.0",
                "IdentityManager": {
                    "Default": {}
                },
                "CredentialsProvider": {
                    "CognitoIdentity": {
                        "Default": {
                            "PoolId": "ap-south-1:xxx",
                            "Region": "ap-south-1"
                        }
                    }
                },
                "CognitoUserPool": {
                    "Default": {
                        "PoolId": "ap-south-1_xxx",
                        "AppClientId": "xxx",
                        "Region": "ap-south-1"
                    }
                },
                "Auth": {
                    "Default": {
                        "authenticationFlowType": "USER_SRP_AUTH",
                        "socialProviders": [],
                        "usernameAttributes": [],
                        "signupAttributes": [
                            "EMAIL"
                        ],
                        "passwordProtectionSettings": {
                            "passwordPolicyMinLength": 8,
                            "passwordPolicyCharacters": []
                        },
                        "mfaConfiguration": "OFF",
                        "mfaTypes": [
                            "SMS"
                        ],
                        "verificationMechanisms": [
                            "EMAIL"
                        ]
                    }
                },
                "AppSync": {
                    "Default": {
                        "ApiUrl": "https://xxx.appsync-api.ap-south-1.amazonaws.com/graphql",
                        "Region": "ap-south-1",
                        "AuthMode": "API_KEY",
                        "ApiKey": "da2-xxx",
                        "ClientDatabasePrefix": "sampleappwithissue_API_KEY"
                    },
                    "sampleappwithissue_AMAZON_COGNITO_USER_POOLS": {
                        "ApiUrl": "https://xxx.appsync-api.ap-south-1.amazonaws.com/graphql",
                        "Region": "ap-south-1",
                        "AuthMode": "AMAZON_COGNITO_USER_POOLS",
                        "ClientDatabasePrefix": "sampleappwithissue_AMAZON_COGNITO_USER_POOLS"
                    }
                }
            }
        }
    }
}

GraphQL Schema

// Put your schema below this line
# This "input" configures a global authorization rule to enable public access to
# all models in this schema. Learn more about authorization rules here: https://docs.amplify.aws/cli/graphql/authorization-rules
# input AMPLIFY { globalAuthRule: AuthRule = { allow: public } } # FOR TESTING ONLY!

type Query {
    getByKey: Int! @function(name: "resolverFunction-${env}") @aws_api_key
    getByUser: Int! @function(name: "resolverFunction-${env}") @aws_cognito_user_pools
}

Additional information and screenshots

As mentioned before, I have a working solution at https://github.com/aws-amplify/amplify-android/compare/main...SureshkumarKV:amplify-android:main which I would like to raise as a pull request. This code will add the feature as well as improve the code using interfaces.

SureshkumarKV avatar Jan 01 '23 07:01 SureshkumarKV