Posts Tagged Design
Grails: Ajax Login using Basic Auth
Posted by Morten in Uncategorized on April 7, 2009
So I have my Grails environment setup. The point is to build a REST-service that will work as a back end to a highly dynamic JavaScript page. I chose Grails, since it builds on Hibernate and Spring.
Two frameworks Id like to examine for the purpose of seeing the differences between Castle and nHibernate in the .Net world.
Building domain-classes and having the represented as XML is straight forward in Grails, but I need to take care of the login scenario. If you’d like to know more about building REST web services with Grails, I recommend reading the Mastering Grails: RESTful Grails article. Login seems like a good place to start, to ensure that my domain-controllers can dictate login as I develop the domain.
Now Grails.org has a list of tutorials, one of them, focusing on Login. It’s a good beginners tutorial showing how to use interceptors to execute user verification before showing the actual view requested. For my scenario however it has a few problems. Lets use the tutorial as a start of point.
The problems I have with the solution is with the following code:
def checkUser() {
if(!session.user) {
// i.e. user not logged in
redirect(controller:'user',action:'login')
return false
}
}
For my scenario this has one problem, in two places. Its stateful. First of it always directs the user to the same place, of course it can be different per controller. I need it to simple say access denied.
def checkUser() {
if(!session.user) {
// i.e. user not logged in
response.sendError(401)
return false
}
}
The above code is changed to instead of redirecting the user, it simply sets the response code to Access Denied. Now there’s just one issue left, the session code.
I don’t want to use session, as it requires my server to remember each session, preferably I want the client to remember the state.
Another issue is that I want to use Mor.ph AppSpace, if I pay for the most basic of subscriptions at Mor.ph I get two Cube, i.e. two servers with a load balancers in front. As a result I can’t be sure that the same server will service the same client all the time.
If we instead choose to check for the logged in user using the authorization header. The state is always provided by the client, instead of keeping the state on the server.
def checkUser() {
if(!UserController.checkAuthorization(request, response)) {
// i.e. user not logged in
response.sendError(401)
return false
}
return true
}
I let the UserController do the checking of the user, using a static method. This will let me keep the authorization code in the same place I handle users to begin with. It also allows me to change the authorization method later by changing the code in the checkAuthorization method. We could use Dependency Injection here to inject a real instance of the UserController, or even better an object with the sole responsibility to check user access. However DI is out of scope for this post.
You can implement any way of checking the user login you want. If you want a simple solution and stick with the HTTP standard you could use Basic auth. Here is a good explaination of how to implement Basic auth for Grails. Another way is too use a cookie to hold authorization information.
For this example were just sending username:password in the authorization header. My final implementation will be Basic Auth with the password hashed to a checksum. The point of the hash is to never send plain-text password across the net.
Here is the checkAuthorization method in the UserController for this example.
static boolean checkAuthorization(HttpServletRequest request, HttpServletResponse response) {
def authString = request.getHeader('Authorization')
if (!authString) {
return false;
}
def credentials = authString.split(':')
if( credentials.length != 2 || credentials[0] == null || credentials[0] == "" || credentials[1] == "" || credentials[1] == null)
return false;
def user = User.findByEmailAndPassword(credentials[0], credentials[1])
if (user) {
return true;
}
return false;
}
Now we can create some JQuery based JavaScript code to handle login.
function RestClient() {
var self = this;
var auth;
function ShowLoginUI(afterLoginCallback) {
var dialog = document.createElement('div');
$(dialog).html("<table><tr><td>Email</td><td><input id='email' type='text'/></td></tr><tr><td>Password</td><td><input id='pass' type='password'/></td></tr></table>");
$(dialog).dialog({ buttons: {"Login": function() {
auth = $(this).find("#email").val() + ":" + $(this).find("#pass").val();
afterLoginCallback();
$(this).dialog("close");
}, "Cancel":function() {
$(this).dialog("close");
}}, modal:true});
}
this.Get = function(url) {
var data = null;
data = $.ajax({
url : url,
method : 'GET',
beforeSend : function(req) {
req.setRequestHeader('Authorization', auth);
}, cache : true,
error: function(request, textStatus, error) {
if (request.status == 401) {
ShowLoginUI(function() {
data = self.Get(url);
});
}
}});
return data;
};
}
The above code does Ajax Get-calls to the specified address. If the call failed due to Access Denied, it shows a login form and tries to execute the Ajax request again. The class remembers the authorization string, so as long as the user uses the same RestClient-object the state is maintained at the client side.
Ill leave instructions on how to wire up Grails with JQuery to someone else.
Here is a simple usage example:
var a = new RestClient();
$("#test").click(function() {
var data = a.Get("plant/create");
$(document).append(data);
});
Good luck writing scalable login scenarios using Ajax instead of page reloads.
Working with a domain model
Posted by Morten in Uncategorized on March 4, 2009
We just took a new turn on the work with our Domain Model in RemoteX Applications.
In recent months, mostly due to the increased number of customers using the system. There had been some innovative ways in using the product. Some for which we hadnt intended the product to be used. Also requests were coming in that were requesting information to be ordered in a way that wasn’t possible using the existing domain model.
This combined with new team-members putting a slight strain in the communication, since the ubiquitous language was evolving based on new experiences and people. And the Domain Model wasn’t evolving with it.
As a result we had a meeting today, where we discussed the Domain Model, as is. The goal was to introduce it, and the reasons for it, to the new people on the team. But also to find a way to keep it more in line with the rest of the organization and our customers.
We came up with a few actions. One of them is to find a file based wiki to keep the documenation of the domain model in. That way, we can have the domain model checked in under source control, and update it as we update the product. The goal here is to not let the domain model get out of sync with the application, causing it to either become out-dated or as in our previous case risking it coming down with a bad case of YAGNI.
This change also makes it more apparent that the Wiki is for the developers to maintain, ensuring that the ubiquitous language alive in the development team.
Every time you downcast a kitten breaks a rib
Posted by Morten in Uncategorized on February 19, 2009
This is a snippet taken from our design guidelines document.
Most code doesn’t require casting. Avoid casting, especially if you cast to a more specialized class.
Use extension methods with care
Posted by Morten in Uncategorized on February 9, 2009
.Net 3.5 introduced the extension methods; they can be a nice way to extend classes we have no control over. They can wrap common usages of objects; even implement methods on interfaces to assist the common responsibility of the usage of that interface.
However, extension methods are basically just static methods. They cannot be mocked; also functionality in an extension method has to be white box tested. Remote calls or construction of objects in an extension method requires extra mocking of the objects that use the extension method, which might not be apparent when first writing the tests.
Design consideration when using Extention methods
Posted by Morten in Uncategorized on January 15, 2009
Extension methods are a nice way to warp up code that you often execute on different classes. However do not forget to consider the test implications of the Extension methods you are creating.
A simple mutating extension method is easy enough. But if you have an extension method that does remote calls to other classes. You will need to create expectations or results for those calls if you Mock them.
Sometimes you could want to put such logic in extension methods since you do not own the class or assembly that you use. In such scenarios consider writing a class that implements the logic using composition. The class can then be tested independently and mocked for the usages of it.
The cost of an conditional flow in a user story
Posted by Morten in Uncategorized on November 30, 2008
During this sprint in at my work, some minor touch up stories were added to the sprint. These stories however we’re thought out, at least not to the level that they were ready to be implemented.
Ill try to describe a particular problem of one of them.
The problem is with time management, and perceived different behaviour based on certain constraints.
Here is an example:
Consider a shipping company, each worker packs certain crates and ships them according to a schedule. The worker marks each package as packed and places them in the loading area, where someone else takes over. Every day the worker receives a set of scheduled orders to pack. The worker uses a stock handling tool to manage the product stock while packing.
A nice feature for this system would be for a question to pop-up to the user as he is using the Stock handling tool for picking the products for packing, asking the user if he or she wants to mark the package as packed when all products are picked from stock.
The stock handling tool doesn’t know anything about the order, being picked. So that tool tries to be smart, by asking the packaging system which package is supposed to be packed right now based on the schedule, check if this is the only product to be shipped and if so ask the user to mark the package as packed automatically.
Now the scenario isn’t exactly as clear as I hoped it would. But the point is that the system tries to make assumptions, based on the schedule and the current time, instead implementing a correct version where the system that tries to make the assumption actually has the data needed to make it. In this case, which package currently being picked.
The idea for us was to have a “cheap” version to give a similar flow. The problem is that since there is no immediate link between the product begin picked and the package to pack, the pop-up only shows up during times where the system can guess that the package is fully packed.
So what is the cost of this.
For the developers, its probably fairly cheap, its a if-statement somewhere, perhaps with some extra glue code.
For the support, this is hell, consider the questions: “Sometimes I get this pop-up and sometimes i don’t. Why don’t I get it all the time?”. Imagine the answer, the support technician has to try to describe how that specific if-statement works to the customer, who most likely doesn’t care about if-statements or the likes.
What is worse with such a user-flow is that the developers, being smart people, often make that specific If-statement complex. Trying to maximize the benefit of the specific pop-up. Well, sometimes we can make the assumption based on this, sometimes on that.
For each “or” and “and” function in that if-statement the cost for the support goes up exponentially.
What is potentially a bigger problem is that customers do not like non-deterministic behaviour. The system should just work, users get uneased when their expectations on the user-flow aren’t met, or worse are met only half the time based on some obscure logic that the customer has no real-world conception of.