summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVineet Kumar <git@vineetk.net>2026-05-22 16:45:27 -0400
committerVineet Kumar <git@vineetk.net>2026-05-22 16:47:40 -0400
commit6cbb431459e9a0db73264c4144937a136fdb5b83 (patch)
tree215f8cd38160a0005a03890e39a3af815bdcfaac
parentf3e21ba9cdaec50f2a99f8d33e68204c694c7ac7 (diff)
add random password/username generation
-rw-r--r--kasi.el55
1 files changed, 44 insertions, 11 deletions
diff --git a/kasi.el b/kasi.el
index f2ca588..1031afd 100644
--- a/kasi.el
+++ b/kasi.el
@@ -44,35 +44,68 @@
44 44
45(defvar kasi-version "1.0") 45(defvar kasi-version "1.0")
46 46
47(defun kasi-filename-short (file) 47(defun kasi--filename-short (file)
48 "Returns shortened name of filename." 48 "Returns shortened name of filename."
49 (file-name-sans-extension 49 (file-name-sans-extension
50 (file-relative-name file kasi-dir))) 50 (file-relative-name file kasi-dir)))
51 51
52(defun kasi-filename () 52(defun kasi--filename ()
53 "Returns full filename of the secret file." 53 "Returns full filename of the secret file."
54 (let* ((filenames (file-expand-wildcards (format "%s/*/*" kasi-dir))) 54 (let* ((filenames (file-expand-wildcards (format "%s/*/*" kasi-dir)))
55 (options (mapcar (lambda (f) 55 (options (mapcar (lambda (f)
56 (kasi-filename-short f)) 56 (kasi--filename-short f))
57 filenames)) 57 filenames))
58 (selected (completing-read "File: " options)) 58 (selected (completing-read "File: " options))
59 (file (elt filenames (seq-position options selected)))) 59 (file (elt filenames (seq-position options selected))))
60 file)) 60 file))
61 61
62(defun kasi-get (file elem) 62(defun kasi--get (file elem)
63 "Returns element from secret file." 63 "Returns element from secret file."
64 (car (with-temp-buffer 64 (car (with-temp-buffer
65 (insert-file-contents file) 65 (insert-file-contents file)
66 (alist-get elem (read (current-buffer)))))) 66 (alist-get elem (read (current-buffer))))))
67 67
68(defun kasi-totp (file) 68(defun kasi--totp (file)
69 "Returns current TOTP code from secret file." 69 "Returns current TOTP code from secret file."
70 (let* ((totp-secret (kasi-get file 'totp)) 70 (let* ((totp-secret (kasi--get file 'totp))
71 (totp-code (totp (base32-hex-decode totp-secret)))) 71 (totp-code (totp (base32-hex-decode totp-secret))))
72 (kill-new totp-code) 72 (kill-new totp-code)
73 (message (format "TOTP %s for %s copied to kill ring" 73 (message (format "TOTP %s for %s copied to kill ring"
74 totp-code 74 totp-code
75 (kasi-filename-short file))))) 75 (kasi--filename-short file)))))
76
77(defun kasi--random-string (length charset)
78 "Generate a random string of LENGTH using characters from CHARSET.
79Uses /dev/urandom for cryptographic security."
80 ;; I have not seen any other built-in way to get cryptographically
81 ;; random outputs in Emacs.
82 (let* ((bytes (with-temp-buffer
83 (call-process "dd" nil (current-buffer) nil
84 "if=/dev/urandom" "bs=1" (format "count=%d" (* length 4)))
85 (buffer-string)))
86 (charset-len (length charset))
87 (result ""))
88 (dotimes (i length)
89 (setq result (concat result
90 (char-to-string
91 (aref charset
92 (% (aref bytes i)
93 charset-len))))))
94 result))
95
96;;;###autoload
97(defun kasi-generate-password (&optional length)
98 "Generate a random password of LENGTH (default 32)."
99 (interactive "P")
100 (let ((charset "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\"!#$%&'()*+,-./:;<=>?@[]^_`{|}~"))
101 (message (kasi--random-string (or length 32) charset))))
102
103;;;###autoload
104(defun kasi-generate-username (&optional length)
105 "Generate a random username of LENGTH (default 12)."
106 (interactive "P")
107 (let ((charset "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"))
108 (message (kasi--random-string (or length 12) charset))))
76 109
77;;;###autoload 110;;;###autoload
78(defun kasi (command file) 111(defun kasi (command file)
@@ -83,15 +116,15 @@
83 username 116 username
84 email 117 email
85 totp))) 118 totp)))
86 (kasi-filename))) 119 (kasi--filename)))
87 (pcase command 120 (pcase command
88 ('edit (find-file-other-window file)) 121 ('edit (find-file-other-window file))
89 ('totp (kasi-totp file)) 122 ('totp (kasi--totp file))
90 ((or 'password 'username 'email) 123 ((or 'password 'username 'email)
91 (progn 124 (progn
92 (kill-new (kasi-get file command)) 125 (kill-new (kasi--get file command))
93 (message (format "Copied %s for %s to kill ring." 126 (message (format "Copied %s for %s to kill ring."
94 command 127 command
95 (kasi-filename-short file))))))) 128 (kasi--filename-short file)))))))
96 129
97(provide 'kasi) 130(provide 'kasi)