/Main_Page

::You must have ninja focus to complete your mission::NinjaFocus::

DotProject

Views:


Contents

IMPORTANT

In each project, change the "Company" to "Varndean College", for each user then add "Varndean College" as the "Company" (and "ICT" as the department), then under each project add under permississon both the company and user permissions. Bnb 14:38, 10 October 2007 (BST)

General

dotProject is a web based project management server setup for ICT to students to use. A lot of the user administration is taken care of by the ICT Teaching staff

Companies

An "ICT Students" company has been defined

Projects

All projects are predefined, ready to be associated with a user account. Students won't be creating projects themselves. ICT Teaching staff are responsible for creating the blank projects. Students will need to login once before they can be linked up with a project.

Permissions

dotProject has a permissions system which has been used to stop students trashing each others projects and to give ICT Teaching staff more control over the student acccounts.

Student accounts are associated with the Students role, while ICT Teacher accounts are associated with the User Administration role.

User Roles Level

Roles are defined in the "System Admin", "User Roles" section of dotProject by using the Admin user.

Two custom User Roles have been created, one for student account and one for ICT Teaching staff.

students
  • ID: students
  • Description: Students
  • Permissions:
    • Admin Modules/Access, View/deny
    • Contacts/Access, View/deny
    • Projects/Access/allow
    • Companies/Access,View/deny
    • Tasks/Access,Add,Delete,Edit,View/allow
    • Files/Access,Add,Delete,Edit,View/deny
    • Events/Access,Add,Delete,Edit,View/allow
    • Resources/Access,Add,Delete,Edit,View/allow
user-admin
  • ID: user-admin
  • Description: User Administration
  • Permissions
    • User Administration/Access,Add,Delete,Edit,View/allow
    • User Table/Access,Add,Delete,Edit,View/allow
    • Non-Admin Modules/Access,Add,Delete,Edit,View/allow

User Permission Level

Any ICT Teacher that logs in to dotProject will need to have the User Administration role added to their account. They will also need a permission set to deny viewing/access to the Admin user account.

Student accounts need to have the Students roles added to their account. They also need Access,View/allow permissions to the ICT Students company, and Access,View,Add,Edit,Delete/allow permissions for the designated project.

Other Settings

System Administration

System Configuration
  • Currency Symbol: £
  • Company Name: Varndean College
  • Site Domain: varndean.ac.uk
  • PDF Indexing Parser: /usr/local/bin/pdftotext
  • Memory Limit for Gantt: 64MB
  • User Authentication Method: LDAP
  • LDAP User Filter: (cn=%USERNAME%)
  • LDAP Base DN: o=vsfc
  • SMTP: mail.varndean.ac.uk
  • Default Module: projects
View Modules
Module Status Menu Status Order
Calendar active visible1
Companiesactivehidden2
Contactsactivehidden3
Departmentsactivehidden4
Filesdisabledhidden5
Forums disabledhidden6
Helpactivevisible7
Projectsactivevisible8
Resourcesactivevisible9
System Administrationactivevisible10
Tasksactive visible11
Ticketsdisabledhidden12
User Administrationactivevisible13
Default User Settings
  • Locale: en GB
  • Tabbed Box View: enable
  • Short Date Format: 01/12/2006
  • Time Format: 12:30pm
  • Currency Format: GBP1,000,000.00
  • User Interface Style: Default Clean Style
  • User Task Assignment Maximum: 100
  • Default Event Filter: My Events
  • Task Notification Method: Don't incluse task/event owner
  • Task Log Email Defaults: (None ticked)
  • Task Log Email Subject: (blank)
  • Task Log Email Recording Method: None

LDAP Authentication

The authentication class has been modified to only allow memebers of cn=project-server-users,ou=learner,o=daytime access to the server

Some addtional entries are needed in the config table of the database

INSERT INTO config VALUES (1666,'ldap_group','cn=project-server-users,ou=learner,o=vsfc','','text');
INSERT INTO config VALUES (1667,'ldap_group_filter','(member=%FILTER%)','','text');
INSERT INTO config VALUES (1668,'ldap_group_member_attribute','member','','text');
<?php
// $Id: authenticator.class.php,v 1.13 2005/04/15 11:32:03 mosen Exp $

	/*
	 *	Authenticator Class
	 *
	 */


	function &getAuth($auth_mode)
	{
		switch($auth_mode)
		{
			case "ldap":
				$auth = new LDAPAuthenticator();
				return $auth;
				break;
			case "pn":
				$auth = new PostNukeAuthenticator();
				return $auth;
				break;
			default:
				$auth = new SQLAuthenticator();
				return $auth;
				break;
		}
	}

	/**
	 * PostNuke authentication has encoded information
	 * passed in on the login request.  This needs to 
	 * be extracted and verified.
	 */
	class PostNukeAuthenticator extends SQLAuthenticator
	{

		function PostNukeAuthenticator()
		{
			global $dPconfig;
			$this->fallback = isset($dPconfig['postnuke_allow_login']) ? $dPconfig['postnuke_allow_login'] : false;
		}

		function authenticate($username, $password)
		{
			global $db, $AppUI;
			if (!isset($_REQUEST['userdata'])) { // fallback to SQL Authentication if PostNuke fails.
				if ($this->fallback)
					return parent::authenticate($username, $password);
				else {
					die($AppUI->_('You have not configured your PostNuke site correctly'));
				}
			}

			if (! $compressed_data = base64_decode(urldecode($_REQUEST['userdata']))) {
				die($AppUI->_('The credentials supplied were missing or corrupted') . ' (1)');
			}
			if (! $userdata = gzuncompress($compressed_data)) {
				die($AppUI->_('The credentials supplied were missing or corrupted') . ' (2)');
			}
			if (! $_REQUEST['check'] = md5($userdata)) {
				die ($AppUI->_('The credentials supplied were issing or corrupted') . ' (3)');
			}
			$user_data = unserialize($userdata);

			// Now we need to check if the user already exists, if so we just
			// update.  If not we need to create a new user and add a default
			// role.
			$username = trim($user_data['login']);
			$this->username = $username;
			$names = explode(' ', trim($user_data['name']));
			$last_name = array_pop($names);
			$first_name = implode(' ', $names);
			$passwd = trim($user_data['passwd']);
			$email = trim($user_data['email']);
			
			$q  = new DBQuery;
			$q->addTable('users');
			$q->addQuery('user_id, user_password, user_contact');
			$q->addWhere("user_username = '$username'");
			if (! $rs = $q->exec()) {
				die($AppUI->_('Failed to get user details') . ' - error was ' . $db->ErrorMsg());
			}
			if ( $rs->RecordCount() < 1) {
				$q->clear();
				$this->createsqluser($username, $passwd, $email, $first_name, $last_name);
			} else {
				if (! $row = $rs->FetchRow())
					die($AppUI->_('Failed to retrieve user detail'));
				// User exists, update the user details.
				$this->user_id = $row['user_id'];
				$q->clear();
				$q->addTable('users');
				$q->addUpdate('user_password', $passwd);
				$q->addWhere("user_id = {$this->user_id}");
				if (! $q->exec()) {
					die($AppUI->_('Could not update user credentials'));
				}
				$q->clear();
				$q->addTable('contacts');
				$q->addUpdate('contact_first_name', $first_name);
				$q->addUpdate('contact_last_name', $last_name);
				$q->addUpdate('contact_email', $email);
				$q->addWhere("contact_id = {$row['user_contact']}");
				if (! $q->exec()) {
					die($AppUI->_('Could not update user details'));
				}
				$q->clear();
			}
			return true;
		}

		function createsqluser($username, $password, $email, $first, $last)
		{
			GLOBAL $db, $AppUI;

			require_once($AppUI->getModuleClass("contacts"));
	
			$c = New CContact();
			$c->contact_first_name = $first;
			$c->contact_last_name = $last;
			$c->contact_email = $email;
			$c->contact_order_by = "$last, $first";

			db_insertObject('contacts', $c, 'contact_id');
			$contact_id = ($c->contact_id == NULL) ? "NULL" : $c->contact_id;
			if (! $c->contact_id)
				die($AppUI->_('Failed to create user details'));

			$q  = new DBQuery;
			$q->addTable('users');
			$q->addInsert('user_username',$username );
			$q->addInsert('user_password', $password);
			$q->addInsert('user_type', '1');
			$q->addInsert('user_contact', $c->contact_id);
			if (! $q->exec())
				die($AppUI->_('Failed to create user credentials'));
			$user_id = $db->Insert_ID();
			$this->user_id = $user_id;
			$q->clear();

			$acl =& $AppUI->acl();
			$acl->insertUserRole($acl->get_group_id('anon'), $this->user_id);
		}
	}

	class SQLAuthenticator
	{
		var $user_id;
		var $username;

		function authenticate($username, $password)
		{
			GLOBAL $db, $AppUI;

			$this->username = $username;

			$q  = new DBQuery;
			$q->addTable('users');
			$q->addQuery('user_id, user_password');
			$q->addWhere("user_username = '$username'");
			if (!$rs = $q->exec()) {
				$q->clear();
				return false;
			}
			if (!$row = $q->fetchRow()) {
				$q->clear();
				return false;
			}

			$this->user_id = $row["user_id"];
			$q->clear();
			if (MD5($password) == $row["user_password"]) return true;
			return false;
		}

		function userId()
		{
			return $this->user_id;
		}
	}	

	class LDAPAuthenticator extends SQLAuthenticator
	{
		var $ldap_host;
		var $ldap_port;
		var $ldap_version;
		var $base_dn;
		var $ldap_search_user;
		var $ldap_search_pass;	
		var $filter;

		var $user_id;
		var $username;

		function LDAPAuthenticator()
		{
			GLOBAL $dPconfig;

			$this->fallback = isset($dPconfig['ldap_allow_login']) ? $dPconfig['ldap_allow_login'] : false;

			$this->ldap_host = $dPconfig["ldap_host"];
			$this->ldap_port = $dPconfig["ldap_port"];
			$this->ldap_version = $dPconfig["ldap_version"];
			$this->base_dn = $dPconfig["ldap_base_dn"];
			$this->ldap_search_user = $dPconfig["ldap_search_user"];
			$this->ldap_search_pass = $dPconfig["ldap_search_pass"];
			$this->filter = $dPconfig["ldap_user_filter"];
			 ///////////////////////////////////////////////////////////////
                        // KJW Group Membership Modification Starts Here
                        ///////////////////////////////////////////////////////////////

                        $this->group_filter = $dPconfig["ldap_group_filter"];
                        $this->group = $dPconfig["ldap_group"];
                        $this->group_member_attribute = $dPconfig["ldap_group_member_attribute"];

                        ///////////////////////////////////////////////////////////////
                        // KJW Group Membership Modification Ends Here
                        ///////////////////////////////////////////////////////////////
		}

		function authenticate($username, $password)
		{
			GLOBAL $dPconfig;
			$this->username = $username;

			if (strlen($password) == 0) return false; // LDAP will succeed binding with no password on AD (defaults to anon bind)
			 ///////////////////////////////////////////////////////////////
                        // KJW Group Membership Modification Starts Here
                        ///////////////////////////////////////////////////////////////

                        if (($this->fallback == true) && ($username == "admin")) // KJW: we only want the admin user to login in via SQL
                        {
                                if (parent::authenticate($username, $password)) return true;
                        }

                        ///////////////////////////////////////////////////////////////
                        // KJW Group Membership Modification Ends Here
                        ///////////////////////////////////////////////////////////////

                        //KJW // Fallback SQL authentication fails, proceed with LDAP
			//KJW if ($this->fallback == true)
			//KJW {
			//KJW 	if (parent::authenticate($username, $password)) return true;	
			//KJW }

			// Fallback SQL authentication fails, proceed with LDAP

			if (!$rs = @ldap_connect($this->ldap_host, $this->ldap_port))
			{
				return false;
			}
			@ldap_set_option($rs, LDAP_OPT_PROTOCOL_VERSION, $this->ldap_version);
			@ldap_set_option($rs, LDAP_OPT_REFERRALS, 0);

			//$ldap_bind_dn = "cn=".$this->ldap_search_user.",".$this->base_dn;
			$ldap_bind_dn = $this->ldap_search_user;	

			if (!$bindok = @ldap_bind($rs, $ldap_bind_dn, $this->ldap_search_pass))
			{
				// Uncomment for LDAP debugging
					
				$error_msg = ldap_error($rs);
				die("Couldnt Bind Using ".$ldap_bind_dn."@".$this->ldap_host.":".$this->ldap_port." Because:".$error_msg);
				
				return false;
			}
			else
			{
				$filter_r = str_replace("%USERNAME%", $username, $this->filter);
				$result = @ldap_search($rs, $this->base_dn, $filter_r);
				if (!$result) return false; // ldap search returned nothing or error
				
				$result_user = ldap_get_entries($rs, $result);
				//KJW if ($result_user["count"] == 0) return false; // No users match the filter

				//KJW $first_user = $result_user[0];
				//KJW $ldap_user_dn = $first_user["dn"];
				///////////////////////////////////////////////////////////////
                                // KJW Group Membership Modification Starts Here
                                ///////////////////////////////////////////////////////////////



                                if ($result_user["count"] != 1) return false; // We only want to find one user object

                                $first_user = $result_user[0];
                                $ldap_user_dn = $first_user["dn"];

                                $group_filter = str_replace("%FILTER%", $ldap_user_dn, $this->group_filter);
                                // Grab a list of members in a group object (need to add a way of setting this in the database I anyone can be arsed)
                                $search = ldap_read($rs, $this->group,  $group_filter, array($this->group_member_attribute));
                                if (ldap_count_entries($rs, $search)) $info = ldap_get_entries($rs, $search);

                                if (count($info)<1) return false;



                                /////////////////////////////////////////////////////////////////
                                // KJW Group Membership Modification Ends Here
                                /////////////////////////////////////////////////////////////////

				// Bind with the dn of the user that matched our filter (only one user should match sAMAccountName or uid etc..)

				if (!$bind_user = @ldap_bind($rs, $ldap_user_dn, $password))
				{
					
					$error_msg = ldap_error($rs);
					die("Couldnt Bind Using ".$ldap_user_dn."@".$this->ldap_host.":".$this->ldap_port." Because:".$error_msg);
					
					return false;
				}
				else
				{
					if ($this->userExists($username))
					{
						return true;
					}
					else
					{
						$this->createsqluser($username, $password, $first_user); 
					}
					return true;
				} 
			}
		

		function userExists($username)
		{
			GLOBAL $db;
			$q  = new DBQuery;
			$result = false;
			$q->addTable('users');
			$q->addWhere("user_username = '$username'");
			$rs = $q->exec();
			if ($rs->RecordCount() > 0) 
			$result = true;
			$q->clear();
			return $result;
		}

		function userId($username)
		{
			GLOBAL $db;
			$q  = new DBQuery;
			$q->addTable('users');
			$q->addWhere("user_username = '$username'");
			$rs = $q->exec();
			$row = $rs->FetchRow();
			$q->clear();
			return $row["user_id"];	
		}

		function createsqluser($username, $password, $ldap_attribs = Array())
		{
			GLOBAL $db, $AppUI;
			$hash_pass = MD5($password);

			require_once($AppUI->getModuleClass("contacts"));
	
			if (!count($ldap_attribs) == 0)
			{
				// Contact information based on the inetOrgPerson class schema
				$c = New CContact();
				$c->contact_first_name = $ldap_attribs["givenname"][0];
				$c->contact_last_name = $ldap_attribs["sn"][0];
				$c->contact_email = $ldap_attribs["mail"][0];
				$c->contact_phone = $ldap_attribs["telephonenumber"][0];
				$c->contact_mobile = $ldap_attribs["mobile"][0];
				$c->contact_city = $ldap_attribs["l"][0];
				$c->contact_country = $ldap_attribs["country"][0];
				$c->contact_state = $ldap_attribs["st"][0];
				$c->contact_zip = $ldap_attribs["postalcode"][0];
				$c->contact_job = $ldap_attribs["title"][0];

				//print_r($c); die();
				db_insertObject('contacts', $c, 'contact_id');
			}
			$contact_id = ($c->contact_id == NULL) ? "NULL" : $c->contact_id;

			$q  = new DBQuery;
			$q->addTable('users');
			$q->addInsert('user_username',$username );
			$q->addInsert('user_password', $hash_pass);
			$q->addInsert('user_type', '1');
			$q->addInsert('user_contact', $c->contact_id);
			$q->exec();
			$user_id = $db->Insert_ID();
			$this->user_id = $user_id;
			$q->clear();

			$acl =& $AppUI->acl();
			$acl->insertUserRole($acl->get_group_id('anon'), $this->user_id);
		}

	}


?>

Main Menu

Personal tools

Toolbox