Wednesday, March 31, 2010

Unit Testing Role Based Security w/ ASP.Net MVC

I recently started working on a little project management demo project in ASP.Net MVC. As part of that I wanted to make sure I unit tested as much as possible so that it could act as a good example of how to do things for other people in the future.

I ran into a bit of a snag when trying to verify that the right security roles are required on my actions. I found out from a few blog posts that ASP.Net follows the .Net 2.0 membership and role provider model, and that you can simple decorate a controller or action with [Authorized] attributes to restrict access. Pretty cool and really simple unfortunately not very testable. When you unit test actions in MVC you call the method directly from the test, bypassing the routing engine where these authorization checks are made.

Fortunately I found Paul Brown's excellent post on how to test that you have applied the right roles. I liked what he did but it was a bit to case specific for me so I made it a bit more generic. Here's what I came up with:

I took Paul's code and turned it into a series of three controller extension methods which verify if the entire controller requires authorization, a particular method requires authorization or if a particular method requires a given role (i have not yet written the obvious 4th case - an entire controller requires a given role but it should be trivial.)
public static class ControllerExtensions 
{
     public static bool RequiresAuthorization(this Controller controller)
     {
           MemberInfo memberInfo = controller.GetType();
           var attributes = memberInfo.GetCustomAttributes(typeof(AuthorizeAttribute), true);              
           return attributes != null && attributes.Length == 1;
     }
     
     public static bool ActionRequiresAuthorization<T>(this Controller controller, Expression<Action<T>> expression)
     {
           var member = expression.Body as MethodCallExpression;
           if (member != null)
           {
                 var methodInfo = member.Method;
                 if (methodInfo != null)
                 {
                       var attributes = methodInfo.GetCustomAttributes(typeof(AuthorizeAttribute), true);
                       return attributes != null && attributes.Length == 1;
                 }
           }
           return false;
      }
 
      public static bool ActionRequiresRole<T>(this Controller controller, Expression<Action<T>> expression, string role)
      {
            var member = expression.Body as MethodCallExpression;
            if (member != null)
            {
                 var methodInfo = member.Method;
                 if (methodInfo != null)
                 {
                       var attributes = methodInfo.GetCustomAttributes(typeof(AuthorizeAttribute), true);
                       var authorizeAttribute = (AuthorizeAttribute)attributes[0];
                       return authorizeAttribute.Roles.Contains(role);
                 }
            }
            return false;
       }
}


Here is an example test for Requires Authorization: (using NUnit)
[Test]
public void Should_require_authorized_user_for_all_actions()
{
     var controller = new ProjectController(null);             
     Assert.That(controller.RequiresAuthorization());
}


And a sample for ActionRequiresRole
[Test]
public void Should_require_admin_to_add_a_bug()
{
     var controller = new BugController(null);
     Assert.That(controller.ActionRequiresRole<BugController>(x=>x.Add(), "Admin"));       
}



EDIT: John suggested changing the extension methods into lambda actions so that they would be strongly typed. I agreed so this has been updated accordingly.

Friday, March 19, 2010

Forcing Visual Studio to run as an Administrator

This superuser post explains how you can force visual studio (or any application) run as an administrator. This is helpful for Windows Vista and Win7 users who have issues with IIS when running Visual Studio as a non-admin.

http://superuser.com/questions/23462/how-to-always-launch-vs-net-as-administrator

Just in case the link dies here's the answer:

To ensure visual studio and any file opened w/ visual studio (i.e. double clicking on a solution file) always opens VS as an admin (from Vdex):


Got to the actual deven.exe in "C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\", right click on devenv.exe, properties, compatibility and tick "run as administrator"


To set a particular shortcut to always open as an administrator (From Jared Harley):



  • Right-click on the shortcut (this works even in the Start Menu)

  • Select "Properties"

  • Select the "Compatibility" tab

  • Click the "Change settings for all users" button at the bottom

  • Enter the administrative username/password

  • In the new window, select "Run this program as an administrator"

  • Click OK

  • Click OK


Wednesday, March 10, 2010

Making the Switch: VMWare vs Parallels

A few years back when I first make the switch from Windows XP to OSX 10.4 (at the time) as my default platform of choice I knew there would be a few challenges. Mainly I knew that being a .NET developer there were a number of applications I really needed to run that didn't exist on the OSX side of the equation, specifically the Microsoft Development Stack.

At the time that Apple switched from the PowerPC platform to Intel a competition sprung up to see who could be the first person to get a copy of Windows running on Apple hardware. Eventually a bunch of hackers solved that problem. Shortly thereafter Apple released Boot Camp, it's semi-official (Beta) take on running windows on a Mac. Then Parallels threw their hat in the ring with a virtualization product that in no simple terms kicked ass. Finally a few months later veteran virtualization powerhouse VMWare brought out VMWare Fusion to compete with Parallels.

Today the offerings from VMWare and Parallels are very similar. They both offer Windows 7 support, a coherance / unity mode which breaks windows applications out of the windows desktop and several other bells and whistles you would expect from a fully featured product designed to help switchers.

One of the questions I get asked frequently by people looking to switch is which one do I recommend. The truth is I recommend both but I use VMWare Fusion.

Ultimately there were two reasons, at the time, that I chose Fusion:

1) At the time (and still now I believe) it managed RAM better than Parallels.

Specifically it didn't pre-allocate all of your allotted memory up front. What that means is when you set up a virtual machine you tell it how much system memory it can use. On my 4GB machine i allocate 2G to my VM.With Parallels when you allocated 2 gigs the virtual OS takes all 2 gigs up front and then the virtual OS manages it. Basically its like your running 2 machines and each has 2 gigs of ram.With VMWare if you allocate 2gigs it will give the virtual OS as much memory as it needs at any given point in time UP TO 2gb. After that it begins swapping to disc like any normal OS would. So if your not doing much in your VM OSX could retain 3gigs to use as it sees fit up until your VM needs that extra gig.

This comes in handy when your doing a simple windows task like testing an application in IE or opening word to work on a document. Usually windows wont need all of the memory you give over to it leaving iTunes and all your OSX apps free to eat up that space.

2) I work for a company who uses VMWare in our server infrastructure. We run VMWare ESX servers which means we have a number of VMWare formatted VMs. Fusion is able to open and run many of these VMs which makes life easier if I want to copy over an image of a particular server setup. Really this is the reason I broke out the credit card one day and bought Fusion. But if i were starting from scratch all over again I would go with Fusion from the get go because of number 1.

That's pretty much it, in every other way the two products are competitive and to be honest I'm not even sure if number 1 is relevant anymore (by all means if its not please leave a comment.)

It's worth noting there is a third option, Sun's VirtualBox, which I have not personally tried. I have heard good reviews but I've also head it lags behind the commercial products in feature set so if you can buy one of the commercial ones you should.

Making the Switch: Intro

Three years ago I bought a Macbook Pro for my own personal use. I envied OSX's BSD based core and seemingly fluid UI for quite a while. At the time I spent most of my time outside of my day job working on PHP projects and while PHP works well on windows I always had a disconnect when I inevitably uploaded my projects to a Linux based server.

Secondly while the notion of toying around with hardware, drivers, operating systems, debugging issues and keeping my machine clean of viruses, spyware and other nefarious applications was something I didn't mind and even secretly enjoyed in high school or college I seemed to have grown past those days. Every little configuration issue or accidental bad download on Windows cost me time I didn't care to spend anymore. I'm not nieve enough to think OSX is free of problems but the relativley tech savvy people I knew who had made the switch swore by it in terms of increased productivity.

It was for these reasons that one day I went on eBay, found a first generation Macbook Pro and took the plunge. Through the help of some friends I figured out how to adapt to the subtle differences between Windows and OSX and now three years later I'm on my second macbook pro and even switched my wife over to the platform a little over a year ago.

So, what is the point of all of this? Why am i recanting my love for all things Apple to you dear reader? Well this post is meant to serve as an introduction to a series of posts I intend on writing on what it's like to be a programmer, specifically a .NET programmer, who spends most of his time in OSX. I'm going to go over the tools I use (like why I chose VMWare Fusion over Parallels) some tricks I've picked up and anything else that comes to mind. First off thanks to John Miller for the idea for this series. I had a bit of writer's block this morning and he proposed I write it given his current situation of anxiously awaiting the release of the next round of macbook pros.

Monday, March 1, 2010

Intro to Agile (Part 2)

In the last post i went over the first half of my presentation on agile software development. We talked about the purpose of agile and how, at a fundamental level, it's all about the way you think and not the things you do. That post was WAY more important than this one so if you're starting from scratch in agile I highly recommend reading that first.

Today I'm going to cover the various tools, practices and patterns people apply to try and be an effective agile team.

Agile Project Management


There are three overarching project management techniques that are applied to agile projects. They differ in their implementation but all focus on the same concept of continuous feedback and close collaboration. They are:

1) eXtreme Programming (or XP) - This was the first technique I heard of and in some ways it is the "strictest" of the agile methodologies. In focuses on short development iterations (or sprints), a series of planning meetings throughout the process and sound development practices like test driven development and paired programming.

2) Scrum - Scrum is an incredibly popular technique among enterprise agile implementations. It is very similar to XP in day to day implementation but also covers the scenario where a product is being developed by a large team and how you would go about managing that. Specifically scrum speaks about breaking large teams into smaller scrums then developing some sort of process (called a scrum-up) where the smaller teams report to a higher organization to share information. Development practices are more left to the individual implementations to decide but TDD is generally encouraged in all of the agile implementations.

3) Kanban - I perceive Kanban to be one of the newest options but it is getting a lot of traction. It emphasizes a continuous flow of new functionality with intermittent triggered events that might bring about planning meetings or retrospectives. It is heavily focused on pulling story cards through the process represented by a Kanban board the team views the project status from.

Which of these options you choose is up to you and your business. For the type of project work we do at my company Kanban seems like the best fit, but I have worked for in house IT departments where Scrum or XP was perfect. As with most things in agile the key is being flexible.

Storycarding


One of the common practices that occurs in any of the methodologies listed above is storycarding. Put simply storycarding is the act of breaking up an applications requirements in to small chunks and framing the description of that requirement from the perspective of the intended end user. Put even more simply its turning your product into a series of small stories.

With storycarding we have a few rules:


  1. Each card should tell a story about how a user will interact with the system

  2. A card should have some business value

  3. Each story should have as little complexity as possible

  4. Stories should consist of as little detail as possible


Numbers 1 and 2 above leave us with a problem. If every story has to be about the user and they all have to have concrete BUSINESS value how do we account for tasks that are purely IT driven, like "Setup infrastructure" or "Upgrade to .NET 4.0?" As with most things in our profession the answer is "it depends." Purists would say that those tasks need to be taken inline with some other business focused task that drives them. For example your very first story could be used as a catalyst for "setup infrastructure" because without that infrastructure that first story can never be released and thus is never complete. Some more practical teams opt to put in technical story cards and negotiate with the business time and prioritization of those tasks. Ultimately this is up to the team.

Numbers 3 and 4 go hand in hand as well. We want out stories to have little complexity so that they are each to test, complete and assign. We don't want to have stories that take weeks to finish and we don't want a lot of overhead in order to get started on one.

The reason why we favor less detail in a story is to encourage conversation and collaboration. The more we put in writing in advance of the work beginning the more likely it is that we will need to change the details later on, most likely after the card has already been completed as written. Instead a storycard is treated as an "invitation to have a conversation" with our business partner.

Managing Work-flow


So knowing how agile teams usually generate application requirements is one thing, but what do you do with all those story cards?

This is an area where the different agile approaches differ. XP and Scrum are generally in line so we'll talk about their approach first.

XP and Scrum focus on working in short sprints (also called iterations.) In this system work is typically done in 2 week spurts of activity (although the actual amount of time varies by team.) Each sprint follows a cycle that consists of a sprint planning meeting, a period of work and collaboration with the business followed by a retrospective, then the whole process starts again.

Sprint Planning Meeting


A sprint planning meeting is a time period where the team evaluates how they are doing so far (retrospective) and plans out storycards for the next sprint. Typically the business will assign priorities to cards and the cards will be scheduled for the sprint in priority order. Exceptions to the priority order rule occur when one card is dependent on another or the business, having seen the progress the team is making, decided to re-prioritize a card during the SPM.

The actual process associated with an SPM varies by team but in general it begins with a retrospective on the previous sprint. It then involves someone reviewing what tasks in the previous sprint were finished and which ones need to be rescheduled, potentially into the upcoming sprint. Some teams then opt to do a live demo of the currently in development system. Finally the business works with the team leadership to prioritize the remaining cards and schedule them into the sprint. XP uses the concept of "yesterday's weather" when determining how many stories make it into a sprint. Basically this means that however much work was accomplished in the previous sprint if the amount of work you anticipate for the next sprint. Any remaining stories are placed in a buffer to be picked up in priority order if all of the scheduled tasks are completed.

Release Planning Meetings


Scrum and XP also have a concept of a release planning meeting or RPM. An RPM occurs in advance of the kickoff of the project as a whole and is used to plan out how the major areas of functionality will occur throughout the course of the project. The estimations and schedules that come out of an RPM are really fuzzy but they give the team an roadmap of sorts as they progress throughout the project. Some teams will create storycards in advance for the first few sprints and pre-schedule those cards in the RPM. This process works well enough so long as the result is seen as flexible. Those schedules will change as you learn more.

The Kanban Approach


Kanban takes a different approach from Scrum and XP. Instead of having prescheduled meetings and working in short sprints Kanban focuses on a continuous pull of new functionality into the system. Reviews, retrospectives, demos and planning sessions still occur but they are triggered instead of scheduled.

A storycard in Kanban begins prioritized and ready to be worked on. Team members pull cards from the ready bucket into the development bucket, as they are finished they move to QA, staging and deployment (or any number of other buckets depending on the team.) New cards are planned when the ready bucket gets low. What "low" means is up to the team. For one team they might decide that when there are only 4 stories pending they need to sit down with the business and plan out more stories. For another team that number might be 20. The same applies for demos or retrospectives. One team I saw triggered a formal retrospective when enough post-it notes were left by team members on a "retrospective" board. So as team members saw good, bad  and ugly things happen they would leave notes on the board (anonymously if they choose) and when a certain number were there they would all sit down and review them.

The key thing to note here is that Kanban really doesn't "stop." There is no break to plan an IPM and then restart work. Team members keep building for as long as there is work to be done.

The Daily Standup


The final meeting that seems to be consistent across Scrum, XP and Kanban is a daily standup. A standup meeting is a short meeting held daily where all of the development team members and sometimes testing and business will get together to go over the current state of the project. In general everyone in the team should be able to answer three questions.


  1. What did I do yesterday?

  2. What am I doing today?

  3. Do I have any roadblocks?


Should a team member encounter any problems the team should match people up to overcome those obstacles and move on. In general an ideal stand up is no more than 15-20 mins long.

Sprint 0


There's a lot of debate as to what an Agile team can do in advance of a project. The notion of pre-planning and pre-work has come to be referred to as "sprint 0." Generally the point of Agile is to adapt as time goes on and to not make decisions well in advance of when they need to be made. The notion of a period of pre-planning and decision making seems to fly against the goals of an agile team, but practically there will always be a number of tasks that must occur before the project can get rolling.

The rule of thumb for Sprint 0 is to not do any work or make any commitment to a course of action that could change based on the businesses requirements. If a task is aligned with the requirements of the project it should be accounted for in a storycard and prioritized into the project.

There are a number of activities that do make sense though. You can identify team members, stakeholders and set expectations for the project. In most situations you can decide on an overarching technology, for example if you tend to be a .NET shop you might choose between webforms or ASP.NET MVC. Finally you might identify the very large functional areas you want to hit on for this project, i.e. you might say "we are working on a billing and inventory management application that ties into our enterprise ERP system."

Wrap Up


So that's the majority of the content from my presentation on agile to my coworkers. The Slides have a bit more information if interested.

In my general experience agile is a concept worth learning about. The teams I have been on have had higher quality products, more tightly knit relationships within the teams and have ultimately delivered a result that the business was very happy with. Agile may not work in every environment but if you can make it work in your organization I would recommend giving it a try.