[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

scratch/tzz/auth-source-reveal-mode 7e411b7 3/3: Create and document aut

From: Teodor Zlatanov
Subject: scratch/tzz/auth-source-reveal-mode 7e411b7 3/3: Create and document auth-source-reveal-mode
Date: Thu, 18 Jun 2020 14:34:37 -0400 (EDT)

branch: scratch/tzz/auth-source-reveal-mode
commit 7e411b7593571a98a17a1768c124cf2ccccc6f1d
Author: Ted Zlatanov <tzz@lifelogs.com>
Commit: Ted Zlatanov <tzz@lifelogs.com>

    Create and document auth-source-reveal-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.
    * doc/misc/auth.texi (Hiding passwords in text buffers): Document
 doc/misc/auth.texi  |  56 ++++++++++++++++++++++++++-
 lisp/auth-source.el | 106 +++++++++++++++++++++++++++++++++++++---------------
 2 files changed, 130 insertions(+), 32 deletions(-)

diff --git a/doc/misc/auth.texi b/doc/misc/auth.texi
index 61dc62e..30cb6fb 100644
--- a/doc/misc/auth.texi
+++ b/doc/misc/auth.texi
@@ -1,6 +1,6 @@
 \input texinfo                  @c -*-texinfo-*-
-@set VERSION 0.3
+@set VERSION 0.4
 @setfilename ../../info/auth.info
 @settitle Emacs auth-source Library @value{VERSION}
@@ -58,6 +58,7 @@ It is a way for multiple applications to share a single 
 * Overview::                    Overview of the auth-source library.
 * Help for users::
 * Multiple GMail accounts with Gnus::
+* Hiding passwords in text buffers::
 * Secret Service API::
 * The Unix password store::
 * Help for developers::
@@ -280,6 +281,59 @@ machine gmail login account@@gmail.com password "account 
password" port imap
 machine gmail2 login account2@@gmail.com password "account2 password" port imap
 @end example
+@node Hiding passwords in text buffers
+@chapter Hiding passwords in text buffers
+Emacs users and developers have to look at netrc files in text or JSON
+formats sometimes. Pro Tip: one easy way to protect from
+password-shoulder-surfers is to enter a hair band, grow long hair,
+curl it daily until it creates a visual barrier, become famous, keep
+using Emacs.
+An alternative is to enable @code{auth-source-reveal-mode} as follows:
+(require 'auth-source)
+(setq prettify-symbols-unprettify-at-point 'right-edge) ;; or customize it
+(add-hook 'prog-mode-hook 'turn-on-auth-source-reveal-mode)
+(add-hook 'text-mode-hook 'turn-on-auth-source-reveal-mode)
+(add-hook 'json-mode-hook 'turn-on-auth-source-reveal-mode)
+;; or if you prefer use-package...
+(use-package auth-source
+  :custom
+  (prettify-symbols-unprettify-at-point 'right-edge)
+  :hook
+  (prog-mode . auth-source-reveal-mode)
+  (json-mode . auth-source-reveal-mode)
+  (text-mode . auth-source-reveal-mode))
+@end example
+You should definitely customize
+@code{prettify-symbols-unprettify-at-point} to be t or
+@code{right-edge}. If it's nil (the default), the password will not be
+revealed when you're inside it, which will annoy you AND
+You can further customize the following.
+@defvar auth-source-reveal-regex
+A 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''.
+Use only non-capturing parens inside this regular expression.
+@end defvar
+@defvar auth-source-reveal-json-modes
+This 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.
+@end defvar
+@itemize @bullet
+@item How does it work?
+Underneath, @code{prettify-symbols-mode} is used to hide passwords based on a 
regular expression for netrc plain text or JSON files.
+@item Why does it depend on prettify-symbols-mode?
+Eventually it won't. For now it does.
+@end itemize
 @node Secret Service API
 @chapter Secret Service API
diff --git a/lisp/auth-source.el b/lisp/auth-source.el
index 7a0e09b..76e9c87 100644
--- a/lisp/auth-source.el
+++ b/lisp/auth-source.el
@@ -44,6 +44,7 @@
 (require 'cl-lib)
 (require 'eieio)
+(require 'prog-mode)
 (autoload 'secrets-create-item "secrets")
 (autoload 'secrets-delete-item "secrets")
@@ -2405,44 +2406,87 @@ MODE can be \"login\" or \"password\"."
       (setq password (funcall password)))
     (list user password auth-info)))
-;;; Tiny mode for editing .netrc/.authinfo modes (that basically just
-;;; hides passwords).
+;;; Tiny minor mode for editing .netrc/.authinfo modes (that basically
+;;; just hides passwords).
-(defcustom authinfo-hidden "password"
-  "Regexp matching elements in .authinfo/.netrc files that should be hidden."
+(defcustom auth-source-reveal-regex "password"
+  "Regexp matching tokens or JSON keys in .authinfo/.netrc/JSON files.
+The text following the tokens or under the JSON keys will be hidden."
   :type 'regexp
   :version "27.1")
-(define-derived-mode authinfo-mode fundamental-mode "Authinfo"
-  "Mode for editing .authinfo/.netrc files.
+(defcustom auth-source-reveal-json-modes '(json-mode js-mode js2-mode 
+  "List of symbols for modes that should use JSON parsing logic."
+  :type 'list
+  :version "27.1")
-This is just like `fundamental-mode', but hides passwords.  The
-passwords are revealed when point moved into the password.
+(defcustom auth-source-reveal-hider '(?* (base-right . base-left) ?© 
(base-right . base-left) ?© (base-right . base-left) ?*)
+  "A character or a composition list to hide passwords.
+In the composition list form, you can use the format
+(?h (base-right . base-left) ?i (base-right . base-left) ?d (base-right . 
base-left) ?e)
+to show the string \"hide\" (by aligning character left/right baselines).
-  (authinfo--hide-passwords (point-min) (point-max))
-  (reveal-mode))
+Other composition keywords you can use: top-left/tl,
+top-center/tc, top-right/tr, base-left/Bl, base-center/Bc,
+base-right/Br, bottom-left/bl, bottom-center/bc, bottom-right/br,
+center-left/cl, center-center/cc, center-right/cr."
+  :type '(choice
+          (const :tag "A single copyright sign" ?©)
+          (character :tag "Any character")
+          (sexp :tag "A composition list"))
+  :version "27.1")
-(defun authinfo--hide-passwords (start end)
-  (save-excursion
-    (save-restriction
-      (narrow-to-region start end)
-      (goto-char start)
-      (while (re-search-forward (format "\\(\\s-\\|^\\)\\(%s\\)\\s-+"
-                                        authinfo-hidden)
-                                nil t)
-        (when (auth-source-netrc-looking-at-token)
-          (let ((overlay (make-overlay (match-beginning 0) (match-end 0))))
-            (overlay-put overlay 'display (propertize "****"
-                                                      'face 'warning))
-            (overlay-put overlay 'reveal-toggle-invisible
-                         #'authinfo--toggle-display)))))))
-(defun authinfo--toggle-display (overlay hide)
-  (if hide
-      (overlay-put overlay 'display (propertize "****" 'face 'warning))
-    (overlay-put overlay 'display nil)))
+(defun auth-source-reveal-compose-p (start end _match)
+  "Return true iff the symbol MATCH should be composed.
+The symbol starts at position START and ends at position END.
+This overrides the default for `prettify-symbols-compose-predicate'."
+  ;; Check that the chars should really be composed into a symbol.
+  t)
+(define-minor-mode auth-source-reveal-mode
+  "Toggle password hiding for auth-source files using `prettify-symbols-mode'.
+If called interactively, enable auth-source-reveal mode if ARG is
+positive, and disable it if ARG is zero or negative.  If called
+from Lisp, also enable the mode if ARG is omitted or nil, and
+toggle it if ARG is toggle; disable the mode otherwise.
+When auth-source-reveal mode is enabled, passwords will be
+hidden. To reveal them when point is inside them, see
+See `auth-source-password-hide-regex' for the regex matching the
+tokens and keys associated with passwords."
+  ;; The initial value.
+  :init-value nil
+  ;; The indicator for the mode line.
+  :lighter " asr"
+  :group 'auth-source
+  (when auth-source-reveal-mode
+    ;; Install the prettification magic.
+    (prettify-symbols-add-prettification-rx
+     'auth-source-reveal-mode-prettify-regexp ; The identifier symbol.
+     ;; regexp to hide/reveal
+     (if (apply #'derived-mode-p auth-source-reveal-json-modes)
+         (format "\"?password\"?[:[:blank:]]+\"\\([^\t\r\n\"]+\\)\"" 
+       (format "\\b%s\\b\\s-+\\([^ \t\r\n]+\\)" auth-source-reveal-regex))
+     auth-source-reveal-hider)
+    (setq-local
+     prettify-symbols-compose-predicate #'auth-source-reveal-compose-p)
+    (unless prettify-symbols-unprettify-at-point
+      (auth-source-do-warn
+       "Please set `%s' to _see_ passwords at point"
+       'prettify-symbols-unprettify-at-point)))
+  (prettify-symbols-mode (if auth-source-reveal-mode 1 -1)))
+(defun turn-on-auth-source-reveal-mode ()
+  (when (and (not auth-source-reveal-mode)
+             (local-variable-p 'prettify-symbols-alist))
+    (auth-source-reveal-mode 1)))
 (provide 'auth-source)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]