Curious (Clojure) Programmer Simplicity matters

Menu

  • Home
  • Archives
  • Tags
  • About
  • My Talks
  • Weekly Bits & Pieces
  • Clojure Tip of the Day Screencast
  • RSS
February 28, 2022

Weekly Bits 05/2022 - Ukraine, CloudFront & OriginCommError, Double-submit cookies, Frontend monitoring, Emacs' query-replace-regexp

Table of Contents
  • Ukraine
  • PF.tv Domain Modeling series
    • 461: Rules of thumb don’t scale
  • Clojure
    • Learn Reagent - video course
  • AWS & Cloud
    • CloudFront - OriginCommError and mysterious timeouts
    • Terraform lifecycle policies vs modules
  • Reading (Books)
    • Grokking Simplicity
    • Api Security in Action
      • Double-submit cookies
    • Practical Monitoring
      • Frontend monitoring
  • MISC
    • Emacs - Searching and replacements via (query)-replace-regex
    • 1Password CLI & MFA authentication codes
  • Links

Some of the interesting things I did, learned, or found in the (week before the) past week. This time it’s not very complete and comes a bit later - the reason is simple:

Ukraine

We’ve been witnessess of terrible aggresivity with far-reaching consequences. As many others, I’m horrified. The people of Ukraine need all the support we can give them.

PF.tv Domain Modeling series

461: Rules of thumb don’t scale

  • We should analyze the structure of the domain. An important structural feature is alternative.

  • This method focuses on substance (alternative) first and style (which representation) second.

    • It is superior to design rules of thumb (“always/never use an interface for this or that”) or principles such as Open/Closed which focus exclusively on style.

  • Programming is like designing a door. We can’t say “program to interfaces” (Open/Closed principle).

    • Those are rules of thumb with the same problems as “make the doors symmetrical." or "design the door to require less hardware"

    • ⇒ they follow conflicting paths: Which one is correct?

  • We must understand the purpose (of the door, for instance)

    • Some doors welcome strangers off the street (customers). Others allow easy escape but no entry (fire escapes). Yet others signal an area private to some small group of people (employees only!).

    • ⇒ then consider the purpose and systemic context (cost, material availability, culture, etc.) to decide

Clojure

Learn Reagent - video course

Learn Reagent is a nice video course by Jacek Schae. It teaches you how to use Reagent to implement a single-page application to show gigs & orders.

While I used Reagent a couple of times, frontend programming is my weak point so I welcome this refreshing tutorial and I’m slowly going through it.

AWS & Cloud

CloudFront - OriginCommError and mysterious timeouts

Last week, I had a lot of "fun" with CloudFront and mysterious timeouts that some people were getting when accessing our website. The issues were intermittent and I couldn’t reproduce it myself which made it hard to debug.

After a lot of pain and suffering, inspecting CloudFront logs and searching on the Internet, I finally find what was the problem. Interested in knowing more? Read CloudFront and mysterious OriginCommError

Terraform lifecycle policies vs modules

Terraform lifecycle policy - lifecycle + ignore_changes can typically be used to ignore changes in some attributes. Unfortunately, this doesn’t work for modules and cannot be applied conditionally/dynamically.

Wisfull thinking:

  lifecycle {
    ignore_changes = [
      image_uri
    ]
  }

This is worth a separate blog post so I’m leaving out the details for later

Reading (Books)

Grokking Simplicity

I finished chapter 5 which contains some nice refactorings - factoring out calculations out of actions.

Here’s a good example of a function with too many responsibilities (see the comment in the code). Can you spot which part has which responsibility?

// this function is doing a lot of things...
// 1. It operates on 'buy buttons'
// 2. It does cart & item operations - adding new item, checking free shipping
// 3. It manipulates the DOM: hide/show free shipping icons
function update_shipping_icons(cart, buttons) {
  buttons.forEach(button => {
    const {item: {price, name}} = button;
    // this is the update: call make_cart_item
    const new_cart = add_item(cart, make_cart_item(name, price));
    if (gets_free_shipping(new_cart)) {
      button.show_free_shipping_icon();
    } else {
      button.hide_free_shipping_icon();
    }
  });
}

Api Security in Action

I was plodding through the chapter 4 examples and implementing all the examples.

There’s a ton of useful stuff so it’s hard to summarize. But it’s all about session cookies and how they can be used for authentication. It touches things like SOP (Same Origin Policy), Session fixation attacks, Timing attacks, CSRF and double-submit cookies.

Double-submit cookies

Double-submit cookies cookies are an interesting technique for protecting your API (used by a JavaScript client) leveraging cookies for authentication against CSRF. Using this technique, there’s a anti-CSRF token derived from the session token, preferably with a cryptographic hash function like SHA-256. This token is then read by JavaScript and stored in a cookie on the client. When the client (JavaScript) calls the API, it reads the cookie and passes its value in the X-CSRF-Token header which is then read and verified by the server.

Some sample code:

// the provided token is expected to be Base64-encoded version of SHA256 of session token
var providedToken = Base64Url.decode(request.headers("X-CSRF-Token"));
var computedToken =  sha256(session.id());
if (!MessageDigest.isEqual(providedToken, computedToken)) { (1)
    // somebody is trying to forge the token?
    return Optional.empty();
}

// here's the code to compute sha256
String randomToken = ...
MessageDigest.getInstance("sha256").digest(randomToken.getBytes(StandardCharsets.UTF_8));
  1. Using MessageDigest.isEqual instead of ordinary string equality we mitigate timing attacks.

Practical Monitoring

I read chapter 5 (Business Metrics) and chapter 6 (Frontend Monitoring).

Both of them are tremdendously useful and focus on monitoring real business KPIs and user experience rather than traditional monitoring which focuses on servers and low-level machine metrics.

Frontend monitoring

Two basic approaches:

  • Real User Monitoring (RUM) - preferable

  • Synthetic monitoring - tools like WebpageTest.org

Navigation Timing API - You can compute page load times:

  • total page load time = domComplete - navigationStart

  • user-perceived page load time = domComplete - navigationStart

MISC

Emacs - Searching and replacements via (query)-replace-regex

I was trying to move a bunch of widgets on a Cloudwatch dashboard. The problem was how to quickly add a fixed number to their y coordinate. A dashboard source is a JSON like this:

{
    "widgets": [
        {
            "height": 2,
            "width": 19,
            "y": 0,
            "x": 0,
...

And so it continues with many other widgets. I basically wanted to add number 10 to all those y coordinates.

For that, I found a very convenient emacs function query-replace-regex - the sequence goes like this:

C-M-%
"y": \([0-9]+\)
RET
"y": \,(+ 10 \#1)

This searches for all lines matching "y" followed by a number, capturing the value of the number with parentheses (a capturing group). Then using \, to provide arbitrary elisp expression and using \#1 to reference the first matching group and interpreting it as a number.

See section Regexp Replacement of the Emacs Manual for more details.

1Password CLI & MFA authentication codes

I’ve been using 1Password for a long time, but I’ve never used their CLI. This week, I was trying to fetch the one-time authentication code for my AWS account to produce a session token. So I installed 1Password CLI.

Getting the code is then easy:

eval $(op signin my);
op get totp  'AWS console login'; (1)
  1. 'AWS console login' is the name/title of the login item in 1Password

Links

A quick recap of some of the links mentioned in this post:

  • PF.tv 461: Rules of thumb don’t scale

  • Learn Reagent - video course

  • Emacs - Regexp Replacement

  • 1Password CLI


Tags: war security clojure aws emacs weekly-bits

« On the not-so-easy transition from lein-figwheel to figwheel-main CloudFront and mysterious OriginCommError »

Copyright © 2022 Juraj Martinka

Powered by Cryogen | Free Website Template by Download Website Templates