Move to metadata server v1 API
Support any scope that may be accepted by a service.
Change-Id: Ifef92158ff425b1e478b6fb73eae60878d782f63
diff --git a/git-cookie-authdaemon b/git-cookie-authdaemon
index 9e37004..27fae4b 100755
--- a/git-cookie-authdaemon
+++ b/git-cookie-authdaemon
@@ -20,10 +20,31 @@
REFRESH = 25 # seconds remaining when starting refresh
RETRY_INTERVAL = 5 # seconds between retrying a failed refresh
-A = 'http://metadata/0.1/meta-data/service-accounts/default/acquire'
-S = 'https://www.googleapis.com/auth/gerritcodereview'
+META_URL = 'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/'
+SUPPORTED_SCOPES = [
+ 'https://www.googleapis.com/auth/gerritcodereview',
+ 'https://www.googleapis.com/auth/source.full_control',
+ 'https://www.googleapis.com/auth/source.read_write',
+ 'https://www.googleapis.com/auth/source.read_only',
+]
COOKIE_JAR = None
+def read_meta(part):
+ r = urllib2.Request(META_URL + part)
+ r.add_header('Metadata-Flavor', 'Google')
+ return contextlib.closing(urllib2.urlopen(r))
+
+def select_scope():
+ with read_meta('scopes') as d:
+ avail = set(d.read().split())
+ scopes = [s for s in SUPPORTED_SCOPES if s in avail]
+ if scopes:
+ return iter(scopes).next()
+ sys.stderr.write('error: VM must have one of these scopes:\n\n')
+ for s in SUPPORTED_SCOPES:
+ sys.stderr.write(' %s\n' % (s))
+ sys.exit(1)
+
def configure_git():
global COOKIE_JAR
@@ -39,59 +60,43 @@
'http.cookiefile', COOKIE_JAR
])
-def acquire_token(retry):
+def acquire_token(scope, retry):
while True:
try:
- with contextlib.closing(urllib2.urlopen(A + '?scopes=' + S)) as token:
- return json.load(token)
+ with read_meta('token?scopes=' + scope) as d:
+ return json.load(d)
except urllib2.URLError:
if not retry:
raise
time.sleep(RETRY_INTERVAL)
-def update_cookie(retry):
- token = acquire_token(retry)
- expires = token['expiresAt']
- access_token = token['accessToken']
+def update_cookie(scope, retry):
+ now = int(time.time())
+ token = acquire_token(scope, retry)
+ access_token = token['access_token']
+ expires = now + int(token['expires_in'])
tmp_jar = COOKIE_JAR + '.lock'
cj = cookielib.MozillaCookieJar(tmp_jar)
- cj.set_cookie(cookielib.Cookie(
- version = 0,
- name = 'o',
- value = access_token,
- port = None,
- port_specified = False,
- domain = 'source.developers.google.com',
- domain_specified = True,
- domain_initial_dot = False,
- path = '/',
- path_specified = True,
- secure = True,
- expires = expires,
- discard = False,
- comment = None,
- comment_url = None,
- rest = None))
-
- cj.set_cookie(cookielib.Cookie(
- version = 0,
- name = 'o',
- value = access_token,
- port = None,
- port_specified = False,
- domain = '.googlesource.com',
- domain_specified = True,
- domain_initial_dot = True,
- path = '/',
- path_specified = True,
- secure = True,
- expires = expires,
- discard = False,
- comment = None,
- comment_url = None,
- rest = None))
+ for d in ['source.developers.google.com', '.googlesource.com']:
+ cj.set_cookie(cookielib.Cookie(
+ version = 0,
+ name = 'o',
+ value = access_token,
+ port = None,
+ port_specified = False,
+ domain = d,
+ domain_specified = True,
+ domain_initial_dot = d.startswith('.'),
+ path = '/',
+ path_specified = True,
+ secure = True,
+ expires = expires,
+ discard = False,
+ comment = None,
+ comment_url = None,
+ rest = None))
cj.save()
os.rename(tmp_jar, COOKIE_JAR)
@@ -103,7 +108,7 @@
if os.path.exists(p):
os.remove(p)
-def refresh_loop(expires):
+def refresh_loop(scope, expires):
atexit.register(cleanup)
expires = expires - REFRESH
while True:
@@ -112,11 +117,12 @@
while now < expires:
time.sleep(expires - now)
now = time.time()
- expires = update_cookie(retry=True) - REFRESH
+ expires = update_cookie(scope, retry=True) - REFRESH
def main():
+ scope = select_scope()
configure_git()
- expires = update_cookie(retry=False)
+ expires = update_cookie(scope, retry=False)
if '--nofork' not in sys.argv:
if os.fork() > 0:
@@ -128,10 +134,10 @@
pid = os.fork()
if pid > 0:
- print '%s PID %d' % (sys.argv[0], pid)
+ print 'git-cookie-authdaemon PID %d' % (pid)
sys.exit(0)
- refresh_loop(expires)
+ refresh_loop(scope, expires)
if __name__ == '__main__':
main()