FUDforum
Fast Uncompromising Discussions. FUDforum will get your users talking.

Home » FUDforum » FUDforum Suggestions » SSO with TYPO3
Show: Today's Messages :: Unread Messages :: Show Polls :: Message Navigator
| Subscribe to topic | Bookmark topic 
Switch to threaded view of this topic Create a new topic Submit Reply
SSO with TYPO3 [message #166236] Sun, 16 October 2011 07:57 Go to next message
kaystrobach is currently offline  kaystrobach   
Messages: 28
Registered: May 2006
Location: Bannewitz
Karma: 0
Junior Member
add to buddy list
ignore all messages by this user

Hello guys,

currently i'm working on a SSO Adapter for fudforum from TYPO3 based on http://single-signon.com during the development i found some problems for implementing SSO Adapters:

first cool things:
- external_* functions are great

there some functions missing:
- it would be nice to have a additional function, called external_sync_groups(int $userId, array $groupnames), which automatically checks if a user is in the given groups an add or remove the membership
- also it would be nice to have a function like the following one to get the id for a given username without knowing a password

function external_getUserByUsername($login) {
	__fud_login_common(1);
	$r = db_sab('SELECT id FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'users WHERE login='. _esc($login));
	if($r) {
		return $r->id;
}
}


Thanks so far.

The code of the sso adapter can be obtained via PM, i will add it to single-singon.com when it's stable with group sync.

Regards
Kay
Re: SSO with TYPO3 [message #166241 is a reply to message #166236] Sun, 16 October 2011 13:17 Go to previous messageGo to next message
naudefj is currently offline  naudefj   South Africa
Messages: 3632
Registered: December 2004
Karma: 17
Senior Member
Administrator
Core Developer
add to buddy list
ignore all messages by this user
Great, the lookup function will be added.

Not sure how "external_sync_groups()" will work, but it you code it, we will definitely consider it.
Aw: Re: SSO with TYPO3 [message #166250 is a reply to message #166241] Mon, 17 October 2011 01:56 Go to previous messageGo to next message
kaystrobach is currently offline  kaystrobach   
Messages: 28
Registered: May 2006
Location: Bannewitz
Karma: 0
Junior Member
add to buddy list
ignore all messages by this user

the groups function should accept a comma list of group names (or array) and do the following stuff:

- add group if not existing
- add user to group if not member
- remove user from groups which are not in the list

This way it's really easy to have very flexible and powerfull sso adapters Wink
Re: Aw: Re: SSO with TYPO3 [message #166251 is a reply to message #166250] Mon, 17 October 2011 05:34 Go to previous messageGo to next message
naudefj is currently offline  naudefj   South Africa
Messages: 3632
Registered: December 2004
Karma: 17
Senior Member
Administrator
Core Developer
add to buddy list
ignore all messages by this user
Sounds great! Can you help us to code it?
Aw: Re: Aw: Re: SSO with TYPO3 [message #166253 is a reply to message #166251] Mon, 17 October 2011 05:37 Go to previous messageGo to next message
kaystrobach is currently offline  kaystrobach   
Messages: 28
Registered: May 2006
Location: Bannewitz
Karma: 0
Junior Member
add to buddy list
ignore all messages by this user

i do - what's the schedule for the next release?

could you please decide:

a) a name for the function
b) if the input should be a array of groups or a comma seperated string - while i prefer an array (would enable the use of commas in groupnames)

Regards
Kay
Re: Aw: Re: Aw: Re: SSO with TYPO3 [message #166256 is a reply to message #166253] Mon, 17 October 2011 06:07 Go to previous messageGo to next message
naudefj is currently offline  naudefj   South Africa
Messages: 3632
Registered: December 2004
Karma: 17
Senior Member
Administrator
Core Developer
add to buddy list
ignore all messages by this user
See FUDforum 3.0.4 - 2011/Q4 or 2012/Q1.

It doesn't really matter, we can finalize the name and input parameters later.
Aw: Re: Aw: Re: Aw: Re: SSO with TYPO3 [message #166257 is a reply to message #166256] Mon, 17 October 2011 06:36 Go to previous messageGo to next message
kaystrobach is currently offline  kaystrobach   
Messages: 28
Registered: May 2006
Location: Bannewitz
Karma: 0
Junior Member
add to buddy list
ignore all messages by this user

mhmm, i would like to use the final name in the sso adapter to avoid refactoring Wink
Aw: Re: Aw: Re: Aw: Re: SSO with TYPO3 [message #166258 is a reply to message #166257] Mon, 17 October 2011 09:08 Go to previous messageGo to next message
kaystrobach is currently offline  kaystrobach   
Messages: 28
Registered: May 2006
Location: Bannewitz
Karma: 0
Junior Member
add to buddy list
ignore all messages by this user

during working with fudforum i found a problem :

function db_all($q)
{
	return uq($q)->fetchAll(PDO::FETCH_COLUMN);
}


should be

function db_all($q)
{
	$qo = uq($q);
	if(method_exists($qo, 'fetchAll)) {
		return ->fetchAll(PDO::FETCH_COLUMN);
	} else {
		return null;
	}
}
Aw: Re: Aw: Re: Aw: Re: SSO with TYPO3 [message #166259 is a reply to message #166258] Mon, 17 October 2011 11:47 Go to previous messageGo to next message
kaystrobach is currently offline  kaystrobach   
Messages: 28
Registered: May 2006
Location: Bannewitz
Karma: 0
Junior Member
add to buddy list
ignore all messages by this user

currently i struggle at the following problem:

my function looks so:

function sso_syncGroups($userID, $groupNames) {
		// iterate
	foreach($groupNames as $groupName) {
			// Use special name
		$groupName = 'SSO: ' . $groupName;
			// Check wether group exists
		$r = db_sab('SELECT id FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'groups WHERE name='. _esc($groupName));
		if($r) {
			$groupId = $r->id;
		} else {
			$groupId = ins_m(
				$GLOBALS['DBHOST_TBL_PREFIX'] .'groups',
				'name',
				_esc($groupName)
			);
		}
			// Check wether user is in group and add it
		$r = db_sab('SELECT id FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'group_members WHERE group_id='. _esc($groupId) . ' AND user_id=' . _esc($userID));
		if(!$r) {
			ins_m(
				$GLOBALS['DBHOST_TBL_PREFIX'] .'group_members',
				'group_id, user_id',
				array(
					_esc($groupId),
					_esc($userID)
				)
			);
		}
	}
		// remove groups which are removed in external adapter
	$list = '';
	foreach($groupNames as $groupName) {
		if($list !== '') {
			$list.= ', ';
		}
		$list.= _esc($groupName);
	}
	$q = '
		SELECT * 
		FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'group_members 
		LEFT JOIN '. $GLOBALS['DBHOST_TBL_PREFIX'] .'groups ON '. $GLOBALS['DBHOST_TBL_PREFIX'] .'group_members.group_id = fud_groups.id
		WHERE '. $GLOBALS['DBHOST_TBL_PREFIX'] .'group_members.user_id = ' . _esc($userID) . '
		AND '. $GLOBALS['DBHOST_TBL_PREFIX'] .'groups.name NOT IN (' . $list . ')
		AND '. $GLOBALS['DBHOST_TBL_PREFIX'] .'groups.name LIKE "SSO:%"
	';
	$groupsToRemove = uq($q);
	if(method_exists($groupsToRemove, 'fetchAll')) {
		$groupsToRemove = $groupsToRemove->fetchAll(PDO::FETCH_COLUMN);
		foreach($groupsToRemove as $group) {
			echo $group;
			uq('DELETE FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'group_members WHERE id = ' . _esc($group->id));
		}
	}
}


Using external_fud_login($User_ID) afterwards throws the following sql error - any idea?

HY000: Cannot execute queries while other unbuffered queries are active.


Thanks in advice - regards
Kay
Aw: Re: Aw: Re: Aw: Re: SSO with TYPO3 [message #166263 is a reply to message #166259] Tue, 18 October 2011 23:42 Go to previous messageGo to next message
kaystrobach is currently offline  kaystrobach   
Messages: 28
Registered: May 2006
Location: Bannewitz
Karma: 0
Junior Member
add to buddy list
ignore all messages by this user

would be nice, if you would point me to the right usage of the fudapi (know how to bypass it - but that should'nt be the goal).

Below is the complete adapter throwing the error:

The function sso is called twice in my use case:
1. create user
2. login user

The Problem occurs during login, if i add the groups, so i assume, that i misuse some of the api functions, but i didn't found anyway to close the buffered query cursors in your queries (except closing the connection ...)

<?php
/*
* Signature-Based Single Sign-On Framework
* TPA Adapter for
* fudforum (http://www.fudforum.org )
*
*  Version            : 3.0.3
*  Last update        : 13.10.2011
*
* (c) Kay Strobach, Bannewitz, Germany
*  http://www.kay-strobach.de
*  http://www.single-signon.com
*/

/**
*  function which is called after including this file in the SSO-Agent.
*
*  @param
*    User_Name    string    Username the Session will be created for
*    remote_addr  string    Remoteaddress of the users system
*    agent        string    Browser
*    sso_url      string    Url where the user will be redirected after establishing a session for him
*    sso_version  string    the protocol version of the calling agent
*    sso_action   string    the action to perform. Right now this is either 'logon' or 'create_modify'
*    sso_userdata string    the userdata submitted by the agent
*
*  @return        string    return the session data
*
*  Leave stubs if you dont need all four params.
*/

/*
* return the protocol version
*/

//include libs
require_once('GLOBALS.php');
require_once($INCLUDE.'../scripts/forum_login.php');
require_once($INCLUDE.'../scripts/fudapi.inc.php');



function get_version(){
	return "2.0";
}

function sso($User_Name,$ip,$agent,$sso_url,$sso_version="",$sso_action="",$sso_userdata="") {
		// alternative: return error
	if ($sso_version == "") return array("Error"=>"sso version out of date");

		//process sso data
	$sso_userdata = process_userdata($sso_userdata);

	$User_ID   = sso_get_userByUsername($User_Name);

	$err = null;

	switch($sso_action){	
		// action: create user / update userdata
		case 'create_modify':
			$vals = array(
				'login' =>$User_Name,
				'passwd'=>md5(microtime(true)),
				'email' =>$sso_userdata['email'],
				'name'  =>$sso_userdata['name']
			);

			__fud_login_common(1);

			if(!$User_ID) {
				$User_ID = fud_add_user(
					$vals,
					$err
				);
			} else {
				fud_update_user(
					$User_ID,
					$vals,
					$err
				);
			}
			if(array_key_exists('usergroup', $sso_userdata)) {
				sso_syncGroups($User_ID, explode(',', $sso_userdata['usergroup']));
			}
		break;
		// perform logon for given $User_Name
		case 'logon':
			if (external_fud_login($User_ID)) {
				$return_val    = array();
				$return_val[0] = array();
				$return_val   += array( "redirecturl" => $sso_url);
				return $return_val;
			}
			return array("Error"=>"no account for this user");
		break;
	}
}

/* 
* process the userdata string and return an associative array
* @param string $sso_userdata: the data from fe_users (pipe-separated)
* @return array	$data: the userdata
*/
function process_userdata($sso_userdata){
	$sso_userdata = split("\|",$sso_userdata);
	for ($i=0;$i<count($sso_userdata);$i++) {
		$sso_userdata[$i]=split("=",$sso_userdata[$i]);
		$data[$sso_userdata[$i][0]]=$sso_userdata[$i][1];
	}
	unset ($sso_userdata);
	return $data;
}


function sso_get_userByUsername($login) {
	__fud_login_common(1);
	$r = db_sab('SELECT id FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'users WHERE login='. _esc($login));
	if($r) {
		return $r->id;
	}
}
function sso_syncGroups($userID, $groupNames) {
		// iterate
	foreach($groupNames as $groupName) {
			// Use special name
		$groupName = 'SSO: ' . $groupName;
			// Check wether group exists
		$r = db_sab('SELECT id FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'groups WHERE name='. _esc($groupName));
		if($r) {
			$groupId = $r->id;
		} else {
			$groupId = ins_m(
				$GLOBALS['DBHOST_TBL_PREFIX'] .'groups',
				'name',
				_esc($groupName)
			);
		}
			// Check wether user is in group and add it
		$r = db_sab('SELECT id FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'group_members WHERE group_id='. _esc($groupId) . ' AND user_id=' . _esc($userID));
		if(!$r) {
			ins_m(
				$GLOBALS['DBHOST_TBL_PREFIX'] .'group_members',
				'group_id, user_id',
				array(
					_esc($groupId),
					_esc($userID)
				)
			);
		}
	}
		// remove groups which are removed in external adapter
	$list = '';
	foreach($groupNames as $groupName) {
		if($list !== '') {
			$list.= ', ';
		}
		$list.= _esc($groupName);
	}
	$q = '
		SELECT * 
		FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'group_members 
		LEFT JOIN '. $GLOBALS['DBHOST_TBL_PREFIX'] .'groups ON '. $GLOBALS['DBHOST_TBL_PREFIX'] .'group_members.group_id = fud_groups.id
		WHERE '. $GLOBALS['DBHOST_TBL_PREFIX'] .'group_members.user_id = ' . _esc($userID) . '
		AND '. $GLOBALS['DBHOST_TBL_PREFIX'] .'groups.name NOT IN (' . $list . ')
		AND '. $GLOBALS['DBHOST_TBL_PREFIX'] .'groups.name LIKE "SSO:%"
	';
	$groupsToRemove = uq($q);
	if(method_exists($groupsToRemove, 'fetchAll')) {
		$groupsToRemove = $groupsToRemove->fetchAll(PDO::FETCH_COLUMN);
		foreach($groupsToRemove as $group) {
			echo $group;
			uq('DELETE FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'group_members WHERE id = ' . _esc($group->id));
		}
	}
}
Aw: Re: Aw: Re: Aw: Re: SSO with TYPO3 [message #166292 is a reply to message #166263] Wed, 02 November 2011 05:00 Go to previous messageGo to next message
kaystrobach is currently offline  kaystrobach   
Messages: 28
Registered: May 2006
Location: Bannewitz
Karma: 0
Junior Member
add to buddy list
ignore all messages by this user

no idea so far - i would really like to get the sso adapter ready, and the problem seems to be a small misuse of the fud db api - so please provide a tipp Wink

[Updated on: Wed, 02 November 2011 05:00]

Report message to a moderator

Re: Aw: Re: Aw: Re: Aw: Re: SSO with TYPO3 [message #166293 is a reply to message #166292] Wed, 02 November 2011 05:36 Go to previous messageGo to next message
naudefj is currently offline  naudefj   South Africa
Messages: 3632
Registered: December 2004
Karma: 17
Senior Member
Administrator
Core Developer
add to buddy list
ignore all messages by this user
> "Cannot execute queries while other unbuffered queries are active."

Use q() instead of uq();
Aw: Re: Aw: Re: Aw: Re: Aw: Re: SSO with TYPO3 [message #166298 is a reply to message #166293] Wed, 02 November 2011 06:35 Go to previous message
kaystrobach is currently offline  kaystrobach   
Messages: 28
Registered: May 2006
Location: Bannewitz
Karma: 0
Junior Member
add to buddy list
ignore all messages by this user

is db_sab buffering ready, for me it seems, that using that function is the problem, so i replaced it as well.

the following function should be modified for future releases:

function db_all($q)
{
	$r = uq($q);
	if($r) {
		return $r->fetchAll(PDO::FETCH_COLUMN);
	} else {
		return array();
	}
}


i still have the same problem, it always occurs in sso_get_userByUsername

This is my current state (same error and a bit frustrated Very Happy ):

<?php
/*
* Signature-Based Single Sign-On Framework
* TPA Adapter for
* fudforum (http://www.fudforum.org )
*
*  Version            : 3.0.3
*  Last update        : 13.10.2011
*
* (c) Kay Strobach, Bannewitz, Germany
*  http://www.kay-strobach.de
*  http://www.single-signon.com
*/

/**
*  function which is called after including this file in the SSO-Agent.
*
*  @param
*    User_Name    string    Username the Session will be created for
*    remote_addr  string    Remoteaddress of the users system
*    agent        string    Browser
*    sso_url      string    Url where the user will be redirected after establishing a session for him
*    sso_version  string    the protocol version of the calling agent
*    sso_action   string    the action to perform. Right now this is either 'logon' or 'create_modify'
*    sso_userdata string    the userdata submitted by the agent
*
*  @return        string    return the session data
*
*  Leave stubs if you dont need all four params.
*/

/*
* return the protocol version
*/

//include libs
require_once('GLOBALS.php');
require_once($INCLUDE.'../scripts/forum_login.php');
require_once($INCLUDE.'../scripts/fudapi.inc.php');


define('fud_debug', 1);

function get_version(){
	return "2.0";
}

function sso($User_Name,$ip,$agent,$sso_url,$sso_version="",$sso_action="",$sso_userdata="") {
		// alternative: return error
	if ($sso_version == "") return array("Error"=>"sso version out of date");

		//process sso data
	$sso_userdata = process_userdata($sso_userdata);

	__fud_login_common(1);
	$User_ID   = sso_get_userByUsername($User_Name);

	$err = null;

	switch($sso_action){	
		// action: create user / update userdata
		case 'create_modify':
			$vals = array(
				'login' =>$User_Name,
				'passwd'=>md5(microtime(true)),
				'email' =>$sso_userdata['email'],
				'name'  =>$sso_userdata['name']
			);

			

			if(!$User_ID) {
				$User_ID = fud_add_user(
					$vals,
					$err
				);
			} else {
				fud_update_user(
					$User_ID,
					$vals,
					$err
				);
			}
			if(array_key_exists('usergroup', $sso_userdata)) {
				sso_syncGroups($User_ID, explode(',', $sso_userdata['usergroup']));
			}
		break;
		// perform logon for given $User_Name
		case 'logon':
			if (external_fud_login($User_ID)) {
				$return_val    = array();
				$return_val[0] = array();
				$return_val   += array( "redirecturl" => $sso_url);
				return $return_val;
			}
			return array("Error"=>"no account for this user");
		break;
	}
}

/* 
* process the userdata string and return an associative array
* @param string $sso_userdata: the data from fe_users (pipe-separated)
* @return array	$data: the userdata
*/
function process_userdata($sso_userdata){
	$sso_userdata = split("\|",$sso_userdata);
	for ($i=0;$i<count($sso_userdata);$i++) {
		$sso_userdata[$i]=split("=",$sso_userdata[$i]);
		$data[$sso_userdata[$i][0]]=$sso_userdata[$i][1];
	}
	unset ($sso_userdata);
	return $data;
}


function sso_get_userByUsername($login) {
	$r = db_all('SELECT id FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'users WHERE login='. _esc($login));
	if(count($r)) {
		return $r[0];
	}
}
function sso_syncGroups($userID, $groupNames) {
		// iterate
	foreach($groupNames as $groupName) {
			// Use special name
		$groupName = 'SSO: ' . $groupName;
			// Check wether group exists
		
		$r = db_all('SELECT id FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'groups WHERE name='. _esc($groupName));
		
		if(count($r)) {
			$groupId = $r[0];
		} else {
			$groupId = ins_m(
				$GLOBALS['DBHOST_TBL_PREFIX'] .'groups',
				'name',
				0,
				array(
					_esc($groupName)
				)
			);
		}
			// Check wether user is in group and add it
		$r = db_all('SELECT id FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'group_members WHERE group_id='. _esc($groupId) . ' AND user_id=' . _esc($userID));
		if(!count($r)) {
			ins_m(
				$GLOBALS['DBHOST_TBL_PREFIX'] .'group_members',
				'group_id, user_id',
				0,
				array(
					_esc($groupId) . ',' . _esc($userID)
				)
			);
		}
	}
		// remove groups which are removed in external adapter
	$list = '';
	foreach($groupNames as $groupName) {
		if($list !== '') {
			$list.= ', ';
		}
		$list.= _esc($groupName);
	}
	$q = '
		SELECT fud_group_members.id 
		FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'group_members 
		LEFT JOIN '. $GLOBALS['DBHOST_TBL_PREFIX'] .'groups ON '. $GLOBALS['DBHOST_TBL_PREFIX'] .'group_members.group_id = fud_groups.id
		WHERE '. $GLOBALS['DBHOST_TBL_PREFIX'] .'group_members.user_id = ' . _esc($userID) . '
		AND '. $GLOBALS['DBHOST_TBL_PREFIX'] .'groups.name NOT IN (' . $list . ')
		AND '. $GLOBALS['DBHOST_TBL_PREFIX'] .'groups.name LIKE "SSO:%"
	';
	$groupsToRemove = db_all($q);
	if(count($groupsToRemove)) {
		foreach($groupsToRemove as $group) {
			echo $group;
			q('DELETE FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'group_members WHERE id = ' . _esc($group));
		}
	}
}
Quick Reply
Formatting Tools:   
  Switch to threaded view of this topic Create a new topic
Previous Topic: RSS 2 Topic
Next Topic: list all smilies on the same page
Goto Forum:
  

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ]

Current Time: Fri Dec 15 16:52:10 EST 2017

Total time taken to generate the page: 0.00566 seconds