This commit is contained in:
19
.htaccess
Normal file
19
.htaccess
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<IfModule mod_rewrite.c>
|
||||||
|
|
||||||
|
# Magic Quotes are the Root-of-all-Evil and must be burned at the stake.
|
||||||
|
php_flag magic_quotes_gpc off
|
||||||
|
|
||||||
|
# Enable mod_rewrite for pretty urls
|
||||||
|
RewriteEngine on
|
||||||
|
# Treat all rules as starting from this directory
|
||||||
|
RewriteBase /ecs/
|
||||||
|
|
||||||
|
# Redirect rating requests specifically to the image generator
|
||||||
|
RewriteRule ratings/([0-9\.]*) resources/rating.php?r=$1 [L,NC,NS]
|
||||||
|
|
||||||
|
# If the requeted item doesnt already exist, redirect it to our dispatch page
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-d
|
||||||
|
RewriteRule (.*) index.php [L,NC,NS]
|
||||||
|
|
||||||
|
</IfModule>
|
||||||
38
code/auth_mysql.php
Normal file
38
code/auth_mysql.php
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MySQL Authentication Module
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Authenticator_mysql implements IAuthenticator {
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function initialise() {
|
||||||
|
// Nothing required
|
||||||
|
}
|
||||||
|
|
||||||
|
public function uninitialise() {
|
||||||
|
// Nothing required
|
||||||
|
}
|
||||||
|
|
||||||
|
public function user_exists( $username ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function authenticate( $username, $password ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function username2fullname( $username ) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function fullname2username( $fullname ) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
?>
|
||||||
103
code/config.php
Normal file
103
code/config.php
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configuration
|
||||||
|
* This file contains all global configuration variables
|
||||||
|
*/
|
||||||
|
|
||||||
|
$_config = array();
|
||||||
|
|
||||||
|
// DEBUG MODE
|
||||||
|
// This config variable triggers verbose error output, which is useful for developers, but
|
||||||
|
// would be ugly or bad practice to show to users. Enable this variable on development systems
|
||||||
|
// and disable it for a production system.
|
||||||
|
$_config['DEBUG'] = true;
|
||||||
|
error_reporting( E_ALL | E_NOTICE | E_STRICT );
|
||||||
|
|
||||||
|
// Current timezone settings
|
||||||
|
date_default_timezone_set('Europe/London');
|
||||||
|
|
||||||
|
require_once('request_handler.php');
|
||||||
|
require_once("functions.php");
|
||||||
|
require_once("exceptions.php");
|
||||||
|
require_once("session_handler.php");
|
||||||
|
|
||||||
|
|
||||||
|
// Variable used for passing information around the script,
|
||||||
|
// Should not be used by the user
|
||||||
|
$_meta = array( 'base-dir' => get_web_base_dir(),
|
||||||
|
'script-dir' => get_fs_base_dir(),
|
||||||
|
'error-code' => 403,
|
||||||
|
'error-message' => 'Unknown Error');
|
||||||
|
// Placeholder for template fragments
|
||||||
|
$_template = array( 'messages' => array(),
|
||||||
|
'redirect-to' => false,
|
||||||
|
'head' => '',
|
||||||
|
'title' => 'Default',
|
||||||
|
'page' => '');
|
||||||
|
// Forward declarations
|
||||||
|
$_session = null;
|
||||||
|
|
||||||
|
// Templating
|
||||||
|
$_config['template-file'] = "{$_meta['script-dir']}/templates/default.php";
|
||||||
|
|
||||||
|
// Homepage
|
||||||
|
$_config['homepage'] = "{$_meta['script-dir']}/page-sources/home.php";
|
||||||
|
|
||||||
|
// Sessions
|
||||||
|
// How long a logged in session will last without activity from the user
|
||||||
|
$_config['session-login-timeout'] = 60*60*1; // One hour
|
||||||
|
// How long the username will be stoed in the users cookie
|
||||||
|
$_config['session-username-timeout'] = 60*60*24*7; // Seven days
|
||||||
|
|
||||||
|
// See session-handler.php for reasons behind the session-network-* config variables
|
||||||
|
// session-network-mask is used to determine how much of the users IP is hashed into the salt
|
||||||
|
$_config['session-network-mask'] = 24;
|
||||||
|
// session-network-mode defines whether the above parameter was passed as a CIDR form, or dotted decimal form
|
||||||
|
$_config['session-network-mode'] = MASK_CIDR;
|
||||||
|
|
||||||
|
// Maximum number of items to keep in the users session history
|
||||||
|
$_config['max-history'] = 5;
|
||||||
|
|
||||||
|
// Account Lockout
|
||||||
|
// How many incorrect authentication attempts before the user is locked out
|
||||||
|
$_config['lockout-attempts'] = 3;
|
||||||
|
// How long the account lockout period lasts. During this time, the user will not
|
||||||
|
// be able to authenticate, even witha valid passwords
|
||||||
|
$_config['lockout-duration'] = 60*10; // Ten minutes
|
||||||
|
|
||||||
|
|
||||||
|
// Authantication
|
||||||
|
require_once( "{$_meta['script-dir']}/code/iauthenticator.php" );
|
||||||
|
$_config['authentication-module'] = 'mysql';
|
||||||
|
|
||||||
|
// Database
|
||||||
|
// Mysql connections parameters
|
||||||
|
$_config['db'] = null;
|
||||||
|
$_config['mysql'] = array();
|
||||||
|
$_config['mysql']['host'] = 'localhost';
|
||||||
|
$_config['mysql']['port'] = 3306;
|
||||||
|
$_config['mysql']['username'] = '';
|
||||||
|
$_config['mysql']['password'] = '';
|
||||||
|
$_config['mysql']['database'] = '';
|
||||||
|
|
||||||
|
// Database tables
|
||||||
|
$_config['mysql']['prefix'] = '';
|
||||||
|
|
||||||
|
// Connecting to the database
|
||||||
|
$_db = null;
|
||||||
|
require_once( "{$_meta['script-dir']}/code/db_mysql.php" );
|
||||||
|
|
||||||
|
// Only show php error messages if the application is in debug mode
|
||||||
|
if( isset($_GET['nodebug']) ) $_config['DEBUG'] = false;
|
||||||
|
if( !$_config['DEBUG'] ) {
|
||||||
|
set_error_handler( "null_error_handler" );
|
||||||
|
set_exception_handler( "null_exception_handler" );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the default template for all individual pages
|
||||||
|
$_template['template-file'] = $_config['template-file'];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
21
code/db_mysql.php
Normal file
21
code/db_mysql.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MySQL Database wrappper
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
if( $_config['db'] == 'mysql' ) {
|
||||||
|
|
||||||
|
// Egress checking, make sure everyting we need is available
|
||||||
|
if( !class_exists( 'mysqli' ) ) throw new ConfigException('Missing required PHP Extension "mysqli".');
|
||||||
|
if( !is_array( $_config['mysql'] ) ) throw new ConfigException('Missing configuration data: mysql');
|
||||||
|
|
||||||
|
// Connect to the database using the config variables provided in _config
|
||||||
|
$_db = new mysqli( $_config['mysql']['host'], $_config['mysql']['username'], $_config['mysql']['password'], $_config['mysql']['database'], $_config['mysql']['port'] );
|
||||||
|
if( mysqli_connect_errno() ){
|
||||||
|
throw new ConfigException('Cannot connect to the mysql database');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
41
code/exceptions.php
Normal file
41
code/exceptions.php
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Exceptions
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
class BaseException extends Exception {
|
||||||
|
|
||||||
|
// Overridden constuctor with message and code parameters, which will optionally display error output
|
||||||
|
public function __construct( $message = '', $code = 0) {
|
||||||
|
global $_config;
|
||||||
|
|
||||||
|
parent::__construct( $message, $code );
|
||||||
|
// If debug mode is on, print out the raw data
|
||||||
|
if( $_config['DEBUG'] ) {
|
||||||
|
echo get_class($this) . ": Code='{$code}', Message='{$message}'<br />\n";
|
||||||
|
echo '<pre>';print_r($this->getTrace());echo '</pre>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class FatalException extends BaseException {
|
||||||
|
// Overridden constructor prints an error message, then terminates the application
|
||||||
|
public function __construct( $message = '', $code = 0 ) {
|
||||||
|
parent::__construct( $message, $code );
|
||||||
|
die( 'FATAL EXCEPTION: ' . $message );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigException extends BaseException {};
|
||||||
|
class SessionException extends BaseException {};
|
||||||
|
class AccountLockoutException extends BaseException {};
|
||||||
|
class AuthenticationException extends BaseException {};
|
||||||
|
class ParameterException extends BaseException {};
|
||||||
|
class NotImplementedException extends BaseException {};
|
||||||
|
|
||||||
|
?>
|
||||||
76
code/functions.php
Normal file
76
code/functions.php
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility Functions
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
define("MASK_DOTTED_DECIMAL", 1);
|
||||||
|
define("MASK_CIDR", 2);
|
||||||
|
|
||||||
|
// Override the default error handler to prevent error messages being shown to the user
|
||||||
|
function null_error_handler( $errno, $errstr, $errfile, $errline, $errcontext ) {
|
||||||
|
switch( $errono ) {
|
||||||
|
case E_ERROR:
|
||||||
|
case E_CORE_ERROR:
|
||||||
|
case E_COMPILE_ERROR:
|
||||||
|
case E_USER_ERROR:
|
||||||
|
case E_RECOVERABLE_ERROR: {
|
||||||
|
// Fatal error, cause the page to fail here
|
||||||
|
header("HTTP/1.1 500 Internal Server Error");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
// non fatal error, let it pass
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Override the default exception handler to prevent error messages being shown to the user
|
||||||
|
function null_exception_handler( $exception ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_web_base_dir() {
|
||||||
|
static $Dir;
|
||||||
|
if (!isset($Dir))
|
||||||
|
$Dir = dirname($_SERVER['SCRIPT_NAME']);
|
||||||
|
return $Dir;
|
||||||
|
}
|
||||||
|
function get_fs_base_dir() {
|
||||||
|
static $Dir;
|
||||||
|
if (!isset($Dir))
|
||||||
|
$Dir = dirname($_SERVER['SCRIPT_FILENAME']);
|
||||||
|
return $Dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_network_mask( $ip, $subnet, $mode = MASK_DOTTED_DECIMAL ) {
|
||||||
|
$ip_l = ip2long( $ip );
|
||||||
|
if( $mode == MASK_DOTTED_DECIMAL )
|
||||||
|
// 255.255.255.0 type subnet
|
||||||
|
$subnet_l = ip2long( $subnet );
|
||||||
|
else
|
||||||
|
// CIDR type subnet
|
||||||
|
$subnet_l = (~0) << (32 - $subnet);
|
||||||
|
|
||||||
|
// Mask the two together
|
||||||
|
$network_l = $ip_l & $subnet_l;
|
||||||
|
|
||||||
|
return long2ip($network_l);
|
||||||
|
}
|
||||||
|
|
||||||
|
function array_clone( &$source, &$dest ) {
|
||||||
|
foreach( $source as $key => $value ) {
|
||||||
|
$dest[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function print_rating_graph( $star_rating ) {
|
||||||
|
global $_meta;
|
||||||
|
?>
|
||||||
|
<img class="foreground" src="<?php echo $_meta['base-dir']; ?>/resources/ratings/<?php echo $star_rating; ?>" alt="Rated: <?php echo $star_rating; ?>" />
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
60
code/iauthenticator.php
Normal file
60
code/iauthenticator.php
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IAuthenticator
|
||||||
|
* Interface for authentication classes
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface IAuthenticator {
|
||||||
|
|
||||||
|
// Do any module-specific initialisation
|
||||||
|
public function initialise();
|
||||||
|
// Shutdown the module cleanly when finished
|
||||||
|
public function uninitialise();
|
||||||
|
|
||||||
|
// Identifies whether a user with a given name exists
|
||||||
|
public function user_exists( $username );
|
||||||
|
// Checks a given username and password
|
||||||
|
public function authenticate( $username, $password );
|
||||||
|
|
||||||
|
// Does translation between a username and full name
|
||||||
|
public function username2fullname( $username );
|
||||||
|
// And vice versa
|
||||||
|
public function fullname2username( $fullname );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IAuthenticatorFactory
|
||||||
|
* Creates an instance of an Authenticator module, given its name
|
||||||
|
*/
|
||||||
|
class IAuthenticatorFactory {
|
||||||
|
|
||||||
|
// Prevent any instances of this class being constructed
|
||||||
|
private function __construct() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function get( $module ) {
|
||||||
|
global $_meta;
|
||||||
|
|
||||||
|
// Get the filename and classnames for this module
|
||||||
|
$filename = "{$_meta['script-dir']}/code/auth_{$module}.php";
|
||||||
|
$classname = "Authenticator_{$module}";
|
||||||
|
|
||||||
|
// Check to make sure this module exists
|
||||||
|
if( !file_exists($filename) ) throw new ConfigException("Authentication module could not be found: '{$filename}.'", 500);
|
||||||
|
|
||||||
|
// Import the auth modules code
|
||||||
|
require_once( $filename );
|
||||||
|
|
||||||
|
// Ensure the class has been defined
|
||||||
|
if( !class_exists( $classname ) ) throw new ConfigException("Authentication module is invalid: '{$classname}'.", 500);
|
||||||
|
|
||||||
|
// Create an instance of the module, and return it
|
||||||
|
return new $classname();
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
?>
|
||||||
58
code/iauthorisor.php
Normal file
58
code/iauthorisor.php
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IAuthorisor
|
||||||
|
* Interfakce for authorisation classes
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface IAuthorisor {
|
||||||
|
|
||||||
|
// Do any module-specific initialisation
|
||||||
|
public function initialise();
|
||||||
|
// Shutdown the module cleanly when finished
|
||||||
|
public function uninitialise();
|
||||||
|
|
||||||
|
// Find out which usergroup a given member belongs
|
||||||
|
public function is_student( $username, $module, $year = null );
|
||||||
|
public function is_lecturer( $username, $module, $year = null );
|
||||||
|
public function is_sysadmin( $username );
|
||||||
|
// A sysadmin should not be able to administrate a course for which they are a student
|
||||||
|
public function may_sysadmin( $username, $module, $year = null );
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IAuthorisor
|
||||||
|
* Interface for authorisation classes
|
||||||
|
*/
|
||||||
|
|
||||||
|
class IAuthorisorFactory {
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function get( $module ) {
|
||||||
|
global $_meta;
|
||||||
|
|
||||||
|
// Get the filename and classnames for this module
|
||||||
|
$filename = "{$_meta['script-dir']}/code/auth_{$module}.php";
|
||||||
|
$classname = "Authorisor_{$module}";
|
||||||
|
|
||||||
|
// Check to make sure this module exists
|
||||||
|
if( !file_exists($filename) ) throw new ConfigException("Authorisation module could not be found: '{$filename}.'", 500);
|
||||||
|
|
||||||
|
// Import the auth modules code
|
||||||
|
require_once( $filename );
|
||||||
|
|
||||||
|
// Ensure the class has been defined
|
||||||
|
if( !class_exists( $classname ) ) throw new ConfigException("Authorisation module is invalid: '{$classname}'.", 500);
|
||||||
|
|
||||||
|
// Create an instance of the module, and return it
|
||||||
|
return new $classname();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
?>
|
||||||
71
code/request_handler.php
Normal file
71
code/request_handler.php
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RequestHandler
|
||||||
|
* This class decodes the Request URI in order to store multiple variables in the request URI itself
|
||||||
|
*/
|
||||||
|
|
||||||
|
class RequestHandler {
|
||||||
|
|
||||||
|
// The request uri
|
||||||
|
private $request_string;
|
||||||
|
// Stores a list of all the variables we've already found to avoid needing to
|
||||||
|
// find them using regular expressions many times.
|
||||||
|
private $cache;
|
||||||
|
|
||||||
|
public function __construct( $request_string ) {
|
||||||
|
$this->request_string = $request_string;
|
||||||
|
$this->cache = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function current_page() {
|
||||||
|
return $this->request_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get( $key, $value_pattern = '[^/]*' ) {
|
||||||
|
// Look in the cache to see if weve already decoded this variable
|
||||||
|
if( in_array( $key, $this->cache ) ) return $this->cache[ $key ];
|
||||||
|
|
||||||
|
// Construct the regex to search for /$key/$value/ pairs, and return the $value part
|
||||||
|
$key = str_replace('£', '\£', $key);
|
||||||
|
$value_pattern = str_replace('£', '\£', $value_pattern);
|
||||||
|
$pattern = "£/{$key}/({$value_pattern})(/|\$)£";
|
||||||
|
|
||||||
|
// Look to see if this variable is in the request string
|
||||||
|
$count = preg_match( $pattern, $this->request_string, $matches );
|
||||||
|
|
||||||
|
// See if the variable was set
|
||||||
|
if( $count == 0 ) return null;
|
||||||
|
|
||||||
|
// Store the result for next time
|
||||||
|
$this->cache[ $key ] = $matches[1];
|
||||||
|
|
||||||
|
// And return it to the user
|
||||||
|
return $matches[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function construct() {
|
||||||
|
global $_meta;
|
||||||
|
|
||||||
|
// Varargsy
|
||||||
|
$args = func_get_args();
|
||||||
|
|
||||||
|
// Construct the proper request string for these arguments
|
||||||
|
$request_string = "{$_meta['base-dir']}/";
|
||||||
|
$count = count( $args );
|
||||||
|
for( $i = 0 ; $i < $count; $i++ ) {
|
||||||
|
$arg = $args[ $i ];
|
||||||
|
// If this item is null, try to find the value of the previous key from the current
|
||||||
|
// request object as a convenience to the user. It assumes the default value pattern.
|
||||||
|
if( $arg === null && $i > 0) {
|
||||||
|
$arg = $this->get( $args[ $i -1 ] );
|
||||||
|
}
|
||||||
|
$request_string .= urlencode($arg) . '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $request_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
?>
|
||||||
229
code/session_handler.php
Normal file
229
code/session_handler.php
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SessionHandler
|
||||||
|
* This class handles using php sessions to maintain user state across
|
||||||
|
* multiple sessions
|
||||||
|
*/
|
||||||
|
|
||||||
|
class SessionHandler {
|
||||||
|
|
||||||
|
private $authentication;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
global $_config;
|
||||||
|
|
||||||
|
// Initialise PHP's Session subsystem
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
// Check to see if this is a new session
|
||||||
|
if( !isset( $_SESSION['initialised'] ) || !$_SESSION['initialised'] ) {
|
||||||
|
$this->start_new_session();
|
||||||
|
} else {
|
||||||
|
// The session already exists, check its validity
|
||||||
|
if( $this->is_session_valid() ) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// BAD USER SESSION, start a new one
|
||||||
|
$this->start_new_session();
|
||||||
|
// And inform the user
|
||||||
|
$_template['messages'][] = "Bad session, starting a new one";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the Authentication modules
|
||||||
|
$this->authentication = IAuthenticatorFactory::get( $_config['authentication-module'] );
|
||||||
|
$this->authentication->initialise();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __destruct() {
|
||||||
|
// Shut down the authentication modules
|
||||||
|
$this->authentication->uninitialise();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Accessors
|
||||||
|
*/
|
||||||
|
public function authenticator() { return $this->authentication; }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following methods deal with the user session
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Initialises all the variables we require in each user session
|
||||||
|
public function start_new_session() {
|
||||||
|
global $_config;
|
||||||
|
|
||||||
|
// Set up all the session variables
|
||||||
|
$_SESSION['initialised'] = true;
|
||||||
|
$_SESSION['logged_in'] = false;
|
||||||
|
$_SESSION['username'] = '';
|
||||||
|
$_SESSION['hash'] = $this->generate_hash();
|
||||||
|
$_SESSION['previous_page'] = $_config['homepage'];
|
||||||
|
$_SESSION['requested_page'] = '';
|
||||||
|
$_SESSION['history'] = array('home');
|
||||||
|
$_SESSION['lockout'] = false;
|
||||||
|
$_SESSION['lockout-attempts'] = 0;
|
||||||
|
|
||||||
|
// Be paranoid, change session id
|
||||||
|
$this->auth_state_changed();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function is_session_valid() {
|
||||||
|
// Check that the identifying information given by the user matches that which was
|
||||||
|
// saved in the session when it was created
|
||||||
|
return ($_SESSION['hash'] == $this->generate_hash());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function should be called whenever the authorisation level
|
||||||
|
* changes in order to keep the session secure.
|
||||||
|
* It prevents against Session Fixation (http://www.acros.si/papers/session_fixation.pdf)
|
||||||
|
*/
|
||||||
|
public function auth_state_changed() {
|
||||||
|
session_regenerate_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function marks a user as having been logged into the system
|
||||||
|
*/
|
||||||
|
private function mark_logged_in_as( $username ) {
|
||||||
|
$_SESSION['username'] = $username;
|
||||||
|
$_SESSION['logged_in'] = true;
|
||||||
|
|
||||||
|
// The login state has changed
|
||||||
|
$this->auth_state_changed();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function marks a user as having been logged out of the system
|
||||||
|
*/
|
||||||
|
private function mark_logged_out() {
|
||||||
|
$_SESSION['logged_in'] = false;
|
||||||
|
|
||||||
|
// The login state has changedd
|
||||||
|
$this->auth_state_changed();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function returns whether or not the user is logged in
|
||||||
|
*/
|
||||||
|
public function is_logged_in() {
|
||||||
|
return $_SESSION['logged_in'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function returns the username of the currently logged in user
|
||||||
|
*/
|
||||||
|
public function username() {
|
||||||
|
return $_SESSION['username'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function requires a user to be logged in, else an exception is thrown
|
||||||
|
*/
|
||||||
|
public function require_logged_in() {
|
||||||
|
if( !$_SESSION['logged_in'] ) throw new AuthenticationException('You must be logged on to view this resource');
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function generates a hash from user identifiable information
|
||||||
|
* to try and prevent session theft.
|
||||||
|
* If the session id is stolen by an attacker, chances are some of the
|
||||||
|
* information used to generate the hash will change, and the session
|
||||||
|
* will be immediately marked as invalid. This hash is checked for
|
||||||
|
* consistency on every request.
|
||||||
|
*/
|
||||||
|
public function generate_hash() {
|
||||||
|
global $_config;
|
||||||
|
// Hash together the following pieces of identifying information which remain constant throughout the session:
|
||||||
|
// User Agent string - This will be constant for the user, but might not be for the attacker
|
||||||
|
// Netork Mask - ensures each request is coming from the same network. We may not be able to use the
|
||||||
|
// while ip, because some ISPs use load-balanced proxies, so subsequent requests may come from a
|
||||||
|
// different machine ip, but we can still use at least part of the address to filter out would be attackers.
|
||||||
|
$key = $_SERVER['HTTP_USER_AGENT'] . get_network_mask( $_SERVER['REMOTE_ADDR'], $_config['session-network-mask'], $_config['session-network-mode']);
|
||||||
|
return md5( $key );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following methods deal with the users history
|
||||||
|
* These will be used to set up redirection after special pages, such as login
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Add a new item to the user history
|
||||||
|
public function history_add_request( $page ) {
|
||||||
|
global $_config;
|
||||||
|
// Add this item to the beginning of the history array
|
||||||
|
array_unshift( $_SESSION['history'], $page );
|
||||||
|
// Keep the size below a fixed limit
|
||||||
|
if( count($_SESSION['history']) > $_config['max-history'] ) {
|
||||||
|
array_pop( $_SESSION['history'] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the current item from the user history
|
||||||
|
public function history_drop_request() {
|
||||||
|
// remove the item from the beginning of the array
|
||||||
|
array_shift( $_SESSION['history'] );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return an item from the user history
|
||||||
|
public function history_get( $index ) {
|
||||||
|
if( is_numeric($index) ) {
|
||||||
|
if( $index < count($_SESSION['history']) ) {
|
||||||
|
return $_SESSION['history'][$index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following methods deal with user authentication and authorisation
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Log the user in
|
||||||
|
public function login( $username, $password ) {
|
||||||
|
global $_config;
|
||||||
|
|
||||||
|
// Check the user hasnt been locked out before trying to login
|
||||||
|
if( $_SESSION['lockout'] == true ) {
|
||||||
|
// See if the lockout has expired
|
||||||
|
if($_SESSION['lockout-expiry'] > time() ) throw new AccountLockoutException('Your session is currently locked as a result of enterring too many incorrect passwords. You will not be able to attempt a login for another ' . date('i \m\i\n(\s), s \s\e\c(\s)', $_SESSION['lockout-expiry']-time()));
|
||||||
|
else {
|
||||||
|
// Unset the lockout
|
||||||
|
$_SESSION['lockout'] = false;
|
||||||
|
$_SESSION['lockout-expiry'] = 0;
|
||||||
|
$_SESSION['lockout-attempts'] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Attempt to authenticate with these credentials
|
||||||
|
$this->authentication->authenticate( $username, $password );
|
||||||
|
} catch( Exception $e ) {
|
||||||
|
// Increment the number of failed authentication attempts
|
||||||
|
$_SESSION['lockout-attempts']++;
|
||||||
|
// Check the lockout attempts
|
||||||
|
if( $_SESSION['lockout-attempts'] >= $_config['lockout-attempts'] ) {
|
||||||
|
$_SESSION['lockout'] = true;
|
||||||
|
$_SESSION['lockout-expiry'] = time() + $_config['lockout-duration'];
|
||||||
|
throw new AccountLockoutException('You have enterred an incorrect password too many times, and your session has been locked. You will not be able to attempt another login for the next 10 minutes.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// The login failed, rethrow the original exception
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Successful login, update the session state
|
||||||
|
$this->mark_logged_in_as( $username );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log the current user out
|
||||||
|
public function logout() {
|
||||||
|
$this->mark_logged_out();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
?>
|
||||||
2
deny.htaccess
Normal file
2
deny.htaccess
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
Order Allow,Deny
|
||||||
|
Deny from all
|
||||||
82
index.php
Normal file
82
index.php
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Index
|
||||||
|
* This page handles all requests, authentication, authorisation, etc.
|
||||||
|
* It loads the page requested by the user, embeds it in the template, and sends it to the browser
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Begin output buffering on the entire document, so we can set cookies
|
||||||
|
// after some output has been printed.
|
||||||
|
ob_start();
|
||||||
|
|
||||||
|
// Include our global configuration.
|
||||||
|
// It will pull all other includes we need, as well as define all global configuration and state variables.
|
||||||
|
require_once('code/config.php');
|
||||||
|
|
||||||
|
// Process the request uri for this page
|
||||||
|
$_req = new RequestHandler( $_SERVER['REQUEST_URI'] );
|
||||||
|
|
||||||
|
try {
|
||||||
|
// We will use PHP sessions to track users of the system.
|
||||||
|
// On their own, php sessions are not secure by default, so we will
|
||||||
|
// do some additional work to ensure they are used correctly.
|
||||||
|
$_session = new SessionHandler();
|
||||||
|
|
||||||
|
// See if the requested page exists
|
||||||
|
$_chroot = realpath("{$_meta['script-dir']}/page-sources/");
|
||||||
|
$_pagename = (!is_null($_req->get('page')) ? strtolower($_req->get('page')) : 'home');
|
||||||
|
$_page = $_chroot . '/' . $_pagename . '.php';
|
||||||
|
|
||||||
|
// Capture this request so we know where the user wanted to go
|
||||||
|
$_session->history_add_request( $_SERVER['REQUEST_URI'] );
|
||||||
|
|
||||||
|
// Check that this path exists
|
||||||
|
$_realpath = realpath($_page);
|
||||||
|
if( $_realpath === false ) throw new Exception('Requested page doesnt exist', 404);
|
||||||
|
|
||||||
|
// Check that the real file exists under the pages directory
|
||||||
|
if( substr($_realpath, 0, strlen($_chroot)) != $_chroot ) throw new Exception('Forbidden', 403);
|
||||||
|
|
||||||
|
|
||||||
|
} catch( Exception $e ) {
|
||||||
|
$_meta['error-code'] = $e->getCode();
|
||||||
|
$_meta['error-message'] = $e->getMessage();
|
||||||
|
$_page = "{$_meta['script-dir']}/page-sources/error.php";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Capture the output and store it in the template
|
||||||
|
ob_start();
|
||||||
|
|
||||||
|
try {
|
||||||
|
include( $_page );
|
||||||
|
} catch( AuthenticationException $e ) {
|
||||||
|
// Redirect to the login page
|
||||||
|
$_template['messages'][] = $e->getMessage();
|
||||||
|
$_page = "{$_meta['script-dir']}/page-sources/login.php";
|
||||||
|
// Get the new page
|
||||||
|
ob_clean();
|
||||||
|
include( $_page );
|
||||||
|
} catch( ParameterException $e ) {
|
||||||
|
// Redirect to the error page
|
||||||
|
$_meta['error-code'] = $e->getCode();
|
||||||
|
$_meta['error-message'] = "Required parameter is either missing, or contains an illegal value: '{$e->getMessage()}'";
|
||||||
|
$_page = "{$_meta['script-dir']}/page-sources/error.php";
|
||||||
|
// Get the new page
|
||||||
|
ob_clean();
|
||||||
|
include( $_page );
|
||||||
|
}
|
||||||
|
|
||||||
|
$_template['page'] = ob_get_contents();
|
||||||
|
|
||||||
|
// Since we've already caught them, prevent the contents from being
|
||||||
|
// passed to the browser
|
||||||
|
ob_end_clean();
|
||||||
|
|
||||||
|
// Get the template
|
||||||
|
include( $_template['template-file'] );
|
||||||
|
|
||||||
|
// Send any remaining output to the browser
|
||||||
|
ob_end_flush();
|
||||||
|
|
||||||
|
?>
|
||||||
10
page-sources/cv.php
Normal file
10
page-sources/cv.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curriculum Vitae
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
$_template['title'] = "Curriculum Vitae";
|
||||||
|
|
||||||
|
?>
|
||||||
15
page-sources/error.php
Normal file
15
page-sources/error.php
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Hide this page from the users history in the session
|
||||||
|
$_session->history_drop_request();
|
||||||
|
// Display the error message, and redirect
|
||||||
|
$_template['title'] = "Errawr";
|
||||||
|
$_template['messages'][] = $_meta['error-message'];
|
||||||
|
$_template['redirect-to'] = $_session->history_get(0); // Top of the list now
|
||||||
|
|
||||||
|
?>
|
||||||
10
page-sources/home.php
Normal file
10
page-sources/home.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
$_template['title'] = 'Home';
|
||||||
|
|
||||||
|
?>
|
||||||
59
page-sources/login.php
Normal file
59
page-sources/login.php
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Login
|
||||||
|
* This page allows and processes a user login
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
$_template['title'] = 'Login';
|
||||||
|
|
||||||
|
// Has the login form been submitted?
|
||||||
|
if( count( $_POST ) > 0 ) {
|
||||||
|
// Hide this request from the user's history
|
||||||
|
$_session->history_drop_request();
|
||||||
|
// Now it wont matter how many times a user fails authentication, they will always be redirected to the
|
||||||
|
// page they requested in the first place
|
||||||
|
|
||||||
|
// Check for the presence of the required form fields
|
||||||
|
if( !isset($_POST['username']) ) throw new ParameterException(); $username = $_POST['username'];
|
||||||
|
|
||||||
|
$password = '';
|
||||||
|
if( isset($_POST['password']) ) $password = $_POST['password'];
|
||||||
|
|
||||||
|
// Attempt the login
|
||||||
|
try {
|
||||||
|
$_session->login( $username, $password );
|
||||||
|
|
||||||
|
// Present a message to the user
|
||||||
|
$_template['messages'][] = 'You have successfully logged in.';
|
||||||
|
|
||||||
|
// Set a redirection to the page the user was originally on (now the top of the list, because we dropped this page)
|
||||||
|
$_template['redirect-to'] = $_session->history_get(0);
|
||||||
|
|
||||||
|
} catch (AuthenticationException $e) {
|
||||||
|
// Authentication failed
|
||||||
|
$_template['messages'][] = 'Authentication failed';
|
||||||
|
_show_login_form();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_show_login_form();
|
||||||
|
}
|
||||||
|
|
||||||
|
function _show_login_form() {
|
||||||
|
global $_meta, $_req;
|
||||||
|
|
||||||
|
// Present the login form to the user
|
||||||
|
?>
|
||||||
|
<form method="post" action="<?php echo $_req->construct('page','login'); ?>">
|
||||||
|
<p class="loginform">
|
||||||
|
<input class="username" name="username" type="text" /><label for="username">Username</label><br />
|
||||||
|
<input name="submit" type="submit" value="Login" />
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
17
page-sources/logout.php
Normal file
17
page-sources/logout.php
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Log the user our of their current session
|
||||||
|
$_session->logout();
|
||||||
|
|
||||||
|
// Leave the user a notice, and redirect them back to the home page
|
||||||
|
$_template['title'] = 'Logout';
|
||||||
|
$_template['messages'][] = 'You have successfully been logged out.';
|
||||||
|
$_template['redirect-to'] = $_req->construct('page','home');
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
133
resources/normal.css
Normal file
133
resources/normal.css
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
Layout
|
||||||
|
*/
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0em;
|
||||||
|
padding: 0em;
|
||||||
|
font-family: verdana, tahoma, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.header {
|
||||||
|
border-bottom: 1px solid grey;
|
||||||
|
padding-bottom: 0.5em;
|
||||||
|
margin: 0.5em 1em 1em 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.sidebar {
|
||||||
|
border-right: 1px solid grey;
|
||||||
|
margin: 0em;
|
||||||
|
padding: 1em;
|
||||||
|
float: left;
|
||||||
|
line-height: 1.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.page {
|
||||||
|
margin: 1em;
|
||||||
|
margin-left: 9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.footer {
|
||||||
|
border-top: 1px solid grey;
|
||||||
|
margin: 1em;
|
||||||
|
margin-top: 2em;
|
||||||
|
padding-top: 0.5em;
|
||||||
|
height: 3em;
|
||||||
|
clear: both;
|
||||||
|
|
||||||
|
font-size: smaller;
|
||||||
|
color: grey;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.sidebar ul {
|
||||||
|
list-style: circle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Page styles
|
||||||
|
*/
|
||||||
|
|
||||||
|
div.header h1 {
|
||||||
|
font-size: 3.0em;
|
||||||
|
margin: 0.2em;
|
||||||
|
margin-left: 0em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Utilities
|
||||||
|
*/
|
||||||
|
br.spacer {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.quote {
|
||||||
|
margin-left: 1em;
|
||||||
|
padding-left: 2em;
|
||||||
|
border: 1px solid moccasin;
|
||||||
|
background-color: moccasin;
|
||||||
|
background-image: url('../resources/quote-32.png');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: top left;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.quote blockquote {
|
||||||
|
margin: 0em;
|
||||||
|
padding: 0.3em 0.6em 0em 0.3em;
|
||||||
|
font-style: italic;
|
||||||
|
background-color: lightyellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Dialog boxes
|
||||||
|
*/
|
||||||
|
|
||||||
|
p.message {
|
||||||
|
border: 1px solid red;
|
||||||
|
background-color: lightsalmon;
|
||||||
|
color: darkred;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.information {
|
||||||
|
border: 1px solid blue;
|
||||||
|
background-color: powderblue;
|
||||||
|
color: darkslateblue;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Boxed item
|
||||||
|
*/
|
||||||
|
|
||||||
|
div.box {
|
||||||
|
margin-bottom: 2em;
|
||||||
|
padding: 1.5em;
|
||||||
|
border: 1px solid grey;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.box ul {
|
||||||
|
width: 20em;
|
||||||
|
line-height: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.box span.result {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Forms
|
||||||
|
*/
|
||||||
|
p.loginform {
|
||||||
|
width: 30em;
|
||||||
|
}
|
||||||
|
p.loginform label {
|
||||||
|
line-height: 200%;
|
||||||
|
}
|
||||||
|
p.loginform input {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
BIN
resources/quote-32.png
Normal file
BIN
resources/quote-32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.4 KiB |
36
resources/rating.php
Normal file
36
resources/rating.php
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
if( !isset($_GET['r']) || (float)$_GET['r'] < 0.0 || 10.0 < (float)$_GET['r'] ) {
|
||||||
|
header("HTTP/1.0 500 Illegal Parameter", true, 500);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
$rating = (float)$_GET['r'] / 10;
|
||||||
|
|
||||||
|
// Load in the two images
|
||||||
|
$bg = imagecreatefrompng( "rating_bg.png" );
|
||||||
|
$fg = imagecreatefrompng( "rating_fg.png" );
|
||||||
|
|
||||||
|
// Find the size of the source images
|
||||||
|
$width = imagesx( $bg );
|
||||||
|
$height = imagesy( $bg );
|
||||||
|
|
||||||
|
// Modify the width to crop to the required percentage
|
||||||
|
$fgwidth = $rating * $width;
|
||||||
|
|
||||||
|
// Crop the foreground to the desired width, copying it over the background
|
||||||
|
imagecopyresampled( $bg, $fg, 0, 0, 0, 0, $fgwidth, $height, $fgwidth, $height );
|
||||||
|
|
||||||
|
// Send the correct image content type header
|
||||||
|
header("Content-Type: image/png");
|
||||||
|
|
||||||
|
// Send the new combined image
|
||||||
|
imagepng( $bg );
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
BIN
resources/rating_bg.png
Normal file
BIN
resources/rating_bg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 990 B |
BIN
resources/rating_fg.png
Normal file
BIN
resources/rating_fg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
80
templates/default.php
Normal file
80
templates/default.php
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Template
|
||||||
|
* This file contains the common html elements for all pages in the site.
|
||||||
|
* _template variables contain the information from the acutal page to be displayed
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<title><?php echo $_template['title']; ?></title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="<?php echo $_meta['base-dir']; ?>/resources/normal.css" />
|
||||||
|
<?php
|
||||||
|
// If we have a redirection, implement a meta refresh here
|
||||||
|
if( $_template['redirect-to'] ) {
|
||||||
|
?>
|
||||||
|
<meta http-equiv="refresh" content="5;url=<?php echo $_template['redirect-to']; ?>" />
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add any header info from the page
|
||||||
|
echo $_template['head'];
|
||||||
|
?>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="header">
|
||||||
|
<h1>Ben Roberts</h1>
|
||||||
|
<strong>MEng Computer Science @ ecs.soton.ac.uk</strong>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="sidebar">
|
||||||
|
<strong>Navigation</strong>
|
||||||
|
<ul>
|
||||||
|
<li><a href="<?php echo $_req->construct('page','home'); ?>" title="Homepage">Home</a></li>
|
||||||
|
<li><a href="<?php echo $_req->construct('page','cv'); ?>" title="Curriculum Vitae">CV</a></li>
|
||||||
|
<?php if( $_session->is_logged_in() ) { ?>
|
||||||
|
<li><a href="<?php echo $_req->construct('page','logout'); ?>" title="Logout">Logout</a></li>
|
||||||
|
<?php } ?>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page">
|
||||||
|
<?php
|
||||||
|
// Display any page annoucements
|
||||||
|
if( count($_template['messages']) > 0 ) {
|
||||||
|
foreach( $_template['messages'] as $_message ) {
|
||||||
|
?>
|
||||||
|
<p class="message">
|
||||||
|
<?php echo $_message; ?>
|
||||||
|
</p>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<h1><?php echo $_template['title']; ?></h1>
|
||||||
|
<?php
|
||||||
|
// Include the main page content
|
||||||
|
echo $_template['page'];
|
||||||
|
|
||||||
|
// Display any redirections
|
||||||
|
if( $_template['redirect-to'] ) {
|
||||||
|
?>
|
||||||
|
<p class="information">
|
||||||
|
About to be redirected... If nothing happens after 10 seconds, please click <a href="<?php echo $_template['redirect-to']; ?>" title="Redirecting">here</a>.
|
||||||
|
</p>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer">
|
||||||
|
Footer, rar rar rar.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
39
test.php
Normal file
39
test.php
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once( 'code/config.php' );
|
||||||
|
|
||||||
|
if( isset($_GET['destroy']) ) {
|
||||||
|
session_start();
|
||||||
|
session_destroy();
|
||||||
|
echo "Session destroyed";
|
||||||
|
}
|
||||||
|
|
||||||
|
if( isset($_GET['request']) ) {
|
||||||
|
require_once( "code/request_handler.php" );
|
||||||
|
|
||||||
|
echo '<pre>';
|
||||||
|
$req1 = new RequestHandler( "/page/user_reviews/username/tw205/aux&/true/false/" );
|
||||||
|
var_dump( $req1->get("page") );
|
||||||
|
var_dump( $req1->get("username") );
|
||||||
|
var_dump( $req1->get("aux") );
|
||||||
|
var_dump( $req1->get("aux&", ".+") );
|
||||||
|
|
||||||
|
var_dump( $req1->construct('page', $req1->get('page'), 'username', null, 'aux&', null) );
|
||||||
|
|
||||||
|
echo '</pre>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if( isset($_GET['session']) ) {
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
echo '<pre>';
|
||||||
|
var_dump($_SESSION);
|
||||||
|
echo '</pre>';
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
Reference in New Issue
Block a user