<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Michael's Dev Blog]]></title><description><![CDATA[Michael's Dev Blog]]></description><link>https://blog.lehmamic.ch</link><generator>RSS for Node</generator><lastBuildDate>Mon, 14 Sep 2026 02:45:09 GMT</lastBuildDate><atom:link href="https://blog.lehmamic.ch/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[My favorite unit test tech stack for .Net]]></title><description><![CDATA[15 years ago, C# did not have a large variety of unit test frameworks and supporting libraries.
That has changed in the meantime. The community has grown considerably and so has the range of libraries and tools that can be used for unit tests. While ...]]></description><link>https://blog.lehmamic.ch/my-favorite-unit-test-tech-stack-for-net</link><guid isPermaLink="true">https://blog.lehmamic.ch/my-favorite-unit-test-tech-stack-for-net</guid><category><![CDATA[code]]></category><category><![CDATA[.NET]]></category><category><![CDATA[unit testing]]></category><category><![CDATA[Testing]]></category><category><![CDATA[TechStack]]></category><dc:creator><![CDATA[Michael Lehmann]]></dc:creator><pubDate>Mon, 27 Feb 2023 11:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1699463811709/0c80b240-de2f-4534-87ed-81c038cff25e.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>15 years ago, C# did not have a large variety of unit test frameworks and supporting libraries.</p>
<p>That has changed in the meantime. The community has grown considerably and so has the range of libraries and tools that can be used for unit tests. While <a target="_blank" href="http://Asp.Net">Asp.Net</a> Core is the absolute standard for a REST API, there is hardly any software project that uses the same setup for unit tests.</p>
<p>The choice of a unit test project setup is also often very much driven by developer preference and opinions. I have even seen developers insisting on a specific unit test framework at the customer site.</p>
<p>Even though no project has ever failed with the selection of the unit test framework, it does have an impact on the productivity, maintainability, and readability of the code. And of course, I also have my preferences, which I would like to describe here.</p>
<h2 id="heading-the-test-framework">The test framework</h2>
<p>Let's first discuss the unit test framework we use.</p>
<p>I started using <a target="_blank" href="https://xunit.net/">XUnit</a> during the early days of .Net Core. At that time there was no framework besides XUnit that ran on .Net Core. The MSTest framework was ported later, but I like the ability of XUnit to write simple data-driven tests. Also, XUnit provides an easy way to share context between tests with the fixtures. This also makes it easy to write database and integration tests. There would also be <a target="_blank" href="https://nunit.org/">NUnit</a> in the field, but I never like NUnit, since it is quite heavyweight compared to XUnit.</p>
<h2 id="heading-the-mocking-library">The mocking library</h2>
<p>Mocking is also an important aspect of unit testing. I have used <a target="_blank" href="https://nsubstitute.github.io/">NSubstitute</a> and <a target="_blank" href="https://github.com/moq/moq4">Moq</a> in the past. I like Moq a bit more since it is a bit more powerful about mocking protected members and most of the projects I joined used Moq, so it is quite popular.</p>
<p>But I don't use Moq alone, I always use it in combination with <a target="_blank" href="https://github.com/moq/Moq.AutoMocker">Moq.AutoMocker</a>. AutoMocker creates an instance of a target class and automatically mocks all its dependencies. When I introduce a new constructor parameter in a service I want only touch the tests that test some specific aspects of a new dependency and not all tests. AutoMocker helps with this approach since it adds the ability to create an instance of a class and automatically mocks all dependencies.</p>
<p>Example from the Moq.AutoMocker documentation:</p>
<pre><code class="lang-cs"><span class="hljs-keyword">var</span> mocker = <span class="hljs-keyword">new</span> AutoMocker();
<span class="hljs-keyword">var</span> car = mocker.CreateInstance&lt;Car&gt;();

car.DriveTrain.ShouldNotBeNull();
car.DriveTrain.ShouldImplement&lt;IDriveTrain&gt;();
Mock&lt;IDriveTrain&gt; mock = Mock.Get(car.DriveTrain);
</code></pre>
<h2 id="heading-the-fake-data-generator">The fake data generator</h2>
<p>In a project with large entities, it is a big effort to provide the test data. In various projects we implemented so-called entity generators. Entity generators are simple and configurable classes to create entity instances.</p>
<pre><code class="lang-cs"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">AgendaItemBuilder</span> : <span class="hljs-title">EntityBuilder</span>&lt;<span class="hljs-title">AgendaItem</span>&gt;
{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span> _title;

    <span class="hljs-function"><span class="hljs-keyword">public</span> AgendaItemBuilder <span class="hljs-title">WithTitle</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> title</span>)</span>
    {
        _title = title;
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">async</span> Task&lt;AgendaItem&gt; <span class="hljs-title">EnhanceEntityAsync</span>(<span class="hljs-params">AgendaItem entity</span>)</span>
    {
        entity.Title = <span class="hljs-keyword">string</span>.IsNullOrEmpty(_title) ? <span class="hljs-string">$"Title of <span class="hljs-subst">{<span class="hljs-keyword">nameof</span>(AgendaItem)}</span> <span class="hljs-subst">{unique}</span>"</span> : _title;

        <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> Task.FromResult(entity);
    }
}
</code></pre>
<p>This can be used for following:</p>
<pre><code class="lang-cs"><span class="hljs-keyword">var</span> builder = <span class="hljs-keyword">new</span> AgendaItemBuilder()
    .WithTitle(<span class="hljs-string">"My Title"</span>);
<span class="hljs-keyword">var</span> entity = builder.Build();
</code></pre>
<p>The advantage of those builders is, that you have a shared class preparing the test data for a specific entity. But it is still a big effort to write and maintain them. Another drawback is that the test data contains static data which are always the same until it is specified otherwise.</p>
<p>A while ago I came across a library called <a target="_blank" href="https://github.com/bchavez/Bogus">Bogus</a>. Bogus uses a random generator to generate test data. The test data is context-specific, e.g. addresses, names, phone numbers, etc. Bogus has a huge list of data generators. We can inherit from a Bogus faker and share its configuration.</p>
<pre><code class="lang-cs"><span class="hljs-keyword">public</span> <span class="hljs-keyword">sealed</span> <span class="hljs-keyword">class</span> <span class="hljs-title">AgendaItemFaker</span> : <span class="hljs-title">Faker</span>&lt;<span class="hljs-title">AgendaItemFaker</span>&gt;
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">AgendaItemFaker</span>(<span class="hljs-params"></span>)</span>
    {
        RuleFor(c =&gt; c.Name, f =&gt; f.Random.String(<span class="hljs-number">1</span>, <span class="hljs-number">10</span>));
    }
}
</code></pre>
<p>A fake can be used like the following snippet:</p>
<pre><code class="lang-cs"><span class="hljs-keyword">var</span> faker = <span class="hljs-keyword">new</span> AgendaItemFaker();
<span class="hljs-keyword">var</span> item = faker.Generate();
</code></pre>
<p>I don't use Bogus alone, I always use it in combination with <a target="_blank" href="https://github.com/nickdodd79/AutoBogus">AutoBogus</a>. AutoFaker is a wrapper of the Bogus Faker class and provides conventions and integration into Moq which makes everything fit together.</p>
<p>Our fake looks like this now:</p>
<pre><code class="lang-cs"><span class="hljs-keyword">public</span> <span class="hljs-keyword">sealed</span> <span class="hljs-keyword">class</span> <span class="hljs-title">AgendaItemFaker</span> : <span class="hljs-title">Faker</span>&lt;<span class="hljs-title">AgendaItemFaker</span>&gt;
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">AgendaItemFaker</span>(<span class="hljs-params"></span>)</span>
    {
        Configure(builder =&gt;
                {
                        builder.WithConventions();
                });
    }
}
</code></pre>
<p>With this, the effort to write and maintain my test data generators are reduced to a minimum.</p>
<h2 id="heading-summary">Summary</h2>
<p>Here we are, at the end of the article. Testing code should be as clean and well-maintained as our productive code. My tech stack has been built with the goal of reducing boilerplate code and the maintainability effort of the tests to a minimum.</p>
<p>I'm using the following libraries in combination:</p>
<ul>
<li><p><a target="_blank" href="https://xunit.net/">XUnit</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/moq/moq4">Moq</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/moq/Moq.AutoMocker">Moq.AutoMocker</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/bchavez/Bogus">Bogus</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/nickdodd79/AutoBogus">AutoBogus</a></p>
</li>
</ul>
<p>What is your opinion? Do you use a different tech stack? Did I forget something?</p>
]]></content:encoded></item><item><title><![CDATA[Implement pagination with NextJS and MongoDB]]></title><description><![CDATA[If you read my blog regularly you may have noticed that I recently introduced pagination to my article list. In order of that, I would like to explain how I implemented that with the tech stack of my blog - NextJS and MongoDB.
Pagination is one of th...]]></description><link>https://blog.lehmamic.ch/implement-pagination-with-nextjs-and-mongodb</link><guid isPermaLink="true">https://blog.lehmamic.ch/implement-pagination-with-nextjs-and-mongodb</guid><category><![CDATA[code]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[Next.js]]></category><category><![CDATA[Node.js]]></category><dc:creator><![CDATA[Michael Lehmann]]></dc:creator><pubDate>Wed, 23 Nov 2022 11:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1699463615579/5f803b42-cfc0-45e0-93b8-400d0a7f4a3d.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you read my blog regularly you may have noticed that I recently introduced pagination to my article list. In order of that, I would like to explain how I implemented that with the tech stack of my blog - <a target="_blank" href="https://nextjs.org/">NextJS</a> and <a target="_blank" href="https://www.mongodb.com/">MongoDB</a>.</p>
<p>Pagination is one of the major mechanisms to reduce page loading time and is widely adopted. It is a good practice to do pagination when you have many rows, resp. an unknown amount of rows. It can help to improve the performance with three aspects:</p>
<ol>
<li><p>It reduces the query time on the database</p>
</li>
<li><p>It reduces the payload size returned to the client</p>
</li>
<li><p>It reduces the amount of elements the browser needs to render</p>
</li>
</ol>
<p>Especially the third point can help a lot when there are some expensive elements such as images per data row.</p>
<h2 id="heading-how-does-pagination-generally-work">How does pagination generally work</h2>
<p>The mechanism is actually quite simple. The data as a whole needs to be split into junks of the same size. These junks we call pages.</p>
<p><img src="https://ik.imagekit.io/lehmamic/leh-web/pagination_p1u0JPQBo.png?ik-sdk-version=javascript-1.4.3&amp;updatedAt=1669098375547" alt="Row junks|469x155" /></p>
<p>Every page has a <code>page number</code>, a <code>size</code> , and an <code>offset</code>. In order to get a reliable result the data <strong>needs to be sorted</strong>.</p>
<p>We now can translate this into a database query. Usually, the databases don't know the concept or pages. But they have a syntax to <code>skip</code> and <code>take</code> a certain amount of rows. In terms of SQL, it would be <code>offset</code> and <code>fetch</code>. We can translate the page number into this syntax. Assuming the pages start with <code>1</code> we can do following query <code>skip = (page - 1) * size, take = size</code>.</p>
<p>A full <em>SQL</em> query loading page 2 could look like this:</p>
<pre><code class="lang-sql"><span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> [Posts]
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> [Published]
<span class="hljs-keyword">OFFSET</span> <span class="hljs-number">10</span> <span class="hljs-keyword">ROWS</span>
<span class="hljs-keyword">FETCH</span> <span class="hljs-keyword">NEXT</span> <span class="hljs-number">10</span> <span class="hljs-keyword">ROWS</span> <span class="hljs-keyword">ONLY</span>;
</code></pre>
<p>If we know the total amount of rows, we can calculate the total page count as well <code>Math.Ceil(totalRowCount / size)</code>.</p>
<h2 id="heading-implementing-pagination-with-nextjs-server-side-rendering">Implementing pagination with NextJS server-side rendering</h2>
<p>Since I have a database, concrete MongoDB, for storing my articles in place I need to use the SSR mechanism of NextJS to pre-render the articles on the server side.</p>
<p>Assuming I have a UI which is illustrated in the next image. It contains a table of data and controls for navigating through the pages. In my case, I allow only navigation forward and backwards. In some implementations, there are controls for a dedicated page. But in the end, this does not matter.</p>
<p><img src="https://ik.imagekit.io/lehmamic/leh-web/paged-table_o4Pxab0tE.png?ik-sdk-version=javascript-1.4.3&amp;updatedAt=1669188633430" alt="Pagination UI|253x169" /></p>
<p>Having the design in place we need a way to tell the server-side rendering which page to load. We do that by passing it with the URL as a query parameter <a target="_blank" href="https://domain/blog?page=2"><code>https://domain/blog?page=2</code></a>.</p>
]]></content:encoded></item><item><title><![CDATA[An introduction to task-based UI's]]></title><description><![CDATA[A good friend of mine once told me about a conference talk that was about so-called task-based UIs. I considered this architecture style for an application in a private bank which was responsible for checking the suitability for finance instrument tr...]]></description><link>https://blog.lehmamic.ch/an-introduction-to-task-based-uis</link><guid isPermaLink="true">https://blog.lehmamic.ch/an-introduction-to-task-based-uis</guid><category><![CDATA[architecture]]></category><category><![CDATA[ui-composition]]></category><category><![CDATA[Microfrontend]]></category><category><![CDATA[Web Components]]></category><dc:creator><![CDATA[Michael Lehmann]]></dc:creator><pubDate>Thu, 10 Nov 2022 11:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1699463153276/3ef933df-2a94-4a41-9578-f9e49771c06a.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A good friend of mine once told me about a conference talk that was about so-called task-based UIs. I considered this architecture style for an application in a private bank which was responsible for checking the suitability for finance instrument transactions.</p>
<p>I'm on a project with a completely different topic now. However, the software architecture and the way business entities are getting processed are quite similar. So I remembered this architectural pattern from those times. Since I consider that a very good fit, it might be worth an article.</p>
<h2 id="heading-pipes-and-filters">Pipes and filters</h2>
<p>Task-based UI is a special kind of micro frontend architecture pattern invented for a very specific use case.</p>
<p>Imagine we have a business entity that follows a well-defined business process during its lifetime. We can model that with the well-known <a target="_blank" href="https://learn.microsoft.com/en-us/azure/architecture/patterns/pipes-and-filters">pipes and filter architecture pattern</a>.</p>
<p><img src="https://ik.imagekit.io/lehmamic/leh-web/pipe-and-filter_2w8IuMmcCc.png?ik-sdk-version=javascript-1.4.3&amp;updatedAt=1668064476609" alt="Pipes and Filter|600x113" /></p>
<p>This pattern is quite flexible. It can enforce the sequential flow of the business process. But it is not necessary. Certain process steps can also be handled in parallel.</p>
<p>It fits very well into a microservice architecture where every task along the business process gets handled by its own microservice. But what about the UI for such an application? We don't want to lose the benefit of the decoupling gained through the microservice architecture. I wrote a few articles about this topic. It basically leads us to go in the direction of <a target="_blank" href="https://micro-frontends.org/">micro frontends</a> or <a target="_blank" href="https://scs-architecture.org/">self-contained systems</a>.</p>
<p>We can actually go a step further and introduce an SCS per process step. Every SCS has its own UI and is responsible for handling the process step it is responsible for in its own UI.</p>
<p><img src="https://ik.imagekit.io/lehmamic/leh-web/pipes-and-filters-with-scs_1__ozJIgqTAE.png?ik-sdk-version=javascript-1.4.3&amp;updatedAt=1668097835092" alt="Pipes and Filter with SCS|741x191" /></p>
<h2 id="heading-the-idea-behind-a-task-based-ui">The idea behind a task-based UI</h2>
<p>There is actually nothing new until now. Anything I described so far we do in an SCS system as well. The idea of the task-based UI starts with the need for an overview of the entities describing their status along the process. This is not a simple thing since the processing of the entities is now distributed.</p>
<p>We could build an SCS gathering all the data from the process-related data over an API and build a UI that aggregates this data. This will build up a strong dependency on those SCS and this is something we actually want to avoid. We have a loose coupling through the asynchronous nature of the pipes and filter architecture and destroy it more or less with an aggregation.</p>
<p>What is, when we would leverage the micro frontend approach? Every SCS can provide a frontend snippet showing their piece of status from the corresponding entity. This is will return the responsibility of displaying its own data to its origin and we can loosely couple it in the frontend. This UI composition pattern is called task-based UI.</p>
<p><img src="https://ik.imagekit.io/lehmamic/leh-web/task-based-ui_jsvwfUe1x.png?ik-sdk-version=javascript-1.4.3&amp;updatedAt=1668098937936" alt="Task based UI|741x407" /></p>
<h2 id="heading-how-we-can-implement-this-technically">How we can implement this technically?</h2>
<p>Task-based UI's are a special kind of micro frontends. Basically, every technical approach of the micro frontend architecture pattern also works for task-based UIs. A modern way to build micro frontends will leverage the new standard of web components. I will not explain how to build micro frontends and web components in this article. But give you a small example of how it could look like using them. Important is, that we pass in only the identifier of the processed entity. The rest is the responsibility of the corresponding microservice or SCS:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"...../financial-instruments.js"</span> /&gt;</span><span class="xml">
<span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"...../suitability-check.js"</span> /&gt;</span><span class="xml">
<span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"...../document-handover.js"</span> /&gt;</span><span class="xml">
<span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"...../contact-notes.js"</span> /&gt;</span><span class="xml">

<span class="hljs-tag">&lt;<span class="hljs-name">fi-transaction-proposal</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">financial-instruments</span> <span class="hljs-attr">order-id</span>=<span class="hljs-string">"1"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">suitability-check</span> <span class="hljs-attr">order-id</span>=<span class="hljs-string">"1"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">document-handover</span> <span class="hljs-attr">order-id</span>=<span class="hljs-string">"1"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">contact-notes</span> <span class="hljs-attr">order-id</span>=<span class="hljs-string">"1"</span> /&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">fi-transaction-proposal</span>&gt;</span></span></span></span></span>
</code></pre>
<h2 id="heading-summary">Summary</h2>
<p>Entities that will go through several steps of a business process can be distributed with the pipes and filter architecture pattern. Aggregating and displaying the data from the different services/steps will break the benefits of the distributed and loosely coupled architecture. We can mitigate this problem by introducing the task-based UI architecture pattern. This is a special type of micro frontends dedicated to displaying the status(es) of entities that go through a distributed business process.</p>
<p>What do you think about this architectural pattern? Did you already have some experience with something similar? Leave a comment and discuss it with me.</p>
]]></content:encoded></item><item><title><![CDATA[Implement reading time for your blog articles]]></title><description><![CDATA[I recently implemented a small hint showing the reading time of an article in my blog. This is a functionality used quite much when reading some technical articles written by the developer community. It helps me to decide whether I have the time to r...]]></description><link>https://blog.lehmamic.ch/implement-reading-time-for-your-blog-articles</link><guid isPermaLink="true">https://blog.lehmamic.ch/implement-reading-time-for-your-blog-articles</guid><category><![CDATA[code]]></category><category><![CDATA[TypeScript]]></category><dc:creator><![CDATA[Michael Lehmann]]></dc:creator><pubDate>Tue, 01 Nov 2022 11:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/o0Qqw21-0NI/upload/9e4e890bdb7c694fab93aaa74d2f8032.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I recently implemented a small hint showing the reading time of an article in my blog. This is a functionality used quite much when reading some technical articles written by the developer community. It helps me to decide whether I have the time to read an article just now or if I'm going to put it on my stack. So I thought it would be nice to provide my readers with the same flexibility.</p>
<blockquote>
<p>According to <a target="_blank" href="https://help.medium.com/hc/en-us/articles/214991667-Read-time">Medium</a> the reading time is based on the average reading speed of an adult (roughly 265 words per minute).</p>
</blockquote>
<p>To get a basic implementation of this I could get rid of the Markdown markings and count the words by splitting the string by spaces. Images add additional time to the reading time and this approach would not consider that.</p>
<p>Luckily I found a nice npm package <a target="_blank" href="https://www.npmjs.com/package/reading-time">reading-time</a> that does this for me. It can handle plain text, HTML, and markdown.</p>
<p>All I need to do is install the package.</p>
<pre><code class="lang-bash">npm install reading-time --save-dev
</code></pre>
<p>And use it to convert my markdown content to an estimated reading time</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> readingTime, { ReadTimeResults } <span class="hljs-keyword">from</span> <span class="hljs-string">'reading-time'</span>;

<span class="hljs-keyword">const</span> result = readingTime(post.content)
</code></pre>
<p>The result contains several properties. I can get the text <em>3 min read</em> by accessing <code>result.text</code> or alternatively the reading time as a time <code>result.time</code>, in minutes <code>result.minutes</code> and the word count <code>result.words</code>.</p>
<p>In the end, it was very simple for me to integrate an estimated reading time into my blog.</p>
]]></content:encoded></item><item><title><![CDATA[The 4 shades of UI composition]]></title><description><![CDATA[In larger projects, the cooperation of several teams and long-term maintenance is always an issue. The architecture must be defined in such a way that such aspects are possible. This is often implemented with a certain degree of modularization.
This ...]]></description><link>https://blog.lehmamic.ch/the-4-shades-of-ui-composition</link><guid isPermaLink="true">https://blog.lehmamic.ch/the-4-shades-of-ui-composition</guid><category><![CDATA[architecture]]></category><category><![CDATA[ui-composition]]></category><category><![CDATA[Microfrontend]]></category><category><![CDATA[self-contained-system]]></category><dc:creator><![CDATA[Michael Lehmann]]></dc:creator><pubDate>Mon, 26 Sep 2022 10:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1699463258686/7648d46a-ebcd-40ff-9380-06f201bf1d74.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In larger projects, the cooperation of several teams and long-term maintenance is always an issue. The architecture must be defined in such a way that such aspects are possible. This is often implemented with a certain degree of modularization.</p>
<p>This applies not only to the backend but also to the frontend. For a long time, front-end applications were somewhat neglected. Often the frontend was developed by the designer and cross-directional beginners or was done by the developers on the side. After all, pixel pushing was not so popular with the developers. The "real" work, namely in the backend, was given more attention and done seriously. This inevitably led to the front end being more or less a patchwork. But user interfaces in general have become very important in recent times. Hardly any application can be brought to the people these days without an appealing user interface. And that makes it all the more important that the above-mentioned attributes are also taken into account in the frontend.</p>
<p>I have worked on several, very large, projects in my career. I have seen and helped develop several types of modularization in the frontend. The community has also moved forward. Topics such as microservice architecture have also an impact on the frontend architecture with new practices and patterns.</p>
<p>In this article, I am going to discuss some of these modularization patterns.</p>
<h2 id="heading-the-monolith">The monolith</h2>
<p>I would like to start with traditional monolithic architecture. What used to be the standard is somewhat unpopular today, but it has its justification.</p>
<p>Especially for smaller software projects, it is still common to fall back onto this architecture. Using a certain architecture is always associated with compromises. In the case of smaller projects, this is definitely in favor of a monolith. The advantages are clearly in the simplicity of a monolithic architecture. There is only one system that needs to be developed and maintained. And the communication between the components, apart from a SPA frontend, takes place exclusively in memory.</p>
<p>But this does not mean that a monolith is completely un-modularized. There are many software architecture patterns such as layered architecture, onion architecture, ports, and adapters, or the popular Clean Architecture pattern from Uncle Bob helping structure a software application.</p>
<p><img src="https://ik.imagekit.io/lehmamic/leh-web/cleanarchitecture_QKZDlPg5K.png" alt="Clean Architecture|360x240" /></p>
<p>However, these have in common that they modularize an application in horizontal layers. This horizontal orientation of, not only the presentation layer but of the whole application makes certain problems more complicated. I am talking about issues such as working in several teams, the independent deployment of each component, and long-term maintenance, including the transition to new technologies.</p>
<p>At some point, the compromises become too painful and it is worth moving on. But at what point, or at what size of software application is this point? Personally, I always use the single responsibility principle as a guideline. I am not talking about all the infrastructure plumbing that is always involved. But as soon as an application has several responsibilities in terms of business features, it is time to consider an expansion of the architecture.</p>
<h2 id="heading-modularized-monolith">Modularized monolith</h2>
<p>To mitigate these problems, the application must be modularized vertically. This means that the application is divided into modules across all horizontal layers. A module in each layer has its own, more or less independent, part. From the frontend down to the database.</p>
<p><img src="https://ik.imagekit.io/lehmamic/leh-web/ModularizedMonolith_j4GwILD5j.png?ik-sdk-version=javascript-1.4.3&amp;updatedAt=1663580097309" alt="Modularized Monolith|434 x 291" /></p>
<p>The boundaries of a module are usually defined by a business feature or a group of features. For this purpose, the methodologies of <a target="_blank" href="https://en.wikipedia.org/wiki/Domain-driven_design">Domain Driven Design</a> are often utilized and the application is subdivided into so-called bounded contexts. Then a module is generated for each bounded context.</p>
<p>Modularization also raises the question of how far to go. We have a wide range of options, from simple folder structures to <a target="_blank" href="https://en.wikipedia.org/wiki/Distributed_computing">distributed systems</a>. But as soon as communication goes beyond the process boundary, the complexity of the system increases considerably. Because then, topics such as API versioning, service availability, service discovery, network instabilities, authentication, and authorization have to be dealt with.</p>
<p>Again, the trade-offs of the available options need to be weighed. You want to make your application better structured, more maintainable, and more accessible for several teams. However, people often fear the costs of a distributed system. This brings us to the compromise where simple approaches such as folder structures are used to split an application into modules within the application boundaries. We are talking here about <em>modularized monoliths</em>.</p>
<p>As mentioned above, there are many technical possibilities to modularize an application within the application boundaries. The simplest way is to organize the code into a specific folder structure. In some projects, they even go a step further. The code can also be organized in its own libraries (jar, dll, npm, etc.). This works in the backend as well as in the frontend. And with a little extra effort, an independent deployment can even be achieved via drop-in replacement.</p>
<p>However, a modularized monolith also has its limitations. First of all, it is difficult to enforce the design and module boundaries. Violations creep in very quickly. This has a lot to do with the discipline of the developers. So you have to be careful not to accumulate a lot of technical debt over time. On the other hand, the modules are highly interdependent. Technology selection, deployments, and maintenance cannot be chosen independently at all, or only to a very limited extent. Even in the frontend, a decision is made for a technology that is used for the entire application. Upgrades or even a migration to newer technologies are difficult and can be very expensive.</p>
<p>I have seen many modularized monoliths in my career. 10-20 years ago this was simply the standard architecture used for web applications. There was early talk about <a target="_blank" href="https://en.wikipedia.org/wiki/Service-oriented_architecture">service-oriented architecture</a> (SOA). Of course, this alleviates the problem, but only in the backend. The user interface is still mostly a monolith.</p>
<p>We are often asked to revitalize such systems, i.e. modernize them. In most of cases, we fall back on a more modern architecture that is related to microservices and micro frontends - the <a target="_blank" href="https://scs-architecture.org/">Self-Contained System (SCS)</a>. Read my <a target="_blank" href="https://blog.lehmamic.ch/blog/recipe-to-make-large-web-apps-fit-for-the-future">article about application revitalization</a>.</p>
<h2 id="heading-self-contained-systems">Self-contained systems</h2>
<p>There is a lot going on in the development community about microservices. Microservices solve exactly the problems I mentioned earlier and bring even more advantages, such as independent scaling. But also with microservices, we tend to have a UI monolith. The community has an answer ready for that as well, micro frontends. Before we get into this topic, I would like to talk about self-contained systems, a special kind of micro frontend architecture.</p>
<p>I have already mentioned that you can cut a monolithic system along its domains and wrap it into modules. Taking the approach further and wrapping each domain into separate, replaceable web applications, we refer to this application as a <a target="_blank" href="https://scs-architecture.org/">Self-Contained System (SCS)</a>.</p>
<p><img src="https://ik.imagekit.io/lehmamic/leh-web/self-contained-system_h2UyLhYwW.png?ik-sdk-version=javascript-1.4.3&amp;updatedAt=1663788175478" alt="Self-Contained System|387x290" /></p>
<p>An SCS contains its own user interface, specific business logic, and separate data storage. They communicate with other systems via hyper links, RESTful services, or asynchronous messaging. An SCS is responsible for its core domain and master of its own data. Data and logic can be shared via a well-defined API. An SCS can consume microservices to solve domain-specific problems.</p>
<p>You see, this way every SCS can be developed with its own platform, frameworks, and release cycles. This enables a future-proof and maintainable system. Of course, this comes with a price. Every application needs to have its own CI/CD pipeline and its own deployment procedure. We need to think about how certain constraints, such as common layouts, styles, and components can be guaranteed.</p>
<p>This problem can be solved with different approaches as well. A pragmatic solution would be to do nothing at all and leave design and layout to the SCS. In certain cases, this may even be desirable.</p>
<p>A step further is the introduction of UI guidelines, which are not enforced, but provide a strict framework. This still gives the applications a lot of freedom and maximum independence. Each system must ensure that it adheres to the guidelines. Accordingly, different interpretations and adaptation speeds occur quickly. Under certain circumstances, the system may not appear to be made from a single mold.</p>
<p>If you want to enforce a design, you cannot avoid sharing something. However, there is always the risk that the individual SCSs will experience a technology lock. For example, if you make a library with Angular components, the SCSs are forced to implement their frontend in Angular. And that is exactly what we want to avoid. I have had good experiences with extracting style sheets with colors, spacing, typography, etc. into a library and integrating them into the applications. It is also a good idea to make a technology-agnostic component library with WebComponent. There are frameworks like <a target="_blank" href="https://stenciljs.com/">StencilJS</a> that are specialized for such use cases.</p>
<p>What has also worked well for me is using the microfrontend approach for layout and components like headers and footers. This is done by using web components that are compiled into a single file bundle and hosted in a CDN. An SCS can dynamically include these components at runtime via <code>&lt;script&gt;</code> tag. By the way, this also works very well when an SCS needs to render concrete content of another SCS. We name it widgets. This ensures that the responsibilities of the SCS focused on its own domain. I wrote an <a target="_blank" href="https://blog.lehmamic.ch/blog/a-step-closer-towards-micro-frontend">article</a> about this topic a while ago.</p>
<p><img src="https://ik.imagekit.io/lehmamic/leh-web/scs-layout_Vwm3XbFNM.png?ik-sdk-version=javascript-1.4.3&amp;updatedAt=1663916240187" alt="Shared layout in SCS|387x244" /></p>
<p>This way we achieve maximum independence for shared components. But still, don`t forget that everything that is shared hurts and you want to avoid this!</p>
<h2 id="heading-micro-frontend">Micro frontend</h2>
<p>The last UI composition pattern I want to cover is the <a target="_blank" href="https://micro-frontends.org/">microfrontend architecture pattern</a>.</p>
<p>This pattern has its origin in the microservice architecture. Microservices solve many of the problems already discussed. But with microservices, we still end up with a monolithic UI.</p>
<p><img src="https://ik.imagekit.io/lehmamic/leh-web/ui-monolith_xGAhgzWYp7.png?ik-sdk-version=javascript-1.4.3&amp;updatedAt=1663920540408" alt="UI monolith with microservices|431x297" /></p>
<p>This means that the advantages we gain from the microservice architecture are lost in the frontend. But we actually want independent teams, technology selection, deployment, scaling, and release cycles in the frontend as well. Microfrontends address this problem.</p>
<p>The idea is that each microservice also has its own frontend. Compared to a self-contained system, however, this is not an independent application. In a microfrontend architecture, a so-called shell is needed. The shell is a very lean web application that combines the frontends of the individual microservices into one application. The communication of the microservice is preferably done via microfrontend. That means, via hyperlinks or HTML properties and events.</p>
<p><img src="https://ik.imagekit.io/lehmamic/leh-web/micro-frontends_j4tNXCtBsg.png?ik-sdk-version=javascript-1.4.3&amp;updatedAt=1663922566398" alt="Micro frontends|431x371" /></p>
<p>An example could be a shop selling video games. Team product is responsible for the product page and everything that needs to be included here. Team checkout is responsible for everything regarding the purchase process and team marketing manages the product recommendations on this page.</p>
<p><img src="https://ik.imagekit.io/lehmamic/leh-web/microfrontend-example_kj2K_2XO2.png?ik-sdk-version=javascript-1.4.3&amp;updatedAt=1663923411578" alt="Micro frontends example|588x366" /></p>
<p>Again, there are many technical ways to implement this, some of them are:</p>
<ul>
<li><p>Manually load and embed an HTML file via JavaScript</p>
</li>
<li><p>The micro frontends can be integrated via iFrames</p>
</li>
<li><p>Compose your frontend with WebComponents</p>
</li>
</ul>
<p>As you see, the technical support for this pattern isn't that great. There is still a lot of manual work involved. Nobody wants to manually load and embed HTML via JavaScript and iFrames are troubleson concerning scaling of its content. The most promising approach is to compose your frontend with modern web components. There are a lot of frameworks that are specialized in authoring web components such as <a target="_blank" href="https://angular.io/guide/elements">Angular Elements</a>, <a target="_blank" href="https://stenciljs.com/">StencilJS</a>, or <a target="_blank" href="https://lit.dev/">LitComponent</a>. This works the same way I used to integrate a header into a Self-Contained System. Web Components get compiled to a single file bundle, deployed to a CDN, and consumed via <code>&lt;script&gt;</code> tag.</p>
<p>We also have the same problem with sharing styles and layouts across the micro frontends. We can rely on guidelines or develop a framework-agnostic UI library with web components.</p>
<p>I want to mention at this point, that there are also JavaScript frameworks emerging which are specialized in microfrontends. One of those is <a target="_blank" href="https://single-spa.js.org/">Single SPA</a>. I never tried it out so far, but it could be a big help in doing microfrontends.</p>
<h2 id="heading-summary">Summary</h2>
<p>I covered the 4 most used UI composition patterns I am aware of. It starts with a monolithic system, breaking it into modules and Self-Contained Systems. At the end of the line, I covered the microfrontend architecture.</p>
<p>One of the key points here is considering trade-offs. Mostly between simplicity and the advantage of independent teams, technology stacks, deployments, and release cycles.</p>
<p>And one thing to mention again: <strong>it hurts to share code!</strong></p>
<p>What do you think about those UI composition patterns? What is your experience? Leave a comment and discuss it with me.</p>
]]></content:encoded></item><item><title><![CDATA[Why you should automate your development environment setup]]></title><description><![CDATA[Setting up a development environment for a new project is not one of the most popular tasks. As a new developer in the project, you don't know the environment and have to work through pages and pages of documentation until your own development enviro...]]></description><link>https://blog.lehmamic.ch/why-you-should-automate-your-development-environment-setup</link><guid isPermaLink="true">https://blog.lehmamic.ch/why-you-should-automate-your-development-environment-setup</guid><category><![CDATA[infrastructure]]></category><category><![CDATA[Microservices]]></category><category><![CDATA[Devops]]></category><category><![CDATA[self-contained-system]]></category><dc:creator><![CDATA[Michael Lehmann]]></dc:creator><pubDate>Thu, 23 Jun 2022 10:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/7cc4Zi_L3x0/upload/b3ed7991c8385d10be4a7ab13cd16963.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Setting up a development environment for a new project is not one of the most popular tasks. As a new developer in the project, you don't know the environment and have to work through pages and pages of documentation until your own development environment is up and running. Experience shows that such documentation is often not up to date. This leads to a lot of trial and error and asking questions. In the end, it often takes several hours or sometimes more than a day before you can start developing.</p>
<p>This can be very frustrating and we even haven't talked about repeating this when you are working on a micro-service-based project or want to flush your dev env setup.</p>
<p>I'm working on lots of self-contained systems and micro-service-based projects. And it can happen that I need to switch those projects several times a week. So it is crucial for me to avoid such wasted time. I automate the dev env setup as much as possible and keep improving it. <strong>With this approach, you can get up and running within minutes!</strong></p>
<h2 id="heading-use-docker-to-install-your-infrastructure">Use docker to install your infrastructure</h2>
<p>First of all, we can avoid installing a huge list of software infrastructure, such as SQL Server, Message Broker, SMTP Client, Identity Provider, etc. All this can be set up by using docker.</p>
<p>Using docker has several advantages:</p>
<ul>
<li><p>You don't pollute your operating systems with these applications. Even when you uninstall them, some relics are left in your system.</p>
</li>
<li><p>Everyone on the team has exactly the same versions of the infrastructure.</p>
</li>
<li><p>Everyone in the team automatically gets additional infrastructure, without installing them manually.</p>
</li>
<li><p>You can get and run this software within minutes, it actually only needs one command to start them all.</p>
</li>
</ul>
<p>Using docker reduces the list of software to install to the following and this is something that will be the same for all of your projects, so you do it only once:</p>
<ul>
<li><p>GIT (or your preferred source version control system)</p>
</li>
<li><p>Docker Desktop</p>
</li>
<li><p>SDK's (Usually .Net Core and Node)</p>
</li>
<li><p>IDE (In my case Visual Studio, Rider, or whatever)</p>
</li>
</ul>
<p>And then I prepare a docker-compose file, containing all required infrastructure, in the root of the SVC repository:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">version:</span> <span class="hljs-string">"3.8"</span>

<span class="hljs-attr">services:</span>
  <span class="hljs-attr">mssql:</span>
    <span class="hljs-attr">container_name:</span> <span class="hljs-string">mssql</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">mcr.microsoft.com/azure-sql-edge:1.0.6</span>
    <span class="hljs-attr">ports:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-number">1433</span><span class="hljs-string">:1433</span>
    <span class="hljs-attr">environment:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">ACCEPT_EULA=Y</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">SA_PASSWORD=&lt;any</span> <span class="hljs-string">password&gt;</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">TZ=Europe/Zurich</span>
    <span class="hljs-attr">volumes:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">local-dev-sql:/var/opt/mssql</span>

  <span class="hljs-attr">azurite:</span>
    <span class="hljs-attr">container_name:</span> <span class="hljs-string">azurite</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">mcr.microsoft.com/azure-storage/azurite:1.4.2-linux-amd64</span>
    <span class="hljs-attr">ports:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-number">10000</span><span class="hljs-string">:10000</span>
      <span class="hljs-bullet">-</span> <span class="hljs-number">10001</span><span class="hljs-string">:10001</span>
      <span class="hljs-bullet">-</span> <span class="hljs-number">10002</span><span class="hljs-string">:10002</span>
    <span class="hljs-attr">volumes:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">local-dev-azurite:/data</span> <span class="hljs-string">mcr.microsoft.com/azure-storage/azurite</span>

  <span class="hljs-attr">smtp-mock:</span>
    <span class="hljs-attr">container_name:</span> <span class="hljs-string">smtp</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">rnwood/smtp4dev:v3.1</span>
    <span class="hljs-attr">ports:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">"6200:80"</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">"2525:25"</span>

<span class="hljs-attr">volumes:</span>
  <span class="hljs-attr">local-dev-sql:</span>
  <span class="hljs-attr">local-dev-azurite:</span>
</code></pre>
<p>And it will require only one command to start up everything:</p>
<pre><code class="lang-bash">docker-compose -f docker-compose.dev-env -p my-app up
</code></pre>
<p>You can flush your infrastructure with only one command as well:</p>
<pre><code class="lang-bash">docker-compose -f docker-compose.dev-env -p my-app down -v
</code></pre>
<h2 id="heading-script-application-specific-configurations-and-setups-with-nuke">Script application-specific configurations and setups with Nuke</h2>
<p>The first part of your dev env setup is done with that. Usually, there needs to be additional things done. Things like local configurations, database setup, etc.</p>
<p>A few years ago, I stumbled over <a target="_blank" href="https://nuke.build/">Nuke</a>. A build scripting engine running plain .Net code and is fully integrated into your .Net development IDE. Everyone in our teams is used to writing C# code, so everyone is comfortable in using this tool. And this is the reason why I love this great tool so much. Kudos to <em>Matthias Koch</em> for it!</p>
<p>As you might guess, I'm using Nuke scripts to set up everything else which usually has to be done manually. I'm not going to write a tutorial for nuke at this place, but just as much as need to get you a picture of it.</p>
<p>A nuke script can be initialized with the following commands:</p>
<pre><code class="lang-bash">dotnet tool install Nuke.GlobalTool --global
nuke :setup
</code></pre>
<p>This will guide you through a wizard and set up a Nuke project including some startup scripts for you. Then you can start to implement your automation script with it.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">class</span> <span class="hljs-title">Build</span> : <span class="hljs-title">NukeBuild</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">int</span> <span class="hljs-title">Main</span>(<span class="hljs-params"></span>)</span> =&gt; Execute&lt;SetupDevEnv&gt;();

    Target SetupDevEnv =&gt; _ =&gt; _
            .DependsOn(CreateOrUpgradeDatabase)
        .Executes(() =&gt;
        {
             <span class="hljs-comment">// This one usually has no implementation, but calls other targets which are doing their jobs</span>
        });

    Target CreateOrUpgradeDatabase =&gt; _ =&gt; _
        .Executes(() =&gt;
        {
            <span class="hljs-comment">// Create or upgrade databasae implementation</span>
        });
}
</code></pre>
<p>And afterward you can execute the script with the following command:</p>
<pre><code class="lang-bash">nuke.sh --target SetupDevEnv
</code></pre>
<p>And with that your dev env is ready and you can start hacking.</p>
<h2 id="heading-final-dev-env-setup-steps">Final dev env setup steps</h2>
<p>With all this in place, your dev env setup will be reduced to the following steps.</p>
<h3 id="heading-dev-env-setup-instruction">Dev Env Setup Instruction</h3>
<p>Required software:</p>
<ul>
<li><p>GIT</p>
</li>
<li><p>Docker Desktop</p>
</li>
<li><p>DotNet Core SDK</p>
</li>
<li><p>NodeJS</p>
</li>
<li><p>Rider or Visual Studio</p>
</li>
</ul>
<p>Clone the repo:</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> &lt;repor-url&gt; my-app
</code></pre>
<p>Startup infrastructure:</p>
<pre><code class="lang-bash">docker-compose -f docker-compose.dev-env -p my-app up
</code></pre>
<p>Setup dev env:</p>
<pre><code class="lang-bash">nuke.sh --target SetupDevEnv
</code></pre>
<p>Great, that's it! You can open your IDE and hit F5.</p>
]]></content:encoded></item><item><title><![CDATA[A step closer towards micro-frontend]]></title><description><![CDATA[In my previous post, I described our way to build a library to share layout, styles, and components in the user interface of our self-contained systems architecture.
This helped us a lot because it reduced the coupling of the shared code to the appli...]]></description><link>https://blog.lehmamic.ch/a-step-closer-towards-micro-frontend</link><guid isPermaLink="true">https://blog.lehmamic.ch/a-step-closer-towards-micro-frontend</guid><category><![CDATA[ui-composition]]></category><category><![CDATA[self-contained-system]]></category><category><![CDATA[Microfrontend]]></category><category><![CDATA[stenciljs]]></category><category><![CDATA[Web Components]]></category><dc:creator><![CDATA[Michael Lehmann]]></dc:creator><pubDate>Mon, 13 Jun 2022 10:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1699461810152/3d55c928-cdae-4a3e-9b4f-b4d577db86b8.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In my <a target="_blank" href="https://blog.lehmamic.ch/blog/sharing-ui-components-in-self-contained-systems">previous post</a>, I described our way to build a library to share layout, styles, and components in the user interface of our <em>self-contained systems</em> architecture.</p>
<p>This helped us a lot because it reduced the coupling of the shared code to the applications in our system. However, we started to struggle with it again after an inconsistent navigation in the header due to an update in the shared header component. Let's be serious, this is bad and should not happen! It is ok when some little CSS styling is not up to date in the application. Most likely nobody will recognize that. However, the navigation <strong>must</strong> be consistent in a <em>self-contained system</em>. It is bad when the navigation to an application suddenly disappears when the user navigates through the system. Even worse, when there is a dead link in the navigation.</p>
<h2 id="heading-dynamically-rendered-layout">Dynamically rendered Layout</h2>
<p>We discussed two options to solve that problem:</p>
<ul>
<li>Extracting the header and footer into its own shared library. All the infrastructure for this approach already exists. It would be easy to build and would make it easier to automatically integrate and update it in all applications. But it still has a dependency on certain npm package versions which can turn an update into a bigger exercise.</li>
</ul>
<ul>
<li>Deploy the header and footer separately and integrate it into the applications during runtime. This is clearly a step towards a <a target="_blank" href="https://micro-frontends.org/">micro-frontend architecture</a>. We initially decided against micro-frontends because it would increase the complexity and our project is not large enough that it would be worth using that pattern. But for the current problem, it seemed to be a good fit.</li>
</ul>
<p>We decided, obviously, to deploy the header and footer separately and integrate it at runtime into our applications. That we would implement it by using WebComponents, was also clear from the beginning. Still open was the Framework we wanted to use. We are using Angular. Angular Elements could be a fit but has some drawbacks.</p>
<p>Our goal was to create a single js file, deploy it to Azure Blob Storage, and dynamically include it via <code>&lt;script&gt;</code> tag. Let's have a look at the options we evaluated:</p>
<ul>
<li><p><a target="_blank" href="https://angular.io/guide/elements">Angular Elements</a>, obviously. It is possible to create a single file with <a target="_blank" href="https://github.com/manfredsteyer/ngx-build-plus">ngx-build-plus</a> which is what we would like to have. But Angular Elements is building a complete Angular application into the WebComponent, hence it will be a rather large bundle.</p>
</li>
<li><p><a target="_blank" href="https://stenciljs.com/">StencilJS</a>, developed by the Ionic team to make their UI components independent of the UI framework.</p>
</li>
<li><p><a target="_blank" href="https://github.com/lit/lit-element">LitElement</a>, just another lightweight framework to write WebComponents.</p>
</li>
</ul>
<p>We decided to use StencilJS. We think it is a better option than Angular Elements, even though it is actually designed for compile-time integration. We want to have a fast application and the bundle size of Angular Element is way larger than any output from StencilJS.</p>
<h2 id="heading-create-and-stencil-project">Create and Stencil project</h2>
<p>Let's have a look at our setup with StencilJS and the integration in our Angular applications. We are using <a target="_blank" href="https://nx.dev/">NX</a> for our UI workspaces. Let's create an NX workspace with a StencilJS project.</p>
<p>First, we create the NX workspace with typescript presets:</p>
<pre><code class="lang-bash">npx create-nx-workspace my-workspace --preset=ts
</code></pre>
<p>Afterwards, we are going to create a Stencil project in our freshly created NX workspace by using the NX plugin from <a target="_blank" href="https://nxext.dev/docs/nxext/overview.html">Nnext</a>:</p>
<pre><code class="lang-bash">npm install @nxext/stencil --save-dev
nx g @nxext/stencil:library my-lib
</code></pre>
<p>The Nnext plugin provides a generator that allows to create our first component:</p>
<pre><code class="lang-bash">nx g @nxext/stencil:component my-header --project my-lib
</code></pre>
<p>This outputs a component skeleton like this:</p>
<pre><code class="lang-ts"><span class="hljs-meta">@Component</span>({
  tag: <span class="hljs-string">'my-header'</span>,
  styleUrl: <span class="hljs-string">'my-header.scss'</span>,
  shadow: <span class="hljs-literal">true</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> MyHeader {
  <span class="hljs-meta">@Prop</span>() first: <span class="hljs-built_in">string</span>;
  <span class="hljs-meta">@Prop</span>() middle: <span class="hljs-built_in">string</span>;
  <span class="hljs-meta">@Prop</span>() last: <span class="hljs-built_in">string</span>;

  <span class="hljs-keyword">private</span> getText(): <span class="hljs-built_in">string</span> {
    <span class="hljs-keyword">return</span> (<span class="hljs-built_in">this</span>.first || <span class="hljs-string">''</span>) + (<span class="hljs-built_in">this</span>.middle ? <span class="hljs-string">` <span class="hljs-subst">${<span class="hljs-built_in">this</span>.middle}</span>`</span> : <span class="hljs-string">''</span>) + (<span class="hljs-built_in">this</span>.last ? <span class="hljs-string">` <span class="hljs-subst">${<span class="hljs-built_in">this</span>.last}</span>`</span> : <span class="hljs-string">''</span>);
  }

  render() {
    <span class="hljs-keyword">return</span> &lt;div&gt;Hello, World! I<span class="hljs-string">'m {this.getText()}&lt;/div&gt;;
  }
}</span>
</code></pre>
<p>I will not going to write a StencilJS tutorial at this place. But one thing I need to mention. Stencil provides several <a target="_blank" href="https://stenciljs.com/docs/output-targets">output targets</a>. We actually want to have a single file bundle which would be the <code>dist-custom-elements-bundle</code> out target. Unfortunately, this has been deprecated. We use its successor <code>dist-custom-elements</code>. It does basically the same thing but produces a js file per component. This is the better way because it is better to load several smaller bundles than a large one. It will also be better for leveraging <code>http2</code>. We would prefer a single file because it means less file handling on our frontend, but we can work with that.</p>
<pre><code class="lang-json">outputTargets: [
  {
    type: 'dist-custom-elements',
  },
];
</code></pre>
<p>Finally, we are deploying these output files in an Azure Blob Storage. But any static hosting would do the job.</p>
<p>It sounds that easy, but nobody on our team has real experience in StencilJS and is especially lazy load them in an Angular application. One problem worth mentioning is the handling of assets. If the component uses assets that get deployed, you need to make sure to load them with an absolute path. <strong>Relative paths get resolved to the URL where the application is deployed</strong>. We solved the problem by compiling everything (e.g. SVG icons and JSON translation files) into the bundle. This way, we don't need to load them during the runtime.</p>
<h2 id="heading-consuming-the-webcomponents-dynamically-during-run-time">Consuming the WebComponents dynamically during run time</h2>
<p>After creating and deploying our WebComponents, they need to be integrated into the frontend of our applications. A simple script element loading js bundle will do the job. Then we just can use the custom element:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">'https://cdn.jsdelivr.net/npm/my-name@0.0.1/dist/myname.js'</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">my-header</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">my-header</span>&gt;</span>
</code></pre>
<p>We found a nice library, <a target="_blank" href="https://angular-extensions.github.io/elements/#/home">ANGULAR EXTENSIONS ELEMENTS</a>, which makes it even easier to lazy load elements in Angular. It also supports displaying special components for the loading and error cases.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">my-header</span> *<span class="hljs-attr">axLazyElement</span>=<span class="hljs-string">"headerUrl; errorTemplate: errorHeader; loadingTemplate: loading; module: true"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">my-header</span>&gt;</span>
</code></pre>
<p>One thing which needs to be done to make this work is defining the custom elements schema on the corresponding Angular module.</p>
<pre><code class="lang-ts"><span class="hljs-meta">@NgModule</span>({
  declarations: [...],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  imports: [ LazyElementsModule],
})
</code></pre>
<h2 id="heading-summary">Summary</h2>
<p>Not all of our problems were solved by introducing a shared Angular library. We came to the conclusion that an independently deployed and lazy loaded header and footer would be the best solution for us. We decided to use WebComponents for that job. Finally, we implemented it with StencilJS and integrated it with the Angular Extension Elements library.</p>
<p>Implementing header and footer as a micro-frontend was not very smooth. We had a steep learning curve and spent a lot more time than expected. But we are very happy with the result and I, personally, would do that definitely again.</p>
]]></content:encoded></item><item><title><![CDATA[Sharing UI components in Self-Contained systems]]></title><description><![CDATA[In my current project, we use Self-Contained systems to modularize large web applications into multiple applications. We were facing the question of how we should share code across our applications in the system.
The drivers for building self-contain...]]></description><link>https://blog.lehmamic.ch/sharing-ui-components-in-self-contained-systems</link><guid isPermaLink="true">https://blog.lehmamic.ch/sharing-ui-components-in-self-contained-systems</guid><category><![CDATA[architecture]]></category><category><![CDATA[ui-composition]]></category><category><![CDATA[self-contained-system]]></category><dc:creator><![CDATA[Michael Lehmann]]></dc:creator><pubDate>Mon, 30 May 2022 10:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1699461112356/82433a68-9e3d-4f1e-b56e-7e2796b5ac71.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In my current project, we use <a target="_blank" href="https://scs-architecture.org/">Self-Contained systems</a> to modularize large web applications into multiple applications. We were facing the question of how we should share code across our applications in the system.</p>
<h2 id="heading-the-drivers-for-building-self-contained-systems">The drivers for building self-contained systems</h2>
<p>Let's talk about our drivers to use the self-contained systems architecture before we go deeper into that question.</p>
<p>We were facing a situation, where our customer had two legacy systems running. They are doing more or less the same. Actually, one of them was supposed to replace the other one, which has never been completed entirely. For extending and replacing those two systems we have chosen the self-contained system approach. This gives us the flexibility to maintain and migrate separate parts of the system in the future more easily.</p>
<p>One important part of the self-contained system architecture is to keep them as independent and decoupled as possible, otherwise, we would lose the advantages why we have chosen this approach.</p>
<h2 id="heading-enforcing-ui-design-guidelines">Enforcing UI design guidelines</h2>
<p>We are working on a couple of applications in this system now. The user should not really recognize that he/she is browsing multiple applications. We can't avoid page loads due to the architectural design we have chosen. But design, styles, and layout should not look different between the app.</p>
<p><img src="https://ik.imagekit.io/lehmamic/leh-web/shared-components_NDx1Q8oKjY.png?ik-sdk-version=javascript-1.4.3&amp;updatedAt=1653922949582" alt="shared UI components in self-contained systems|680x254" /></p>
<p>Sooner or later, we need to think about, how we can enforce these constraints. Now, <em>self-contained systems</em> have a lot in common with <a target="_blank" href="https://microservices.io/">Micro Services</a>.</p>
<p>One strong recommendation when building micro-services is to <strong>not share code</strong> between the services. Sharing code increases the coupling between the services. And that makes it harder to maintain them independently. There are some companies like Netflix that purposely share code though, but I think they are the minority.</p>
<p>The rule to not share code is also valid for <em>self-contained systems</em>. We don't want to touch the entire <em>system of systems</em> when we, for example, update an application to a new Angular version. On the other hand, we don't want to fix bugs in code which is used from multiple applications multiple times. Or change the style in all applications manually.</p>
<h2 id="heading-introducing-versioned-libraries">Introducing versioned libraries</h2>
<p>We need to find a way in between. Sharing code directly creates a hard dependency on that piece of code and we want to keep the freedom to prioritize and decide when we touch an application. We decided to create versioned libraries containing the shared code. It is important to make it versioned because it allows you to update this library in an application independently and on demand.</p>
<p>Building, publishing, and consuming an npm library is easy. So everything fine? No! For us, it introduced a completely new constraint. We have two teams and we first had to learn how we handle this library. Questions like "How do we do versioning?", "How do we handle branching?" or "How do we handle changes, especially breaking changes?" needed to be answered.</p>
<p>We introduced <a target="_blank" href="https://semver.org/">Semantic Versioning</a> to be able to <em>express</em> breaking changes. We are working in a mono repo. When we create a release branch we update the major version number of the develop branch to avoid version conflicts between the branches. And we keep a lean changelog to have an overview of the changes and breaking changes we did. We also have a gathering among the developers. We call it a <em>dev exchange</em>. This is the platform where we discuss and announce cross-cutting concerns like our shared libraries.</p>
<h2 id="heading-retrospective">Retrospective</h2>
<p>Would I do it again? I'm not that sure. It definitely brings some value for us. It works quite well for things like UI components and global styles, but it also introduced an overhead we actually don't want to have.</p>
<p>Nothing is a silver bullet. It did not solve all our problems with shared UI components at the end. With this approach, we still need to touch all the applications when we introduce a new navigation item. But that is another story.</p>
]]></content:encoded></item><item><title><![CDATA[A recipe to make large web applications fit for the future]]></title><description><![CDATA[I have been working on some projects, where we replaced 10 to 20-year-old enterprise applications like customer portals or internal business applications. Actually, I found this very impressive since those applications have been running for more than...]]></description><link>https://blog.lehmamic.ch/a-recipe-to-make-large-web-applications-fit-for-the-future</link><guid isPermaLink="true">https://blog.lehmamic.ch/a-recipe-to-make-large-web-applications-fit-for-the-future</guid><category><![CDATA[architecture]]></category><category><![CDATA[ui-composition]]></category><category><![CDATA[self-contained-system]]></category><dc:creator><![CDATA[Michael Lehmann]]></dc:creator><pubDate>Mon, 16 May 2022 10:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1699460845159/c10fe60d-f5b9-4d0b-86f9-d9c6466ab3f5.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I have been working on some projects, where we replaced 10 to 20-year-old enterprise applications like customer portals or internal business applications. Actually, I found this very impressive since those applications have been running for more than 15 years and they are doing their job. But still, after such a long time they are reaching their end of life. It is always the same reason why we get paid to replace those old relics.</p>
<ul>
<li><p>The application is so huge, that it is difficult to get into the code base, and the original knowledge is gone for a long.</p>
</li>
<li><p>The code is too fragile so it got expensive to build more value with it.</p>
</li>
<li><p>Old technologies and libraries are not supported anymore.</p>
</li>
</ul>
<p>Unfortunately, it is very expensive to replace an old system that has been built over decades and it does not bring any business value to just rewrite them with new technologies. In the worst case, it never finishes and the old system keeps running forever beside the new application. Did I mention that syncing data between software systems is no fun and expensive as well? And what are we supposed to do in 10 years when the new system will be outdated as well? Do we rewrite it again and have 3 generations of systems running in parallel? <em>Yes that happens, I'm working currently on such a project...</em></p>
<p>So we are locked in a loop, replacing applications. Actually, we want to add business value and not reinvent the wheel again. What can we do to break this circle? I use an architectural style which is called a <a target="_blank" href="https://scs-architecture.org/">self-contained system</a>.</p>
<h2 id="heading-what-is-actually-the-problem-of-large-legacy-systems">What is actually the problem of large legacy systems?</h2>
<p>Before we dig deeper into this architecture, let's see what causes this problem. Why do those systems reach a state where we can't move forward or backward? One of the reasons is the monolithic nature of the architectures which were usually used for those kinds of systems 15 years ago. A common architectural style at that time was the layered architecture. They are cut horizontally into layers like the UI layer, business layer, and data access layer.</p>
<p><img src="https://ik.imagekit.io/lehmamic/leh-web/monolith_T8Do4m78S.png?ik-sdk-version=javascript-1.4.3&amp;updatedAt=1652883886490" alt="monolith architecture|300x319" /></p>
<p>We are talking about large applications. Having only horizontal cuts in the system results in a tight coupling between features and modules. That makes it difficult to change things like migrating the UI to a newer technology. And that's just because it's so big. Where should we start? It's like opening the box of Pandora.</p>
<h2 id="heading-what-about-microservices">What about microservices?</h2>
<p>Micro-services are well known to face problems like that. They enable the usage of different technologies, scalability, team decoupling etc. And they are small enough to be easily replaced by a new one when their technologies get outdated.</p>
<p>Are they really a solution? I won't say no. But micro-services get hyped maybe a bit too much. Micro-services are complex to handle. They introduce a lot more complexity into the system. Things like distributed communication, traceability, resilience, monitoring, etc need to be adapted to micro-services. Further, micro-services are not an answer to modularize or split a user interface into maintainable parts. In the end, there is a big danger that it will end in a <em>distributed monolith</em>. We are also talking about <em>UI monoliths</em>.</p>
<p><img src="https://ik.imagekit.io/lehmamic/leh-web/ui-monolith_cAIMumzwm.png?ik-sdk-version=javascript-1.4.3&amp;updatedAt=1652883886390" alt="ui monolith architecture|300x463" /></p>
<h2 id="heading-between-a-microservice-and-a-monolith">Between a microservice and a monolith</h2>
<p>If we would have a small application we would not talk about it and just refactor or rewrite it. Small applications are easy to understand as a whole. They are small enough to be migrated or even replaced. It also doesn't hurt to throw them away if not needed anymore.</p>
<p>Why don't we break our large system down into several smaller applications? <strong>This is it!</strong> We can cut our system vertically into completely separated, independent applications. Each application has its own tech stack such as user interface, database, and deployment stack. It has its own backlog and its own release cycle. This way we don't have the overhead of micro-services but each of those applications is small enough to be understood and to be maintained for a very long time.</p>
<p><img src="https://ik.imagekit.io/lehmamic/leh-web/self-contained-system_7_50mL0L9.png?ik-sdk-version=javascript-1.4.3&amp;updatedAt=1652883886374" alt="self-contained system architecture|300x330" /></p>
<p>It is actually a <em>system of systems</em>. This way we can build s sustainable system architecture that is and can stay fit for the future. We don't need to completely rewrite the old legacy system, as well. We can revitalize it by replacing only parts of it, or adding new features with new tiny applications. The coexistence of the legacy application with a replacement is not a risk anymore, but a feature. If we do that, it is important to make sure that the replaced features are built back into the legacy system as well. We make sure it can be slowly transitioned completely into the new self-contained systems architecture.</p>
<h2 id="heading-summary">Summary</h2>
<p>Let's the main message of this blog post. Large enterprise applications often reach their end of life due to unsupported technologies and lack of knowledge. Rewriting them doesn't bring any value, is expensive, and introduces the risk of never getting rid of the old application. An architecture style called <em>self-contained systems</em> splits a software system vertically into many small applications that are easy to understand and maintain. This way, it's also possible to transition an old, very large software system into a system which is fit for the future.</p>
]]></content:encoded></item><item><title><![CDATA[Leveraging existing libraries to write a console application]]></title><description><![CDATA[Small console applications are handy and quite common in software projects to solve infrastructural problems which are not easy maintainable with shell scripts. For example I often use DbUp to migrate SQL databases. It is a great library, but provide...]]></description><link>https://blog.lehmamic.ch/leveraging-existing-libraries-to-write-a-console-application</link><guid isPermaLink="true">https://blog.lehmamic.ch/leveraging-existing-libraries-to-write-a-console-application</guid><category><![CDATA[architecture]]></category><category><![CDATA[code]]></category><category><![CDATA[.NET]]></category><dc:creator><![CDATA[Michael Lehmann]]></dc:creator><pubDate>Thu, 24 Jun 2021 10:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1699460442363/905b09a4-1ab4-4758-987d-0f981de80010.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Small console applications are handy and quite common in software projects to solve infrastructural problems which are not easy maintainable with shell scripts. For example I often use <a target="_blank" href="https://dbup.readthedocs.io/en/latest/">DbUp</a> to migrate SQL databases. It is a great library, but provides only a library and no executable. So we tend to make dedicated console application in every project <code>DbUp</code>gets used. This is quite handy, it can be installed as a dotnet core tool, packed in a docker image or delivered with an Octopus Deploy package.</p>
<p>Every time we do that rather 'hacky' instead of having a proper code base for such kind of tools. I hate code which is not cleaned up, but has a lifetime of the whole project or product. This tend to suffer from the broken window effect and become worse and worse. So one day, I sat down and thought about how I can build a console application which is properly built and very easy to set up. You can get the sample code <a target="_blank" href="https://github.com/lehmamic/sample-dotnet-tool">here</a>.</p>
<p>I don't like to reinvent the wheel I was looking for libraries doing the job for me.</p>
<ul>
<li><p><a target="_blank" href="https://www.nuget.org/packages/CommandLineParser/">CommandLineParser</a></p>
</li>
<li><p><a target="_blank" href="https://www.nuget.org/packages/MediatR/">MediatR</a></p>
</li>
<li><p><a target="_blank" href="https://www.nuget.org/packages/Microsoft.Extensions.DependencyInjection/6.0.0-preview.5.21301.5">Microsoft Dependency Injection</a></p>
</li>
<li><p><a target="_blank" href="https://www.nuget.org/packages/Serilog/2.10.1-dev-01315">Serilog</a></p>
</li>
</ul>
<p>To have more control over the log output, I'm using Serilog. With Serilog we can write to the console, a file or wherever we want to send and store our log messages.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">var</span> levelSwitch = <span class="hljs-keyword">new</span> LoggingLevelSwitch
{
    MinimumLevel = LogEventLevel.Information,
};

Log.Logger = <span class="hljs-keyword">new</span> LoggerConfiguration()
    .MinimumLevel.ControlledBy(levelSwitch)
    .Enrich.FromLogContext()
    .WriteTo.Console(outputTemplate: <span class="hljs-string">"{Timestamp:HH:mm:ss} [{Level:u3}] {SourceContext} {Message:lj}{NewLine}{Exception}"</span>)
    .CreateLogger();
</code></pre>
<p>In any normal application I would use a dependency injection container to leverage the inversion of control principle. Basically it does not matter which framework we use for that job. I just hooked on the dependency injection extension from Microsoft which are also used in <a target="_blank" href="http://Asp.Net">Asp.Net</a> Core. As you may recognize, I'm registering the logger with the Microsoft logging extension into the dependency injection container. This libraries play neatly together, which makes this easier for us.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">var</span> serviceProvider = <span class="hljs-keyword">new</span> ServiceCollection()
    .AddLogging()
    .AddSingleton&lt;ILoggerFactory&gt;(_ =&gt; <span class="hljs-keyword">new</span> SerilogLoggerFactory(Log.Logger))
    .BuildServiceProvider();
</code></pre>
<p>And that I can setup the <code>CommanLineParser</code> to parse the program arguments.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> Parser.Default.ParseArguments&lt;Option1, Option1&gt;(args)
    .MapResult(
        <span class="hljs-comment">// the command arguments are valid and we can do something here</span>
        <span class="hljs-keyword">async</span> (<span class="hljs-keyword">object</span> options) =&gt;
        {
            <span class="hljs-keyword">return</span> Task.FromResult(<span class="hljs-number">0</span>);
        },
        <span class="hljs-comment">// the command was invalid, we return an error code</span>
        _ =&gt; Task.FromResult(<span class="hljs-number">1</span>));
</code></pre>
<p>Now almost everything is in place in order that we can work with it. The <code>CommanLineParser</code> requires you to implement annotated classes which are filled from the parser. I want to create a git commands like tool, so I'm using the <code>Verb</code> feature of the <code>CommanLineParser</code>.</p>
<pre><code class="lang-csharp">[<span class="hljs-meta">Verb(<span class="hljs-meta-string">"hello"</span>, HelpText = <span class="hljs-meta-string">"Just an example command."</span>)</span>]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">HelloCommand</span>
{
    [<span class="hljs-meta">Option('t', <span class="hljs-meta-string">"target"</span>, Required = true, HelpText = <span class="hljs-meta-string">"Specifies whom to say hello."</span>)</span>]
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> GreetingTarget { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
}

[<span class="hljs-meta">Verb(<span class="hljs-meta-string">"goodbye"</span>, HelpText = <span class="hljs-meta-string">"Just an example command."</span>)</span>]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">GoodbyeCommand</span>
{
    [<span class="hljs-meta">Option('t', <span class="hljs-meta-string">"target"</span>, Required = true, HelpText = <span class="hljs-meta-string">"Specifies whom to say hello."</span>)</span>]
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> GreetingTarget { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
}
</code></pre>
<p>I need to register my command in the <code>CommanLineParser</code>.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> Parser.Default.ParseArguments&lt;HelloCommand, GoodbyeCommand&gt;(args)
    .MapResult(
        <span class="hljs-keyword">async</span> (<span class="hljs-keyword">object</span> options) =&gt;
        {
            <span class="hljs-keyword">return</span> Task.FromResult(<span class="hljs-number">0</span>);
        }
</code></pre>
<p>Oh wait, the map results is untyped. I need to distinguish between the different options classes and cast them in order to access their information. This could lead to nasty code with many <code>if</code> or <code>switch</code> blocks. I prefer to have some cleaner way to do that job. Luckily there is a software development pattern for this problem. The <a target="_blank" href="https://en.wikipedia.org/wiki/Mediator_pattern#:~:text=In%20software%20engineering%2C%20the%20mediator,alter%20the%20program%27s%20running%20behavior.&amp;text=This%20reduces%20the%20dependencies%20between%20communicating%20objects%2C%20thereby%20reducing%20coupling.">mediator</a> pattern can help us calling the correct command logic according to our inputs. I'm using the <code>MediatR</code> library which is a fully managed implementation of that pattern. And because we are using a dependency injection container it comes with no overhead at all.</p>
<p>I'm registering the <code>MediatR</code> library in the dependency injection container.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">var</span> serviceProvider = <span class="hljs-keyword">new</span> ServiceCollection()
    .AddLogging()
    .AddSingleton&lt;ILoggerFactory&gt;(_ =&gt; <span class="hljs-keyword">new</span> SerilogLoggerFactory(Log.Logger))
    .AddMediatR(Assembly.GetExecutingAssembly())
    .BuildServiceProvider();
</code></pre>
<p>The commands must inherit from <code>IRequest</code> in order that it works together with the <code>MediatR</code> library. I'm creating a command base class for that, we also can use it later on to add some general command line arguments to the commands.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title">CommandBase</span> : <span class="hljs-title">IRequest</span>&lt;<span class="hljs-title">int</span>&gt;
{
}
</code></pre>
<p>Every command has a command handler, which executes the logic of the command. We can inject our dependencies into our command handlers. I'm only using the logger, but it can be anything you want. E.g. an Entity Framework context or whatever.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">HelloCommandHandler</span> : <span class="hljs-title">IRequestHandler</span>&lt;<span class="hljs-title">HelloCommand</span>, <span class="hljs-title">int</span>&gt;
{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> ILogger&lt;HelloCommandHandler&gt; _logger;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">HelloCommandHandler</span>(<span class="hljs-params">ILogger&lt;HelloCommandHandler&gt; logger</span>)</span>
    {
        _logger = logger ?? <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> ArgumentNullException(<span class="hljs-keyword">nameof</span>(logger));
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> Task&lt;<span class="hljs-keyword">int</span>&gt; <span class="hljs-title">Handle</span>(<span class="hljs-params">HelloCommand request, CancellationToken cancellationToken</span>)</span>
    {
        _logger.LogInformation(<span class="hljs-string">$"Hello <span class="hljs-subst">{request.GreetingTarget}</span>"</span>);

        <span class="hljs-keyword">return</span> Task.FromResult(<span class="hljs-number">0</span>);
    }
}

<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">GoodbyeCommandHandler</span> : <span class="hljs-title">IRequestHandler</span>&lt;<span class="hljs-title">GoodbyeCommand</span>, <span class="hljs-title">int</span>&gt;
{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> ILogger&lt;GoodbyeCommandHandler&gt; _logger;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">GoodbyeCommandHandler</span>(<span class="hljs-params">ILogger&lt;GoodbyeCommandHandler&gt; logger</span>)</span>
    {
        _logger = logger ?? <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> ArgumentNullException(<span class="hljs-keyword">nameof</span>(logger));
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> Task&lt;<span class="hljs-keyword">int</span>&gt; <span class="hljs-title">Handle</span>(<span class="hljs-params">GoodbyeCommand request, CancellationToken cancellationToken</span>)</span>
    {
        _logger.LogInformation(<span class="hljs-string">$"Goodbye <span class="hljs-subst">{request.GreetingTarget}</span>"</span>);

        <span class="hljs-keyword">return</span> Task.FromResult(<span class="hljs-number">0</span>);
    }
}
</code></pre>
<p>And finally we can call the <code>MediatR</code> with the command and this will execute the corresponding command handler.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> Parser.Default.ParseArguments&lt;HelloCommand, GoodbyeCommand&gt;(args)
    .MapResult(
        <span class="hljs-keyword">async</span> (CommandBase command) =&gt;
        {
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> serviceProvider.GetRequiredService&lt;IMediator&gt;().Send(command);
        },
        _ =&gt; Task.FromResult(<span class="hljs-number">1</span>));
</code></pre>
<p>Cool! with that we have a clean command line tool which is easy to test and maintain.</p>
<p>As an addition, I'm adding some general arguments to the base class. To demonstrate this, I'm adding a Verbose flag which adjusts the current log level.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title">CommandBase</span> : <span class="hljs-title">IRequest</span>&lt;<span class="hljs-title">int</span>&gt;
{
    [<span class="hljs-meta">Option(<span class="hljs-meta-string">"verbose"</span>, Default = false, Required = false, HelpText = <span class="hljs-meta-string">"Enables verbose output."</span>)</span>]
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> Verbose { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
}

<span class="hljs-keyword">async</span> (CommandBase command) =&gt;
{
    <span class="hljs-keyword">if</span> (command.Verbose)
    {
        levelSwitch.MinimumLevel = LogEventLevel.Verbose;
    }

    <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> serviceProvider.GetRequiredService&lt;IMediator&gt;().Send(command);
},
</code></pre>
<p>I used this architecture already in a few projects and I must say it was worth to do it. It is easy to understand and it does not get messed up. At the end, every line of code brings in maintenance effort and can waist the time of the team. Just care a bit, even though it is not the main product you are creating helps you and all involved peoples.</p>
]]></content:encoded></item><item><title><![CDATA[Async file upload with NextJS]]></title><description><![CDATA[I'm currently playing around with NextJS. My background is clearly in the Microsoft environment and for a few years Angular, so I practice web development with TypeScript.
I had a hard time when I tried to implement a file upload with a NextJS API en...]]></description><link>https://blog.lehmamic.ch/async-file-upload-with-nextjs</link><guid isPermaLink="true">https://blog.lehmamic.ch/async-file-upload-with-nextjs</guid><category><![CDATA[code]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[Next.js]]></category><dc:creator><![CDATA[Michael Lehmann]]></dc:creator><pubDate>Thu, 03 Jun 2021 10:00:00 GMT</pubDate><content:encoded><![CDATA[<p>I'm currently playing around with NextJS. My background is clearly in the Microsoft environment and for a few years Angular, so I practice web development with TypeScript.</p>
<p>I had a hard time when I tried to implement a file upload with a NextJS API endpoint. The problems had basically nothing to do with NextJS but with Node and its huge node module base which sometimes has questionable quality. But let's start with how I used to implement NextJS endpoints. I'm using the <code>next-connect</code> for implementing and routing the endpoints.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> handler = nextConnect&lt;NextApiRequest, NextApiResponse&gt;();

handler.post(<span class="hljs-keyword">async</span> (req, res) =&gt; {
  rest.status(<span class="hljs-number">200</span>).end();
});

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> handler;
</code></pre>
<p>Since I'm using TypeScript, I want to leverage the <code>async await</code> language feature which simplifies the handling of asynchronous logic massively. But together with the callback approach of Node, it turns out to be not as easy as expected.</p>
<p>I first had a look, at which libraries for file upload handling are available:</p>
<ul>
<li><p><a target="_blank" href="https://www.npmjs.com/package/formidable">formidable</a></p>
</li>
<li><p><a target="_blank" href="https://www.npmjs.com/package/busboy">busboy</a></p>
</li>
</ul>
<p>First I had a try with <code>busboy</code> because it allows handling the file upload without temporary files. The first implementation with Node callbacks worked. However, I did not manage to collect and return the file rules in the callbacks. I still don't know if I'm too stupid or if the library has a bug, but any shared variable updates to collect the URLs did not work for me.</p>
<p>Fine, I thought, let's find a library that is capable of doing the asynchronous handling with Promises.</p>
<ul>
<li><p><a target="_blank" href="https://www.npmjs.com/package/await-busboy">await-busboy</a></p>
</li>
<li><p><a target="_blank" href="https://www.npmjs.com/package/async-busboy">async-busboy</a></p>
</li>
</ul>
<p>The <code>await-busboy</code> library looked quite good, but it does not provide TypeScript type definitions. Implementing them yourself is a lot of work, especially if the API changes. So I tried out <code>async-busboy</code>. The advantage of a file upload handling without temp files is already gone with the async feature, but better than a not-working solution. I implemented the code, which looked quite nice to me. But when I tried it out, it kept hanging while parsing the file upload. After researching I found this GitHub issue <a target="_blank" href="https://github.com/m4nuC/async-busboy/issues/42">https://github.com/m4nuC/async-busboy/issues/42</a>. My first thoughts were: <strong>"it cannot be that there is no fucking stable library to handle file uploads in Node!"</strong></p>
<p>Seriously, there are so many Node modules out there, and a lot of them were just uploaded by some dudes without testing and any quality behind it. When developing a Node app, you are forced to assemble your application with a patchwork of libraries, from which you don't know its quality and future maintenance. I consider that as a big risk for productive applications.</p>
<p>Nevertheless, I gave <code>formidable</code> a try. Even though there is no async version of this library I managed to promisify it and use it in the async world. Here is my final and working solution.</p>
<p>First of all, we need to switch off the body parsing from NextJS otherwise the file upload will not work.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> config = {
  api: {
    bodyParser: <span class="hljs-literal">false</span>,
  },
};
</code></pre>
<p>Then I wrote a wrapper around <code>formidable</code> which returns a promise instead of using callbacks in my main code.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> parseForm = (req: IncomingMessage): <span class="hljs-built_in">Promise</span>&lt;[Fields, Files]&gt; =&gt; {
  <span class="hljs-keyword">const</span> form = <span class="hljs-keyword">new</span> IncomingForm({ keepExtensions: <span class="hljs-literal">true</span>, allowEmptyFiles: <span class="hljs-literal">false</span>, multiples: <span class="hljs-literal">true</span> });

  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>&lt;[Fields, Files]&gt;(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
    form.parse(req, <span class="hljs-function">(<span class="hljs-params">err, fields, files</span>) =&gt;</span> {
      <span class="hljs-keyword">if</span> (err) reject(err);
      <span class="hljs-keyword">else</span> resolve([fields, files]);
    });
  });
};
</code></pre>
<p>And than i would implement my file upload endpoint, by using <code>async await</code>.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> handler = nextConnect&lt;NextApiRequest, NextApiResponse&gt;();

handler.post(<span class="hljs-keyword">async</span> (req, res) =&gt; {

  <span class="hljs-keyword">const</span> contentType = req.headers[<span class="hljs-string">'content-type'</span>];

  <span class="hljs-keyword">if</span> (!contentType || contentType.indexOf(<span class="hljs-string">'multipart/form-data'</span>) &lt; <span class="hljs-number">0</span>) {
    res.status(HttpStatus.BAD_REQUEST).end();
    <span class="hljs-keyword">return</span>;
  }

  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> [, fileResult] = <span class="hljs-keyword">await</span> parseForm(req);

    <span class="hljs-keyword">const</span> files = <span class="hljs-built_in">Array</span>.isArray(fileResult.file) ? fileResult.file : [fileResult.file];
    <span class="hljs-keyword">if</span> (!validateFiles(files)) {
      res.status(HttpStatus.BAD_REQUEST).end();
    }

    <span class="hljs-keyword">const</span> images = <span class="hljs-keyword">await</span> <span class="hljs-built_in">Promise</span>.all(
      files.map(uploadFilesToFirebaseStorage),
    );

    res.status(HttpStatus.CREATED).json(images);
  } <span class="hljs-keyword">catch</span> (e) {
    res.status(HttpStatus.INTERNAL_SERVER_ERROR).end();
  }
});

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> handler;
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Implement resource-based authorization with Angular]]></title><description><![CDATA[I wrote about my approach for resource-based authorization and possible implementation in ASP.NET Core. This article will continue the story and show how this can be implemented in Angular.
After the last article, we have a protected REST API in our ...]]></description><link>https://blog.lehmamic.ch/implement-resource-based-authorization-with-angular</link><guid isPermaLink="true">https://blog.lehmamic.ch/implement-resource-based-authorization-with-angular</guid><category><![CDATA[Angular]]></category><category><![CDATA[Security]]></category><category><![CDATA[architecture]]></category><category><![CDATA[code]]></category><dc:creator><![CDATA[Michael Lehmann]]></dc:creator><pubDate>Thu, 08 Apr 2021 10:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/ieic5Tq8YMk/upload/56dd9ba2d9e6b243815e230a50bad93a.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I wrote about my approach for resource-based authorization and possible implementation in <a target="_blank" href="http://ASP.NET">ASP.NET</a> Core. This article will continue the story and show how this can be implemented in Angular.</p>
<p>After the last article, we have a protected REST API in our <a target="_blank" href="http://ASP.NET">ASP.NET</a> Core backend. Technically we are fine with that. From a user's perspective, it is not very handy to run into unauthorized operations. To make this more user friendly we need a way to also check these permissions in our frontend. In the last few projects, I was involved in, we used Angular. So this article will target Angular even though the concept is also applicable to other frontend technologies such as React or ViewJS.</p>
<h2 id="heading-loading-the-permissions-from-the-backend">Loading the permissions from the backend</h2>
<p>To be able to perform a permission check in the frontend, we need to load the authorization policies and user permissions from the backend.</p>
<p>First, we create an <a target="_blank" href="http://ASP.NET">ASP.NET</a> API controller returning the permissions of the logged-in user.</p>
<pre><code class="lang-csharp">[<span class="hljs-meta">ApiController</span>]
[<span class="hljs-meta">Route(<span class="hljs-meta-string">"api/v1/authorization-permissions"</span>)</span>]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">ResourcePermissionsController</span> : <span class="hljs-title">ControllerBase</span>
{
    [<span class="hljs-meta">HttpGet</span>]
    <span class="hljs-keyword">public</span> ActionResult&lt;Permission[]&gt; GetPermissions()
    {
        <span class="hljs-keyword">var</span> permissions = User.GetPermissions();
        <span class="hljs-comment">// I usually map the entities to dto's, but  removed this here for simplicity</span>
        <span class="hljs-keyword">return</span> Ok(permissions);
    }
}
</code></pre>
<p>Then we create a service in the Angular frontend that can load the permissions.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">type</span> PermissionAction = <span class="hljs-string">'Read'</span> | <span class="hljs-string">'Write'</span> | <span class="hljs-string">'ReadRestricted'</span> | <span class="hljs-string">'ReadConfidential'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> Permission {
  resourceId: <span class="hljs-built_in">string</span>[];
  actions: PermissionAction[];
}

<span class="hljs-meta">@Injectable</span>({
  providedIn: <span class="hljs-string">'root'</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AuthorizeService {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> http: HttpClient</span>) {}

  <span class="hljs-keyword">public</span> getResourcePermissions(): Observable&lt;Permission[]&gt; {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.http.get&lt;Permission[]&gt;(<span class="hljs-string">`<span class="hljs-subst">${environment.apiBaseUrl}</span>/authorize-permissions`</span>);
  }
}
</code></pre>
<p>I usually use NgRX in my Angular applications, load the data in an effect, and store it in the NgRX state. I'm not going to go deeper into that topic because it is not important to the topic in this post.</p>
<p>Important is only, that you load the permissions at the correct time. Do you have any permissions to query for unauthenticated users, or are you forced to be logged in? In the applications I implemented, a user gets automatically logged in by single sign-on over an OAuth identity provider. So we loaded the user permission after the user had been signed in.</p>
<h2 id="heading-loading-the-policies-from-the-backend">Loading the policies from the backend</h2>
<p>As mentioned before, we also need to load the authorization policies into the Angular frontend. This is done similarly to the permissions.</p>
<p>We create an <a target="_blank" href="http://ASP.NET">ASP.NET</a> API controller returning the authorization policies. To mention is, that we need to allow to request them without the user being logged in because we are going to load them at the startup of the Angular application.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">AuthorizePolicyDto</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span>? Name { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">ICollection</span>&lt;<span class="hljs-title">RequiredPermissionDto</span>&gt; Permissions</span> { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; } = <span class="hljs-keyword">new</span> Collection&lt;RequiredPermissionDto&gt;();
}

<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">RequiredPermissionDto</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">ICollection</span>&lt;<span class="hljs-title">string</span>&gt; ResourceId</span> { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; } = <span class="hljs-keyword">new</span> Collection&lt;<span class="hljs-keyword">string</span>&gt;();

    <span class="hljs-keyword">public</span> PermissionAction Action { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
}

[<span class="hljs-meta">ApiController</span>]
[<span class="hljs-meta">AllowAnonymous</span>] <span class="hljs-comment">// important, because we call this endpoint before the user has beed logged in</span>
[<span class="hljs-meta">Route(<span class="hljs-meta-string">"api/v1/authorization-policies"</span>)</span>]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">AuthorizationPoliciesController</span> : <span class="hljs-title">ControllerBase</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">AuthorizationPoliciesController</span>(<span class="hljs-params"></span>)</span>
    {
        _mapper = mapper;
    }

    [<span class="hljs-meta">HttpGet</span>]
    <span class="hljs-keyword">public</span> ActionResult&lt;AuthorizePolicyDto[]&gt; GetPolicies()
    {
        <span class="hljs-keyword">var</span> policies = Enumeration.GetAllValues&lt;AuthorizePolicy&gt;();
        <span class="hljs-keyword">return</span> Ok(MapToDtos(policies));
    }

    <span class="hljs-comment">// in this case we map to dto's because the frontend needs it in a different format</span>
    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> IEnumerable&lt;AuthorizePolicyDto&gt; <span class="hljs-title">MapToDtos</span>(<span class="hljs-params">IEnumerable&lt;AuthorizePolicy&gt; policies</span>)</span>
    {
        <span class="hljs-keyword">return</span> policies.Select(p =&gt; <span class="hljs-keyword">new</span> AuthorizePolicyDto
            {
                Action = p.Action,
                ResourceId = p.ResourceId.Split(<span class="hljs-string">'/'</span>, StringSplitOptions.None),
            });
    }
}
</code></pre>
<p>And then again, we load the policies into the Angular frontend.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> AuthorizePolicy {
  name: AuthorizePolicies;
  permissions: RequiredPermission[];
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> RequiredPermission {
  resourceId: <span class="hljs-built_in">string</span>[];
  action: PermissionAction;
}

<span class="hljs-comment">// we extend the Authorize Service</span>
<span class="hljs-meta">@Injectable</span>({
  providedIn: <span class="hljs-string">'root'</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AuthorizeService {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> http: HttpClient</span>) {}

  <span class="hljs-keyword">public</span> getAuthorisationPolicies(): Observable&lt;AuthorizePolicy[]&gt; {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.http.get&lt;AuthorizePolicy[]&gt;(<span class="hljs-string">`<span class="hljs-subst">${environment.apiBaseUrl}</span>/authorization-policies`</span>);
  }
}
</code></pre>
<p>The authorization policies need to be loaded latest with the user permissions. You could load them together. We separated it and loaded the Policies in the Angular <code>APP_INITIALIZER</code> routine.</p>
<h2 id="heading-checking-the-user-permissions">Checking the user permissions</h2>
<p>Now we have all the data that is required to check the permissions in the frontend. We'll extend the <code>AuthorizeService</code> with the logic required to check the permissions against the policies. Again, I'm using NgRX, but you can use anything to store the permissions and policies in the front end.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// we extend the Authorize Service</span>
<span class="hljs-meta">@Injectable</span>({
  providedIn: <span class="hljs-string">'root'</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AuthorizeService {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> http: HttpClient, <span class="hljs-keyword">private</span> store$: Store</span>) {}

  <span class="hljs-keyword">public</span> isAuthorized(policyName: AuthorizePolicies, values: <span class="hljs-built_in">Map</span>&lt;<span class="hljs-built_in">string</span>, <span class="hljs-built_in">string</span>&gt;): Observable&lt;<span class="hljs-built_in">boolean</span>&gt; {
    <span class="hljs-keyword">return</span> combineLatest([
      <span class="hljs-built_in">this</span>.store$.pipe(select(selectResourcePermissions)),
      <span class="hljs-built_in">this</span>.store$.pipe(select(selectAuthorizationPolicies)),
    ]).pipe(
      <span class="hljs-comment">// check if the permissions have been loaded</span>
      filter(<span class="hljs-function">(<span class="hljs-params">[permissions]</span>) =&gt;</span> permissions.status === <span class="hljs-string">'SUCCEEDED'</span> || permissions.status === <span class="hljs-string">'FAILED'</span>),

      <span class="hljs-comment">// get the policy with the provided key</span>
      map(<span class="hljs-function">(<span class="hljs-params">[permissions, policies]</span>) =&gt;</span> {
        <span class="hljs-keyword">if</span> (!policies.some(<span class="hljs-function">(<span class="hljs-params">p</span>) =&gt;</span> p.name === policyName)) {
          <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">`No policy with name '<span class="hljs-subst">${policyName}</span>' has been found`</span>);
        }

        <span class="hljs-keyword">return</span> {
          permissions,
          policy: policies.find(<span class="hljs-function">(<span class="hljs-params">p</span>) =&gt;</span> p.name === policyName),
        };
      }),

      <span class="hljs-comment">// check if the user is authorized</span>
      map(<span class="hljs-function">(<span class="hljs-params">{ permissions, policy }</span>) =&gt;</span> <span class="hljs-built_in">this</span>.authorizeUser(permissions.data, policy, values)),
      first(),
    );
  }

  <span class="hljs-keyword">private</span> authorizeUser(permissions: Permission[], policy: AuthorizePolicy, values: <span class="hljs-built_in">Map</span>&lt;<span class="hljs-built_in">string</span>, <span class="hljs-built_in">string</span>&gt;): <span class="hljs-built_in">boolean</span> {
    <span class="hljs-keyword">const</span> isAuthorized =
      policy.permissions
        <span class="hljs-comment">// replace variables in the policy</span>
        .map(<span class="hljs-function">(<span class="hljs-params">p</span>) =&gt;</span> AuthorizeService.substitutePermission(policy.name, p, values))

        <span class="hljs-comment">// check policies against the permissions</span>
        .map(<span class="hljs-function">(<span class="hljs-params">p</span>) =&gt;</span> <span class="hljs-built_in">this</span>.hasPermission(permissions, p))

        <span class="hljs-comment">// are all required permissions granted?</span>
        .findIndex(<span class="hljs-function">(<span class="hljs-params">granted</span>) =&gt;</span> !granted) &lt; <span class="hljs-number">0</span>;

    <span class="hljs-keyword">return</span> isAuthorized;
  }

  <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> substitutePermission(
    policy: <span class="hljs-built_in">string</span>,
    permission: RequiredPermission,
    values: <span class="hljs-built_in">Map</span>&lt;<span class="hljs-built_in">string</span>, <span class="hljs-built_in">string</span>&gt;,
  ): RequiredPermission {
    <span class="hljs-keyword">return</span> {
      ...permission,
      resourceId: permission.resourceId.map(<span class="hljs-function">(<span class="hljs-params">r</span>) =&gt;</span> {
        <span class="hljs-keyword">if</span> (<span class="hljs-regexp">/^{.*}/g</span>.test(r)) {
          <span class="hljs-keyword">const</span> variableName = r.replace(<span class="hljs-string">'{'</span>, <span class="hljs-string">''</span>).replace(<span class="hljs-string">'}'</span>, <span class="hljs-string">''</span>);
          <span class="hljs-keyword">if</span> (!values.has(variableName)) {
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">`A value for the variable '<span class="hljs-subst">${variableName}</span>' is missing for policy <span class="hljs-subst">${policy}</span>.`</span>);
          }
          <span class="hljs-keyword">return</span> values.get(variableName);
        }
        <span class="hljs-keyword">return</span> r;
      }),
    };
  }

  <span class="hljs-keyword">private</span> hasPermission(permissions: Permission[], requiredPermission: RequiredPermission): <span class="hljs-built_in">boolean</span> {
    <span class="hljs-comment">// check the every user permission if it matches the required permission</span>
    <span class="hljs-keyword">const</span> hasPermission =
      permissions.map(<span class="hljs-function">(<span class="hljs-params">p</span>) =&gt;</span> AuthorizeService.matchPermission(p, requiredPermission)).findIndex(<span class="hljs-function">(<span class="hljs-params">matched</span>) =&gt;</span> matched) &gt;=
      <span class="hljs-number">0</span>;

    <span class="hljs-keyword">return</span> hasPermission;
  }

  <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> matchPermission(permission: Permission, requiredPermission: RequiredPermission): <span class="hljs-built_in">boolean</span> {
    <span class="hljs-keyword">if</span> (permission.actions.findIndex(<span class="hljs-function">(<span class="hljs-params">a</span>) =&gt;</span> a === requiredPermission.action) &lt; <span class="hljs-number">0</span>) {
      <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
    }
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; requiredPermission.resourceId.length; i++) {
      <span class="hljs-keyword">if</span> (permission.resourceId.length &lt;= i) {
        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
      }
      <span class="hljs-keyword">if</span> (permission.resourceId[i] === <span class="hljs-string">'**'</span>) {
        <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
      }
      <span class="hljs-keyword">if</span> (permission.resourceId[i] !== <span class="hljs-string">'*'</span> &amp;&amp; permission.resourceId[i] !== requiredPermission.resourceId[i]) {
        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
      }
    }
    <span class="hljs-keyword">if</span> (permission.resourceId.length !== requiredPermission.resourceId.length) {
      <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
    }
    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
  }
}
</code></pre>
<p>Are we done with that? Not yet. This is only the service that allows us to check the permission in any place within our Angular app. We can inject it into controllers, services, route guards, or directives to check the permissions.</p>
<h3 id="heading-authorize-angular-routes">Authorize Angular routes</h3>
<p>We usually do a check in the routing. This can be done with a route guard which prevents the user from opening a page in the Angular app.</p>
<p><strong>Note: we usually combine a check for authenticated AND authorized, I skip the authentication check because this depends on your way how authenticating a user.</strong></p>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> RouteData {
  authorize?: AuthorizeRouteData;
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> createAuthorizeRouteData = (policies: AuthorizePolicies[]): <span class="hljs-function"><span class="hljs-params">RouteData</span> =&gt;</span> ({ authorize: { policies } });

<span class="hljs-meta">@Injectable</span>({
  providedIn: <span class="hljs-string">'root'</span>,
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AuthGuard <span class="hljs-keyword">implements</span> CanActivate, CanActivateChild {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> oauthService: OAuthService, <span class="hljs-keyword">private</span> store: Store, <span class="hljs-keyword">private</span> authorizeService: AuthorizeService</span>) {}

  <span class="hljs-keyword">async</span> canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): <span class="hljs-built_in">Promise</span>&lt;<span class="hljs-built_in">boolean</span>&gt; {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.isAuthorized(route);
  }

  <span class="hljs-keyword">async</span> canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): <span class="hljs-built_in">Promise</span>&lt;<span class="hljs-built_in">boolean</span>&gt; {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.isAuthorized(childRoute);
  }

  <span class="hljs-keyword">private</span> <span class="hljs-keyword">async</span> isAuthorized(route: ActivatedRouteSnapshot): <span class="hljs-built_in">Promise</span>&lt;<span class="hljs-built_in">boolean</span>&gt; {
    <span class="hljs-comment">// the required policy is defined in the Angular route data</span>
    <span class="hljs-keyword">const</span> routeData: RouteData = route.data;

    <span class="hljs-comment">// skip it when no permission is required</span>
    <span class="hljs-keyword">if</span> (!routeData.authorize) {
      <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
    }

    <span class="hljs-comment">// extract the authorize policy variables from the route parameters</span>
    <span class="hljs-keyword">const</span> values = extractParams(route.root);

    <span class="hljs-comment">// interate through the policies and check the user permissions</span>
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> policy <span class="hljs-keyword">of</span> routeData.authorize.policies) {
      <span class="hljs-keyword">const</span> isAuthorized = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.authorizeService.isAuthorized(policy, values).toPromise();
      <span class="hljs-keyword">if</span> (!isAuthorized) {
        <span class="hljs-built_in">this</span>.store.dispatch(go({ path: [<span class="hljs-string">'/auth'</span>, <span class="hljs-string">'unauthorized'</span>] }));
        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
      }
    }
    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
  }
}
</code></pre>
<p>As you have seen, the authorization policy variables get extracted from the route parameters. To do this we wrote a few helper methods.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> extractParams = (
  route: ActivatedRouteSnapshot,
  params: <span class="hljs-built_in">Map</span>&lt;<span class="hljs-built_in">string</span>, <span class="hljs-built_in">string</span>&gt; = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Map</span>&lt;<span class="hljs-built_in">string</span>, <span class="hljs-built_in">string</span>&gt;(),
): <span class="hljs-built_in">Map</span>&lt;<span class="hljs-built_in">string</span>, <span class="hljs-built_in">string</span>&gt; =&gt; {
  <span class="hljs-keyword">if</span> (route.paramMap) {
    addParamMap(params, route.paramMap);
  } <span class="hljs-keyword">else</span> {
    addParams(params, route.params);
  }
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> child <span class="hljs-keyword">of</span> route.children) {
    extractParams(child, params);
  }
  <span class="hljs-keyword">return</span> params;
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> addParams = (params: <span class="hljs-built_in">Map</span>&lt;<span class="hljs-built_in">string</span>, <span class="hljs-built_in">string</span>&gt;, values: { [index: <span class="hljs-built_in">string</span>]: <span class="hljs-built_in">string</span> }): <span class="hljs-built_in">Map</span>&lt;<span class="hljs-built_in">string</span>, <span class="hljs-built_in">string</span>&gt; =&gt; {
  <span class="hljs-keyword">if</span> (values) {
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> key <span class="hljs-keyword">of</span> <span class="hljs-built_in">Object</span>.keys(values)) {
      params.set(key, values[key]);
    }
  }
  <span class="hljs-keyword">return</span> params;
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> addParamMap = (params: <span class="hljs-built_in">Map</span>&lt;<span class="hljs-built_in">string</span>, <span class="hljs-built_in">string</span>&gt;, values: ParamMap): <span class="hljs-built_in">Map</span>&lt;<span class="hljs-built_in">string</span>, <span class="hljs-built_in">string</span>&gt; =&gt; {
  <span class="hljs-keyword">if</span> (values) {
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> key <span class="hljs-keyword">of</span> values.keys) {
      params.set(key, values.get(key));
    }
  }
  <span class="hljs-keyword">return</span> params;
};
</code></pre>
<p>To make this work, the parent route parameters must be inherited in order that all parameters are present in the current route.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> routes: Routes = [
  <span class="hljs-comment">// your routes</span>
];

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> routingConfiguration: ExtraOptions = {
  paramsInheritanceStrategy: <span class="hljs-string">'always'</span>,
};

<span class="hljs-meta">@NgModule</span>({
  imports: [RouterModule.forRoot(routes, routingConfiguration)],
  <span class="hljs-built_in">exports</span>: [RouterModule],
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AppRoutingModule {}
</code></pre>
<p>With that in place, a specific route can be guarded with one or more authorization policies.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> routes: Routes = [
  {
    path: <span class="hljs-string">'employees/:employeeId'</span>,
    component: EmployeeComponent,
    data: createAuthorizeRouteData([<span class="hljs-string">'EMPLOYEE_READ'</span>]),
    canActivate: [AuthGuard],
  },
];
</code></pre>
<h3 id="heading-authorize-html-elements-with-an-angular-directive">Authorize HTML elements with an Angular directive</h3>
<p>The last thing I want to show you is how we show, resp. hide HTML elements if you are authorized to see them or not. Instead of always injecting the <code>AuthorizeService</code> into the controllers, we implemented a simple structural directive that does the check for us.</p>
<p>There are two ways to pass the authorization policy variables to the directive:</p>
<ul>
<li><p>by leveraging the route parameters as we did in the <code>AuthGuard</code></p>
</li>
<li><p>by passing them directly into the directive</p>
</li>
</ul>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> AuthorizeOptions {
  values: { [index: <span class="hljs-built_in">string</span>]: <span class="hljs-built_in">string</span> };
}

<span class="hljs-meta">@Directive</span>({ selector: <span class="hljs-string">'[appShowAuthorized]'</span> })
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ShowAuthorizedDirective <span class="hljs-keyword">implements</span> OnInit, OnDestroy {
  <span class="hljs-meta">@Input</span>(<span class="hljs-string">'appShowAuthorized'</span>) authorizePolicies: AuthorizePolicies;
  <span class="hljs-meta">@Input</span>() appShowAuthorizedOptions: AuthorizeOptions;

  <span class="hljs-keyword">private</span> unsubscribe$ = <span class="hljs-keyword">new</span> Subject();

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">
    <span class="hljs-keyword">private</span> authorizeService: AuthorizeService,
    <span class="hljs-keyword">private</span> store$: Store&lt;RootState&gt;,
    <span class="hljs-keyword">private</span> templateRef: TemplateRef&lt;unknown&gt;,
    <span class="hljs-keyword">private</span> viewContainer: ViewContainerRef,
  </span>) {}

  ngOnInit(): <span class="hljs-built_in">void</span> {
    <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">this</span>.authorizePolicies) {
      <span class="hljs-built_in">this</span>.viewContainer.clear();
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-built_in">this</span>.store$
      .pipe(
        select(<span class="hljs-function">(<span class="hljs-params">state</span>) =&gt;</span> state.router),
        <span class="hljs-comment">// prevent the directive to get a different route config than the initial one on navigating away</span>
        scan(<span class="hljs-function">(<span class="hljs-params">acc: RouterReducerState&lt;SerializedRouterStateSnapshot&gt;, val</span>) =&gt;</span> {
          <span class="hljs-keyword">if</span> (!acc || routeConfigEquals(acc.state.root, val.state.root)) {
            <span class="hljs-keyword">return</span> val;
          }

          <span class="hljs-keyword">return</span> acc;
        }, &lt;RouterReducerState&lt;SerializedRouterStateSnapshot&gt;&gt;<span class="hljs-literal">null</span>),
        filter(<span class="hljs-function">(<span class="hljs-params">router</span>) =&gt;</span> !!router),
        map(<span class="hljs-function">(<span class="hljs-params">router</span>) =&gt;</span> extractParams(router.state.root)),
        map(<span class="hljs-function">(<span class="hljs-params">params</span>) =&gt;</span> addParams(params, <span class="hljs-built_in">this</span>.appShowAuthorizedOptions?.values)),
        mergeMap(<span class="hljs-function">(<span class="hljs-params">params</span>) =&gt;</span> <span class="hljs-built_in">this</span>.authorizeService.isAuthorized(<span class="hljs-built_in">this</span>.authorizePolicies, params)),
        takeUntil(<span class="hljs-built_in">this</span>.unsubscribe$),
      )
      .subscribe(<span class="hljs-function">(<span class="hljs-params">isAuthorized</span>) =&gt;</span> {
        <span class="hljs-keyword">if</span> (isAuthorized) {
          <span class="hljs-built_in">this</span>.viewContainer.clear();
          <span class="hljs-built_in">this</span>.viewContainer.createEmbeddedView(<span class="hljs-built_in">this</span>.templateRef);
        } <span class="hljs-keyword">else</span> {
          <span class="hljs-built_in">this</span>.viewContainer.clear();
        }
      });
  }

  ngOnDestroy(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">this</span>.unsubscribe$.next();
  }
}
</code></pre>
<p>This directive can be used directly in an HTML element.</p>
<pre><code class="lang-typescript">&lt;div *appShowAuthorize=<span class="hljs-string">"'EMPLOYEE_READ'; options: { values: { employeeId: specificEmployeeId } }"</span>&gt;
    &lt;......&gt;&lt;/......&gt;
&lt;/div&gt;
</code></pre>
<h2 id="heading-summary">Summary</h2>
<p>Wow, that was quite a bit... After explaining our approach to a resource-based authorization model and implementing it in <a target="_blank" href="http://ASP.NET">ASP.NET</a> Core I showed you how to implement it in an Angular application. It is basically always the same concept and logic but implemented in a different language and framework. I hope it can help you build your authorization framework in your own application. If you have questions, please feel free to add a comment.</p>
]]></content:encoded></item><item><title><![CDATA[Implement resource-based authorization with ASP.NET Core]]></title><description><![CDATA[In my previous article, I wrote about my approach for Resource Based Authorization. This article will continue the story and show how this can be implemented in ASP.NET Core.
The traditional ASP.NET and WebAPI ASP.NET support only role-based authoriz...]]></description><link>https://blog.lehmamic.ch/implement-resource-based-authorization-with-aspnet-core</link><guid isPermaLink="true">https://blog.lehmamic.ch/implement-resource-based-authorization-with-aspnet-core</guid><category><![CDATA[architecture]]></category><category><![CDATA[.NET]]></category><category><![CDATA[asp.net core]]></category><category><![CDATA[code]]></category><category><![CDATA[Security]]></category><dc:creator><![CDATA[Michael Lehmann]]></dc:creator><pubDate>Tue, 06 Apr 2021 22:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1699458303904/8129e483-1ae2-41ad-b7e3-94d211558f59.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In my previous article, I wrote about my approach for Resource Based Authorization. This article will continue the story and show how this can be implemented in ASP.NET Core.</p>
<p>The traditional ASP.NET and WebAPI ASP.NET support only role-based authorization and with the ASP.NET Identity Model extension it was possible to use claim-based authorization. Both were limited in terms of resource-based authorization and a lot of manual work was required. Luckily, ASP.NET Core made a big progress with its <a target="_blank" href="https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-5.0">Policy-based Authorization</a>. This allows us to integrate our resource-based permission into the framework.</p>
<h2 id="heading-resource-permissions">Resource Permissions</h2>
<p>Let's start with the resource permissions. I have the following base implementation of the <code>ResourcePermission</code> class:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">enum</span> PermissionAction
{
    Read,
    Write,
}

<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">ResourcePermission</span> : <span class="hljs-title">IEquatable</span>&lt;<span class="hljs-title">ResourcePermission</span>&gt;
{
    <span class="hljs-keyword">public</span> Guid Id { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Resource { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; } = <span class="hljs-literal">null</span>!;

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span>? UserGroup { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span>? User { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">ICollection</span>&lt;<span class="hljs-title">PermissionAction</span>&gt; Actions</span> { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; } = <span class="hljs-keyword">new</span> Collection&lt;PermissionAction&gt;();
}
</code></pre>
<p>It is an entity which is stored in our database. So it has an <code>Id</code>, the <code>Resource</code>, the <code>PermissionAction</code> and the <code>User</code> resp. <code>UserGroup</code> navigation properties. In the simplest case, this can be strings, storing the AD Account Name and the AD Group. But you also can properly model that in your database depending on your needs. The <code>PermissionAction</code> is a simple enum containing the actions we want to protect.</p>
<p>We also need to be able to load the <code>ResourcePermission</code> entities for a specific user or his/her user group(s). We had several sources from where these resource permissions could originate:</p>
<ul>
<li><p>Static resource permissions</p>
</li>
<li><p>Manually assigned and stored in the database</p>
</li>
<li><p>Generated from other entities such as team members, etc.</p>
</li>
</ul>
<p>To cover that, we implemented a <code>PermissionService</code>, which retrieved and aggregated all permissions from several providers.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title">IResourcePermissionsProvider</span>
{
    Task&lt;IReadOnlyCollection&lt;ResourcePermission&gt;&gt; GetPermissionsAsync(<span class="hljs-keyword">string</span> userName, IReadOnlyCollection&lt;<span class="hljs-keyword">string</span>&gt; userGroups);
}

<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">ResourcePermissionsService</span> : <span class="hljs-title">IResourcePermissionsService</span>
{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> IEnumerable&lt;IResourcePermissionsProvider&gt; _providers;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">ResourcePermissionsService</span>(<span class="hljs-params">IEnumerable&lt;IResourcePermissionsProvider&gt; providers</span>)</span>
    {
        _providers = providers;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;IReadOnlyCollection&lt;ResourcePermission&gt;&gt; GetPermissionsAsync(<span class="hljs-keyword">string</span> userName, IReadOnlyCollection&lt;<span class="hljs-keyword">string</span>&gt; userGroups)
    {
        <span class="hljs-keyword">var</span> result = <span class="hljs-keyword">new</span> List&lt;ResourcePermission&gt;();

        <span class="hljs-keyword">foreach</span> (<span class="hljs-keyword">var</span> provider <span class="hljs-keyword">in</span> _providers)
        {
            <span class="hljs-keyword">var</span> permissions = <span class="hljs-keyword">await</span> provider.GetPermissionsAsync(userName, userGroups);
            result.AddRange(permissions);
        }

        <span class="hljs-keyword">return</span> result;
    }
}
</code></pre>
<h2 id="heading-authorization-policies">Authorization Policies</h2>
<p>To describe the authorization policies, we need to define the required permissions first. Compared to the <code>RequiredPermission</code> class, we only need one <code>PermissionAction</code> to query what the user should be able to do on the provided resource.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">RequiredPermission</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">RequiredPermission</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> resourceId, PermissionAction action</span>)</span>
    {
        ResourceId = resourceId;
        Action = action;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Resource { <span class="hljs-keyword">get</span>; }

    <span class="hljs-keyword">public</span> PermissionAction Action { <span class="hljs-keyword">get</span>; }
}
</code></pre>
<p>The implementation for the <code>AuthorizationPolicy</code> class is based on the <a target="_blank" href="https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/enumeration-classes-over-enum-types">Enumeration Class</a> pattern, described by Microsoft. This includes a similar behavior as the traditional <code>enum</code> type, but allows us to enrich them with additional attributes. The key of the policy is also declared as a constant. Later on we will need it to access the policy in the standard ASP.NET Core <code>AuthorizationAttribute</code>.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title">IAuthorizePolicy</span>
{
    RequiredPermission[] Permissions { <span class="hljs-keyword">get</span>; }

    <span class="hljs-keyword">string</span> Key { <span class="hljs-keyword">get</span>; }
}

<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">AuthorizePolicy</span> : <span class="hljs-title">Enumeration</span>&lt;<span class="hljs-title">string</span>&gt;, <span class="hljs-title">IAuthorizePolicy</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">const</span> <span class="hljs-keyword">string</span> DepartmentRead = <span class="hljs-string">"DEPARTMENT_READ"</span>;
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">const</span> <span class="hljs-keyword">string</span> DepartmentWrite = <span class="hljs-string">"DEPARTMENT_WRITE"</span>;

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">readonly</span> AuthorizePolicy DepartmentReadPolicy = <span class="hljs-keyword">new</span>(
        DepartmentRead,
        <span class="hljs-keyword">new</span>[] { <span class="hljs-keyword">new</span> RequiredPermission(<span class="hljs-string">"/departments/{departmentId}"</span>, PermissionAction.Read) });

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">readonly</span> AuthorizePolicy DepartmentWritePolicy = <span class="hljs-keyword">new</span>(
        DepartmentWrite,
        <span class="hljs-keyword">new</span>[] { <span class="hljs-keyword">new</span> RequiredPermission(<span class="hljs-string">"/departments/{departmentId}"</span>, PermissionAction.Write) });

    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-title">AuthorizePolicy</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> key, RequiredPermission[] permissions</span>)
        : <span class="hljs-title">base</span>(<span class="hljs-params">key</span>)</span>
    {
        Permissions = permissions;
    }

    <span class="hljs-keyword">public</span> RequiredPermission[] Permissions { <span class="hljs-keyword">get</span>; }
}
</code></pre>
<h2 id="heading-checking-the-permission">Checking the permission</h2>
<p>After we have the <code>ResourcePermission</code> and <code>AutorizationPolicy</code> ready, it's time to implement the permission check. We do that with plain C# first. The ASP.NET core integration will follow afterward.</p>
<p>To check if a <code>ResourcePermission</code> matches with a <code>RequiredPermission</code> we need to check two things:</p>
<ol>
<li><p>Has the <code>ResourcePermission</code> the required <code>PermissionAction</code>?</p>
</li>
<li><p>Is the resource of the <code>ResourcePermission</code> matching with the explicit resource id string from the <code>RequiredPermission</code>?</p>
</li>
</ol>
<p>To match the resource path, we split both, the permission resource id and the required resource id into its segments by the <code>/</code> character. Now it is quite easy to compare the resource IDs. If every segment is equal, or if the permission resource id segment has a wild card <code>*</code> the resource IDs are matching. It is important to start with the root segment and work down the path. If the permission resource id segment has a deep wild card <code>**</code> the matching can be aborted because every sub-segment will be a match anyway.</p>
<p>The following code snippet shows how the matching can be implemented.</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">MatchesPermission</span>(<span class="hljs-params">ResourcePermission permission, <span class="hljs-keyword">string</span> specificResourceId, PermissionAction requiredAction</span>)</span>
{
    <span class="hljs-keyword">if</span> (!permission.Actions.Contains(requiredAction))
    {
        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
    }

    <span class="hljs-keyword">var</span> requiredResourceId = specificResourceId.Split(<span class="hljs-string">'/'</span>);
    <span class="hljs-keyword">var</span> permissionResourceId = permission.Resource.Split(<span class="hljs-string">'/'</span>);

    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i &lt; requiredResourceId.Length; i++)
    {
        <span class="hljs-keyword">if</span> (permissionResourceId.Length &lt;= i)
        {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }

        <span class="hljs-keyword">if</span> (permissionResourceId[i] == <span class="hljs-string">"**"</span>)
        {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
        }

        <span class="hljs-keyword">if</span> (permissionResourceId[i] != <span class="hljs-string">"*"</span> &amp;&amp; permissionResourceId[i] != requiredResourceId[i])
        {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }
    }

    <span class="hljs-keyword">if</span> (permissionResourceId.Length != requiredResourceId.Length)
    {
        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
    }

    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
}
</code></pre>
<p>But this is not the complete permission check yet. An <code>AuthorizationPolicy</code> can contain multiple required permissions and we still need to replace the parameters in the required permissions with its target value.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">readonly</span> Regex Regex = <span class="hljs-keyword">new</span>(<span class="hljs-string">"{(.*?)}"</span>, RegexOptions.Compiled);

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">IsMetByPermissions</span>(<span class="hljs-params"><span class="hljs-keyword">this</span> IAuthorizePolicy policy, IReadOnlyList&lt;ResourcePermission&gt; permissions, Dictionary&lt;<span class="hljs-keyword">string</span>, <span class="hljs-keyword">string</span>?&gt; paramMap</span>)</span>
{
    <span class="hljs-keyword">foreach</span> (<span class="hljs-keyword">var</span> requiredPermission <span class="hljs-keyword">in</span> policy.Permissions)
    {
        <span class="hljs-keyword">var</span> specificResourceId = requiredPermission.ResourceId;

        <span class="hljs-comment">// replacing the parameters in the required permission resoruce id</span>
        <span class="hljs-keyword">var</span> matches = Regex.Matches(requiredPermission.ResourceId).ToList();
        <span class="hljs-keyword">foreach</span> (<span class="hljs-keyword">var</span> match <span class="hljs-keyword">in</span> matches)
        {
            <span class="hljs-keyword">var</span> parameterName = match.Groups[<span class="hljs-number">1</span>].Value;
            <span class="hljs-keyword">if</span> (!paramMap.ContainsKey(parameterName))
            {
                <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> ArgumentException(<span class="hljs-string">$"Parameter with name <span class="hljs-subst">{parameterName}</span> was not found."</span>, <span class="hljs-keyword">nameof</span>(paramMap));
            }

            specificResourceId = specificResourceId.Replace(match.Value, paramMap[parameterName], StringComparison.InvariantCultureIgnoreCase);
        }

        <span class="hljs-comment">// checking whether the user has a matching permission</span>
        <span class="hljs-keyword">if</span> (!permissions.Any(permission =&gt; MatchesPermission(permission, specificResourceId, requiredPermission.Action)))
        {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }
    }

    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
}
</code></pre>
<p>Now we can call the permission check on the authorization policy. We need to retrieve the permissions of the corresponding user and provide the parameters that are required for the target policy.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">var</span> user = <span class="hljs-string">"my-user"</span>;
<span class="hljs-keyword">var</span> groups = <span class="hljs-keyword">new</span>[] { <span class="hljs-string">"group1"</span>, <span class="hljs-string">"group2"</span> };

<span class="hljs-comment">// get the permissions from the resource service</span>
<span class="hljs-keyword">var</span> permissions = <span class="hljs-keyword">await</span> permissionService.GetPermissionsAsync(user, groups);

<span class="hljs-comment">// specify the corresponding resource ids which are required</span>
<span class="hljs-keyword">var</span> parameters = <span class="hljs-keyword">new</span> Dictionary&lt;<span class="hljs-keyword">string</span>, <span class="hljs-keyword">string</span>&gt;
{
    { <span class="hljs-string">"departmentId"</span>, <span class="hljs-string">"A"</span> },
};


<span class="hljs-keyword">var</span> userHasAccess = AuthorizePolicy.DepartmentReadPolicy.IsMetByPermissions(permissions, parameters);
</code></pre>
<h2 id="heading-aspnet-core-integration">ASP.NET Core integration</h2>
<p>Microsoft has built a completely new and flexible authorization handling into ASP.NET Core. Besides the traditional role-based authorization and claim-based authorization, it provides the so-called policy-based authorization. We can cover almost every scenario we could think about with this approach.</p>
<p>To marry our resource-based authorization with the policy-based authorization from ASP.NET Core, we need four things:</p>
<ol>
<li><p>Retrieve the user permissions</p>
</li>
<li><p>An authorization handler that calls the permission check</p>
</li>
<li><p>An authorization requirement that maps an ASP.NET Core policy with our <code>AuthorizationPolicy</code></p>
</li>
<li><p>Register our implementations in the ASP.NET Core application</p>
</li>
</ol>
<h3 id="heading-retrieve-the-user-permissions">Retrieve the user permissions</h3>
<p>We could do that simply by injecting the <code>PermissionService</code> wherever we need the user permissions. But this way it might happen that we load the permissions several times in a single endpoint call. To prevent this, we load the permissions in the token-validated event, after the user has been authenticated.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">var</span> authenticationBuilder = services
   .AddJwtBearer(OidcConstants.AuthenticationSchemes.AuthorizationHeaderBearer, options =&gt;
{

    options.Events = <span class="hljs-keyword">new</span> JwtBearerEvents
    {
        OnTokenValidated = <span class="hljs-keyword">async</span> context =&gt;
        {
            <span class="hljs-comment">// get the permission service</span>
            <span class="hljs-keyword">var</span> permissionService = context.HttpContext.RequestServices
                .GetRequiredService&lt;IResourcePermissionsService&gt;();

            <span class="hljs-comment">// get user name and role from the claims principal</span>
            <span class="hljs-keyword">var</span> loginName = context.Principal!.GetLoginName();
            <span class="hljs-keyword">var</span> roles = context.Principal!.GetRoles()
                .ToList();

            <span class="hljs-comment">// load the permissions</span>
            <span class="hljs-keyword">var</span> permissions = <span class="hljs-keyword">await</span> permissionService.GetPermissionsAsync(loginName, roles);

            <span class="hljs-comment">// add the permissions as claims to the claims principal</span>
            <span class="hljs-keyword">var</span> appIdentity = permissions.ToClaimsIdentity();
            context.Principal!.AddIdentity(appIdentity);
        },
    };
});
</code></pre>
<p>The permissions are converted to claims and added to the <code>ClaimsPrincipal</code>of the user. This way we can retrieve them whenever we want.</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Claim <span class="hljs-title">ToClaim</span>(<span class="hljs-params"><span class="hljs-keyword">this</span> ResourcePermission permission</span>)</span>
{
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Claim(ShopDbClaimTypes.Permission, JsonSerializer.Serialize(permission), <span class="hljs-string">"json"</span>);
}

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> IEnumerable&lt;Claim&gt; <span class="hljs-title">ToClaims</span>(<span class="hljs-params"><span class="hljs-keyword">this</span> IEnumerable&lt;ResourcePermission&gt; permissions</span>)</span>
{
    <span class="hljs-keyword">return</span> permissions.Select(ToClaim);
}

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> ClaimsIdentity <span class="hljs-title">ToClaimsIdentity</span>(<span class="hljs-params"><span class="hljs-keyword">this</span> IEnumerable&lt;ResourcePermission&gt; permissions</span>)</span>
{
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> ClaimsIdentity(permissions.ToClaims());
}
</code></pre>
<h3 id="heading-authorization-requirement">Authorization Requirement</h3>
<p>Let's start with the authorization requirement. Our authorization requirement implementation is only a wrapper around one or more authorization policies to make them compatible with the ASP.NET Core policy-based authorization.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">AuthorizePolicyRequirement</span> : <span class="hljs-title">IAuthorizationRequirement</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">AuthorizePolicyRequirement</span>(<span class="hljs-params"><span class="hljs-keyword">params</span> IAuthorizePolicy[] requiredPolicies</span>)</span>
    {
        RequiredPolicies = requiredPolicies;
    }

    <span class="hljs-keyword">public</span> IAuthorizePolicy[] RequiredPolicies { <span class="hljs-keyword">get</span>; }
}
</code></pre>
<p>We also need to register our authorization policies in ASP.NET Core. To do that, we convert them into requirements and add them to the ASP.NET Core authorization policies. If you have a look at the code snippet below, you may notice that we register the requirements with the key of the mapped authorization policy. This allows us later to just use the standard <code>AuthorizeAttribute</code> and pass in the policy name. See also (https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-3.0).</p>
<pre><code class="lang-csharp">services.AddAuthorization(options =&gt;
{
    <span class="hljs-comment">// this adds all our authorize policies see</span>
    <span class="hljs-keyword">foreach</span> (<span class="hljs-keyword">var</span> policy <span class="hljs-keyword">in</span> AuthorizePolicy)
    {
        options.AddPolicy(policy.Key, p =&gt; p.Requirements.Add(<span class="hljs-keyword">new</span> AuthorizePolicyRequirement(policy)));
    }
});
</code></pre>
<h3 id="heading-authorization-handler">Authorization Handler</h3>
<p>The authorization handler gets called when we enforce an authorization, e.g, by using the <code>AuthorizeAttribute</code>. The authorization handler does basically the same as the example earlier, where I illustrated how to use the resource-based authorization.</p>
<ul>
<li><p>Retrieving the permissions of the user</p>
</li>
<li><p>Providing the parameters that are required for the authorization policy</p>
</li>
<li><p>Call the permission check</p>
</li>
</ul>
<p>We added the permission to the <code>ClaimsPrincipal</code> of the user. So it is quite easy to retrieve them in the authorization handler.</p>
<p>One of the benefits of this approach comes into place now. We can model our resource identifiers exactly the same or similar as our REST URI's. That means we have all the parameters that are required from the policy present in the ASP.NET Core route data. We just need to extract them and provide them in a shape we can use it. <strong>One thing has to be ensured in order to make that work, the parameter names in the ASP.NET Core route must match the parameter name of the used authorization policy</strong>.</p>
<p>And then we only need to call the permission check as we already have seen before.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">AuthorizePolicyHandler</span> : <span class="hljs-title">AuthorizationHandler</span>&lt;<span class="hljs-title">AuthorizePolicyRequirement</span>&gt;
{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> IHttpContextAccessor _httpContextAccessor;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">AuthorizePolicyHandler</span>(<span class="hljs-params">IHttpContextAccessor httpContextAccessor</span>)</span>
    {
        _httpContextAccessor = httpContextAccessor;
    }

    <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">HandleRequirementAsync</span>(<span class="hljs-params">AuthorizationHandlerContext context, AuthorizePolicyRequirement requirement</span>)</span>
    {
        <span class="hljs-keyword">if</span> (!requirement.RequiredPolicies.Any())
        {
            <span class="hljs-keyword">return</span>;
        }

        <span class="hljs-comment">// get the routing parameters and provide them as parameters required by the authorization policy</span>
        <span class="hljs-keyword">var</span> routeData = _httpContextAccessor.HttpContext!.GetRouteData();
        <span class="hljs-keyword">var</span> paramMap = routeData.Values.ToDictionary(x =&gt; x.Key, x =&gt; x.Value?.ToString());

        <span class="hljs-comment">// get the permissions from the claims principal</span>
        <span class="hljs-keyword">var</span> permissions = context.User.GetPermissions();

        <span class="hljs-comment">// check the permissions</span>
        <span class="hljs-keyword">if</span> (requirement.RequiredPolicies.All(policy =&gt; policy.IsMetByPermissions(permissions.ToList(), paramMap)))
        {
            context.Succeed(requirement);
        }

        <span class="hljs-keyword">await</span> Task.CompletedTask;
    }
}
</code></pre>
<p>Also, the authorization handler needs to be registered in ASP.NET Core. This can be done by simply registering it as a service.</p>
<pre><code class="lang-csharp">services.AddTransient&lt;IAuthorizationHandler, AuthorizePolicyHandler&gt;();
</code></pre>
<p>With that in place, we can use our resource-based authorization through the ASP.NET Core authorization.</p>
<pre><code class="lang-csharp">[<span class="hljs-meta">HttpGet(<span class="hljs-meta-string">"{departmentId}"</span>)</span>]
[<span class="hljs-meta">Authorize(AuthorizePolicy.DepartmentRead)</span>]
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;ActionResult&gt; <span class="hljs-title">GetDepartmentAsync</span>(<span class="hljs-params">Guid departmentId</span>)</span>
{
    <span class="hljs-keyword">return</span> Ok();
}
</code></pre>
<h2 id="heading-summary">Summary</h2>
<p>In part one of the article series we explained our approach to a resource-based authorization model. In this article, we integrated this approach into the ASP.NET Core framework by using the ASP.NET Core policy-based authorization. Now we are able to protect the resources in our ASP.Net Core applications.</p>
<p>The next step will be to extend it with an Angular implementation to provide user-friendly authorization handling.</p>
]]></content:encoded></item><item><title><![CDATA[Add syntax highlighting support for additional languages in the Caffein Ghost theme]]></title><description><![CDATA[I just set up my new Ghost blog and recognized the missing support for the C# programming language. C# is my main programming language and plan to write some posts about my work with it.
With that in mind, I searched for a way to add the syntax highl...]]></description><link>https://blog.lehmamic.ch/add-syntax-highlighting-support-for-additional-languages-in-the-caffein-ghost-theme</link><guid isPermaLink="true">https://blog.lehmamic.ch/add-syntax-highlighting-support-for-additional-languages-in-the-caffein-ghost-theme</guid><category><![CDATA[infrastructure]]></category><category><![CDATA[code]]></category><dc:creator><![CDATA[Michael Lehmann]]></dc:creator><pubDate>Sun, 14 Mar 2021 11:00:00 GMT</pubDate><content:encoded><![CDATA[<p>I just set up my new Ghost blog and recognized the missing support for the C# programming language. C# is my main programming language and plan to write some posts about my work with it.</p>
<p>With that in mind, I searched for a way to add the syntax highlighting support for additional languages. I'm using the <a target="_blank" href="https://github.com/kelyvin/caffeine-theme">Caffein Theme</a> for the Ghost platform. The theme uses <a target="_blank" href="https://prismjs.com/">PrismJS</a> to introduce syntax highlighting for code snippets.</p>
<p>Prism has a plugin called "Autoloader". Autoloader will dynamically load the language used in code blocks. I did not want to make big changes to the theme, but Luckily Ghost allows us to inject code on the index page. Add the following code to the site footer code injection:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdnjs.cloudflare.com/ajax/libs/prism/1.15.0/components/prism-core.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdnjs.cloudflare.com/ajax/libs/prism/1.15.0/plugins/autoloader/prism-autoloader.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">Prism.plugins.autoloader.languages_path = <span class="hljs-string">'https://cdnjs.cloudflare.com/ajax/libs/prism/1.15.0/components/'</span></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>With that change, the syntax highlighting should now also work for languages like C# by specifying the language on the markdown code block.</p>
]]></content:encoded></item><item><title><![CDATA[Resource based authorization model]]></title><description><![CDATA[I worked on a few projects where a classic-based authorization was not enough to cover the needs. We had the requirement to restrict the access to certain entities. The solution for this was to use the so-called "Resource Based Authorization".
I will...]]></description><link>https://blog.lehmamic.ch/resource-based-authorization-model</link><guid isPermaLink="true">https://blog.lehmamic.ch/resource-based-authorization-model</guid><category><![CDATA[architecture]]></category><category><![CDATA[Security]]></category><category><![CDATA[code]]></category><dc:creator><![CDATA[Michael Lehmann]]></dc:creator><pubDate>Sat, 06 Mar 2021 11:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1699457900294/b9f7195c-1e45-4669-816c-7f2dd49a9934.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I worked on a few projects where a classic-based authorization was not enough to cover the needs. We had the requirement to restrict the access to certain entities. The solution for this was to use the so-called "Resource Based Authorization".</p>
<p>I will cover our approach to Resource Based Authorization in a series of articles. So stay tuned, more is coming.</p>
<h1 id="heading-requirements">Requirements</h1>
<p>As I mentioned before, we basically need to restrict access to certain entities, but what means that in detail?</p>
<p>Let's say we provide a service for a large customer, where we manage the staff, inventory, tasks, and so on for him (an example is imaginary) and we implement a new application to support this service.</p>
<p>There are different types of users in this application:</p>
<ul>
<li><p>Business administrators, who can basically access everything</p>
</li>
<li><p>System administrators, who have read-only access to everything</p>
</li>
<li><p>Department Managers who have access to the department functionality like employee management and basically have access to the entities belonging to an employee, e.g. his tasks.</p>
</li>
<li><p>The standard user who only has access to his tasks and publicly available information.</p>
</li>
</ul>
<p>On top of that, we had the requirement, that the permissions for the resources could be assigned in several ways:</p>
<ul>
<li><p>Automatic assignment through AD groups</p>
</li>
<li><p>Manual assignment through an admin user</p>
</li>
<li><p>Automatic assignment through the user's role in his department</p>
</li>
<li><p>Automatic assignment through resource ownership when a user creates a resource, e.g. a task</p>
</li>
</ul>
<h1 id="heading-our-concept">Our concept</h1>
<p>A business administrator, who can access everything, could be covered with a simple role-based authorization like Active Directory groups. But as soon as we would need to break down a permission for specific resources to a dedicated user, it would be difficult to mirror that in the Active Directory. We also need to keep the JWT token size in mind. Mirroring everything into the Active Directory will produce very large JWT tokens, which also blow up Auth Cookies. That can be a problem with certain proxies like the Ingress controller in Kubernetes.</p>
<h2 id="heading-resource-permission-model">Resource Permission Model</h2>
<p>We came up with the following model for our resource-based authorization:</p>
<p><img src="https://ik.imagekit.io/lehmamic/leh-web/PermissionModel_bNy4_Zgd1.png?ik-sdk-version=javascript-1.4.3&amp;updatedAt=1652360339899" alt="Permission-Model|584x349" /></p>
<p>The model is quite obvious. We have a user who can have some permissions. Theoretically, we already could work with that. If we have multiple users with the same permissions, let's say a manager and his deputy, it would lead to several duplicate permission entries. This would increase the complexity because we need to maintain these permissions.</p>
<p>To simplify that, we introduce the user groups. A user group can also have several permissions. A user can be a member of one or more groups. Of course, the user gets automatically all permissions of the groups (s)he is a member of.</p>
<p>We can model that in a database. We can retrieve the user by its AD Account Name and resolve the corresponding permissions. We also can resolve all groups the user is a member of and with that collect all permissions that are involved. Global groups can be modeled with AD groups which have a direct relation to our user groups.</p>
<h3 id="heading-resource-identifiers">Resource Identifiers</h3>
<p>Every entity has a unique identifier. Theoretically, we can use this identifier to associate a permission with its recourse. This approach would work, but is kind of limited. How you would cover a scenario like all employees of a department? Every single employee of that department would need to be mirrored as resource permission. The meaning of "access to all employment of the department 'A'" would be lost.</p>
<p>We introduced the concept of resource identifiers. A resource identifier is a kind of a URI describing the resource. To target the employee '1' of the department 'A' we have the resource identifier <code>/department/A/employees/1</code>. This is clearly unique identifying, and can be matched to REST endpoint url's, which is also a resource identifier and introduces a context that makes it understandable.</p>
<p>Wildcards can express any resource on the corresponding path segment. With, all employees of department 'A' are matched and <code>/department/*/employees/*</code> would indicate all employees of all departments. We can go even a step further and target all sub-resources of department 'A' with the identifier <code>/departent/A/**</code>.</p>
<p>With this approach, we can target any kind of resources. We introduced a context with the identifier which makes it easier to understand and debug. As a bonus, we prevent our database from being flooded by resource permissions.</p>
<h3 id="heading-permission-actions">Permission Actions</h3>
<p>If you have everything publicly accessible and only want to restrict write access, the resource identifier is enough to express a permission for a resource. In our case, we also needed to restrict the read access for our entities. In fact, I would consider to introduce that from scratch, otherwise, it will be quite an effort to change it.</p>
<p>We introduced the permission actions to express what can be done with this permission. Generally, we used only two of them: <code>read</code> and <code>write</code>. In some projects, we extended them through actions like <code>read confidential</code>.</p>
<p>Let's make this more clear: <code>resource permission = resource identifier + resource actions</code>. An example would be <code>/department/A/employees/1 -&gt; [read, write]</code> which indicates read/write access on the employee with id '1'.</p>
<h3 id="heading-validating-permissions">Validating Permissions</h3>
<p>Now we have resource permissions for dedicated resources, but how do we check if a user has access to this resource? We need to compare the required permission with the resource permissions the user has.</p>
<p>Let's give some examples. We want to check if the user is permitted to modify employee '1' of department 'A'. We express that with <code>/department/A/employees/1 -&gt; write</code>. Now we compare this with every permission of the user.</p>
<ul>
<li><p><code>/department/A/employees/1 -&gt; [read, write]</code>: All segments are matching, and the user is permitted.</p>
</li>
<li><p><code>/department/A/employees/2 -&gt; [read, write]</code>: The employee ID does not match, the user is not permitted.</p>
</li>
<li><p><code>/department/A/employees/* -&gt; [read, write]</code>: We have a wildcard permission that matches any employee ID of department 'A', the user is permitted.</p>
</li>
<li><p><code>/department/** -&gt; [read, write]</code>: The wildcard permission indicates full access to all departments and its sub-resources, the user is permitted.</p>
</li>
<li><p><code>/department/A/employees/1 -&gt; [read]</code>: The resource action is not matching, and the user is not permitted.</p>
</li>
</ul>
<p>If any resource permission of the user is matched, the permission is granted.</p>
<h2 id="heading-authorization-policies">Authorization Policies</h2>
<p>At this stage, we have almost everything together that we can work with. We modeled the resource permissions and we know how we can validate the permissions of a user. A tiny piece is missing - the authorization policies.</p>
<p>In the real world, we don't query for a specific resource identifier. We wrap them into a so-called authorization policy.</p>
<p><img src="https://ik.imagekit.io/lehmamic/leh-web/AuthorizationPolicy_FmkowsxxKy.png?ik-sdk-version=javascript-1.4.3&amp;updatedAt=1652361038224" alt="Authorization-Policy|556x142" /></p>
<p>Maybe you noticed that <code>required permission</code> which almost looks the same as the <code>resource permission</code>. There is one small, but important difference. While resource permission identifiers contain exact entity IDs or wildcards, a required permission identifier contains variables that can be replaced at query time.</p>
<p>For example, with the identifier, <code>/departments/{departmentId}/employees/{employeeId}</code> we express a <em>generic</em> resource identifier that needs to be used in a certain context. The steps to query this policy against the permissions would be:</p>
<ol>
<li><p>Get the required permissions of the policy with the key <code>EMPLOYEE_WRITE</code></p>
</li>
<li><p>Replace all variables with the required permission. <code>/departments/{departmentId}/employees/{employeeId}</code> will become <code>/departments/A/employees/1</code>.</p>
</li>
<li><p>Query the resulting required permission identifier with the required action against the user permissions.</p>
</li>
<li><p>If we query for an authorization policy, all required permissions must be matched.</p>
</li>
</ol>
<p>This is very handy. If you align the naming of the required resource variables with the routing properties in <a target="_blank" href="http://Asp.Net">Asp.Net</a> Core or Angular, the policies can be queried during the routing and the variables can be automatically resolved.</p>
<h2 id="heading-additional-thoughts">Additional thoughts</h2>
<p>Some of my fellows also introduced an additional property on the resource permission to indicate whether the permission is granted or denied. While this brings some more flexibility into the game, it also increases the complexity of querying the permissions. It is a possibility, but I personally never used it. The decision is yours.</p>
]]></content:encoded></item><item><title><![CDATA[Welcome to Michael's developer blog]]></title><description><![CDATA[Welcome to my new developer blog. After having a long blogging break I decided to move away from my old blog lehmamic.wordpress.com on WordPress. You can still visit my old blog though. As a consultant and architect in software development, I have ex...]]></description><link>https://blog.lehmamic.ch/welcome-to-my-new-blog</link><guid isPermaLink="true">https://blog.lehmamic.ch/welcome-to-my-new-blog</guid><dc:creator><![CDATA[Michael Lehmann]]></dc:creator><pubDate>Mon, 01 Mar 2021 23:00:00 GMT</pubDate><content:encoded><![CDATA[<p>Welcome to my new developer blog. After having a long blogging break I decided to move away from my old blog <a target="_blank" href="http://lehmamic.wordpress.com">lehmamic.wordpress.com</a> on WordPress. You can still visit my old blog though. As a consultant and architect in software development, I have experienced a lot and also stumbled over some problems. My goal is to document my experiences, adventures, and ideas and share them with you. I hope this information can be helpful for someone else, instead of just hanging around in my notes. ## About me I am a husband, father, developer, architect, consultant, coach, and occasional speaker with passion. I work at <a target="_blank" href="https://zuehlke.com">Zühlke Engineering AG</a> as lead software architect. I advise my customers in development, architecture, and DevOps topics and develop software with them that gives them added value. I graduated with a diploma in information technology from University of Applied Sciences Winterthur in 2007. I worked as a Dot Net software engineer for several years until I joined Zuehlke in 2012 to become a consultant. I have a lot of experience in developing and designing distributed systems, event-driven architectures, building frontends in various technologies, and driving agile methodologies, cultures and DevOps as well in the development teams.</p>
]]></content:encoded></item></channel></rss>