Function: auth-source-secrets-search

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

Signature

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

Documentation

Search the Secrets API; spec is like auth-source.

The :label key specifies the item's label. It is the only key that can specify a substring. Any :label value besides a string will allow any label.

All other search keys must match exactly. If you need substring matching, do a wider search and narrow it down yourself.

You'll get back all the properties of the token as a plist.

Here's an example that looks for the first item in the Login Secrets collection:

 (let ((auth-sources '("secrets:Login")))
    (auth-source-search :max 1))

Here's another that looks for the first item in the Login Secrets collection whose label contains gnus:

 (let ((auth-sources '("secrets:Login")))
    (auth-source-search :max 1 :label "gnus"))

And this one looks for the first item in the Login Secrets collection that's a Google Chrome entry for the git.gnus.org site authentication tokens:

 (let ((auth-sources '("secrets:Login")))
    (auth-source-search :max 1 :signon_realm "https://git.gnus.org/Git"))

Source Code

;; Defined in /usr/src/emacs/lisp/auth-source.el.gz
(cl-defun auth-source-secrets-search (&rest spec
                                      &key backend create delete label max
                                      &allow-other-keys)
  "Search the Secrets API; spec is like `auth-source'.

The :label key specifies the item's label.  It is the only key
that can specify a substring.  Any :label value besides a string
will allow any label.

All other search keys must match exactly.  If you need substring
matching, do a wider search and narrow it down yourself.

You'll get back all the properties of the token as a plist.

Here's an example that looks for the first item in the `Login'
Secrets collection:

 (let ((auth-sources \\='(\"secrets:Login\")))
    (auth-source-search :max 1))

Here's another that looks for the first item in the `Login'
Secrets collection whose label contains `gnus':

 (let ((auth-sources \\='(\"secrets:Login\")))
    (auth-source-search :max 1 :label \"gnus\"))

And this one looks for the first item in the `Login' Secrets
collection that's a Google Chrome entry for the git.gnus.org site
authentication tokens:

 (let ((auth-sources \\='(\"secrets:Login\")))
    (auth-source-search :max 1 :signon_realm \"https://git.gnus.org/Git\"))"

  ;; TODO
  ;; (secrets-delete-item coll elt)
  (cl-assert (not delete) nil
             "The Secrets API auth-source backend doesn't support deletion yet")

  (let* ((coll (oref backend source))
         (max (or max 5000))     ; sanity check: default to stop at 5K
         (items
          (cl-loop
           for search-spec in
           (auth-source-secrets-listify-pattern (auth-source-search-spec spec))
           nconc
           (cl-loop for item in (apply #'secrets-search-items coll search-spec)
                    unless (and (stringp label)
                                (not (string-match label item)))
                    collect item)))
         ;; TODO: respect max in `secrets-search-items', not after the fact
         (items (take max items))
         ;; convert the item name to a full plist
         (items (mapcar (lambda (item)
                          (append
                           ;; make an entry for the secret (password) element
                           (list
                            :secret
                            (let ((v (secrets-get-secret coll item)))
                              (lambda () v)))
                           ;; rewrite the entry from ((k1 v1) (k2 v2)) to plist
                           (apply #'append
                                  (mapcar (lambda (entry)
                                            (list (car entry) (cdr entry)))
                                          (secrets-get-attributes coll item)))))
                        items))
         ;; Ensure each item has each key in `auth-source-returned-keys'.
         (items (mapcar (lambda (plist)
                          (append
                           (apply #'append
                                  (mapcar (lambda (req)
                                            (if (plist-get plist req)
                                                nil
                                              (list req nil)))
                                          (auth-source-returned-keys spec)))
                           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-secrets-search
                          (plist-put spec :create nil))))))
    items))