JENS MALMGREN I create.

Porting my blog for the second time, editing part 1

This is post #46 of my series about how I port this blog from Blogengine.NET 2.5 ASPX on a Windows Server 2003 to a Linux Ubuntu server, Apache2, MySQL and PHP. A so called LAMP. The introduction to this project can be found in this blog post https://www.malmgren.nl/post/Porting-my-blog-for-the-second-time-Project-can-start.aspx.

It is time to make it possible to edit blog posts. Somehow I want my blog to turn into editing mode just like magic. Often you see websites with a little "log in" button but I was thinking that such button could as well be renamed "start hacking here". So lets not do that. I have another very different idea, namely using the the search field for commands. Suppose one could add a command in the search field to activate various functions in the house? For example "Turn on the kettle" or "Turn on the lights in the living-room". Just kidding. For example when I want to start editing a blog post? Suppose the commands for that starts with a hash sign followed by "edit". For a new blog post it could be "#new".  There are endless possibilities for what commands I could support.

The first little challenge is to adapt the search to realize that "yeah, here is a command and not a search" but the real challenge is to properly verify that the user is authorized to start a command. For this I will display a form with a field for username and one for a password. When submitting the correct combination of username and password the authorization succeed and the command can be started. If the authorization fails then not much will happen.

At this point when the authorization succeed it is about time to display a page making it possible to for example edit a blog post. For that I will need an editor. I found several editors that I can use. I just grab anything to see how it works. For example this from ckeditor.com.

When done with editing I need a query setting up the record for the new blog post. Well... this is the plan.

So without any further ado, we start from an end, the beginning: Teach the search field to detect commands.

I find it a bit challenging to create a rock solid authentication and also talk about it in this blog. Perhaps I reveal a weakness in the process that others will know about but I don't. Oh well, there is a chance that I will be informed about my mistake by more well informed visitors of my blog and tell me so that I will learn how to improve my code rather than keeping it secret and learn nothing new.

So here we begin with the authentication system. My solution rests heavily on session variables. They are stored on the server and there is some ID juggling going on to ensure they are "kept alive" as long as a visitors window is kept open.

This chain of events all starts with that the user enters a command into the search field and press the '>>' button. The handling of this routine starts in this modified search routine.

# http://www.jens.malmgren.nl/post/Porting-my-blog-for-the-second-time-right-sidebar-part-2.aspx
# http://www.jens.malmgren.nl/post/Porting-my-blog-for-the-second-time-editing.aspx
if (isset($_POST['action_clear_search']) && $_POST['action_clear_search'] == 'action_clear_search')
{
	$_SESSION['search'] = "";
}
if (isset($_POST['search']) && $_POST['search'] != "")
{
	if ($_POST['search'] == "#edit")
	{
		if (!startsWith( $_SERVER['HTTP_REFERER'], "http://" . $domain))
		{
			header("Location: http://$domain");
			die;
		}
		
		if (array_key_exists("post", $arrayArgs))
		{
			$_SESSION['post'] = $arrayArgs["post"];
		}

		if (isset($_SESSION['JensBlogLoggedInUser']))
		{
			header("Location: http://$domain/edit.php");
			die();
		}
		else
		{
			header("Location: http://$domain/login.php");
			die();
		}
	}
	else
	{
		$_SESSION['search'] = $_POST['search'];
	}
}

 

At line 9 the search field is checked for the command. In this case it is "#edit". If we have the edit command the first thing to verify is that the referrer came from the same domain. It is just a little precaution.

The next step is to check if we resolved the page attribute then we store this in a session variable so that we later can now what to edit.

In the next step it perhaps feels a little backward to check for if we already have a checked in user and if so go straight to the edit page. The idea here is that if we are already logged in we don't need to validate the user again.

For a moment I thought that the session variable was accessible through the client so that if someone crafted a page that could inject a 'JensBlogLoggedInUser' then they would get straight to the edit page but it does not work like that. The variable is stored on my server. I feel so lucky, lucky lucky. On the other hand something in the client is keeping track of the session so somehow it should be possible to get to it. I forget about that for now.

Lets continue with the log on process. If we were not logged in then we go to the login page.

≺?php
# http://www.jens.malmgren.nl/post/Porting-my-blog-for-the-second-time-editing.aspx
session_start();
global $domain;
include "domain.php";

function startsWith($ip_strTextToTest, $ip_strTextToStartWith)
{
	return substr($ip_strTextToTest, 0, strlen($ip_strTextToStartWith)) == $ip_strTextToStartWith;
}

if (!startsWith( $_SERVER['HTTP_REFERER'], "http://" . $domain))
{
	header("Location: http://$domain");
	die;
}
?≻
≺html≻
	≺head≻
		≺script type="text/javascript" src="jquery-1.11.3.min.js"≻≺/script≻
	≺/head≻
	≺body≻
		≺form id="Form1" method="post" action = "validate.php"≻
			≺p≻≺?php
				if (array_key_exists("message", $_SESSION))
				{
					echo $_SESSION['message'];
				}
				?≻≺/p≻
			≺p≻Username: ≺input type="text" name="username" id = "username"/≻≺/p≻
			≺p≻Password: ≺input type="password" name="password" id = "password"/≻≺/p≻
			≺input type="submit" name="formSubmit" value="Login" id = "submit"≻
		≺/form≻
	≺/body≻
	≺script≻
	
	$(document).ready ( function()
	{
		$('#submit').prop('disabled', true);
		
		$('#username,#password').keyup(function(){
			var bDisable = $('#username').val() == "" || $('#password').val() == "";
			$('#submit').prop('disabled', bDisable);
		} )
	})

	≺/script≻
≺/html≻

This is a small little php page. Also on this page I start with checking that the referrer came from the same domain.

Then I render a login page with a username and password field. The action for the form is the validation page. When we hit submit then the validation page will be loaded.

I am not going to bore you with the source code for the validation page. It too checks for that the referrer came from the same domain.

Then I look up the username in the database to get the hash key of the password. A hash key is the result of some kind of function that given a string, in this case the password, the function returns a specific value. The benefit of doing like this is that then I don't store the passwords as readable text in the database so that if someone manage to hack the database the hash keys cannot be used to enter the system.

Then I use the same hash key calculation algorithm on the given password and when the hash from the database match the hash of the given password then I know that they are matching and that the user can be logged in.

I also salt the pass key with something from the username or other meta data that belongs to the user. That way it makes it even more difficult to hack the system because then the hacker needs to have the complete algorithm making up the pass string being used to create the hash and then he needs to reverse engineer the hash calculations which really only can be done by hackers having nothing more important in life to do. Losers. Come on, this is is little personal blog. Don't waste your time on me.

When I found that someone could be logged on then I set up the session variable I talked about earlier 'JensBlogLoggedInUser' and then I redirect to the edit page.

If figure that later on when I want to use the same login for several functions I will need to know what to do upon successful login but that is for later.

If login failed I set a vague message and return to the login page.

In the edit page it is about time to start editing!!!

But... That is for next time.


I moved from Sweden to The Netherlands in 1995.

Here on this site, you find my creations because that is what I do. I create.