01 Dec 2024

Servant and a weirdness in Keycloak

When writing a small tool to interface with Keycloak I found an endpoint that require the content type to be application/json while the body should be plain text. (The details are in the issue.) Since servant assumes that the content type and the content match (I know, I'd always thought that was a safe assumption to make too) it doesn't work with ReqBody '[JSON] Text. Instead I had to create a custom type that's a combination of JSON and PlainText, something that turned out to required surprisingly little code:

data KeycloakJSON deriving (Typeable)

instance Accept KeycloakJSON where
    contentType _ = "application" // "json"

instance MimeRender KeycloakJSON Text where
    mimeRender _ = fromStrict . encodeUtf8

The bug has already been fixed in Keycloak, but I'm sure there are other APIs with similar weirdness so maybe this will be useful to someone else.

Tags: haskell servant
09 Sep 2024

Followup on secrets in my work notes

I got the following question on my post on how I handle secrets in my work notes:

Sounds like a nice approach for other secrets but how about :dbconnection for Orgmode and sql-connection-alist?

I have to admit I'd never come across the variable sql-connection-alist before. I've never really used sql-mode for more than editing SQL queries and setting up code blocks for running them was one of the first things I used yasnippet for.

I did a little reading and unfortunately it looks like sql-connection-alist can only handle string values. However, there is a variable sql-password-search-wallet-function, with the default value of sql-auth-source-search-wallet, so using auth-source is already supported for the password itself.

There seems to be a lack of good tutorials for setting up sql-mode in a secure way – all articles I found place the password in clear-text in the config – filling that gap would be a nice way to contribute to the Emacs community. I'm sure it'd prompt me to re-evaluate incorporating sql-mode in my workflow.

Tags: emacs org-mode
01 Sep 2024

Improving how I handle secrets in my work notes

At work I use org-mode to keep notes about useful ways to query our systems, mostly that involves using the built-in SQL support to access DBs and ob-http to send HTTP requests. In both cases I often need to provide credentials for the systems. I'm embarrassed to admit it, but for a long time I've taken the easy path and kept all credentials in clear text. Every time I've used one of those code blocks I've thought I really ought to find a better way of handling these secrets one of these days. Yesterday was that day.

I ended up with two functions that uses auth-source and its ~/.authinfo.gpg file.

(defun mes/auth-get-pwd (host)
  "Get the password for a host (authinfo.gpg)"
  (-> (auth-source-search :host host)
      car
      (plist-get :secret)
      funcall))

(defun mes/auth-get-key (host key)
  "Get a key's value for a host (authinfo.gpg)

Not usable for getting the password (:secret), use 'mes/auth-get-pwd'
for that."
  (-> (auth-source-search :host host)
      car
      (plist-get key)))

It turns out that the library can handle more keys than the documentation suggests so for DB entries I'm using a machine (:host) that's a bit shorter and easier to remember than the full AWS hostname. Then I keep the DB host and name in dbhost (:dbhost) and dbname (:dbname) respectively. That makes an entry look like this:

machine db.svc login user port port password pwd dbname dbname dbhost dbhost

If I use it in a property drawer it looks like this

:PROPERTIES:
:header-args:sql: :engine postgresql
:header-args:sql+: :dbhost (mes/auth-get-key "db.svc" :dbhost)
:header-args:sql+: :dbport (string-to-number (mes/auth-get-key "db.svc" :port))
:header-args:sql+: :dbuser (mes/auth-get-key "db.svc" :user)
:header-args:sql+: :dbpassword (mes/auth-get-pwd "db.svc")
:header-args:sql+: :database (mes/auth-get-key "db.svc" :dbname)
:END:
Tags: emacs org-mode
11 Aug 2024

Removing symlink question

I'm not sure why, but all of a sudden I started getting this question every time emacs starts

Symbolic link to Git-controlled source file; follow link?

After some searching I found out that it's VC asking. I'm guessing this comes from straight's very liberal use of symlinks. Though I'm still a little surprised at VC kicking in when reading the config.

Anyway, there are two variables to consider, vc-follow-symlinks and vc-handled-backends. I opted to modify the latter one, and since I don't use VC at all I'm turning it off completely.

(setopt vc-handled-backends nil)
Tags: emacs
21 Jul 2024

Emacs via Nix with mu4e

I've been running development versions of Emacs ever since I switched to Wayland and needed the PGTK code. The various X-git packages on AUR makes that easy, as long as one doesn't mind building the packages locally, and regularly. Building a large package like Emacs does get a bit tiring after a while though so I started looking at the emacs overlay to see if I could keep up without building quite that much.

The first attempt at this failed as I couldn't get my email setup working; emacs simply refused to find the locally installed mu4e package. I felt I didn't have time to solve it at the time, reverted back to doing the builds myself again. It kept irritating me though, and today I made another attempt. This time I invested a bit more time in reading up on how to install emacs via Nix with packages. Something that paid off.

I'm managing my packages using nix profile and a flake.nix. To install emacs with a working mu4e I started with adding the emacs overlay to the inputs

inputs = {
  nixpkgs.url = "github:nixos/nixpkgs?ref=nixpkgs-unstable";
  ...
  community-emacs.url = "github:nix-community/emacs-overlay";
};

and in my outputs I made sure to use the overlay on nixpkgs

outputs = inputs@{ nixpkgs, community-emacs, ... }:
  let
    system = "x86_64-linux";
    pkgs = import nixpkgs {
      inherit system;
      overlays = [ community-emacs.overlays.emacs ];
    };
    ...

and in the list of packages passed to pkgs.buildEnv I added

...
((emacsPackagesFor emacs-pgtk).emacsWithPackages
  (epkgs: [ epkgs.mu4e ]))
mu
...

That's all there's to it. After running nix profile update 0 I had a build of emacs with Wayland support that's less than a day old, all downloaded from the community cache. Perfect!

Tags: emacs nix
Other posts