about summary refs log tree commit diff
diff options
context:
space:
mode:
authorsefidel <contact@sefidel.net>2024-02-19 20:26:04 +0900
committersefidel <contact@sefidel.net>2024-02-19 20:26:04 +0900
commitb87d8f473020d1495bbaf42976d96c5c589c88ff (patch)
tree87e71bdb9df2813e0c070a4a3a76fcae4c7bb756
parent4705b022723290a8e4402945f9cf4c75da2331a3 (diff)
downloadinfra-b87d8f473020d1495bbaf42976d96c5c589c88ff.tar.gz
infra-b87d8f473020d1495bbaf42976d96c5c589c88ff.zip
feat(modules/akkoma): support OAuth login
-rw-r--r--modules/services/akkoma/default.nix68
1 files changed, 67 insertions, 1 deletions
diff --git a/modules/services/akkoma/default.nix b/modules/services/akkoma/default.nix
index 91aa2e8..3671cb4 100644
--- a/modules/services/akkoma/default.nix
+++ b/modules/services/akkoma/default.nix
@@ -15,6 +15,9 @@ in
     domain = mkOption { type = types.str; };
     realHost = mkOption { type = types.str; };
     instanceName = mkOption { type = types.str; default = "Akkoma on ${cfg.domain}"; };
+
+    oauthBaseUrl = mkOption { type = types.str; default = "Base URL of the OAuth provider"; };
+    secrets.akkoma-envs = mkOption { type = types.str; default = "Path to the akkoma environment file"; };
   };
 
   config = mkIf cfg.enable {
@@ -22,6 +25,43 @@ in
 
     services.akkoma = {
       enable = true;
+      package = pkgs.akkoma.overrideAttrs (old: {
+        # Akkoma doesn't include OAuth2 dependencies by default
+        # This can be obtained by running `OAUTH_CONSUMER_STRATEGIES="..." mix deps.get`.
+        # The server should also be launched with the same environment variable set.
+        nativeBuildInputs = let
+          inherit (pkgs.beamPackages) fetchHex buildMix;
+          oldMixDeps = old.passthru.mixNixDeps;
+        in old.nativeBuildInputs ++ builtins.attrValues rec {
+          # TODO: This needs to be bumped from time to time
+          oauth2 = buildMix rec {
+            name = "oauth2";
+            version = "2.1.0";
+
+            src = fetchHex {
+              pkg = name;
+              inherit version;
+              sha256 = "0h9bps7gq7bac5gc3q0cgpsj46qnchpqbv5hzsnd2z9hnf2pzh4a";
+            };
+
+            beamDeps = [ oldMixDeps.tesla ];
+          };
+          ueberauth_keycloak_strategy = buildMix rec {
+            name = "ueberauth_keycloak_strategy";
+            version = "0.4.0";
+
+            src = fetchHex {
+              pkg = name;
+              inherit version;
+              sha256 = "06r10w0azlpypjgggar1lf7h2yazn2dpyicy97zxkjyxgf9jfc60";
+            };
+
+            beamDeps = [ oauth2 oldMixDeps.ueberauth ];
+          };
+        };
+        OAUTH_CONSUMER_STRATEGIES = "keycloak:ueberauth_keycloak_strategy";
+      });
+
       initDb.enable = true;
 
       extraStatic = {
@@ -33,7 +73,7 @@ in
         "favicon.png" = wrapFile "favicon.png" ./favicon-withbg.png;
       };
       config =
-        let inherit ((pkgs.formats.elixirConf { }).lib) mkRaw mkMap;
+        let inherit ((pkgs.formats.elixirConf { }).lib) mkRaw mkMap mkTuple;
         in {
           ":pleroma"."Pleroma.Web.Endpoint".url.host = cfg.realHost;
           ":pleroma"."Pleroma.Web.WebFinger".domain = cfg.domain;
@@ -53,6 +93,9 @@ in
           ":pleroma".":frontend_configurations" = {
             pleroma_fe = mkMap {
               logo = "/static/logo.png";
+              # FIXME: https://akkoma.dev/AkkomaGang/akkoma/pulls/668
+              # TODO: enable on next release
+              # loginMethod = "token";
             };
           };
           ":pleroma".":mrf" = {
@@ -67,6 +110,23 @@ in
             enabled = true;
             method = mkRaw "Pleroma.Captcha.Kocaptcha";
           };
+          ":ueberauth" = {
+            "Ueberauth.Strategy.Keycloak.OAuth" = {
+              client_id = mkRaw ''System.get_env("AUTHENTIK_CLIENT_ID")'';
+              client_secret = mkRaw ''System.get_env("AUTHENTIK_CLIENT_SECRET")'';
+              site = cfg.oauthBaseUrl;
+              authorize_url = "${cfg.oauthBaseUrl}/application/o/authorize/";
+              token_url = "${cfg.oauthBaseUrl}/application/o/token/";
+              userinfo_url = "${cfg.oauthBaseUrl}/application/o/userinfo/";
+              token_method = mkRaw ":post";
+            };
+            Ueberauth.providers = {
+              keycloak = mkTuple [(mkRaw "Ueberauth.Strategy.Keycloak") {
+                default_scope = "openid profile email";
+                uid_field = mkRaw ":preferred_username";
+              }];
+            };
+          };
         };
 
       nginx = {
@@ -85,6 +145,12 @@ in
       };
     };
 
+    systemd.services.akkoma = {
+      after = [ "authentik.service" ];
+      environment.OAUTH_CONSUMER_STRATEGIES = "keycloak:ueberauth_keycloak_strategy";
+      serviceConfig.EnvironmentFile = cfg.secrets.akkoma-envs;
+    };
+
     services.nginx.virtualHosts.${cfg.domain} = {
       forceSSL = true;
       useACMEHost = cfg.domain;