[Notes] [Git][BuildStream/buildstream][valentindavid/netrc] Add support for .netrc in remote/tar/zip plugins



Title: GitLab

Valentin David pushed to branch valentindavid/netrc at BuildStream / buildstream

Commits:

1 changed file:

Changes:

  • buildstream/plugins/sources/_downloadablefilesource.py
    ... ... @@ -5,11 +5,95 @@ import urllib.request
    5 5
     import urllib.error
    
    6 6
     import contextlib
    
    7 7
     import shutil
    
    8
    +import netrc
    
    8 9
     
    
    9 10
     from buildstream import Source, SourceError, Consistency
    
    10 11
     from buildstream import utils
    
    11 12
     
    
    12 13
     
    
    14
    +class NetrcFTPOpener(urllib.request.FTPHandler):
    
    15
    +
    
    16
    +    def __init__(self, netrc):
    
    17
    +        self.netrc = netrc
    
    18
    +
    
    19
    +    def _split(self, netloc):
    
    20
    +        userpass, hostport = urllib.parse.splituser(netloc)
    
    21
    +        host, port = urllib.parse.splitport(hostport)
    
    22
    +        if userpass:
    
    23
    +            user, passwd = urllib.parse.splitpasswd(userpass)
    
    24
    +        else:
    
    25
    +            user = ''
    
    26
    +            passwd = ''
    
    27
    +        return host, port, user, passwd
    
    28
    +
    
    29
    +    def _unsplit(self, host, port, user, passwd):
    
    30
    +        if port:
    
    31
    +            host = '{}:{}'.format(host, port)
    
    32
    +        if user:
    
    33
    +            if passwd:
    
    34
    +                user = '{}:{}'.format(user, passwd)
    
    35
    +            host = '{}@{}'.format(user, host)
    
    36
    +
    
    37
    +        return host
    
    38
    +
    
    39
    +    def ftp_open(self, req):
    
    40
    +        host, port, user, passwd = self._split(req.host)
    
    41
    +
    
    42
    +        if (not user or not passwd) and self.netrc:
    
    43
    +            entry = self.netrc.authenticators(host)
    
    44
    +            if entry:
    
    45
    +                entry_login, _, entry_password = entry
    
    46
    +                if not user:
    
    47
    +                    user = entry_login
    
    48
    +                if not passwd:
    
    49
    +                    passwd = entry_password
    
    50
    +
    
    51
    +        req.host = self._unsplit(host, port, user, passwd)
    
    52
    +
    
    53
    +        return super().ftp_open(req)
    
    54
    +
    
    55
    +
    
    56
    +class NetrcPasswordManager:
    
    57
    +
    
    58
    +    def __init__(self, netrc):
    
    59
    +        self.netrc = netrc
    
    60
    +
    
    61
    +    def add_password(self, realm, uri, user, passwd):
    
    62
    +        pass
    
    63
    +
    
    64
    +    def find_user_password(self, realm, authuri):
    
    65
    +        if not self.netrc:
    
    66
    +            return None, None
    
    67
    +        parts = urllib.parse.urlsplit(authuri)
    
    68
    +        entry = self.netrc.authenticators(parts.hostname)
    
    69
    +        if not entry:
    
    70
    +            return None, None
    
    71
    +        else:
    
    72
    +            login, _, password = entry
    
    73
    +            return login, password
    
    74
    +
    
    75
    +
    
    76
    +_urlopener = None
    
    77
    +
    
    78
    +
    
    79
    +def get_urlopener(plugin):
    
    80
    +    global _urlopener
    
    81
    +    if not _urlopener:
    
    82
    +        try:
    
    83
    +            netrc_config = netrc.netrc()
    
    84
    +        except FileNotFoundError:
    
    85
    +            _urlopener = urllib.request.build_opener()
    
    86
    +        except netrc.NetrcParseError as e:
    
    87
    +            plugin.warn('{}: While reading .netrc: {}'.format(plugin, e))
    
    88
    +            return urllib.request.build_opener()
    
    89
    +        else:
    
    90
    +            netrc_pw_mgr = NetrcPasswordManager(netrc_config)
    
    91
    +            http_auth = urllib.request.HTTPBasicAuthHandler(netrc_pw_mgr)
    
    92
    +            ftp_handler = NetrcFTPOpener(netrc_config)
    
    93
    +            _urlopener = urllib.request.build_opener(http_auth, ftp_handler)
    
    94
    +    return _urlopener
    
    95
    +
    
    96
    +
    
    13 97
     class DownloadableFileSource(Source):
    
    14 98
         # pylint: disable=attribute-defined-outside-init
    
    15 99
     
    
    ... ... @@ -118,7 +202,8 @@ class DownloadableFileSource(Source):
    118 202
                         if etag and self.get_consistency() == Consistency.CACHED:
    
    119 203
                             request.add_header('If-None-Match', etag)
    
    120 204
     
    
    121
    -                with contextlib.closing(urllib.request.urlopen(request)) as response:
    
    205
    +                opener = get_urlopener(self)
    
    206
    +                with contextlib.closing(opener.open(request)) as response:
    
    122 207
                         info = response.info()
    
    123 208
     
    
    124 209
                         etag = info['ETag'] if 'ETag' in info else None
    



  • [Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]