def __init__(self, service_account_email, service_account_key, google_api_url, server_api_key, http): self.service_account_email = service_account_email self.service_account_key = service_account_key self.google_api_url = google_api_url + 'identitytoolkit/v3/relyingparty/' self.server_api_key = server_api_key if http is None: self.http = httplib2.Http(client.MemoryCache()) else: self.http = http
def __init__(self, service_account_email, service_account_key, google_api_url, http): self.credentials = None if service_account_email and service_account_key: self.service_account_email = service_account_email self.service_account_key = service_account_key else: self.service_account_email = '' self.service_account_key = '' try: self.credentials = GoogleCredentials.get_application_default() \ .create_scoped(RpcHelper.GITKIT_SCOPE) except Exception as e: print( 'WARNING: unable to retrieve service account credentials.') self.google_api_url = google_api_url + 'identitytoolkit/v3/relyingparty/' if http is None: self.http = httplib2.Http(client.MemoryCache()) else: self.http = http
class GitkitService(object): # Wire ops cause nonintuitive numbers of RPCs that can make operation slow # (for example, the first call often gets public certs). Cache these results # and share them across all instances within a process. _CACHE = client.MemoryCache() def __init__(self, client_id, server_api_key, service_account_email, service_account_key, widget_url, http=None): self._instance = gitkitclient.GitkitClient( client_id, service_account_email, service_account_key, http=http if http is not None else httplib2.Http(self._CACHE), server_api_key=server_api_key, widget_url=widget_url) def get_provider_id(self, token): """Returns the provider id string if token is valid, else None. Args: token: string. Raw GITKit response token. Raises: GitkitClientError: if invalid input from caller. GitkitServerError: if error from GITKit server. RuntimeError: if GITKit is misconfigured. Returns: String. An identifier for the user's provider (for example, 'google.com'). """ gitkit_user = self._get_gitkit_user(token) return gitkit_user.provider_id if gitkit_user else None def get_user(self, token): """Returns a users.User if token is valid, else None. This method also verifies the GITKit token. If the token is invalid we return None. Note that token age is one of the things that can make a token invalid. This means persisting this object is risky, because there is no guarantee that an old object's token is still valid. If having a valid user is important to you, always call this method rather than re-using a previously-returned value. Note that it may cause an RPC in order to get public certs, but unless you pass your own http object to __init__, responses are cached across _Gitkit intances. Args: token: string. Raw GITKit response token. Raises: GitkitClientError: if invalid input from caller. GitkitServerError: if error from GITKit server. RuntimeError: if GITKit is misconfigured. Returns: users.User if token is valid else None. """ gitkit_user = self._get_gitkit_user(token) return self._get_users_user(gitkit_user) if gitkit_user else None def _get_gitkit_user(self, token): try: return self._instance.VerifyGitkitToken(token) except NotImplementedError, e: # When GITKit is misconfigured, the error it returns complains about # bad crypto. Detecting misconfiguration this way is risky: we could # be getting a false positive from real bad crypto. There is no good # way to disambiguate, and the value of giving a useful error # message here outweighs the rare chance of a false positive where # someone has turned off pycrypto in prod (which would require them # changing the libraries in app.yaml, and is really a you-broke-it- # you-bought-it situation). if _BAD_CRYPTO_NEEDLE in e.message: raise RuntimeError( 'Unable to communicate with users service. Please check ' 'your configuration values and try again.')
import threading import json import webapp2 import httplib2 from oauth2client import crypt, client _cached_http = httplib2.Http(client.MemoryCache()) def verify_id_token(id_token, audience, http=None, cert_uri=client.ID_TOKEN_VERIFICATON_CERTS): """Verifies a signed JWT id_token. This function requires PyOpenSSL and because of that it does not work on App Engine. Args: id_token: string, A Signed JWT. audience: string, The audience 'aud' that the token should be for. http: httplib2.Http, instance to use to make the HTTP request. Callers should supply an instance that has caching enabled. cert_uri: string, URI of the certificates in JSON format to verify the JWT against. Returns: The deserialized JSON in the JWT. Raises: oauth2client.crypt.AppIdentityError if the JWT fails to verify. """