Fake binary trees
... rants, ramblings and occasional good idea ...

Hello, Crumbs

Finally got a few spare hours to do some hacking on my poor man's NH profiler, and that resulted with Crumbs.

It's an NHibernate profiler for web applications based on Asp.Net, regardless of which framework (Monorail, Asp.Net MVC,...) you prefer to use. It is now much easier to set it up: just drop in the Crumbs.Profiler HttpModule and off you go (actually, you will also need additional CCS stylesheet to make it look nice, and maybe jQuery to make it act nice).

Hopefully, future versions should bring even simpler usage and better functionality.

At the moment code is rather ugly (actually, my first HttpHandler ever) and has no tests at all, but it will change. It is now hosted at Google Code, so feel free to check it out.

Posted at 13:38 on February 15, 2010
Categories: .NET | NHibernate | Crumbs   E-mail | del.icio.us | Permalink | Comments (0) | Post RSSRSS comment feed

Poor man's NHibernate profiler

First of all, if you do any serious work with NHibernate, consider using the excellent NHibernate profiler. It will save you time and pinpoint many non-obvious issues with your NHibernate usage patterns.

Now, if all you need is a way to check what SQL has your web application been executing (e.g to optimize lazy loading, check for N+1 issues, etc), it is helpful if you can see this information straight on the web page which executed the statements.

For my web development work, I prefer using Castle Monorail (+ ActiveRecord or NHibernate) I have attached a demo project (see the bottom of the post) which you can feel free to use with your application. It shows how to trace NHibernate log data into the web page by using Monorail filter which collects the NHibernate information (by reading from log4net in-memory appender which receives NHibernate.SQL logging), and a component which displays the collected data.

In order to use this in your application, you need to:

  • copy DebuggingFilter and DebuggingComponent into your project
  • register DebuggingFilter with your controllers
  • set up the log4net in-memory appender (see web.config in the sample)
  • set DebuggingFilter.DebuggingActive to true at some point (e.g OnApplicationStart)
  • copy and include jQuery JavaScript in your pages (if you want to toggle the details)
  • copy a part of the stylesheet which formats debugging div (or roll your own)
  • if some step is missing, please drop me a comment

If time allows me, I would like to implement following features:

  • providing an implementation for Asp.Net MVC (actually, I already have it)
  • setting a global/per-request limit of SQL statements, which triggers an error information
  • filtering who can see the data (for use on live site, but there are issues with logging all the SQL)
  • an HttpModule implementation - need no setting up, independent of framework (Monorail, Asp.Net MVC)
  • extract CSS for debug window into separate file
  • use only minimum JavaScript instead of full jQuery

It would also be great if Oren would provide similar functionality in NHProf. E.g. you would just embed the URL of NHProf service into your pages, and the service would return the requested data.

Here's how it looks in action:

When a request is executed, the summary of the SQL is shown at the top. If there was a redirect, each request will have separate entry.



Clicking the 'toggle details' button will display the executed statements:



Download Monorail sample (uses ActiveRecord for DB access): demoapp.zip (1.87 mb)

Posted at 07:09 on January 29, 2010
Categories: .NET | Monorail | NHibernate   E-mail | del.icio.us | Permalink | Comments (1) | Post RSSRSS comment feed

Converting Pascal case to sentences using regular expression

Here's another reminder to myself: a nifty one-liner regex which transforms Pascal/camel case string into a sentence. I always write it from scratch so I decided to put it here. It might also be a good idea to write it as an extension method for string class.

static string PascalCaseToSentence(string input)
{
   return Regex.Replace(input, ".[A-Z]", m => m.ToString()[0] + " " + char.ToLower(m.ToString()[1]));
}

Following line

Console.Out.WriteLine(PascalCaseToSentence("MyVeryLongSentence"));

will result in:

My very long sentence
Posted at 22:56 on April 29, 2009
Categories: .NET   E-mail | del.icio.us | Permalink | Comments (0) | Post RSSRSS comment feed

Build automation issues wit NAnt and .NET 3.5

On our project, we are experimenting with continuous integration, and so we set up a build server based on CruiseControl.NET. The server is running on Windows Server 2008, and we try to keep it as clean as possible. Development machines typically run on Win XP.

The project tree contains tools folder which contains copy of NAnt and other tools which are used to run the build (NUnit, NCover, Simian, etc). This way, when a developer downloads project files to development machine, he just runs the build script and same version of tools is used to perform a local build, thus avoiding the risk of using mismatching version of tools. NAnt build script internally uses <msbuild> task to compile the msbuild solutions.

This has all worked great until we recently switched from .NET 2.0 to .NET 3.5. During this, our development machines were updated to Visual Studio 2008, and our build server was updated to 3.5 framework and SDK (we don't install Visual Studio on build server,so we have to install SDK separately after the .NET framework is installed).

This initially created issues with some of our build scripts: builds started failing with error messages pointing to the fact that <msbuild> task doesn't understand format of the solution file (new version is 10 and build complained about understanding only 7 and 9). After updating NAnt to latest version and testing on a dev machine, problem seemed to went away.

However, builds on our CI build server started failing with same error.

After some investigation, it turned out that Visual Studio 2008 installs version 6.0A of Windows SDK. However, standalone Windows SDK installs version 6.1, thus resulting in mismatch between build server and dev machines.

The heart of the problem is that nant.exe.config internally uses ${sdkInstallRoot} variable which is initialized to the value read from the registry key SOFTWARE\Microsoft\Microsoft SDKs\Windows\v6.0A\WinSDKNetFxTools\InstallationFolder. Now, we couldn't just change the entry in nant.exe.config because the same file is used both on server and dev machines, and if we fix it for one it won't work for the other.

We also didn't want to install Visual Studio 2008 on build server.

The solution (or more precisely, the hack) was simple:

  • Open regedit
  • Go to 'SOFTWARE\Microsoft\Microsoft SDKs\Windows\v6.1\WinSDKNetFxTools\InstallationFolder' key
  • Export it into a file
  • Open the file and replace all references in key names from "v6.1" into "v6.0A". Leave the file paths with 'v6.1' unchanged.
  • Save the file and import it into regedit

Now you have the exact copy of the SDK 6.1 keys, saved under 6.0A key. This way, build server can use the same nant.exe.config file as dev machines.

If there is a cleaner way, I would be glad to hear it, but this is working for us without any problems.

Posted at 14:03 on September 24, 2008
Categories: .NET | Continuous Integration | NAnt   E-mail | del.icio.us | Permalink | Comments (0) | Post RSSRSS comment feed

Using assembly resources as NVelocity templates

For those who don't already know, NVelocity is a .NET port of Jakarta Velocity template engine. Castle team took it over, due to the lack of releases, support and bug fixes on the original port, and I strongly suggest to use this improved version.

NVelocity is a fine tool, but it is not quite obvious how to set it up so that embedded assembly resources can be used as templates. This is done by setting a group of properties which control what implementation of ResourceLoader abstract class is used to load the templates. To use embedded resources, you need to register the NVelocity.Runtime.Resource.Loader.AssemblyResourceLoader class as ResourceLoader, and specify the assembly which contains the templates as parameter "assembly.resource.loader.assembly". Here's how: 

private static void InitializeVelocity()
{
  ExtendedProperties properties = new ExtendedProperties();

  properties.AddProperty("resource.loader", "assembly");
  properties.AddProperty("assembly.resource.loader.class",
          "NVelocity.Runtime.Resource.Loader.AssemblyResourceLoader, NVelocity");
  properties.AddProperty("assembly.resource.loader.assembly",
          Assembly.GetExecutingAssembly().GetName().Name);
     
  m_velocity = new VelocityEngine(properties);
}

You can find the full sample here: NVelocitySample.zip (87.13 kb)

Posted at 18:34 on September 19, 2008
Categories: .NET | NVelocity   E-mail | del.icio.us | Permalink | Comments (0) | Post RSSRSS comment feed

Access control based security

Natural question to ask after previous post is: that's all fine and dandy but how do you combine this with access control list (ACL) based security?

First, let's explain the issue here: What I refer to as 'ACL based security' is defining permissions (access rights) for individual resources, similar to the way operating systems allow access to file system. E.g. user 'xy' can see all tasks for projects he manages, but also all other tasks in other projects where their managers have allowed access to 'xy', or tasks which are assigned to 'xy'. This changes our imaginary security API from HasPermission(user, permission) to HasPermissionFor(user, permission, object)

Although security is usually not considered a business logic, the line starts to get blurry here. In my opinion, this is both a business and infrastructure concept.

One possible solution, which unfortunatelly can be seen too often, is to retrieve data as usual and then throw away resources which don't match the permissions. This approach fails miserably in many aspects: performance, filtering, paging, etc.

I am not sure if it is even possible to create a 'one size fits all' solution for this problem. However, in most systems that I had to deal with, following solution was able to get me quite far.

Note: I presume that the infrastructure is already set up: additional database tables store ACL entries which define who is allowed or denied access to individual resources, so that queries which retrieve items from the database can join on these tables. This is not a trivial thing and can become quite complex, especially when you take into account resource hierarchies (e.g. project-task), but it is out of scope of this post.

Anyway, suppose that we have ITaskManagementService which exposes following method:

[RequiresPermission(Permission.Edit)]
void GetTasks( ... parameters...)
{
    // m_taskRepository is an instance of ISecureRepository<T>
    m_taskRepository.GetAll(); 
}

Service has SecurityInterceptor implemented through Windsor/DP2, which checks for RequiresPermission attribute and do something like:

class SecurityInterceptor : IMethodInterceptor
{
    public object Intercept(IMethodInvocation invocation, params object[] args)
    {
            CallContext[Context.Security] = new SecurityContext(CurrentUser, attr.Permission);         
            return invocation.Proceed(args);
    }
}

than in the SecureRepository implementation, permissions are added to the query:

public IList<T> GetAll()
{
    ICriteria criteria = BuildCriteria();
    return criteria.List<T>();
}

public void BuildCriteria<T>()
{
    ICriteria criteria = Session.CreateCriteria(typeof(T));
    SecurityContext security = CallContext[Context.Security];
    // now we modify criteria to join entity tables with ACL tables...
    AddPermissions(criteria, security.UserId, security.RequiredPermissions);
}

This will make sure that GetAll() method returns only those tasks for which the caller has sufficient permissions. The drawback of the solution is that it only works if the resources and permissions are stored in tables in the same database so you can join them, but this usually isn't an issue for most small to medium solution.

Posted at 18:01 on February 6, 2008
Categories: .NET | Software Design   E-mail | del.icio.us | Permalink | Comments (0) | Post RSSRSS comment feed

Implementing security (and other cross-cutting concerns) through AOP

A common problem with implementing security is that you end up with bunch of repeated code blocks which check the current user's permissions and then allow or disallow the execution of some method. Example:

public class OrderManagementService : IOrderManagementService
{
    public Guid CreateOrder(string orderCode)
    {   
        if(!CallContext.CurrentUser.HasPermission(Permissions.CanCreateOrder))
        {
            throw new SecurityException("Only users with CanCreateOrder permission can create an order.");
        }

        Order order = new Order(orderCode);
        order.Save(order); // ActiveRecord-like implementation
        return order.Id;
    }
}

The problem with this approach is that you have to implement the check in every method which requires some combination of permissions. While this is not overly hard to do, it becomes a maintenance hell as the number of such methods grows. Also, if you want to change the behavior in case of missing permissions you have to modify all those functions. Of course, you can encapsulate it in some common utility method, like this:

    ...
    if(!CallContext.CurrentUser.HasPermission(Permissions.CanCreateOrder))
    {
        HandleMissingPermissions("Only users with CanCreateOrder permission can create an order.");
    }
    ...

This is also not perfect: If you decide that you need more context info in the utility method (e.g. required permissions or method name) you have to modify it:

    ...
    if(!CallContext.CurrentUser.HasPermission(Permissions.CanCreateOrder))
    {
        HandleMissingPermissions("CreateOrder", Permissions.Admin, "Only users with CanCreateOrder permission can create an order.");
    }
    ...

Now you have to modify all calls to HandleMissingPermissions method, etc.

The issue with application security is that it is a cross-cutting concern: it applies to all parts of system and not to a specific context, therefore, it doesn't make sense to implement it at each point where it is needed. In other words it is an application aspect (in AOP sense), and it is often best implemented in such manner.

There are many ways to implement AOP in .NET world: (Aspect#, NAspect), IL weaving (PostSharp) etc. In my opinion, one of the easiest is using interception features which are provided by some IOC container (e.g. Windsor and Spring.NET have it, StructureMap added it recently). In this example, I will use Windsor, because I am more familiar with it than with the others. For those who somehow missed it, Windsor is a quite popular IOC library, which is a part of Castle, an open source set of tools for easier development of enterprise and web applications.

So, here is how we are going to implement security:

  • We are going to define security requirements for each method using attributes
  • Instances of the target service (IOrderManagementService) will be retreived through the IOC container
  • IOC container will inject the security interceptors
  • Interceptor will check whether the method caller has required permissions


Our OrderManagementService class will now look like this:

[Interceptor(typeof(SecurityInterceptor))]
public class OrderManagementService : IOrderManagementService
{
    [RequiredPermission(Permissions.CanCreateOrder)]
    public virtual Guid CreateOrder(string orderCode)
    {   
        Order order = new Order(orderCode);
        order.Save(order); // ActiveRecord-like implementation
        return order.Id;
    }
}

OrderManagementService class is decorated with [Interceptor] attribute which defines the interceptor class which will be used to wrap the methods. You can define multiple interceptor classes, but usually it is better to do this in configuration file (see attached sample) than directly in the code, because you can switch the interceptors on/off without recompiling the code. This can be useful for debugging purposes or trouble-shooting.

Back to the implementation: security related logic is not checked in CreateOrder method anymore. Instead, SecurityInterceptor reads metadata for each method which is executed and according to RequiredPermission attribute of the method and permissions granted to the current user decides whether the method should be executed or not. Here is the implementation of the SecurityInterceptor:

class SecurityInterceptor : IMethodInterceptor
{
    public object Intercept(IMethodInvocation invocation, params object[] args)
    {
        MethodInfo method = invocation.Method;
        if(NeedsAuthorization(method) && GetRequiredPermission(method) != Context.Caller.Permission)
        {
            string message = string.Format("Method {0} requires {0} permission",
                                            method.Name,
                                            GetRequiredPermission(method));
            throw new SecurityException(message);           
        }

        return invocation.Proceed(args);
    }

    private bool NeedsAuthorization(MethodInfo method)
    {
        return method.IsDefined(typeof(RequiredPermission), true);   
    }

    private Permission GetRequiredPermission(MethodInfo method)
    {
         RequiredPermission attribute = (RequiredPermission)method.GetCustomAttributes(typeof(RequiredPermission), false)[0];
        return attribute.Permission;
    }
}

The only thing left to be done is to modify the client code to retrieve the IOrderManagementService instance via IOC container and call the method:

private void OnCreateOrderClicked(object sender, EventArgs e)
{
    // caller permissions have already been set
    IOrderManagementService svc = m_container.Resolve<IOrderManagementService>();   
    svc.CreateOrder("#ord-1-01");
}

This covers all the interesting parts of such implementation. Of course, in real-life scenarios this is not enough. The sample code is a bit more elaborated: you can define custom message for every RequiredPermission attribute instance, permissions can be combined etc.

The same approach can be used for other cross-cutting services, like logging and transaction handling.

You can download the sample here:  AopSecurity.zip (123.55 kb)

Posted at 12:31 on February 4, 2008
Categories: Castle.Net | .NET | AOP   E-mail | del.icio.us | Permalink | Comments (0) | Post RSSRSS comment feed