State driven security in LightSwitch (part 5): let the state dictate what you can update

Introduction

We have so far a decent way to protect state transitions and a comfortable client side implementation. Now, we will cover another important facet of state driven security: the ability to update entities based on the current state.

Why do we need some new base infrastructure for this?

It is tempting to think that we can use for this the standard LightSwitch Can_<CRUD> methods like the one here for update:

partial void HolidayRequests_CanUpdate(ref bool result)
{
}

What’s the problem? Well, … these set of methods is only suitable for course grained security. It can provide a go/no go for updating an entity as a whole, without referring to a particular row. Indeed, there is no current entity parameter in the above method.

Of course, we can still use these set of security methods, but not when it is about security related to the current state of an entity.

What do we need exactly?

We need a way to enforce that given a certain state (e.g. Approved) an entity (or any entity inside the object graph related to the entity monitored by the state property) can not be updated. Let’s extend our Validate method, with another one from our StateManagement class: the ValidateCanUpdateEntityGivenCurrentState method:

Basically, all props are entity are checked if there are changes. We have also the ability to excluded certain properties. Why do we need this? Well, in case you state field is present inside the entity you are checking for modifications, it should be possible to exclude this field from the modification check. Obviously, the “RowVersion” field should be excluded also.

For this reason it could make sense (and the ValidateCanUpdateEntityGivenCurrentState is ready for this) to store the state field in a dedicated entity which is bound as a 1 to 0..1 relationship to the entity on which the state is applied. By doing so, you can avoid the avoid the usage of the above ExcludeProperties.

The nice thing about the exclude properties is that they can be specified in a strongly typed manner (by means of a lambda expression).

We can also apply the same validation method the the entity attached to the HolidayRequest entity: