Embed example with LDAP Authentication

jkuter

Joined: 2007-11-27
Posts: 7
Posted: Tue, 2007-11-27 14:34

I just wanted to put an example in here of what I did to embed gallery using LDAP as an authentication mechanism (index.php). I have also added to the wiki here:

http://codex.gallery2.org/LDAP_authentication

This took a lot of work to get going and I still believe it is the wrong way to do it, however it does work. Hopefull this will help someone else out.

*SESSION is unset in logout.inc
*login.php is just an input that posts the username
*LDAP does not require a password

<?php
// look for a user id in the session, if its not there start the session so we can make one
if (!isset($_SESSION['emAppUserId'])) {
	session_name('GalleryOnInside'); // Choose session name
	session_set_cookie_params(1209600);
	session_start(); // Initialize a session
}
// triggers embed classes for gallery so the below will work
require_once('embed.php');

// pull in gallery content and trigger user functions
$data = runGallery();

// set page title
$data['title'] = (isset($data['title']) && !empty($data['title'])) ? $data['title'] : 'Gallery';
//set up page html
if (isset($data['bodyHtml'])) {
	print <<<EOF
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>{$data['title']}</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
{$data['javascript']}
{$data['css']}
</head>

<body>
{$data['bodyHtml']}
</body>
</html>
EOF;
}
// Close Gallery Connection
GalleryEmbed::done();

function runGallery() {
	// required configuration of embed vars	
	$embedUri = '/phpapps/gallery2/index.php';
	$g2Uri = '/phpapps/gallery2/main.php';
	$loginRedirect = '/phpapps/gallery2/login.php';
	// see if this is an initial login and set username
	$username = isset($_POST['username']) ? $_POST['username'] : "";
	if ($username != "") {
		// try and authenticate posted name
		$auth = authenticateLogin($username);
		if ($auth['ErrorCode'] == "Username and Password validated") {
			//set config vars from LDAP
			$_SESSION['emAppUserId'] = $auth['uid'];
			$emAppUserLogin = $auth['cn'];
			$emAppUserName = $auth['fullname'];
			$emAppUserEmail = $auth['email'];
		} else {
			die('Authentication Failed: ' . $auth['ErrorCode']);
		}
	}

	if (isset($_SESSION['emAppUserId'])) {
		// if user is logged in, set user ID to emApp's session user_id
		$emAppUserId = $_SESSION['emAppUserId'];
	} else {
		// if anonymous user, set g2 activeUser to ''
		$emAppUserId = '';
	}
	
	// actually get gallery going passing all needed config
	$ret = GalleryEmbed::init(array('embedUri' => $embedUri, 'g2Uri' => $g2Uri, 'fullInit' => true, 'loginRedirect' => $loginRedirect, 'activeUserId' => $emAppUserId));

	// Display login link with our credentials from $loginRedirect
	GalleryCapabilities::set('login', true);

	if ($ret) {
		// Did we get an error because the user doesn't exist in g2 yet?
		$ret2 = GalleryEmbed::isExternalIdMapped($emAppUserId, 'GalleryUser');
		if ($ret2 && $ret2->getErrorCode() & ERROR_MISSING_OBJECT) {
			// The user does not exist in G2 yet. Create in now on-the-fly
			$ret = GalleryEmbed::createUser($emAppUserId, array ( 'username' => $emAppUserLogin, 'email' => $emAppUserEmail, 'fullname' => $emAppUserName));
			if ($ret) {
				// An error during user creation. Not good, print an error or do whatever is appropriate
				print "An error occurred during the on-the-fly user creation <br>";
				print $ret->getAsHtml();
				exit;
			}
		} else {
			// The error we got wasn't due to a missing user, it was a real error
			if ($ret2) {
				print "An error occurred while checking if a user already exists<br>";
				print $ret2->getAsHtml();
			}
			print "An error occurred while trying to initialize G2<br>";
			print $ret->getAsHtml();
			exit;
		}
	}

	// At this point we know that either the user either existed already before or that it was just created
	$g2moddata = GalleryEmbed::handleRequest();

	// show error message if isDone is not defined
	if (!isset($g2moddata['isDone'])) {
		$data['bodyHtml'] = 'isDone is not defined, something very bad must have happened.';
		return $data;
	}

	// exit if it was an immediate view / request (G2 already outputted some data)
	if ($g2moddata['isDone']) {
		exit;
	}

	// put the body html
	$data['bodyHtml'] = isset($g2moddata['bodyHtml']) ? $g2moddata['bodyHtml'] : '';

	// get the page title, javascript and css links from the <head> html from G2
	$title = ''; $javascript = array();	$css = array();

	if (isset($g2moddata['headHtml'])) {
		list($data['title'], $css, $javascript) = GalleryEmbed::parseHead($g2moddata['headHtml']);
		$data['headHtml'] = $g2moddata['headHtml'];
	}


	// Add G2 javascript
	$data['javascript'] = '';
	if (!empty($javascript)) {
		foreach ($javascript as $script) {
			$data['javascript'] .= "\n".$script;
		}
	}

	// Add G2 css
	$data['css'] = '';
	if (!empty($css)) {
		foreach ($css as $style) {
			$data['css'] .= "\n".$style;
		}
	}

	return $data;
}

function authenticateLogin($username) {
	// ldap config
	$server="ldap://myldap.server.com:389";
	$basedn="dc=ad,dc=domainname,dc=com";
	$filter="(&(objectclass=user)(cn=$username)(!(userAccountControl=66050))(!(objectclass=computer)))";
	// try and connect
	if (!($connect = ldap_connect($server))) {
		$loginError = 'Could not connect to LDAP server';
	} else {
		// Logged in - Override some options
		ldap_set_option($connect, LDAP_OPT_REFERRALS, 0);
		ldap_set_option($connect,LDAP_OPT_PROTOCOL_VERSION,3);
		$bind = ldap_bind($connect);
		// Search for the user to get the DN
		$sr = ldap_search($connect,$basedn,$filter);
		$info = ldap_get_entries($connect, $sr);
		// set basic user info
		$fullname=$info[0]["displayname"][0];
		$cn=$info[0]["cn"][0];
		$uid=$info[0]["uidnumber"][0];
		$email=$info[0]["userprincipalname"][0];
		$dn=$info[0]["dn"];

		// Store key user information in an array to be returned
		$result['fullname'] = $fullname;
		$result['uid'] = $uid;
		$result['cn'] = $cn;
		$result['email'] = $email;
		if ($dn != "") {
			$loginError = 'Username and Password validated';
		} else {
			$loginError = "Bind Failed for $dn";
		}
	}
	// set results of bind
	$result['ErrorCode'] = $loginError;
	
	return $result;
}
?>
 
rmaltete

Joined: 2008-01-04
Posts: 3
Posted: Fri, 2008-01-04 10:50

did you tried that with an AD directory ?

 
jkuter

Joined: 2007-11-27
Posts: 7
Posted: Fri, 2008-01-04 13:56

They are one in the same for us, so yes this is working with AD.

 
pinkpari

Joined: 2008-01-08
Posts: 16
Posted: Tue, 2008-01-08 12:58

hi
i am also using the same code for my application, although i dont use LDAP to authenticate. My problem is that the application seems to be working fine when i write echo in any part. I think it is the error with the headers,Can u pleaseeeeeeee guide, m struct with it from long.
View my post at
http://gallery.menalto.com/node/73116

 
jkuter

Joined: 2007-11-27
Posts: 7
Posted: Tue, 2008-01-08 14:12

Sounds like an output buffer issue. Make sure you flush out the data when you are done. I believe that GalleryEmbed::done(); will do this but you may want to stick ob_end_flush() in there to get the data out of the buffer (at the end of your script). Especially if you are using output buffering in php.ini.

See http://us2.php.net/ob_end_flush

 
pinkpari

Joined: 2008-01-08
Posts: 16
Posted: Wed, 2008-01-09 08:24

i tried doing that, but no results. For eg if i upload a picture, it will work fine for the first time but if try doing again it shows that default page cannot be displayed.Please a have a look at the file i am using at

http://gallery.menalto.com/node/73116

Thanks in advance :)

 
jkuter

Joined: 2007-11-27
Posts: 7
Posted: Wed, 2008-01-09 13:30

I unfortunately am in the middle of a very large project right now (I have been finished with gallery for about a month) and don't have time to help you debug. However I did look at you code and it seems you are trying to recreate alot of gallery functions on your own. Gallery's api can handle most of the functions you have written for displaying blocks and albums. You shoudl have another look at the api doc. Also turn debugging on so that you can see the code failures along the way. It will help you out tremedously and is how I created the above code. Sorry I can;t be of more assistance right now. Worse comes to worse you can use my code above and subsititute you own autentication function and go from there. Don't try and reinvent the wheel, the gallery developers have put alot of work into the code and even though the documentation isn't fantastic, it does exist. Perhaps someone else will see this and chime in.

 
pinkpari

Joined: 2008-01-08
Posts: 16
Posted: Thu, 2008-01-10 06:09

hi jkuter
I am really thankfull to you for atleast you thought of even guiding. I used the above code in my wrapper class, now when i debugged it extensively i found that the function GalleryEmbed::handlerequest() is returning no data at all, making the site to crash. I know ur busy but still if u can spare little time to tell what could be the reason it would be highly appreciating.
Thanks in advance

For your reference, i am putting the code below

<?php
// look for a user id in the session, if its not there start the session so we can make one
session_start();
if (!isset($_SESSION['user_id'])) {
session_name('GalleryOnInside'); // Choose session name
session_set_cookie_params(1209600);
session_start(); // Initialize a session
}
// triggers embed classes for gallery so the below will work
require_once(dirname(__File__) . '/../../gallery2/embed.php');

// pull in gallery content and trigger user functions
$data = runGallery();

global $gallery;

$gallery->setConfig('login', true);

// set page title
$data['title'] = (isset($data['title']) && !empty($data['title'])) ? $data['title'] : 'Gallery';
//set up page html
if (isset($data['bodyHtml'])) {
print <<<EOF
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>{$data['title']}</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
{$data['javascript']}
{$data['css']}
</head>

<body>
{$data['bodyHtml']}
</body>
</html>
EOF;
}

// Close Gallery Connection
GalleryEmbed::done();

function runGallery() {
// required configuration of embed vars
$embedUri = '/rang/framework/albums/Albums.php';
$g2Uri = '/rang/gallery2/';
$loginRedirect = '/rang/framework/';
// see if this is an initial login and set username

if (isset($_SESSION['user_id'])) {
// if user is logged in, set user ID to emApp's session user_id
$emAppUserId = $_SESSION['user_id'];
} else {
// if anonymous user, set g2 activeUser to ''
$emAppUserId = '';
}

// actually get gallery going passing all needed config
$ret = GalleryEmbed::init(array('embedUri' => $embedUri, 'g2Uri' => $g2Uri, 'fullInit' => true, 'loginRedirect' => $loginRedirect, 'activeUserId' => $emAppUserId));
// Display login link with our credentials from $loginRedirect
GalleryCapabilities::set('login', true);

if ($ret) {
echo "user does not exist";
} else {
// The error we got wasn't due to a missing user, it was a real error
if ($ret2) {
print "An error occurred while checking if a user already exists<br>";
print $ret2->getAsHtml();
}
print "An error occurred while trying to initialize G2<br>";
print $ret->getAsHtml();
exit;
}
}

// At this point we know that either the user either existed already before or that it was just created

$g2moddata = GalleryEmbed::handleRequest();

print_r($g2moddata); //No resust!!!!!!
// show error message if isDone is not defined
if (!isset($g2moddata['isDone'])) {
$data['bodyHtml'] = 'isDone is not defined, something very bad must have happened.';
return $data;
}

// exit if it was an immediate view / request (G2 already outputted some data)
if ($g2moddata['isDone']) {
//exit;
}

// put the body html
$data['bodyHtml'] = isset($g2moddata['bodyHtml']) ? $g2moddata['bodyHtml'] : '';

// get the page title, javascript and css links from the <head> html from G2
$title = ''; $javascript = array(); $css = array();

if (isset($g2moddata['headHtml'])) {
list($data['title'], $css, $javascript) = GalleryEmbed::parseHead($g2moddata['headHtml']);
$data['headHtml'] = $g2moddata['headHtml'];
}

// Add G2 javascript
$data['javascript'] = '';
if (!empty($javascript)) {
foreach ($javascript as $script) {
$data['javascript'] .= "\n".$script;
}
}

// Add G2 css
$data['css'] = '';
if (!empty($css)) {
foreach ($css as $style) {
$data['css'] .= "\n".$style;
}
}

return $data;
}
?>

 
jkuter

Joined: 2007-11-27
Posts: 7
Posted: Sun, 2008-01-13 13:51

The reason that handle request isnt returning any data is that:

$ret = GalleryEmbed::init(array('embedUri' => $embedUri, 'g2Uri' => $g2Uri, 'fullInit' => true, 'loginRedirect' => $loginRedirect, 'activeUserId' => $emAppUserId));

Is probably failing. In my wrapper there is another section that handles user creation. Gallery must have an external user id map table for embed to work and it must be set up properly. The best way is to have gallery do that for you (see gallery api for more info on that external map table). Most likely there is an error in #ret. Print that out to see. If not it may just not be initializing and not throwing and error, but certainly nothing will work until the init works. You can also try not using a full init (for which I have no idea what the purpose truly is). You can poke around that class in the code to see more information about its function.

In my environment we map ldap user names and uid's to the newly created gallery username (which matches) but the uid's do not match which is why that table must be created. The function that checks $ret after init is what is taking care of that for us. Good luck.