Function: auth-source-plstore-search

auth-source-plstore-search is a byte-compiled function defined in auth-source.el.gz.

Signature

(auth-source-plstore-search &rest SPEC &key BACKEND CREATE DELETE MAX &allow-other-keys)

Documentation

Search the PLSTORE; SPEC is like auth-source.

Source Code

;; Defined in /usr/src/emacs/lisp/auth-source.el.gz
;;; Backend specific parsing: PLSTORE backend

(cl-defun auth-source-plstore-search (&rest spec
                                      &key backend create delete max
                                      &allow-other-keys)
  "Search the PLSTORE; SPEC is like `auth-source'."
  (let* ((store (oref backend data))
         (max (or max 5000))     ; sanity check: default to stop at 5K
         (ignored-keys '(:create :delete :max :backend :label :require :type))
         (search-keys (cl-loop for i below (length spec) by 2
                               unless (memq (nth i spec) ignored-keys)
                               collect (nth i spec)))
         ;; build a search spec without the ignored keys
         ;; if a search key is nil or t (match anything), we skip it
         (search-spec (apply #'append (mapcar
                                      (lambda (k)
                                        (let ((v (plist-get spec k)))
                                          (if (or (null v)
                                                  (eq t v))
                                              nil
                                            (list
                                             k
                                             (auth-source-ensure-strings v)))))
                                      search-keys)))
         ;; needed keys (always including host, login, port, and secret)
         (returned-keys (delete-dups (append
				      '(:host :login :port :secret)
				      search-keys)))
         (items (plstore-find store search-spec))
         (item-names (mapcar #'car items))
         (items (take max items))
         ;; convert the item to a full plist
         (items (mapcar (lambda (item)
                          (let* ((plist (copy-tree (cdr item)))
                                 (secret (plist-member plist :secret)))
                            (if secret
                                (setcar
                                 (cdr secret)
                                 (let ((v (car (cdr secret))))
                                   (if (functionp v)
                                       (lambda () (funcall v plist))
                                   (lambda () v)))))
                            plist))
                        items))
         ;; ensure each item has each key in `returned-keys'
         (items (mapcar (lambda (plist)
                          (append
                           (apply #'append
                                  (mapcar (lambda (req)
                                            (if (plist-get plist req)
                                                nil
                                              (list req nil)))
                                          returned-keys))
                           plist))
                        items)))
    (cond
     ;; if we need to create an entry AND none were found to match
     ((and create
           (not items))

      ;; create based on the spec and record the value
      (setq items (or
                   ;; if the user did not want to create the entry
                   ;; in the file, it will be returned
                   (apply (slot-value backend 'create-function) spec)
                   ;; if not, we do the search again without :create
                   ;; to get the updated data.

                   ;; the result will be returned, even if the search fails
                   (apply #'auth-source-plstore-search
                          (plist-put spec :create nil)))))
     ((and delete
           item-names)
      (dolist (item-name item-names)
        (plstore-delete store item-name))
      (plstore-save store)))
    items))