Sunday, May 11, 2008

Role-based views using CSS

In multi-role applications, most views are needed to contain almost the same content, but with different actions, varying according to the role of the user. This can be accomplished in most server-side views (like jsp, aspx, erb, ...etc) in a traditional way.

<!--
common content
-->
<% if role1 %>
<!--
role1 actions
-->
<% else if role2 %>
<!--
role2 actions
-->
<% else if role3 %>
<!--
role3 actions
-->

This works just fine. However, It's just so ugly!! Obviously we are embedding runtime logic in the views description. This breaks the concept of separation of concerns. Also, it makes the page fragments hard to cache because the resulting html becomes variant according to role values. The good news is that it can be accomplished in a much more elegant way. Basically, what we could do is, include all possible actions of all roles in the resulting html, relying on simple CSS style rules to show/hide those actions. We assign actions to CSS classes, add simple style rules to show the right actions in the right contexts. As as example, assume possible roles are admin, user, guest. assume the role of current user is known in variable 'role'. we assign the 'body' element an id that varies according to the current user role

< body id= <%=role%> >

Then we add the common content

<!--
common content
-->

Then we add all the possible actions, assigning each action CSS class names that represent the roles where the action should be displayed in.

< a href='.....' class="admin" >
< a href='.....' class="admin user" >
< a href='.....' class="user guest" >
< a href='.....' class="guest" >

The default definition of all those CSS classes are:

.admin, .user, .guest{ display: none }
so they are all hidden by default.
What's left is adding CSS style rules to the view 'head' element to show the right actions in the right context.

< style >
body#admin .admin { display: block }
body#user .user { display: block }
body#guest .guest { display: block }
</ style >

This simply means: show the admin actions if body id is 'admin', show the user actions if body id is 'user' and, show the guest actions if body id is 'guest'.

One more important thing to mention; this scheme introduces (or rather makes easier) a security vulnerability to the application. An opponent, assuming a guest role, can use any client side tool to change the resulting html, to show the hidden admin controls and use them. Obviously, nothing prevents such an attack, even if the proposed scheme was not used. The point is that we're making it easier for him. So, the bottom line is, different roles actions that result from hidden controls must be secured on the server side. Typically, we give everybody the control to DO something, but make sure they are privileged to DO it when they try to.


Thursday, May 8, 2008

Rails: When Functional Tests are not Functional !!

One of the most well-known virtues of the Rails framework is that everything has its own place to go in the project hierarchy. A perfect example is testing. Everything that is associated with tests goes under the "test" directory. Moreover, further grouping take place under the "test" directory. Unit tests are to be used when testing models functionality, and functional tests are to be used when testing controllers functionality. The good hidden feature in this modular division scheme is that, the shape of the functional test cases you write to cover your controllers code actually measures the degree of your code quality.

A typically 'good' rails functional test case could look like this:

def test_create_new_item
post :create, { :name => "name",
:description => "description" },
{ :session_key1 => "session_value1" }
assert_response :success
assert_template "create"
end

while a 'bad' rails functional test case could look like this:

def test_create_new_item
post :create, { :name => "name",
:description => "description" },
{ :session_key1 => "session_value1" }
assert_not_nil Item.find_by_name("name")
assert_equal users(:user1).item_count, 10
assert_response :success
assert_template "create"
end

So, what exactly makes the first example better than the second? Basically, functional tests is just about simulating requests and testing the 'behavior' of the controller action in such requests. The word 'behavior' means the group of characteristics of the request and response. For example, A good functional test case is that simulates a request, then just asserts for the request and/or response headers and/or body, like the first example. A bad example is asserting for a specific state of the data after the request is handled, like the second example. This is not right because, in such a case, you are making one of two mistakes:

-You are adding some redundant assertions to test some model functionality that is already covered in unit tests.
-Your controllers incorporate some model-level chunks of code. Consequently, you needed to cover them in the functional tests. This is a strong indicator that these chunks of code are misplaced in the controllers. They sure need to be abstracted to some model functionality, being covered in unit tests.

So the bottom line is, in your functional tests, mind only the 'behavior' of the controller action you're testing. If you find your functional test cases not covering all controller code after all, try to reconsider your controller code. Go for some model abstraction of your controller code, and cover the new model code in the unit tests.


Rails: ActionMailer with TLS (SSL)

Starting to work with Ruby on Rails, ActionMailer was quite a relief. Writing code for mass mailing was just a matter of configuration. You just need to configure your application mailer to use a given smtp server account to forward emails generated in the application. The common problem I faced was that ActionMailer does not support TLS, i.e. it cannot be configured to use an smtp account on a server that uses SSL for authentication.

The typical configuration in such a case is (using an smtp server that doesn't require SSL fro authentication) :

config.action_mailer.smtp_settings = {
:address => 'smtp.mailserver.com',
:port => 123,
:domain => "your domain name",
:authentication => :login,
:user_name => "account@mailserver.com",
:password => "account_password"
}

Or maybe you could use an smtp server that doesn't require authentication at all, disregarding that it will be considered as spam by
default by most respectful email providers:

config.action_mailer.smtp_settings = {
:address => 'smtp.mailserver.com',
:port => 123,
:domain => "your domain name",
:authentication => :plain
}

That's it for the problem. We need to use the great ActionMailer, with a respectful smtp server that requires SSL at the same time. The solution is the magical plugin action_mailer_tls. You just download and install the plugin, and add one line to the smtp settings:

config.action_mailer.smtp_settings = {
:address => 'smtp.mailserver.com',
:port => 123,
:domain => "your domain name",
:authentication => :login,
:user_name => "account@mailserver.com",
:password => "account_password",
:tls => true
}

That's it. Now you can generate mails and use that smtp server with TLS to forward your emails. Pretty handy, right?


Web 2.0: Client-side Views

In a previous article, We saw how DOM manipulation can become so handy using JavaScript Templates. Massive changes could be applied to the html document hierarchy using one-line JavaScript functions. In this article we will introduce a generic web development technique that we can name Client-side Views.We will build on our knowledge of JST in order to compose a closed set of tools to follow client-side views with minimal effort. At the end we will get to know the benefits obtained by following such a technique.

What is Client-side Views?

Client-side views can be defined as the concept of abstracting the server-side of a web application to respond to different actions with a standard non-graphical data format, leaving the task of forming a graphical representation of this data to its client-side. This means that the server will not respond with formatted html as usual. However, it will respond with some data format (like xml). Notice that, obviously, this technique helps future transformation of a web application into an abstract web service.

A Closed Set of Tools

Now let's introduce a closed set of tools that will help us follow client-side views with minimal effort. As it can be guessed, there is no restriction on the server-side development tools. However, on the client-side we'll stick to JavaScript, being the most famous standard client-side scripting language. In addition we'll select Prototype Ajax, JSON and JavaScript Templates.
Prototype Ajax
Protoype JS library contains a very powerful abstraction of almost all the functionality of XMLHttpRequest (xhr). Hiding most of the details, Prototype Ajax introduces a very nice interface to the native xhr Ajax. In this context, we are interested in only one api, which is "Ajax.Request". We will send an ajax request to the server, expecting it to respond with a known data format (discussed in next section). For more information about Ajax.Request api, visit its documentation page.

JSON

As mentioned before, we will send an ajax request to the server, expecting a response with an agreed on format. The most handy data format that supports our technique is JSON. JSON stands for "JavaScript object notation". It is the representation of an object in JavaScript. As we are using JavaScript as a language, we can't be happier if the server responds with the notation that JavaScript best understands. Almost all programming/scripting languages have their own libraries for JSON manipulation. For example, in Ruby on Rails, we can just call "object.to_json" to obtain the JSON representation of the ruby object. for more details about JSON and its libraries in different languages, visit json.org.

Combining with JST

Combining with JavaScript Templates (introduced in the previous articles), our adopted scenario will be a close variant of the following:

- Send an Ajax request to the server application, providing a callback that's called on success of the request.
- The server responds with JSON format of all data needed to transfer the state of the front-end representation of the application.
- On request success, the callback we provided is called. A typical client-side renderer callback will look as follows:

function callback(transport){
//evaluate the JSON string returned from the server
//(one line)
var jsData = eval( '(' + transport.responseText + ')' );

//evaluate the resulting html provided the data
//obtained from the server
var newHTML = TrimPath.processDOMTemplate('jst_id',
{ jstData: jsData } );

//insert the newly formatted html in its placeholder
$('placeholder_id').innerHTML = newHTML;
}

Hurray.. We have just transferred the view rendering logic that we used to follow on the server to the client, using a three-line JS function.

Benefits

Let's compare our technique to the traditional ajax technique of sending an ajax request, forming an html snippet at the server, and returning it to the client to insert it in its placeholder. Our benefits are:

- Ability of developing multiple clients with different graphical representation to the same web application (the concept of web services).
- Massive reduction to the server response time; the time that used to be consumed in evaluating server-side templates is now reduced and divided among other requests.
- Massive reduction to the bandwidth used; the size of JSON text of some data is dramatically less than its formatted html representation.

However, there is a disadvantage we can't totally avoid; our typical three-line rendering function incorporates extensive string processing (parsing the template and evaluating the output html using the supplied date). It's a known fact that JavaScript is relatively slow on most web browsers when it comes to string operations. So, at least, one has to watch out for the performance measure, try to optimize his code as far as possible, just not to make things worse.


Friday, May 2, 2008

JavaScript Templates: A major leap on the way of Web2.0

An undisputed fact is that JavaScript acts as a cornerstone to Web 2.0 application development. Web 2.0 applications extensively rely on JavaScript logic to manipulate DOM elements on the fly. let's consider a typical example. A JavaScript function is needed to generate some HTML fragment and insert it into a placeholder that already exists in the document. Let's say that the resulting fragment represents some user's data and that it is required to look like this:

<img src='/users/12/image' title='Haitham Mohammad' alt='Haitham Mohammad' />
<label class='user_label'> Name: </label>
<span class='user_name'> Haitham Mohammad </span>
<label class='user_label'> Telephone: </label>
<span class='user_telephone'> 0127038199 </span>

Now let's see how that JavaScript function would look like: (I know it's not minimal, but it's a typical example. let's say that it will, at least, look like that)

showUserDetails = function(user){
placeHolder = document.getElementById('place_holder');

img = document.createElement
img = document.createElement('img');
img.src = user.imageSource;
img.title = user.name;
img.alt = user.name;
placeHolder.appendChild(img);

nameLabel = document.createElement('label');
nameLabel.className = 'user_label';
nameLabel.innerHTML = 'Name: ';
placeHolder.appendChild(nameLabel);

nameSpan = document.createElement('span');
nameSpan.className = 'user_name';
nameSpan.innerHTML = user.name;
placeHolder.appendChild(nameSpan);

telLabel = document.createElement('label');
telLabel.className = 'user_label';
telLabel.innerHTML = 'Telephone: ';
placeHolder.appendChild(telLabel);

telSpan = document.createElement('span');
telSpan.className = 'user_telephone';
telSpan.innerHTML = user.telephone;
placeHolder.appendChild(telSpan);
}

Yes, I know, it's long and ugly. However, this is what I used to do in my early couple of months in JavaScript. Now let's formulate the problem that lead to this long and ugly code. The problem is that HTML is a descriptive language while JavaScript is a procedural one. The anomaly appeared when we tried to 'describe' our HTML fragment using JavaScript 'procedure'. i.e. When we tried to override the descriptive nature of HTML using the procedural nature of JavaScript.

Now let's be a bit positive. The solution simply exists in a relatively new open source JavaScript library called JavaScript Templates (or JST), developed by TrimPath . A JavaScript Template is an HTML template that is yet to be evaluated using some JavaScript variables. This principle is so close to all server-side templates like jsp, erb, ..etc.

Now, the new steps are: i) write the JST that DESCRIBES your data representation. ii)write the JavaScript function that EVALUATES that template some given JavaScript variables as data parameters. Let's apply to the example.

Performing step (i), Our JST will look like that:

<textarea id='jst_user_details' style='display: none;'>
<img src='${theUser.imageSource}' title='${theUser.name}'
alt='${theUser.name}' />
<label class='user_label'> Name: </label>
<span class='user_name'> ${theUser.name} </span>
<label class='user_label'> Telephone: </label>
<span class='user_telephone'> ${theUser.telephone} </span>
</textarea>

We hold the template code inside a hidden textarea with a known id just to be able to get the template afterwards at runtime. The evaluation sign '${}' means that what's inside the curly braces is still to be evaluated afterwards at runtime.

Now comes the magic in step (ii). Our long and ugly JavaScript function will be replaced with this one:

showUserDetails = function(user){
userHTML = TrimPath.processDOMTemplate('jst_user_details',
{ theUser: user } );
placeHolder = document.getElementById('place_holder');
placeHolder.innerHTML = userHTML;
}

We simply called a function that processes the JST contained inside the textarea with id = 'jst_user_details', given one data variable named 'theUser' with the same value as the parameter 'user'. And, tadaa, we have a pure HTML fragment that describes a certain user's details.

JST also supports basic functionality of any server-side template language, like repitition and conditionals. A JST can typically contain the following snippet:

{for item in itemss}
{if user.admin}
<input type='button' value='edit' ...
{else}
<input type='button' value='view' ...
{/if}
{/for}

To sum it up, what JST does is eliminating the problem we introduced before. It simply separates HTML description from JavaScript procedures. Talking about myself, It made me at least four times as productive as I used to be using traditional DOM manipulations. Besides, your code becomes more neat, more modular, and more organized. Go ahead and give it a try: http://code.google.com/p/trimpath/wiki/JavaScriptTemplates


Thursday, May 1, 2008

Prototype JS incompatibility with Facebook JS client library

I have been working on a facebook application using their all new JavaScript client library. I was trying to reuse a large self-contained module that relied heavily on prototype & scriptaculous JS libraries. The module was working just fine outside the context of the Facebook application. But after including the Facebook JS library, runtime JS errors began to appear, especially when initiating a scriptaculous effect. Obvoiusly, that was concluded to be a compatibility issue between the prototype & scriptacuolous family on one side, and Facebook JS client library on the other.

The origin of incompatibility, courtesy of Mohammad Ali, was discovered to be a tiny bug in Prototype's browser identification. To the point, the problem was discovered to be as follows:
  1. Prototype identifies the browser as IE according to the presence of the IE specific function 'attachEvent'. In prototype.js line 13:
    IE: !!(window.attachEvent && !window.opera),
  2. Obviously, this condition is fragile, and will fail if any other included script defines a "window.attachEvent" function for any other browser, which is the exact case of Facebook JS client library.
  3. The Facebook library contains thefollowing line (FacebookApi.debug.js line 387):
    if (window.navigator.userAgent.indexOf('Safari') >= 0) {
    _loadSafariCompat(window);
    }
    else {
    _loadMozillaCompat(window);
    }
    This code is embedded in an if-condition that it is only executed if the browser is not IE.
  4. The function "_loadMozillaCompat" defines "window.attachEvent" for mozilla browser type, which causes Prototype's IE identification condition to fail, leading to a total mess up in many cases.

    The solution is to power up Prototype's IE identification condition, by adding a check that the browser is not mozilla. The new condition looks like that ( and it works :) )
    IE: !!(window.attachEvent && !window.opera && navigator.userAgent.indexOf('Gecko') == -1),
This will do it for this specific incompatibility instance. However, the sure thing is that the foundation of Prototype's browser identification needs a basic tweak to be concrete against other libraries.