Strange SSO problem using ProxyConnect when connecting new accounts
I'm experiencing some strange issues with ProxyConnect SSO (version bundled with git master). It's connected to a custom made SSO solution which also integrates with MediaWiki. On my local machine everything works great but in the production environment things get messy.
I've run the test and it reports that my SSO application is correctly returning the data it needs, and if I load up the authentication url in my browser I can see it's returning the right data, and for existing user accounts login and logout are working as expected. However, when creating new accounts things fall apart. If I follow these steps, I can reproduce the problem every time, and then make it magically disappear by clearing cookies.
- Clear all vanilla related cookies
- Register at my SSO and activate the account
- Visit the forum
- Behind the scenes vanilla correctly automatically creates a new user account matching the data the SSO returned
- Vanilla then tells me an account already exists with that email address (it didn't beforehand, vanilla just made it!)
- It's not possible to link the account, since no password has been set for it
- Clear all vanilla related cookies
- Visit the forum again and I'm logged in correctly and able to use the forum
I'm totally perplexed. As I said it works fine on my local machine. The cookie domain and path for my SSO and Vanilla are the same.
Is there anything I can do to help further debug this? Any reasons you might know of that would cause a difference between my local development version and production?
The SSO is: http://practicalplants.org/sso
The forum is: http://practicalplants.org/community
Comments
Ok, I've chased the problem through class.proxyconnect.plugin.php and class.entrycontroller.php, and it seems like the call to UserModel->Synchronise from line 846
$UserID = $this->UserModel->Synchronize($UserInfo['UserKey'], array( 'Name' => $UserInfo['UserName'], 'Email' => $UserInfo['UserEmail'], 'Roles' => GetValue('Roles', $UserInfo) ));
returns a user id on my local machine, but on the server it always returns 0 (but creates the user nonetheless!).
I'm chasing it further into the usermodel, thinking maybe it could be down to a delayed insert or somesuch. Anyone know the internals I'm dealing with here, I'm having to get my head around it as I go, chasing things from method to method.
Ok, resolved via a hack.
I guess this is a bug in Vanilla, possibly relating to delayed database writes? Honestly, I have no idea. The install was on a MediaTemple gridserver, so it's very possible database writes don't behave as predictably as on a dedicated or shared server. As stated above, the problem was that the call to the Synchronize method of the UserModel (around line 850 of class.entrycontroller.php) almost always returns 0, but the user row is infact created.
I just hacked it by adding the following immediately below the call to
UserModel->Synchronize
:if($UserID===0){ $Auth = $this->UserModel->GetAuthentication($UserInfo['UserKey'], $UserInfo['ConsumerKey']); if($Auth && isset($Auth['UserID'])) $UserID = $Auth['UserID']; }
Which always returns the newly created user id as the Synchronize method in-fact should.
I hope this helps anyone else stumbling across the same problem.