Change RPC client to only use Google Accounts for authentication

Hosted domain account (such as "@google.com" itself) don't work on the
Google App Engine service unless the user specifically creates their
own Google Account (https://www.google.com/accounts/NewAccount) with
the same email address.

When both such accounts exist we must *only* use the Google Account in
our auth request, as that is all Google App Engine will honor when we
send it the session cookie.

However, Google has internal servers that may also be running Gerrit
based applications.  In those case we must use the hosted auth login
for @google.com user accounts, as the internal servers honor only the
hosted account and not the public Google Account database.

In the future we may need to add other domains to the "HOSTED" list
if other Gerrit instances are setup on hosted domains and locked to
only those domain's user accounts, similar to how a server that is
internal to Google would be setup.  Since this is currently not a
likely occurrence I'm not worrying about making it configurable at
this juncture.

Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
Shawn O. Pearce 2008-10-22 13:02:56 -07:00
parent 02dbb6d120
commit bb0ee80571
2 changed files with 17 additions and 6 deletions

View File

@ -1 +1 @@
__version__ = 'v1.0' __version__ = 'v1.0-14-gc4f226bc'

View File

@ -167,6 +167,10 @@ class HttpRpc(RpcChannel):
Returns: Returns:
The authentication token returned by ClientLogin. The authentication token returned by ClientLogin.
""" """
account_type = 'GOOGLE'
if self.host.endswith('.google.com'):
account_type = 'HOSTED'
req = self._CreateRequest( req = self._CreateRequest(
url="https://www.google.com/accounts/ClientLogin", url="https://www.google.com/accounts/ClientLogin",
data=urllib.urlencode({ data=urllib.urlencode({
@ -174,7 +178,7 @@ class HttpRpc(RpcChannel):
"Passwd": password, "Passwd": password,
"service": "ah", "service": "ah",
"source": "gerrit-codereview-client", "source": "gerrit-codereview-client",
"accountType": "HOSTED_OR_GOOGLE", "accountType": account_type,
}) })
) )
try: try:
@ -214,7 +218,6 @@ class HttpRpc(RpcChannel):
response.info()["location"] != continue_location): response.info()["location"] != continue_location):
raise urllib2.HTTPError(req.get_full_url(), response.code, response.msg, raise urllib2.HTTPError(req.get_full_url(), response.code, response.msg,
response.headers, response.fp) response.headers, response.fp)
self.authenticated = True
def _GetXsrfToken(self): def _GetXsrfToken(self):
"""Fetches /proto/_token for use in X-XSRF-Token HTTP header. """Fetches /proto/_token for use in X-XSRF-Token HTTP header.
@ -253,10 +256,18 @@ class HttpRpc(RpcChannel):
authentication cookie, it returns a 401 response and directs us to authentication cookie, it returns a 401 response and directs us to
authenticate ourselves with ClientLogin. authenticate ourselves with ClientLogin.
""" """
for i in range(3): attempts = 0
credentials = self.auth_function() while True:
auth_token = self._GetAuthToken(credentials[0], credentials[1]) attempts += 1
try:
cred = self.auth_function()
auth_token = self._GetAuthToken(cred[0], cred[1])
except ClientLoginError:
if attempts < 3:
continue
raise
self._GetAuthCookie(auth_token) self._GetAuthCookie(auth_token)
self.authenticated = True
if self.cookie_file is not None: if self.cookie_file is not None:
self.cookie_jar.save() self.cookie_jar.save()
return return