Explorar el Código

Initial commit

Thomas Leister hace 11 años
padre
commit
1f571ce576

+ 60 - 0
config/config.inc.php

@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * MySQL server and database settings
+ */
+
+define("MYSQL_HOST", "localhost");
+define("MYSQL_USER", "");
+define("MYSQL_PASSWORD", "");
+define("MYSQL_DATABASE", "");
+
+
+/*
+ * Database table names
+ */
+
+// Table names
+define("DBT_USERS", "users");
+define("DBT_DOMAINS", "domains");
+define("DBT_ALIASES", "aliases");
+
+// Users table columns
+define("DBC_USERS_ID", "id");
+define("DBC_USERS_USERNAME", "username");
+define("DBC_USERS_DOMAIN", "domain");
+define("DBC_USERS_PASSWORD", "password");
+define("DBC_USERS_MAILBOXLIMIT", "mailbox_limit");
+
+// Domains table columns
+define("DBC_DOMAINS_ID", "id");
+define("DBC_DOMAINS_DOMAIN", "domain");
+
+// Aliases table columns
+define("DBC_ALIASES_ID", "id");
+define("DBC_ALIASES_SOURCE", "source");
+define("DBC_ALIASES_DESTINATION", "destination");
+
+
+/*
+ * Frontend paths
+ */
+
+define("FRONTEND_BASE_PATH", "http://localhost/webmum/");
+define("SUBDIR", "/webmum/");
+
+
+/*
+ * Admin e-mail address
+ */
+
+define("ADMIN_EMAIL", "admin@server.tld");
+
+
+/*
+ * Minimal password length
+ */
+
+define("MIN_PASS_LENGTH", 8);
+
+?>

+ 246 - 0
include/css/style.css

@@ -0,0 +1,246 @@
+body{
+	font-family:Arial;
+	font-size:12px;
+	margin:0px;
+	background-color:white;
+}
+
+
+/*
+ * Main Layout
+ */
+
+#header{
+	position:relative;
+	height:50px;
+	width:100%;
+	background-color:rgba(15, 15, 15, 1);
+	background: linear-gradient(rgba(63, 63, 63, 1), rgba(15, 15, 15, 1));
+	color:white;
+	line-height:50px;
+	box-sizing:border-box;
+	padding-left:20px;
+	padding-right:20px;
+}
+
+	#header div.title{
+		float:left;
+		height:50px;
+		width:auto;
+	}
+	
+		#header div.title a{
+			font-size:15px;
+			color:white;
+			text-decoration:none;
+		}
+		#header div.title a:hover{
+			text-decoration:underline;
+		}
+	
+	#header div.header-menu{
+		float:left;
+		padding-left:100px;
+	}
+	
+	#header div.header-button{
+		float:left;
+		height:50px;
+		margin-right:30px;
+		color:white;
+	}
+	
+	
+		#header div.header-button a{
+			color:white;
+			text-decoration:none;
+		}
+		#header div.header-button a:hover{
+			text-decoration:underline;
+		}
+
+#content{
+	height:auto;
+	min-height:400px;
+	padding:20px;
+	background-color:white;
+}
+
+	#content h1{
+		color:rgba(62, 59, 59, 1);
+	}
+	
+	#content a{
+		color: blue;
+		text-decoration: none;
+	}
+	#content a:hover{
+		text-decoration:underline;
+	}
+
+
+/*
+ * Buttons
+ */
+
+	#content .button{
+		background:none;
+		background: linear-gradient(white, rgba(237, 237, 237, 1));
+		border: 1px solid rgba(200, 200, 200, 1);
+		border-radius:3px;
+		font-family:arial;
+		min-width:200px;
+		margin-bottom:10px;
+		height:auto;
+		transition: box-shadow 0.2s;
+	}
+	
+	#content a.button{
+		display:block;
+	}
+	
+	#content .button:hover{
+		box-shadow: 1px 1px 4px #DBDBDB;
+		text-decoration:none;
+		cursor:pointer;
+		transition: box-shadow 0.2s;
+	}
+	
+	#content .button-big{
+		width:300px;
+		font-size:18px;
+		line-height:45px;
+		padding-left:20px;
+		padding-right:20px;
+		color:rgba(57, 57, 57, 1);
+		text-decoration:none;
+	}
+	
+	#content .button-small{
+		width:200px;
+		font-size:13px;
+		line-height:30px;
+		padding-left:10px;
+		padding-right:10px;
+		color:rgba(57, 57, 57, 1);
+		text-decoration:none;
+	}
+	
+	
+	
+	#content .button a{
+		
+	}
+		
+	#content div.button-big a{
+		
+	}	
+	
+	
+	
+/****** Tables ******/
+	
+	#content table{
+		border-collapse: collapse;
+		border:none;
+	}
+	
+	#content table tr th{
+		padding-bottom:10px;
+		padding-left:15px;
+		padding-right:15px;
+	}
+	
+	#content table tr td{
+		padding:10px;
+		border:1px solid rgba(179, 176, 176, 1);
+	}
+	
+	#content table.list{
+		margin-top:40px;
+	}
+	
+	#content table.list tr:hover{
+		background-color:rgba(234, 234, 234, 1);
+	}
+	#content table.list tr.head:hover{
+		background:none;
+	}
+	#content table.list tr:hover a{
+		color:blue;
+	}
+	
+	#content table.list a {
+		color:rgba(148, 148, 255, 1);
+	}
+	
+/****** Tables END ******/
+
+
+	#content input.textinput, textarea.textinput, select{
+		background: none repeat scroll 0% 0% transparent;
+		border: 1px solid rgba(200, 200, 200, 1);
+		border-radius: 3px;
+		margin-bottom: 5px;
+		padding: 3px;
+		box-shadow: inset 1px 1px 3px rgba(230, 230, 230, 1);
+	}
+	
+	#content input.textinput:focus, textarea.textinput:focus{
+		border: 1px solid rgba(137, 137, 137, 1);
+	}
+	
+	#content textarea.textinput{
+		min-height:150px;
+		min-width:400px;
+	}
+	
+	
+	
+
+#footer{
+	position:relative;
+	height:50px;	
+	width:100%;
+	background-color:rgba(15, 15, 15, 1);
+	background-color:white;
+	padding:20px;
+	box-sizing:border-box;
+}
+
+
+/*
+ * Notifications
+ */
+
+div.notification{
+	height:auto;
+	width:100%;
+	margin-top:15px;
+	text-align:center;
+	border-style:solid;
+	border-width:1px;
+	border-radius:3px;
+	padding:10px;
+	box-sizing:border-box;
+	margin-bottom:40px;
+}
+
+div.notification-fail{
+	background-color:#FCACAC;
+	border-color:red;
+}
+
+div.notification-success{
+	background-color:rgba(182, 255, 183, 1);
+	border-color:green;
+}
+
+
+/*
+ * Headlines
+ */
+
+#content h1{
+	font-size:
+}

+ 38 - 0
include/php/checkpermissions.inc.php

@@ -0,0 +1,38 @@
+<?php
+/*
+ * Checks, if the current user has the permission, which is required for an action.
+ * $role_req = required role [string]
+ * 
+ * Returns:
+ * true: User has role $role_req
+ * false: User doesn't have role $role_req
+ * 
+ * Possible roles: user, admin
+ */
+
+function user_has_permission($role_req){
+	global $user;
+	if($user->isLoggedIn() === true){
+		// User is logged in. Check permissions
+		// To be done. Load user role from database or better: save in SESSION
+		if($role_req === "user"){
+			if($user->getRole() == "user" || $user->getRole() == "admin"){
+				return true;
+			}
+			else{
+				return false;
+			}
+		}
+		else if($role_req === "admin"){
+			if($user->getRole() == "admin"){
+				return true;
+			}
+		}
+	}
+	else{
+		// User is not logged in => public user => no permissions
+		return false;
+	}
+}
+
+?>

+ 126 - 0
include/php/classes/user.class.php

@@ -0,0 +1,126 @@
+<?php
+class USER {
+	
+	/* 
+	 * Class attributes
+	 */
+	
+	private $uid;
+	private $email;
+	private $role;
+	private $loggedin = false;
+	
+	/*
+	 * Constructor
+	 * 
+	 * Fills the user object up with anonymous data
+	 */
+	
+	function __construct(){
+		// Start session
+		session_start();
+		session_regenerate_id();
+		
+		if($_SESSION['email'] === ADMIN_EMAIL){
+			$this->role = "admin";
+		}
+		else{
+			$this->role = "user";
+		}	
+		
+		if(isset($_SESSION['uid']) && $_SESSION['uid'] != ""){
+			// revive session ...
+			$this->uid = $_SESSION['uid'];
+			$this->loggedin = true;
+		}
+	}
+	
+	/*
+	 * Getter functions
+	 */
+	
+	function getUID(){
+		return $this->uid;
+	}
+	
+	function getRole(){
+		return $this->role;
+	}
+	
+	function isLoggedIn(){
+		return $this->loggedin;
+	}
+	
+	
+	
+	/*
+	 * Login function. Checks login data and writes information to SESSION
+	*
+	* Returns:
+	* true: Login was successful
+	* false: Login was not successful
+	*/
+	
+	function login($email, $password){
+		global $db;
+		// Prepare e-mail address
+		$email = $db->escape_string($email);
+		$password = $db->escape_string($password);
+		$email_part = explode("@", $email);
+		$username = $email_part[0];
+		$domain = $email_part[1];
+	
+	
+		// Check e-mail address
+		$sql = "SELECT `".DBC_USERS_ID."`, `".DBC_USERS_PASSWORD."` FROM `".DBT_USERS."` WHERE `".DBC_USERS_USERNAME."` = '$username' AND `".DBC_USERS_DOMAIN."` = '$domain' LIMIT 1;";
+	
+		if(!$result = $db->query($sql)){
+			die('There was an error running the query [' . $db->error . ']');
+		}
+	
+		if($result->num_rows === 1){
+			$userdata = $result->fetch_array(MYSQLI_ASSOC);
+			$uid = $userdata[DBC_USERS_ID];
+			$password_hash = $userdata[DBC_USERS_PASSWORD];
+				
+			// Check password
+			if (crypt($password, $password_hash) === $password_hash) {
+				// Password is valid, start a logged-in user session
+				$this->loggedin = true;
+				$_SESSION['uid'] = $uid;
+				$_SESSION['email'] = $email;
+	
+				return true;
+			}
+			else {
+				// Password is invalid
+				return false;
+			}
+		}
+		else{
+			// User could not be found
+			return false;
+		}
+	}
+	
+	
+	/*
+	 * Changes user password. 
+	 * Returns:
+	 * true: Change success
+	 * false: Error
+	 */
+	
+	function change_password($newpass, $newpass_rep){
+		$pass_ok = check_new_pass($newpass, $newpass_rep);
+		if($pass_ok === true){
+			$pass_hash = gen_pass_hash($newpass);
+			write_pass_hash_to_db($pass_hash, $this->uid);
+			return true;
+		}
+		else{
+			return false;
+		}
+	}
+}
+?>

+ 7 - 0
include/php/db_close.inc.php

@@ -0,0 +1,7 @@
+<?php
+/*
+ * Free resources
+ */
+
+$db->close();
+?>

+ 22 - 0
include/php/default.inc.php

@@ -0,0 +1,22 @@
+<?php
+
+// Include config
+require_once 'config/config.inc.php';
+
+// Establish database connection 
+
+$db = new mysqli(MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE);
+
+if($db->connect_errno > 0){
+	die('Unable to connect to database [' . $db->connect_error . ']');
+}
+
+/* Import classes */
+require_once 'include/php/classes/user.class.php';
+
+$user = new USER();
+
+require_once 'include/php/global.inc.php';
+require_once 'include/php/checkpermissions.inc.php';
+
+?>

+ 93 - 0
include/php/global.inc.php

@@ -0,0 +1,93 @@
+<?php 
+
+/*
+ * Message manager
+ * Types of notifications:
+ * success
+ * fail
+ * info
+ */
+
+$MESSAGES = array();
+
+function add_message($type, $message){
+	global $MESSAGES;
+	$newmessage = array();
+	$newmessage['type'] = $type;
+	$newmessage['message'] = $message;
+
+	$MESSAGES[] = $newmessage;
+}
+
+function output_messages(){
+	echo "<div class=\"messages\">";
+	global $MESSAGES;
+	foreach($MESSAGES as $message){
+		echo "<div class=\"notification notification-".$message['type']."\">".$message['message']."</div>";
+	}
+	echo "</div>";
+}
+
+
+
+
+/*
+ * Function checks password input for new password
+ * Return codes:
+ * true: password is okay
+ * 2: One password field is empty
+ * 3: Passwords are not equal
+ * 4: Passwort is too snort
+ */
+
+function check_new_pass($pass1, $pass2){
+	global $PASS_ERR;
+	global $PASS_ERR_MSG;
+	// Check if one passwort input is empty
+	if($pass1 !== "" && $pass2 !== ""){
+		// Check if password are equal
+		if($pass1 === $pass2){
+			// Check if password length is okay
+			if(strlen($pass1) >= MIN_PASS_LENGTH){
+				// Password is okay.
+				return true;
+			}
+			else{
+				// Password is not long enough
+				$PASS_ERR = 4;
+				$PASS_ERR_MSG = "Password is not long enough. Please enter a password which has ".MIN_PASS_LENGTH." characters or more.";
+				return $PASS_ERR;
+			}
+		}
+		else{
+			// Passwords are not equal
+			$PASS_ERR = 3;
+			$PASS_ERR_MSG = "Passwords are not equal.";
+			return $PASS_ERR;
+		}
+	}
+	else{
+		// One password is empty.
+		$PASS_ERR = 2;
+		$PASS_ERR_MSG = "Not all password fields were filled out";
+		return $PASS_ERR;
+	}
+}
+
+
+function gen_pass_hash($pass){
+	$salt = base64_encode(rand(1,1000000) + microtime());
+	$pass_hash = crypt($pass, '$6$rounds=5000$'.$salt.'$');
+	return $pass_hash;
+}
+
+
+function write_pass_hash_to_db($pass_hash, $uid){
+	global $db;
+	$uid = $db->escape_string($uid);
+	$pass_hash = $db->escape_string($pass_hash);
+	$db->query("UPDATE `".DBT_USERS."` SET `".DBC_USERS_PASSWORD."` = '$pass_hash' WHERE `".DBC_USERS_ID."` = '$uid';");
+}
+
+
+?>

+ 9 - 0
include/php/pages/404.php

@@ -0,0 +1,9 @@
+<?php
+
+?>
+
+<h1>This page does not exist.</h1>
+
+<p>
+	Sorry, the page you requested could not be found.
+</p>

+ 34 - 0
include/php/pages/admin/createdomain.php

@@ -0,0 +1,34 @@
+<?php 
+
+if(isset($_POST['domain'])){
+	$domain = $db->escape_string($_POST['domain']);
+	
+	if($domain !== ""){
+		$sql = "INSERT INTO `".DBT_DOMAINS."` (`".DBC_DOMAINS_DOMAIN."`) VALUES ('$domain');";
+			
+		if(!$result = $db->query($sql)){
+			die('There was an error running the query [' . $db->error . ']');
+		}
+		else{
+			header("Location: ".FRONTEND_BASE_PATH."admin/listdomains/?created=1");
+		}
+	}
+	else{
+		add_message("fail", "Empty domain could not be created.");
+	}
+}
+
+?>
+
+<h1>Create new domain</h1>
+
+<?php output_messages(); ?>
+
+<p>
+	<a class="button button-small" href="<?php echo FRONTEND_BASE_PATH; ?>admin/listdomains/">&#10092; Back to domain list</a>
+</p>
+
+<form action="" method="post">
+	<p><input name="domain" class="textinput" type="text" placeholder="domain.tld"/></p>
+	<p><input type="submit" class="button button-small" value="Create domain"/>
+</form>

+ 72 - 0
include/php/pages/admin/deletedomain.php

@@ -0,0 +1,72 @@
+<?php 
+
+$id = $db->escape_string($_GET['id']);
+
+if(isset($_POST['confirm'])){
+	$confirm = $_POST['confirm'];
+	
+	if($confirm === "yes"){
+		$sql = "SELECT `".DBC_DOMAINS_DOMAIN."` FROM `".DBT_DOMAINS."` WHERE `".DBC_DOMAINS_ID."` = '$id' LIMIT 1;";
+			
+		if(!$result = $db->query($sql)){
+			die('There was an error running the query [' . $db->error . ']');
+		}
+		
+		else{	
+			while($row = $result->fetch_assoc()){
+				$domain = $row[DBC_DOMAINS_DOMAIN];
+			}
+			
+			$sql = "DELETE FROM `".DBT_DOMAINS."` WHERE `".DBC_DOMAINS_ID."` = '$id'";
+				
+			if(!$result = $db->query($sql)){
+				die('There was an error running the query [' . $db->error . ']');
+			}
+			
+			else{
+				$sql = "DELETE FROM `".DBT_USERS."` WHERE `".DBC_USERS_DOMAIN."` = '$domain'";
+					
+				if(!$result = $db->query($sql)){
+					die('There was an error running the query [' . $db->error . ']');
+				}
+				else{
+					header("Location: ".FRONTEND_BASE_PATH."admin/listdomains/?deleted=1");
+				}
+			}
+		}
+	}
+	
+	else{
+		header("Location: ".FRONTEND_BASE_PATH."admin/listdomains/");
+	}
+}
+
+else{
+	//Load user data from DB
+	$sql = "SELECT `".DBC_DOMAINS_DOMAIN."` FROM `".DBT_DOMAINS."` WHERE `".DBC_DOMAINS_ID."` = '$id' LIMIT 1;";
+	
+	if(!$result = $db->query($sql)){
+		die('There was an error running the query [' . $db->error . ']');
+	}
+	
+	while($row = $result->fetch_assoc()){
+		$domain = $row[DBC_DOMAINS_DOMAIN];
+	}
+}
+?>
+
+<h1>Delete domain "<?php echo $domain ?>"?</h1>
+
+<p>
+	<strong>All mailboxes matching the domain will be deleted from the user database!</strong><br>
+	Mailbox directories in the filesystem won't be affected.
+</p>
+
+<form action="" method="post">
+	<select name="confirm">
+		<option value="no">No!</option>
+		<option value="yes">Yes!</option>
+	</select>
+	
+	<input type="submit" class="button button-small" value="Okay"/>
+</form>

+ 58 - 0
include/php/pages/admin/deleteredirect.php

@@ -0,0 +1,58 @@
+<?php 
+
+$id = $db->escape_string($_GET['id']);
+
+if(isset($_POST['confirm'])){
+	$confirm = $_POST['confirm'];
+	
+	if($confirm === "yes"){
+		$sql = "DELETE FROM `".DBT_ALIASES."` WHERE `".DBC_ALIASES_ID."` = '$id'";
+			
+		if(!$result = $db->query($sql)){
+			die('There was an error running the query [' . $db->error . ']');
+		}
+		else{
+			header("Location: ".FRONTEND_BASE_PATH."admin/listredirects/?deleted=1");
+		}
+	}
+	
+	else{
+		header("Location: ".FRONTEND_BASE_PATH."admin/listredirects/");
+	}
+}
+
+else{
+	//Load user data from DB
+	$sql = "SELECT `".DBC_ALIASES_SOURCE."`, `".DBC_ALIASES_DESTINATION."` FROM `".DBT_ALIASES."` WHERE `".DBC_ALIASES_ID."` = '$id' LIMIT 1;";
+	
+	if(!$result = $db->query($sql)){
+		die('There was an error running the query [' . $db->error . ']');
+	}
+	
+	while($row = $result->fetch_assoc()){
+		$source = $row[DBC_ALIASES_SOURCE];
+		$destination = $row[DBC_ALIASES_DESTINATION];
+	}
+	
+}
+?>
+
+<h1>Delete redirection?</h1>
+
+<p>
+	<table>
+	<tr> <th>From</th> <th>To</th> </tr>
+	<tr> <td><?php echo $source; ?></td> <td><?php echo $destination; ?></td> </tr>
+	</table>
+</p>
+
+<p>
+	<form action="" method="post">
+		<select name="confirm">
+			<option value="no">No!</option>
+			<option value="yes">Yes!</option>
+		</select>
+		
+		<input type="submit" class="button button-small" value="Okay"/>
+	</form>
+</p>

+ 55 - 0
include/php/pages/admin/deleteuser.php

@@ -0,0 +1,55 @@
+<?php 
+
+$id = $db->escape_string($_GET['id']);
+
+if(isset($_POST['confirm'])){
+	$confirm = $_POST['confirm'];
+	
+	if($confirm === "yes"){
+		$sql = "DELETE FROM `".DBT_USERS."` WHERE `".DBC_USERS_ID."` = '$id'";
+			
+		if(!$result = $db->query($sql)){
+			die('There was an error running the query [' . $db->error . ']');
+		}
+		else{
+			header("Location: ".FRONTEND_BASE_PATH."admin/listusers/?deleted=1");
+		}
+	}
+	
+	else{
+		header("Location: ".FRONTEND_BASE_PATH."admin/listusers/");
+	}
+}
+
+else{
+	//Load user data from DB
+	$sql = "SELECT `".DBC_USERS_USERNAME."`, `".DBC_USERS_DOMAIN."` FROM `".DBT_USERS."` WHERE `".DBC_USERS_ID."` = '$id' LIMIT 1;";
+	
+	if(!$result = $db->query($sql)){
+		die('There was an error running the query [' . $db->error . ']');
+	}
+	
+	while($row = $result->fetch_assoc()){
+		$username = $row[DBC_USERS_USERNAME];
+		$domain = $row[DBC_USERS_DOMAIN];
+	}
+	
+	$mailaddress = $username."@".$domain;
+}
+?>
+
+<h1>Delete user "<?php echo $mailaddress ?>"?</h1>
+
+<p>
+	<strong>The user's mailbox will be deleted from the database!</strong><br>
+	The mailbox in the filesystem won't be affected.
+</p>
+
+<form action="" method="post">
+	<select name="confirm">
+		<option value="no">No!</option>
+		<option value="yes">Yes!</option>
+	</select>
+	
+	<input type="submit" class="button button-small" value="Okay"/>
+</form>

+ 107 - 0
include/php/pages/admin/editredirect.php

@@ -0,0 +1,107 @@
+<?php 
+	if(isset($_POST['savemode'])){
+		$savemode = $_POST['savemode'];
+		
+		if($savemode === "edit"){
+			$id = $db->escape_string($_POST['id']);
+			
+			$source = $db->escape_string($_POST['source']);
+			$destination = $db->escape_string($_POST['destination']);
+			
+			if($source !== "" && $destination !== ""){
+			
+				$sql = "UPDATE `".DBT_ALIASES."` SET `".DBC_ALIASES_SOURCE."` = '$source', `".DBC_ALIASES_DESTINATION."` = '$destination' WHERE `".DBC_ALIASES_ID."` = '$id'";
+				
+				if(!$result = $db->query($sql)){
+					die('There was an error running the query [' . $db->error . ']');
+				}
+				else{
+					// Edit successfull, redirect to overview
+					header("Location: ".FRONTEND_BASE_PATH."admin/listredirects/?edited=1");
+				}
+			}
+			else{
+				add_message("fail", "Redirect could not be edited. Fill out all fields.");
+			}
+		}
+		
+		else if($savemode === "create"){
+			$source = $db->escape_string($_POST['source']);
+			$destination = $db->escape_string($_POST['destination']);
+			
+			if($source !== "" && $destination !== ""){
+				$sql = "INSERT INTO `".DBT_ALIASES."` (`".DBC_ALIASES_SOURCE."`, `".DBC_ALIASES_DESTINATION."`) VALUES ('$source', '$destination')";
+					
+				if(!$result = $db->query($sql)){
+					die('There was an error running the query [' . $db->error . ']');
+				}
+				
+				else{
+					// Redirect to user edit page when user is created
+					header("Location: ".FRONTEND_BASE_PATH."admin/listredirects/?created=1");
+				}
+			}
+			else{
+				add_message("fail", "Redirect could not be created. Fill out all fields.");
+			}
+		}
+	}
+	
+	
+	// Select mode 
+	$mode = "create";	
+	if(isset($_GET['id'])){
+		$mode = "edit";
+		$id = $db->escape_string($_GET['id']);
+	}
+	
+	if($mode === edit){
+		//Load user data from DB
+		$sql = "SELECT `".DBC_ALIASES_SOURCE."`, `".DBC_ALIASES_DESTINATION."` from `".DBT_ALIASES."` WHERE `".DBC_ALIASES_ID."` = $id LIMIT 1;";
+		
+		if(!$result = $db->query($sql)){
+			die('There was an error running the query [' . $db->error . ']');
+		}
+		
+		while($row = $result->fetch_assoc()){
+			$source = $row[DBC_ALIASES_SOURCE];
+			$destination = $row[DBC_ALIASES_DESTINATION];
+		}
+	}
+?>
+
+<h1><?php if($mode === "create") { ?> Create <?php } else {?>Edit <?php } ?>Redirect</h1>
+
+<?php output_messages(); ?>
+
+<p>
+Here you can edit a redirect.
+</p>
+
+<p>
+	<a class="button button-small" href="<?php echo FRONTEND_BASE_PATH; ?>admin/listredirects/">&#10092; Back to redirects list</a>
+</p>
+
+<form action="" method="post">	
+	<table>
+	<tr> <th>Source</th> <th>Destination</th> </tr>
+	
+	<tr>
+		<td>
+			<textarea name="source" class="textinput" placeholder="Source"><?php echo $source; ?></textarea>
+		</td>
+		
+		<td>
+			<textarea name="destination" class="textinput" placeholder="Destination"><?php echo $destination; ?></textarea>
+		</td>
+	</tr>
+	
+	</table>
+	
+	<input name="savemode" type="hidden" value="<?php echo $mode; ?>"/>
+	<input name="id" type="hidden" value="<?php echo $id; ?>"/>
+	
+	<p>
+		<input type="submit" class="button button-small" value="Save settings">
+	</p>
+</form>

+ 168 - 0
include/php/pages/admin/edituser.php

@@ -0,0 +1,168 @@
+<?php 
+	if(isset($_POST['savemode'])){
+		$savemode = $_POST['savemode'];
+		
+		if($savemode === "edit"){
+			// Edit mode entered
+			$id = $db->escape_string($_POST['id']);		
+			$mailbox_limit = $db->escape_string($_POST['mailbox_limit']);
+			
+			$sql = "UPDATE `".DBT_USERS."` SET `".DBC_USERS_MAILBOXLIMIT."` = '$mailbox_limit' WHERE `".DBC_USERS_ID."` = '$id';";
+			if(!$result = $db->query($sql)){
+				die('There was an error running the query [' . $db->error . ']');
+			}
+			else{
+				// SQL was successful
+				// Is there a changed password?
+				if($_POST['password'] !== ""){
+					$pass_ok = check_new_pass($_POST['password'], $_POST['password_rep']);
+					if($pass_ok === true){
+						// Password is okay and can be set
+						$pass_hash = gen_pass_hash($_POST['password']);
+						write_pass_hash_to_db($pass_hash, $id);
+						// $editsuccessful = true;
+						add_message("success", "User edited successfully.");
+						
+					}
+					else{
+						// Password is not okay
+						// $editsuccessful = 2;
+						add_message("fail", $PASS_ERR_MSG);
+					}
+				}
+				else{
+					// Redirect user to user list
+					header("Location: ".FRONTEND_BASE_PATH."admin/listusers/?edited=1");
+				}
+			}				
+		}
+		
+		else if($savemode === "create"){
+			// Create mode entered
+			$username = $db->escape_string($_POST['username']);
+			$domain = $db->escape_string($_POST['domain']);
+			$mailbox_limit = $db->escape_string($_POST['mailbox_limit']);			
+			$pass = $_POST['password'];
+			$pass_rep = $_POST['password_rep'];
+			
+			if($username !== "" && $domain !== "" && $quota !== ""){
+				// All fields filled with content
+				// Check passwords
+				$pass_ok = check_new_pass($pass, $pass_rep);
+				if($pass_ok === true){
+					// Password is okay ... continue
+					$pass_hash = gen_pass_hash($pass);
+					
+					$sql = "INSERT INTO `".DBT_USERS."` (`".DBC_USERS_USERNAME."`, `".DBC_USERS_DOMAIN."`, `".DBC_USERS_PASSWORD."`, `".DBC_USERS_MAILBOXLIMIT."`) VALUES ('$username', '$domain', '$pass_hash', '$mailbox_limit')";
+					
+					if(!$result = $db->query($sql)){
+						die('There was an error running the query [' . $db->error . ']');
+					}
+					
+					// Redirect user to user list
+					header("Location: ".FRONTEND_BASE_PATH."admin/listusers/?created=1");
+				}
+				else{
+					// Password not okay
+					add_message("fail", $PASS_ERR_MSG);
+				}
+			}
+		 	else{
+		 		// Fields missing
+		 		add_message("fail", "Not all fields were filled out.");
+		 	}		
+		}
+	}
+	
+	
+	// Select mode 
+	$mode = "create";	
+	if(isset($_GET['id'])){
+		$mode = "edit";
+		$id = $db->escape_string($_GET['id']);
+	}
+	
+	if($mode === edit){
+		//Load user data from DB
+		$sql = "SELECT * from `".DBT_USERS."` WHERE `".DBC_USERS_ID."` = '$id' LIMIT 1;";
+		
+		if(!$result = $db->query($sql)){
+			die('There was an error running the query [' . $db->error . ']');
+		}
+		
+		while($row = $result->fetch_assoc()){
+			$username = $row[DBC_USERS_USERNAME];
+			$domain = $row[DBC_USERS_DOMAIN];
+			$mailbox_limit = $row[DBC_USERS_MAILBOXLIMIT];
+		}
+	}
+?>
+
+
+
+<h1><?php if($mode === "create") { ?> Create <?php } else {?>Edit <?php } ?>User</h1>
+
+
+<?php output_messages(); ?>
+
+
+<p>
+	<a class="button button-small" href="<?php echo FRONTEND_BASE_PATH; ?>admin/listusers/">&#10092; Back to user list</a>
+</p>
+
+<p>
+<?php 
+	if($mode === "edit"){
+		echo "Username and domain cannot be edited.";
+	}
+?>
+</p>
+
+<form action="" method="post">	
+	<table>
+	<tr> <th>Username</th> <th>Domain</th> <th>Password</th> <th>Mailbox limit (in MB)</th> </tr>
+	
+	<tr>
+		<td>
+			<input name="username" class="textinput" type="text" value="<?php echo $username; ?>" placeholder="Username"/>
+		</td>
+		
+		<td>
+			@ 
+			<select name="domain">
+				<?php  
+				//Load user data from DB
+				$sql = "SELECT `".DBC_DOMAINS_DOMAIN."` FROM `".DBT_DOMAINS."`;";
+				
+				if(!$result = $db->query($sql)){
+					die('There was an error running the query [' . $db->error . ']');
+				}
+				
+				while($row = $result->fetch_assoc()){
+					$selected = "";
+					if($row[DBC_DOMAINS_DOMAIN] === $domain){$selected = "selected=\"selected\"";}
+					echo "<option value=\"".$row[DBC_DOMAINS_DOMAIN]."\" ".$selected." >".$row[DBC_DOMAINS_DOMAIN]."</option>";
+				}
+				?>
+			</select>
+		</td>
+		
+		<td>
+			<input name="password" class="textinput" type="password" placeholder="New password"/></br>
+			<input name="password_rep"  class="textinput" type="password" placeholder="New password (repeat)"/>
+		</td>
+		
+		<td>
+			<input name="mailbox_limit" class="textinput" type="number" value="<?php echo $mailbox_limit; ?>" placeholder="Mailbox size (MB)"/> 
+		</td>
+	</tr>
+	
+	</table>
+	
+	<input name="savemode" type="hidden" value="<?php echo $mode; ?>"/>
+	<input name="id" class="sendbutton" type="hidden" value="<?php echo $id; ?>"/>
+	
+	<p>
+		<input type="submit" class="button button-small" value="Save settings">
+	</p>
+</form>

+ 41 - 0
include/php/pages/admin/listdomains.php

@@ -0,0 +1,41 @@
+<?php 
+	if($_GET['deleted'] == "1"){
+		add_message("success", "Domain deleted successfully.");
+	}
+	else if($_GET['created'] == "1"){
+		add_message("success", "Domain created successfully.");
+	}		
+?>
+
+
+<h1>Domains</h1>
+
+<?php output_messages(); ?>
+
+<p>
+Manage the domains which you want to use
+</p>
+
+
+
+<?php 
+	$sql = "SELECT * FROM `".DBT_DOMAINS."` ORDER BY `".DBC_DOMAINS_DOMAIN."` ASC;";
+	
+	if(!$result = $db->query($sql)){
+		die('There was an error running the query [' . $db->error . ']');
+	}
+?>
+
+<p>
+	<a class="button button-small" href="<?php echo FRONTEND_BASE_PATH; ?>admin/createdomain/">Create new domain</a>
+</p>
+
+<table class="list">
+<tr class="head"><th>Domain</th> <th></th><tr>
+
+<?php 
+	while($row = $result->fetch_assoc()){
+		echo "<tr><td>".$row[DBC_DOMAINS_DOMAIN]."</td> <td><a href=\"".FRONTEND_BASE_PATH."admin/deletedomain/?id=".$row[DBC_DOMAINS_ID]."\">[Delete]</a></td> </tr>";
+	}
+?>
+</table>

+ 38 - 0
include/php/pages/admin/listredirects.php

@@ -0,0 +1,38 @@
+<?php
+
+if($_GET['deleted'] == "1"){
+	add_message("success", "Redirect deleted successfully.");
+}
+else if($_GET['created'] == "1"){
+	add_message("success", "Redirect created successfully.");
+}
+else if($_GET['edited'] == "1"){
+	add_message("success", "Redirect edited successfully.");
+}
+
+
+$sql = "SELECT * FROM `".DBT_ALIASES."` ORDER BY `".DBC_ALIASES_SOURCE."` ASC;";
+
+if(!$result = $db->query($sql)){
+	die('There was an error running the query [' . $db->error . ']');
+}
+
+?>
+
+<h1>Redirects</h1>
+
+<?php output_messages(); ?>
+
+<p>
+	<a class="button button-small" href="<?php echo FRONTEND_BASE_PATH; ?>admin/editredirect/">Create new redirect</a>
+</p>
+
+<table class="list">
+<tr class="head"><th>Source</th> <th>Destination</th> <th></th><th></th><tr>
+
+<?php 
+	while($row = $result->fetch_assoc()){
+		echo "<tr><td>".$row[DBC_ALIASES_SOURCE]."</td> <td>".$row[DBC_ALIASES_DESTINATION]."</td> <td><a href=\"".FRONTEND_BASE_PATH."admin/editredirect/?id=".$row[DBC_ALIASES_ID]."\">[Edit]</a></td> <td><a href=\"".FRONTEND_BASE_PATH."admin/deleteredirect/?id=".$row[DBC_ALIASES_ID]."\">[Delete]</a></td></tr>";
+	}
+?>
+</table>

+ 45 - 0
include/php/pages/admin/listusers.php

@@ -0,0 +1,45 @@
+<?php 
+
+if($_GET['deleted'] == "1"){
+	add_message("success", "User deleted successfully."); 
+}
+else if($_GET['created'] == "1"){
+	add_message("success", "User created successfully.");
+}
+else if($_GET['edited'] == "1"){
+	add_message("success", "User edited successfully.");
+}
+	
+?>
+
+
+
+<h1>List of all mailbox accounts</h1>
+
+
+<?php output_messages(); ?>
+
+
+<?php 
+
+$sql = "SELECT * FROM `".DBT_USERS."` ORDER BY `".DBC_USERS_DOMAIN."`, `".DBC_USERS_USERNAME."` ASC;";
+
+if(!$result = $db->query($sql)){
+	die('There was an error running the query [' . $db->error . ']');
+}
+
+?>
+
+<p>
+	<a class="button button-small" href="<?php echo FRONTEND_BASE_PATH; ?>admin/edituser/">Create new user</a>
+</p>
+
+<table class="list">
+<tr class="head"><th>Username</th> <th>Domain</th> <th>Mailbox Limit (MB)</th> <th></th> <th></th><tr>
+
+<?php 
+	while($row = $result->fetch_assoc()){
+		echo "<tr><td>".$row[DBC_USERS_USERNAME]."</td><td>".$row[DBC_USERS_DOMAIN]."</td><td>".$row[DBC_USERS_MAILBOXLIMIT]."<td><a href=\"".FRONTEND_BASE_PATH."admin/edituser/?id=".$row[DBC_USERS_ID]."\">[Edit]</a></td> <td><a href=\"".FRONTEND_BASE_PATH."admin/deleteuser/?id=".$row[DBC_USERS_ID]."\">[Delete]</a></td> </tr>";
+	}
+?>
+</table>

+ 13 - 0
include/php/pages/admin/start.php

@@ -0,0 +1,13 @@
+<?php
+
+?>
+
+<h1>Admin Dashboard</h1>
+
+<p style="margin-top:50px;">
+	<a class="button button-big" href="<?php echo FRONTEND_BASE_PATH; ?>admin/listusers/">Manage users</a>
+
+	<a class="button button-big" href="<?php echo FRONTEND_BASE_PATH; ?>admin/listdomains/">Manage domains</a>
+
+	<a class="button button-big" href="<?php echo FRONTEND_BASE_PATH; ?>admin/listredirects/">Manage redirects</a>
+</p>

+ 34 - 0
include/php/pages/login.php

@@ -0,0 +1,34 @@
+<?php 
+
+if(isset($_POST['email']) && isset($_POST['password'])){
+	// Start login
+	$login_success = $user->login($_POST['email'], $_POST['password']);
+	if($login_success){
+		header("Location: ".FRONTEND_BASE_PATH."private/");
+	}
+	else{
+		add_message("fail", "Sorry, I couldn't log you in :(");
+	}
+}
+
+// If user is already logged in, redirect to start.
+if($user->isLoggedIn()){
+	header("Location: ".FRONTEND_BASE_PATH."private/");
+}
+
+?>
+
+
+<h1>Login</h1>
+
+<?php output_messages(); ?>
+
+<form action="" method="post">
+	<input name="email" class="textinput" type="text" placeholder="E-Mail Address"/><br>
+	<input name="password" class="textinput" type="password" placeholder="Password"/>
+	
+	<p>
+		<input type="submit" class="button button-small" value="Log in"/>
+	</p>
+</form>
+

+ 6 - 0
include/php/pages/logout.php

@@ -0,0 +1,6 @@
+<?php
+require_once 'include/php/default.inc.php';
+
+session_destroy();
+header("Location: ".FRONTEND_BASE_PATH);
+?>

+ 9 - 0
include/php/pages/not-allowed.php

@@ -0,0 +1,9 @@
+<?php
+
+?>
+
+<h1>Not allowed!</h1>
+
+<p>
+	Sorry, you are not allowed to access this page.
+</p>

+ 42 - 0
include/php/pages/private/changepass.php

@@ -0,0 +1,42 @@
+<?php
+
+if(isset($_POST['sent'])){
+	// User tries to change password
+	$change_pass_success = $user->change_password($_POST['password'], $_POST['password_repeat']);
+	
+	if($change_pass_success === true){
+		add_message("success", "Password changed successfully!");
+	}
+	else if($change_pass_success === false){
+		add_message("fail", "Error while changing password! ".$PASS_ERR_MSG);
+	}
+}
+
+?>
+
+
+
+<h1>Change password</h1>
+
+<?php output_messages(); ?>
+
+<p>
+	<a class="button button-small" href="<?php echo FRONTEND_BASE_PATH; ?>private/">&#10092; Back to personal dashboard</a>
+</p>
+
+
+<p>
+	Your new password must have <?php echo MIN_PASS_LENGTH; ?> characters or more.
+</p>
+
+<form action="" method="post">
+	<p>
+		<input name="password" class="textinput" type="password" placeholder="New password"/><br/>
+		<input name="password_repeat" class="textinput" type="password" placeholder="New password (repeat)"/>
+		<input name="sent" type="hidden" value="1"/>
+	</p>
+	
+	<p>
+		<input type="submit" class="button button-small" value="Change password"/>
+	</p>
+</form>

+ 17 - 0
include/php/pages/private/start.php

@@ -0,0 +1,17 @@
+<?php
+
+?>
+
+<h1>Welcome to your personal account!</h1>
+
+<p>
+	What do you want to do?
+</p>
+
+<p>
+	<a class="button button-big" href="<?php echo FRONTEND_BASE_PATH; ?>private/changepass/">Change my e-mail password</a>
+</p>
+
+<p>
+<i>(Yeah, that's all you can do right now :P)</i>
+</p>

+ 17 - 0
include/php/pages/start.php

@@ -0,0 +1,17 @@
+<?php
+if($user->isLoggedIn() === true){
+	header("Location: ".FRONTEND_BASE_PATH."private/");
+}
+?>
+
+<h1>WebMUM</h1>
+
+<p>
+WebMUM is an easy to use webinterface for managing user accounts on your mailserver's MySQL user backend.<br/>
+Users of your server can log in here to change their passwords.
+</p>
+
+<p style="margin-top:30px;">
+	<a class="button button-small" href="<?php echo FRONTEND_BASE_PATH; ?>login/">Log in</a>
+</p>
+

+ 7 - 0
include/php/template/footer.php

@@ -0,0 +1,7 @@
+		</div> <!-- Closing content -->
+		
+		<div id="footer">
+			WebMUM is free software created by Thomas Leister.
+		</div>
+	</body>
+</html>

+ 17 - 0
include/php/template/header.php

@@ -0,0 +1,17 @@
+<!doctype html>
+<html>
+	<head>
+		<title>WebMUM</title>
+		<link rel=stylesheet href="<?php echo FRONTEND_BASE_PATH; ?>include/css/style.css" type="text/css" media=screen>
+	</head>
+	
+	<body>
+		<div id="header">
+			<div class="title"><a href="<?php echo FRONTEND_BASE_PATH; ?>">WebMUM - Web Mailsystem User Manager</a></div>
+			<div class="header-menu">
+				<?php if(user_has_permission("admin")){ ?><div class="header-button"> <a href="<?php echo FRONTEND_BASE_PATH ?>admin/">[Admin Dashboard]</a> </div> <div class="header-button"> <a href="<?php echo FRONTEND_BASE_PATH ?>private/">[Personal Dashboard]</a> </div><?php } ?>
+				<?php if($user->isLoggedIn()){?><div class="header-button">Logged in as <?php echo $_SESSION['email']; ?> <a href="<?php echo FRONTEND_BASE_PATH ?>logout/">[Logout]</a></div><?php }?>
+			</div>
+		</div>
+		
+		<div id="content"> <!-- Opening content -->

+ 118 - 0
index.php

@@ -0,0 +1,118 @@
+<?php
+define("BACKEND_BASE_PATH", preg_replace("index.php", "", $_SERVER['SCRIPT_FILENAME']));
+require_once 'include/php/default.inc.php';
+
+
+require_once 'include/php/template/header.php';
+
+
+function load_page($p){
+	
+	if(preg_match("/^\/private(.*)$/", $p) == 1){
+		// Page is user page
+		if(user_has_permission("user")){
+			switch($p){
+				case "/private/":
+					return "include/php/pages/private/start.php";
+					break;
+				case "/private/changepass/":
+					return "include/php/pages/private/changepass.php";
+					break;
+				default:
+					return "include/php/pages/404.php";
+			}
+		}
+		else{ return "include/php/pages/not-allowed.php"; }
+	}
+	
+	else if(preg_match("/^\/admin(.*)$/", $p) == 1){
+		// Page is admin page
+		if(user_has_permission("admin")){
+			switch($p){
+				case "/admin/":
+					return "include/php/pages/admin/start.php";
+					break;
+				case "/admin/listusers/":
+					return "include/php/pages/admin/listusers.php";
+					break;
+				case "/admin/edituser/":
+					return "include/php/pages/admin/edituser.php";
+					break;
+				case "/admin/deleteuser/":
+					return "include/php/pages/admin/deleteuser.php";
+					break;
+				case "/admin/listdomains/":
+					return "include/php/pages/admin/listdomains.php";
+					break;
+				case "/admin/deletedomain/":
+					return "include/php/pages/admin/deletedomain.php";
+					break;
+				case "/admin/createdomain/":
+					return "include/php/pages/admin/createdomain.php";
+					break;
+				case "/admin/listredirects/":
+					return "include/php/pages/admin/listredirects.php";
+					break;
+				case "/admin/editredirect/":
+					return "include/php/pages/admin/editredirect.php";
+					break;
+				case "/admin/deleteredirect/":
+					return "include/php/pages/admin/deleteredirect.php";
+					break;
+				default:
+					return "include/php/pages/404.php";
+			}
+		}
+		else{ return "include/php/pages/not-allowed.php"; }
+	}
+	
+	else{
+		// Page is public accessible
+		switch($p){
+			case "/login/":
+				return "include/php/pages/login.php";
+				break;
+			case "/logout/":
+				return "include/php/pages/logout.php";
+				break;
+			case "/":
+				return "include/php/pages/start.php";
+				break;
+			default:
+				return "include/php/pages/404.php";
+		}
+	}
+}
+
+
+/*
+ * Here is the content of the page
+ */
+
+$path = $_SERVER["REQUEST_URI"];
+// Remove GET Parameters
+$path = preg_replace('/\?.*/', '', $path);
+// Remove prescending directory part e.g. /webmum/ defined in SUBDIR
+$path = preg_replace("/\\".SUBDIR, '', $path);
+
+// Webserver should add trailing slash, but if there is no trailing slash for any reason, add one ;)
+if(strrpos($path,"/") != strlen($path)-1){
+	$path = $path."/";
+}
+
+
+/* Finally, inlude page content */
+
+include load_page($path);
+
+
+
+/*
+ * End of dynamic content
+ */
+
+require_once 'include/php/template/footer.php';
+include_once 'include/php/db_close.inc.php';
+?>
+
+