Agree, wish I had just written my own basic forum given the time spent bug fixing/trawling Vanilla's code. That said I'm using the entire themed vanilla forum (views etc), I just want it to login when I login with the other app and think requiring two logins for one site is bad-practise.
Perhaps feasible to intercept the ReadUser function and make it point to AppSite User Database? Instead of having the GDN_User table just intercept all read/write's and return custom.
I think I go back to the original point, which is you need to pay someone to do the SSO for you. You might streamline the SSO somewhat. What you want is secure sessions, with user management, there are a number of ways of achieving this. ProxyConnect is a methodology, implementations may vary.
I applaud you for making the effort, and giving it a go, but you need some expertise to debug it for you, and possibly make it streamline.
You don't actually want to replicate all the forum functionality, this would be expensive and unnecessary.
I tried my best not to mock you I was just trying to steer you in the right direction, and first find out what you real wanted to do.
<?php
/*
Vanilla Forum Helper Functions
*/
class appForum {
function __construct(){
define('APPLICATION', 'Vanilla');
define('APPLICATION_VERSION', '2.0.18.4');
define('DS', '/');
define('PATH_ROOT', 'forum');
}
/*
* Set the vanilla session as logged in with this user object.
*/
public static function setLoggedIn($bLoggedIn, $cUser, $iVanillaUserID = -1) {
ob_start();
require_once(PATH_ROOT.DS.'bootstrap.php');
ob_end_clean();
$cAuthenticator = new Gdn_PasswordAuthenticator();
//Get the vanilla ID:
if ($iVanillaUserID == -1) {
$cUserAuth = mysql_query("SELECT * FROM GDN_UserAuthentication WHERE ForeignUserKey = ? LIMIT 1", array($cUser['id']));
$iVanillaUserID = $cUserAuth['userid']; //UserID
}
//Set cookie: persist login for a month
$cAuthenticator->SetIdentity($iVanillaUserID, true);
Gdn::Authenticator()->Trigger(Gdn_Authenticator::AUTH_SUCCESS);
}
/*
* Check if user is logged in, if so return user model.
*/
public static function loggedIn() {
ob_start();
require_once(PATH_ROOT.DS.'bootstrap.php');
ob_end_clean();
$Session = Gdn::Session();
$Authenticator = Gdn::Authenticator();
if ($Session->IsValid()) {
return true;
} else {
return false;
}
}
/*
* Log out of the user's account:
*/
public static function logout($sCookiePath = '/', $sCookieDomain = '.mydomain.com') {
$iPastTime = time() - 24 * 60 * 60;
setcookie('Vanilla', ' ', $iPastTime, $sCookiePath, $sCookieDomain);
setcookie('VanillaSessionID', ' ', $iPastTime, $sCookiePath, $sCookieDomain);
setcookie('Vanilla-Volatile', ' ', $iPastTime, $sCookiePath, $sCookieDomain);
unset($_COOKIE['Vanilla']);
unset($_COOKIE['Vanilla-Volatile']);
unset($_COOKIE['VanillaSessionID']);
session_destroy();
$_COOKIE = null;
}
/*
* Manually insert a user into the vanilla tables:
*/
public static function createUser($iUserID, $sName, $sEmail, $sPassword, $sProviderKey = "my provider key here") {
ob_start();
require_once(PATH_ROOT.DS.'bootstrap.php');
ob_end_clean(); // clear any header output from vanila
$User = new UserModel();
$iVanillaUserID = $User->InsertForBasic(
array('Email'=>$sEmail, 'Name'=>$sName, 'ShowEmail'=>'0', 'Gender'=>'m', 'Password'=>$sPassword, 'Preferences'=>'a:1:{s:13:"Authenticator";s:5:"proxy";}'),
FALSE,
array('ValidateEmail' => FALSE, 'NoConfirmEmail' => TRUE)
);
if ($iVanillaUserID) {
// Save the authentication - different array keys to the database...igits.
$User->SaveAuthentication(array(
'UniqueID' => $iUserID,
'Provider' => $sProviderKey,
'UserID' => $iVanillaUserID
));
//Set user logged in:
appForum::setLoggedIn(true, null, $iVanillaUserID);
}
//Save the vanilla ID to your own user database to call for setLogin later.
return $iVanillaUserID;
}
/*
* Vanilla User Is logged iN
*/
public static function VanillaAuth() {
ob_start();
require_once(PATH_ROOT.DS.'bootstrap.php');
ob_end_clean(); // clear any header output from vanila
$Session = Gdn::Session();
$Authenticator = Gdn::Authenticator();
if ($Session->IsValid()) {
return $Session->User;
} else {
$Authenticator = Gdn::Authenticator()->GetAuthenticator('proxy');
$Authenticator->Authenticate();
}
}
}
?>
What for us, then, with no code expertise despite our envy having even close to that $100 amount at the same time? @jaredNZ, would you kindly show us some guidelines or modify and make up a full -and working- vanilla plugin?
$cUserAuth = mysql_query("SELECT * FROM GDN_UserAuthentication WHERE ForeignUserKey = ? LIMIT 1", array($cUser['id']));
$iVanillaUserID = $cUserAuth['userid']; //UserID
You could use Gdn::SQL() query builder with PDO, and mysql_query is depreciated. I'm not sure what you are trying to do here becuase the second parameter is supposed the connection identifier. You don't get the data from the query unless you fetch the row.
@EdelAli said:
What for us, then, with no code expertise despite our envy having even close to that $100 amount at the same time? jaredNZ, would you kindly show us some guidelines or modify and make up a full -and working- vanilla plugin?
This would be a nesting situation of loading the framework inside the framework. the line require_once(PATH_ROOT.DS.'bootstrap.php'); is the key line that is in each function. If you were to take out the lines:
@x00 -- mysql_query is just a placeholder, I have my own SQL sanitizer on the application I removed it from this copy-paste since it wouldn't make sense. Please do take this and replace parts to make it use Vanilla SQL.
@EdelAli -- This is more like a plugin for an external application/website/blog etc. Its not a plugin for vanilla. You could embed this in Vanilla but it wouldn't make sense I don't think? Vanilla plugins work with events, so you can't have an event trigger a user login, or an event creating a new user?
e.g. WordPress > inside the wordpress createUser function > insert line forum.createUser(...);
@businessdad -- I like hungarian for PHP, JS - Languages without strong typing built in sort of need it. Especially PHP which is so "flexible".
@jaredNZ I haven't used Hungarian Notation in a long time, simply because I didn't find it useful, despite all the attempts of my Professors and some of my former bosses to enforce it. Application Hungarian made some sense, Systems Hungarian not so much (wparam and lparam of Windows API are examples of that). Personally, I don't really care what the type of a variable is, I care about what information it carries.
Anyway, mine was not a criticism, just a "reminiscence". Everybody is free to use the notation and coding style he/she prefers. For example, I also develop for WordPress, but I can't stand "Yoda" comparisons, and I dislike spaces used within parentheses (as in if ( SomeFunc( SomeVar ) )), so I don't use them.
I don't really care what the type of a variable is, I care about what information it carries
Its for other developers reading the code later, for example:
function login(variable) {
...
}
"variable" is an argument to a function -- without looking anywhere else, what information does "variable" carry? Code must be discrete and modular according to good OOP practises.
The only real debate about hungarian is whether the extra information about the information it carries is worth making the variable name slightly less readable.
@jaredNZ said:
The only real debate about hungarian is whether the extra information about the information it carries is worth making the variable name slightly less readable.
In my opinion, the type is still irrelevant, as it might change later. That's why I find Systems Hungarian pointless. Besides, if the function is documented properly, there is no need to carry type information within its name.
/**
* The function does something.
*
* @param int UserID A User ID.
* @return some_type The User ID of User's cousin.
*/
function MyFunction($UserID) {
// UserID contains a UserID, which will be passed to methods and classes who can handle it. If that
// is an integer, a string, a float or a class, I don't really care, as I need to know how to use it anyway.
// Besides, just calling the variable $iUserID won't prevent anybody from passing another thing.
}
In case a variable has to be of a specific type, one can use Type Hinting:
function MyFunction(array $SomeVar) {
}
function MyFunction(SomeClass $SomeVar) {
}
@jaredNZ said:
businessdad - it would've been lovely to see those comments in Vanilla =P... Perhaps you can go through and add them?
I add them in every piece of code I write. Actually, some of my pastime, when I sip coffee during breaks, is looking for method that I forgot to document and fix the issue. I'm afraid that documenting the whole Vanilla Core would take me more time than I have left to live.
@businessdad said:
I'm afraid that documenting the whole Vanilla Core would take me more time than I have left to live.
Possible. I've added hundreds of lines of documentation to core and it's still eons from done. I play a game where anytime I'm flying somewhere I write inline docs during the flight and tag it with what airports I was flying between.
@jaredNZ said:
businessdad - it would've been lovely to see those comments in Vanilla =P... Perhaps you can go through and add them?
That could be a community effort once everyone knows how github works and when there's a separate branch for documentation
Besides : we know how the community Wiki is going so need a special someone to lead the documentation community. Also I wouldn't expect documentation with 2.1 until it goes really really beta or beyond
@UnderDog said:
when there's a separate branch for documentation
You can document directly on master or whatever branch you fancy, really. It's not like we'll turn it down because of performance concerns. Just match the format of the rest of it closely. Have a look around a lot of files so you get the patterns involved.
@Lincon Hacking a new solution ain't a great plan.
This is something you don't have at the moment, not a hack of past methods. This is to integrate with outside websites.
And sorry but jsConnect is just lazy and bad practise. I implemented it already as mentioned at the top of the discussion:
1 - It requires action from the user to sign up when they already are a member on your site
2 - Requires JS pings back and forth to server to do the auth using data on client side... insane?!
These are just PHP files accessing a database. There's no reason you need to do this client-side.
ProxyConnect is deprecated and will be deleted one day.
If you actually read the code you'll see it doesn't use ProxyConnect at all. Just the key for provider table which can be anything.
Comments
Thanks for the reply @hbf,
Agree, wish I had just written my own basic forum given the time spent bug fixing/trawling Vanilla's code. That said I'm using the entire themed vanilla forum (views etc), I just want it to login when I login with the other app and think requiring two logins for one site is bad-practise.
Perhaps feasible to intercept the ReadUser function and make it point to AppSite User Database? Instead of having the GDN_User table just intercept all read/write's and return custom.
I think I go back to the original point, which is you need to pay someone to do the SSO for you. You might streamline the SSO somewhat. What you want is secure sessions, with user management, there are a number of ways of achieving this. ProxyConnect is a methodology, implementations may vary.
I applaud you for making the effort, and giving it a go, but you need some expertise to debug it for you, and possibly make it streamline.
You don't actually want to replicate all the forum functionality, this would be expensive and unnecessary.
I tried my best not to mock you I was just trying to steer you in the right direction, and first find out what you real wanted to do.
grep is your friend.
Done. Set the provider key from proxy connect and it automagically creates a new user and logs them in.
Provider key comes from GDN_UserAuthentication table.
http://pastebin.com/rf4gz6Gu
glad you persevered.
grep is your friend.
What for us, then, with no code expertise despite our envy having even close to that $100 amount at the same time? @jaredNZ, would you kindly show us some guidelines or modify and make up a full -and working- vanilla plugin?
/me with that @jaredNZ . newb , now I feel even more
Well done @jaredNZ. I see that you reused existing Vanilla libraries, I think it's the best way.
By the way, the Systems Hungarian notation brings back memories...
My shop | About Me
true
@jaredNZ
I'd maybe change this
You could use
Gdn::SQL()
query builder with PDO, andmysql_query
is depreciated. I'm not sure what you are trying to do here becuase the second parameter is supposed the connection identifier. You don't get the data from the query unless you fetch the row.grep is your friend.
@jaredNZ Thanks for sharing!
Don't forget to pay out that bounty
This would be a nesting situation of loading the framework inside the framework. the line
require_once(PATH_ROOT.DS.'bootstrap.php');
is the key line that is in each function. If you were to take out the lines:from each function, you could call these functions from any Vanilla plugin.
Search first
Check out the Documentation! We are always looking for new content and pull requests.
Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.
Thanks,
@x00 -- mysql_query is just a placeholder, I have my own SQL sanitizer on the application I removed it from this copy-paste since it wouldn't make sense. Please do take this and replace parts to make it use Vanilla SQL.
@EdelAli -- This is more like a plugin for an external application/website/blog etc. Its not a plugin for vanilla. You could embed this in Vanilla but it wouldn't make sense I don't think? Vanilla plugins work with events, so you can't have an event trigger a user login, or an event creating a new user?
e.g. WordPress > inside the wordpress createUser function > insert line forum.createUser(...);
@businessdad -- I like hungarian for PHP, JS - Languages without strong typing built in sort of need it. Especially PHP which is so "flexible".
@jaredNZ I haven't used Hungarian Notation in a long time, simply because I didn't find it useful, despite all the attempts of my Professors and some of my former bosses to enforce it. Application Hungarian made some sense, Systems Hungarian not so much (
wparam
andlparam
of Windows API are examples of that). Personally, I don't really care what the type of a variable is, I care about what information it carries.Anyway, mine was not a criticism, just a "reminiscence". Everybody is free to use the notation and coding style he/she prefers. For example, I also develop for WordPress, but I can't stand "Yoda" comparisons, and I dislike spaces used within parentheses (as in
if ( SomeFunc( SomeVar ) )
), so I don't use them.My shop | About Me
Its for other developers reading the code later, for example:
"variable" is an argument to a function -- without looking anywhere else, what information does "variable" carry? Code must be discrete and modular according to good OOP practises.
vs.
bVariable carries ? boolean.
sVariable carries ? string.
iVariable carries? integer.
The only real debate about hungarian is whether the extra information about the information it carries is worth making the variable name slightly less readable.
In my opinion, the type is still irrelevant, as it might change later. That's why I find Systems Hungarian pointless. Besides, if the function is documented properly, there is no need to carry type information within its name.
In case a variable has to be of a specific type, one can use Type Hinting:
My shop | About Me
@businessdad - it would've been lovely to see those comments in Vanilla =P... Perhaps you can go through and add them?
I add them in every piece of code I write. Actually, some of my pastime, when I sip coffee during breaks, is looking for method that I forgot to document and fix the issue. I'm afraid that documenting the whole Vanilla Core would take me more time than I have left to live.
My shop | About Me
You really want to use jsConnect for single sign on.
ProxyConnect is deprecated and will be deleted one day.
Hacking a new solution ain't a great plan. We integrate many, many SSO solutions on a weekly basis, and they are nearly all based on jsConnect.
Possible. I've added hundreds of lines of documentation to core and it's still eons from done. I play a game where anytime I'm flying somewhere I write inline docs during the flight and tag it with what airports I was flying between.
That could be a community effort once everyone knows how github works and when there's a separate branch for documentation
Besides : we know how the community Wiki is going so need a special someone to lead the documentation community. Also I wouldn't expect documentation with 2.1 until it goes really really beta or beyond
There was an error rendering this rich post.
You can document directly on master or whatever branch you fancy, really. It's not like we'll turn it down because of performance concerns.
Just match the format of the rest of it closely. Have a look around a lot of files so you get the patterns involved.
This is something you don't have at the moment, not a hack of past methods. This is to integrate with outside websites.
And sorry but jsConnect is just lazy and bad practise. I implemented it already as mentioned at the top of the discussion:
1 - It requires action from the user to sign up when they already are a member on your site
2 - Requires JS pings back and forth to server to do the auth using data on client side... insane?!
These are just PHP files accessing a database. There's no reason you need to do this client-side.
If you actually read the code you'll see it doesn't use ProxyConnect at all. Just the key for provider table which can be anything.