Reputation: 66
I want to add a layer of security to my app (Amplify using appsync) so that only contacts who are part of a specific company can see cases that are a part of that company. My idea is that I query the case table by company to return all the cases, but I need to do a query that checks the contacts company first.
I have the following graphql schema:
type Case @model @auth(rules: [{ allow: public }, { allow: private }]) {
id: ID! @primaryKey(sortKeyFields: ["company"])
internal_id: String
case_number: Int
created_date: String
end_date: String
last_message_date: String
depot: String
project: Boolean
title: String
project_id: String
email: String
product: String
module: String
sla: String
priority: String
asset_type: String
truck_reg: String
failure_reason: String
software_issue: String
assigned: String
solution_id: String
status: String
stage: String
routine_maintenance_case: Boolean
subcategory: String
category: String
description: String
availability: String
subsidiary: String
search_title: String
search_depot: String
escalated: Boolean
company: String! @index(name: "company")
}
type Company @model @auth(rules: [{ allow: public }, { allow: private }]) {
id: ID
internal_id: String! @primaryKey
name: String
cases: [Case] @hasMany(indexName: "company", fields: ["internal_id"])
contact: [Contact] @hasMany(indexName: "company", fields: ["internal_id"])
}
type Contact @model @auth(rules: [{ allow: public }, { allow: private }]) {
id: ID
internal_id: String! @primaryKey(sortKeyFields: ["company"])
salutation: String
first_name: String
middle_name: String
last_name: String
email: String
phone: String
mobile_phone: String
office_phone: String
home_phone: String
is_internal: Boolean
first_login: Boolean
language: Int
communication_preference: Int
contact_role: String
company: String! @index(name: "company")
}
Im trying to use the autogenerated casesByCompany(company: "") query but include the contact internal_id so that only contacts who are part of the company have access to that case.
for example: casesByCompany(company: "", contact = "") where contact is the contact internal id, then it will run a test that the contact internal_id matches the company passed up.
the auto created resolver is:
## [Start] Set query expression for key **
#if( !$util.isNull($ctx.args.sortDirection) )
$util.error("sortDirection is not supported for List operations without a Sort key defined.", "InvalidArgumentsError")
#end
#set( $modelQueryExpression = {} )
#if( !$util.isNull($ctx.args.company) )
#set( $modelQueryExpression.expression = "#company = :company" )
#set( $modelQueryExpression.expressionNames = {
"#company": "company"
} )
#set( $modelQueryExpression.expressionValues = {
":company": {
"S": "$ctx.args.company"
}
} )
#end
## [End] Set query expression for key **
#set( $limit = $util.defaultIfNull($context.args.limit, 100) )
#set( $QueryRequest = {
"version": "2018-05-29",
"operation": "Query",
"limit": $limit,
"query": $modelQueryExpression,
"index": "company"
} )
#if( !$util.isNull($ctx.args.sortDirection)
&& $ctx.args.sortDirection == "DESC" )
#set( $QueryRequest.scanIndexForward = false )
#else
#set( $QueryRequest.scanIndexForward = true )
#end
#if( $context.args.nextToken ) #set( $QueryRequest.nextToken = $context.args.nextToken ) #end
#if( !$util.isNullOrEmpty($ctx.stash.authFilter) )
#set( $filter = $ctx.stash.authFilter )
#if( !$util.isNullOrEmpty($ctx.args.filter) )
#set( $filter = {
"and": [$filter, $ctx.args.filter]
} )
#end
#else
#if( !$util.isNullOrEmpty($ctx.args.filter) )
#set( $filter = $ctx.args.filter )
#end
#end
#if( !$util.isNullOrEmpty($filter) )
#set( $filterExpression = $util.parseJson($util.transform.toDynamoDBFilterExpression($filter)) )
#if( $util.isNullOrEmpty($filterExpression) )
$util.error("Unable to process the filter expression", "Unrecognized Filter")
#end
#if( !$util.isNullOrBlank($filterExpression.expression) )
#if( $filterExpression.expressionValues.size() == 0 )
$util.qr($filterExpression.remove("expressionValues"))
#end
#set( $QueryRequest.filter = $filterExpression )
#end
#end
$util.toJson($QueryRequest)
what is the best solution to add in the contact id? If it requires a custom query how can i create a resolver that allows me to have that check in place.
The reason I have had to do this is because im using cognito users to allow access to the site, but anyone can take the given token and copy the graphql query in the request sent up and put it into postman and edit the details to pull back other companies information.
Please let me know if any other information is needed.
Thanks
Upvotes: 1
Views: 220