Friday, 17 June 2011

Managing Quality in the Workplace

Consider the scenario, you have a software project which is dependent on 2 dlls from the same project built elsewhere. Simple scenario but already you have several things that can go wrong:

  1. You might forget to update the dlls when they are changed
  2. You might only update one dll when they are changed
  3. You might deploy the application in a way that means the defect is not noticed until runtime
What can you do? You have several approaches you can take:
  1. Hope it never happens (the most common and least effective measure)
  2. You can write a process which reminds people to update dlls - not bad but people don't always read or understand the implications of processes
  3. You can write a tool that updates things automatically - good idea but can require investment in the development for a simple scenario. Also how do we monitor whether it is working?
  4. Write unit tests that can test for the presence of the correct items - a good idea generally if possible but how to ensure they are kept up-to-date and are testing all the right places?
  5. You can design projects to not require such a dependency - best idea if it is possible without any other knock-on disadvantages or..
  6. A combination of the above dependent on the exact requirements.
As I have said before, anything is better than nothing. There is no single solution because all decisions in life have pros and cons which need to be considered objectively rather than dismissing out of hand. How much damage could occur if the defect is injected. Charge that at £1000/$1500 per day and then how much to develop or create the solution? Even a minor bug can have knock-on effects, both causing other defects and also damage to reputation before you have even thought about fixing the defect itself. The fix is then another potential defect injection since systems are rarely tested to the same degree after a bug fix than they are initially. Basically, even a small defect fix, if you are going to fix it, costs thousands in real terms, money which you are NOT going to get from the customer. Get it right the first time since you will not have time to do it right a second time if you didn't have time to do it right in the first place!

Thursday, 16 June 2011

MVC hacking for foreign keys

I have an unusual scenario for MVC entity framework 4. Firstly I have a table with a primary key (not used for foreign keys) and a unique constraint (which is used for foreign keys). Entity framework does not recognise unique constraints and therefore does not let you use them for foreign keys. The fix is to open the crm.edmx in an xml editor (you might be able to do it from the designer!) and then change the key to point to your unique field and not to your primary key. This allows EF4 to point foreign keys to your field. If you had already created the keys and then re-generated, you might have found that the associations have lost their referential settings which you will need to restore. Obviously if you regenerate, this change might be undone.
The second issue is that although one of my table columns has a theoretical foreign key to another table, the key does not exist which allows us to test the scenario where an item is orphaned (the foreign key does not exist on the customer system), therefore EF does not provide all the wiring up for a drop-down list on my view to edit this 'foreign' field. The answer is to use a ViewModel which is simply a class that contains your entity and any other supporting data, in my case a list of SelectItem which is used in the DropDown list. This is populated in the constructor. Then rather than creating the view against the entity, you specify the view model instead and link fields to Model.EntityPropertyName.Name rather than just Model.Name. This also means you can simply link your drop down to the list of SelectItem in the view model which does not exist in the entity itself:

public class AccountDetailViewModel
public AccountDetailViewModel()
AccountDetail = new AccountDetail();

public AccountDetailViewModel(AccountDetail source)
AccountDetail = source;
// Get list of 'Account' entities from db and add number and rowid to the list
var accounts = new Entities().Accounts;
Accounts = new List();
foreach (var acc in accounts)
Accounts.Add(new SelectListItem{ Text= acc.AccountNumber, Value= acc.RowId.ToString()});

public AccountDetail AccountDetail { get; set;}
public List Accounts { get; set; }

And then in the view:

<%: Html.DropDownListFor(model => model.AccountDetail.PrimeAccountInternalRefNo, Model.Accounts, Strings.DropDownListSelectItem)%>
<%: Html.ValidationMessageFor(model => model.AccountDetail.PrimeAccountInternalRefNo)%>

Monday, 6 June 2011

Who is Responsible for Web Security?

Web security for many people is quite simply one of the most important responsibilities that IT departments have. Even a simple forum site, if cracked, can expose passwords and email addresses which can then be used to access other sites - since many people use the same passwords for all their logins.
It is a simple but important question: Who is responsible for application security? Perhaps it's not you because you are not paid? Rubbish. Not you because you are the manager and it is a developer job? Nonsense. Sadly, my experience is that there is a lot of assumption about whose responsibility it is but few people who will stand up and take responsibility when things go wrong. What is worse is that in many ways it is too late when a site has been hacked. Whoever is sorry becomes irrelevant.
Think about some of the risks you have as an individual or company. The integrity of the firewall, the integrity of the network, the applications, the personnel management of people who might cause damage from the inside. Have you even thought about them and done a formal risk assessment? I doubt it. Most people have a very poor and non-methodical approach to security and then try and blame others when it goes wrong. You use an off-the-shelf product but do you keep it up-to-date? You use a lot of networking but are your staff really qualified to keep it secure? Can someone simply plug into your network switches and immediately gain access to your network layer?
So many risks, so little control. Is it any wonder why even high-profile companies suffer from hacking? It is time we started taking this thing seriously. We need auditing, expertise and responsibility. We need people to own up to where their expertise is lacking and the compulsion from management to pay in order to put things right.
I'm not going to hold my breath though. Contact me if you need any consulting on the security risks faced by electronic commerce.

Holistic Approach to Security

Great article outlining the ways in which we need to consider application security: Software Mag

OO Design - do it properly

If there is one thing I have noticed about software, it is that people tend to do something well up to a point and then let it all fall down with a "quick hack". In fact, there is no such thing because a quick hack immediately creates technical debt which invariably takes much longer to fix later on, if it is fixed at all. Once you have compromised in one area, it is then hard to try and keep the OO design pure in other areas and before you know it, your code has become a great ball of mud.
For instance, at work we have a service which is used by more than one customer so it has a base part and then a customer-specific part. However, somehow, the base project has ended up with an id of type Guid which is actually customer specific but which goes through the design as if it was customer agnostic. The result? Well, now we are not clear where these Guids should live because another customer simply uses an integer for a customer ID and not a Guid. The design is polluted and other decisions have been made which are not good.
One of the problems is that people are still taught in very structured, low level ways, to think about guids and ints and strings even though normal people don't understand such concepts. All they understand is a "product ID" or "text".
When we design in OO, we must be merciless with abstraction. Even if our id is a Guid, we should make it an abstract type since the fact it is a guid is irrelevant, it is a unique key and could be abstracted into UniqueKey which can inherit or contain whatever it needs to. This way, the abstraction holds true when another customer uses text for a unique key because IT IS STILL A UNIQUE KEY!
The thing is, we only learn these things after a mistake is made which is why it is important to train, to code-review and to retain people who are good at their job by recognising and rewarding them otherwise they will think the grass is greener on the other side and jump ship, leaving us with the average people who are not good enough to move jobs or who are not interested enough in work to care!