kasi-auth-source.el (4926B)
1 ;;; kasi-auth-source.el --- auth-sources backend for kasi -*- lexical-binding: t -*- 2 3 ;; Copyright (C) 2026 Vineet K 4 5 ;; Author: Vineet K <git@vineetk.net> 6 ;; Version: 1.0 7 8 ;; This program is free software; you can redistribute it and/or modify 9 ;; it under the terms of the GNU General Public License as published by 10 ;; the Free Software Foundation, either version 3 of the License, or 11 ;; (at your option) any later version. 12 13 ;; This program is distributed in the hope that it will be useful, 14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 ;; GNU General Public License for more details. 17 18 ;; You should have received a copy of the GNU General Public License 19 ;; along with this program. If not, see <https://www.gnu.org/licenses/>. 20 21 ;;; Commentary: 22 23 ;; Provides an auth-sources backend for kasi.el. After loading, add 24 ;; 'kasi to `auth-sources', e.g.: 25 ;; 26 ;; (add-to-list 'auth-sources 'kasi) 27 ;; (auth-source-forget-all-cached) 28 ;; 29 ;; The kasi file path (e.g. "category/file") is matched against the 30 ;; `:host' parameter only if it contains a "/" (i.e. looks like a 31 ;; directory path). Otherwise the `:host' is ignored and the search 32 ;; falls back to matching by `:user'. 33 34 ;;; Code: 35 36 (require 'auth-source) 37 (require 'kasi) 38 (require 'cl-lib) 39 (require 'seq) 40 41 (eval-when-compile (require 'subr-x)) 42 43 (defgroup kasi-auth-source nil 44 "auth-sources integration for kasi." 45 :prefix "kasi-auth-source-" 46 :group 'auth-source 47 :group 'kasi) 48 49 (cl-defun kasi-auth-source--search (&rest spec 50 &key backend type host user 51 port require max 52 &allow-other-keys) 53 "Search kasi entries matching SPEC. 54 55 See `auth-source-search' for details on SPEC, BACKEND, TYPE, HOST, 56 USER, PORT, REQUIRE, and MAX." 57 (cl-assert (or (null type) (eq type (oref backend type))) 58 t "Invalid kasi search: %s %s" type (oref backend type)) 59 60 (when (eq host t) 61 (warn "kasi-auth-source does not handle host wildcards.") 62 (cl-return-from kasi-auth-source--search nil)) 63 64 (when-let* ((results (kasi-auth-source--find host user port require))) 65 (when (and max (> (length results) max)) 66 (setq results (seq-take results max))) 67 results)) 68 69 (defun kasi-auth-source--find (host user port require) 70 "Find kasi entries matching HOST, USER, PORT and REQUIRE. 71 72 Searches all kasi files under `kasi-dir`. HOST is matched against 73 the kasi file path (e.g. \"category/file\"). USER is matched against 74 the username stored in each kasi entry. PORT and REQUIRE are 75 optional filters." 76 (let ((files (file-expand-wildcards (concat kasi-dir "/*/*"))) 77 result) 78 (cl-block nil 79 (dolist (file files) 80 (message "kasi-auth-source: checking %s" file) 81 (when-let* ((short-name (kasi--filename-short file)) 82 ((or (not host) (not (string-match-p "/" host)) (string= short-name host))) 83 (entry-user (kasi--get file 'username)) 84 (entry-email (kasi--get file 'email)) 85 ((or (not user) (string= entry-user user))) 86 (require-match (seq-every-p 87 (lambda (key) 88 (pcase key 89 ('user (and user (string= entry-user user))) 90 ('host t) 91 ('port t) 92 (_ t))) 93 (or require '())))) 94 (setq result (list (list :host short-name 95 :user entry-user 96 :port port 97 :email entry-email 98 :secret (lambda () 99 (let ((pw (kasi--get file 'password))) 100 pw))))) 101 (cl-return-from nil result))) 102 result))) 103 104 (defvar kasi-auth-source-backend 105 (auth-source-backend 106 :source "." 107 :type 'kasi 108 :search-function #'kasi-auth-source--search) 109 "Auth-source backend for kasi.") 110 111 (defun kasi-auth-source-backend-parse (entry) 112 "Create a kasi auth-source backend from ENTRY." 113 (when (eq entry 'kasi) 114 (auth-source-backend-parse-parameters entry kasi-auth-source-backend))) 115 116 (add-hook 'auth-source-backend-parser-functions 117 #'kasi-auth-source-backend-parse) 118 119 ;;;###autoload 120 (defun kasi-auth-source-enable () 121 "Enable kasi as an auth-source backend. 122 123 This adds 'kasi to `auth-sources' and clears the auth-source cache." 124 (interactive) 125 (add-to-list 'auth-sources 'kasi) 126 (auth-source-forget-all-cached) 127 (message "kasi auth-source backend enabled")) 128 129 (provide 'kasi-auth-source) 130 ;;; kasi-auth-source.el ends here