Skip to content
Snippets Groups Projects
options.php 11.1 KiB
Newer Older
<?php

// e-mail, password validation functions
require_once("../lib/validation.php");


// Some Constants
// These could possibly be moved somewhere saner?
define('GUESTNET_LOW','137.44.10.130'); // These could possibly be a set of ranges or a subnet which might be saner?
define('GUESTNET_HIGH','137.44.10.134'); // These could possibly be a set of ranges or a subnet which might be saner?
$sucsdbname = 'sucs'; // This was stored in config, I just don't have it here in the test

// Helper Functions
// Could these be moved to some kind of library?

// Set next payment date
$paydate = "Sept. ".(academicYear(time())+1);

// function to change a user's password
function changePassword ($oldpass, $newpass1, $newpass2) {

	if ($newpass1 !== $newpass2) {
		// new passwords do not match!
		trigger_error("New passwords do not match", E_USER_WARNING);
	$reason = weakPassword($newpass1);
	if ($reason !== FALSE) {
		trigger_error("New password is weak: $reason", E_USER_WARNING);
		return FALSE;
	}

	if (!($ldap = @ldap_connect("ldap://localhost"))) {
		trigger_error("LDAP connect failed", E_USER_ERROR);
		return FALSE;
	}
	
	if (!($ldapbind = ldap_bind($ldap, "uid=".$session->username.",ou=People,dc=sucs,dc=org",$oldpass))) {
		trigger_error("Existing password incorrect", E_USER_WARNING);
		ldap_close($ldap);
		return FALSE;
	}

	// if everything looks OK, attempt to make the change
	$success = ldap_mod_replace ($ldap, "uid=".$session->username.",ou=People,dc=sucs,dc=org",
		array('userpassword' => "{SHA}".base64_encode(pack("H*", sha1($newpass1)))));

	ldap_close($ldap);
	return $success;
}

// function to update contact details
function changeContactDetails($address, $phone, $externalEmail) {
	global $sucsDB, $session, $error;
	// Do some kind of checking here
	// Check valid email (do we have a function for this?
	if (!validEmail($externalEmail)) 
		return FALSE; // Valid Email handles errors itself
	// Check valid phone number (do we have a function for this?)
	if (empty($phone) || (strlen($phone) < 6)) {
		trigger_error("You must have a contact phone number!", E_USER_WARNING);
		return FALSE;
	}
	// Update 
	if ($sucsDB->Execute('UPDATE members SET address = ?,phone = ?, email = ?, lastupdate = now(), lastedit = uid WHERE username = ?', 
			array($address, $phone, $externalEmail, $session->username)) === FALSE) {
		trigger_error("There was an error updating your contact details. Please contact admin.", E_USER_ERROR);
		return FALSE;
	}
	return TRUE;
}

function changeGuestnetDetails($wiredMAC) {
	global $sucsDB, $session, $error;
	// Get UID as we don't have it yet	
	if(($uid = $sucsDB->GetOne("SELECt uid FROM members WHERE username = ?", array($session->username))) === FALSE) {
		trigger_error("There was an error updating your GuestNET MAC Address. Please contact admin. (UID)", E_USER_ERROR);
		return FALSE;
	}
	// Replace the guestnet record with the one with the new mac
	if (!$sucsDB->Replace('guestnet', array('mac' => "'$wiredMAC'", 'uid' => $uid), 'uid')) {
		trigger_error("There was an error updating your GuestNET MAC Address. Please contact admin. (QUERY)", E_USER_ERROR);
		return FALSE;
	}
	exec('/usr/local/bin/update-dhcpd', $placeholder, $returnVar);
	
	if ($returnVar == 0) {
		return TRUE;
		//  $message[] = 'GuestNet MAC Address updated. Please wait a minute or two for the changes to take effect.';
	} else {
		trigger_error("There was an error updating your GuestNet Mac Address. Please contact admin. (RETURNVAR)", E_USER_ERROR);
		return FALSE;
	}
}

// Checks whether the given string mac address is valid
function isValidMACAddr($mac) {
	// Put code here if needed
	return TRUE;
}

// Returns the users GuestNet MAC Address if they have one and false otherwise
function getGuestNetMAC() {
	$ip = trim($_SERVER['REMOTE_ADDR']);
	// Sanity Check ip?
	// Check we are in the correct ip range (unregistered GuestNET addresses)
	if (ip2long($ip) && (ip2long($ip) >= ip2long(GUESTNET_LOW)) && (ip2long($ip) <= ip2long(GUESTNET_HIGH))) {
	
		exec("sudo /usr/local/sbin/gw-copy-arp.sh", $placeholder, $returnVar);
		if ($returnVar == 0) {
			$arpLines = file('/tmp/gwarp');
			foreach ($arpLines as $arpLine) {
				$arpFields = preg_split('/[\s\t\n]+/', $arpLine);
				if ($arpFields[0] == $ip) {
					// Perhaps do some checking on the mac here?
					if (isValidMACAddr($arpFields[3])) 
						return $arpFields[3];
					else 
						break;
				}
			}
		}
		// We didn't find their mac address :\
		trigger_error("There was an error finding your MAC Address. Please contact admin.", E_USER_ERROR);
		return FALSE;
	} else {
		return FALSE;
	}
}

// Delete the user's hackergotchi file cause they've decided they're too embarrassed by it
function clearHackergotchi() {
	$imagefilepath = hackergotchiPath($session->username);

	if (unlink($imagefilepath)) {
		return true;
	} else { 
		trigger_error("Unable to remove hackergotchi file", E_USER_ERROR);
		return false; 
	}
}

// construct the filesystem path to a user's hackergotchi picture
function hackergotchiPath($username) {
	global $base; 
	$path = $base."htdocs/pictures/people/".$username.".png"; 
	return $path;
}

// Takes an entry from $_FILES and makes this the new hackergotchi
function updateHackergotchi($fileDetails) {
	if ( ((list($width, $height, $type, $attr) = @getimagesize($fileDetails['tmp_name'])) !== false)) { 
	    
		if ($type != IMAGETYPE_PNG) {
			trigger_error("Uploaded hackergotchi is not in PNG format. Please convert your image to PNG and try again.", E_USER_ERROR);
			return FALSE;
		} else if (($width > 128) || ($height > 128)) {
			trigger_error("Uploaded hackergotchi is too large. Hackergotchis must be 128x128 pixels or smaller.", E_USER_ERROR);
			return FALSE;
		}

		$imagefilepath = hackergotchiPath($session->username);

		// Move uploaded hackergotchi into place
		if( move_uploaded_file($fileDetails['tmp_name'], $imagefilepath) && chmod($imagefilepath, 0644) ) {
			return TRUE;
		}
	// We should have returned True by now
	trigger_error("There was an error updating your hackergotchi. Please contact admin.", E_USER_ERROR);
function changeBlogFeed($type, $feed, $syndicate) {
	global $sucsDB, $session, $smarty;
	if ($type == "sucs") {
		$feed="http://sucs.org/blog/feed/atom/".$session->username;
	}
	
	if ($syndicate=="on") {
		$syndicate = "t";
	} else {
		$syndicate = "f";
	}

	// try to read up to 100KB of the provided feed uri
	if (@file_get_contents($feed,FALSE,null,0,100000) == FALSE) {
		trigger_error("Unable to read from provided blog feed URL", E_USER_WARNING);
		return FALSE;
	}

	if ($sucsDB->Execute("UPDATE members SET blogfeed=?,syndicateblog=? WHERE username=?", 
		array($feed, $syndicate, $session->username)) == FALSE) {
		return FALSE;
		}	

function updateRenew() {
	global $sucsDB, $session, $error;
	global $paydate;

	if (!isset($_REQUEST['userid']) || !isset($_REQUEST['supass'])) {
		trigger_error("Invalid renewal info", E_USER_ERROR);
		return FALSE;
	}
	$userid = (int)$_REQUEST['userid'];
	$pass = $_REQUEST['supass'];
	$member = $sucsDB->GetRow("select * from members left join member_type on members.type=member_type.id where username='".$session->username."'");

	$signup = $sucsDB->GetRow("select * from signup where id=?", array($userid));
	if (!is_array($signup) || count($signup) < 1) {
		trigger_error("Invalid renewal info", E_USER_ERROR);
		return FALSE;
	}
	if ($signup['password'] != $pass) {
		trigger_error("Invalid renewal info", E_USER_ERROR);
		return FALSE;
	}
	if ($signup['activated'] != NULL) {
		trigger_error("Signup slip already used", E_USER_ERROR);
		return FALSE;
	}

	$sucsDB->Execute("update members set paid=?, lastupdate=DEFAULT, lastedit=uid where uid=?", array($paydate, $member['uid']));
	$sucsDB->Execute("update signup set activated=NOW(), username=? where id=?", array($member['username'], $signup['id']));
	return TRUE;
}

// Template Setup

$smarty->assign('session', $session);

if ($session->loggedin === TRUE) {

	$sucsDB = NewADOConnection('postgres8');
	$sucsDB->Connect('dbname='.$sucsdbname.' user=apache');
	$sucsDB->SetFetchMode(ADODB_FETCH_ASSOC);
	
	$newGuestNetMAC = getGuestNetMAC();

	// Handle Postbacks
	if (isset($_POST['action'])) {
		switch($_POST['action']) {
			case 'changepass' :
				if (changePassword($_POST['oldpass'], $_POST['newpass1'], $_POST['newpass2'])) {
					message_flash('Password changed.');
				} else {
					// Should we log something here for bug trcaking use?
					trigger_error("Password change failed.", E_USER_WARNING);
				}
				break;
			case 'changecontact' :
				if(changeContactDetails($_POST['address'], $_POST['phone'], $_POST['email'])) {
					message_flash('Contact Details Updated.');
				}
				break;
			case 'changeguestnet' :
				if(changeGuestNetDetails($newGuestNetMAC)) {
					message_flash('GuestNet Details Updated!');
				}
				break;
			case 'updatehackergotchi' :
				if (updateHackergotchi($_FILES['hackergotchi'])) {
					message_flash('Hackergotchi Updated');
				} 
				break;
			case 'clearhackergotchi' :
				if (clearHackergotchi()) {
					message_flash('Hackergotchi Cleared');
			case 'changeblogfeed' :
				if (changeBlogFeed($_POST['blogtype'], $_POST['bloguri'], $_POST['syndicateblog'])){
					message_flash("Blog Feed Updated");
				} else {
					trigger_error("Blog Feed has not been updated", E_USER_NOTICE);
			case 'renew' :
				if (updateRenew()) {
					message_flash('Account renewed');
				}
				break;
		}
	}


	// Display Details
	// Some checking could be done here to ensure we have a members record. Ideally we should
	// be able to assume this though if they are logged in.

	if (is_file($base."htdocs/pictures/people/".$session->username.".png")) $smarty->assign('hackergotchi', TRUE);


	$member = $sucsDB->GetRow("select * from members left join member_type on members.type=member_type.id where username='".$session->username."'");
	$smarty->assign('paydate', $paydate);

	if(($currentGuestNetMAC = $sucsDB->GetOne('SELECT * FROM guestnet WHERE uid=?', array((int)$member['uid']))) !== FALSE) {
		$smarty->assign('currentGuestNetMAC', $currentGuestNetMAC);
	} else {
		$smarty->assign('currentGuestNetMAC', '');
	}

	if (($newGuestNetMAC !== false) && ($newGuestNetMAC != $currentGuestNetMAC)) {
		$smarty->assign('newGuestNetMAC', $newGuestNetMAC);
	}


// connect to Blog DB to see if user has a SUCS blog	
	require_once("/usr/share/php/adodb/adodb.inc.php");
	$BlogDB = NewADOConnection('postgres8');
	$BlogDB->Connect('dbname=blogs user=apache');
	$BlogDB->SetFetchMode(ADODB_FETCH_ASSOC); 
	require_once('../lib/blog/validation.lib.php');
	if (blogger($session->username)) {
		$smarty->assign("sucsblogger", TRUE);
		$feed="http://sucs.org/blog/feed/atom/".$session->username;
		if ($member['blogfeed'] == $feed) {
			$smarty->assign("sucsblogfeed", TRUE);
		}
	}

	// change postgresql boolean to PHP boolean
	if ($member['syndicateblog'] == 't') {
		$member['syndicateblog'] = true;
	} else {
		$member['syndicateblog'] = false;
	}
	$smarty->assign('member', $member);

}

$smarty->assign('url', $component['path']);
$result = $smarty->fetch('options.tpl');
$smarty->assign('title', "Options");
$smarty->assign('body', $result);
?>