<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ronny.haryan.to &#187; Articles</title>
	<atom:link href="http://ronny.haryan.to/archives/category/articles/feed/" rel="self" type="application/rss+xml" />
	<link>http://ronny.haryan.to</link>
	<description>Print: $9.50 -- Online: free</description>
	<lastBuildDate>Thu, 04 Feb 2010 13:05:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Revision Control for Web Application Content</title>
		<link>http://ronny.haryan.to/archives/2006/06/26/revision-control-for-web-application-content/</link>
		<comments>http://ronny.haryan.to/archives/2006/06/26/revision-control-for-web-application-content/#comments</comments>
		<pubDate>Mon, 26 Jun 2006 12:52:53 +0000</pubDate>
		<dc:creator>ronny</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://ronny.haryan.to/archives/2006/06/26/revision-control-for-web-application-content/</guid>
		<description><![CDATA[Revision control is a wonderful concept. Using revision control has helped me personally in managing content and source code. Traditionally revision control is used to track changes in source code files, but people has since extended revision control to manage other things such as system configuration files, web pages, term papers, and so on. In [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Revision_control">Revision control</a> is a
wonderful concept. Using revision control has helped me personally in
managing content and source code. Traditionally revision control is used to
track changes in source code files, but people has since extended revision
control to manage other things such as system configuration files, web
pages, term papers, and so on. In this article, I will focus on applying the
revision control concept in managing content in web applications, for
example, like how <a href="http://en.wikipedia.org/">Wikipedia</a> keeps track of
changes in the articles
(<a href="http://en.wikipedia.org/w/index.php?title=Revision_control&amp;action=history">example</a>).</p>

<h3>Why?</h3>

<p>Having a revision control is really useful when we want to keep a history of
contents in our web applications. This history data can be used to revert
changes to a certain revision, find out by whom and when certain changes are
made, and visualise the differences between revisions. Accidental
overwriting of content is no longer a problem with revision control in
place. Aside from history, revision control can also help in a multi-user
environment where many people may potentially work on the same content. In
my opinion, these are the main benefits of having revision control.</p>

<p><span id="more-99"></span></p>

<h3>Cons</h3>

<p>The only main drawback of having revision control is that extra storage
space is needed to keep the revision data. The actual requirements vary,
depending on the implementation. If done inefficiently (e.g. storing the
whole revision content instead of just the differences), then the space
requirement could be significant. However, storage is cheap nowadays, and in
many cases the benefits far outweigh the drawbacks.</p>

<h3>Traditional vs. web app.</h3>

<p>Traditional revision control systems such as
<a href="http://subversion.tigris.org/">Subversion</a> or
<a href="http://www.nongnu.org/cvs/">CVS</a> operate on files. Web application contents
are normally stored in a database instead of files. This is one major
difference that should be kept in mind.</p>

<h3>Requirements</h3>

<p>I&#8217;m going to give an example of two simple implementation approaches of revision control
for web application content. But first I&#8217;m going to list the requirements
for this simple implementation. Let say I already have a simple web
application that is used by my family to manage our notes (think of a
<strong>very</strong> simple family wiki). This is what I want to get from adding a
revision control to the system:</p>

<ul>
<li><strong>content history</strong>, ability to store, retrieve and rollback to certain
revision, as well as to show differences between revisions</li>
<li><strong>audit</strong>, I want to know who did what and when </li>
<li><strong>all database</strong>, everything is stored in the database itself, no external
files</li>
<li><strong>no cheating</strong>, I can&#8217;t use subversion or cvs behind the scene</li>
<li><strong>simple</strong>, minimal and straightforward modifications in the database
structure and code</li>
<li><strong>generic</strong>, the design should be database- and language-agnostic</li>
<li><strong>storage</strong>, in this case I&#8217;m willing to pay the price of space for having
a history of my notes, so storage space size is not a concern</li>
</ul>

<h3>Existing system</h3>

<p>Let say this is the (simplified) existing database structure:</p>

<pre><code>users:
    + id
    - name

notes:
    + id
    - status
    - title
    - content
    - created_by
    - created_at
    - last_modified_by
    - last_modified_at
</code></pre>

<h3>First approach: the simple method</h3>

<p>I think one of the simplest tricks that can be used to implement revision
control is to add a <code>revision_id</code> column, and make it part of the primary
key. And that is exactly what I&#8217;m going to do first. Here&#8217;s the modified
database structure:</p>

<pre><code>users:
    + id
    - name

notes:
    + id
    + rev_id
    - status
    - title
    - content
    - rev_user_id
    - rev_time
</code></pre>

<p>The <code>users</code> table is unchanged because I don&#8217;t need to put anything there
under revision control. The primary key of the <code>notes</code> table now becomes a
composite key <code>(id, rev_id)</code>. The audit information now becomes the revision
metadata, <code>rev_user_id</code> and <code>rev_time</code>, because now we can track who did
what and when for <em>each</em> revision, not just the first and the last ones.</p>

<p>This method is the simplest that I can think of. There is a limitation,
however, that every column in that table becomes under revision control.
That&#8217;s probably fine for most needs, but there could be situations where
only some of the columns should be under revision control, for example when
storage space is a concern.</p>

<p>Now comes the more interesting part. How can we actually achieve common
revision control tasks? I&#8217;m going to provide some example MySQL statements to
illustrate how to do certain things:</p>

<ul>
<li><p>To list all published notes:</p>

<pre>SELECT DISTINCT id
FROM notes
WHERE status='published'</pre></li>
<li><p>To retrieve the latest revision of note 5:</p>

<pre>SELECT *
FROM notes
WHERE id=5
  AND rev_id=(SELECT MAX&#x28;rev_id)
      FROM notes
      WHERE id=5)</pre></li>
<li><p>To create a new revision of note 5 by user 3:</p>

<pre>BEGIN;
    SELECT @newid := MAX&#x28;rev_id) + 1 FROM notes WHERE id=5;
    INSERT INTO notes
    (id, rev_id, status, title, content, rev_user_id, rev_time)
        VALUES (5, @newid, 'published', '...', '...', 3, NOW());
COMMIT;</pre></li>
<li><p>To edit a revision: simply create a new revision. Editing or deleting a
revision is beating the purpose of having revision control in the first
place. By never editing or deleting any revision we can rollback to a
particular revision if we need to.</p></li>
<li>To delete a revision: simply create a new revision with status set to
&#8216;deleted&#8217; and exclude the deleted notes from your view. Again, we never
edit or delete any revisions, this way we can &#8220;resurrect&#8221; deleted notes by
simply rollback to a previous revision.</li>
<li><p>To list all revision metadata of note 5:</p>

<pre>SELECT rev_id, rev_user_id, rev_time
FROM notes
WHERE id=5</pre></li>
<li>To rollback note 5 to revision 2: create a new revision for note 5 by
copying the content of revision 2 (excluding the revision metadata
<code>rev_user_id</code> and <code>rev_time</code>) into the new revision.</li>
<li>To show differences between revision 2 and 3 for note 5: retrieve both
revisions and pass them into a <code>diff</code> program or its equivalent</li>
</ul>

<h3>Second approach: an alternative method</h3>

<p>There is an alternative approach using a separate table to store revisions.
This method practically addresses the aforementioned limitation of the
simple method. Using the same example, the modified database structure now
becomes:</p>

<pre><code>users:
    + id
    - name

notes:
    + id
    - title

notes_revisions:
    + id
    + notes_id
    - status
    - content
    - rev_user_id
    - rev_time
</code></pre>

<p>In the above structure the <code>title</code> column is not under revision control.
Although <code>title</code> may not be the best example to illustrate the storage space
restriction requirement, I used it as an example to show that we can put
certain columns outside revision control. The <code>id</code> column of
<code>notes_revisions</code> is the revision id. If you&#8217;re using MySQL, then you can&#8217;t
make <code>notes_revisions(id)</code> column as <code>auto_increment</code> in this case.
The <code>notes_id</code> column is a foreign key referencing <code>notes(id)</code> and is part
of the composite primary key.</p>

<p>And here&#8217;s how you do common revision control tasks using this alternative
method:</p>

<ul>
<li><p>To list all published notes:</p>

<pre>SELECT n.*
FROM notes n
LEFT OUTER JOIN notes_revisions nr
    ON nr.notes_id = n.id
WHERE nr.status='published'
  AND nr.id=( SELECT MAX&#x28;id)
        FROM notes_revisions
        WHERE notes_id=nr.notes_id)</pre></li>
<li><p>To retrieve the latest revision of note 5:</p>

<pre>SELECT n.*, nr.*
FROM notes n
LEFT OUTER JOIN notes_revisions nr ON nr.notes_id = n.id
WHERE n.id=5
  AND nr.id=(SELECT MAX&#x28;id)
      FROM notes_revisions
      WHERE notes_id=5)</pre></li>
<li><p>To create a new revision of note 5 by user 3:</p>

<pre>BEGIN;
SELECT @newrid := MAX&#x28;id) + 1 FROM notes_revisions WHERE notes_id=5;
INSERT INTO notes_revisions
    (id, notes_id, status, content, rev_user_id, rev_time)
        VALUES (@newrid, 5, 'published', '...', 3, NOW());
COMMIT;</pre></li>
<li><p>To list all revision metadata of note 5:</p>

<pre>SELECT id, rev_user_id, rev_time
FROM notes_revisions
WHERE notes_id=5</pre></li>
</ul>

<p>Other tasks are done in a similar manner to the simple method.</p>

<h3>Addressing simultaneous edits</h3>

<p>Many times it is useful to allow simultaneous editing of the same content without locking. The basic idea is to allow users to edit anyway and let the system merge the differences between simultaneous editing sessions when creating new revisions. To do this properly, we need the help of a <code>diff</code> program and a <code>patch</code> program (or their equivalents) to merge differences. I think this could make my application too complicated for my purposes. So I&#8217;ll settle for a less complicated workaround: during save, if a simultaneous edit is detected, then the application will deny the save request. Although I have to admit that this workaround is not better than locking. Maybe I will write another article in the future that discusses this specifically in more details.</p>

<p>How to detect simultaneous edits? When presenting a note for editing, the revision number must be attached to the form (e.g. as a hidden input field). After submitting the edited note and before creating a new revision, the system must first check that the revision number in the database is not higher than the current revision. If it is higher, then that means somebody else has edited the same note.</p>

<h3>Conclusions</h3>

<p>There are more to revision control than what is written in this article, and
it could be a very complicated discussion topic. But <em>basic</em> revision
control is good to have, and easy enough to implement in most web
applications.</p>

<h3>Related information</h3>

<ul>
<li><a href="http://cvsbook.red-bean.com/">Open Source Development with CVS, 3rd Edition</a></li>
<li><a href="http://svnbook.red-bean.com/">Version Control with Subversion</a></li>
</ul>

<h3>Acknowledgements</h3>

<p>The alternative approach was inspired by <a href="http://www.mediawiki.org/">MediaWiki</a>.
Thank God for open source!</p>
]]></content:encoded>
			<wfw:commentRss>http://ronny.haryan.to/archives/2006/06/26/revision-control-for-web-application-content/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>802.1X Authentication</title>
		<link>http://ronny.haryan.to/archives/2004/10/25/8021x-authentication/</link>
		<comments>http://ronny.haryan.to/archives/2004/10/25/8021x-authentication/#comments</comments>
		<pubDate>Mon, 25 Oct 2004 11:10:29 +0000</pubDate>
		<dc:creator>ronny</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://ronny.haryan.to/archives/2004/10/25/8021x-authentication/</guid>
		<description><![CDATA[I just finished writing a research paper on 802.1X authentication as part of the assessments in one of the subjects I&#8217;m taking this semester. I will do a presentation on this topic to the class and the faculty this Saturday. The abstract of the paper is given below. The paper is available in PDF format. [...]]]></description>
			<content:encoded><![CDATA[<p>I just finished writing a research paper on 802.1X authentication as part of the assessments in one of the subjects I&#8217;m taking this semester. I will do a presentation on this topic to the class and the faculty this Saturday. The abstract of the paper is given below.</p>

<p>The paper is available in <a href="/files/802.1x.pdf">PDF format</a>.</p>

<p><span id="more-12"></span></p>

<blockquote>
  <p>The ever increasing complexity of today&#8217;s applications and services demands better security design and implementations. One of the most popular new technologies today is wireless LAN. It has different characteristics compared to the wired LAN so it requires new ways to provide proper security and authentication for wireless solutions. There are some early workarounds that tried to address wireless LAN security, one of the most popular was Wired Equivalent Privacy (WEP) which proved to be inadequate. 802.1X is the authentication part of the solution to the overall security problem. </p>
  
  <p>The IEEE 802.1X is a standard that tries to address authentication issues by utilising an authentication protocol called Extensible Authentication Protocol (EAP) encapsulated over LANs, or EAPOL for short, that in turn utilizes many existing protocols for authentication such as PPP, MD5, TLS, CHAP, and RADIUS. 802.1X can be used for wireless as well as wired LANs. </p>
  
  <p>This paper will discuss EAP and 802.1X in more details, what it is, how it works, what components are needed and how they interact with each other, where it can be used, some examples, and more. This paper could also provide some understanding of the 802.1X and EAP technology to network designers so that they can utilize it in their wired and/or wireless solutions.</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://ronny.haryan.to/archives/2004/10/25/8021x-authentication/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
