OLD | NEW |
1 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved. | 1 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """ | 5 """ |
6 Utilities for requesting information for a gerrit server via https. | 6 Utilities for requesting information for a gerrit server via https. |
7 | 7 |
8 https://gerrit-review.googlesource.com/Documentation/rest-api.html | 8 https://gerrit-review.googlesource.com/Documentation/rest-api.html |
9 """ | 9 """ |
10 | 10 |
11 import base64 | 11 import base64 |
| 12 import cookielib |
12 import httplib | 13 import httplib |
13 import json | 14 import json |
14 import logging | 15 import logging |
15 import netrc | 16 import netrc |
16 import os | 17 import os |
17 import re | 18 import re |
18 import socket | 19 import socket |
19 import stat | 20 import stat |
20 import sys | 21 import sys |
21 import time | 22 import time |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 return GceAuthenticator() | 85 return GceAuthenticator() |
85 return NetrcAuthenticator() | 86 return NetrcAuthenticator() |
86 | 87 |
87 | 88 |
88 class NetrcAuthenticator(Authenticator): | 89 class NetrcAuthenticator(Authenticator): |
89 """Authenticator implementation that uses ".netrc" for token. | 90 """Authenticator implementation that uses ".netrc" for token. |
90 """ | 91 """ |
91 | 92 |
92 def __init__(self): | 93 def __init__(self): |
93 self.netrc = self._get_netrc() | 94 self.netrc = self._get_netrc() |
| 95 self.gitcookies = self._get_gitcookies() |
94 | 96 |
95 @staticmethod | 97 @staticmethod |
96 def _get_netrc(): | 98 def _get_netrc(): |
97 path = '_netrc' if sys.platform.startswith('win') else '.netrc' | 99 path = '_netrc' if sys.platform.startswith('win') else '.netrc' |
98 path = os.path.join(os.environ['HOME'], path) | 100 path = os.path.join(os.environ['HOME'], path) |
99 try: | 101 try: |
100 return netrc.netrc(path) | 102 return netrc.netrc(path) |
101 except IOError: | 103 except IOError: |
102 print >> sys.stderr, 'WARNING: Could not read netrc file %s' % path | 104 print >> sys.stderr, 'WARNING: Could not read netrc file %s' % path |
103 return netrc.netrc(os.devnull) | 105 return netrc.netrc(os.devnull) |
104 except netrc.NetrcParseError as e: | 106 except netrc.NetrcParseError as e: |
105 st = os.stat(e.path) | 107 st = os.stat(e.path) |
106 if st.st_mode & (stat.S_IRWXG | stat.S_IRWXO): | 108 if st.st_mode & (stat.S_IRWXG | stat.S_IRWXO): |
107 print >> sys.stderr, ( | 109 print >> sys.stderr, ( |
108 'WARNING: netrc file %s cannot be used because its file ' | 110 'WARNING: netrc file %s cannot be used because its file ' |
109 'permissions are insecure. netrc file permissions should be ' | 111 'permissions are insecure. netrc file permissions should be ' |
110 '600.' % path) | 112 '600.' % path) |
111 else: | 113 else: |
112 print >> sys.stderr, ('ERROR: Cannot use netrc file %s due to a ' | 114 print >> sys.stderr, ('ERROR: Cannot use netrc file %s due to a ' |
113 'parsing error.' % path) | 115 'parsing error.' % path) |
114 raise | 116 raise |
115 return netrc.netrc(os.devnull) | 117 return netrc.netrc(os.devnull) |
116 | 118 |
| 119 @staticmethod |
| 120 def _get_gitcookies(): |
| 121 gitcookies = {} |
| 122 path = os.path.join(os.environ['HOME'], '.gitcookies') |
| 123 try: |
| 124 f = open(path, 'rb') |
| 125 except IOError: |
| 126 return gitcookies |
| 127 |
| 128 with f: |
| 129 for line in f: |
| 130 try: |
| 131 fields = line.strip().split('\t') |
| 132 if line.strip().startswith('#') or len(fields) != 7: |
| 133 continue |
| 134 domain, xpath, key, value = fields[0], fields[2], fields[5], fields[6] |
| 135 if xpath == '/' and key == 'o': |
| 136 login, secret_token = value.split('=', 1) |
| 137 gitcookies[domain] = (login, secret_token) |
| 138 except (IndexError, ValueError, TypeError) as exc: |
| 139 logging.warning(exc) |
| 140 |
| 141 return gitcookies |
| 142 |
117 def get_auth_header(self, host): | 143 def get_auth_header(self, host): |
118 auth = self.netrc.authenticators(host) | 144 auth = None |
| 145 for domain, creds in self.gitcookies.iteritems(): |
| 146 if cookielib.domain_match(host, domain): |
| 147 auth = (creds[0], None, creds[1]) |
| 148 break |
| 149 |
| 150 if not auth: |
| 151 auth = self.netrc.authenticators(host) |
119 if auth: | 152 if auth: |
120 return 'Basic %s' % (base64.b64encode('%s:%s' % (auth[0], auth[2]))) | 153 return 'Basic %s' % (base64.b64encode('%s:%s' % (auth[0], auth[2]))) |
121 return None | 154 return None |
122 | 155 |
123 | 156 |
124 class GceAuthenticator(Authenticator): | 157 class GceAuthenticator(Authenticator): |
125 """Authenticator implementation that uses GCE metadata service for token. | 158 """Authenticator implementation that uses GCE metadata service for token. |
126 """ | 159 """ |
127 | 160 |
128 _INFO_URL = 'http://metadata.google.internal' | 161 _INFO_URL = 'http://metadata.google.internal' |
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 username = review.get('email', jmsg.get('name', '')) | 605 username = review.get('email', jmsg.get('name', '')) |
573 raise GerritError(200, 'Unable to set %s label for user "%s"' | 606 raise GerritError(200, 'Unable to set %s label for user "%s"' |
574 ' on change %s.' % (label, username, change)) | 607 ' on change %s.' % (label, username, change)) |
575 jmsg = GetChangeCurrentRevision(host, change) | 608 jmsg = GetChangeCurrentRevision(host, change) |
576 if not jmsg: | 609 if not jmsg: |
577 raise GerritError( | 610 raise GerritError( |
578 200, 'Could not get review information for change "%s"' % change) | 611 200, 'Could not get review information for change "%s"' % change) |
579 elif jmsg[0]['current_revision'] != revision: | 612 elif jmsg[0]['current_revision'] != revision: |
580 raise GerritError(200, 'While resetting labels on change "%s", ' | 613 raise GerritError(200, 'While resetting labels on change "%s", ' |
581 'a new patchset was uploaded.' % change) | 614 'a new patchset was uploaded.' % change) |
OLD | NEW |