Patchwork [2,of,2,STABLE] url: do not continue HTTP authentication with user=None (issue6425)

login
register
mail settings
Submitter Yuya Nishihara
Date Oct. 23, 2020, 12:17 p.m.
Message ID <be11c752c0fe3c4755f2.1603455433@mimosa>
Download mbox | patch
Permalink /patch/47514/
State New
Headers show

Comments

Yuya Nishihara - Oct. 23, 2020, 12:17 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1603452816 -32400
#      Fri Oct 23 20:33:36 2020 +0900
# Branch stable
# Node ID be11c752c0fe3c4755f2567a302123bda3e236af
# Parent  15e5d72561363a7e83ea9a7c70d85db760bc57e8
url: do not continue HTTP authentication with user=None (issue6425)

I initially thought this is a py3-compat bug of passwordmgr._writedebug(),
but actually returning (None, str) pair is wrong at all. HTTP authentication
would continue with user="None" in that case.

Since registering a password of user=None should also be wrong, this patch
simply adds early return.

Patch

diff --git a/mercurial/url.py b/mercurial/url.py
--- a/mercurial/url.py
+++ b/mercurial/url.py
@@ -96,6 +96,13 @@  class passwordmgr(object):
             if not passwd:
                 passwd = self.ui.getpass()
 
+        # As of Python 3.8, the default implementation of
+        # AbstractBasicAuthHandler.retry_http_basic_auth() assumes the user
+        # is set if pw is not None. This means (None, str) is not a valid
+        # return type of find_user_password().
+        if user is None:
+            return None, None
+
         self.passwddb.add_password(realm, authuri, user, passwd)
         self._writedebug(user, passwd)
         return (pycompat.strurl(user), pycompat.strurl(passwd))
diff --git a/tests/test-http.t b/tests/test-http.t
--- a/tests/test-http.t
+++ b/tests/test-http.t
@@ -192,6 +192,34 @@  test http authentication
   $ hg id http://localhost:$HGPORT2/
   abort: http authorization required for http://localhost:$HGPORT2/
   [255]
+  $ hg id --config ui.interactive=true --debug http://localhost:$HGPORT2/
+  using http://localhost:$HGPORT2/
+  sending capabilities command
+  http authorization required for http://localhost:$HGPORT2/
+  realm: mercurial
+  user: abort: response expected
+  [255]
+  $ cat <<'EOF' | hg id --config ui.interactive=true --config ui.nontty=true --debug http://localhost:$HGPORT2/
+  > 
+  > EOF
+  using http://localhost:$HGPORT2/
+  sending capabilities command
+  http authorization required for http://localhost:$HGPORT2/
+  realm: mercurial
+  user: 
+  password: abort: response expected
+  [255]
+  $ cat <<'EOF' | hg id --config ui.interactive=true --config ui.nontty=true --debug http://localhost:$HGPORT2/
+  > 
+  > 
+  > EOF
+  using http://localhost:$HGPORT2/
+  sending capabilities command
+  http authorization required for http://localhost:$HGPORT2/
+  realm: mercurial
+  user: 
+  password: abort: authorization failed
+  [255]
   $ hg id --config ui.interactive=true --config extensions.getpass=get_pass.py http://user@localhost:$HGPORT2/
   http authorization required for http://localhost:$HGPORT2/
   realm: mercurial
@@ -360,6 +388,9 @@  test http authentication
   "GET /?cmd=capabilities HTTP/1.1" 401 -
   "GET /?cmd=capabilities HTTP/1.1" 401 -
   "GET /?cmd=capabilities HTTP/1.1" 401 -
+  "GET /?cmd=capabilities HTTP/1.1" 401 -
+  "GET /?cmd=capabilities HTTP/1.1" 401 -
+  "GET /?cmd=capabilities HTTP/1.1" 401 -
   "GET /?cmd=capabilities HTTP/1.1" 200 -
   "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