0
votes

Greeting all! I have a client application in React that uses an AppSync GraphQL API back end. I have added storage to amplify and can upload files to the storage. When a file is uploaded to the Storage a Lambda function is triggered and I am able to iterate through the contents. I have configured my AWS AppSync API with Cognito User Pool authentication My requirement is I need to make GraphQL mutation from the Lambda Function(written in python) to an AppSync API.

The requirement in Short:

  • Upload an Excel file to the S3 Storage bucket using AppSync
  • Trigger a lambda function(python) on upload to extract contents of the Excel file
  • Send a GraphQL mutation to the AppSync GraphQL from the Lambda function with the contents of the file using the schema as required.

I need to use the Cognito user credentials, as I need to get details of the user making the mutations/

With the last update, I am able to upload content to the Client app, which dumps the Excel sheet in the S3 bucket triggering the Lambda function.

I tried to use "Assume role" but was getting the below error

[ERROR] ClientError: An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:sts::#############:assumed-role/S3Accessfunction/uploadProcessor is not authorized to perform: sts:AssumeRole on resource: AWS:#######################:CognitoIdentityCredentials

1

1 Answers

0
votes

I'm currently using this workaround in python to authorize my AppSync calls with cognito:

First my authorization:

import boto3
import json
from botocore.exceptions import ClientError
import requests
from requests_aws4auth import AWS4Auth

#AppSync variables
s3 = boto3.client('s3')
APPSYNC_API_ENDPOINT_URL = ""
appSyncUnsername = ""
appSyncPassword = ""
appSyncClientID = ""
appSyncUserPool = ""

#create Token for AppSync functionalities using an authorized user
def createToken():
    client = boto3.client('cognito-idp')
    response = client.initiate_auth(
        ClientId=appSyncClientID,
        AuthFlow='USER_PASSWORD_AUTH',
        AuthParameters={
            'USERNAME': appSyncUnsername,
            'PASSWORD': appSyncPassword
        },
        ClientMetadata={
            "UserPoolId" : appSyncUserPool
        }
    )
    token = response["AuthenticationResult"]["AccessToken"]
    return token

And using this token i can then make authorized calls:

def getExample(Id, token):
    session = requests.Session()
    
    Id = "\""+Id+"\""

    query= """query MyQuery {
          getSomething(id: """+Id+""") {
            id
            something
          }
        }"""

    response = session.request(
        url=APPSYNC_API_ENDPOINT_URL,
        method='POST',
        headers={'authorization': token},
        json={'query': query}
        )

    something = response.json()["data"]["getSomething"]["something"]
    return something