Sunday 21 April 2013

Playing with Google App Engine

I am following the the Web Development (CS253) course offered by Udacity. If you do have spare time, I would recommend this course. Yes, I have worked with web technologies for few years, but this course is a good eye opener!. Above all its all free!. It is taught by Steve Huffman (co founder of reddit).

I primarily code in .NET and recently started looking at Python. I have to say, its so good, and refreshing. 

As a part of the course, we are introduced to Google App Engine. It is fantastic! 

One of the tasks in the course was to create a simple blog using Python and Google App Engine. The blog uses the Google App Engine data store, which is a massively scalable distributed database.  

If you have not used Google App Engine, have a look at today. 

My skeletal blog is here.

Tuesday 16 April 2013

("quirky") SQL Server with IIS App Pool users

Scene

So you have developed a great .NET MVC web application. All the unit/integration tests passing and ready to go live!. You have tested the site using Visual Studio built-in web server (Cassini) and would like to try it out in "real" IIS.

New site is created and deployed but you are faced with the "yellow-screen-of-death".



The issue is that the site is impersonating the application pool user. As we just want to view the site, we can go to SQL Server and give the application pool user (IIS APPPOOL\SamplesSites) the permission to read the database. Simple!

Problem

We can add a new SQL Server user mapped to the IIS AppPool user. (See below.)


Looks good, but when we try to add a new user, we get the following error.


This is very strange. Even though the "Select User" dialog finds the application pool user, it cannot be mapped to a SQL Server login.

Solution

Here comes the MAGIC!

If you return to the "Login - New" dialog and type in the application pool user and click "OK" then the login is added.



Once the user is added, you can see it by expanding the security tab. (See below).


Fun!

(see this post for more information.)

Friday 12 April 2013

("quirky") Entity Framework with DatabaseGeneratedOption.Identity

I am pretty impressed with Entity Framework 5 so far. Especially Entity Framework Code First is a massive time saver!

Caution
I recently needed to share a reference to a row in a table with an external system. Simplest solution is to share the primary key which most of the time is auto incremental unique value. From the outset this does not look too bad. However, sharing primary keys can be a massive security flow. If a someone gets hold of the primary key, they can "guess" what the next key might be.

Setup
Entity Framework kindly provide us a standard pattern to setup a primary key for an entity. See the following model class.


The "Id" is set to be the primary key, with the seed and increment set to 1. See the following illustration.



It is never a good idea to share technical keys outside the application boundary. The way around is to have random key that is uniquely identifies the row. We can achieve this by introducing a new "Reference" column with the type "GUID". The modified model class looks like the following.


Problem
There two ways to populate the GUID. The simplest approach is to create a new GUID (GUID.NewGuid()) just before saving the entity.  This is proven to work and reliable.

Alternatively we can get the database to do the work and generate a new GUID. In order to force the database to create the GUID automatically, we need to "inform" Entity Framework our intention. The first step is the update the model class to the following. (BTW you need to reference System.ComponentModel.DataAnnotations.Schema namespace). I am using data annotation, but the same behavior can be achieved by the Entity Framework fluent API.


I find the syntax pretty strange. We are basically saying that "Reference" is the "identity" of the entity. Does this mean primary key is no longer the "identity"? (we'll find out soon).

If you regenerate the database (using Entity Framework Code First) what you see may surprise you. By the outset the table looks pretty good. (see the illustration).


As expected the "Id" is the primary key and the "Reference" is an uniqueidentifier field.The biggest surprise is the seed and the increment for the primary key. (see below.)


The seed and the increment is not set and worse "Id" column is no longer the identity. This is strange. 

If we dig a just a bit deeper, we see how SQL Server generate the uniqueidentifier automatically (see below).


The "DefaultValue" is set to "NewId()" which is how SQL Server generate a GUID. When a new row is added, the "NewId()" function is invoked and it populates the "Reference" column.

Solution
We yet fix the problem. Our desire is to have an incremental primary key and a random "Reference". In order to achieve this, we need to update the model to the following. 


The key point here is that we have added "DatabaseGeneratedOption.Identity" to the "Id". This adds the seed and increment to "Id". So when we add a new entity database, automatically generate a random "GUID". The GUID is safe and can be shared externally.