Exemple #1
0
async def test_event_hubs_send_override_token_refresh_window(
        live_eventhub_config):
    uri = "sb://{}/{}".format(live_eventhub_config['hostname'],
                              live_eventhub_config['event_hub'])
    target = "amqps://{}/{}/Partitions/0".format(
        live_eventhub_config['hostname'], live_eventhub_config['event_hub'])
    token = None

    async def get_token():
        nonlocal token
        return _AccessToken(token, expiry)

    jwt_auth = authentication.JWTTokenAsync(
        uri,
        uri,
        get_token,
        refresh_window=300  # set refresh window to be 5 mins
    )

    send_client = uamqp.SendClientAsync(target, auth=jwt_auth, debug=False)

    # use token of which the valid remaining time < refresh window
    expiry = int(time.time()) + (60 * 4 + 30)  # 4.5 minutes
    token = utils.create_sas_token(live_eventhub_config['key_name'].encode(),
                                   live_eventhub_config['access_key'].encode(),
                                   uri.encode(),
                                   expiry=timedelta(minutes=4, seconds=30))

    for _ in range(3):
        message = uamqp.message.Message(body='Hello World')
        await send_client.send_message_async(message)

    auth_status = constants.CBSAuthStatus(jwt_auth._cbs_auth.get_status())
    assert auth_status == constants.CBSAuthStatus.RefreshRequired

    # update token, the valid remaining time > refresh window
    expiry = int(time.time()) + (60 * 5 + 30)  # 5.5 minutes
    token = utils.create_sas_token(live_eventhub_config['key_name'].encode(),
                                   live_eventhub_config['access_key'].encode(),
                                   uri.encode(),
                                   expiry=timedelta(minutes=5, seconds=30))

    for _ in range(3):
        message = uamqp.message.Message(body='Hello World')
        await send_client.send_message_async(message)

    auth_status = constants.CBSAuthStatus(jwt_auth._cbs_auth.get_status())
    assert auth_status == constants.CBSAuthStatus.Ok
    await send_client.close_async()
Exemple #2
0
    def from_shared_access_key(
            cls,
            uri,
            key_name,
            shared_access_key,
            expiry=None,
            port=constants.DEFAULT_AMQPS_PORT,
            timeout=10,
            retry_policy=TokenRetryPolicy(),
            verify=None,
            encoding='UTF-8'):
        """Attempt to create a CBS token session using a Shared Access Key such
        as is used to connect to Azure services.

        :param uri: The AMQP endpoint URI. This must be provided as
        a decoded string.
        :type uri: str
        :param key_name: The SAS token username, also referred to as the key
        name or policy name.
        :type key_name: str
        :param shared_access_key: The SAS token password, also referred to as the key.
        :type shared_access_key: str
        :param expiry: The lifetime in seconds for the generated token. Default is 1 hour.
        :type expiry: int
        :param port: The TLS port - default for AMQP is 5671.
        :type port: int
        :param timeout: The timeout in seconds in which to negotiate the token.
         The default value is 10 seconds.
        :type timeout: int
        :param retry_policy: The retry policy for the PUT token request. The default
        retry policy has 3 retries.
        :type retry_policy: ~uamqp.authentication.TokenRetryPolicy
        :param verify: The path to a user-defined certificate.
        :type verify: str
        :param encoding: The encoding to use if hostname is provided as a str.
        Default is 'UTF-8'.
        :type encoding: str
        """
        expires_in = datetime.timedelta(seconds=expiry or constants.AUTH_EXPIRATION_SECS)
        encoded_uri = urllib_parse.quote_plus(uri).encode(encoding)  # pylint: disable=no-member
        encoded_key = urllib_parse.quote_plus(key_name).encode(encoding)  # pylint: disable=no-member
        expires_at = time.time() + expires_in.seconds
        token = utils.create_sas_token(
            encoded_key,
            shared_access_key.encode(encoding),
            encoded_uri,
            expires_in)
        return cls(
            uri, uri, token,
            expires_in=expires_in,
            expires_at=expires_at,
            username=key_name,
            password=shared_access_key,
            port=port,
            timeout=timeout,
            retry_policy=retry_policy,
            verify=verify,
            encoding=encoding)
Exemple #3
0
 def update_token(self):
     """If a username and password are present - attempt to use them to
     request a fresh SAS token.
     """
     if not self.username or not self.password:
         raise errors.TokenExpired(
             "Unable to refresh token - no username or password.")
     encoded_uri = compat.quote_plus(self.uri).encode(self._encoding)  # pylint: disable=no-member
     encoded_key = compat.quote_plus(self.username).encode(self._encoding)  # pylint: disable=no-member
     self.expires_at = time.time() + self.expires_in.seconds
     self.token = utils.create_sas_token(
         encoded_key, self.password.encode(self._encoding), encoded_uri,
         self.expires_in)
Exemple #4
0
def _generate_sas_token(uri, policy, key, expiry=None):
    # type: (str, str, str, Optional[timedelta]) -> _AccessToken
    """Create a shared access signiture token as a string literal.
    :returns: SAS token as string literal.
    :rtype: str
    """
    if not expiry:
        expiry = timedelta(hours=1)  # Default to 1 hour.

    abs_expiry = int(time.time()) + expiry.seconds
    encoded_uri = quote_plus(uri).encode("utf-8")  # pylint: disable=no-member
    encoded_policy = quote_plus(policy).encode("utf-8")  # pylint: disable=no-member
    encoded_key = key.encode("utf-8")

    token = utils.create_sas_token(encoded_policy, encoded_key, encoded_uri, expiry)
    return _AccessToken(token=token, expires_on=abs_expiry)
    def from_shared_access_key(cls,
                               uri,
                               key_name,
                               shared_access_key,
                               expiry=None,
                               port=constants.DEFAULT_AMQPS_PORT,
                               timeout=10,
                               retry_policy=TokenRetryPolicy(),
                               verify=None,
                               http_proxy=None,
                               transport_type=TransportType.Amqp,
                               encoding='UTF-8'):
        """Attempt to create a CBS token session using a Shared Access Key such
        as is used to connect to Azure services.

        :param uri: The AMQP endpoint URI. This must be provided as
         a decoded string.
        :type uri: str
        :param key_name: The SAS token username, also referred to as the key
         name or policy name.
        :type key_name: str
        :param shared_access_key: The SAS token password, also referred to as the key.
        :type shared_access_key: str
        :param expiry: The lifetime in seconds for the generated token. Default is 1 hour.
        :type expiry: int
        :param port: The TLS port - default for AMQP is 5671.
        :type port: int
        :param timeout: The timeout in seconds in which to negotiate the token.
         The default value is 10 seconds.
        :type timeout: float
        :param retry_policy: The retry policy for the PUT token request. The default
         retry policy has 3 retries.
        :type retry_policy: ~uamqp.authentication.cbs_auth.TokenRetryPolicy
        :param verify: The path to a user-defined certificate.
        :type verify: str
        :param http_proxy: HTTP proxy configuration. This should be a dictionary with
         the following keys present: 'proxy_hostname' and 'proxy_port'. Additional optional
         keys are 'username' and 'password'.
        :type http_proxy: dict
        :param transport_type: The transport protocol type - default is ~uamqp.TransportType.Amqp.
         ~uamqp.TransportType.AmqpOverWebsocket is applied when http_proxy is set or the
         transport type is explicitly requested.
        :type transport_type: ~uamqp.TransportType
        :param encoding: The encoding to use if hostname is provided as a str.
         Default is 'UTF-8'.
        :type encoding: str
        """
        expires_in = datetime.timedelta(
            seconds=expiry or constants.AUTH_EXPIRATION_SECS)
        encoded_uri = compat.quote_plus(uri).encode(encoding)  # pylint: disable=no-member
        encoded_key = compat.quote_plus(key_name).encode(encoding)  # pylint: disable=no-member
        expires_at = time.time() + expires_in.seconds
        token = utils.create_sas_token(encoded_key,
                                       shared_access_key.encode(encoding),
                                       encoded_uri, expires_in)
        return cls(uri,
                   uri,
                   token,
                   expires_in=expires_in,
                   expires_at=expires_at,
                   username=key_name,
                   password=shared_access_key,
                   port=port,
                   timeout=timeout,
                   retry_policy=retry_policy,
                   verify=verify,
                   http_proxy=http_proxy,
                   transport_type=transport_type,
                   encoding=encoding)