* Which Category is your question related to? *
API
* What AWS Services are you utilizing? *
AppSync
* Provide additional details e.g. code snippets *
type User
@model
{
name: String
balance: Int @auth(rules: [
{allow: groups, groups: ["Admins"], operations: [update, create, read]},
{allow: owner, ownerField: "id", operations: [read]},
])
}
It appears I get an error if I issue a graphql query for name and balance.
Meaning, I have to issue two different queries depending on whether the logged in user is an admin or not.
Seems to me that if I try to read a particular field and don't have permissions, it should just return null.
This is even further complicated because we want the model owner to be able to read the "balance" property but not other users.
So, take the example of User X visiting User Y's profile vs User Y visiting User Y's profile. We have to issue two different queries to get User Y's profile - one without the "balance" field and one WITH the balance field.
@CodySwannGT can you add code snippet of your queries?.
This seems an issue more related to amplify cli, I will transfer it to that repo.
Thanks!
type User
@model
{
name: String
balance: Int @auth(rules: [
{allow: groups, groups: ["Admins"], operations: [update, create, read]},
{allow: owner, ownerField: "id", operations: [read]},
])
}
Would generate this in graphql/queries
export const getUser = `query GetUser($id: ID!) {
getUser(id: $id) {
id
name
balance
createdAt
updatedAt
}
}
But then if I use the auto-generated query, I will get an error because I'm including the "balance" field in my query
````
import { getUser } from '../graphql/queries';
import { useQuery } from 'react-apollo-hooks';
....
//// this will throw an error because I'm not signed in as an "Admins". Desired behavior is to return null for balance
const { data: {getUser: {} = {}} = {} } = useQuery(gql(getUser), {
variables: {
id: userId
}
});
....
````
The workaround, of course, is to write my own 'getUser' query that omits the balance field
````
import { getUser } from '../graphql/queries';
import { getUserWithoutBalance } from '../custom/queries';
import { useQuery } from 'react-apollo-hooks';
....
//// this will throw an error because I'm not signed in as an "Admins". Desired behavior is to return null for balance
const { data: {getUser: {} = {}} = {} } = useQuery(gql(!!currentUser.isAdmin ? getUser : getUserWithoutBalance), {
variables: {
id: userId
}
});
....
````
But this seems wildly inefficient to maintain two separate queries
@CodySwannGT I agree this shouldn't be the ideal behavior. We're looking into this.
@CodySwannGT What type of error are you receiving on your query from the client? Is it a 4xx error?
Yes. 401 or 403 - I don't recall exactly
Yes a 403
On Tue, Aug 6, 2019 at 6:44 PM Kaustav Ghosh notifications@github.com
wrote:
@CodySwannGT https://github.com/CodySwannGT What type of error are you
receiving on your query from the client? Is it a 4xx error?—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/aws-amplify/amplify-cli/issues/1972?email_source=notifications&email_token=AACHQO56XLYA6KTHKVXQFZ3QDH5EDA5CNFSM4IJMUTHKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3WVPMY#issuecomment-518870963,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AACHQO4XNSBUO4XA5OHBZIDQDH5EDANCNFSM4IJMUTHA
.
--
Cody Swann - CEO, Gunner Technology
T: 213.915.4083 | [email protected] | www.gunnertech.com
http://www.gunnertech.com/
Check out our Live Show every Thursday at 1 pm EST on Facebook
https://www.facebook.com/gunnertechnology, YouTube
https://www.youtube.com/channel/UCjURDi2kurZOJFK1OY-QRHg and Periscope
https://www.periscope.tv/gunnertech.
CONFIDENTIALITY NOTICE: This email message, together with any documents,
files and/or email messages attached to it, is intended for the sole use of
the individual or entity to whom it is addressed, and may contain
information that is legally privileged, confidential and restricted from
disclosure. If you are not the intended recipient, or responsible for
delivery to that person, you are hereby notified that any dissemination or
copying of this communication is STRICTLY PROHIBITED. In such case please
notify the sender by reply email and delete this message without reading,
printing or saving.
@CodySwannGT I tried out experimenting with your schema
type User
@model
{
name: String
balance: Int @auth(rules: [
{allow: groups, groups: ["Admins"], operations: [update, create, read]},
{allow: owner, ownerField: "id", operations: [create, read]},
])
}
I had the following queries which i tested
query GetUser {
getUser(id: "kaustav") {
name
balance
}
}
mutation CreateUser {
createUser(input: {name: "kaustav", balance: 123}) {
name
balance
}
}
For non-admin case - for which you're saying you're getting an error, I got the following response from AppSync
{
"data": {
"getUser": {
"name": "kaustav",
"balance": null
}
},
"errors": [
{
"path": [
"getUser",
"balance"
],
"data": null,
"errorType": "Unauthorized",
"errorInfo": null,
"locations": [
{
"line": 33,
"column": 5,
"sourceName": null
}
],
"message": "Not Authorized to access balance on type Int"
}
]
}
The AppSync response has an error block in it (due to the partial authorization the user has), but it also has the correct data block with the expected 'null' value on the balance field. Could you please verify your response data (in the browser network tab) and make sure you have both the data and the error field in the response?
Also, AppSync would return a 401 or 403 when there is an issue at the request level. Could you check in your network tab as to what's the error message?
So you're correct on the 4xx. There is none.
And here's the problem - when Apollo (which ships with AppSync) detects an error, no data is returned.
Here's a pseudo example for a NON "Admins" user
````
const { fetchMore, loading, error, data: {[queryName]: {items, nextToken} = {items: [], nextToken: null}} = {}} = useQuery(gql(query), {
variables
});
console.log("IM THE DATA from APOLLO QUERY", items)
console.log("IM THE ERROR", error)
````
https://www.dropbox.com/s/mdiz3s3lum8sylg/Screenshot%202019-08-06%2021.03.44.png?dl=0
Now with an "ADMINS" user
https://www.dropbox.com/s/1cttu02c9rmtnii/Screenshot%202019-08-06%2021.04.59.png?dl=0
I suppose you could say this is upstream with Apollo, but AppSync is documented hand-in-hand with Apollo, so I'm not sure who's lap this should fall in.
Edit - also since AppSync is a bit behind on version for Apollo, I'm locked at this:
"react-apollo": "2.5.6",
"react-apollo-hooks": "0.4.5",
@CodySwannGT This looks like an issue with the AppSync JS SDK (and maybe the apollo sdk used underneath). I'm transferring this issue back to the Amplify JS team to look into this further.
Thanks.
Since we're on topic.
Assuming I have an input:
input CreateActivityInput {
id: ID
createdAt: String
updatedAt: String
model: String!
modelId: ID!
owner: String
title: String
data: String
}
And I try to create an activity with a "foo" field - right now the request errors without creating the activity since "foo" was not a valid input field.
Is that the expected behavior?
Likewise, imagine only an "Admins" could set the "data" property above.
Right now, we see an error if a non "Admins" tries to set that property (instead of making the update and ignoring that property).
Is that the expected behavior?
I imagine the answer is "yes" in both cases, but this issue has me questioning myself.
Hi @coderbyheart
Have you tried without the useQuery hook? I suspect it might not be working correctly with partial data (try e.g. with plain client.query(...) or the graphql(...) HOC)
I have tried it with the client directly with the same results:
apolloClient.query({
query: gql(getUser),
variables: {id: cognitoUser.username},
fetchPolicy: "network-only"
}),
Any joy here? This one is killing us.
What is the error that you're getting? Is it an uncaught promise? If so then you'll need to do something like this:
async function getData() {
try {
const results = await API.graphql(graphqlOperation(listPosts))
dispatch({ type: 'QUERY', todos: results.data.listPosts.items });
} catch (err){
if(err.errors[0].errorType === 'Unauthorized' &&
(err.errors[0].path.indexOf("ssn") > -1)
){
dispatch({ type: 'QUERY', todos: err.data.listPosts.items });
}
}
}
This assumes I'm doing field level auth on the ssn field, but in general if you're getting an Authorization error which is expected behavior you'll need to catch the promise and then continue on depending on what your business logic dictates (in this case I'm ok with it failing on ssn as that's a partial failure).
my results object is an empty object when there is an error.
As stated above, I'm not using the simplified Amplify GraphQL - but AppSync-suggested Apollo package.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Any action here?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
This issue has been automatically closed because of inactivity. Please open a new issue if are still encountering problems.