Wednesday, November 28, 2007

Constraints & Good Design

The best of artists hath no thought to show, which the rough stone in its superfluous shell, doth not include; to break the marble spell, is all the hand that serves the brain can do. —Michelangelo

A well-designed application does not include artificial constructs to model business processes; it simply models what is there.

If we use solid development practices, this tends to happen naturally. If, instead, we immediately adopt crutches in our design process, we begin to heavily rely on artificial constructs and our users may even become convinced that what we have given them is "the way it is".

Consider the case of a project management web application. A given user with a couple of projects going in the application calls for support. What information does the support person ask for in order to identify the customer? Let's imagine two scenarios. The first is an application where "the DBA" uses auto-incrementing integral surrogate primary keys for everything. The second is a scenario where natural keys are used as much as possible.

Both Scenarios
Tech Support: Hello, thanks for calling XYZ Support, can I help you?
Customer: Hi there, yeah, I am having problems accessing one of my projects.
Tech Support: I can help with that. I just need to get some information first.

Scenario #1: Surrogate Keys
Tech Support: What's your customer ID?
Customer: Eh, wha-? I don't know, where do I get that?
Tech Support: Don't worry, I can look it up for you. What's your name?

Scenario #2: Natural Keys
Tech Support: May I have your name please?

Customer: John Public
Tech Support: Thank you Mr. Public, could you confirm your billing address?
Customer: 100 W Main St., Smithville, Oregon
Tech Support: Thank you sir. For security purposes, please confirm the last four digits of your social security number.
Customer: 9999
Tech Support: Thank you Mr. Public. Now, which project are you having trouble accessing?
Customer: My "foo for bar" project. I can't even get into it.

Scenario #1: Surrogate Key
Tech Support: Mr. Public, I see you have several "foo for bar" projects here.
Customer: yeah, I was going to try and start over, I guess, but I don't want to do all that work again. Can you help me get into my old one?
Tech Support: Yes, sir, what is the project ID?
Customer: I'm sorry, the project ID? It's "foo for bar".
Tech Support: No, sir, I mean what is the numeric ID of the project?
Customer: I-uh-where do I get that?
Tech Support: It's okay sir, let me see if I can figure out which one you want.

Scenario #2: Natural Keys
Tech Support: Mr. Public, I see you have a few "foo for bar" projects here. There's "foo for bar", "foo for bar 2", and "foo for bar 3".
Customer: Yeah, I was going to start over, I guess. I want my original one, just "foo for bar".
Tech Support: Okay, sir, I can help you with that.

What happened here? In scenario #1, we lazily just used numeric Ids all over the place. Our tech support staff thinks in those terms now, and our customer feels less than valued and perhaps a little stupid. In scenario #2, we used the natural key of customer identfier + project title as the primary key and our application reflects that. Customers cannot create duplicate projects with the same name; tech support staff cannot just reduce people and their work to numbers; and the application accurately models the real world processes it is designed to support without artificially introducing ids.

Make your software support your users, not vice versa.

Saturday, November 17, 2007

Front-to-Back Security Framework

I've had a bit of wine this evening, so if this post seems to ramble, you know why. Also, please permit me the novelty of thinking aloud in this blogpost. Generally, I reserve this blog as a sort of lab notes area, but this time my discussion is not a direct product of my work. Instead, I'm trying to connect some things in my head that may not have a natural connection, but I think they do.

Most web frameworks will list security among the tenets of their design. Lift will talk about precluding XSS vulnerabilities, ASP.NET will mention its MAC validation of viewstate, and, honestly, I don't have any other examples at hand. But, I think it should be self-evident that web frameworks think about security.

...their security, the security of the platform, the bumpers in the gutter of web security bowling lanes are what they tout. But, dear reader, what have they offered in the way of a framework for application security? Most of us, rightly, assume that our platform is secure against exploits out of our control. Further, we appreciate those features that force us to fall into the pit of success as concerns security or naively rail against the nominal complications imposed by those features. What I have never heard anyone talk about is application security.

In line-of-business applications, the security conversation isn't about XSS or buffer overruns or SQL Injection or phishing. For those of us that build custom LOB applications, the conversation is about:

  • sales people walking away with lists of customers,

  • call center employees stealing credit card information,

  • preventing users from making expensive mistakes,

  • protecting the identity of patients, customers, or abuse victims.

In short, the LOB application developer, be she working for a government human welfare agency or a gypsum supplier, is less concerned about external hackers and more concerned about internal security. This is as it should be, as it must be. Most LOB developers don't have the capacity to evaluate the security of a web framework as a platform, and the threats they are being paid to guard against aren't from the outside.

Where is the web framework that makes securing the individual fields that compose a record easy? Where is the framework that makes it transparent for a certain user to be able to view columns A, B, and C without being able to edit them, while being able to view and edit columns D, and providing a full audit record of all of these actions? Where is the framework that makes it easy to prevent user's from expensing dinners over $80 without management approval? Why doesn't this framework then apply the same rules at the domain model level as well as giving us full support at the UI level?

Obviously, this is a rhetorical question, because someone has most certainly dealt with this in some non-mainstream framework. The answer, I believe, lies partially in the impedance mismatch found between the tiers of a traditional web application. It also something to do with a lack of security primitives in most platforms, I believe. Let's first look at the impedance mismatch problem, and ask if there are new technologies that could help up us close this gap.

Many of us have developed some sort of custom framework for dealing with security. However, as do most attempts at creating "security" whole cloth, it invariably has serious flaws. The problem lies in the seemingly simple question: where do we put the security rules? If we put the rules in the database, we will create triggers, constraints, stored procedures, schemas, etc. in order to enforce access control. If we choose the middle-tier, we may create policies, use code access security, or security aware factory methods. If we choose the UI, we should be fired, but the reader should not be at all surprised that this is probably the most common way security is enforced in LOB applications. When the page or screen is loaded a bunch of imperative code is executed that sets visible and disable properties on controls.

There are problems with each of these approaches. And, like most problems, they can be solved by approximating a correct solution through a lot of code. The UI approach doesn't scale as the number of screens and fields on those screens increase. The middle-tier, or business object, approach pulls too much data from the persistent store and doesn't easily tell the UI how it should behave, forcing a duplication of security logic. The database approach leaves the other tiers to fend for themselves and makes it hard to incorporate business logic into security decisions.

A through-going exposition of these shortcomings is beyond the scope of this post. No, seriously, it is, but anyone who has spent any time in the trenches and has seriously thought about this issue will have nodded their head through the last paragraph, I think. I did, however, intimate that their might be something coming out for .NET that could help us with this problem. And, I believe there is such a beast: expression trees. The expression trees that made Linq to Sql (aka dlinq) possible are exactly what you need in a generalized security framework.

Dlinq expression trees are a representation of the current execution environment's intent to access data. From a data-reading perspective, they are declarative intent. Presuming this model is extended to the other CRUD operations: create, update, and delete, the various expressions trees could be pruned. Or, perhaps, the leaf nodes could be filtered. The point is that expression trees and the lambda expressions that create them are data, and security policies can be applied to data. If we used declarative code for our UI bound to declarative data access intent, shouldn't we be able to defer access evaluation to runtime using declarative security policies?

Tuples are the key. Can we formulate a way to secure tuples through the application tiers? Tune in next time when I present my thoughts on how this might be possible in ASP.NET.

Wednesday, November 14, 2007

Why I Love PowerShell

There are a lot of tools out there to help you get your job done, and your effectual use of them is the singular most important factor in your productivity as a developer. One of my favorite questions to ask a candidate in an interview is, "Please name your top five favorite tools besides your IDE." This should be an easy one for a productive developer.

PowerShell is one of my favorite tools, and here's a short list of reasons. PowerShell, I love you because:

  • You make it easy to validate my regex is working

  • You give me an easy way to test my ExpressionBuilder

  • You make it easy to translate a SID to a username

  • You make it easy to find the biggest files in a folder recursively

  • You make it easy to copy only the largest files that don't have a certain extension

  • You're an object-oriented, dynamic language driven SHELL!!!

Monday, November 12, 2007

On Liking LINQ

This past Sunday marked Veteran's Day on the calendar. I observed the holiday in true patriotic fashion: by working.

Truthfully, I spent the day working through the LINQ hands-on lab. You can find all the links you'd need to get started with LINQ and the VS2008 Beta2 release at Charlie Calvert's blog.

First Impressions

It didn't take me long to get used to the new syntax, though I think my experience with JavaScript and Erlang might account for that. I absolutely love the inclusion of lamda expressions; these are huge syntax improvement over writing delegates today in-line today. The extension methods provide a uniformity across the various "LINQ to" APIs that make moving from one type of data source to another very easy. I was pleased that it was so easy to see the SQL output of LINQ to SQL, and I pleasantly suprised that code generated by the designer for LINQ to Objects was so readable and well organized.

I will update this post with more comments later.

Wednesday, November 7, 2007

Tips on Optimizing VirtualPC 2007 Performance

Here a few helpful tips on getting for Virtual PC 2007 image to run blazing fast.

  1. Purchase VMWare Workstation 6

  2. Install VMWare Workstation

  3. Import your slow, crufty Virtual PC 2007 image into VMWare

  4. Start up your new VMWare virtual machine and enjoy the speed

  5. Profit