Themis, a bit dipper dive

I just committed some new code for Themis examples, which for now on, will be also an integration tests. The whole case is about values which are allowed for some roles.

Let’s take a case where there are two types of users: Admins and standard users, for the sake of briefness called Users. Let Admins are allowed to choice an offer type between Internal and External, and a standard user’s choice is narrowed to one value: Internal. How can a domain be modeled to handle it easily? First of all roles are needed:

public class AdminRoleDefinition : RoleDefinitionBase<Admin>
{
    public AdminRoleDefinition( )
    {
        ValueIsAllowed(OfferType.Internal);
        ValueIsAllowed(OfferType.External);
    }
}

public class UserRoleDefinition : RoleDefinitionBase<User>
{
    public UserRoleDefinition( )
    {
       ValueIsAllowed (OfferType.Internal);
    }
}

What’s the method ValueIsAllowed? It’s a simple, internal extension method, setting the possible value, using an markup demand.

public static class ServiceExtensions
{
    public static TValue[] GetAllowedValues<TValue>(this IDemandService @this, params object[] roles)
    {
        return @this.Evaluate<AllowedValueDemand<TValue>, TValue>(
                AllowedValueDemand<TValue>.Instance, roles);
    }
}

internal sealed class AllowedValueDemand<TValue> : IDemand<TValue>
{
    public static readonly AllowedValueDemand<TValue> Instance = new AllowedValueDemand<TValue>();
}

Having all this configured, now one can query a demand service for allowed values for a specific drop-down! It could be also done on the filtering basis with NHibernate, but it was an example how simply extensible Themis is.

Themis, take a break

Sometimes it’s good to take a break and give some ideas a while to regenerate in your head. After a few weeks of not touching Themis at all, I wrote a lot of documentation yesterday (and a few paragraphs today). I also recompiled it with the newest build of NHibernate, to allow you using with the newest fluent NHibernate. One more news is that Themis will be used in a production project. So far it brings profits but I’m ready to immerse into it if there any optimization/extension/refactorization will be needed.

Happy Themissing!

Themis wants you to hibernate her!

Recently, I’ve been working on project which in the near future will have a quite complex authorization rules. Additionally, these rules will affect the display, simply filtering data sets, which one can view. Instantly I thought about Themis and it’s ‘future feature’ allowing to integrate with NH. What I’d like to have is simple Themis’ role definition:

public class AnalystRoleDefinition : BaseRoleDefinition
{
    public AnalysRoleDefinition( )
    {
        // CanView - helper method introduced in the application, wrapping Themis': Add blah blah
        CanView<IProtectedDocument>((document, analyst)=> document.ProtectionLevel <= analyst.AllowedProtectionLevel);
    }
}

Ok… As I can see, each analyst is given permission to view protected documents ONLY when he/she has AllowedProtectionLevel greater than document. According to Themis’ functionality it’s simple to create a service configured this way and check, whether in the context of a specified document this permission is granted. But what about filtering? If the analyst is disallowed to view such a document, shouldn’t it be hidden?

NHibernate filters to the rescue

NHibernate filters can be used to add specific conditions to querying classes and their collections. Being given the role definition mentioned earlier I could add filter with an easy condition (the analyst property would be a parameter got from the context, the real condition is based on a document ProtectionLevel column) for each class implementing the IProtectedDocument and activate them with one call based on the context. My very first proposal for API would be:

var roles = _roleService.GetCurrentUserRoles();
using(var filter = _nhAuthorizationService.ApplySessionFilters(_session, roles)
{
    var q = _session.CreateQuery("from IProtectedDocument");
    // other query stuff
}

The filter wrapped in using is an applier of filters which uses ISession.EnableFilter during creation and ISession.DisableFilter to undo filtering. It leave the session in a untouched filtering state.

If you bothered with explicitness and you want something implicit, you can easily add this behavior to your DI and never thing about it again.

Any thoughts about it?