hamacs/ha-passwords.org
Howard Abrams f4df7d4368 Redact sensitive information with regular expressions
Found a great idea from Zenodium.
2023-09-18 10:32:59 -07:00

133 lines
5.3 KiB
Org Mode
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#+TITLE: Personal Password Generator
#+AUTHOR: Howard X. Abrams
#+DATE: 2021-01-11
A literate programming version for Emacs code to generate and store passwords.
#+begin_src emacs-lisp :exports none
;;; ha-passwords --- Emacs code to generate and store passwords. -*- lexical-binding: t; -*-
;;
;; © 2021-2023 Howard X. Abrams
;; Licensed under a Creative Commons Attribution 4.0 International License.
;; See http://creativecommons.org/licenses/by/4.0/
;;
;; Author: Howard X. Abrams <http://gitlab.com/howardabrams>
;; Maintainer: Howard X. Abrams
;; Created: January 11, 2021
;;
;; This file is not part of GNU Emacs.
;;
;; *NB:* Do not edit this file. Instead, edit the original literate file at:
;; ~/other/hamacs/ha-passwords.org
;; And tangle the file to recreate this one.
;;
;;; Code:
#+end_src
* Overlay Redaction
Love [[https://xenodium.com/redact-that-buffer/][this idea]] for using a regular expression to /redact/ (or at least, obscure) sensitive information before screen sharing.
#+begin_src emacs-lisp
(defun toggle-redact-buffer (regexp)
"Redact buffer content matching regexp. A space redacts all."
(interactive (list (read-regexp "Text to Redact (Regexp)" 'regexp-history-last)))
(let* ((redacted)
(matches (let ((results '()))
(when (string-empty-p regexp)
(setq regexp "[[:graph:]]")
(setq regexp-history-last regexp)
(add-to-history 'regexp-history regexp))
(save-excursion
(goto-char (point-min))
(while (re-search-forward regexp nil t)
(push (cons (match-beginning 0) (match-end 0)) results)))
(nreverse results))))
(mapc (lambda (match)
(dolist (overlay (overlays-in (car match) (cdr match)))
(setq redacted t)
(delete-overlay overlay))
(unless redacted
(overlay-put (make-overlay (car match) (cdr match))
'display (make-string (- (cdr match) (car match)) ?x))))
matches)))
#+end_src
Im not sure how often I will use this, so Im not putting it on a keybinding, also so, I will also not put a name-spacing prefix on the function.
* Password Generation
Let's assume that I store a bunch of words in data files:
#+begin_src emacs-lisp
(defvar ha-passwords-data-files (list (expand-file-name "adjectives.txt"
(expand-file-name "data" hamacs-source-dir))
(expand-file-name "colors.txt"
(expand-file-name "data" hamacs-source-dir))
(expand-file-name "nouns.txt"
(expand-file-name "data" hamacs-source-dir)))
"List of file name containing a data lines for our password generator. Order of these files matter.")
(defvar ha-passwords-data nil
"Contains a list of lists of words that we can choose.")
#+end_src
You can see where I'm going with this, can't you? Let's read them into list variables.
#+begin_src emacs-lisp
(defun ha-passwords--read-data-file (filename)
(with-temp-buffer
(insert-file-contents filename)
(split-string (buffer-string) "\n" t)))
#+end_src
Now we get three or so words from our list of lists:
#+begin_src emacs-lisp
(defun ha-passwords-words ()
(unless ha-passwords-data
(setq ha-passwords-data
(--map (ha-passwords--read-data-file it) ha-passwords-data-files)))
(--map (nth (random (length it)) it) ha-passwords-data))
#+end_src
Let's make a password:
#+begin_src emacs-lisp
(defun ha-passwords-generate (&optional separator)
(unless separator
(setq separator "-"))
(let* ((choices '("!" "@" "#" "$" "%" "^" "&" "*"))
(choice (random (length choices)))
(number (1+ choice)))
(->> (ha-passwords-words)
(s-join separator)
(s-capitalize)
(s-append (nth choice choices))
(s-append (number-to-string number)))))
#+end_src
#+begin_src emacs-lisp
(defun generate-password (&optional separator)
(interactive)
(let ((passphrase (ha-passwords-generate separator)))
(kill-new passphrase)
(message "Random password: %s" passphrase)))
#+end_src
* Keybindings
Got make it easy to call:
#+begin_src emacs-lisp
(ha-leader "a g" '("generate passwd" . generate-password))
#+end_src
* Technical Artifacts :noexport:
This will =provide= a code name, so that we can =require= this.
#+begin_src emacs-lisp :exports none
(provide 'ha-passwords)
;;; ha-passwords.el ends here
#+end_src
#+DESCRIPTION: A literate programming version for Emacs code to generate and store passwords.
#+PROPERTY: header-args:sh :tangle no
#+PROPERTY: header-args:emacs-lisp :tangle yes
#+PROPERTY: header-args :results none :eval no-export :comments no mkdirp yes
#+OPTIONS: num:nil toc:nil todo:nil tasks:nil tags:nil date:nil
#+OPTIONS: skip:nil author:nil email:nil creator:nil timestamp:nil
#+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js