Permission Pattern

Most application code revolves around doing things – reading and writing data primarily. But a large portion is dedicated to the sole task of checking if you can do things. This is generally referred to as “business rules”. The logic of these rules is often subject to rapid change at request of the client, and it can get very complex. This makes it a prime nest for bugs, or worse yet, features masquerading as bugs.

In the real world, you might mentally check dozens of questions before you do something, and then other people might check as well. Lets say you want to go to a trendy new night club. A preliminary set of permission checks might include:

  1. Do you have money for the cover?
  2. Are you old enough?
  3. Are you carrying an ID?
  4. Are you dressed according to the dress code?
  5. Are you carrying any drugs, weapons or other forbidden items?

Now the establishement might have additional checks:

  1. Is the club letting in patrons at this time?
  2. Is the club filled to capacity?
  3. Are you on the guest list or with someone on the guest list?

Additional rules might supersede other rules:

  1. Are you a VIP? If so, you don’t need to pay the cover or get an ID check. Also you will be in a VIP room so you may enter even if the club is filled to capacity.

So as you can see, the process of checking if you can enter the club is much more complex than the action of walking through the door. The same is true of application logic. In fact, the explicit nature of coding would apply additional questions that you wouldn’t reasonably ask in the real world:

  1. Do you exist?
  2. Does the club exist?
  3. Are you a human?
  4. Are you alive?
  5. Have you already entered the club?

If there are multiple entrances to the club, you might have to relay these rules to several people, make sure they are notified if the rules change, make sure they stay in sync as global conditions change (like max capacity), and be sure they are enforcing the rules vigorously.

Suddenly a seemingly simple check has become a complex beast with a high probability of failure.

I developed the Permission Pattern primarily to encapsulate and organize rules, to increase code readability and continuity, as well as to improve security and data integrity.

Can You Dig It?

For every business action, create a method that answers whether that action is permitted.

In code speak, if you have a class with a method called DoSomething(), write a method called CanDoSomething() which returns true or false. Keep these methods paired so the pattern can be easily replicated.

No matter how complex the permission check gets, you can write it once and forget about it. From a readability perspective, the calling code practically reads like English. It’s that simple!

 vb.net |  copy code |? 
1
2
If Thing.CanDoSomething() Then Thing.DoSomething()
3

The key is to create both functions at the same time even if the permission check initially always returns true.

Tell Me Why

But what if you can’t do something? You’re normally going to want a reason why not, so you can decide how to proceed.

So now our permission function will return two values: a boolean and a string. To accomplish this, I’m going to pass in an optional reference string and modify it internally. In our generic example, let’s imagine the Thing class has a property called SomeRequiredData:

 vb.net |  copy code |? 
1
2
Public Function CanDoSomething(Optional ByRef ReasonWhyNot As String = "") As Boolean
3
            If Me.SomeRequiredData is Nothing Then
4
                ReasonWhyNot = "No Data was received."
5
                Return False
6
            End If
7
            Return True
8
        End Function
9

Notice the parameter is ByRef and not ByVal. It is critical that the parameter is a pointer to the original string and not a copy. By default in nearly all languages, strings are copied and not referenced when they are passed into methods.

Let’s also assume that our calling code has a Message function that displays a message to the user.

 vb.net |  copy code |? 
1
2
 
3
Dim ReasonWhyNot = ""
4
If Thing.CanDoSomething(ReasonWhyNot) Then 
5
   Thing.DoSomething()
6
   Message("Something was done.")
7
Else
8
   Message("Something was not done. " & ReasonWhyNot)
9

Now maybe this isn’t sitting well with you. It’s a bit unconventional and you might be wondering why it’s necessary to pass in an empty string rather than just making the string a return value. Or why not return a status code that references the messages somewhere else. Let’s examine those two options and see.

Alternate 1: Just return the string response

First off, a function with a prefix of Can or Is should return a boolean. So let’s also change the name to be more specific.

 vb.net |  copy code |? 
1
2
Public Function GetReasonYouCanNotDoSomething() As String
3
            If Me.SomeRequiredData is Nothing Then
4
                Return "No Data was received."
5
            End If
6
            Return ""
7
        End Function
8

 vb.net |  copy code |? 
1
2
Dim ReasonWhyNot as String = Thing.GetReasonYouCanNotDoSomething()
3
If Not String.IsNullOrEmpty(ReasonWhyNot) Then 
4
   Thing.DoSomething()
5
   Message("Something was done.")
6
Else
7
   Message("Something was not done. " & ReasonWhyNot)
8

See how awkward that is to read? In conversation, there is a two part dialog of asking if you can, then asking why not. You wouldn’t simply ask someone to provide a reason you can’t do something, then interpret their silence as permission! This brings me to a key point:

The more closely code resembles natural language, the easier it is to read, understand, and spot bugs

Alternate 2: Return a status code

Again, we’ll change the name to match the new purpose.

 vb.net |  copy code |? 
1
2
Public Function GetDoSomethingStatus() As Integer
3
            If Me.SomeRequiredData is Nothing Then
4
                Return Status.NoData // 2
5
            End If
6
            Return Status.CanDoSomething  // 1
7
        End Function
8

 vb.net |  copy code |? 
1
2
Dim Status as Integer = Thing.GetDoSomethingStatus()
3
If Status = Status.CanDoSomething Then 
4
   Thing.DoSomething()
5
   Message("Something was done.")
6
Else
7
   Message("Something was not done. " & Thing.GetStatusDescription(Status))
8

So in this case, the readability of the If statement is better than the previous example. The main drawback about this approach is that the calling code now has to be more knowledgeable of the class it calls. It has to know about status codes, what they mean, and how to convert them to a text response. A true or false response as to whether you can do something is about as clear as it gets. And there is another advantage to passing in a reference string.

Chaining

With even a small application, you’re rarely interacting with a single object that makes all the decisions. You generally have a web of interconnected objects that all communicate with each other. If you replicate the Permission pattern in several classes, the permission functions can call each other and pass the same reference string along.

Let’s assume there’s a global CurrentUser object with some permission rules. And let’s also assume that Thing contains modifies two child objects in DoSomething()

 vb.net |  copy code |? 
01
02
Public Function CanDoSomething(Optional ByRef ReasonWhyNot As String = "") As Boolean
03
            If Not CurrentUser.CanModifyThing(ReasonWhyNot)
04
                Return False
05
            End If
06
            If Not Me.ChildObject.CanBeModified(ReasonWhyNot) Then
07
                Return False
08
            End If
09
            Return Me.AnotherChildObject.CanBeModified(ReasonWhyNot)
10
        End Function
11

What’s nice is that even as your logic grows more complex, the calling code stays the same. The ReasonWhyNot string can get passed around to different objects and update accordingly. Conversely, the status code approach would have needed to grow to accommodate the various codes, and each class would be required to know more about the other classes.

Internal Enforcement

What if you don’t check if you can do something before you do it? In the night club scenario, you could get away with it, or get thrown out on your head. Either way, it’s a bad idea and likely to cause trouble.

Even though you will probably write your calling code and your class interface at the same time, defensive programming dictates you should write your class with the assumption that the calling code will misuse it. Here’s how to add some security to DoSomething()

 vb.net |  copy code |? 
1
2
public sub DoSomething()
3
  Dim ReasonWhyNot = ""
4
  If Not CanDoSomething(ReasonWhyNot) Then 
5
    throw Exception("Thing.CanDoSomething = false " & ReasonWhyNot)
6
  End If
7
 //execute code here
8
end sub
9

Now you’ve added an extra layer of security, you’ve possibly prevented some data corruption, and you have a user friendly error message in your exception.

The cost is that now the CanDoSomething check is being called twice. There might be cases where that check is resource intensive, testing dozens of other classes and you don’t want the performance hit of redundant calls. Now you could store the results of CanDoSomething() internally the first time and just return it the second time, but this is risky if you are checking external factors that are subject to change.

Try Something

One way around this is to modify the calling code. Rather than calling CanDoSomething() followed by DoSomething(), you could simply wrap DoSomething() in a Try/Catch block and use the exception message as your response.

 vb.net |  copy code |? 
1
2
Try
3
   Thing.DoSomething()
4
   Message("Something was done.")
5
Catch ex
6
   Message("Something was not done. " & ex.Message)
7
End
8

This approach should be used very judiciously because it will catch all exceptions including any cases you might have missed in CanDoSomething(). This could have the unwanted effect of preventing deeper exceptions that would stop code execution, as well as possibly exposing exception messages that are either not user friendly or leak secure application information if you choose to display the exception message to the user.

User Interface

It’s a much better user experience to prevent an action before it’s ever attempted. Using the Permission Pattern, we can easily toggle a button and display the reason why not as the title of a disabled button. The caveat is that the Thing object must exist and have all necessary data required to make the check at the time the page is displayed. So it works better for role and status checks than input validation, which is kind of a separate process than the privilege check.

 ASP |  copy code |? 
1
2
<% Dim ReasonWhyNot = ""
3
  If Thing.CanDoSomething(ReasonWhyNot) Then %>
4
     <button title="Click to do something" onClick="Thing.DoSomething()" />
5
  <% Else %>
6
     <button disabled title="<%= ReasonWhyNot %>" />
7
  <% End If %>
8

With all these features in place, you are now checking privileges with the same logic and displaying the same messages in the user interface, the calling code, and within the class itself. It’s easy to read and keeps the logic hidden away where it belongs.

Multiple Permission Denial Message at Once

It’s often better for the user if you can give all the reasons an action is denied at once. Imagine once again that there are several reasons you can’t enter our trendy night club.

  1. You don’t adhere to the dress code (input validation)
  2. The night club is full except for VIP’s (business rule)
  3. You are not a VIP (role-based access)

Now you would be pretty upset if you were only given the first reason, went home, changed your clothes, came back, waited in line, then got the second reason! You would much prefer to get all the information at once, so you could make a more informed decision and not waste time. In this case you could modify the pattern to pass either a list or dictionary object instead of a string. You would also need to rewrite the permission functions to not return early if a reason is discovered. This has to be handled on a case by case basis depending on your specific needs.

Real World Example

I was working on a file uploader when I truly evaluated and solidified this pattern. File uploading in general requires checks against missing data, file size, valid name, valid extension, and for extra security, valid mime type. With the file size requirement, I wanted to provide a custom response with the size of your file and the max size.

 vb.net |  copy code |? 
01
02
Public Function CanUploadFile(Optional ByRef ReasonWhyNot As String = "") As Boolean
03
 
04
            If MFileData Is Nothing Then
05
                ReasonWhyNot = "No File Data was received."
06
                Return False
07
            End If
08
 
09
            Dim fileSize = FileData.Length
10
 
11
            If fileSize > MAX_FILE_BYTE_SIZE Then
12
                Dim fileMegs = Math.Round(fileSize / 1000000, 2)
13
                Dim maxMegs = Math.Round(MAX_FILE_BYTE_SIZE / 1000000, 2)
14
                ReasonWhyNot = String.Format("The file size is {0} MB and exceeds the max size of {1} MB.", fileSize, maxMegs)
15
                Return False
16
            End If
17
 
18
            If Not ExtensionIsValid Then
19
                ReasonWhyNot = String.Format("{0} is not a valid file type. Only the following file types are accepted: {1}", Extension, String.Join(",", BusUserFile.VALID_EXTENSIONS))
20
                Return False
21
            End If
22
 
23
 
24
            Return True
25
        End Function
26
 
27
 
28

Summary

The main objective of this pattern is to simplify complex rules. All too often I’ve seen permission checks begin at the beginning of a post action, and continue to grow into monstrosities as rules get more complex. These monstrosities then replicate with new pages. If you simply get into the habit of creating a CanDo() function right above your Do() function, you will keep permission checks simple, keep your classes loosely coupled and your business logic modular and flexible. Simple code also means less bugs, and in this case that means greater security as well. That’s all for now. Happy coding and I’ll see you in the VIP section.

Posted in asp.net, object oriented programming, The Good | 3 Comments

TheToothPlace.com launches!

The Tooth Place

Mindstorm is proud to announce the official launch of www.thetoothplace.com.

Since 1978, The Tooth Place has been brightening smiles in Severna Park, MD. That’s a really long time so these people clearly know what they’re doing. Go get your teeth cleaned.

We are very happy with the final result and send many thanks to the good people at the Tooth Place for putting choosing us to help bring their vision to light. It was a fun project and seeing it launch put a smile on our face.

Posted in press release | Leave a comment

.NET Extension Methods

Dear loyal readers (all 3 of you),

Thank you for your patience. This is my first blog since the birth of my first child. The balance of work/life tipped in the direction of life for a while, and I’ve been playing catch up ever since. Sorry to keep you waiting for me to bestow my wisdom upon
you. So without further adieu, let’s get started.

Today we’re going to introduce .NET Extension Methods, briefly explain what they are and how they work, and discuss the advantages, potential pitfalls and best practices for this feature.

What are extension methods?

It’s not easy to describe, but you could say extension methods are functions that are written outside of the original class file. They attach themselves to the class during compilation so you can add your own custom functions or override built in functions of framework classes that were previously closed off to alteration. If you are coming from a dynamic language background, this is similar to prototype methods.

Here an example in VB.NET. It returns the fiscal year of a datetime object. This is a domain specific method. In the government, the fiscal year is shifted by 3 months, beginning on October 1st and ending September 30th. Other businesses might have a different fiscal year. Note: DateTime.AddMonths() returns a new DateTime without altering the original.

Example of Extension Method

 vb.net |  copy code |? 
01
02
 
03
Imports System.Runtime.CompilerServices
04
 
05
Public Module DateTimeExtensions
06
 
07
   <Extension()>
08
   Public Function FiscalYear(ByVal dateTime As DateTime) As Integer   
09
      Return dateTime.AddMonths(3).Year
10
   End Function
11
 
12
End Module
13

In an extension method, the first parameter is the class being extended. The method is invoked like any other function of that class. So you would call this function like this:

 vb.net |  copy code |? 
1
2
Dim dt as New DateTime('2011-10-15')
3
Dim fy = dt.FiscalYear() 'returns 2012 
4

Alternates

Before discussing deeper methodology, lets look at a few examples of alternate patterns and briefly list their advantages and disadvantages.

Inherited Class

A custom class that extends a framework class and exposes extended methods:

 vb.net |  copy code |? 
01
02
Public Class GovDateTime Extends DateTime
03
 
04
   Public Function FiscalYear() As Integer
05
      Return AddMonths(3).Year
06
   End Function
07
 
08
End Module
09
 
10
Dim dt as New DateTime('2011-10-15')
11
Dim gdt As GovDateTime = Ctype(dt, GovDateTime)
12
Dim fy = gdt.FiscalYear() 'returns 2012 
13
 
14

Advantages:
Clearly a domain specific class.

Disadvantages:
Not discoverable. Requires casting to work with existing DateTime objects. Will throw an exception if object is null.

Wrapper Class

A custom class that contains a framework class and exposes extended methods:

 vb.net |  copy code |? 
01
02
Public Class GovDateTime
03
 
04
   Private _DateTime As DateTime
05
 
06
   Public Sub New(Byval dt as DateTime)
07
       _DateTime = dt
08
   End Sub
09
 
10
   Public Function FiscalYear() As Integer
11
      Return _DateTime.AddMonths(3).Year
12
   End Function
13
 
14
End Module
15
 
16
Dim dt as New DateTime('2011-10-15')
17
Dim gdt As New GovDateTime(dt)
18
Dim fy = gdt.FiscalYear() 'returns 2012 
19
 
20

Advantages:
Clearly a domain specific class. Can limit access to just the functions you want. Can safely handle nulls.

Disadvantages:
Not discoverable. More difficult to refactor since you are no longer working directly with the framework class.

Helper Class

A static (or shared) class that applies the extended logic to other classes:

 vb.net |  copy code |? 
01
02
Public Class DateTimeHelper
03
 
04
   Public Shared Function FiscalYear(ByVal dateTime As DateTime) As Integer
05
      Return dateTime.AddMonths(3).Year
06
   End Function
07
 
08
End Module
09
 
10
Dim dt as New DateTime('2011-10-15')
11
Dim fy = DateTimeHelper.FiscalYear(dt) 'returns 2012 
12

Advantages:
Clearly a domain specific class. No casting required.

Disadvantages:
Not discoverable. Reverses the natural syntax of noun then verb. (think dog.IsRunning vs. DogHelper.IsRunning(dog))

The Inline Approach

Just smack the logic inline wherever you need it. Probably the most popular method for microfunctions:

 vb.net |  copy code |? 
1
2
Dim dt as New DateTime('2011-10-15')
3
Dim fy = dt.AddMonths(3).Year
4

Advantages:
No discoverability required – nothing to discover.

Disadvantages:
Logic is decentralized and duplicated. Code becomes more complex to read and harder to maintain if logic changes. Pretty much violates every rule of object oriented programming.

Advantages of Extension Methods

Discoverability

If you didn’t already know, discoverability refers to the ability to find code while you’re writing code. This method shows up with intellisense when working with basic framework classes. In order to use a custom class, a developer would first have to know (and remember) that a custom class exists and know where to find it. With larger project it often becomes faster to duplicate logic than to search for it in your code base.

Readability

When compared to the other examples, the implementation of the extension method reads the most naturally. This is possibly even more pronounced when overriding built-in methods like ToString(), which often returns useless values like ‘[Object Classname]’.

Safety with null objects

If you call a method on a null object, you get a null object reference exception. This is probably one of the most common exceptions in code, and can be difficult to track down because it’s so generic.

So dt.Year will throw an exception if dt is null.

But dt.FiscalYear() actually calls FiscalYear(dt) behind the scenes. So, if we put a null check in our function, we can call this function with a safe default response in case of nulls.

 vb.net |  copy code |? 
1
2
   <Extension()>;
3
   Public Function FiscalYear(ByVal dateTime As DateTime) As Integer
4
      'check for null and return a "safe" value, the current fiscal year for example.
5
      If dateTime is Nothing then return DateTime.Now.AddMonths(3).Year
6
      Return dateTime.AddMonths(3).Year
7
   End Function
8

This function is probably not the best example, but the point is that you have control over how to handle nulls. You could just not check for nulls if you want the exception, or you can return a “safe” value.

Easier separation in n-Tier applications (huh?)

I could write a whole post on this point alone, but suffice it to say, keeping pure separation between your presentation, business and data layers is nearly impossible or requires some sacrifice in organization. A common example would be a function that outputs html for a web app. You don’t want to include that in a business or data class. But you can write an extension in your web layer to ensure good layer separation.

Lightweight

Oftentimes you only need a single extension method. Adding an extra class, a new file, and custom code is a lot more burdensome than making one method.

Potential Pitfalls

I elect not to call this section “disadvantages” because the potential harm comes more from bad practices and programmer misunderstanding rather than the feature itself.

Confusion with Original Framework

We had an extension method html.Image(filename) which added (without duplicating) the path to the images folder in our app. Not a bad method. Keeps markup concise and centralizes a folder path so it can easily change. I realized there was a problem when a new developer claimed to now know how to include images in MVC. They would be very confused if they copied that code to a different project!

While you could put the responsibility on new developers to learn the feature, we live in the real world where people copy and paste code blindly. Hiding custom code within what appears to be framework can not only cause confusion, especially if extension methods behave differently than framework methods.

Our workaround for that project was to make extensions that returned a domain specific wrapper class for the extension methods. So the code became html.OurProject.Image(filename). Still discoverable but more explicitly a domain object.

Higher Potential for Class Collision

If two extension methods have the same name, you will have a collision issue. This can happen as coders carry around their bag of tricks to different project and tend to use common names and add extension methods to primative classes. An easy workaround is to place a namespace around your extensions, but when you do that you lose intellisense discoverability unless that namespace is included.

Promotes bad habits due to safety with nulls

It’s good practice to check if an object is null before accessing any method. “Swallowing” exceptions is rarely the right thing to do. What can seem like it’s making your code safer may actually be creating hidden bugs. You have to be extremely cautious when checking for null. I prefer function names like ValueOrDefault() or ValueOrNothing() to show that I’m handling nulls internally.

Overuse can cause “Language Spam”

Coders have a tendency to write just enough code to get done what they need at the time without much consideration to class design. Framework classes, by comparison, have been meticulously thought out, reviewed, and fine-tuned over years. It’s very likely the framework already provides a method that could be used in place of the one you’re writing, possibly several. The sheer vastness of the framework can make things hard to find.

Adding hundreds of extension methods to a single class is probably not a good idea. But patterns are repeated and code is copied, so it’s easy for this to happen. To avoid this, ask if your extension method needs to be easily discovered. Also consider what will happen if it’s accidentally discovered. Will it cause confusion?

Altering Framework Conventions

Significantly altering a function signature by using a new convention makes your method more difficult to work with. Try to make your methods mirror the framework as closely as possible. Generic names should be reserved for functions that work seamlessly with the framework. Use Domain specific names for domain specific functions. Even though my FiscalYear implementation was specific to the government, the concept of a FiscalYear is general, so if the code was imported into a business with a different fiscal year, you would just have to change how the method works rather than the entire code base (as in the inline approach).

Breaking Class Design

Also, classes modeled after real-world objects lose their meaning if you add methods that break the metaphor. For instance Employee.ToByteArray() doesn’t make any sense. If you’re not careful, you can add so many specific functions that you’ve virtually changed the definition of the class.

Summary

In the long standing debate between static and dynamic languages, most experts will agree that the “perfect” language would lie somewhere in the middle, combining the flexibility of dynamic languages with the integrity of static. In the static realm of C# and VB, language extensions take a step toward the middle, allowing access to modify previously immutable classes. If implemented judiciously and well understood by all members of a development team, it can be a very powerful tool in your bag of tricks. Consideration for novice developers should be make, but that doesn’t mean avoiding advanced techniques. You just need to use them safely, hide away as much as possible and educate team members on your practices. Your project doesn’t need to be a training ground for novices, but it shouldn’t be a proving ground either.

Posted in asp.net | 4 Comments