Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: third_party/gsutil/plugins/sso_auth.py

Issue 86123002: Adds SSO auth to gsutil (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Review fixes, added caching Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/gsutil/plugins/__init__.py ('k') | upload_to_google_storage.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
Vadim Sh. 2013/12/03 23:32:42 nit: one new line here
Ryan Tseng 2013/12/03 23:55:25 Done.
5
6 """AuthHandler plugin for gsutil's boto to support LOAS based auth."""
7
Vadim Sh. 2013/12/03 23:32:42 nit: and here
Ryan Tseng 2013/12/03 23:55:25 Done.
8
9 import json
10 import getpass
11 import os
12 import re
13 import urllib2
Vadim Sh. 2013/12/03 23:32:42 nit: sort imports
Ryan Tseng 2013/12/03 23:55:25 Done.
14 import subprocess
15 import time
16
17 from boto.auth_handler import AuthHandler
18 from boto.auth_handler import NotReadyToAuthenticate
19
20 CMD = ['stubby', '--proto2', 'call', 'blade:sso', 'CorpLogin.Exchange']
21
22 STUBBY_CMD = """target: {
23 scope: GAIA_USER
24 name: "%s"
25 }
26 target_credential: {
27 type: OAUTH2_TOKEN
28 oauth2_attributes: {
29 scope: 'https://www.googleapis.com/auth/devstorage.read_only'
30 }
31 }"""
32
33 COOKIE_LOCATION = os.path.expanduser('~/.devstore_token')
34
35 TOKEN_EXPIRY = 300
36
37
38 class SSOAuthError(Exception):
39 pass
40
41
42 class SSOAuth(AuthHandler):
43 """SSO based auth handler."""
44
45 capability = ['google-oauth2', 's3']
46
47 def __init__(self, path, config, provider):
48 if provider.name == 'google' and self.has_prodaccess():
49 # If we don't have a loas token, then bypass this auth handler.
50 if subprocess.call('loas_check',
51 stdout=subprocess.PIPE,
52 stderr=subprocess.PIPE):
53 raise NotReadyToAuthenticate()
54 else:
55 raise NotReadyToAuthenticate()
56 self.token = None
57 self.expire = 0
58
59 def GetAccessToken(self):
60 # Return from in-memory cache if its there already.
61 if self.token and self.expire > time.time():
62 return self.token
63
64 # Try to retrieve token from filesystem cache.
65 if os.path.exists(COOKIE_LOCATION):
66 last_modified = os.path.getmtime(COOKIE_LOCATION)
67 if time.time() - last_modified < TOKEN_EXPIRY:
68 with open(COOKIE_LOCATION, 'rb') as f:
69 self.token = f.read()
70 self.expire = last_modified + TOKEN_EXPIRY
71 return self.token
72
73 # If the token is not in either caches, or has expired, then fetch token.
74 username = '%s@google.com' % getpass.getuser()
75 proc = subprocess.Popen(CMD, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
76 out, err = proc.communicate(STUBBY_CMD % username)
77 if proc.returncode:
78 raise SSOAuthError('Stubby returned %d\n%s' % (proc.returncode, err))
79 token_match = re.search(r'oauth2_token: "(.*)"$', out)
80 if token_match:
Vadim Sh. 2013/12/03 23:32:42 nit: swap if\else sections, that will make larger
Ryan Tseng 2013/12/03 23:55:25 Done.
81 token = token_match.group(1)
82 self.token = token
83 self.expire = time.time() + TOKEN_EXPIRY
84 with open(COOKIE_LOCATION, 'wb') as f:
85 f.write(token)
86 os.chmod(COOKIE_LOCATION, 0600) # Mark cookie read-only to user.
Vadim Sh. 2013/12/03 23:32:42 Strictly speaking, there's a chance that someone (
Ryan Tseng 2013/12/03 23:55:25 Done.
87 return token
88 raise SSOAuthError('Oauth2 token not found in %s' % out)
89
90 def add_auth(self, http_request):
91 http_request.headers['Authorization'] = 'OAuth %s' % self.GetAccessToken()
92
93 @staticmethod
94 def has_prodaccess():
95 for path in os.environ['PATH'].split(os.pathsep):
96 exe_file = os.path.join(path, 'prodaccess')
97 if os.path.exists(exe_file) and os.access(exe_file, os.X_OK):
98 return True
99 return False
OLDNEW
« no previous file with comments | « third_party/gsutil/plugins/__init__.py ('k') | upload_to_google_storage.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698