Patchwork [5,of,6] tests: enable HTTP digest testing

login
register
mail settings
Submitter Matt Harbison
Date Feb. 6, 2019, 2:35 a.m.
Message ID <766e1b887a85c352e103.1549420548@Envy>
Download mbox | patch
Permalink /patch/38472/
State Accepted
Headers show

Comments

Matt Harbison - Feb. 6, 2019, 2:35 a.m.
# HG changeset patch
# User Matt Harbison <matt_harbison@yahoo.com>
# Date 1549403239 18000
#      Tue Feb 05 16:47:19 2019 -0500
# Node ID 766e1b887a85c352e10381e30f3caaae320483e2
# Parent  1a4bd7696b7e12673ddc46733babd15151f00e05
tests: enable HTTP digest testing

I suppose we could spin the client side extension off to a *.py file if it gets
more use.  I was basically just looking to avoid killing the server and
relaunching it just to change authentication schemes, because that doesn't
always work on Windows.

The test changes capture the problem with py3.
Yuya Nishihara - Feb. 6, 2019, 12:33 p.m.
On Tue, 05 Feb 2019 21:35:48 -0500, Matt Harbison wrote:
> # HG changeset patch
> # User Matt Harbison <matt_harbison@yahoo.com>
> # Date 1549403239 18000
> #      Tue Feb 05 16:47:19 2019 -0500
> # Node ID 766e1b887a85c352e10381e30f3caaae320483e2
> # Parent  1a4bd7696b7e12673ddc46733babd15151f00e05
> tests: enable HTTP digest testing

Queued the series, thanks.

>  def perform_authentication(hgweb, req, op):
>      auth = req.headers.get(b'Authorization')
> +
> +    if req.headers.get(b'X-HgTest-AuthType') == b'Digest':
> +        global digest

>  def extsetup(ui):
>      common.permhooks.insert(0, perform_authentication)
> +
> +    global digest

Nit: these global aren't needed. removed in flight.

Patch

diff --git a/tests/httpserverauth.py b/tests/httpserverauth.py
--- a/tests/httpserverauth.py
+++ b/tests/httpserverauth.py
@@ -85,8 +85,24 @@  class digestauthserver(object):
 
         return True
 
+digest = digestauthserver()
+
 def perform_authentication(hgweb, req, op):
     auth = req.headers.get(b'Authorization')
+
+    if req.headers.get(b'X-HgTest-AuthType') == b'Digest':
+        global digest
+
+        if not auth:
+            challenge = digest.makechallenge(b'mercurial')
+            raise common.ErrorResponse(common.HTTP_UNAUTHORIZED, b'who',
+                    [(b'WWW-Authenticate', b'Digest %s' % challenge)])
+
+        if not digest.checkauth(req, auth[7:]):
+            raise common.ErrorResponse(common.HTTP_FORBIDDEN, b'no')
+
+        return
+
     if not auth:
         raise common.ErrorResponse(common.HTTP_UNAUTHORIZED, b'who',
                 [(b'WWW-Authenticate', b'Basic Realm="mercurial"')])
@@ -96,3 +112,6 @@  def perform_authentication(hgweb, req, o
 
 def extsetup(ui):
     common.permhooks.insert(0, perform_authentication)
+
+    global digest
+    digest.adduser(b'user', b'pass', b'mercurial')
diff --git a/tests/test-http.t b/tests/test-http.t
--- a/tests/test-http.t
+++ b/tests/test-http.t
@@ -173,7 +173,7 @@  test http authentication
   $ cd test
 
   $ hg serve --config extensions.x=$TESTDIR/httpserverauth.py -p $HGPORT2 -d \
-  >    --pid-file=pid --config server.preferuncompressed=True \
+  >    --pid-file=pid --config server.preferuncompressed=True -E ../errors2.log \
   >    --config web.push_ssl=False --config web.allow_push=* -A ../access.log
   $ cat pid >> $DAEMON_PIDS
 
@@ -209,6 +209,26 @@  test http authentication
   $ hg id http://user@localhost:$HGPORT2/
   5fed3813f7f5
 
+  $ cat > use_digests.py << EOF
+  > from mercurial import (
+  >     exthelper,
+  >     url,
+  > )
+  > 
+  > eh = exthelper.exthelper()
+  > uisetup = eh.finaluisetup
+  > 
+  > @eh.wrapfunction(url, 'opener')
+  > def urlopener(orig, *args, **kwargs):
+  >     opener = orig(*args, **kwargs)
+  >     opener.addheaders.append((r'X-HgTest-AuthType', r'Digest'))
+  >     return opener
+  > EOF
+
+  $ hg id http://localhost:$HGPORT2/ --config extensions.x=use_digests.py || true
+  abort: HTTP Error 403: bad user (py3 !)
+  5fed3813f7f5 (no-py3 !)
+
 #if no-reposimplestore
   $ hg clone http://user:pass@localhost:$HGPORT2/ dest 2>&1
   streaming all changes
@@ -362,6 +382,15 @@  test http authentication
   "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
   "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
   "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
+  "GET /?cmd=capabilities HTTP/1.1" 401 - x-hgtest-authtype:Digest
+  "GET /?cmd=capabilities HTTP/1.1" 403 - x-hgtest-authtype:Digest (py3 !)
+  "GET /?cmd=capabilities HTTP/1.1" 200 - x-hgtest-authtype:Digest (no-py3 !)
+  "GET /?cmd=lookup HTTP/1.1" 401 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (no-py3 !)
+  "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (no-py3 !)
+  "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (no-py3 !)
+  "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (no-py3 !)
+  "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (no-py3 !)
+  "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (no-py3 !)
   "GET /?cmd=capabilities HTTP/1.1" 401 - (no-reposimplestore !)
   "GET /?cmd=capabilities HTTP/1.1" 200 - (no-reposimplestore !)
   "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (no-reposimplestore !)
@@ -431,6 +460,9 @@  check error log
 
   $ cat error.log
 
+  $ cat errors2.log
+  $LOCALIP - - [$ERRDATE$] HG error:  No hash found for user/realm "b'user'/mercurial" (glob) (py3 !)
+
 check abort error reporting while pulling/cloning
 
   $ $RUNTESTDIR/killdaemons.py