Wordpress Plugin

From RavenWiki
Revision as of 15:09, 26 September 2008 by mvl22 (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

This is a plugin to Raven which was written by Daniel Hill for a student-run Wordpress site.

It is provided 'as is' without support and may not work for everyone.

Note that www.DEPARTMENT.cam.ac.uk must be changed below.


<?php
/*
Plugin Name: Raven Logins
Description: Uses raven to authenticate users.
Author: Daniel Hill
Author URI: http://www.serenestudios.co.uk/
Version: 1.0 + subsequent changes following update to ucam_webauth
*/

/* This was written for the a student-run newspaper site so may require changes in terms of the 'categories' bit below */



// Load the Raven class
require_once ($_SERVER['DOCUMENT_ROOT'] . '/wp-content/plugins/ucam_webauth.php');



// Hook for adding admin menus
add_action('admin_menu', 'sscms_raven_add_pages');

function sscms_raven_add_pages()
{
	add_submenu_page('users.php', 'Raven Authentication', 'Raven Authentication', 8, 'sscms_raven', 'sscms_raven_admin_page');
}
add_action('lost_password','raven_disable_function');
add_action('retrieve_password', 'raven_disable_function');
add_action('password_reset', 'raven_disable_function');
add_action('register_form','raven_disable_function');
add_action('check_passwords', 'raven_check_passwords', 10, 3);
add_filter('show_password_fields','raven_show_password_fields');
add_action('wp_authenticate', 'raven_authenticate', 10, 2);
add_action('wp_logout', 'raven_logout');

add_filter('get_comment_author', 'raven_get_comment_author');


add_action('admin_head', 'sscms_raven_admin_page_process');




function sscms_raven_admin_page() {
	$kms = array();
	$as = array();
	$ms = array();
	
	if(file_exists(ABSPATH . PLUGINDIR . '/ravenkeys/keymasters.rkf'))
		$kms = unserialize(file_get_contents(ABSPATH . PLUGINDIR . '/ravenkeys/keymasters.rkf'));
	if(file_exists(ABSPATH . PLUGINDIR . '/ravenkeys/admins.rkf'))
		$as = unserialize(file_get_contents(ABSPATH . PLUGINDIR . '/ravenkeys/admins.rkf'));
	if(file_exists(ABSPATH . PLUGINDIR . '/ravenkeys/members.rkf'))
		$ms = unserialize(file_get_contents(ABSPATH . PLUGINDIR . '/ravenkeys/members.rkf'));
	
	foreach($kms as $key)
	{
		$kms_o .= $key . "\n";
	}
	foreach($as as $key)
	{
		$as_o .= $key . "\n";
	}
	foreach($ms as $key)
	{
		$ms_o .= $key . "\n";
	}
	
?>
	<div class="wrap">
	<h2>Raven</h2>
    <p>Raven authenticated users fall into three categories: keymasters can do everything; section editors can edit content that is assigned to them. Anyone else can sign in to post comments and no more.</p>
    <p>In each box, simply enter one crsid (the abc123 of abc123@cam.ac.uk) per line and hit save. To specify which sections a section editor can work with, enter a semicolon followed by a list of section after their name (for example 'abc123: news, music, theatre').</p>
    <form method="post">
	<h3>Keymasters:</h3>
	<p><textarea name="kms" rows="5" cols="70"><?php echo $kms_o ?></textarea></p>
    
    <h3>Section Editors:</h3>
	<p><textarea name="as" rows="5" cols="70"><?php echo $as_o ?></textarea></p>
    
    <p>(Available sections are: <?php 
	$categories = get_categories();
	foreach($categories as $cat)
	{
		//print_r($cat);
		echo strtolower($cat->category_nicename) . ', '; 
			
	}
	 ?>)</p>
    
    <!--<h3>Authors:</h3>
	<p><textarea name="ms" rows="5" cols="70"><?php echo $ms_o ?></textarea></p>-->
	
	<p class="submit alignleft">
		<input name="submit" type="submit" value="<?php _e('Update'); ?>" tabindex="90" />
	</p>
	</form>
    </div>
<?php
}

function sscms_raven_admin_page_process()
{
	if(isset($_POST['kms']) || isset($_POST['as']) || isset($_POST['ms']))
	{
		
		$kms_t = explode("\n", trim(trim($_POST['kms']), "\n") . "\n");
		$as_t = explode("\n", trim(trim($_POST['as']), "\n") . "\n");
		$ms_t = explode("\n", trim(trim($_POST['ms']), "\n") . "\n");
		$kms_o = '';
		$as_o = '';
		$ms_o = '';
		if(is_array($kms_t))
		{			
			$kms_o = serialize($kms_t);
		}
		if(is_array($as_t))
		{			
			$as_o = serialize($as_t);
		}
		if(is_array($ms_t))
		{
			$ms_o = serialize($ms_t);
		}
		
		
		$file_handle = fopen(ABSPATH . PLUGINDIR . '/ravenkeys/keymasters.rkf',"w+");
		chmod(ABSPATH . PLUGINDIR . '/ravenkeys/keymasters.rkf', 0777);
		fwrite($file_handle, $kms_o);
		fclose($file_handle);
		$file_handle = fopen(ABSPATH . PLUGINDIR . '/ravenkeys/admins.rkf',"w+");
		chmod(ABSPATH . PLUGINDIR . '/ravenkeys/admins.rkf', 0777);
		fwrite($file_handle, $as_o);
		fclose($file_handle);
		$file_handle = fopen(ABSPATH . PLUGINDIR . '/ravenkeys/members.rkf',"w+");
		chmod(ABSPATH . PLUGINDIR . '/ravenkeys/members.rkf', 0777);
		fwrite($file_handle, $ms_o);
		fclose($file_handle);
	}
}


		
/*
	We call phpCAS to authenticate the user at the appropriate time (the script dies there if login was unsuccessful)
	If the user has not logged in previously, we create an accout for them
*/
function raven_authenticate($username, $password) {
	global $using_cookie;
	
	if($username == 'admin')
		return;
	
	require_once(ABSPATH . '/wp-settings.php');

	// Reset values from input ($_POST and $_COOKIE)
	$username = $password = '';		
	
	global $webauth;
		
	if(!isset($webauth))
	{
		$webauth = new Ucam_Webauth(array(
			'key_dir' => ABSPATH . PLUGINDIR . '/ravenkeys',
			'cookie_key' => 'sscms_raven',
			# next line (specification of 'hostname' added on 080811 due to release of ucam_webauth.php version 0.51
			'hostname' => 'www.DEPARTMENT.cam.ac.uk',
		));
	}

	$complete = $webauth->authenticate();
	
	
	if (!$complete) { die('FAIL - ' . $webauth->status() . ':' . $webauth->msg()); exit(); }
	
	if ($webauth->success()) {
	
		
		$username = $webauth->principal();
		$email = $username . '@cam.ac.uk';
		
		require_once(ABSPATH . WPINC . '/pluggable.php');
		require_once(ABSPATH . WPINC . '/registration.php');
		if(function_exists('get_userdatabylogin') && function_exists('wp_create_user'))
		{
			$user = get_userdatabylogin($username);
		
			if ($user and $username == $user->user_login) {
				// Feed WordPress a double-MD5 hash (MD5 of value generated in check_passwords)
				$password = md5($user->user_pass);
				
			} else {
				// User is not in the WordPress database
				// they passed Raven and so are authorized
				// add them to the database (password field is arbitrary, but must be constant and should be hard to guess)
				$user_id = wp_create_user( $username, md5('Authenticated through Raven'), $email );
				
				if ( !$user_id )
					$errors['registerfail'] = sprintf(__('<strong>ERROR</strong>: The login system couldn\'t register you in the local database. Please contact the <a href="mailto:%s">webmaster</a> !'), get_option('admin_email'));
				else {
					wp_new_user_notification($user_id, $user_pass);
				}
			}
			$using_cookie = true;
			wp_setcookie($user->user_login, $password, $using_cookie);
			
			$kms = array();
			$as = array();
			$ms = array();
			
			if(file_exists(ABSPATH . PLUGINDIR . '/ravenkeys/keymasters.rkf'))
				$kms = unserialize(file_get_contents(ABSPATH . PLUGINDIR . '/ravenkeys/keymasters.rkf'));
			if(file_exists(ABSPATH . PLUGINDIR . '/ravenkeys/admins.rkf'))
				$as = unserialize(file_get_contents(ABSPATH . PLUGINDIR . '/ravenkeys/admins.rkf'));
			if(file_exists(ABSPATH . PLUGINDIR . '/ravenkeys/members.rkf'))
				$ms = unserialize(file_get_contents(ABSPATH . PLUGINDIR . '/ravenkeys/members.rkf'));
			
			
			$user->user_login = trim($user->user_login, "\n");
			$user->user_login = trim($user->user_login);
			
			$user->role = 'subscriber';			
			if(is_array($ms))
			{
				foreach($ms as $t)
				{
					$t = trim($t, "\n");
					$t = trim($t);
					$u = explode(':', $t);
					$t = $u[0];
					if($user->user_login == $t)
						$user->role = 'contributor';						
				}
			}
			if(is_array($as))
			{
				foreach($as as $t)
				{
					$t = trim($t, "\n");
					$t = trim($t);
					$u = explode(':', $t);
					$t = $u[0];
					if($user->user_login == $t)
						$user->role = 'editor';
										
				}
			}
			if(is_array($kms))
			{
				foreach($kms as $t)
				{
					$t = trim($t, "\n");
					$t = trim($t);
					$u = explode(':', $t);
					$t = $u[0];
					if($user->user_login == $t)
						$user->role = 'administrator';						
				}
			}
			
			$user->user_pass = $password;
			// User is now authorized; force WordPress to use the generated password
			
			
			
			ldapusername($user->user_login);
			
			wp_update_user( get_object_vars( $user ));
		}				
		else {
			die("Could not load user data");
		}
		
	}
	else {
		die('Could not log you in');
	}
}

function ldapusername($crsid)
{
	$nicename = $crsid;
	$nicename = str_replace('@cam.ac.uk', '', $nicename);
		
	$ds=ldap_connect("ldap.lookup.cam.ac.uk");  // must be a valid LDAP server!
	
	if ($ds) {
		$r=ldap_bind($ds);     // this is an "anonymous" bind, typically
							   // read-only access
		// Search surname entry
		$sr=ldap_search($ds, "ou=people,o=University of Cambridge,dc=cam,dc=ac,dc=uk", "mail=" . $crsid . "*"); 
		$info = ldap_get_entries($ds, $sr);
		
		
		$sname = $info[0]["sn"][0];			
		$nicename = $info[0]["displayname"][0];
		if(empty($nicename))
			$nicename = $info[0]["cn"][0];
		if(empty($nicename))
			$nicename = $crsid;
		$college = $info[0]["ou"][0];
		
		ldap_close($ds);
	
	}
	$user = get_userdatabylogin($crsid);
	
	global $wpdb;
	
	$college = str_replace('- Undergraduates', '', $college);
	$college = str_replace('- Postgraduates', '', $college);
	$college = trim($college);
	$query = "UPDATE $wpdb->users SET display_name = '" . htmlentities($nicename . ', ' . $college, ENT_QUOTES) . "', user_nicename = '" . htmlentities($nicename, ENT_QUOTES) . "' WHERE ID = '" . $user->ID . "'";
	$query = apply_filters('update_user_query', $query);
	$wpdb->query( $query );
	update_usermeta($user->ID, 'nickname', $nicename);
	update_usermeta($user->ID, 'last_name', $sname);
	if(!empty($college))
	{
		return htmlentities($nicename . ', ' . $college, ENT_QUOTES);
	}
	return htmlentities($nicename, ENT_QUOTES);
}

function raven_get_comment_author($author)
{
	global $comment;
	global $wpdb;
	if(isset($comment->user_id))
	{
		$res = $wpdb->get_results( "SELECT user_login FROM $wpdb->users WHERE ID = $comment->user_id LIMIT 1" );
		return ldapusername($res[0]->user_login);
	}
	return $author;
}


/*
	We use the provided logout method (which also destorys the client's Raven cookie)
*/
function raven_logout() {

	setcookie('Ucam-WebAuth-Session', ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN);
	setcookie('Ucam-WebAuth-Session', ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN);
	
	
	session_destroy();
	
	global $current_user;
	unset($current_user);	
	
}


/*
	Should match the md5 of whatever we gave wp_create_user earlier
 */
function raven_check_passwords($username, $password1, $password2) {
	$password1 = $password2 = md5(md5('Authenticated through Raven'));
}


/*
	Don't show password fields on user profile page.
 */
function raven_show_password_fields($show_password_fields) {
	return false;
}


function raven_disable_function() {
	die('Disabled');
}