News:

Wondering if this will always be free?  See why free is better.

Main Menu

integrate_verify_user with SMF 2.0

Started by devnul, June 03, 2014, 03:05:32 PM

Previous topic - Next topic

devnul

Hi community,

I have intagrated SMF Forum into a larger site and the complete SMF Code resides in a subdirectory under DOCUMENT_ROOT.
After upgrading SMF 1.1.13 to SMF 2.0.7, I tried to re-implement the code, for checking if the user is known and already logged in. This workes fine with the old version and the code introduced in: http://www.simplemachines.org/community/index.php?topic=233362.msg1510078#msg1510078 . But this code does not work as expected, when I use it in SMF 2.0.7. Instead of welcome me as known user, the forum displays a login page.
My questions now:
Are there any changes on the way, to achieve the expected behaviour (welcome already known users instead of let them login once again) ?
Is there another code example?
How to avoid the extra login?

Thanks in advance
devnul

Kindred

Слaва
Украинi

Please do not PM, IM or Email me with support questions.  You will get better and faster responses in the support boards.  Thank you.

"Loki is not evil, although he is certainly not a force for good. Loki is... complicated."

devnul

Quote from: Kindred on June 03, 2014, 11:59:33 PM
http://wiki.simplemachines.org/smf/Integration_hooks
yes, I had read this before. And after reading, my questions are still open. Please excuse my stupidness. Maybe I could understand this stuff by a concrete example.
My integration code looks like this:

forum/index.php

<?php
session_start
();
$incdir "include";
require_once(
$_SERVER['DOCUMENT_ROOT']."/$incdir/basic_set.php");
dbconnect(true); 
// here is the code, I use to check if the user is logged in in the "parent" system
// it sets $logged_in to true or false
if ($logged_in) {
   
define('SMF_INTEGRATION_SETTINGS'serialize(array(
      
'integrate_verify_user' => 'integrate_verify_user',
   )));

   function 
integrate_verify_user () {
    
// ... as described in http://www.simplemachines.org/community/index.php?topic=233362.msg1510078#msg1510078
    // ... do an INSERT INTO {$db_prefix}members, if the user is logged in and uses the forum the first time
    // ... returns SMF's user-id
  
}
}
// ... here follows the original index.php, as installed by upgrade


as I read the Integration_hooks manual, I should use
add_integration_function('integrate_verify_user', 'integrate_verify_user', TRUE)
instead of
   define('SMF_INTEGRATION_SETTINGS', serialize(array(  'integrate_verify_user' => 'integrate_verify_user',  )));

Is this the only change, I have to make, or are there further ones?
Could I use the outer logic, to add and define the hook only, if the user is logged in?
I'm really confused. Please be patient with a grandfather like me  :)

Thank you once more

Arantor

Question: why are you starting your own session?

SMF will start the session itself, then call your hook to obtain the user id based on your external routine...

devnul

Quote from: Arantor on June 04, 2014, 12:02:59 PM
Question: why are you starting your own session?
...
This is, because the forum is just a sub-page of a bigger site, where a session already is active, because the user has to login there. Otherwise he/she will see only a very small section of the forum, where a anonymous user can ask for an invite to our closed community. As I implemented it 4 years ago, I examined this was necessary to get proper functionality. Maybe I don't need it anymore with 2.0.

Do you have a hint or example 4 me, to reduce my doubt?

Thank you.

devnul

after playing around a little bit, I've changed my code to:
forum/index.php (the very top of the file)

<?php

require_once($_SERVER['DOCUMENT_ROOT']."/include/basic_set.php");  // function dbconn() is defined here
dbconn(true);     // connects to external DB

function integrate_verify_user ()
{

  global 
$external_db$db_name$db_prefix$sql$userdata;

  
$uid = isset($_COOKIE['user_main_id']) ? $_COOKIE['user_main_id'] : false;
  
$u mysql_query"SELECT username, passhash, email FROM {$external_db}.users WHERE user_main_id='$uid'"();
  if (
mysql_num_rows($u) > )
  {
    
$userdata mysql_fetch_assoc($u);
  }  else  {
    
// user is unknown
    
return 0;
  }
  
$query mysql_query("SELECT id_member FROM {$db_prefix}members WHERE member_Name = '$userdata[username]'");

  
// does a user with this name exists in SMF-DB?
  
if ( ! ( list($ID_MEMBER) = mysql_fetch_row($query) ) )
  {
    
// if not, create one ...
      
mysql_query("INSERT INTO {$db_prefix}members
        (member_name, real_name, passwd, email_address, date_registered, id_group, id_post_group, lngfile, last_login, buddy_list, pm_ignore_list, message_labels, personal_text, website_title, website_url, location, icq, msn, hide_email, signature, avatar, usertitle, member_ip, member_ip2, secret_question, additional_groups)
        VALUES ('
$userdata[username]', '$userdata[username]', '$userdata[passhash]', '$userdata[email]', ".time().", '10', '4', 'german-utf8', NOW(), '', '', '', '', '', '', '', '', '', '1', '', '', '', '', '', '', '')");
    
// ... and fetch the new created id 
      
$ID_MEMBER mysql_insert_id();
  }
  return 
$ID_MEMBER;
}

$modSettings['integrate_verify_user'] = 'integrate_verify_user';

// ... here follows the rest of original index.php ...


but this will not work though. :(
When calling forum/index.php from my main page, where I'm already logged in, the forum welcomes me with
QuoteWillkommen %1$s. Bitte einloggen oder registrieren.
(on english this would be
QuoteWelcome %1$s Please log in or register.
) ...
I've checked the cookies and there are all values as expected, delivered from the main site. I manually checked the SQL statements and they return also values as expected.
How can I determine, the function integrate_verify_user is called? How can I debug it by setting a global $MYDEBUGVAR and display its value later on welcome page? Where I have to place the "echo $MYDEBUGVAR;" in the code?

I'm absolutely confused, where to place this stuff, especially where and how to write the line with $modSettings[...]=...
Is there a step by step tutorial, how to realize a integrate_ hook function?
The page http://wiki.simplemachines.org/smf/Integration_hooks is very hard to understand for not native english speakers like me, so a complete sample will help much more. It would be enough to provide pseudo-code on most of the sample. Only the one or two syntax-relevant things should be as exact as possible.

Thanks in advance again
hopefully
devnul

PS. @Arantor: You're right, it is not necessary to start the session again. I omit the appropriate line. Thank you for that hint.

Kindred

why are you calling index.php from your main page?   Are you trying to run the forum inside another page?  in an iframe?   neither of those is a particularly good choice.
Слaва
Украинi

Please do not PM, IM or Email me with support questions.  You will get better and faster responses in the support boards.  Thank you.

"Loki is not evil, although he is certainly not a force for good. Loki is... complicated."

devnul

Quote from: Kindred on June 11, 2014, 04:28:25 PM
why are you calling index.php from your main page?   
because this main page is a larger framework, were the users where authenticated already and I won't them to log in twice. The forum is just a "sub-function" of my communities site. My purpose is to re-use this authentification, as I understand the description of "integrate_verify_user".
Do I misunderstand this? Is there another way to achieve the described behaviour?

Quote from: Kindred on June 11, 2014, 04:28:25 PM
Are you trying to run the forum inside another page?  in an iframe?   neither of those is a particularly good choice.
no, only bypassing SMF's login-page is wanted. The forum itself runs in its own framework in an own subdirectory. I want to keep this bridge as simple as possible.
(btw. I HATE iframes  ;D )

Thanks for further suggestions
devnul

Kindred

Are you using SMF's authentication system?

It almost sound slike your should be using the API rather than the hooks.
Слaва
Украинi

Please do not PM, IM or Email me with support questions.  You will get better and faster responses in the support boards.  Thank you.

"Loki is not evil, although he is certainly not a force for good. Loki is... complicated."

devnul

Quote from: Kindred on June 11, 2014, 05:04:12 PM
Are you using SMF's authentication system?
...
this is a question of viewpoint.  :)
Yes, because I create a user with his (unique) nickname, he has in the outer system, in SMFs DB, if he does not exists in SMF. And SMF rely on its own db values (id, credentials, ...)
No because the initial register, auth, verifying, etc., is done in the outer system.
just have a look on the code, I posted above: http://www.simplemachines.org/community/index.php?topic=523372.msg3706713#msg3706713

thanks again
devnul

Kindred

then I think you are doing it wrong.

the hooks are used to trigger additional or outside actions during the SMF function calls...

If you are inserting the user into the SMF stuff form a third party system, then you should be using the SMF API instead... 
Слaва
Украинi

Please do not PM, IM or Email me with support questions.  You will get better and faster responses in the support boards.  Thank you.

"Loki is not evil, although he is certainly not a force for good. Loki is... complicated."

Arantor

No... he's got the right idea.

His system injects the user, this is simply about telling SMF to replace how it normally detects the cookie and rely on a third party system to feed it a user id (which is known)

Adding to the $modSettings array means tweaking the smf_settings table, adding a row where the 'variable' is 'integrate_verify_user' and where the value is the name of the function to call which must already have been loaded (in which case a reference to the file must be left in a similar setting called 'integrate_pre_load' which contains the path of a file to load during bootstrap)

devnul

#12
Quote from: Arantor on June 11, 2014, 05:56:42 PM
No... he's got the right idea.
Thank you very much for this sentence.

Quote from: Arantor on June 11, 2014, 05:56:42 PM
Adding to the $modSettings array means tweaking the smf_settings table, adding a row where the 'variable' is 'integrate_verify_user' and where the value is the name of the function to call which must already have been loaded (in which case a reference to the file must be left in a similar setting called 'integrate_pre_load' which contains the path of a file to load during bootstrap)
1. Does this mean, I have to place the code of function integrate_verify_user(){...} in an external file (eg. "{$_SERVER['DOCUMENT_ROOT']}/forum/my_integrate_verify_user.php" ) instead of the very top of index.php?

2. For $modSettings, should I issue: INSERT INTO myforum_settings (variable, value)
VALUES
('integrate_pre_load', '/srv/www/htdocs/forum/my_integrate_verify_user.php'),
('integrate_verify_user', 'integrate_verify_user')
with phpmyadmin or similar, is this right?

Very thanks
devnul

edited: deleted a comma, that was too much in SQL Statement

Arantor

1. Yes. That's the way it should be anyway - don't pollute SMF's code (or anything else) when you can just instruct SMF to do it for you cleanly.

2. Yes, that looks fine to me. Though your original code borrowed from declaring a constant with the serialised array of settings which also would have worked too.

devnul

hm, I've done as described above, but it still doesn't work  :(
So as last ressort for debugging, I've spread a few trigger_error("file reached",E_USER_NOTICE); over my new my_integrate_verify_user.php, to see what happen in apaches error-log.
As a result, I see, the file with the integrate_ function is not reached. When I put this line in index.php, error log throws "PHP Notice:  file reached in /srv/www/forum/index.php on line 131", as expected.

So let us determine, why SMF is not calling the new codefile.
Where should I start to search by putting the trigger_error() on several places, one after another?

-------------------------------
foreach ($post_in_this_thread as $t) { if ($member != 'devnul') echo "Many Thanks";} ;D

devnul

added a trigger_error in Sources/Subs.php in function "call_integration_hook"  in line 4199:
trigger_error("  DEBUG: call_integration_hook: $hook   ". (empty($modSettings[$hook])?'':"- modSettings:".$modSettings[$hook])."  ",E_USER_NOTICE);
and called forum after logged in on main page with a link there.

Apache-error-logfile:

... PHP Notice:    DEBUG: call_integration_hook: integrate_pre_load   - modSettings:/srv/www/htdocs/forum/my_integrate_verify_user.php  in /srv/www/htdocs/forum/Sources/Subs.php on line 4199...
... PHP Notice:    DEBUG: call_integration_hook: integrate_output_error in /srv/www/htdocs/forum/Sources/Subs.php on line 4199  ...
... PHP Notice:    DEBUG: call_integration_hook: integrate_output_error in /srv/www/htdocs/forum/Sources/Subs.php on line 4199  ...
(last line is repeated 17 times)


I stuck. What I'm doing wrong?
Why is my hook-function not called?

my_integrate_verify_user.php:

<?php

trigger_error
("DEBUG file reached",E_USER_NOTICE);
// ... some code

function integrate_verify_user()
{
  
// ... some initializing code ...
  
trigger_error("DEBUG user_id:$user_id",E_USER_NOTICE);
  
// ... some code ...
  
return 0;
}

?>



If anyone of the SMF-Cracks would implement and try to run this test-code and then post a runnable solution, my thankfulness will follow him the next 5 years  ;)

Arantor

What URL are you hitting when you try to do this, exactly?

devnul

Quote from: Arantor on June 12, 2014, 02:55:47 PM
What URL are you hitting when you try to do this, exactly?
on my third party page, there is a link:
<a href="forum/index.php" target="_blank" title="Our Forum">Forum</a>
This link is only displayed, when the user is authenticated and user-id-cookie is set.

Arantor

That wasn't quite what I meant.

The integration hooks only run when SMF is running. So you're just going to index.php when this stuff is happening?

devnul

Quote from: Arantor on June 12, 2014, 03:14:56 PM
The integration hooks only run when SMF is running. So you're just going to index.php when this stuff is happening?
Yes, it doesn't matter, if I calling forum/index.php via link or directly via adressline in browser. As I put the trigger_error into "Sources/Subs.php" intothe function "call_integration_hook" immediatly after "global $modSettings;" , I could see SMF is running, because it calls this file and the function "call_integration_hook". But it does not call my custom file.
I hope, I don't misunderstand your question.

Advertisement: