Software Development

Two Factor Authentication with GitHub and Visual Studio 2013

New job, new tools, new processes. In my new job we’re using GitHub for source control, and because the data is sensitive we’re also using two factor authentication. Because I develop with Visual Studio that presents and interesting issue if you are using Visual Studio 2013’s build in Git Source Control provider.

After turning on Two Factor Authentication, the next time you have to communicate with GitHub (e.g. pull/push/sync’ing, etc.) it will pop up a dialog asking for your credentials, even if you already entered them previously before turning on 2FA.

You get an error message that looks like this:

An error occurred. Detailed message: An error was raised by libgit2. Category = Net (Error).
Response status code does not indicate success: 401 (Authorization Required).

Entering your credentials won’t do you any good. It won’t work. It will just request them again, ad infinitum.

There is no where to enterthe 2FA code, so you can’t authenticate yourself here.

However, you can go to GitHub and create a personal access token in order that Visual Studio 2013 can access your repositories.

You can either drop down the menu on your avatar and go to “Settings”, then go to “Personal Access Tokens” (link in the side bar) or you can just go here https://github.com/settings/tokens.

Then click on “Generate New Token”. You’ll be asked for your credentials again just to be sure you are still you.

Once you’ve done that you’ll be taken to the page to create your credentials

For what Visual Studio wants the default permissions are fine. Also, give the token an appropriate name so it can be identified easily.

Then press “Generate token”.

You will then be taken back to the “Personal access tokens” page. This time there is a new token which you can use in Visual Studio. Be careful here, this is the one and only time you will be able to access this token so copy it and keep it safe.

Back in Visual Studio try and sync the commits to GitHub. It will pop up the credentials dialog again. This time you are going to enter the token in the username box and leave the password box blank.

Then press OK.

Finally, your changes will sync with GitHub and you’ll get a success message.

Tip of the Day

Tip of the day: Default project location in Visual Studio

When rebuilding a machine I always end up hunting this setting down just after installing Visual Studio because I keep forgetting where it is. I never put my projects in my documents directory. Ever.

In Visual Studio go to Tools –> Options... then navigate to “Projects and Solutions” and in the “General” section change the “Projects location” to the one you want.

Visual Studio Options dialog

In the workplace

How not to interview a candidate

I recently started a new job. I interviewed for a few companies and got a few offers on the table. However, one interview stuck out for me because, well, let me tell you the story…

I interviewed for a company and the first interview went really well. I liked the guys that were interviewing me and everything went really positively. They also liked me and invited me back for a second interview. They explained at the end of the first interview that the second interview was going to involve some technical competency questions, whiteboarding and so on. I was looking forward to it.

A few days later the recruitment agent called to confirm the time for the second interview and I duly turned up at the appropriate time. The second interview had a different panel to the first which isn’t unusual. However, the format was very similar to the first interview.

Towards the end of the interview one of the interviewers asked me about Scottish Developers, the user group I help run. This is not unusual. Companies are often keen to see such passion for the job that they see this as a positive. Not this chap. I was subjected to several minutes of questions about how my involvement could negatively impact the company and what I’d be doing to mitigate that.

I have found that negative leaning questions fail to understand the implications of running a user group. I run Scottish Developers as part of my own personal training and skills improvement programme, it also benefits many people around me also. To ask how that might negatively affect the company and to seek further assurances that any activities that are organised in my own time, which they are, and are done so well in advance displays a level of control that would be unacceptable, not to mention detrimental to them as I would not be able to keep my skills as up-to-date as I’d like. Something that benefits them more than it does me. I do this because I enjoy software development and I want to continually improve, the side effect of this is that they get a employee that is highly skilled and highly motivated. To cause demotivation in that way would be detrimental to both of us.

Suffice to say that line of questioning left a bitter taste in my mouth.

Then they asked me what I thought of the interview process, so I mentioned in my answer that I thought that the second interview was going to be the more technical and there would be some whiteboarding, problem-solving, and technical questions.

“Where did you hear that from?” was the unexpected, almost barked, response.

“Well, I was told…” was as far as I got in a reply.

“Was it the [name-of-recruitment-agent] at [recruitment-agents-firm]?”

“N…” again I didn’t get a chance to respond.

“I’m going to have to have words with her. That’s not acceptable”

And that was when a previously very positive impression of the company turned into a very firm definite rejection.

He refused to listen to my answer. In fact, he refused to let me speak. He made a wild assumption, which was wrong, and wouldn’t let me correct it. Finally he set out a course of action he was going to take based on that incorrect assumption which was to chastise the recruitment agent for something that was clearly not her fault.

Some interviewers forget that an interview is a two way process. The company want to see what the candidate is like and the candidate want to see what the company is like. For an interviewer to act in such a way was quite revealing.

In one respect I was glad that he did react this way at the interview stage, it saved me finding out once I actually started with the job.

Software Development

Custom routing to support multi-tenancy applications

The company I currently work for has many brands so they are looking for a website that can be restyled for each brand. They also want the styling information to be managed through an admin area rather than have to go to the development team each time they want to change something.

To that end I have added some custom routing into the application to allow assets to be delivered via a controller yet have the URL look like a path to a file on disk.

The summary of the steps involved are:

  • Set up a custom route with a custom route handler
  • Build the logic in the custom route handler to ensure that the data is passed to the controller correctly.
  • Update the web.config file to tell IIS to allow certain paths through to ASP.NET MVC that would otherwise look like a static path.

Setting up the custom route

My custom route is inside an area to keep all tenant specific URLs separate from the rest of the application.

public override void RegisterArea(AreaRegistrationContext context) 
{
    context.MapRoute(
        "Tenant_customLogic",
        "Tenant/{tenant}/content/{*contents}",
        new { action = "Index", controller="Content"}
    ).RouteHandler = new TenantRouteHandler();
}

So, this means that the routing engine can extract the “tenant” from the URL and it will also allow multiple path parts in the “contents” value. So, if the URL is: http://example.com/Tenant/MyBrand/content/my/virtual/file/path/to/styles.css then the RouteValueDictionary will contain:

  • tenant: MyBrand
  • controller = Content
  • action = Index
  • contents = my/virtual/file/path/to/styles.css

However, we want to split up the contents into its individual components, so a TenantRouteHandler class is created to do that.

Build the custom route handler

Without going too much in to what this class does in this specific instance (which isn’t relevant to the general concept) the basics are

  • Create a class that implements IRouteHandler
  • In GetHttpHandler process the routing information to get what we want in a format that suits the application.
  • Create a regular IRouteHandler object (normally an MvcRouteHandler) and call its GetHttpHandler() method with the updated requestContext as I otherwise want the same functionality as a regular handler.
public class TenantRouteHandler : IRouteHandler
{
    private readonly Func<IRouteHandler> _routeHandlerFactory;
 
    public TenantRouteHandler()
    {
        _routeHandlerFactory = ()=> new MvcRouteHandler();
    }

    public TenantRouteHandler(Func<IRouteHandler> routeHandlerFactory)
    {
        _routeHandlerFactory = routeHandlerFactory;
    }

    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        ProcessRoute(requestContext); // does stuff to modify the request context
        IRouteHandler handler = _routeHandlerFactory();
        return handler.GetHttpHandler(requestContext);
    }
}

ProcessRoute(requestContext) is the specific implementation that extracts the information out of the route and I then add it back into the RouteValueDictionary so my controller can access it. It isn’t relevant so I’m not including it.

What I also do here (because ASP.NET MVC, despite being launched in 2009 to a fanfare of being easy to unit test, isn’t east to unit test at all) is also set up some functional hooks that I can use in unit testing. The default constructor simply sets up the strategy to return a regular MvcRouteHandler and that’s the constructor that will be used in production. The other constructor is used in unit tests so that I can inject my own handler that doesn’t need tons of MVC infrastructure to be set up in advance.

So, the contents part of the route is now split out as we need it for the application.

Getting IIS to pass through these routes to ASP.NET MVC

Running the application at this point won’t return anything. In fact, IIS will throw up an error page that it cannot find the file. The expected paths all look like static content, which IIS thinks it is best placed to deal with. However, the web.config can be updated to let IIS know that certain paths have to be passed through to ASP.NET MVC for processing.

Once the following is added to the web.config everything should work as expected.

  <system.webServer>
    <handlers>
      <!-- This is required for the multi-tenancy part so it can serve virtual files that don't exist on the disk -->
      <add
        name="TenantVirtualFiles"
        path="Tenant/*"
        verb="GET"
        type="System.Web.Handlers.TransferRequestHandler"
        preCondition="integratedMode" />
    </handlers>
  </system.webServer>

And that’s it. Everything should work now. Anything in the Tenant/* path will be processed by ASP.NET MVC and the controller will decide what to serve up to the browser.

Software Development

Changing the default Assembly/Namespace on an MVC appliction

TL;DR

When getting an error message like this:

Compiler Error Message: CS0246: The type or namespace name 'UI' could not be found (are you missing a using directive or an assembly reference?)

when compiling Razor views after changing the namespace names in your project, check the web.config file in each of the view folders for a line that looks like this:

<add namespace="UI" />

And update it to the correct namespace, e.g.

<add namespace="‹CompanyName›.‹ProjectName›.UI" />

Full story

I guess this is something I’ve not done before, so it caught me out a little.

I’ve recently created a new project and to reduce the file paths I omitted information that is already implied by the parent directory.

So, what I ended up with is a folder called ‹Company Name›/‹ProjectName› and in it a solution with a number of projects named UI or Core and so on. I then added a couple of areas and ran up the application to see that the initial build would work. All okay… Great!

I now have a source code repository that looks like this:

/src
  /‹CompanyName›
    /‹ProjectName›
      /UI
      /Core

In previous projects I’d have the source set out like this:

/src
  /‹CompanyName›.‹ProjectName›.UI
  /‹CompanyName›.‹ProjectName›.Core

While this is nice and flat, it does mean that when you add in thing like C# project files you get lots of duplication in the paths that are created. e.g. /src/‹CompanyName›.‹ProjectName›.Core/‹CompanyName›.‹ProjectName›.Core.csproj

Next up I realised that the namespaces were out as they were defaulting to the name of the C# project file name. So I went into the project settings and changed the default namespace and assembly name so that they’d be fully qualified (just in case we ever take a third party tool with similar names, so we need to ensure they don’t clash in the actual code). I also went around the few code files that had been created so far and ensured their namespaces were consistent. (ReSharper is good at doing this, so you just have to press Alt-Enter on the namespace and it will correct it for you)

I ran the application again and it immediately failed when trying to compile a Razor view with the following error message:

Compiler Error Message: CS0246: The type or namespace name 'UI' could not be found (are you missing a using directive or an assembly reference?)

Looking at the compiler output I could see where it was happening:

Line 25:     using System.Web.Mvc.Html;
Line 26:     using System.Web.Routing;
Line 27:     using UI;
Line 28:     
Line 29: 

However, it took me a little investigation to figure out where that was coming from.

Each Views folder in the application has something like this in it:

<system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.1.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
        <add namespace="UI" />
      </namespaces>
    </pages>
  </system.web.webPages.razor>

There was my old “UI” namespace that had been replaced. It was these settings that were generating the using statements in the Razor precompiled source.

The solution was simple, replace that “UI” namespace with the fully qualified version.

        <add namespace="‹CompanyName›.‹ProjectName›.UI" />

And now the application works!

Software Development

The difference between & and && operators

Here is a bit of code that was failing:

if (product!=null & !string.IsNullOrEmpty(product.ProductNotes))

If you look closely you can see it uses just the single ampersand operator, not the usual double ampersand operator.

There is a significant function difference between the two that under normal circumstances may not be obvious when performing logic operations on business rules. However in this case it become significant.

Both operators produce a Boolean result, both operators function as in this truth table

LHS (Left-hand side) RHS (Right-hand Side) Result
False False False
True False False
False True False
True True True

But there is a functional difference. For a result to be true, both LHS AND RHS must be true, therefore if LHS is false then the result of RHS is irrelevant as the answer will always be false.

The single ampersand operator (&) evaluates both sides of the operator before arriving at its answer.

The double ampersand operator (&& – also known as the conditional-AND operator) evaluates the RHS only if the LHS  is true. It short-circuits the evaluation so it doesn’t have to evaluate the RHS if it doesn’t have to. This means you can put the quick stuff on the left and the lengthy calculation on the right and you only ever need to do the lengthy calculation if you need it.

In the case above the code is checking if product is not null AND if product notes is not null or whitespace. It cannot evaluate the RHS if the LHS is false. Therefore a single ampersand operator will cause a failure when product is NULL simply because it is trying to evaluate both sides of the operator.

For more information see:

In the workplace

Let’s hack it now and fix it later

“Let’s hack it now and fix it later”. I’ve heard that before!

3 years later looking at some old source code, “WTF was I thinking?!”

Then I remember. The deadline was tight. We needed to get something out the door. And we decided “Let’s hack it now and fix it later”.

Now I’m feeling dispirited.

Reality is often quite nuanced as it was not necessarily a bad decision, it just missed one qualifier.

It depends on when “later” is. If later set at the time of the hack (“lets hack this now and we’ll fix it next month”) then that is acceptable. However, hacking on the never never has many consequences.

The arguments for “lets hack this now and we can fix it later” run the same way as taking on a debt. If it is managed then it can be a sensible decision (e.g. a mortgage or car loan) . If it is left to run rampant (just piling spending on a credit card and only ever playing the minimum balance) then extreme measures may have to be taken down the line.