aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTed Zlatanov2020-06-23 18:19:32 -0400
committerTed Zlatanov2020-07-12 16:44:10 -0400
commitda5b4b6d0856501a163217529c2db2f891e284c0 (patch)
tree9690b6c43bce85a46b01c3769fc2558a7fa923f0
parent0256303f24b1fc193f1d6c1861abf81fd5ee374a (diff)
downloademacs-scratch/tzz/prettify-text-mode.tar.gz
emacs-scratch/tzz/prettify-text-mode.zip
Create and document auth-source-reveal-modescratch/tzz/prettify-text-mode
* lisp/auth-source.el (auth-source-reveal-mode): Add new minor mode to hide passwords. Remove authinfo-mode which provided a major mode for the same purpose before. Use the text-coverup API. * doc/misc/auth.texi (Hiding passwords in text buffers): Document auth-source-reveal-mode.
-rw-r--r--doc/misc/auth.texi45
-rw-r--r--lisp/auth-source.el110
2 files changed, 123 insertions, 32 deletions
diff --git a/doc/misc/auth.texi b/doc/misc/auth.texi
index 61dc62e7711..fc98b773432 100644
--- a/doc/misc/auth.texi
+++ b/doc/misc/auth.texi
@@ -1,6 +1,6 @@
1\input texinfo @c -*-texinfo-*- 1\input texinfo @c -*-texinfo-*-
2 2
3@set VERSION 0.3 3@set VERSION 0.4
4 4
5@setfilename ../../info/auth.info 5@setfilename ../../info/auth.info
6@settitle Emacs auth-source Library @value{VERSION} 6@settitle Emacs auth-source Library @value{VERSION}
@@ -58,6 +58,7 @@ It is a way for multiple applications to share a single configuration
58* Overview:: Overview of the auth-source library. 58* Overview:: Overview of the auth-source library.
59* Help for users:: 59* Help for users::
60* Multiple GMail accounts with Gnus:: 60* Multiple GMail accounts with Gnus::
61* Hiding passwords in text buffers::
61* Secret Service API:: 62* Secret Service API::
62* The Unix password store:: 63* The Unix password store::
63* Help for developers:: 64* Help for developers::
@@ -280,6 +281,48 @@ machine gmail login account@@gmail.com password "account password" port imap
280machine gmail2 login account2@@gmail.com password "account2 password" port imap 281machine gmail2 login account2@@gmail.com password "account2 password" port imap
281@end example 282@end example
282 283
284@node Hiding passwords in text buffers
285@chapter Hiding passwords in text buffers
286
287Emacs users and developers have to look at netrc files in text or JSON
288formats sometimes. Pro Tip: one easy way to protect from
289password-shoulder-surfers is to enter a hair band, grow long hair,
290curl it daily until it creates a visual barrier, become famous, keep
291using Emacs.
292
293An alternative is to enable @code{auth-source-reveal-mode} as follows:
294
295@example
296(require 'auth-source)
297(setq prettify-symbols-unprettify-at-point 'right-edge) ;; or customize it
298
299(add-hook 'prog-mode-hook 'turn-on-auth-source-reveal-mode)
300(add-hook 'text-mode-hook 'turn-on-auth-source-reveal-mode)
301(add-hook 'json-mode-hook 'turn-on-auth-source-reveal-mode)
302@end example
303
304Underneath, the @code{prettify-text} API is used to hide passwords
305based on a regular expression for netrc plain text or JSON files.
306
307You should definitely customize
308@code{prettify-text-unprettify-at-point} to be t or
309@code{right-edge}. If it's nil (the default), the password will not be
310revealed when you're inside it, which will annoy you AND
311password-shoulder-surfers. Note this is different from
312@code{prettify-symbols-unprettify-at-point} which only governs
313@code{prettify-symbols-mode} behavior.
314
315You can further customize the following.
316@defvar auth-source-reveal-regex
317A regular expression matching the text preceding the password (or, in JSON format, the key under which the password lives). By default it will be just ``password'' which also matches e.g. ``my_password''.
318
319Use only non-capturing parens inside this regular expression.
320@end defvar
321
322@defvar auth-source-reveal-json-modes
323This is a list of modes where the JSON regular expression logic should be installed, instead of the plaintext logic. By default this includes @code{json-mode} for instance.
324@end defvar
325
283@node Secret Service API 326@node Secret Service API
284@chapter Secret Service API 327@chapter Secret Service API
285 328
diff --git a/lisp/auth-source.el b/lisp/auth-source.el
index 7a0e09b9e8e..2892cc09925 100644
--- a/lisp/auth-source.el
+++ b/lisp/auth-source.el
@@ -44,6 +44,7 @@
44 44
45(require 'cl-lib) 45(require 'cl-lib)
46(require 'eieio) 46(require 'eieio)
47(require 'prog-mode)
47 48
48(autoload 'secrets-create-item "secrets") 49(autoload 'secrets-create-item "secrets")
49(autoload 'secrets-delete-item "secrets") 50(autoload 'secrets-delete-item "secrets")
@@ -2405,44 +2406,91 @@ MODE can be \"login\" or \"password\"."
2405 (setq password (funcall password))) 2406 (setq password (funcall password)))
2406 (list user password auth-info))) 2407 (list user password auth-info)))
2407 2408
2408;;; Tiny mode for editing .netrc/.authinfo modes (that basically just 2409;;; Tiny minor mode for editing .netrc/.authinfo modes (that basically
2409;;; hides passwords). 2410;;; just hides passwords).
2410 2411
2411(defcustom authinfo-hidden "password" 2412(defcustom auth-source-reveal-regex "password"
2412 "Regexp matching elements in .authinfo/.netrc files that should be hidden." 2413 "Regexp matching tokens or JSON keys in .authinfo/.netrc/JSON files.
2414The text following the tokens or under the JSON keys will be hidden."
2413 :type 'regexp 2415 :type 'regexp
2414 :version "27.1") 2416 :version "27.1")
2415 2417
2416;;;###autoload 2418(defcustom auth-source-reveal-json-modes '(json-mode js-mode js2-mode rjsx-mode)
2417(define-derived-mode authinfo-mode fundamental-mode "Authinfo" 2419 "List of symbols for modes that should use JSON parsing logic."
2418 "Mode for editing .authinfo/.netrc files. 2420 :type 'list
2421 :version "27.1")
2419 2422
2420This is just like `fundamental-mode', but hides passwords. The 2423(defcustom auth-source-reveal-hider '(?* (base-right . base-left) ?© (base-right . base-left) ?© (base-right . base-left) ?*)
2421passwords are revealed when point moved into the password. 2424 "A character or a composition list to hide passwords.
2425In the composition list form, you can use the format
2426(?h (base-right . base-left) ?i (base-right . base-left) ?d (base-right . base-left) ?e)
2427to show the string \"hide\" (by aligning character left/right baselines).
2422 2428
2423\\{authinfo-mode-map}" 2429Other composition keywords you can use: top-left/tl,
2424 (authinfo--hide-passwords (point-min) (point-max)) 2430top-center/tc, top-right/tr, base-left/Bl, base-center/Bc,
2425 (reveal-mode)) 2431base-right/Br, bottom-left/bl, bottom-center/bc, bottom-right/br,
2432center-left/cl, center-center/cc, center-right/cr."
2433 :type '(choice
2434 (const :tag "A single copyright sign" ?©)
2435 (character :tag "Any character")
2436 (sexp :tag "A composition list"))
2437 :version "27.1")
2426 2438
2427(defun authinfo--hide-passwords (start end) 2439(defun auth-source-reveal-compose-p (start end _outer_match _true_match)
2428 (save-excursion 2440 "Return true iff the text between START and END should be composed.
2429 (save-restriction 2441All arguments are currently ignored, always returning t for
2430 (narrow-to-region start end) 2442`auth-source-reveal-mode'. This overrides the default for
2431 (goto-char start) 2443`text-coverup-compose-predicate'."
2432 (while (re-search-forward (format "\\(\\s-\\|^\\)\\(%s\\)\\s-+" 2444 ;; Check that the chars should really be composed into a symbol.
2433 authinfo-hidden) 2445 t)
2434 nil t) 2446
2435 (when (auth-source-netrc-looking-at-token) 2447;;;###autoload
2436 (let ((overlay (make-overlay (match-beginning 0) (match-end 0)))) 2448(define-minor-mode auth-source-reveal-mode
2437 (overlay-put overlay 'display (propertize "****" 2449 "Toggle password hiding for auth-source files using `text-coverup-mode'.
2438 'face 'warning)) 2450
2439 (overlay-put overlay 'reveal-toggle-invisible 2451If called interactively, enable auth-source-reveal mode if ARG is
2440 #'authinfo--toggle-display))))))) 2452positive, and disable it if ARG is zero or negative. If called
2441 2453from Lisp, also enable the mode if ARG is omitted or nil, and
2442(defun authinfo--toggle-display (overlay hide) 2454toggle it if ARG is toggle; disable the mode otherwise.
2443 (if hide 2455
2444 (overlay-put overlay 'display (propertize "****" 'face 'warning)) 2456When auth-source-reveal mode is enabled, passwords will be
2445 (overlay-put overlay 'display nil))) 2457hidden. To reveal them when point is inside them, see
2458`text-coverup-uncover-at-point'.
2459
2460See `auth-source-password-hide-regex' for the regex matching the
2461tokens and keys associated with passwords."
2462 ;; The initial value.
2463 :init-value nil
2464 ;; The indicator for the mode line.
2465 :lighter " asr"
2466 :group 'auth-source
2467
2468 (let ((identifier 'auth-source-reveal-regexp)) ; The identifier symbol.
2469 (if auth-source-reveal-mode
2470 ;; Install the coverup magic.
2471 (when (text-coverup-add-coverup
2472 identifier
2473 ;; The regexp to hide/reveal.
2474 (if (apply #'derived-mode-p auth-source-reveal-json-modes)
2475 (format "\"?password\"?[:[:blank:]]+\"\\([^\t\r\n\"]+\\)\""
2476 auth-source-reveal-regex)
2477 (format "\\b%s\\b\\s-+\\([^ \t\r\n]+\\)"
2478 auth-source-reveal-regex))
2479 ;; The replacement symbol or composed string.
2480 auth-source-reveal-hider
2481 ;; A custom compose matcher.
2482 #'auth-source-reveal-compose-p)
2483 (unless text-coverup-uncover-at-point
2484 (auth-source-do-warn
2485 "Please set `%s' to _see_ passwords at point"
2486 'text-coverup-uncover-at-point)))
2487 ;; Else, when disabling, remove the coverups for our identifier.
2488 (text-coverup-remove-coverups identifier))))
2489
2490;;;###autoload
2491(defun turn-on-auth-source-reveal-mode ()
2492 (when (not auth-source-reveal-mode)
2493 (auth-source-reveal-mode 1)))
2446 2494
2447(provide 'auth-source) 2495(provide 'auth-source)
2448 2496