How to allow specific user to write to Firebase - firebase-security

I am trying to allow specific user to write to Firebase. The issue is that I am getting error:
{
"rules": {
"events": {
".read": true,
".write": "auth.uid = 'google:xxxxxxxx..xx'"
}
}
}
the error that I am getting :
6:18: Rule expressions may not contain assignments.

Related

Why doesn't GraphQL.NET honour the errors.extensions schema?

I recently rewrote some GraphQL services from Java to .NET Core.
In Java, I was able to provide custom error messages to the clients using the errors.extensions in the response, ie:
{
"data": {
"someMutation": null
},
"errors": [{
"cause": null,
"message": "Unauthorized",
"httpStatusCode": 0,
"extensions": {
"uiMessage": "Oh no, your session expired. You'll need to login again to continue.",
"httpStatusDescription": "Unauthorized",
"httpStatusCode": 401
},
"errorType": "ValidationError",
"path": null,
"localizedMessage": "Unauthorized",
"suppressed": []
}
]
}
However, in .NET, I don't seem to be able to replicate this format.
ErrorInfo.Extensions is added to the root of the response, not to the the Errors object itself, eg:
{
"data": {
"someMutation": null
},
"errors": [{
"message": "Auth token not provided"
}
],
"extensions": {
"httpStatusCode": 401,
"httpStatusDescription": null,
"uiMessage": "Oh no, your session expired. You'll need to login again to continue.",
}
}
The GraphQL spec reads (ref https://spec.graphql.org/October2021/#sec-Errors, https://spec.graphql.org/October2021/#example-8b658):
GraphQL services may provide an additional entry to errors with key
extensions. This entry, if set, must have a map as its value. This
entry is reserved for implementors to add additional information to
errors however they see fit, and there are no additional restrictions
on its contents.
eg:
{
"errors": [
{
"message": "Name for character with ID 1002 could not be fetched.",
"locations": [{ "line": 6, "column": 7 }],
"path": ["hero", "heroFriends", 1, "name"],
"extensions": {
"code": "CAN_NOT_FETCH_BY_ID",
"timestamp": "Fri Feb 9 14:33:09 UTC 2018"
}
}
]
}
I created a new test project (.NET Core 3.1) using the latest versions of the libraries (GraphQL 7.1.1 et al) but am still unable to add custom properties to errors.extensions.
This is the test mutation which intentionally throws an exception:
Field<StringGraphType>("greet")
.Argument<NonNullGraphType<StringGraphType>>("name")
.Resolve(context => {
try {
throw new Exception("Invalid input");
return "Hello " + context.GetArgument<String>("name");
} catch(Exception ex) {
// This doesn't seem to get returned anywhere in the response
Dictionary<String, object> extraData = new Dictionary<string, object>();
extraData.Add("error1", "message1");
// Add the error to the response using the overloaded constructor
context.Errors.Add(new ExecutionError("Oh dear, that went wrong", extraData));
// This gets added to the root of the response
context.OutputExtensions.Add("error2", "message2");
return null;
}
});
the mutation to invoke it:
mutation {greet(name:"Chewbacca")}
and the response (I don't know where errors.extensions.details comes from):
{
"errors": [
{
"message": "Oh dear, that went wrong",
"extensions": {
"details": "GraphQL.ExecutionError: Oh dear, that went wrong"
}
}
],
"data": {
"greet": null
},
"extensions": {
"error2": "message2"
}
}
I would imagine that the GraphQL.NET library would expose an Extensions dictionary on the ExecutionError object so one could add custom values in the usual manner, eg:
ExecutionError executionError = new ExecutionError("Oh dear, that went horribly wrong");
executionError.Extensions.Add("customError", "Your custom error here")
context.Errors.Add(executionError);
Which would result in a response similar to this:
{
"data": {
"someMutation": null
},
"errors": [{
"message": "Oh dear, that went horribly wrong",
"extensions": {
"customError": "Your custom error here"
}
}
]
}
I am hopeful that some bright individual in the community can (slap me upside the head and) point me in the right direction.

Cloudflare GraphQL Analytic API does not have access to the path

When I tried query this query
query ($zoneID: String!) {
viewer {
zones(filter: {zoneTag: $zoneID}) {
httpRequestsAdaptiveGroups(filter: {date_gt: "2022-05-29"}, limit: 100) {
count
dimensions {
requestSource
}
sum {
visits
edgeResponseBytes
}
}
}
}
}
and it gave me this error
{
"data": null,
"errors": [
{
"message": "zone '0ab45c20ea56c46d2db5999b19221234' does not have access to the path",
"path": [
"viewer",
"zones",
"0",
"httpRequestsAdaptiveGroups"
],
"extensions": {
"code": "authz",
"timestamp": "2022-06-29T06:14:55.82422442Z"
}
}
]
}
How to have access to viewing httpRequestsAdaptiveGroups, do I have to upgrade the project plan because right now it is currently on free-tier
What I've tried so far was giving all the zone readable-permission and it still happen

Custom user permissions on table in Hasura

I'm developing an app which requires custom permissions on a specific table. I have the following data structure:
Users
-> id
-> name
Accounts
-> id
-> name
UserAccounts
-> userId
-> accountId
-> permissionLevel
permissionLevel is an enum and could be: Owner, ReadAndWrite or ReadOnly.
What I'd like to have is the following:
1) If you're an Owner of a UserAccount, you can invite other users.
2) If you want to create a new Account, you'll get the Owner permission in UserAccounts.
3) You can not add yourself to UserAccounts when you are not the Owner of said Account.
The issue I'm having is I'm not sure on how to solve this in Hasura. I've tried the following Hasura permission (but I'm missing an option to expand the where clause (see below)):
{
"_or": [
{
"_and": [
{
"accountId": {
"_is_null": false
}
},
{
"Account": {
"UserAccounts": {
"_and": [
{
"userId": {
"_eq": "X-Hasura-User-Id"
}
},
{
"permissionLevel": {
"_eq": "Owner"
}
}
]
}
}
}
]
},
{
"_not": {
"_exists": {
"_table": {
"name": "Account",
"schema": "public"
},
"_where": {
"UserAccounts": {
"accountId": {
"_eq": "$accountIdFromQuery" // <-- this does not exist AFAIK
}
}
}
}
}
}
]
}
So I'm at a loss what direction to go. Maybe I'm just missing something, maybe I need to use a custom view or maybe I need to try a custom postgresql function. Any help is greatly appreciated!
For now, my solution is using an event trigger (which triggers an AWS Lambda function) to write into the UserAccounts table with admin privileges. Hasura has documentation on how to achieve this: https://hasura.io/docs/1.0/graphql/manual/event-triggers/serverless.html

Cognito custom claims missing with Amplify but not with Appsync Console

I have the following resolver, allowing me to retrieve information about the current user company (companyId is added as a custom field on the cognito user pool). The field on cognito is set to mutable.
{
"version" : "2017-02-28",
"operation" : "GetItem",
"key": {
"id" : $util.dynamodb.toDynamoDBJson($context.identity.claims.get("custom:companyId"))
}
}
This works fine when using the AWS AppSync interface (after login in) as the logs show:
{
"errors": [],
"mappingTemplateType": "Request Mapping",
"path": "[getMyClientCompany]",
"resolverArn": "arn:aws:appsync:eu-west-1:261378271140:apis/rue25cac6jc6vfbhvu32sjafqy/types/Query/fields/getMyClientCompany",
"transformedTemplate": "{\n \"version\" : \"2017-02-28\",\n \"operation\" : \"GetItem\",\n \"key\": {\n \"id\" : {\"S\":\"0c1c81db-a771-4856-9a30-d11bf8e3cab1\"}\n }\n}",
"context": {
"arguments": {},
"source": null,
"result": null,
"error": null,
"outErrors": []
},
"fieldInError": false
}
But doesn't work when the code comes from Amplify-js:
{
"errors": [],
"mappingTemplateType": "Request Mapping",
"path": "[getMyClientCompany]",
"resolverArn": "arn:aws:appsync:eu-west-1:261378271140:apis/rue25cac6jc6vfbhvu32sjafqy/types/Query/fields/getMyClientCompany",
"transformedTemplate": "{\n \"version\" : \"2017-02-28\",\n \"operation\" : \"GetItem\",\n \"key\": {\n \"id\" : {\"NULL\":null}\n }\n}",
"context": {
"arguments": {},
"source": null,
"result": null,
"error": null,
"outErrors": []
},
"fieldInError": false
}
The key that should be "custom:companyId" is "NULL" now
I imagine the issue is either with Amplify (version 0.4.8) or with the cognito user resolver for some reason
Any idea what could be going on?
There are two JWT tokens Cognito may utilize. ID and Access. ID token seems to contain those custom claims.
From Amplify you tweak the Authorization header to use ID token vs Access token.
Here's the code, put it in AWS Amplify configuration:
API: {
graphql_endpoint: 'https://****.appsync-api.***.amazonaws.com/graphql',
graphql_region: '***',
graphql_authenticationType: 'AMAZON_COGNITO_USER_POOLS',
graphql_headers: async () => {
try {
const token = (await Auth.currentSession()).idToken.jwtToken;
return { Authorization: token }
}
catch (e) {
console.error(e);
return {};
// Potentially you can retrieve it from local storage
}
}
}
Note, there seem to be several different keys to configure Amplify keys:
for example, aws_appsync_graphqlEndpoint vs API { graphql_endpoint }, I used the latter.

Firebase security rules not working

{
"rules": {
"users":{
"$uid":{
".read": "auth.uid == $uid",
".write": "auth.uid == $uid",
}
}
}
}
I want the users who are under the users node only have access to both read and write and those who are not under the users node only have access to read. I wrote this rule but it says some error like Admin: false.
This is most common usage of firebase real time database rule if user is exist can read and write and if user not exists than only read the database.
{
"rules": {
".read": true,
".write": "auth != null"
}
}