Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does emacs url package handle authentication?

Tags:

url

emacs

elisp

I have not seen a really good example on the web. How can I add authentication to a request like this:

(defun login-show-posts ()
  (interactive)
  (let ((url-request-method "GET")
        (url-request-extra-headers '(("Content-Type" . "application/xml"))))
    (url-retrieve "http://localhost:3000/essay/1.xml" 
    (lambda (status)
                    (switch-to-buffer (current-buffer))
                    ))))

if for example, the user and pass is admin:admin?

like image 700
wallyqs Avatar asked Dec 29 '22 13:12

wallyqs


2 Answers

I got the impression that url.el was designed mostly for interactive operations, i.e. you do a call without authorisation, the server responds with a 403 "authorization needed" (correct code?) status and url.el will query the user for user name and password.

You can have a look at my code on http://github.com/hdurer/fluiddb.el where I try to do things programmatically.

Basically, I create the HTTP authorzation header myself (base64 encoding the correctly formatted string and adding the correct header to url-request-extra-headers). Then in a second step I need to add advice to url-http-handle-authentication so that it won't ask the user should the passed credentials not be acceptable.

This feels a lot like raping url.el but it works for me and is the only way I could make it work.


Your code would thus look something like this:

 (defvar xyz-user-name "admin")
 (defvar xyz-password "admin")

 (defvar xyz-block-authorisation nil 
   "Flag whether to block url.el's usual interactive authorisation procedure")

 (defadvice url-http-handle-authentication (around xyz-fix)
   (unless xyz-block-authorisation
       ad-do-it))
 (ad-activate 'url-http-handle-authentication)


 (defun login-show-posts ()
   (interactive)
   (let ((xyz-block-authorisation t)
         (url-request-method "GET")
         (url-request-extra-headers 
          `(("Content-Type" . "application/xml")
            ("Authorization" . ,(concat "Basic "
                                        (base64-encode-string
                                         (concat xyz-user-name ":" xyz-password)))))))
     (url-retrieve "http://localhost:3000/essay/1.xml" 
                   (lambda (status)
                     (switch-to-buffer (current-buffer))
                     ))))
like image 55
HD. Avatar answered Jan 01 '23 02:01

HD.


With twit.el, there was a little farting around to make it work. Authentication info is stored inside of an alist. This a list is bound to the symbol in the variable url-basic-auth-storage.

ELISP> (require 'url)
ELISP> (pp url-basic-auth-storage)
url-http-real-basic-auth-storage

ELISP> (pp (symbol-value url-basic-auth-storage))
(("twitter.com:443"  ("Twitter API" . "@uTh5tr!n6==")) 
 ("twitter.com:80"  ("Twitter API" . "AnotherAuthString==")))
ELISP> 

You could probably do something like this:

(let ((my-temporary-auth '(("host.com:80" ("Auth Realm" . "@uTH5r!n6==")))))
      (url-basic-auth-storage 'my-temporary-auth))
   (do-gunk))

This will leave the users authentication info alone (if they have any). Upon retrospect that might have been the smarter way to go with twit.el.

like image 38
Jonathan Arkell Avatar answered Jan 01 '23 03:01

Jonathan Arkell