def setUp(self): self.fake_model = tests_models.CredentialsModel() self.fake_model_field = self.fake_model._meta.get_field('credentials') self.field = models.CredentialsField(null=True) self.credentials = client.Credentials() self.pickle_str = _helpers._from_bytes( base64.b64encode(pickle.dumps(self.credentials))) self.jsonpickle_str = _helpers._from_bytes( base64.b64encode(jsonpickle.encode(self.credentials).encode()))
def setUp(self): self.fake_model = CredentialsModel() self.fake_model_field = self.fake_model._meta.get_field('credentials') self.field = CredentialsField(null=True) self.credentials = Credentials() self.pickle_str = _helpers._from_bytes( base64.b64encode(pickle.dumps(self.credentials)))
def get(http, path, root=METADATA_ROOT, recursive=None): """Fetch a resource from the metadata server. Args: http: an object to be used to make HTTP requests. path: A string indicating the resource to retrieve. For example, 'instance/service-accounts/default' root: A string indicating the full path to the metadata server root. recursive: A boolean indicating whether to do a recursive query of metadata. See https://cloud.google.com/compute/docs/metadata#aggcontents Returns: A dictionary if the metadata server returns JSON, otherwise a string. Raises: http_client.HTTPException if an error corrured while retrieving metadata. """ url = urlparse.urljoin(root, path) url = _helpers._add_query_parameter(url, 'recursive', recursive) response, content = transport.request(http, url, headers=METADATA_HEADERS) if response.status == http_client.OK: decoded = _helpers._from_bytes(content) if response['content-type'] == 'application/json': return json.loads(decoded) else: return decoded else: raise http_client.HTTPException( 'Failed to retrieve {0} from the Google Compute Engine' 'metadata service. Response:\n{1}'.format(url, response))
def _refresh(self, http_request): """Refreshes the access_token. Skip all the storage hoops and just refresh using the API. Args: http_request: callable, a callable that matches the method signature of httplib2.Http.request, used to make the refresh request. Raises: HttpAccessTokenRefreshError: When the refresh fails. """ query = '?scope=%s' % urllib.parse.quote(self.scope, '') uri = META.replace('{?scope}', query) response, content = http_request(uri) content = _from_bytes(content) if response.status == 200: try: d = json.loads(content) except Exception as e: raise HttpAccessTokenRefreshError(str(e), status=response.status) self.access_token = d['accessToken'] else: if response.status == 404: content += (' This can occur if a VM was created' ' with no service account or scopes.') raise HttpAccessTokenRefreshError(content, status=response.status)
def test_validate_error(self): payload = ( b"{" b' "web": {' b' "client_id": "[[CLIENT ID REQUIRED]]",' b' "client_secret": "[[CLIENT SECRET REQUIRED]]",' b' "redirect_uris": ["http://localhost:8080/oauth2callback"],' b' "auth_uri": "",' b' "token_uri": ""' b" }" b"}" ) ERRORS = [ ("{}", "Invalid"), ('{"foo": {}}', "Unknown"), ('{"web": {}}', "Missing"), ('{"web": {"client_id": "dkkd"}}', "Missing"), (payload, "Property"), ] for src, match in ERRORS: # Ensure that it is unicode src = _helpers._from_bytes(src) # Test load(s) with self.assertRaises(clientsecrets.InvalidClientSecretsError) as exc_manager: clientsecrets.loads(src) self.assertTrue(str(exc_manager.exception).startswith(match)) # Test loads(fp) with self.assertRaises(clientsecrets.InvalidClientSecretsError) as exc_manager: fp = StringIO(src) clientsecrets.load(fp) self.assertTrue(str(exc_manager.exception).startswith(match))
def test_validate_error(self): payload = ( b'{' b' "web": {' b' "client_id": "[[CLIENT ID REQUIRED]]",' b' "client_secret": "[[CLIENT SECRET REQUIRED]]",' b' "redirect_uris": ["http://localhost:8080/oauth2callback"],' b' "auth_uri": "",' b' "token_uri": ""' b' }' b'}') ERRORS = [ ('{}', 'Invalid'), ('{"foo": {}}', 'Unknown'), ('{"web": {}}', 'Missing'), ('{"web": {"client_id": "dkkd"}}', 'Missing'), (payload, 'Property'), ] for src, match in ERRORS: # Ensure that it is unicode src = _from_bytes(src) # Test load(s) try: clientsecrets.loads(src) self.fail(src + ' should not be a valid client_secrets file.') except clientsecrets.InvalidClientSecretsError as e: self.assertTrue(str(e).startswith(match)) # Test loads(fp) try: fp = StringIO(src) clientsecrets.load(fp) self.fail(src + ' should not be a valid client_secrets file.') except clientsecrets.InvalidClientSecretsError as e: self.assertTrue(str(e).startswith(match))
def from_string(cls, key, password='******'): """Construct an RsaSigner instance from a string. Args: key: string, private key in PEM format. password: string, password for private key file. Unused for PEM files. Returns: RsaSigner instance. Raises: ValueError if the key cannot be parsed as PKCS#1 or PKCS#8 in PEM format. """ key = _helpers._from_bytes(key) # pem expects str in Py3 marker_id, key_bytes = pem.readPemBlocksFromFile( six.StringIO(key), _PKCS1_MARKER, _PKCS8_MARKER) if marker_id == 0: pkey = rsa.key.PrivateKey.load_pkcs1(key_bytes, format='DER') elif marker_id == 1: key_info, remaining = decoder.decode( key_bytes, asn1Spec=_PKCS8_SPEC) if remaining != b'': raise ValueError('Unused bytes', remaining) pkey_info = key_info.getComponentByName('privateKey') pkey = rsa.key.PrivateKey.load_pkcs1(pkey_info.asOctets(), format='DER') else: raise ValueError('No key could be detected.') return cls(pkey)
def get(http, path, root=METADATA_ROOT, recursive=None): """Fetch a resource from the metadata server. Args: http: an object to be used to make HTTP requests. path: A string indicating the resource to retrieve. For example, 'instance/service-accounts/default' root: A string indicating the full path to the metadata server root. recursive: A boolean indicating whether to do a recursive query of metadata. See https://cloud.google.com/compute/docs/metadata#aggcontents Returns: A dictionary if the metadata server returns JSON, otherwise a string. Raises: http_client.HTTPException if an error corrured while retrieving metadata. """ url = urlparse.urljoin(root, path) url = _helpers._add_query_parameter(url, 'recursive', recursive) response, content = transport.request( http, url, headers=METADATA_HEADERS) if response.status == http_client.OK: decoded = _helpers._from_bytes(content) if response['content-type'] == 'application/json': return json.loads(decoded) else: return decoded else: raise http_client.HTTPException( 'Failed to retrieve {0} from the Google Compute Engine' 'metadata service. Response:\n{1}'.format(url, response))
def run(self): s = None try: # Do not set the timeout on the socket, leave it in the blocking # mode as setting the timeout seems to cause spurious EAGAIN # errors on OSX. self._socket.settimeout(None) s, unused_addr = self._socket.accept() resp_buffer = '' resp_1 = s.recv(6).decode() nstr, extra = resp_1.split('\n', 1) resp_buffer = extra n = int(nstr) to_read = n - len(extra) if to_read > 0: resp_buffer += _from_bytes(s.recv(to_read, socket.MSG_WAITALL)) if resp_buffer != CREDENTIAL_INFO_REQUEST_JSON: self.bad_request = True l = len(self.response) s.sendall('{0}\n{1}'.format(l, self.response).encode()) finally: # Will fail if s is None, but these tests never encounter # that scenario. s.close()
def from_json(cls, json_data): data = json.loads(_helpers._from_bytes(json_data)) if (data.get('token_expiry') and not isinstance(data['token_expiry'], datetime.datetime)): try: data['token_expiry'] = datetime.datetime.strptime( data['token_expiry'], EXPIRY_FORMAT) except ValueError: data['token_expiry'] = None retval = cls(data['access_token'], data['client_id'], data['client_secret'], data['refresh_token'], data['token_expiry'], data['token_uri'], data['user_agent'], revoke_uri=data.get('revoke_uri', None), id_token=data.get('id_token', None), id_token_jwt=data.get('id_token_jwt', None), token_response=data.get('token_response', None), scopes=data.get('scopes', None), token_info_uri=data.get('token_info_uri', None), cloud_path=data.get('cloud_path', None)) retval.invalid = data['invalid'] return retval
def _get_metadata(http_request=None, path=None, recursive=True): """Gets a JSON object from the specified path on the Metadata Server Args: http_request: an httplib2.Http().request object or equivalent with which to make the call to the metadata server path: a list of strings denoting the metadata server request path. recursive: if true, returns a json blob of the entire tree below this level. If false, return a list of child keys. Returns: A deserialized JSON object representing the data returned from the metadata server """ if path is None: path = [] if not http_request: http_request = httplib2.Http().request r_string = "/?recursive=true" if recursive else "" full_path = _METADATA_ROOT + "/".join(path) + r_string response, content = http_request(full_path, headers={"Metadata-Flavor": "Google"}) if response.status == http_client.OK: decoded = _from_bytes(content) if response["content-type"] == "application/json": return json.loads(decoded) else: return decoded else: msg = ( "Failed to retrieve {path} from the Google Compute Engine" "metadata service. Response:\n{error}" ).format(path=full_path, error=response) raise MetadataServerHttpError(msg)
def from_string(cls, key, password='******'): """Construct an RsaSigner instance from a string. Args: key: string, private key in PEM format. password: string, password for private key file. Unused for PEM files. Returns: RsaSigner instance. Raises: ValueError if the key cannot be parsed as PKCS#1 or PKCS#8 in PEM format. """ key = _from_bytes(key) # pem expects str in Py3 marker_id, key_bytes = pem.readPemBlocksFromFile( six.StringIO(key), _PKCS1_MARKER, _PKCS8_MARKER) if marker_id == 0: pkey = rsa.key.PrivateKey.load_pkcs1(key_bytes, format='DER') elif marker_id == 1: key_info, remaining = decoder.decode( key_bytes, asn1Spec=_PKCS8_SPEC) if remaining != b'': raise ValueError('Unused bytes', remaining) pkey_info = key_info.getComponentByName('privateKey') pkey = rsa.key.PrivateKey.load_pkcs1(pkey_info.asOctets(), format='DER') else: raise ValueError('No key could be detected.') return cls(pkey)
def _refresh(self, http_request): """Refreshes the access_token. Skip all the storage hoops and just refresh using the API. Args: http_request: callable, a callable that matches the method signature of httplib2.Http.request, used to make the refresh request. Raises: AccessTokenRefreshError: When the refresh fails. """ query = '?scope=%s' % urllib.parse.quote(self.scope, '') uri = META.replace('{?scope}', query) response, content = http_request(uri) content = _from_bytes(content) if response.status == 200: try: d = json.loads(content) except Exception as e: raise AccessTokenRefreshError(str(e)) self.access_token = d['accessToken'] else: if response.status == 404: content += (' This can occur if a VM was created' ' with no service account or scopes.') raise AccessTokenRefreshError(content)
def run(self): s = None try: # Do not set the timeout on the socket, leave it in the blocking # mode as setting the timeout seems to cause spurious EAGAIN # errors on OSX. self._socket.settimeout(None) s, unused_addr = self._socket.accept() resp_buffer = '' resp_1 = s.recv(6).decode() nstr, extra = resp_1.split('\n', 1) resp_buffer = extra n = int(nstr) to_read = n - len(extra) if to_read > 0: resp_buffer += _from_bytes(s.recv(to_read, socket.MSG_WAITALL)) if resp_buffer != CREDENTIAL_INFO_REQUEST_JSON: self.bad_request = True l = len(self.response) s.sendall(('%d\n%s' % (l, self.response)).encode()) finally: # Will fail if s is None, but these tests never encounter # that scenario. s.close()
def from_json(cls, json_data): """Overrides.""" data = json.loads(_helpers._from_bytes(json_data)) if ((data.get('token_expiry') and not isinstance(data['token_expiry'], datetime.datetime))): try: data['token_expiry'] = datetime.datetime.strptime( data['token_expiry'], client.EXPIRY_FORMAT) except ValueError: data['token_expiry'] = None kwargs = {} for param in ('revoke_uri', 'id_token', 'id_token_jwt', 'token_response', 'scopes', 'token_info_uri', 'rapt_token'): value = data.get(param, None) if value is not None: kwargs[param] = value retval = cls(data['access_token'], data['client_id'], data['client_secret'], data['refresh_token'], data['token_expiry'], data['token_uri'], data['user_agent'], **kwargs) retval.invalid = data['invalid'] return retval
def setUp(self): self.fake_model = self.FakeFlowModel() self.fake_model_field = self.fake_model._meta.get_field('flow') self.field = FlowField(null=True) self.flow = Flow() self.pickle_str = _from_bytes( base64.b64encode(pickle.dumps(self.flow)))
def setUp(self): self.fake_model = FakeCredentialsModel() self.fake_model_field = self.fake_model._meta.get_field('credentials') self.field = CredentialsField(null=True) self.credentials = Credentials() self.pickle_str = _from_bytes( base64.b64encode(pickle.dumps(self.credentials)))
def _refresh(self, http_request): """Refreshes the access_token. Skip all the storage hoops and just refresh using the API. Args: http_request: callable, a callable that matches the method signature of httplib2.Http.request, used to make the refresh request. Raises: HttpAccessTokenRefreshError: When the refresh fails. """ response, content = http_request(META, headers={'Metadata-Flavor': 'Google'}) content = _from_bytes(content) if response.status == http_client.OK: try: token_content = json.loads(content) except Exception as e: raise HttpAccessTokenRefreshError(str(e), status=response.status) self.access_token = token_content['access_token'] else: if response.status == http_client.NOT_FOUND: content += (' This can occur if a VM was created' ' with no service account or scopes.') raise HttpAccessTokenRefreshError(content, status=response.status)
def setUp(self): self.fake_model = self.FakeFlowModel() self.fake_model_field = self.fake_model._meta.get_field('flow') self.field = FlowField() self.flow = Flow() self.pickle_str = _from_bytes(base64.b64encode(pickle.dumps( self.flow)))
def _refresh(self, http_request): """Refreshes the access_token. Skip all the storage hoops and just refresh using the API. Args: http_request: callable, a callable that matches the method signature of httplib2.Http.request, used to make the refresh request. Raises: HttpAccessTokenRefreshError: When the refresh fails. """ query = '?scope=%s' % urllib.parse.quote(self.scope, '') uri = META.replace('{?scope}', query) response, content = http_request( uri, headers={'Metadata-Flavor': 'Google'}) content = _from_bytes(content) if response.status == http_client.OK: try: token_content = json.loads(content) except Exception as e: raise HttpAccessTokenRefreshError(str(e), status=response.status) self.access_token = token_content['access_token'] else: if response.status == http_client.NOT_FOUND: content += (' This can occur if a VM was created' ' with no service account or scopes.') raise HttpAccessTokenRefreshError(content, status=response.status)
def http_request(uri, method, body, headers): response, content = transport.request(http, uri, method=method, body=body, headers=headers) content = _helpers._from_bytes(content) return response, content
def from_json(cls, json_data): """Deserialize a JSON-serialized instance. Inverse to :meth:`to_json`. Args: json_data: dict or string, Serialized JSON (as a string or an already parsed dictionary) representing a credential. Returns: ServiceAccountCredentials from the serialized data. """ if not isinstance(json_data, dict): json_data = json.loads(_helpers._from_bytes(json_data)) private_key_pkcs8_pem = None pkcs12_val = json_data.get(_PKCS12_KEY) password = None if pkcs12_val is None: private_key_pkcs8_pem = json_data['_private_key_pkcs8_pem'] signer = crypt.Signer.from_string(private_key_pkcs8_pem) else: # NOTE: This assumes that private_key_pkcs8_pem is not also # in the serialized data. This would be very incorrect # state. pkcs12_val = base64.b64decode(pkcs12_val) password = json_data['_private_key_password'] signer = crypt.Signer.from_string(pkcs12_val, password) credentials = cls( json_data['_service_account_email'], signer, scopes=json_data['_scopes'], private_key_id=json_data['_private_key_id'], client_id=json_data['client_id'], user_agent=json_data['_user_agent'], **json_data['_kwargs'] ) if private_key_pkcs8_pem is not None: credentials._private_key_pkcs8_pem = private_key_pkcs8_pem if pkcs12_val is not None: credentials._private_key_pkcs12 = pkcs12_val if password is not None: credentials._private_key_password = password credentials.invalid = json_data['invalid'] credentials.access_token = json_data['access_token'] credentials.token_uri = json_data['token_uri'] credentials.revoke_uri = json_data['revoke_uri'] token_expiry = json_data.get('token_expiry', None) if token_expiry is not None: credentials.token_expiry = datetime.datetime.strptime( token_expiry, client.EXPIRY_FORMAT) return credentials
def from_json(cls, json_data): """Deserialize a JSON-serialized instance. Inverse to :meth:`to_json`. Args: json_data: dict or string, Serialized JSON (as a string or an already parsed dictionary) representing a credential. Returns: ServiceAccountCredentials from the serialized data. """ if not isinstance(json_data, dict): json_data = json.loads(_from_bytes(json_data)) private_key_pkcs8_pem = None pkcs12_val = json_data.get(_PKCS12_KEY) password = None if pkcs12_val is None: private_key_pkcs8_pem = json_data['_private_key_pkcs8_pem'] signer = crypt.Signer.from_string(private_key_pkcs8_pem) else: # NOTE: This assumes that private_key_pkcs8_pem is not also # in the serialized data. This would be very incorrect # state. pkcs12_val = base64.b64decode(pkcs12_val) password = json_data['_private_key_password'] signer = crypt.Signer.from_string(pkcs12_val, password) credentials = cls( json_data['_service_account_email'], signer, scopes=json_data['_scopes'], private_key_id=json_data['_private_key_id'], client_id=json_data['client_id'], user_agent=json_data['_user_agent'], **json_data['_kwargs'] ) if private_key_pkcs8_pem is not None: credentials._private_key_pkcs8_pem = private_key_pkcs8_pem if pkcs12_val is not None: credentials._private_key_pkcs12 = pkcs12_val if password is not None: credentials._private_key_password = password credentials.invalid = json_data['invalid'] credentials.access_token = json_data['access_token'] credentials.token_uri = json_data['token_uri'] credentials.revoke_uri = json_data['revoke_uri'] token_expiry = json_data.get('token_expiry', None) if token_expiry is not None: credentials.token_expiry = datetime.datetime.strptime( token_expiry, EXPIRY_FORMAT) return credentials
def test_from_string_pkcs8_extra_bytes(self): key_bytes = self._load_pkcs8_key_bytes() _, pem_bytes = pem.readPemBlocksFromFile( six.StringIO(_helpers._from_bytes(key_bytes)), _pure_python_crypt._PKCS8_MARKER) with mock.patch('pyasn1.codec.der.decoder.decode') as mock_decode: key_info, remaining = None, 'extra' mock_decode.return_value = (key_info, remaining) with self.assertRaises(ValueError): crypt.RsaSigner.from_string(key_bytes) # Verify mock was called. mock_decode.assert_called_once_with( pem_bytes, asn1Spec=_pure_python_crypt._PKCS8_SPEC)
def test_from_string_pkcs8_extra_bytes(self): key_bytes = self._load_pkcs8_key_bytes() _, pem_bytes = pem.readPemBlocksFromFile( six.StringIO(_from_bytes(key_bytes)), _pure_python_crypt._PKCS8_MARKER) with mock.patch('pyasn1.codec.der.decoder.decode') as mock_decode: key_info, remaining = None, 'extra' mock_decode.return_value = (key_info, remaining) with self.assertRaises(ValueError): RsaSigner.from_string(key_bytes) # Verify mock was called. mock_decode.assert_called_once_with( pem_bytes, asn1Spec=_pure_python_crypt._PKCS8_SPEC)
def _do_refresh_request(self, http, rapt_refreshed=False): """Refresh the access_token using the refresh_token. Args: http: An object to be used to make HTTP requests. rapt_refreshed: If we did or did not already refreshed the rapt token. Raises: HttpAccessTokenRefreshError: When the refresh fails. """ body = self._generate_refresh_request_body() headers = self._generate_refresh_request_headers() logger.info('Refreshing access_token') resp, content = transport.request(http, self.token_uri, method='POST', body=body, headers=headers) content = _helpers._from_bytes(content) if resp.status != http_client.OK: self._handle_refresh_error(http, rapt_refreshed, resp, content) return d = json.loads(content) self.token_response = d self.access_token = d['access_token'] self.refresh_token = d.get('refresh_token', self.refresh_token) if 'expires_in' in d: delta = datetime.timedelta(seconds=int(d['expires_in'])) self.token_expiry = delta + client._UTCNOW() else: self.token_expiry = None if 'id_token' in d: self.id_token = client._extract_id_token(d['id_token']) self.id_token_jwt = d['id_token'] else: self.id_token = None self.id_token_jwt = None # On temporary refresh errors, the user does not actually have to # re-authorize, so we unflag here. self.invalid = False if self.store: self.store.locked_put(self)
def from_json(cls, s): data = json.loads(_from_bytes(s)) credentials = cls( service_account_id=data['_service_account_id'], service_account_email=data['_service_account_email'], private_key_id=data['_private_key_id'], private_key_pkcs8_text=data['_private_key_pkcs8_text'], scopes=[], user_agent=data['_user_agent']) credentials.invalid = data['invalid'] credentials.access_token = data['access_token'] token_expiry = data.get('token_expiry', None) if token_expiry is not None: credentials.token_expiry = datetime.datetime.strptime( token_expiry, EXPIRY_FORMAT) return credentials
def verify_signed_jwt_with_certs(jwt, certs, audience=None): """Verify a JWT against public certs. See http://self-issued.info/docs/draft-jones-json-web-token.html. Args: jwt: string, A JWT. certs: dict, Dictionary where values of public keys in PEM format. audience: string, The audience, 'aud', that this JWT should contain. If None then the JWT's 'aud' parameter is not verified. Returns: dict, The deserialized JSON payload in the JWT. Raises: AppIdentityError: if any checks are failed. """ jwt = _helpers._to_bytes(jwt) if jwt.count(b'.') != 2: raise AppIdentityError( 'Wrong number of segments in token: {0}'.format(jwt)) header, payload, signature = jwt.split(b'.') message_to_sign = header + b'.' + payload signature = _helpers._urlsafe_b64decode(signature) # Parse token. payload_bytes = _helpers._urlsafe_b64decode(payload) try: payload_dict = json.loads(_helpers._from_bytes(payload_bytes)) except: raise AppIdentityError('Can\'t parse token: {0}'.format(payload_bytes)) # Verify that the signature matches the message. _verify_signature(message_to_sign, signature, certs.values()) # Verify the issued at and created times in the payload. _verify_time_range(payload_dict) # Check audience. _check_audience(payload_dict, audience) return payload_dict
def _write_credentials_file(credentials_file, credentials): """Writes credentials to a file. Refer to :func:`_load_credentials_file` for the format. Args: credentials_file: An open file handle, must be read/write. credentials: A dictionary mapping user-defined keys to an instance of :class:`oauth2client.client.Credentials`. """ data = {"file_version": 2, "credentials": {}} for key, credential in iteritems(credentials): credential_json = credential.to_json() encoded_credential = _helpers._from_bytes(base64.b64encode(_helpers._to_bytes(credential_json))) data["credentials"][key] = encoded_credential credentials_file.seek(0) json.dump(data, credentials_file) credentials_file.truncate()
def get(path, http_request=None, root=METADATA_ROOT, recursive=None): """Fetch a resource from the metadata server. Args: path: A string indicating the resource to retrieve. For example, 'instance/service-accounts/defualt' http_request: A callable that matches the method signature of httplib2.Http.request. Used to make the request to the metadataserver. root: A string indicating the full path to the metadata server root. recursive: A boolean indicating whether to do a recursive query of metadata. See https://cloud.google.com/compute/docs/metadata#aggcontents Returns: A dictionary if the metadata server returns JSON, otherwise a string. Raises: httplib2.Httplib2Error if an error corrured while retrieving metadata. """ if not http_request: http_request = httplib2.Http().request url = urlparse.urljoin(root, path) url = util._add_query_parameter(url, 'recursive', recursive) response, content = http_request( url, headers=METADATA_HEADERS ) if response.status == http_client.OK: decoded = _from_bytes(content) if response['content-type'] == 'application/json': return json.loads(decoded) else: return decoded else: raise httplib2.HttpLib2Error( 'Failed to retrieve {0} from the Google Compute Engine' 'metadata service. Response:\n{1}'.format(url, response))
def from_json(cls, json_data): data = json.loads(_helpers._from_bytes(json_data)) if data.get("token_expiry") and not isinstance(data["token_expiry"], datetime.datetime): try: data["token_expiry"] = datetime.datetime.strptime( data["token_expiry"], EXPIRY_FORMAT) except ValueError: data["token_expiry"] = None garpun_creds = cls( data["access_token"], data["client_id"], data["client_secret"], data["refresh_token"], data["token_expiry"], data["token_uri"], data["user_agent"], revoke_uri=data.get("revoke_uri", None), ) garpun_creds.invalid = data["invalid"] return garpun_creds
def _write_credentials_file(credentials_file, credentials): """Writes credentials to a file. Refer to :func:`_load_credentials_file` for the format. Args: credentials_file: An open file handle, must be read/write. credentials: A dictionary mapping user-defined keys to an instance of :class:`oauth2client.client.Credentials`. """ data = {'file_version': 2, 'credentials': {}} for key, credential in iteritems(credentials): credential_json = credential.to_json() encoded_credential = _helpers._from_bytes( base64.b64encode(_helpers._to_bytes(credential_json))) data['credentials'][key] = encoded_credential credentials_file.seek(0) json.dump(data, credentials_file) credentials_file.truncate()
def _get_service_account_email(http_request=None): """Get the GCE service account email from the current environment. Args: http_request: callable, (Optional) a callable that matches the method signature of httplib2.Http.request, used to make the request to the metadata service. Returns: tuple, A pair where the first entry is an optional response (from a failed request) and the second is service account email found (as a string). """ if http_request is None: http_request = httplib2.Http().request response, content = http_request(_DEFAULT_EMAIL_METADATA, headers={'Metadata-Flavor': 'Google'}) if response.status == http_client.OK: content = _from_bytes(content) return None, content else: return response, content
def _get_service_account_email(http_request=None): """Get the GCE service account email from the current environment. Args: http_request: callable, (Optional) a callable that matches the method signature of httplib2.Http.request, used to make the request to the metadata service. Returns: tuple, A pair where the first entry is an optional response (from a failed request) and the second is service account email found (as a string). """ if http_request is None: http_request = httplib2.Http().request response, content = http_request( _DEFAULT_EMAIL_METADATA, headers={'Metadata-Flavor': 'Google'}) if response.status == http_client.OK: content = _from_bytes(content) return None, content else: return response, content
def test_from_string_pkcs1_unicode(self): key_bytes = _from_bytes(self._load_pkcs1_key_bytes()) signer = RsaSigner.from_string(key_bytes) self.assertIsInstance(signer, RsaSigner) self.assertIsInstance(signer._key, rsa.key.PrivateKey)
def test_from_string_pub_cert_unicode(self): public_cert = _helpers._from_bytes(self._load_public_cert_bytes()) verifier = crypt.RsaVerifier.from_string(public_cert, is_x509_cert=True) self.assertIsInstance(verifier, crypt.RsaVerifier) self.assertIsInstance(verifier._pubkey, rsa.key.PublicKey)
def test_from_string_pkcs8_unicode(self): key_bytes = _helpers._from_bytes(self._load_pkcs8_key_bytes()) signer = crypt.RsaSigner.from_string(key_bytes) self.assertIsInstance(signer, crypt.RsaSigner) self.assertIsInstance(signer._key, rsa.key.PrivateKey)
def test_with_bytes(self): value = b"string-val" decoded_value = u"string-val" self.assertEqual(_from_bytes(value), decoded_value)
def verify_signed_jwt_with_certs(jwt, certs, audience): """Verify a JWT against public certs. See http://self-issued.info/docs/draft-jones-json-web-token.html. Args: jwt: string, A JWT. certs: dict, Dictionary where values of public keys in PEM format. audience: string, The audience, 'aud', that this JWT should contain. If None then the JWT's 'aud' parameter is not verified. Returns: dict, The deserialized JSON payload in the JWT. Raises: AppIdentityError if any checks are failed. """ jwt = _to_bytes(jwt) segments = jwt.split(b'.') if len(segments) != 3: raise AppIdentityError('Wrong number of segments in token: %s' % jwt) signed = segments[0] + b'.' + segments[1] signature = _urlsafe_b64decode(segments[2]) # Parse token. json_body = _urlsafe_b64decode(segments[1]) try: parsed = json.loads(_from_bytes(json_body)) except: raise AppIdentityError('Can\'t parse token: %s' % json_body) # Check signature. verified = False for pem in certs.values(): verifier = Verifier.from_string(pem, True) if verifier.verify(signed, signature): verified = True break if not verified: raise AppIdentityError('Invalid token signature: %s' % jwt) # Check creation timestamp. iat = parsed.get('iat') if iat is None: raise AppIdentityError('No iat field in token: %s' % json_body) earliest = iat - CLOCK_SKEW_SECS # Check expiration timestamp. now = int(time.time()) exp = parsed.get('exp') if exp is None: raise AppIdentityError('No exp field in token: %s' % json_body) if exp >= now + MAX_TOKEN_LIFETIME_SECS: raise AppIdentityError('exp field too far in future: %s' % json_body) latest = exp + CLOCK_SKEW_SECS if now < earliest: raise AppIdentityError('Token used too early, %d < %d: %s' % (now, earliest, json_body)) if now > latest: raise AppIdentityError('Token used too late, %d > %d: %s' % (now, latest, json_body)) # Check audience. if audience is not None: aud = parsed.get('aud') if aud is None: raise AppIdentityError('No aud field in token: %s' % json_body) if aud != audience: raise AppIdentityError('Wrong recipient, %s != %s: %s' % (aud, audience, json_body)) return parsed
def test_from_string_pub_cert_unicode(self): public_cert = _from_bytes(self._load_public_cert_bytes()) verifier = RsaVerifier.from_string(public_cert, is_x509_cert=True) self.assertIsInstance(verifier, RsaVerifier) self.assertIsInstance(verifier._pubkey, rsa.key.PublicKey)
def test_from_string_pkcs1_unicode(self): key_bytes = _helpers._from_bytes(self._load_pkcs1_key_bytes()) signer = crypt.RsaSigner.from_string(key_bytes) self.assertIsInstance(signer, crypt.RsaSigner) self.assertIsInstance(signer._key, rsa.key.PrivateKey)
def test_from_string_pkcs8_unicode(self): key_bytes = _from_bytes(self._load_pkcs8_key_bytes()) signer = RsaSigner.from_string(key_bytes) self.assertIsInstance(signer, RsaSigner) self.assertIsInstance(signer._key, rsa.key.PrivateKey)
def test_with_unicode(self): value = u"bytes-val" self.assertEqual(_from_bytes(value), value)
def test_from_string_pub_key_unicode(self): public_key = _helpers._from_bytes(self._load_public_key_bytes()) verifier = crypt.RsaVerifier.from_string( public_key, is_x509_cert=False) self.assertIsInstance(verifier, crypt.RsaVerifier) self.assertIsInstance(verifier._pubkey, rsa.key.PublicKey)
def from_json(cls, json_data): data = json.loads(_from_bytes(json_data)) return AppAssertionCredentials(data['scope'])
def test_with_nonstring_type(self): value = object() with self.assertRaises(ValueError): _helpers._from_bytes(value)
def test_with_bytes(self): value = b'string-val' decoded_value = u'string-val' self.assertEqual(_helpers._from_bytes(value), decoded_value)
def test_with_unicode(self): value = u'bytes-val' self.assertEqual(_helpers._from_bytes(value), value)
def gconnect(): # Validate state token if request.args.get('state') != login_session['state']: response = make_response(json.dumps('Invalid state parameter.'), 401) response.headers['Content-Type'] = 'application/json' return response # Obtain authorization code code = request.data try: # Upgrade the authorization code into a credentials object oauth_flow = flow_from_clientsecrets('client_secrets.json', scope='') oauth_flow.redirect_uri = 'postmessage' credentials = oauth_flow.step2_exchange(code) except FlowExchangeError: response = make_response( json.dumps('Failed to upgrade the authorization code.'), 401) response.headers['Content-Type'] = 'application/json' return response # Check that the access token is valid. access_token = credentials.access_token url = ('https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=%s' % access_token) h = httplib2.Http() result = json.loads(_helpers._from_bytes(h.request(url, 'GET')[1])) # If there was an error in the access token info, abort. if result.get('error') is not None: response = make_response(json.dumps(result.get('error')), 500) response.headers['Content-Type'] = 'application/json' return response # Verify that the access token is used for the intended user. gplus_id = credentials.id_token['sub'] if result['user_id'] != gplus_id: response = make_response( json.dumps("Token's user ID doesn't match given user ID."), 401) response.headers['Content-Type'] = 'application/json' return response # Verify that the access token is valid for this app. if result['issued_to'] != CLIENT_ID: response = make_response( json.dumps("Token's client ID does not match app's."), 401) print("Token's client ID does not match app's.") response.headers['Content-Type'] = 'application/json' return response stored_access_token = login_session.get('access_token') stored_gplus_id = login_session.get('gplus_id') if stored_access_token is not None and gplus_id == stored_gplus_id: response = make_response( json.dumps('''Current user is already connected.'''), 200) response.headers['Content-Type'] = 'application/json' return response # Store the access token in the session for later use. login_session['access_token'] = credentials.access_token login_session['gplus_id'] = gplus_id # Get user info userinfo_url = "https://www.googleapis.com/oauth2/v1/userinfo" params = {'access_token': credentials.access_token, 'alt': 'json'} answer = requests.get(userinfo_url, params=params) data = answer.json() print(data) login_session['username'] = data['name'] login_session['email'] = data['email'] login_session['picture'] = data['picture'] user_id = getUserID(login_session['email']) if not user_id: user_id = createUser(login_session) login_session['user_id'] = user_id output = '' output += '<img src="' output += login_session['picture'] output += ' " id = "profilePic" />' output += '</br><h1>Welcome, ' output += login_session['username'] output += '!</h1>' flash("you are now logged in as %s" % login_session['username']) print("done!") return output
def test_from_string_pub_key_unicode(self): public_key = _from_bytes(self._load_public_key_bytes()) verifier = RsaVerifier.from_string(public_key, is_x509_cert=False) self.assertIsInstance(verifier, RsaVerifier) self.assertIsInstance(verifier._pubkey, rsa.key.PublicKey)