DotNet4Neo4j / Neo4jClient

.NET client binding for Neo4j
https://www.nuget.org/packages/Neo4jClient
Microsoft Public License
431 stars 146 forks source link

Neo4jClient returns 403 FORBIDDEN: Request forbidden by administrative rules #455

Closed guilhermedjr closed 1 year ago

guilhermedjr commented 1 year ago

When trying to add a relationship between two nodes in a neo4j instance using Neo4jClient, I get the following error: Request forbidden by administrative rules.

`public async Task CreateFollowship(Guid followerId, Guid followedId) { await _neo4jClient.ConnectAsync();

    await _neo4jClient.Cypher
        .Match("(follower:User)", "(followed:User)")
        .Where($"(User follower) => follower.Id == {followerId}")
        .AndWhere($"(User followed) => followed.Id == {followedId}")
        .Create("follower-[:FOLLOWS]->followed")
        .ExecuteWithoutResultsAsync();

}`

The query generated is (by example):

MATCH (follower:User), (followed:User) WHERE (User follower) => follower.Id == "970486dc-5430-4532-8ed3-e30efa930105" AND (User followed) => followed.Id == "f6a15b31-e328-4113-8541-3de8108b116d" CREATE follower-[:FOLLOWS]->followed

I tried in other ways:

MATCH (follower:User), (followed:User) WHERE follower.Id == "970486dc-5430-4532-8ed3-e30efa930105" AND followed.Id == "f6a15b31-e328-4113-8541-3de8108b116d" CREATE follower-[:FOLLOWS]->followed

MATCH (follower:User), (followed:User) WHERE follower.Id IS "970486dc-5430-4532-8ed3-e30efa930105" AND followed.Id IS "f6a15b31-e328-4113-8541-3de8108b116d" CREATE follower-[:FOLLOWS]->followed

When running the command on the Neo4j Console using Cypher, i get different syntax errors with every attempt to fix. What is the correct syntax? An incorrect syntax is really the reason for the 403 error?

Clooney24 commented 1 year ago

HI @guilhermedjr, correct Cypher syntax is

MATCH (follower:User), (followed:User) 
WHERE follower.Id = "970486dc-5430-4532-8ed3-e30efa930105" AND followed.Id = "f6a15b31-e328-4113-8541-3de8108b116d" 
CREATE (follower)-[:FOLLOWS]->(followed)

Unless it is intended, I would recommend using MERGE instead of CREATE to prevent creating multiple similar relationsships between the nodes.

Using Neo4jClient in C# this would be (with Create replaced by Merge):

 await _neo4jClient.Cypher
        .Match("(follower:User), (followed:User)")
        .Where((User follower) => follower.Id == followerId)
        .AndWhere((User followed) => followed.Id == followedId)
        .Merge("(follower)-[:FOLLOWS]->(followed)")
        .ExecuteWithoutResultsAsync();

or alternatively by using string and parameters

 await _neo4jClient.Cypher
        .Match("(follower:User) (followed:User)")
        .Where("follower.Id = $followerId")
        .WithParam("followerId", followerId) 
        .AndWhere("followed.Id = $followedId")
        .WithParam("followedId", followedId) 
        .Merge("(follower)-[:FOLLOWS]->(followed)")
        .ExecuteWithoutResultsAsync();

Params could also be set using just one ".WithParams" instead of the two ".WithParam", but I like using it one by one.

Where-Clauses also could be set using string interpolation ($"follower.Id = {followerId}") but this is not recommended as it prevents query caching.

Be aware that Cypher doesn't accept "==" (or "!=") as operators, these only work in C#. Has to be "=" or "<>" in Cypher.

Response status 403 means "Bad Request" so it's due to that incorrect syntax and not a bug in Neo4jClient.

Best, Reiner

guilhermedjr commented 1 year ago

Thanks!

guilhermedjr commented 1 year ago

var query = _neo4jClient.Cypher .Match("(follower:User), (followed:User)") .Where("follower.Id = $followerId") .WithParam("followerId", followerId) .AndWhere("followed.Id = $followedId") .WithParam("followedId", followedId) .Merge("(follower)-[:FOLLOWS]->(followed)");

I am still getting the error 403. Could it be an access restriction to the Neo4j AuraDB?

Clooney24 commented 1 year ago

Sorry, I'm not familiar with AuraDB.

Are other queries running successfully from your app? If so, it must be somehow syntax related.

Did you try to connect to your DB with Neo4jDesktop? If so, you could check your C# app with a very simple cypher like

var query = _neo4jClient.Cypher.Return("1");

just to be sure it's not related on query syntax errors.

If this doesn't work either, the problem might be in the logic that connects the _neo4client to the db

guilhermedjr commented 1 year ago

The queries work from my app using a Neo4jDesktop connection. It seems like it's a security restriction from Neo4j AuraDB that rejects any external write operations. I think it's not a problem with Neo4jClient, since the access to the Neo4j AuraDB works. I'm going to report Neo4j about this problem in order to find the most appropriate solution.

guilhermedjr commented 1 year ago

Hey, could you also help me with this, please? https://stackoverflow.com/questions/74757009/neo4j-cypher-queries-for-twitter-clone-social-graph-of-users

Clooney24 commented 1 year ago

Hi, I could try but I don't know when I'll find time.

cskardon commented 1 year ago

I don't see why you would have a problem with Aura and not allowing write operations from an external source - if you can connect to the server - then it should work fine.

What is your entire connection setup - i.e. how are you creating the IGraphClient?