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()))
Example #2
0
 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()))
Example #3
0
 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)))
Example #4
0
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))
Example #5
0
    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)
Example #6
0
    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))
Example #7
0
    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))
Example #8
0
    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)
Example #9
0
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
Example #12
0
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)
Example #14
0
    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))
Example #15
0
File: gce.py Project: BUBA363/GAM
    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)
Example #16
0
    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)))
Example #20
0
    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)
Example #21
0
 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)))
Example #22
0
    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)
Example #28
0
    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)
Example #29
0
    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
Example #30
0
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()
Example #32
0
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
Example #34
0
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()
Example #35
0
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
Example #37
0
 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)
Example #41
0
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)
Example #43
0
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_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)
Example #48
0
 def from_json(cls, json_data):
     data = json.loads(_from_bytes(json_data))
     return AppAssertionCredentials(data['scope'])
Example #49
0
 def test_with_nonstring_type(self):
     value = object()
     with self.assertRaises(ValueError):
         _helpers._from_bytes(value)
Example #50
0
 def test_with_bytes(self):
     value = b'string-val'
     decoded_value = u'string-val'
     self.assertEqual(_helpers._from_bytes(value), decoded_value)
Example #51
0
 def test_with_unicode(self):
     value = u'bytes-val'
     self.assertEqual(_helpers._from_bytes(value), value)
Example #52
0
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
Example #53
0
File: gce.py Project: BUBA363/GAM
 def from_json(cls, json_data):
     data = json.loads(_from_bytes(json_data))
     return AppAssertionCredentials(data['scope'])
Example #54
0
 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)