[PATCH 1/3] pwclient: Rework HTTP authentication

Stephen Finucane stephen at that.guru
Mon Dec 12 23:02:12 AEDT 2016


On Sat, 2016-12-10 at 02:32 +0100, Thomas Monjalon wrote:
> Transform the HTTP authentication class into a generic transport
> class.
> The credentials become optional so this transport class is always
> used.
> 
> A side effect is to fix the Python 3 support for the authentication.
> Fixes #59
> 
> It will help to bring proxy support while combining http/https and
> authentication cases.
> 
> Signed-off-by: Thomas Monjalon <thomas.monjalon at 6wind.com>

Today I learned that pwclient/XML-RPC only supports alphanumeric
passwords. Once that was resolved, this worked for both me and Sean
(CCd).

Reviewed-by: Stephen Finucane <stephen at that.guru>

> ---
>  patchwork/bin/pwclient | 41 ++++++++++++++------------------------
> ---
>  1 file changed, 14 insertions(+), 27 deletions(-)
> 
> diff --git a/patchwork/bin/pwclient b/patchwork/bin/pwclient
> index 48d7be9..9ec8898 100755
> --- a/patchwork/bin/pwclient
> +++ b/patchwork/bin/pwclient
> @@ -102,31 +102,23 @@ class Filter(object):
>          return str(self.d)
>  
>  
> -class BasicHTTPAuthTransport(xmlrpclib.SafeTransport):
> +class Transport(xmlrpclib.SafeTransport):
>  
> -    def __init__(self, username=None, password=None,
> use_https=False):
> -        self.username = username
> -        self.password = password
> -        self.use_https = use_https
> +    def __init__(self, url):
>          xmlrpclib.SafeTransport.__init__(self)
> +        self.credentials = None
> +        self.https = url.startswith('https')
>  
> -    def authenticated(self):
> -        return self.username is not None and self.password is not
> None
> -
> -    def send_host(self, connection, host):
> -        xmlrpclib.Transport.send_host(self, connection, host)
> -        if not self.authenticated():
> -            return
> -        credentials = '%s:%s' % (self.username, self.password)
> -        auth = 'Basic ' + base64.encodestring(credentials).strip()
> -        connection.putheader('Authorization', auth)
> +    def set_credentials(self, username=None, password=None):
> +        self.credentials = '%s:%s' % (username, password)
>  
>      def make_connection(self, host):
> -        if self.use_https:
> -            fn = xmlrpclib.SafeTransport.make_connection
> +        if self.credentials is not None:

nit: 'if self.credentials' would serve the same purpose here, and
probably be more correct in case a blank string is specified.

> +            host = '@'.join([self.credentials, host])
> +        if self.https:
> +            return xmlrpclib.SafeTransport.make_connection(self,
> host)
>          else:
> -            fn = xmlrpclib.Transport.make_connection
> -        return fn(self, host)
> +            return xmlrpclib.Transport.make_connection(self, host)
>  
>  
>  def project_id_by_name(rpc, linkname):
> @@ -662,18 +654,13 @@ def main():
>  
>      url = config.get(project_str, 'url')
>  
> -    transport = None
> +    transport = Transport(url)
>      if action in auth_actions:
>          if config.has_option(project_str, 'username') and \
>                  config.has_option(project_str, 'password'):
> -
> -            use_https = url.startswith('https')
> -
> -            transport = BasicHTTPAuthTransport(
> +            transport.set_credentials(
>                  config.get(project_str, 'username'),
> -                config.get(project_str, 'password'),
> -                use_https)
> -
> +                config.get(project_str, 'password'))
>          else:
>              sys.stderr.write("The %s action requires authentication,
> but no "
>                               "username or password\nis configured\n"
> % action)



More information about the Patchwork mailing list