Open Tedsterh opened 2 years ago
Hello @Tedsterh, apologies for the delay in a response. Thank you for providing us the reproduction steps. On diving deep, I am curious about the code added to the lambda function as this will enable me to replicate a identical application.(Ref: Added a lambda function with a call to search the model
)
module.exports = {
signRequest,
};
async function signRequest(query, operationName, variable) {
const req = new AWS.HttpRequest(appsyncUrl, region);
req.method = "POST";
req.path = "/graphql";
req.headers.host = endpoint;
req.headers["Content-Type"] = "application/json";
req.body = JSON.stringify({
query: query,
operationName: operationName,
variables: variable,
});
const signer = new AWS.Signers.V4(req, "appsync", true);
signer.addAuthorization(AWS.config.credentials, AWS.util.date.getDate());
const data = await new Promise((resolve, reject) => {
const httpRequest = https.request({ ...req, host: endpoint }, (result) => {
let data = "";
result.on("data", (chunk) => {
data += chunk;
});
result.on("end", () => {
resolve(JSON.parse(data.toString()));
});
});
httpRequest.write(req.body);
httpRequest.end();
});
return data;
}
I have placed this inside a lambda layer that is provided to the function, I then simply call it with signRequest(query, "QueryName", {paramKey: paramValue})
this works for all my calls except aggregation
query Total {
income: searchTransactions (filter: {type: {eq: "income"}}, aggregates: {field: amount, name: "TotalIncome", type: sum}) {
aggregateItems {
result {
... on SearchableAggregateScalarResult {
__typename
value
}
}
name
}
}
expenses: searchTransactions(filter: {type: {eq: "expense"}}, aggregates: {field: amount, name: "TotalIncome", type: sum}) {
aggregateItems {
result {
... on SearchableAggregateScalarResult {
__typename
value
}
}
name
}
}
}
When trying to use the sum is when I get the message: 'Unauthorized to run aggregation on field: amount'
@Tedsterh Thank you for providing me the requested information. I was able to replicate the error in my Lambda function as well.
marking this as bug.
Notes: was able to run queries without the aggregates and run filters as well.
example of query that fails:
searchTransactions(aggregates: {field: amount, name: "id", type: sum}) {
aggregateItems {
name
result {
... on SearchableAggregateScalarResult {
__typename
value
}
}
}
}
but runs the following.
searchTransactions {
items {
amount
}
aggregateItems {
name
result {
... on SearchableAggregateScalarResult {
__typename
value
}
}
}
}
@Tedsterh did you find any temporary solution?
I am also facing the same problem
I found this bug in search auth resolver when adding lambda function with add api permission that return vtl before set allowedAggFields. In file Query.searchTransactions.req.vtl check allowed aggregate field
...
$util.error("Unauthorized to run aggregation on field: ${aggItem.field}", "Unauthorized")
...
but when auth type IAM found so it instant return out of vtl before set stash $allowedAggFields (example lambda function name lambdaEcho-dev in your case is in file Query.searchTransactions.auth.1.req.vtl )
...
#if( $util.authType() == "IAM Authorization" )
#set( $adminRoles = ["lambdaEcho-dev"] )
#foreach( $adminRole in $adminRoles )
#if( $ctx.identity.userArn.contains($adminRole) && $ctx.identity.userArn != $ctx.stash.authRole && $ctx.identity.userArn != $ctx.stash.unauthRole )
#return($util.toJson({})) #### THIS LINE SHOULD PUT TO STASH $allowedAggFields BEFORE RETURN #####
#end
#end
...
should be like this
...
#set( $totalFields = ["id","type","amount","transactionId","startedAt","completedAt","createdAt","updatedAt"] )
#set( $allowedAggFields = ["createdAt","updatedAt","id","type","amount","transactionId","startedAt","completedAt"] )
...
#if( $util.authType() == "IAM Authorization" )
#set( $adminRoles = ["lambdaEcho-dev"] )
#foreach( $adminRole in $adminRoles )
#if( $ctx.identity.userArn.contains($adminRole) && $ctx.identity.userArn != $ctx.stash.authRole && $ctx.identity.userArn != $ctx.stash.unauthRole )
#set( $allowedAggFields = $totalFields )
$util.qr($ctx.stash.put("allowedAggFields", $allowedAggFields))
#return($util.toJson({}))
#end
#end
#if( !$isAuthorized )
#if( $ctx.identity.userArn == $ctx.stash.authRole )
#set( $isAuthorized = true )
#set( $allowedAggFields = $totalFields )
#end
#end
#end
...
or workaround solution extend resolver ie. Query.searchTransactions.auth.2.req.vtl like below
#set( $allowedAggFields = ["createdAt","updatedAt","id","type","amount","transactionId","startedAt","completedAt"] ) ## replace your aggregate fields
#if( $util.authType() == "IAM Authorization" )
#set( $adminRoles = ["lambdaEcho-dev"] ) ## replace your lambda function names
#foreach( $adminRole in $adminRoles )
#if( $ctx.identity.userArn.contains($adminRole) && $ctx.identity.userArn != $ctx.stash.authRole && $ctx.identity.userArn != $ctx.stash.unauthRole )
$util.qr($ctx.stash.put("allowedAggFields", $allowedAggFields))
#return($util.toJson({}))
#end
#end
#end
$util.toJson({"version":"2018-05-29","payload":{}})
@iprach is correct.
Find the Appsync Resolver Querysearch{YOUR_TABLE_NAME}auth0Function
and add $util.qr($ctx.stash.put("allowedAggFields", $allowedAggFields))
right before the return statement as a workaround.
Can someone point to the piece of code where these resolvers are generated so we can write a bugfix?
Before opening, please confirm:
How did you install the Amplify CLI?
npm install -g @aws-amplify/cli
If applicable, what version of Node.js are you using?
v16.14.0
Amplify CLI Version
7.6.26
What operating system are you using?
Mac
Did you make any manual changes to the cloud resources managed by Amplify? Please describe the changes made.
No manual changes made
Amplify Categories
api
Amplify Commands
push
Describe the bug
I am unable to use aggregateItems when searching a model from inside a lambda function, the same lambda function is able to call and return the fields that are being denied by the aggregation.
These are the auth rules on my model
The iam users should have full access permissions, there are no other auth rules on any of the fields.
This is the error returned
But there are no other rules on the model that could be denying it.
Expected behavior
I should be able to get a sum from the searching aggregation without being denied.
Reproduction steps
I created a model with the
@searchable
directiveAdded a lambda function with a call to search the model
I gave the lambda function permission to query and mutate from the cli
The request is signed using the access id and secret key as described in the docs
I then ran amplify push to push the changes
Ran the function from the AWS Lambda console
GraphQL schema(s)
Log output
Additional information
No response