How we use feature flags


I got some feedback that people want to know what feature flags are.

Wikipedia does a good job of explaining it:

"A feature toggle (also feature switch, feature flag, feature flipper, conditional feature, etc.) is a technique in software development that attempts to provide an alternative to maintaining multiple source-code branches (known as feature branches), such that a feature can be tested even before it is completed and ready for release. Feature toggle is used to hide, enable or disable the feature during run time. For example, during the development process, a developer can enable the feature for testing and disable it for other users."


End edit

Feature flags allows us to deploy functionality that is not complete and activate it once we are happy with our testing or when the outside world is ready for our awesomeness. ;) We use Launch Darkly as our feature flag platform but there are many other platforms and the tips in post are valid for all of them.

If you want to learn more about feature flags in general I recommend When feature flags go bad by Edith Harbaugh from NDC Oslo 2017. Edith is the CEO of Launch Darkly but the talk is about feature flags in general and not Launch Darkly as a product.

To keep track of the feature flags we use we abide by the following rules:

Avoid feature flags if possible

Feature flags increase the complexity of both the code and the testing process which makes is unnecessarily complex for our developers, our testers and our stake holders when doing acceptance testing. Our policy is to only use feature flags when modifying existing functionality and never when implementing new functionality.

There can be only one feature flag per use story/task/bug.

If we have a user story that requires a feature flag we will create a single feature flag for that story and name it "\_\". Our feature flags are always of type bool where false is the default value and represents the code as it was before any changes were made.

We must be notified on changes

If a feature flag is created, removed or changed we will get a notification on Slack in the same channel were we get notifications about production issues. This is done to ensure that at least one person will see that a change has been made.

Lock down flags for a context

The first thing that happens on user interaction in the system is that a session is created (not to be confused with a web session e.g. ASP.NET session state). Everything that happens in the system happens in the context of a session. When the session is created we freeze the values of all flags for that session. This reduces complexity when doing updates as we prevent a session from ending up in a broken state if a feature flag is changed during runtime.

Cleanup old flags

If a user story contains a feature flag we tag that story with a "Cleanup" tag. Cleanup means that once this story is deployed to production we have some cleaning up to do. Once deployed we activate the feature flag and let the system run with the flag enabled for a period of time. During this time the feature flag act as a kill switch. Once the time is up and no issues have been found we delete the feature flag from our code, remove the old code and tests and then re-deploy to production. The actual feature flag is left intact in Launch Darkly. We then let the system run for a week or so before verifying that the feature flag has not been accessed during that time. Once verified we remove the feature flag.

Test both old and new code paths

While a feature flag exist we keep duplicate tests for all code that is affected by the feature flag. One test for when the flag is false and one for when the flag is true. During cleanup, when we remove the flag from our code base, we also remove the old tests (the once were the flag is false).



ASP.NET Core 2.0: Authenticating users via Harvest

At Advise we use Harvest for time tracking. On top of Harvest we have build a separate system that we use to keep track of statistics, vaccation periods and salary specifications. All information is fetched from Harvest. Login to the system is done using via Harvest.

We recently migrated this system to ASP.NET Core 2.0 and needed to update the type of authentication used the authentication process has been completely rewritten in ASP.NET Core 2.0.

To make it easier to use we put together a small library called Harvest Connect that helps with this integration. You can grab it from Nuget and the source code is available on Github. What follows is a how to guide on how to use Harvest Connect.

First of all you need to get a clientId and a clientSecret from Harvest. To do this visit the settings section of your Harvest site.

Once setup, grab the HarvestConnect package from Nuget:

dotnet add HarvestConnect

and modify your ConfigureServices method in your Startup.cs class. In the example we use cookies to keep login information for the user but you could just as well use JWT or some other type of storage.

services.AddAuthentication(options =>
    options.DefaultAuthenticateScheme = HarvestOptions.Scheme;
    options.DefaultChallengeScheme = HarvestOptions.Scheme;
    options.DefaultSignInScheme = "auth";
    options.DefaultSignOutScheme = "auth";
.AddCookie("auth", options =>
    options.LogoutPath = "/logout";
.AddHarvest(options =>
    options.ClientId = "<provided by Harvest>";
    options.ClientSecret = "<provided by harvest>";
    options.BaseUrl = "<base url of your site, e.g. http://localhost:13370>";
    options.Events = new HarvestEvents
        // Called on succesful login
        OnSuccessfulLogin = context =>
            // Add the claims your app requires...
            context.Identity.AddClaim(new Claim(context.Identity.NameClaimType,

            if (context.WhoAmI.user.admin)
                context.Identity.AddClaim(new Claim(context.Identity.RoleClaimType, "Administrator"));

            context.Identity.AddClaim(new Claim("Email",;

            // ... or do other stuff with the data received, e.g.:
            // await _db.UpdateAvatar(, context.WhoAmI.user.avatar_url);

            return Task.CompletedTask;
        // Called when login fails or the user denies the login attempt
        OnFailedLogin = async context =>
            await context.HttpContext.SignOutAsync();
            context.HttpContext.Response.Redirect("/home/logout?message=" + WebUtility.UrlEncode(context.FailureMessage));



Make easier screen shots in Windows 10 creators update

A long awaited feature, that Mac's has had for years, is to make partial screen shots of a part of the screen.

On macOS, you use "Shift-Command-4" and click + drag the area that you would like a screen shot of. The image is saved as an .png-file on the desktop.

On Windows 10 (creators update), you use "Shift+Win+S" and click + drag the area that you would like a screen shot of. The image is saved on the clip board and can easily be pasted right into programs like Slack etc.


1 Comment

Migrating from ASP.NET Core 1.1 to 2.0: Custom authentication

While migrating a ASP.NET Core 1.1 app (running on .NET Framework 4.6.1) to ASP.NET Core 2.0 (netcoreapp2.0) I needed to migrate some custom authentication. There are tons of guides on the internet on how to migrate authentication if you are using one of the standard once like JwtBearer, Facebook or Google. If not, there isn't a ton of info avaiable and the info that is there is spread accross multiple Github issues and questions in comments on

Note: If you came here looking for how to setup Facebook, Google etc, have a look at the official Microsoft docs:

Summary / TL;DR

  • Authentication schemes are added as services
  • A single middleware is now used for authentication instead of several as in ASP.NET Core 1.1
  • Options object to pass variables and services to the auth scheme

ASP.NET Core 1.1

Our system consisted of two different types of authentication. "Shared Key" for write access and "public token" for read only access. The two are implemented as middlewares inheriting from AuthenticationMiddleware. Each of these middlewares are only available for some specific controllers in the system.


public void ConfigureServices(IServiceCollection services) 
    // Other setup omitted
        options =>
            // Policy building omitted

 public void Configure(IHostingEnvironment env, IApplicationBuilder app) 
     // Other setup omitted

In ASP.NET Core 1.1 the authentication handlers will be called sequentually for every request if the former handler returns AuthenticateResult.Skip(); from the HandleAuthenticateAsync method. Each of the UseXXXAuthentication registers each middleware to the application builder, e.g:

public static IApplicationBuilder UseSharedKeyAuthentication(this IApplicationBuilder app)
    if (app == null)
        throw new ArgumentNullException(nameof(app));

    return app.UseMiddleware<SharedKeyAuthenticationMiddleware>(Options.Create(new SharedKeyAuthenticationOptions()));

SharedKeyAuthenticationOptions inherit from AuthenticationOptions and set the base class properties as below. AutomaticChallenge and AutomaticAuthenticate is used to run this handler for every request. AuthenticationScheme says which scheme the handler handles.

public class SharedKeyAuthenticationOptions : AuthenticationOptions
        public SharedKeyAuthenticationOptions()
            AutomaticAuthenticate = true;
            AutomaticChallenge = true;
            AuthenticationScheme = "SharedKey";

The setup for UseTokenAuthentication is similar.

The SharedKeyAuthenticationMiddleware inherits from AuthenticationMiddleware<SharedKeyAuthenticationOptions> and simply overrides the CreateHandler method to create a new SharedKeyAuthenticationMiddleware:

protected override AuthenticationHandler<SharedKeyAuthenticationOptions> CreateHandler()
    return new SharedKeyAuthenticationHandler(_sharedKeyAuthenticationProcess, _serviceUserRepository, _logger);

Dependency injection works out of the box to the middleware which in turn passes the injected objects to the handler.

ASP.NET Core 2.0

In 2.0 there is just a single middleware handling all authentication and instead handlers are registered as services.



public void ConfigureServices(IServiceCollection services) 
    // No default schema. Schema is set per policy.

public void Configure(IHostingEnvironment env, IApplicationBuilder app) 

And done! No, not really... there are some more stuff that needs to be done.

AddSharedSecret and AddPublicToken registers a scheme to the AuthenticationBuilder class returned by AddAuthentication.

AddSharedSecret looks like this:

return builder.AddScheme<SharedKeyAuthenticationOptions, SharedKeyAuthenticationHandler>(
                "SharedKey", // Name of scheme
                "SharedKey", // Display name of scheme
                options =>
                    var provider = services.BuildServiceProvider();
                    // Logger, ServiceUserRepository and SharedKeyAuthenticationProcess are all things that were injected into the custom authentication
                    // middleware in ASP.NET Core 1.1. This is now added to the options object instead.
                    options.Logger = provider.GetService<global::Serilog.ILogger>();
                    options.ServiceUserRepository = provider.GetService<IServiceUserRepository>();
                    options.SharedKeyAuthenticationProcess = provider.GetService<ISharedKeyAuthenticationProcess>();

The SharedKeyAuthenticationOptions no longer needs to specify AutomaticChallenge, AutomaticAuthenticate or AuthenticationScheme. The first two are obsolete in 2.0 and the latter is handled by the AuthenticationBuilder. SharedKeyAuthenticationOptions now looks like below. The Validate method can be overridden to add custom validation to the options object. Any exception thrown causes the validation to fail.

public class SharedKeyAuthenticationOptions : AuthenticationSchemeOptions
        public static string AuthenticationScheme => "SharedKey";

        public ISharedKeyAuthenticationProcess SharedKeyAuthenticationProcess { get; set; }

        public IServiceUserRepository ServiceUserRepository { get; set; }

        public global::Serilog.ILogger Logger { get; set; }

        public override void Validate()
            if (SharedKeyAuthenticationProcess == null)
                throw new NullReferenceException($"{nameof(SharedKeyAuthenticationProcess)} is null");

            if (ServiceUserRepository == null)
                throw new NullReferenceException($"{nameof(ServiceUserRepository)} is null");

            if (Logger == null)
                throw new NullReferenceException($"{nameof(Logger)} is null");

There are minimal changes required to SharedKeyAuthenticationHandler:

Constructor must look like this, otherwise an exception will be thrown:

public SharedKeyAuthenticationHandler(IOptionsMonitor<SharedKeyAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
            : base(options, logger, encoder, clock)

All references to the fields we previously used needs to be replaced with references to the Options object, e.g:

ASP.NET Core 1.1 -> _logger.WriteEvent(...);

ASP.NET Core 2.0 _> Options.Logger.WriteEvent(...);

AuthenticateResult.Skip() has been renamed to AuthenticateResult.NoResult(). Note that returning NoResult will NOT call the next handler in the chain.

The above line is important! You can by default only address a single authentication schema in ASP.NET Core 2.0 with the built in authentication middleware. To add multiple schemas you need to specify all schemas supported on each [Authorize] attribute or on each policy (or use a custom middleware). If you only have a single scheme for authentication you can specify this as default in services.AddAuthentication

                        options =>
                            options.DefaultScheme = "SharedKey";

Since we are using claims based authentication I added the different schemas to our policy builder as each policy is only accessible using one authentication schema.

Example code:

public void ConfigureServices(IServiceCollection services) 
    options =>
            builder =>
                // Multiple authentication schemes can be added and the output from them will then be merged into a single identity.
                builder.AddAuthenticationSchemes("SharedKey"); // Runs SharedKeyAuthenticationHandler
                // builder.AddAuthenticationSchemes("Token"); // Runs TokenAuthenticationHandler

1 Comment

1 Comment

Våra favoriter från NDC Oslo

Alla talks från NDC Oslo 2017 finns nu på Vimeo och Youtube. Vi tänkte därför länka till några av de talks vi gillade extra mycket! Ingen inbördes ordning :) Glöm inte att vi skrivit sammanfattningar av många av de talks vi var på. Dessa kan ni hitta på bloggen.

För teknikintresserade:

För de som är mer intresserade av soft skills:

1 Comment


Angular War Stories

Adam Stephensen och Duncan Hunter från SSW, Australien, gav en intressant och ärlig bild av Angular 2 och 4 (fortsättningsvis kallat Angular) och om de läxor de lärt sig genom de projekt som de bedrivit med Angular som javascript framework. De säger att de "älskar" Angular, men att de också har haft en hel del svårigheter. De ville dela med sig av sina erfarenheter så att andra inte gör om samma misstag som de har gjort.

De tar upp fördelarna med Angular vs Angularjs (Angular 1), vilka framförallt är:
•    Performance -> Optimerad kodgenerering, "Universal for server side rendering", Code Splitting (anpassade nedladding av t ex js-filer)
•    Mobilanpassat Framework

De pratade också om vilket angreppssätt man skulle ha för att migrera från Angularjs till Angular. De rekomenderade inte att göra ett total omskrivningsprojekt, utan att man skulle försöka steg för steg bryta ut vissa delar och skriva om dessa i Angular i takt att man får t ex nya change requests etc. Varje kodrad skriven i Angularjs är en ökad teknisk skuld säger de.

Det är svårt att sammanfatta alla problem som de stött på, men vad hade de då lärt sig? Jo, att...
•    Istället för att använda ett bygg- och deployverktyg som Gulp, som de valde från början, så har de byggt en komplex bygg- och deployprocess vilket ökade förståelsen och givit dem möjligheten att skapa en effektivare deployment. De valde bort Gulp och valde webpack för detta ändamål.
•    Använd ej Visual Studio, använd istället Visual Studio Code
•    Använd Material 2, som CSS framework, eller i 2:a hand Boostrap
•    Använd RxJS för ascync anrop, detta för större applikationer.
•    Använd Redux för att hantera states och cache'ad data, samt använd ngrx.

Sammanfattningsvis kan man säga att det var en innehållsrik och pedagogisk presentation om för- och nackdelar med Angular. Både jag och övriga åhörare var mycket nöjda.



Badass 101

Lyndsey Padget gick igenom hur man som utvecklare kan bli en "badass" och vad det egentligen innebär. Innebörden av ordet skulle nog bästa kunna beskrivas på svenska som någon som äger scenen och vet precis vad de gör. 

Några tips som Lyndsey delade med sig av:

  • Människor är illogiska. Ta inte illa vid dig! 
  • Vi behöver underhåll i form av mat, vatten och vila. Och med "mat" menas "näring". "Cheetos and Mountain dew doesn't cut it!"
  • Livet är inte rättvist men det är bara att kämpa på
  • "Get your shit together!". Du kan komma in på jobbet i t-shirt och jeans bara det ser ut som att du inte precis rullat ur sängen.
  • "Control the floor" - Se till att tänka igenom det du vill säga innan du säger det. På så sätt lär sig folk att när du pratar så är det något vettigt som kommer ut.
  • En "badass" är ingen elak robot. Tänk på att folk kan ta illa vid sig om du kör över dem! 



ReST 3.0 – A lap around HTTP Apis' next generation

Serialseb, eller Sebastien Lambla som han egentligen heter, körde en dragning om ReST och hur dessa APIer utvecklats sedan 1991 när webben för första gången såg dagens ljus.

Han inledde med en kort historielektion där vi fick reda på vad 1.0 och 2.0 av ReST innebär och vad de har för nackdelar. 1.0 är originalet med JSON och HTTP anrop och 2.0 är när man gick över på "hypermedia", ett sätt att stödja mer automatisk utforskning av APIer, t ex genom att ge ut länkar till liknande resurser i ett API-svar (se t ex HATEOS)

3.0 däremot kommer, enligt Sebastien, bli mer uniformt mellan APIer så att man inte behöver en klient per API utan istället att man kan standardisera hur t ex felkoder och länkar skickas ut. Två exempel på saker som förekommer i nästan alla ReST-APIer, men som skiljer mellan dem, är vad som kallas ett "home document" dvs. "förstasidan" för APIet där vilka operationer som finns är listade. Det andra är "error details", alltså hur fel i APIet beskrivs för klienten. Det finns ett antal försök redan nu för att försöka standardisera dessa, t ex HAL och Siren. Det senare ger även stöd för hur requester mot APIet ska se ut vilket innebär att vi kan ha ännu mindre kod som måste skrivas för varje ReST-integration. 

Det finns redan idag stöd för länkar i HTTP headers. Dessa beskrivs med en URI samt en "rel" som beskriver vilken relation den har till det dokument som precis laddats ner. En ny sån som kommit är "preload" som säger till klienten att börja ladda ner den så fort det bara går för den kommer vara av användning senare i dokumentet. I kombination med den nya statuskoden "103" ("Early hints") kan data laddas ännu snabbare då servern kan skicka ut dessa preload-headers innan hela svaret är färdigskapat.

Några saker som kommer framöver som Sebastien pratade om är t ex HTTP/2 och multiplexing, där en klient kan skicka flera requester över samma TCP-anslutning och servern kan svara i vilken ordning den vill. Detta snabbar upp dataöverföringen rejält eftersom det oftast är långsamt att starta en ny TCP-anslutning. Liknande har funnits sedan tidigare men då var servern tvungen att svara på anropen i samma ordning de kom in, vilket så klart gör att det kan bli kö om någon tung databasfråga eller liknande ska köras. HTTP/2 kommer även vara helt binärt vilket gör att det både går snabbare för en dator att tolka informationen och att den blir mindre så att det går fortare att skicka den. 

Som om inte HTTP/2 skulle vara snabbt nog har Google även börjat exprimentera med en teknik de kallar QUIC (Quick UDP Internet Connections), ett sätta att köra webben över UDP istället för TCP. Även detta borde snabba upp webben rejält. 



Banish Your Inner Critic v2.0

Hur ser man till att man blir så kreativ som möjligt och får så roligt som möjligt på köpet? Jo man ändrar sitt tankesätt till ett mer positivt! Det var det Denise Jacobs talk gick ut på. 

Hon inledde med att fråga publiken hur många som skulle beskriva sig själva som kreativa. Till de som inte räckte upp handen hade hon ett budskap: "Ni skriver något på datorn och får den att göra saker! Det är kreativitet!". Det hon kallar för "creativity denial" är tydligen ganska vanligt hos utvecklare när det i själva verket är tvärtom. Som bakgrund gick hon igenom studier på området och pratade om saker som "fear conditioning", som innebär att om man t ex har sett en orm i ett område så är man väldigt försiktig när man går i det området. Det omvända gäller dock inte. Om man har sett t ex en fjäril i ett område tänker inte hjärnan automatiskt "Här vill jag gå, för här finns vackra saker!". Så gör den däremot med ormen. 

"Creativity is power!" Och så klart finns det en del "power tools" man kan använda för att bli mer kreativ, t ex mindfulness och self-compassion. 

Det är lätt att ha en s.k. "confirmation bias" där man utgår från en sak man tror är sann och sedan letar bevis för det. Men bara för att något tänks behöver det inte vara sant! Hur du formulerar dina tankar och vad du säger spelar stor roll. Undvik ord som gör dig till ett offer, t ex "borde" och måste "måste". "Jag måste fixa det här" kan sägas som "Jag väljer att fixa det här" och "Jag borde fixa det här" kan ersättas av "Jag vill fixa det här".

Några konkreta tips som delades ut:

  • När man får kritik, försök att vara öppen och nyfiken på kritiken. Man kan alltid lära sig något och vissa som ger kritik är helt enkelt bara dumma i huvudet. :) 
  • Känner du dig inte så kreativ? Försök komma på 10 idéer om dagen! Det behöver inte vara bra idéer, eller ens genomtänkta idéer. Men bara det att man kommer på idéer ökar ens kreativitet och det kommer bli lättare att komma på nya.
  • Skriv en "kudos file". En liten textfil på datorn där det antecknas varje gång någon säger något bra om dig. Dagar du känner dig nere är det perfekt att öppna och titta. "Ush vad jag är dum i huvudet. Nej kolla här, förra tisdagen sa Stefan att han uppskattade mitt jobb och att jag skrev snygg kod! Jag kanske inte är så korkad trots allt..." 
  • Hamnar du ofta i en tankeloop om något jobbigt? Köp en stressboll och krama den med fel hand! Detta ska tydligen få effekten att hjärnan måste tänka på handen och då bryts loopen.
  • Använd gester för att få bort negativa tankar. T ex "swipe left for delete". Swipa vänster med handen i luften och känn hur de negativa tankarna swipas bort.
  • Verkar alla andra lyckligare/smartare/bättre? Det är för att ingen delar saker när det går dåligt. Alla vill däremot dela sin framgång både online och i verkliga livet.

Som avslutning fick vi en väldigt intressant frågestund där flera frågor som jag själv funderat på kom upp. T ex om det ändå inte är lite bra att vara självkritisk. Hur ska man annars bli bättre? Denise svarade att självkritik bara håller dig tillbaka och att du istället ska fokusera på de bra grejorna du gör. De dåliga kommer du ändå göra annorlunda nästa gång! Hur ska man hantera "avundsjuka" mot andra som det går "bättre" för? Formulera om det! Avundsjuka kan lika bra tänkas på som beundran. Ta en funderare på det och se om det inte går att lära sig något av de man är avundsjuk på. 



Imposter Syndrome: Overcoming Self-Doubt in Success

Heather Downing gick igenom vad "imposter syndrome" är, hur det påverkar oss och vad man kan göra åt det. Enligt henne kan så många som 70% lida av imposter syndrome och det är lika vanliga bland män som kvinnor. I kort går det ut på att man känner sig som en "fraud" som bara har haft tur att man kommit dit man har eller lyckats med de saker man gjort. 

Flertalet stora namn togs upp som att de hade liknande symptom och vi fick olika tips för att undvika det, t ex att man inte ska jämföra sig med andra och att man ska försöka tolka sin oro som spänning (eller iver). 

Mer om imposter syndrome på Wikipedia



Hack your career

Eftersom Troy Hunts talk "Something something cyber" var så bra så gick jag även på hans talk "Hack your career" som handlade om hur man bygger sig ett namn i IT-branchen.

När man söker jobb så skickar man oftast in ett CV där det står hur awesome man är. I CVt finns sedan referenser som även de kan berätta hur awesome man är. Vad är då problemet med detta? Både CV och referenser är valda av den som söker jobbet! Så klart kommer de berätta hur awesome personen är, de känner ju personen i fråga. Vore det inte bättre om man skulle kunna kolla på nätet och verkligen se om personen i fråga är awesome? 

Undefär så inledde Troy sitt talk. Troy jobbade tidigare för Pfizer som utvecklare och när han jobbade där började han blogga. Dels för att det var roligt och dels för att han själv skulle komma ihåg vad han gjort. Han pratade mycket om att bygga upp en "active online profile", vare sig det är på blogg, att svara på frågor på Stackoverflow, att göra videos för Pluralsight eller vad det nu kan tänkas vara. I början Troy la mycket fritid på att skriva sin blogg men även arbetstid då han ansåg att bloggandet gjorde honom till en bättre utvecklare och att Pfizer tjänade på det i längden. 

Bloggplatformen valde han just för att han tyckte att det ger bra feedback från läsarna och att det tvingar honom att vara extremt noggrann när han skriver. Finns där ett stavfel eller liknande så spelar det ingen roll om han lagt tre veckors research på det hela. Stavfelet kommer ändå vara det som folk hänger upp sig på. Han drog ett antal exempel där han skojat om Trump och folk blivit upprörda, eller där han haft en bild från ett hack på en porrsite med (självklart gravt censurerad, "No worse than what you can see at the beach") och folk hade blivit extremt upprörda i båda fallen.

Även olika kulturer spelar roll när man skriver online. Han berättade om ett föredrag han haft där han hade visat en bild på en hacker som råkade vara mörkhyad. Efteråt kom en amerikan fram och pratade med Troy och Troy kände direkt att något var fel. Det visade sig att i USA är det extremt tabubelagt att visa upp minoriteter i kombination med brott, något som Troy självklart inte ens reflekterat över. "I didn't even notice that the hacker was black" som han själv lade till. Vad ska man göra åt liknande situationer? Troy menar på att det inte är så mycket att göra utan att man får försöka vara en så bra person som möjligt. Man kan aldrig vara alla till lags.

En annan sak som diskuterades är vad det egentligen kostar att bygga sig en karriär. "What's the price on your family? 'Oh my family is priceless', yet you all took time to come here.". Värt att tänka på :) 



Something Something Cyber

Troy Hunt, en gigant inom IT-säkerhet och mannen bakom, höll ett seminarie om (inte helt oväntat) hackers och vilka säkerhetshot som finns. Låter det tråkigt? Inte alls! Troy blandade allvarliga säkerhetshot med stor humor där han flera gånger frågade publiken hur man vet att det är en hacker på bilden? Jo så klart eftersom han har en luvtröja på sig och texten han skriver är grön. Precis som på film! 

Som bakgrund till hela sitt seminarie hade han ett hack som självaste Donal Trump råkade ut för. Det visade sig att hans site hade direktlänkat till en JavaScript-fil på Github och personen som ägde Github-kontot helt enkelt ändrat i filen och lagt in en massa hyss. 

Att direktlänka filer från t ex ett CDN (content delivery network) är en ganska vanligt sätt att göra saker på. Dels så har ett CDN noder över hela världen så användarna kommer snabbt att få filen, dels är det oftast ingen kostnad för siteinnehavaren att använda ett CDN och dels det kanske viktigaste argumentet, om någon annan site har laddat samma fil från samma CDN, så finns redan filen på användarens dator och behöver inte laddas ner igen. Nackdelen är då det som skrevs ovan. Vågar man lita på de som har filen? 

Kör man Firefox, Opera eller Chrome så behöver man faktiskt inte oroa sig så mycket, då dessa tre har stöd för en teknik som heter "Subresource integrity". Detta innebär kort och gott att man räknar ut en kontrollsumma (en hash) av filen man vill länka till. När webbläsaren laddar filen så kontrolleras den mot kontrollsumman. Stämmer den inte? Då laddas inte filen. Edge har samma feature "under consideration" och Safari kommer ha stöd från och med version 11. Vill man ha hjälp med att räkna fram kontrollsumman kan man använda en site som heter

"Ringer det folk från Microsoft till er också?" frågade Troy lite på skämt och pratade vidare om hur han släppt in en av dessa i en virtuell maskin han hade stående bara för att se vad de skulle göra. Som alla förhoppningsvis redan vet är dessa samtal bluff och båg och inget man ska gå med på. 

Som kontrast till Microsoft-samtalen visade han lite säkerhetsproblem som större företag haft. Ett patologiskt center i Indien råkade av misstänk lägga ut många tiotusentals rapporter från privatpersoner innehållandes provsvar på t ex HIV-tester. Det visade sig att konsultbolaget (inga namn nämda, men ett av världens största) som byggt systemet av misstag aktiverat "directory listing" på mappen där alla rapporter sparades, så att vem som helst kunde hitta dem så länge man kände till adressen. Så då borde det väl varit lugnt, ingen kan ju lista ut den adressen? Tyvärr så hade Google indexerat mappen då siten saknade en "robots.txt" (en fil som säger vad sökmotorer får och inte får indexera). När Troy kontaktade bolaget lovade de att fixa det till nästa version som de skulle släppa... en månad senare. 

Appropå "robots.txt". Är det lugnt att ha datat där om man säger till Google att inte indexera det? En annan av Troys berättelser involverade ett företag som "gömt" sina hemliga mappar genom att lägga till dem i "robots.txt". Problemet med det är att den filen är publikt tillgänglig (eftersom alla sökmotorer ska kunna läsa den) vilket betyder att vem som helst kunde läsa den och se vilka mappar man ville hålla gömda. 

"Have you guys ever heard the word 'Google dork'?" frågade Troy och lade skämtsamt till "This is not my Australian accent trying to say 'Google Docs', a 'Google Dork'". En Google Dork är en person som inte riktigt är hemma i säkerhet när hen konfigurerar en server, vilket gör att de av misstag exponerar hemlig information. Troy pratade länge och väl och gav exempel på hur man gör för att hitta sårbara siter snabbt och enkelt. Eftersom det här är en publik blogg tänker jag inte återge det han delgav. Även här skojade han till det med "Let's search for php becasue you know there will be a problem there!". 

Som avslutning, för att visa hur lätt det faktiskt är att hacka, fick Troys sjuåriga son komma upp på scen och köra ett program som sökte av sårbarheter på en site och plockad ut datat som fanns där som t ex användare. Siten ägdes av Troy så datat var som tur var fake. :) 

Detta var ett av mina absoluta favoritseminarier under hela NDC! Får ni en chans att se Troy prata så ta den. Väldigt kompeten, rolig och entusiastisk kille. 





Gemma Cameron pratade om hur man kan använda visualisering för att förenkla kommunikationen inom en organization eller externt med sina kunder. 

För att illustrera berättade hon om när hon senaste bytte jobb och hamnade i en organization som hade en "cargo culture", dvs. att man gör som man gör därför att det är så man gör. "Because it's agile" som Gemma förklarade det. Hennes tid som projektledare där slutade i att hon skrev en massa dokumentation, som självklart var tråkig och skriva, och ingen läste den. 

Vad gjorde de då för att göra det enklare? T ex så bytte de ut sina user stories mot små seriestrippar på ett par bilder. Det lät konstigt när hon sa det men sen visade hon ett exempel. Hon hade förklarat flera gånger vad företaget gjorde, både i tal och i text på skärmen, men det var inget som sjönk in. Då visade hon en tvåbilds seriestripp och det klickade med en gång! 

Andra anvädningsområden för detta kan vara t ex att visualisera "In progress" på en kanban board. Hur är storyn "in progress"? Är det design, säkerhet, eller kodning som utförs just nu? Eller varför inte sätta upp en synlig road map vid kaffeautomaten så att alla ser den hela tiden? 

Hela seminariet handlade i grund och botten om att människor är bättre på att snabbt ta till sig information från en bild/graf/diagram än från spaltmeter med text. Därför vill man undvika mycket text så långt det bara går. Felloggar på servern? Lägg upp dem som en graf på en skärm så att alla ser det! Chansen är mycket högre att någon går förbi och tänker "Det där ser inte riktigt rätt ut va?" än om det bara ligger i en textfil på någon server och skräpar. 



What is .NET standard

Adam Ralph gav i sin föreläsning på ett föredömligt sätt klarhet i vad .NET Standard är. Microsoft har lyckats göra .NET-communityn ganska konfunderad om vad det är och handlar om. Att det rör sig om ett nytt ramverk tycks vara ett av de vanligaste misstolkningarna. 

 .NET Standard är ett resultat av den utveckling som skett med .NET Framework. I begynnelsen handlade det ju just om ett enda ramverk men 2007 släppte Microsoft Silverlight, kort beskrivet ett subset av .NET. Då och där uppstod behovet av ett sätt att möjliggöra cross plattform genom .NET-baserad kod. Lösningen blev PCL (Portable Class Libraries). Ett PCL definerar intersektionen (av MS definerade som profiler) av API'er mellan två plattformar som på det sätter möjliggör ett binärt kodutbyte. Perfekt eller hur? Nej! Inte med tanke på hur situationen ser ut idag där .NET är en HELT annan värld än den en gång var. Idag har vi ju ungefär följande delar:

  • .NET Framework
  • .NET Core
  • Xamarin.iOS
  • Xamarin.Android
  • UWP
  • Tizen
  • ... 

Adam uttrycker detta målande i ett antal venndiagram. PCL gick från detta:


Till detta:


Förutom Microsofts galna namngivning av profiler, många profiler blir det. Hur många profiler blir det? Adam har räknat på det och visade ett skämtsamt exempel på en tänkbar utveckling:



Portable Class Library är trasigt eller som Adam uttrycker det "PCL is a disaster". Det är iaf detta som .NET Standard är tänkt att laga. I stället för en intersektion av API'er mellan plattformarna är .NET standard istället en mängd utvalda API'er som plattformarna sedan får förhålla sig till för att nå en specifik version av standarden. Som API utvecklare siktar man sedan mot en så låg version som möjligt av ett .NET Standard Class Library för att nå ett bredare stöd av över plattformarna. 


Vid kompilering skapas en netstandard.dll som vid runtime används för att genom type forwarding  peka mot korrekt assembly och typ innehållandes den kod som skall exekveras.



The Developer’s Guide to Promoting Their Work

Det här var ett av de eventen jag såg fram emot mest under hela NDC. I beskrivningen står följande: "A few years ago, I had an idea to make the web better. It was going to be great, and I had the team to build it. Nine months of late nights and lost weekends later, we launched it! The problem: no one cared."

Todd Gardner, utvecklare som gått mer mot sales and marketing, förklarade väldigt bra hur man som introvert utvecklare ska kunna skapa sig ett namn och på så sätt få folk att köpa de idéer som man vill lansera. 

Några av sakerna han tog upp var citatet "Great products sell themselves". Detta är enligt Todd helt och hållet fel! Istället krävs det minst lika mycket tid på att promota sitt projekt som det tog att bygga det. "Förmodligen mer, eftersom vi är utvecklare" lade han till med ett skratt. 

Vad gör man då? Jo man börjar med att ställa sig frågan "Who do I want to be?". "Jag" i det här fallet behöver inte nödvändigtvis vara du som person utan kan lika bra vara organisationen som står bakom projektet du vill sälja in. Nästa steg är att bygga upp sin publik och till sist så säljer man till sin publik. 

Det låter ju lätt! Så hur gör man då? Todd gav konkreta tips på hur man designar sin site för att fånga sin publik:

  1. Single responsibility per sida. En sida är ansvarig för en sak.
  2. Skriv för en specifik publik. Är sidan riktad mot utvecklare? Skriv som en utvecklare vill läsa. Riktar den sig till kunder? Visa hur fantastisk din produkt är! 
  3. Vad är målet med sidan? Är det att någon ska förstå hur något teknisk fungerar eller är det att få så många betalande kunder som möjligt?

Det man vill uppnå är att få #2 att göra #3. Försök inte vara smart! Tekniken är inte poängen. Bygg saker för det din publik vill ha, inte vad du nödvändigtvis tycker att de borde vilja ha. 

Det låter ju bra! Men... hur gör man då? Som utvecklare kanske vi inte är världens mest sociala varelser men det är här vi måste komma ur vår comfort zone. Gå på events, users groups och liknande och prata med folk! Todd beskrev det som att man då skaffar vänner och det är mycket lättare att sälja till sina vänner än till främlingar. Dessutom får man kul på vägen :) 

Sista delen av föredraget handlade om marknadsföring och hur man vet vad man ska lägga pengarna på. Todd beskrev "The funnel", en slags tratt där potentiella kunder kommer in och kunder kommer ut. För att veta om en marknadsföring är lönsam måste man räkna ut ett "lifetime value" av en kund, alltså hur mycket pengar du kommer tjäna på den kunden, inklusive andra kunder som den kunden kanske drar med sig.

För att överhuvudtaget ha en chans att kunna räkna ut det här behöver man använda någon form av analytics (t ex Google analytics eller liknande) för att se hur folk beter sig på hemsidan eller de kanalar där man annonserar. Eftersom Twitter är stort i USA och Todd är från Minnesota pratade han väldigt mycket om Twitterannonser och hur man räknar ut cost per click på en annons och därmed en "cost to aquire" en kund. 



First Class Commands: The 2017 Edition

Reginald Braithwaite har jobbat med mjukvara länge och jobbat för både Github och nu PagerDuty. Hans talk om "first class commands" var en teknisk djupdykning i hur man kan se metod-körningar som körs som ett "command" och hur man gör för att hantera dessa som en "first class citizen" i sitt språk. I de flesta OOP-språk är object first class, dvs man kan spara dem i variabler, skicka in dem i, och returnera dem från, metoder. 

Vad är då poängen med detta? Om vi kan spara undan ett command för senare exekvering kan vi väldigt enkelt bygga en "Undo/Redo"-funktionalitet i vårt språk. Reginald demonstrerade detta genom att skriva en klass som hanterar en textsträng. På denna sträng kan man sedan göra olika Edit-kommandon, som t ex att byta ut delar av strängen mot något annat. Detta är en typ av separation of concerns som man gärna får till i kod för att minska komplexiteten. 

För er som är bekanta med event sourcing kan man se detta som events för metod-körningar.

I grund och botten är detta ett ganska enkelt pattern men det blir snabbt väldigt komplext, speciellt när man kommer till att kunna kombinera commands som körts på olika objekt. Till detta finns en rad olika tekniker man kan använda.

Vet ni vilken annan teknik som bygger på detta? Git. :) 




ETW - Monitor Anything, Anytime, Anywhere

Dina Goldshtein pratade om performance-analys med hjälp av Event tracing for Windows (ETW). ETW finns inbyggt i Windows och kräver inga förändringar av din källkod för att
fungera. Det är bara att aktivera så börjar den spela in events som händer. Det finns en uppsjö monitorer inbyggda i Windows (över 1000 enligt Dina) som mäter allt från
CPU-användning, minnesanvändning, diskanvändning och metodanrop i en .NET-applikation till specifika saker som behövs internt i Windows. 

Det går så klart även att integrera detta i sina egna applikationer om man vill. I .NET genom att installera TraceEvent från Nuget. 

För att läsa loggarna och göra analyser av det hela kan man använda två verktyg, PerfView eller Windows Performance Anayzer (WPA). 

Min uppfattning är att detta är väldigt kraftfulla verktyg men att de mest är användbara för desktopapplikationer eller applikationer som körs på en server som du har
full kontroll över. Det passar sig alltså mindre bra serverless eller VMs (till viss del). 




Abusing C# more

Jon Skeet är ett av de stora namnen inom C# och det var inte så konstigt att hela salen var fullsatt när han körde din dragning om hur man utnyttjar konstigheter i C# för att allmänt retas med kollegorna och få riktigt underliga resultat. Med stor humor blandade han riktiga Wtf-moments med kod som faktiskt såg riktigt bra ut men som lätt spelar bort folk som inte är så insatta. Vad sägs t ex om att "var" (som används för implicit variabeldeklarationer) är ett "contextual keyword" vilket betyder att man kan skapa en klass med samma namn. Detta demonstrerade han genom att deklarera 'var x = "five";' och sedan loopar över detta värde. 

Han pratade även om sin favorit bland unicodetecken, nämligen "the Mongolian vowel separator", ett osynligt tecken som kompilatorn i vissa kontexter plockar bort och i vissa kontexter låter vara kvar. Eftersom tecknet är osynligt får man alla möjliga konstiga fel som är fruktansvärt svåra att hitta i källkoden.  

 Allt var inte skämt och konstiga grejor dock. Jon visade också en del smarta hack som man kan använda för att göra snygg kod, t ex hur man kan använda FormattableString för att formatera SQL via string interpolation samtidigt som man undviker SQL injection. 




Web apps can't really do *that*, can they?

Steve Sanderson från Microsoft visade upp nya fräcka tekniker för webbutveckling som precis kommit ur eller som snart är här. 

Service workers

Ett sätt att registrera javascript i browsern som körs även när användaren inte är kvar på sidan. Låter det farligt? Det är det inte då en service worker inte kan komma åt sidans innehåll utan kan bara lyssna och svara på events.  Användningsområden inkluderar t ex att cacha data så att siten funkar offline, synkar data som skickats när användaren var offline, köra schemalagda jobb eller skicka push notifications till användaren när något händer (även när användaren är på en annan site. Browserstöd: Chrome och Firefox har levererat det, Edge släpps snart och Safari har inte påbörjat utvecklingen. 


Web assembly 

En ny teknik som kompilerar språk till ett binärt format som kan köras direkt i browsern. Även gamla browsers får stöd via polyfills så att även gamla browsern (läs IE) kan ta del av alltihop. I dagsläget finns stöd för att kompilera C och C++ till web assembly men fler språk är på g, bland annat C# via ett projekt som heter Blazor! Självklart finns där stöd för Source maps vilket ger stöd att de bugga originalkoden direkt i browsern! Nerdgasm som heter duga ;) Browserstöd: Chrome och Firefox är klara, Edge är snart klar och Safari är på g. 


Credentials manager  

Tänk er "save my password" på steroider. Apier för att läsa ut credentials automatiskt (som sedan kan användas för t ex backend calls), synkning mellan device och inbyggda kontoväljare i browsern. Browserstödet var tyvärr mindre bra. Endast Chrome har levererat här och övriga överväger att implementera det. 


Payment requests  

Inbyggt stöd i browsern för att hantera betalningar. Javascript apier för att visa vad som ska betalas och hur mycket. Browsern visar sedan, beroende på platform, upp olika betalninngsalternativ där användaren får välja leveransadress, betalningssätt osv. Dessa sparas sedan i browsern så man som användare slipper fylla i informationen gång på gång. Ingen betalning görs av browsern utan man får bara ut information om t ex kreditkort, leveransadress osv som sedan skickas vidare till siten vanliga backend för hantering precis som vanligt. Browserstöd: Chrome och Edge har implementerat det helt, Firefox är på gång och Safari har inte påbörjat något ännu. 


Vill man kolla in nya standarder och hur långt de olika browserutvecklarna kommit kan man kolla på 



Life, Liberty and the Pursuit of APIness : The Secret to Happy Code

För min del blev dagens sista dragning "Life, Liberty and the Pursuit of APIness : The Secret to Happy Code" av Dylan Beattie. Dylan gick igenom hur man gör för att skapa "happy code", kod som utvecklarna trivs i. Som han själv sa så finns det få, om inga, projekt som lyckats där alla medarbetare varit olyckliga och missnöjda över allt. 

I stora drag var det följande som man ska tänka på när man sätter upp ett projekt för att få lyckliga utvecklare:

  • Se till att ha vettiga namn på grejor. "WebSite2" eller "WebApplication2016" gör ingen glad.
  • Det är OK att ha en brant inlärningskurva så länge man undviker "brick walls" så långt det bara går, dvs. ställen i inlärningsprocessen där folk känner att de helt stannat av.
  • När ett felmeddelande visas upp för en utvecklare, inkludera hur felet ska fixas. T ex "Du har glömt att köra kommando: <något kommando>". Som Dylan sa, "Don't be drunk Visual Studio" samtidigt som en screenshot med "Unspecified error" visas.
  • Logga så mycket det bara går och logga sen lite till! "If it moves log in case it stops. If it doesn't log in case it starts moving". :) 
  • User experience är inte bara för GUIn utan gäller också för libs, databaser, API och liknande.

Ingen direkt rocket science men ändå värt att tänka på.