commit 33ffbe9942efeccb22cbf3dc18867d3e7ced0ca9
parent 10002372e673953655032736a0723806cde98357
Author: Vineet Kumar <git@vineetk.net>
Date: Sun, 31 May 2026 14:31:27 -0400
add auth-source backend
Diffstat:
| A | kasi-auth-source.el | | | 129 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 129 insertions(+), 0 deletions(-)
diff --git a/kasi-auth-source.el b/kasi-auth-source.el
@@ -0,0 +1,129 @@
+;;; kasi-auth-source.el --- auth-sources backend for kasi -*- lexical-binding: t -*-
+
+;; Copyright (C) 2026 Vineet K
+
+;; Author: Vineet K <git@vineetk.net>
+;; Version: 1.0
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Provides an auth-sources backend for kasi.el. After loading, add
+;; 'kasi to `auth-sources', e.g.:
+;;
+;; (add-to-list 'auth-sources 'kasi)
+;; (auth-source-forget-all-cached)
+;;
+;; The kasi file path (e.g. "category/file") is matched against the
+;; `:host' parameter. The `:user' parameter can optionally be used to
+;; filter by the username stored in the kasi entry.
+
+;;; Code:
+
+(require 'auth-source)
+(require 'kasi)
+(require 'cl-lib)
+(require 'seq)
+
+(eval-when-compile (require 'subr-x))
+
+(defgroup kasi-auth-source nil
+ "auth-sources integration for kasi."
+ :prefix "kasi-auth-source-"
+ :group 'auth-source
+ :group 'kasi)
+
+(cl-defun kasi-auth-source--search (&rest spec
+ &key backend type host user
+ port require max
+ &allow-other-keys)
+ "Search kasi entries matching SPEC.
+
+See `auth-source-search' for details on SPEC, BACKEND, TYPE, HOST,
+USER, PORT, REQUIRE, and MAX."
+ (cl-assert (or (null type) (eq type (oref backend type)))
+ t "Invalid kasi search: %s %s" type (oref backend type))
+
+ (when (eq host t)
+ (warn "kasi-auth-source does not handle host wildcards.")
+ (cl-return-from kasi-auth-source--search nil))
+
+ (when-let* ((results (kasi-auth-source--find host user port require)))
+ (when (and max (> (length results) max))
+ (setq results (seq-take results max)))
+ results))
+
+(defun kasi-auth-source--find (host user port require)
+ "Find kasi entries matching HOST, USER, PORT and REQUIRE.
+
+Searches all kasi files under `kasi-dir`. HOST is matched against
+the kasi file path (e.g. \"category/file\"). USER is matched against
+the username stored in each kasi entry. PORT and REQUIRE are
+optional filters."
+ (let ((files (file-expand-wildcards (concat kasi-dir "/*/*")))
+ result)
+ (cl-block nil
+ (dolist (file files)
+ (message "kasi-auth-source: checking %s" file)
+ (when-let* ((short-name (kasi--filename-short file))
+ ((or (not host) (string= short-name host)))
+ (entry-user (kasi--get file 'username))
+ (entry-email (kasi--get file 'email))
+ ((or (not user) (string= entry-user user)))
+ (require-match (seq-every-p
+ (lambda (key)
+ (pcase key
+ ('user (and user (string= entry-user user)))
+ ('host t)
+ ('port t)
+ (_ t)))
+ (or require '()))))
+ (setq result (list (list :host short-name
+ :user entry-user
+ :port port
+ :email entry-email
+ :secret (lambda ()
+ (let ((pw (kasi--get file 'password)))
+ pw)))))
+ (cl-return-from nil result)))
+ result)))
+
+(defvar kasi-auth-source-backend
+ (auth-source-backend
+ :source "."
+ :type 'kasi
+ :search-function #'kasi-auth-source--search)
+ "Auth-source backend for kasi.")
+
+(defun kasi-auth-source-backend-parse (entry)
+ "Create a kasi auth-source backend from ENTRY."
+ (when (eq entry 'kasi)
+ (auth-source-backend-parse-parameters entry kasi-auth-source-backend)))
+
+(add-hook 'auth-source-backend-parser-functions
+ #'kasi-auth-source-backend-parse)
+
+;;;###autoload
+(defun kasi-auth-source-enable ()
+ "Enable kasi as an auth-source backend.
+
+This adds 'kasi to `auth-sources' and clears the auth-source cache."
+ (interactive)
+ (add-to-list 'auth-sources 'kasi)
+ (auth-source-forget-all-cached)
+ (message "kasi auth-source backend enabled"))
+
+(provide 'kasi-auth-source)
+;;; kasi-auth-source.el ends here