diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-23 19:05:01 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-23 19:05:01 -0500 |
| commit | fcac4e94c7dd858e7d8604afb3e10e731bf1c8b7 (patch) | |
| tree | 11cb3006702f0dad43d76744c1bebcbab7561490 | |
| parent | b70781e8eeaa67cf2a1aa804c27b92f38fd52742 (diff) | |
| download | dotemacs-fcac4e94c7dd858e7d8604afb3e10e731bf1c8b7.tar.gz dotemacs-fcac4e94c7dd858e7d8604afb3e10e731bf1c8b7.zip | |
refactor(restclient): remove SkyFi key-injection feature
cj/restclient-skyfi-buffer opened the SkyFi template in a file-visiting buffer and rewrote the :skyfi-key line with the live key from authinfo. An accidental save would then persist the plaintext key to disk, which breaks the module's own "key never stored on disk" promise. The template file was gitignored and never tracked, so the exposure was local only, not a repo leak.
I removed the feature rather than hardening it: cj/skyfi-api-key, cj/restclient--inject-skyfi-key, cj/restclient-skyfi-buffer, the C-; R s binding, and the two SkyFi test files are gone, along with the local template. The generic restclient setup stays: scratch buffer on C-; R n, open a .rest file on C-; R o.
| -rw-r--r-- | modules/restclient-config.el | 41 | ||||
| -rw-r--r-- | tests/test-restclient-config-inject-skyfi-key.el | 147 | ||||
| -rw-r--r-- | tests/test-restclient-config-skyfi-buffer.el | 38 |
3 files changed, 1 insertions, 225 deletions
diff --git a/modules/restclient-config.el b/modules/restclient-config.el index 650bb781..6d38739d 100644 --- a/modules/restclient-config.el +++ b/modules/restclient-config.el @@ -8,13 +8,9 @@ ;; results inline. Supports .rest files with variable substitution for ;; reusable API templates. ;; -;; Includes SkyFi satellite imagery API integration with automatic key -;; injection from authinfo.gpg (key never stored on disk). -;; ;; Keybindings (C-; R prefix): ;; - C-; R n : New scratch *restclient* buffer ;; - C-; R o : Open a .rest file (defaults to data/) -;; - C-; R s : Open SkyFi API template ;;; Code: @@ -35,31 +31,8 @@ :if (executable-find "jq") :after restclient) -;; ----------------------------- Private Helpers ------------------------------- - -(defun cj/restclient--inject-skyfi-key () - "Replace the :skyfi-key variable line with the real key from authinfo. -Only acts when the buffer is in `restclient-mode', the filename ends -in \"skyfi-api.rest\", and a :skyfi-key line exists. If the auth -lookup returns nil, leaves the buffer unchanged." - (when (and (derived-mode-p 'restclient-mode) - buffer-file-name - (string-match-p "skyfi-api\\.rest\\'" buffer-file-name)) - (let ((key (condition-case nil - (cj/skyfi-api-key) - (error nil)))) - (when key - (save-excursion - (goto-char (point-min)) - (when (re-search-forward "^:skyfi-key = .*$" nil t) - (replace-match (format ":skyfi-key = %s" key)))))))) - ;; ----------------------------- Public Functions ------------------------------ -(defun cj/skyfi-api-key () - "Fetch SkyFi API key from authinfo.gpg." - (cj/auth-source-secret "app.skyfi.com" "apikey")) - (defun cj/restclient-new-buffer () "Open a scratch *restclient* buffer in `restclient-mode'." (interactive) @@ -77,28 +50,16 @@ lookup returns nil, leaves the buffer unchanged." (string-match-p "\\.rest\\'" f)))))) (find-file file))) -(defun cj/restclient-skyfi-buffer () - "Open the SkyFi API template file. -Runs the key-injection hook after opening." - (interactive) - (let ((skyfi-file (expand-file-name "skyfi-api.rest" cj/restclient-data-dir))) - (unless (file-exists-p skyfi-file) - (user-error "SkyFi template not found: %s" skyfi-file)) - (find-file skyfi-file) - (cj/restclient--inject-skyfi-key))) - ;; -------------------------------- Keybindings -------------------------------- (global-set-key (kbd "C-; R n") #'cj/restclient-new-buffer) (global-set-key (kbd "C-; R o") #'cj/restclient-open-file) -(global-set-key (kbd "C-; R s") #'cj/restclient-skyfi-buffer) (with-eval-after-load 'which-key (which-key-add-key-based-replacements "C-; R" "REST client" "C-; R n" "new scratch buffer" - "C-; R o" "open .rest file" - "C-; R s" "SkyFi API template")) + "C-; R o" "open .rest file")) (provide 'restclient-config) ;;; restclient-config.el ends here diff --git a/tests/test-restclient-config-inject-skyfi-key.el b/tests/test-restclient-config-inject-skyfi-key.el deleted file mode 100644 index d471b913..00000000 --- a/tests/test-restclient-config-inject-skyfi-key.el +++ /dev/null @@ -1,147 +0,0 @@ -;;; test-restclient-config-inject-skyfi-key.el --- Tests for cj/restclient--inject-skyfi-key -*- lexical-binding: t; -*- - -;;; Commentary: -;; Unit tests for cj/restclient--inject-skyfi-key function. -;; Replaces the :skyfi-key placeholder in a restclient buffer with the real -;; API key from authinfo. Tests cover Normal, Boundary, and Error cases. - -;;; Code: - -(when noninteractive - (package-initialize)) - -(require 'ert) -(require 'restclient-config) - -;; --------------------------------------------------------------------------- -;; Test Helpers -;; --------------------------------------------------------------------------- - -(defvar test-inject--fake-key "sk_test_fake_key_12345" - "Fake API key used in tests.") - -(defmacro test-inject--with-skyfi-buffer (content &rest body) - "Create a temp buffer with CONTENT simulating skyfi-api.rest, then run BODY. -Sets buffer-file-name to skyfi-api.rest and activates restclient-mode. -Binds `cj/skyfi-api-key' to return `test-inject--fake-key'." - (declare (indent 1)) - `(with-temp-buffer - (insert ,content) - (setq buffer-file-name (expand-file-name "data/skyfi-api.rest" user-emacs-directory)) - (restclient-mode) - (cl-letf (((symbol-function 'cj/skyfi-api-key) - (lambda () test-inject--fake-key))) - ,@body))) - -;; --------------------------------------------------------------------------- -;;; Normal Cases -;; --------------------------------------------------------------------------- - -(ert-deftest test-inject-skyfi-key-replaces-placeholder () - "Replaces :skyfi-key = PLACEHOLDER with real key." - (test-inject--with-skyfi-buffer - ":skyfi-key = PLACEHOLDER\n#\nGET https://example.com\n" - (cj/restclient--inject-skyfi-key) - (goto-char (point-min)) - (should (string-match-p (format ":skyfi-key = %s" test-inject--fake-key) - (buffer-string))))) - -(ert-deftest test-inject-skyfi-key-preserves-other-content () - "Rest of buffer content unchanged after injection." - (let ((rest-content "# SkyFi API\nGET https://app.skyfi.com/platform-api/\nAPIKey: :skyfi-key\n")) - (test-inject--with-skyfi-buffer - (concat ":skyfi-key = PLACEHOLDER\n" rest-content) - (cj/restclient--inject-skyfi-key) - (should (string-match-p "# SkyFi API" (buffer-string))) - (should (string-match-p "APIKey: :skyfi-key" (buffer-string)))))) - -(ert-deftest test-inject-skyfi-key-only-replaces-skyfi-key-line () - "Does not modify other restclient variable lines." - (test-inject--with-skyfi-buffer - ":skyfi-key = PLACEHOLDER\n:other-var = keep-me\n" - (cj/restclient--inject-skyfi-key) - (should (string-match-p ":other-var = keep-me" (buffer-string))))) - -;; --------------------------------------------------------------------------- -;;; Boundary Cases -;; --------------------------------------------------------------------------- - -(ert-deftest test-inject-skyfi-key-no-key-line-no-error () - "Buffer with no :skyfi-key line — no change, no error." - (test-inject--with-skyfi-buffer - "# Just comments\nGET https://example.com\n" - (let ((before (buffer-string))) - (cj/restclient--inject-skyfi-key) - (should (string= before (buffer-string)))))) - -(ert-deftest test-inject-skyfi-key-already-has-value () - "Buffer where :skyfi-key already has a real value — still replaces (idempotent)." - (test-inject--with-skyfi-buffer - ":skyfi-key = old_real_key_abc\n" - (cj/restclient--inject-skyfi-key) - (should (string-match-p (format ":skyfi-key = %s" test-inject--fake-key) - (buffer-string))))) - -(ert-deftest test-inject-skyfi-key-empty-buffer () - "Empty buffer — no error." - (test-inject--with-skyfi-buffer "" - (cj/restclient--inject-skyfi-key) - (should (string= "" (buffer-string))))) - -(ert-deftest test-inject-skyfi-key-only-first-occurrence () - "Multiple :skyfi-key lines — only first replaced." - (test-inject--with-skyfi-buffer - ":skyfi-key = PLACEHOLDER\n:skyfi-key = SECOND\n" - (cj/restclient--inject-skyfi-key) - (let ((content (buffer-string))) - (should (string-match-p (format ":skyfi-key = %s" test-inject--fake-key) content)) - (should (string-match-p ":skyfi-key = SECOND" content))))) - -;; --------------------------------------------------------------------------- -;;; Error Cases -;; --------------------------------------------------------------------------- - -(ert-deftest test-inject-skyfi-key-wrong-mode-no-replacement () - "Wrong major mode — no replacement happens." - (with-temp-buffer - (insert ":skyfi-key = PLACEHOLDER\n") - (setq buffer-file-name (expand-file-name "data/skyfi-api.rest" user-emacs-directory)) - (fundamental-mode) - (let ((before (buffer-string))) - (cj/restclient--inject-skyfi-key) - (should (string= before (buffer-string)))))) - -(ert-deftest test-inject-skyfi-key-wrong-filename-no-replacement () - "Wrong filename — no replacement happens." - (with-temp-buffer - (insert ":skyfi-key = PLACEHOLDER\n") - (setq buffer-file-name "/tmp/other-file.rest") - (restclient-mode) - (let ((before (buffer-string))) - (cj/restclient--inject-skyfi-key) - (should (string= before (buffer-string)))))) - -(ert-deftest test-inject-skyfi-key-no-filename-no-replacement () - "No filename (scratch buffer) — no replacement happens." - (with-temp-buffer - (insert ":skyfi-key = PLACEHOLDER\n") - (restclient-mode) - (setq buffer-file-name nil) - (let ((before (buffer-string))) - (cj/restclient--inject-skyfi-key) - (should (string= before (buffer-string)))))) - -(ert-deftest test-inject-skyfi-key-auth-returns-nil-no-error () - "Auth-source returns nil — no error, no replacement." - (with-temp-buffer - (insert ":skyfi-key = PLACEHOLDER\n") - (setq buffer-file-name (expand-file-name "data/skyfi-api.rest" user-emacs-directory)) - (restclient-mode) - (cl-letf (((symbol-function 'cj/skyfi-api-key) - (lambda () nil))) - (let ((before (buffer-string))) - (cj/restclient--inject-skyfi-key) - (should (string= before (buffer-string))))))) - -(provide 'test-restclient-config-inject-skyfi-key) -;;; test-restclient-config-inject-skyfi-key.el ends here diff --git a/tests/test-restclient-config-skyfi-buffer.el b/tests/test-restclient-config-skyfi-buffer.el deleted file mode 100644 index 7685c77c..00000000 --- a/tests/test-restclient-config-skyfi-buffer.el +++ /dev/null @@ -1,38 +0,0 @@ -;;; test-restclient-config-skyfi-buffer.el --- Tests for cj/restclient-skyfi-buffer -*- lexical-binding: t; -*- - -;;; Commentary: -;; Unit tests for cj/restclient-skyfi-buffer function. -;; Opens the SkyFi API template file. -;; Covers Normal and Error cases. - -;;; Code: - -(when noninteractive - (package-initialize)) - -(require 'ert) -(require 'restclient-config) - -;;; Normal Cases - -(ert-deftest test-restclient-skyfi-buffer-opens-file () - "Opens existing skyfi-api.rest file and switches to it." - (let ((skyfi-file (expand-file-name "data/skyfi-api.rest" user-emacs-directory))) - (when (file-exists-p skyfi-file) - (unwind-protect - (progn - (cj/restclient-skyfi-buffer) - (should (string-match-p "skyfi-api\\.rest" - (buffer-file-name (current-buffer))))) - (when-let ((buf (get-file-buffer skyfi-file))) - (kill-buffer buf)))))) - -;;; Error Cases - -(ert-deftest test-restclient-skyfi-buffer-missing-file-signals-error () - "Signals user-error when skyfi-api.rest does not exist." - (let ((cj/restclient-data-dir "/tmp/nonexistent-restclient-test-dir/")) - (should-error (cj/restclient-skyfi-buffer) :type 'user-error))) - -(provide 'test-restclient-config-skyfi-buffer) -;;; test-restclient-config-skyfi-buffer.el ends here |
