1

I am trying to adjust FOSUserBundle to work with my Neo4j database and I cant seem to get it working. After a long time of trying to implement my own user system without any luck (Setting up NEO4j in Symfony2), I started trying to use the FOSUserBundle.

I have used the following articles and repositories:

https://github.com/ikwattro/Neo4jUserBundle I have taken this and copied all of the files into my UserBundle. I have changed the namespaces.

I have taken the graph manager from here: https://github.com/ikwattro/KwattroNeo4jOGMBundle

For the rest, I have followed the FOSUserBundle documentation.

Now, when I go to the registration form, all fields appear and I can fill in my preferred credentials. This works. After I click on submit I get redirected to the success page, on which an alert overlay is displayed:

An error occurred while loading the web debug toolbar (500: Internal Server Error). Do you want to open the profiler?

If I then enter the profiler, I can see that I have successfully been authorized and logged in as the user that I just created. The data is also successfully saved in my neo4j database.

The problem now is that if I go to any other page of my Symfony project, I am logged in as Anonymous again. And If I go to the login page, the form is displayed correctly, but it always returns: Invalid credentials.

I am guessing, that there is something wrong with my sessions or my security?

This is my security.yml:

security:
  encoders:
    FOS\UserBundle\Model\UserInterface: bcrypt
    Neo4jUserBundle\Entity\User: bcrypt

  role_hierarchy:
    ROLE_ADMIN: ROLE_USER
    ROLE_SUPER_ADMIN: ROLE_ADMIN

  providers:
    fos_userbundle:
      id: neo4j.user_provider.username

  firewalls:
    main:
      pattern: ^/
      form_login:
        provider: fos_userbundle
        csrf_provider: security.csrf.token_manager
      logout: true
      anonymous: true

  access_control:
    - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/admin/, role: ROLE_ADMIN }

I dont know if this information can help or is relevant, but in the profiler under the Request right after registration (when the user is still authenticated correctly) this is the session information:

Session Metadata
Key           Value
Created       Tue, 21 Jul 15 17:27:34 +0200    
Last used     Tue, 21 Jul 15 17:27:34 +0200    
Lifetime      0

Session Attributes
Key                        Value
_csrf/authenticate         A_H4Ul1XHFYoxQdOirdmbBQRRCJ01Xh8EkGeC6Y7xw0    
_csrf/registration         OAXAXhfhcN6z0WekMN0fk8zg4ikk5uCCZBlvhy8DyVY    
_security.last_username    test    
_security_main             C:74:"Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken":444:{a:3:{i:0;N;i:1;s:4:"main";i:2;s:404:"a:4:{i:0;C:32:"neo4jProxyUserBundle_Entity_User":192:{a:9:{i:0;s:60:"$2y$13$e49oj61cdjk88kk040wg8exlwqVzbdQB5IVNG18Wqcbe.EW8KXi72";i:1;s:31:"e49oj61cdjk88kk040wg8kcc4cg40c4";i:2;s:4:"test";i:3;s:4:"test";i:4;b:0;i:5;b:0;i:6;b:0;i:7;b:1;i:8;i:66;}}i:1;b:1;i:2;a:1:{i:0;O:41:"Symfony\Component\Security\Core\Role\Role":1:{s:47:"Symfony\Component\Security\Core\Role\Rolerole";s:9:"ROLE_USER";}}i:3;a:0:{}}";}}

Flashes
Key               Value
success           [0 => registration.flash.user_created, 1 => registration.flash.user_created, 2 => registration.flash.user_created, 3 => registration.flash.user_created, 4 => registration.flash.user_created, 5 => registration.flash.user_created, 6 => registration.flash.user_created, 7 => registration.flash.user_created, 8 => registration.flash.user_created]

Any help or hints would be appreciated.

UPDATE [21.07.2015]

I have now created a repository: https://github.com/JoranBeaufort/Neo4jUserBundle (I hope this works, the first time I have used GitHub)

I guess that there is something off with the session handling?

Another thing to point out is, that the dependency injection does not seem to do anything. I must be missing a few vital things.

It would be great to be able to offer a Neo4jUserBundle that works out of the box with FOSUserBundle and can be configured in the config file of the Symfony project. Great and vital would also be the authentication with the database (use username and password to connect to neo4j).

UPDATE [22.07.2015]

I have changed the bundlename and I think I have finally gotten the DependencyInjection to work. I'm not quite sure but I think I had a problem with how I named my classes.

I have also tried what you suggested with findUserById. I have written a controller which takes the route myapp.com/neo4juser/debug/finduserbyid/{id} and then uses the findUserById method to return the user. This is working. I have a user in my Neo4j-Database with an ID = 68 and an email=test@test.test. If I now enter myapp.com/neo4juser/debug/finduserbyid/68 the page is loaded displaying the right email of that user.

TWIG can be found here: https://github.com/JoranBeaufort/Neo4jUserBundle/blob/master/Resources/views/Debug/finduserbyid.html.twig

And the CONTROLLER here: https://github.com/JoranBeaufort/Neo4jUserBundle/blob/master/Controller/DebugController.php

The methods in the UserManager seem to be returning the desired objects.

Does this help in figuring out why the login does not work in any way? Does the serialization have anything to do with the error or the encryption type? Or could it be something to do with the CSRF? Any further hints?

UPDATE [23.07.2015]

When using in_memory as the provider and setting up an in_memory user, the login works. So now I have narrowed down the problem to the provider.

I am getting closer! Now the error in the dev.log file reads:

[2015-07-23 17:11:54] security.INFO: Authentication request failed. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\BadCredentialsException(code: 0): Bad credentials. at bla/vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Provider/UserAuthenticationProvider.php:73, Symfony\\Component\\Security\\Core\\Exception\\UsernameNotFoundException(code: 0): Username \"test\" does not exist. at bla/src/Neo4jUserBundle/Security/UserProvider.php:42)"} []

Important is the part `Username "test" does not exist.I am guessing this means that something is not working in the user provider. Can anyone spot what the problem might be? The Provider which I am calling can be found here: https://github.com/JoranBeaufort/Neo4jUserBundle/tree/master/Security

Dhia Djobbi
  • 1,176
  • 2
  • 15
  • 35
Mfbaer
  • 465
  • 3
  • 15
  • do you have a repository where the code is available, there might be so much things playing here. Also can you please post the content of the logs file. thx – Christophe Willemsen Jul 21 '15 at 16:09
  • I have now added a repository and the most recent content of the log file. Kind Regards – Mfbaer Jul 21 '15 at 18:35
  • Thanks, and thanks for mentioning my name in the classes. It is hard to say like this, really. The logs are not really helpful too. Have you checked if the methods in the UserManager are returning anything, by just printing the return of findUserById or findUserByUsername for example – Christophe Willemsen Jul 21 '15 at 20:03
  • Thank you for your answer and no problem, I find that code deserves referencing just like articles and books. I have updated my question and my github again. The methods in the UserManager seem to be returnung the desired objects. – Mfbaer Jul 22 '15 at 18:37
  • It seems that the userprovider and not the usermanager has something wrong with it. Maybe I am forgetting to implement or extend something? have updated my question again. – Mfbaer Jul 23 '15 at 15:20
  • can you debug what the userManager->findUserByUsername is getting as request and is returning as response ? – Christophe Willemsen Jul 23 '15 at 15:24
  • How would I do that? Do I look in the profiler under "Request" or under "Events"? – Mfbaer Jul 23 '15 at 15:37
  • no, just use var_dump in the UserManager and output the content – Christophe Willemsen Jul 23 '15 at 15:40
  • I have added: dump($user); to the UserProvider but now I get an error which then redirects me and in the profiler under dump() there is nothing. Sorry, I am still very new to Symfony – Mfbaer Jul 23 '15 at 16:09
  • And if I use: exit(\Doctrine\Common\Util\Debug::dump($user)); like mentioned here: http://stackoverflow.com/questions/15604565/pretty-dump-variable-object-in-symfony-2 I get a blank page displaying only: "NULL NULL " And same thing happens if I add: exit(\Doctrine\Common\Util\Debug::dump($this->findUserBy(array('usernameCanonical' => $this->canonicalizeUsername($username))))); to the UserManager.php – Mfbaer Jul 23 '15 at 16:13
  • I'll try to download your repo and test in local, will be easier but wait a few hours – Christophe Willemsen Jul 23 '15 at 16:18
  • Thank you very much! And it does not hurry. I will be away till tomorrow and will resume work tomorrow. Thank you so much for your time up to now, you have already helped alot! By the look of the dump() the returned object is empty. Maybe the wrong manager is used? If I use "$em = $this->container->get('neo4j.user_manager'); " in a controller the functions (findUserByUsername()...) work. – Mfbaer Jul 23 '15 at 16:22

2 Answers2

0

Ok. I opened a PR for some tweaks, but I couldn't get the stuff working.

The tweaks I've done are adding the possibility to define a user and password for via the neo4j_user config, and load the services.yml file in the DI extension.

When I register a user, it is well created in the database. However for fetching a user, after some debug, I can see that the underlying client (neo4jphp combined with neo4j-php-ogm) are using the legacy indexes and it is throwing some errors at this stage.

I can not help further except to tell you to try to not use an ogm in the beginning and try with raw cypher queries.

I'm afraid trying to update both libraries used can be difficult in a first instance.

Christophe Willemsen
  • 19,399
  • 2
  • 29
  • 36
  • Thank you for looking into it. What I have found out is, that the findUserById() function in the usermanager returns the desired user object. When telling the login form to use the ID instead of the username following error is thrown: "Warning: Class __PHP_Incomplete_Class has no unserializer " which means that a user IS found but sometthing else goes wrong. Ok, so I will have a look at if I am able to create raw cypher queries to fetch what I want. Thank you and if you happen to have any other ideas please feel free to contact me. Kind Regards – Mfbaer Jul 24 '15 at 15:04
  • maybe we can get in touch on skype, just throw me an email : christophe (at) graphaware (dot) com – Christophe Willemsen Jul 24 '15 at 15:06
  • I have started a new try but seem to be stuck at the same place you mentioned (have debugged up to the error: "[message] => org.apache.lucene.queryParser.ParseException: Cannot parse 'emailCanonical:': Encountered "" at line 1, column 15."). I wanted to ask if you could shed some light on how I should use raw cypher queries to connect the FOSUserBundle to my database? Using https://github.com/graphaware/neo4j-php-client I can build a controller to send queries to the database, but how can i integrate it into the FOSUserBundle? – Mfbaer Jan 30 '16 at 17:52
  • Ps. The git of my new try: Basically just merged the Neo4j-OGM and the Neo4jUserBundles: https://github.com/JoranBeaufort/Neo4jBundle-Userbundle – Mfbaer Jan 30 '16 at 17:58
  • I have now created a new repository which seems to work up till now: https://github.com/JoranBeaufort/Neo4jUserBundle – Mfbaer Feb 02 '16 at 15:51
0

I would say the problem, as of 27/12/2015, is that UserManager, at line 73, does not return the found user (is a void function). I have not tried it yet and can´t for a few days, and maybe it´s an answer not sought anymore, but I´m pretty sure that´s the problem.

IDEs won´t find it a problems due to the @return tag:

* Finds a user by username
 *
 * @param string $username
 *
 * @return UserInterface
 */
public function findUserByUsername($username)
{
    $this->findUserBy(array('usernameCanonical' => $this->canonicalizeUsername($username)));
}
yawmoght
  • 727
  • 6
  • 10
  • Please excuse the late answer. Thank you for your input. Due to time reasons I have now decided to work with a normal MySQL using Doctrine with the FOSUserBundle, for now. I would appreciate the FOSUserBundle having a way of connecting to a Neo4j database, as graph databases seem to be of growing importance. But I do not have time to create something at the moment. If anyone comes across a new Bundle, id be happy to know. Kind Regards – Mfbaer Jan 25 '16 at 15:07