Vanilla 1 is no longer supported or maintained. If you need a copy, you can get it here.
HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.
Vanilla 1.1.X and WordPress
If you are using the WordPress integration and you upgrade to Vanilla 1.1.X, you'll notice that some of your AJAX doesn't work. That's because Vanilla 1.1.X is passing these AJAX scripts an extra parameter, PostBackKey, that gets compared to a SessionPostBackKey value stored in the user's session.
Unfortunately, as Mark points out, WordPress doesn't use PHP sessions. And so Mark's WordPress Authenticator class doesn't use PHP sessions either. That was fine for Vanilla 1.0.X because at that time only the Authenticator had any use for session variables, but for 1.1.X the lack of a PHP session breaks AJAX.
I have tried to fix this by patching People.Class.WordpressAuthenticator.php and it seems to work for me but I'm not confident about it. The problem I can see is that if you log in, then out out from WordPress, then log back in from WordPress, Vanilla will have no way of knowing that the session is a new one. To Vanilla it will be the same session. That may not cause trouble right now but it might in the future if Vanilla adds more session variables. I don't know what the long-term solution for this will be.
For the time being, here's my fix.
Open People.Class.WordpressAuthenticator.php.
Find the function DeAuthenticate() and replace it with this:
Find the function GetIdentity() and replace it with this:
Now let's all be good boys and girls and hope that Santa Claus brings us Swell for Christmas.
Unfortunately, as Mark points out, WordPress doesn't use PHP sessions. And so Mark's WordPress Authenticator class doesn't use PHP sessions either. That was fine for Vanilla 1.0.X because at that time only the Authenticator had any use for session variables, but for 1.1.X the lack of a PHP session breaks AJAX.
I have tried to fix this by patching People.Class.WordpressAuthenticator.php and it seems to work for me but I'm not confident about it. The problem I can see is that if you log in, then out out from WordPress, then log back in from WordPress, Vanilla will have no way of knowing that the session is a new one. To Vanilla it will be the same session. That may not cause trouble right now but it might in the future if Vanilla adds more session variables. I don't know what the long-term solution for this will be.
For the time being, here's my fix.
Open People.Class.WordpressAuthenticator.php.
Find the function DeAuthenticate() and replace it with this:
function DeAuthenticate() {
if (session_id()) session_destroy();
$this->GetWordpressSettings();
setcookie($this->UserCookieName, ' ', time() - 31536000, $this->CookiePath, false);
setcookie($this->PassCookieName, ' ', time() - 31536000, $this->CookiePath, false);
setcookie($this->UserCookieName, ' ', time() - 31536000, $this->SiteCookiePath, false);
setcookie($this->PassCookieName, ' ', time() - 31536000, $this->SiteCookiePath, false);
return true;
}
Find the function GetIdentity() and replace it with this:
function GetIdentity() {
$this->GetWordpressSettings();
// Examine the cookie values for session info
$login = ForceIncomingCookieString($this->UserCookieName, '');
$pass = ForceIncomingCookieString($this->PassCookieName, '');
$dbpass = '';
$UserID = 0;
if ($login != '' && $pass != '') {
$s = "select id, user_pass from wp_users where user_login = '".FormatStringForDatabaseInput($login)."'";
$Result = $this->Context->Database->Execute($s,
'WordpressAuthenticator',
'GetIdentity',
'An error occurred while attempting to retrieve session data.');
if ($Result) {
while ($rows = $this->Context->Database->GetRow($Result)) {
$UserID = ForceInt($rows['id'], 0);
$dbpass = ForceString($rows['user_pass'], '');
}
// If the double-md5d password doesn't match the one in the cookie - don't authenticate
if (md5($dbpass) != $pass) {
$UserID = 0;
}
}
}
else {
if (session_id()) session_destroy();
}
if (!session_id()) {
session_set_cookie_params(0, $this->CookiePath);
session_start();
}
return $UserID;
}
Now let's all be good boys and girls and hope that Santa Claus brings us Swell for Christmas.
0
This discussion has been closed.
Comments
Mark, any input on this?
I didn't really like the use of a session variable. I considered putting the setting into the database, but I didn't like that either since it caused more querying to the database on every page load. In the end the only reason I chose the session was because it was easier to program - the lesser of two evils in my mind at the time.
Now I'm wondering if it would be better to do something like put the variable into the user table. But that involves db alteration scripts - which I hate doing to people in upgrades. Hmmmm.
Well, I guess in the meantime you can change this information on the wiki - at least until we come up with a more complete solution...
Mark, don't you already have a 'VerificationKey' in the users' table? The one you use for cookie-based user credentials? Any reason why that couldn't serve the same purpose?
I agree that the database solution is not the spiffiest, I'm just saying I think it could be made to work.
I'm open to ideas, though.
Create a new file in the library called library/Framework/Framework.Class.Session.php and in there create a copy of the People session class. Then change it so that the getvariable and setvariable methods save/retrieve to/from a cookie or db instead of the session.
Because Vanilla doesn't autoload classes (it loads them on demand looking first in Framework, then People, then Vanilla), it will find this new session class first and use it instead of the default one.
It's a bit of a hack, but it does the trick.
But I guess you could just replace the people session file with the altered one.
I'll think on it some more.