Caveat with AddInitialRequestCultureProvider() in ASP.NET Core

AddInitialRequestCultureProvider() in ASP.NET Core localisation seems to have an undefined behaviour when it is used in both services and application builder configurations to add a custom RequestCultureProvider.

If you want to use a custom RequestCultureProvider to customise how the applicable culture is determined for an incoming HTTP request (for example, by looking up the chosen culture of a user in the database), you must configure the provider in the services collection as described in the section ‘Use a custom provider’.

You must also call IApplicationBuilder.UseRequestLocalization(), but you must not pass any argument to the method. If a RequestLocalizationOptions argument is specified here, it supersedes what is configured in the services collection, and your custom RequestCultureProvider does not work.

Typically, you configure the middleware in the application builder before the services. But in order to emphasise the significance of setting the localisation options only in the services configuration, I have reversed this order on purpose.

How can you minimize the impact of the persistence layer on your domain models?

This is a blog response to the question ‘How can you minimize the impact of the persistence layer on your domain models?’ posted on reddit /r/dotnet, showing how I would have implemented the solution in the purest form of OOP that is possible with C#.

(Note: The implementation of the factory and persistence classes is simplified for demonstration purposes.)

So here is the code. It is tested with .NET 5 on Windows 10.

using System;
using System.Data;
using System.Diagnostics;

namespace Example.Domain
{
    // Let's pretend this namespace is in a separate assembly so that
    // the 'internal' scope modifier applies

    public interface IAccount
    {
	string Username { get; }

	bool IsEnabled { get; }

	void Disable();
    }

    public interface ISavedAccount : IAccount
    {
	int Id { get; }
	
	void Enable();
    }

    // Not accessible from outside assembly
    internal abstract class AccountBase : IAccount
    {
	public string Username { get; protected set; }

	public bool IsEnabled { get; protected set; }

	internal AccountBase(string username)
	{
	    Username = username;
	}

	public void Disable()
	{
	    IsEnabled = false;
	}
    }

    // Not accessible from outside assembly
    internal class MyAccount : AccountBase
    {
	internal MyAccount(string username)
	    : base(username)
	{
	}
    }

    // Not accessible from outside assembly
    internal class MySavedAccount : AccountBase, ISavedAccount
    {
	public int Id { get; private set; }

	internal MySavedAccount(int id, string username, bool isEnabled)
	    : base(username)
	{
	    Id = id;
	    if (isEnabled) 
	    {
		Enable();
	    }
	}

	public void Enable()
	{
	    IsEnabled = true;
	}
    }

    public static class AccountFactory
    {
	public static IAccount Create(string username)
	{
	    return new MyAccount(username);
	}

	public static ISavedAccount Create(int id, string username, bool isEnabled)
	{
	    return new MySavedAccount(id, username, isEnabled);
	}
    }
}

namespace Example.Persistence
{
    using Example.Domain;

    public static class AccountStorage
    {
	static readonly DataTable dt;

	static AccountStorage()
	{
	    dt = new DataTable();
	    dt.Columns.Add("id", typeof(int));
	    dt.Columns.Add("username", typeof(string));
	    dt.Columns.Add("enabled", typeof(bool));
	}

	public static DataRow AddAccountRow(ref IAccount account)
	{
	    var dr = dt.NewRow();
	    dr["id"] = dt.Rows.Count+1;
	    dr["username"] = account.Username;
	    dr["enabled"] = account.IsEnabled;
	    dt.Rows.Add(dr);

	    // This variable does not point to a valid account after it has been saved
	    account = null;

	    return dr;
	}

	public static DataRow UpdateAccountRow(ISavedAccount account)
	{
	    var dr = FindAccountRow(account.Id);
	    dr["username"] = account.Username;
	    dr["enabled"] = account.IsEnabled;
	    return dr;
	}

	public static DataRow FindAccountRow(int id)
	{
	    for (var i=0; i<dt.Rows.Count; ++i)
	    {
		DataRow dr = dt.Rows[i];
		if (((int)dr["id"]) == id)
		{
		    return dr;
		}
	    }
	    return null;
	}
    }
}

namespace Example.Client
{
    // Let's pretend this namespace is in a separate assembly so that it
    // doesn't see the 'internal' definitions from the Example.Domain
    // namespace

    using Example.Domain;
    using Example.Persistence;

    class Program
    {
        static void Main(string[] args)
        {
	    var account = AccountFactory.Create("joebloggs");

	    // FAIL! A new account does not have an id
	    // Debug.Assert(account.Id > 0);

	    // FAIL! A new account cannot be enabled
	    // account.Enable();

	    var newrow = AccountStorage.AddAccountRow(ref account);

            Debug.Assert(account == null, "The account object is no longer valid");

	    Debug.Assert(((int)newrow["id"]) > 0, "The 'id' value is set");
	    Debug.Assert("joebloggs".Equals(newrow["username"]), "The 'username' value is set");
	    Debug.Assert(! (bool)newrow["enabled"], "The 'enabled' value is not set");

	    var savedaccount = AccountFactory.Create((int)newrow["id"], (string)newrow["username"], (bool)newrow["enabled"]);
	    savedaccount.Enable();
	    Debug.Assert(savedaccount.IsEnabled, "The account is enabled");

	    var unused = AccountStorage.UpdateAccountRow(savedaccount);

	    var loadedrow = AccountStorage.FindAccountRow(savedaccount.Id);
	    var loaded = AccountFactory.Create((int)loadedrow["id"], (string)loadedrow["username"], (bool)loadedrow["enabled"]);

	    Debug.Assert(loaded.Id > 0, "An id is assigned");
	    Debug.Assert("joebloggs".Equals(loaded.Username), "The username is set correctly");
	    Debug.Assert(loaded.IsEnabled, "The account is enabled");
        }
    }
}

The line below might be questionable because we are effectively passing ownership of the account object to the persistence layer, but we could assume that there is a contract that formalises this.

	    // This variable does not point to a valid account after it has been saved
	    account = null;

.vimrc

packadd! matchit
filetype plugin indent on
syntax on
set directory=~\vimfiles\swap undofile undodir=~\vimfiles\undo ruler visualbell incsearch ignorecase hlsearch smartcase showmatch autoindent backspace=2 wildmenu
set grepprg=rg.exe\ --vimgrep\ -i
set grepformat=%f:%l:%c:%m
nnoremap <leader>b <Esc>:ls<Cr>:b *
nnoremap <leader>e <Esc>:e *
nnoremap <leader>s <Esc>:split +b *
nnoremap <leader>E <Esc>:e %:h\*
nnoremap <leader>S <Esc>:s %:h\*
nnoremap <leader>w <Esc>:bw
nnoremap <leader>y "+y
vnoremap <leader>y "+y
nnoremap <leader>Y "+Y
nnoremap <leader>p "+p
vnoremap <leader>p "+p
nnoremap <leader>P "+P
nnoremap <BS>      <Esc>:let @/=""<Cr>
nnoremap <C-s>     <Esc>:up<Cr>
inoremap <C-s>     <Esc>:up<Cr>
nnoremap <A-Down>  <Esc>:cnext<Cr>
nnoremap <A-Up>    <Esc>:cprevious<Cr>

rg.exe is part of ripgrep.

Disabling Bluetooth auto-suspend with module options

In my previous post I showed how to restart Bluetooth on Debian Linux. Here I explain how to disable Bluetooth auto-suspend by using a kernel module option.

Kernel modules can be passed parameters that affect how they work. The parameters accepted by a module can be identified with the command modinfo. In the example below modinfo btusb displays the parameters for the Bluetooth module.

$ sudo modinfo btusb
...
parm:           disable_scofix:Disable fixup of wrong SCO buffer size (bool)
parm:           force_scofix:Force fixup of wrong SCO buffers size (bool)
parm:           enable_autosuspend:Enable USB autosuspend by default (bool)
parm:           reset:Send HCI reset command on initialization (bool)

The option enable_autosuspend is the one that interests us. It can be set in a configuration file in directory /etc/modprobe.d/.

options btusb enable_autosuspend=0

Here I have file btusb_autosuspend-disable.conf to disable Bluetooth auto-suspend.

Restarting Bluetooth on Debian Linux

On my laptop I use a Bluetooth keyboard and a Bluetooth mouse. Occasionally the Bluetooth adapter in the laptop shuts off completely, which means that it is not even possible to restart the Bluetooth service with sudo systemctl restart bluetooth.service.

My troubleshooting points to powersaving as the cause of this, but the TLP setting that is supposed to prevent autosuspend on Bluetooth devices does not seem to prevent this sudden death of the Bluetooth connection. As a temporary workaround I am using the commands below to restart Bluetooth from the shell.

$ sudo rmmod btusb && sudo modprobe btusb && sudo systemctl restart bluetooth.service

This solution works on Debian testing bullseye with kernel x86_64 Linux 5.5.0-2-amd64.

Centrino Ultimate N-6300 slow to connect to Wi-Fi network

Wi-Fi connections from my laptop became unstable after I upgraded it to Ubuntu 19.04. To get them to work, I had to turn the Wi-Fi adapter on and off several times, which quickly became annoying.

The following attempts to fix the problem were unsuccessful:

  • disabling IPv6
  • disabling power-saving on the Wi-Fi adapter
  • setting bt_coex_active=0 during kernel loading to disable Bluetooth/Wi-Fi interference protection

Eventually the correct solution was to disable 802.11n with the following procedure:

  1. Edit or create a configuration file under /etc/modprobe.d (e.g. iwlwifi_custom.conf).
  2. Add this line and save the file.
    options iwlwifi 11n_disable=1
  3. Reload the iwlwifi module.
    sudo rmmod iwldvm
    sudo rmmod iwlwifi
    sudo modprobe iwlwifi
  4. Connect to the Wi-Fi network.

SO #57225262—Inputting list of passwords in a class

Stack Overflow question ‘Inputting list of passwords in a class’ is more interesting as an object-oriented design (OOD) exercise than as a debugging exercise, but it also provides an opportunity to practise some Python programming.

The requirements identified in the problem are:

  • represent a set of credentials comprised of a username and a password;
  • represent a user account made up of an identifier and one active set of credentials and zero or more inactive credentials;
  • store user accounts that can be retrieved subsequently by username;
  • validate a given set of credentials, using the stored user accounts.

Additionally, a user account has the following constraints:

  • It must be uniquely identifiable by the username of the active set of credentials.
  • A set of credentials must be used only once for a given user account.

The design model consists of multiple classes, each addressing a single responsibility as follows.

ClassResponsibility
Credentialsrepresent a set of credentials
UserAccountrepresent a user account
AccountStorestore user accounts, enforcing the uniqueness constraint
Authenticationvalidate supplied credentials

The program code implements the model very faithfully and uses the same class names, thus making it easy to reason about. It has been tested with Python 2.7.15rc1 and has been checked for PEP8 compliance.

NOTES

For brevity, the solution presented here does not:

  • implement best practices used for security in real-world scenarios, such as salting and hashing;
  • enforce uniqueness of user account identifiers;
  • consider performance factors.

In lieu of conventional unit tests, a main routine exercises use-cases to ensure that the program works properly.

class Credentials:

    def __init__(self, username, password):
        self.username = username
        self.password = password

    def has_username(self, username):
        return self.username == username

    def matches(self, credentials):
        return self.username == credentials.username and \
            self.password == credentials.password

class UserAccount:

    def __init__(self, user_id):
        self.user_id = user_id
        self.active_credentials = None
        self.past_credentials = []

    def add(self, credentials):
        self._check_uniqueness(credentials)
        if self.active_credentials is None:
            self.active_credentials = credentials
        else:
            self.past_credentials.append(self.active_credentials)
            self.active_credentials = credentials

    def has_username(self, username):
        return self.active_credentials.has_username(username)

    def has_same_username(self, user_account):
        return self.has_username(user_account.active_credentials.username)

    def has_credentials(self, credentials):
        return self.active_credentials is not None and \
            self.active_credentials.matches(credentials)

    def _check_uniqueness(self, credentials):
        if self.has_credentials(credentials):
            raise Exception('These credentials are currently in use.')
        for c in self.past_credentials:
            if c.matches(credentials):
                raise Exception(
                        'These credentials have been used in the past.')

class AccountStore:

    def __init__(self):
        self.user_accounts = []

    def add(self, user_account):
        self._check_uniqueness(user_account)
        self.user_accounts.append(user_account)

    def find_by_username(self, username):
        for ua in self.user_accounts:
            if ua.has_username(username):
                return ua
        return None

    def _check_uniqueness(self, user_account):
        for ua in self.user_accounts:
            if ua.has_same_username(user_account):
                raise Exception(
                        'An account with the same username is already active.')

class Authentication:

    def __init__(self, account_store):
        self.account_store = account_store

    def validate(self, credentials):
        user_account = self.account_store.find_by_username(
                credentials.username)
        if user_account is None:
            return False
        return user_account.has_credentials(credentials)

if __name__ == '__main__':
    credentials = Credentials('user1', 'password1')
    user_account = UserAccount(101)
    user_account.add(credentials)

    account_store = AccountStore()
    account_store.add(user_account)

    user_account1 = account_store.find_by_username('user1')
    print 'user_account1', user_account1

    user_account2 = account_store.find_by_username('user2')
    print 'user_account2', user_account2

    authentication = Authentication(account_store)
    print 'Expecting True...', authentication.validate(
            Credentials('user1', 'password1'))
    print 'Expecting False...', authentication.validate(
            Credentials('user2', 'password1'))
    print 'Expecting False...', authentication.validate(
            Credentials('user1', 'password2'))

    user_account.add(Credentials('user1', 'password2'))
    print 'Expecting True...', authentication.validate(
            Credentials('user1', 'password2'))
    print 'Expecting False...', authentication.validate(
            Credentials('user1', 'password1'))

    try:
        user_account.add(Credentials('user1', 'password1'))
    except Exception:
        print 'Expecting exception... Pass'

    try:
        user_account.add(Credentials('user2', 'password1'))
        print 'Not expecting exception... Pass'
        print 'Expecting True...', authentication.validate(
                Credentials('user2', 'password1'))
    except Exception:
        print 'Not expecting exception... Fail'

    try:
        user_account1 = UserAccount(102)
        user_account1.add(Credentials('user1', 'whatever'))
        account_store.add(user_account1)
        print 'Expecting True...', authentication.validate(
                Credentials('user1', 'whatever'))
    except Exception:
        print 'Not expecting exception... Fail'

    try:
        user_account2 = UserAccount(103)
        user_account2.add(Credentials('user1', 'whatever'))
        account_store.add(user_account1)
        print 'Expecting exception... Fail'
    except Exception:
        print 'Expecting exception... Pass'


The output of the program is:

EY@LENNY:~/Source/junk/python/pwman$ python all.py
user_account1 <__main__.UserAccount instance at 0x7faa36f11170>
user_account2 None
Expecting True... True
Expecting False... False
Expecting False... False
Expecting True... True
Expecting False... False
Expecting exception... Pass
Not expecting exception... Pass
Expecting True... True
Expecting True... True
Expecting exception... Pass
EY@LENNY:~/Source/junk/python/pwman$

Programming Arduino in Atmel Studio

As a fun way to improve my C, I started programming the Arduino using Atmel Studio instead of the friendlier Arduino IDE.

Below is my very first program. It blinks a red LED and a white LED according to a preset pattern.

#define F_CPU 16000000UL

#include <avr/io.h>
#include <util/delay.h>

struct Led
{
    int pin;
    int blinks;
    int on_duration;
    int off_duration;
};

void delay_ms(int ms)
{
    while (ms-- > 0) {
        _delay_ms(1);
    }
}

void blink(const struct Led* const led)
{
    for (int i = 0; i < led->blinks; i++) {
        PORTB |= led->pin;
        delay_ms(led->on_duration);
        PORTB &= ~led->pin;
        delay_ms(led->off_duration);
    }
}

int main(void)
{
    const struct Led white_led = { 1<<PB6, 10, 100, 500 };
    const struct Led red_led = { 1<<PB7, 10, 500, 1000 };

    DDRB |= white_led.pin;
    DDRB |= red_led.pin;
    while (1) {
        blink(&white_led);
        blink(&red_led);
    }
}

With C in Atmel Studio and the AVR-LIBC library, IO ports are manipulated by changing bit patterns in the registers associated with the relevant ports. This requires a good understanding of bitwise operations in C despite the availability of macros to simplify the task.

For example, to set pin 12 of the Arduino to output mode, bit 6 of register DDRB must be set to 1. To do so requires an | (OR) operation with a bit pattern operand where bit 6 is set to 1 and the rest set to 0, so that the states of the other bits in the register are not disturbed.

Using macros DDRB and PB6 defined in AVR-LIBC, this is done like this: DDRB |= 1 << PB6 .

If you are new to C and are unfamiliar with macros, you might wonder about that statement. Besides, DDRB and PB6 are not referenced anywhere else in my program, so how does this line of code work?

DDRB is a macro that expands into C code to dereference the address of the register associated with setting the mode for pin 12, and PB6 is just a symbolic constant for the value 6. In the statement above, by shifting the value 1 left by 6 positions, we create a new value which is then applied to the bit pattern stored at the dereferenced address with an | operation to turn bit 6 of the register to 1. In this case, this sets pin 12 to output mode.

In a nutshell, the sequence of operations is as follows.

Step 1:

1 << 6 = 01000000

Step 2:

Assuming the register DDRB is initially 00000001:

00000001 | 01000000 = 01000001

In my C program, the result of step 1 is assigned to struct field Led.pin and is used as the second operand for the operation in step 2.

It took about an hour to refresh my knowledge of bitwise operations, but the real challenge was interpreting the Arduino schema and the information in datasheets, especially to find the right registers to manipulate.

Hacking SSL support into smtpop.dll

We use smtpop.dll in one application to retrieve email from a POP3 mailbox. Today we had to connect to a mailbox over SSL, which smtpop.dll cannot do.

Our code to retrieve email is in a façade class, so I expected a simple replacement of smtpop.dll with another library and calling new methods. But the tight coupling of the façade with the interface of smtpop.dll classes meant that we needed something that exposed the exact same interface.

After trying several things, I decompiled smtpop.dll and created a new class with the interface that we needed. I was lucky that only two methods, Open and Quit, needed to be changed.

namespace ClassLibrary4
{
    using System.IO;
    using System.Net.Security;
    using System.Net.Sockets;

    using SmtPop;

    public class Pop3ClientWithSsl : POP3Client
    {
        #region Fields

        private SslStream sslStream;

        #endregion

        #region Constructors and Destructors

        public Pop3ClientWithSsl()
        {
            this.UseSsl = true;
        }

        #endregion

        #region Public Properties

        public bool UseSsl { get; set; }

        #endregion

        #region Public Methods and Operators

        public new int Open(string hostname, int port, string username, string password)
        {
            if (this.UseSsl)
            {
                return this.OpenWithSsl(hostname, port, username, password);
            }

            return base.Open(hostname, port, username, password);
        }

        public new string Quit()
        {
            try
            {
                return base.Quit();
            }
            finally
            {
                this.m_streamReader.Close();
                this.m_streamWriter.Close();
                if (this.UseSsl)
                {
                    this.sslStream.Close();
                }
            }
        }

        #endregion

        #region Methods

        private int OpenWithSsl(string hostname, int port, string username, string password)
        {
            this.m_host = hostname;
            this.m_port = port;
            this.m_user = username;
            this.m_tcpClient = new TcpClient(hostname, port);

            this.m_netStream = this.m_tcpClient.GetStream();
            this.sslStream = new SslStream(this.m_netStream, false);
            this.sslStream.AuthenticateAsClient(hostname);

            this.m_streamReader = new StreamReader(this.sslStream);
            this.m_streamWriter = new StreamWriter(this.sslStream) { AutoFlush = true };

            string welcome = this.m_streamReader.ReadLine();
            if (welcome != null && welcome.StartsWith(+OK))
            {
                return this.SendLogin(username, password);
            }

            this.m_error = welcome;
            return -1;
        }

        #endregion
    }
}

The methods of class POP3Client were not virtual, but fortunately some of the class members were in protected scope and were, therefore, accessible in the new class. I rewrote the Open and Quit methods as new methods. This made them no longer polymorphic, thus forcing us to replace calls to POP3Client with calls to Pop3ClientWithSsl everywhere in the code.