コード例 #1
0
ファイル: auth.py プロジェクト: jdavid/ably-python
    def create_token_request(self,
                             token_params=None,
                             key_name=None,
                             key_secret=None,
                             query_time=None):
        token_params = token_params or {}
        token_request = {}

        key_name = key_name or self.auth_options.key_name
        key_secret = key_secret or self.auth_options.key_secret
        if not key_name or not key_secret:
            log.debug('key_name or key_secret blank')
            raise AblyException(
                "No key specified: no means to generate a token", 401, 40101)

        token_request['key_name'] = key_name
        if token_params.get('timestamp'):
            token_request['timestamp'] = token_params['timestamp']
        else:
            if query_time is None:
                query_time = self.auth_options.query_time
            if query_time:
                token_request['timestamp'] = self.ably.time()
            else:
                token_request['timestamp'] = self._timestamp()

        token_request['timestamp'] = int(token_request['timestamp'])

        ttl = token_params.get('ttl')
        if ttl is not None:
            if isinstance(ttl, timedelta):
                ttl = ttl.total_seconds() * 1000
            token_request['ttl'] = int(ttl)

        capability = token_params.get('capability')
        if capability is not None:
            token_request['capability'] = six.text_type(Capability(capability))

        token_request["client_id"] = (token_params.get('client_id')
                                      or self.client_id)

        # Note: There is no expectation that the client
        # specifies the nonce; this is done by the library
        # However, this can be overridden by the client
        # simply for testing purposes
        token_request["nonce"] = token_params.get(
            'nonce') or self._random_nonce()

        token_request = TokenRequest(**token_request)

        if token_params.get('mac') is None:
            # Note: There is no expectation that the client
            # specifies the mac; this is done by the library
            # However, this can be overridden by the client
            # simply for testing purposes.
            token_request.sign_request(key_secret.encode('utf8'))
        else:
            token_request.mac = token_params['mac']

        return token_request
コード例 #2
0
ファイル: http.py プロジェクト: abordeau/ably-python
    def make_request(self, method, path, headers=None, body=None,
                     skip_auth=False, timeout=None, raise_on_error=True):

        if body is not None and type(body) not in (bytes, str):
            body = self.dump_body(body)

        if body:
            all_headers = HttpUtils.default_post_headers(
                self.options.use_binary_protocol, self.__ably.variant)
        else:
            all_headers = HttpUtils.default_get_headers(
                self.options.use_binary_protocol, self.__ably.variant)

        if not skip_auth:
            if self.auth.auth_mechanism == Auth.Method.BASIC and self.preferred_scheme.lower() == 'http':
                raise AblyException(
                    "Cannot use Basic Auth over non-TLS connections",
                    401,
                    40103)
            all_headers.update(self.auth._get_auth_headers())
        if headers:
            all_headers.update(headers)

        timeout = (self.http_open_timeout, self.http_request_timeout)
        http_max_retry_duration = self.http_max_retry_duration
        requested_at = time.time()

        hosts = self.get_rest_hosts()
        for retry_count, host in enumerate(hosts):
            base_url = "%s://%s:%d" % (self.preferred_scheme,
                                       host,
                                       self.preferred_port)
            url = urljoin(base_url, path)
            request = requests.Request(method, url, data=body, headers=all_headers)
            prepped = self.__session.prepare_request(request)
            try:
                response = self.__session.send(prepped, timeout=timeout)
            except Exception as e:
                # Need to catch `Exception`, see:
                # https://github.com/kennethreitz/requests/issues/1236#issuecomment-133312626

                # if last try or cumulative timeout is done, throw exception up
                time_passed = time.time() - requested_at
                if retry_count == len(hosts) - 1 or \
                   time_passed > http_max_retry_duration:
                    raise e
            else:
                try:
                    if raise_on_error:
                        AblyException.raise_for_response(response)

                    # Keep fallback host for later (RSC15f)
                    if retry_count > 0 and host != self.options.get_rest_host():
                        self.__host = host
                        self.__host_expires = time.time() + (self.options.fallback_retry_timeout / 1000.0)

                    return Response(response)
                except AblyException as e:
                    if not e.is_server_error:
                        raise e
コード例 #3
0
 def parse_key(self, key):
     try:
         key_name, key_secret = key.split(':')
         return key_name, key_secret
     except ValueError:
         raise AblyException("key of not len 2 parameters: {0}"
                             .format(key.split(':')),
                             401, 40101)
コード例 #4
0
    def __unpad(self, data):
        padding_size = six.indexbytes(data, -1)

        if padding_size > len(data):
            # Too short
            raise AblyException('invalid-padding', 0, 0)

        if padding_size == 0:
            # Missing padding
            raise AblyException('invalid-padding', 0, 0)

        for i in range(padding_size):
            # Invalid padding bytes
            if padding_size != six.indexbytes(data, -i - 1):
                raise AblyException('invalid-padding', 0, 0)

        return data[:-padding_size]
コード例 #5
0
def get_cipher(cipher_params):
    if cipher_params is None:
        params = get_default_params()
    elif isinstance(cipher_params, CipherParams):
        params = cipher_params
    else:
        raise AblyException("ChannelOptions not supported", 400, 40000)
    return CbcChannelCipher(params)
コード例 #6
0
    def as_dict(self, binary=False):
        data = self.data
        data_type = None
        encoding = self._encoding_array[:]

        if isinstance(data, dict) or isinstance(data, list):
            encoding.append('json')
            data = json.dumps(data)
        elif isinstance(data, six.text_type) and not binary:
            # text_type is always a unicode string
            pass
        elif (not binary and isinstance(data, bytearray) or
              # bytearray is always bytes
              isinstance(data, six.binary_type) and six.binary_type != str):
            # in py3k we will understand <class 'bytes'> as bytes
            data = base64.b64encode(data).decode('ascii')
            encoding.append('base64')
        elif isinstance(data, CipherData):
            encoding.append(data.encoding_str)
            data_type = data.type
            if not binary:
                data = base64.b64encode(data.buffer).decode('ascii')
                encoding.append('base64')
            else:
                data = data.buffer
        elif binary and isinstance(data, bytearray):
            data = six.binary_type(data)

        if not (isinstance(data, (six.binary_type, six.text_type, list, dict,
                                  bytearray)) or data is None):
            raise AblyException("Invalid data payload", 400, 40011)

        request_body = {
            'name': self.name,
            'data': data,
            'timestamp': self.timestamp or int(time.time() * 1000.0),
        }
        request_body = {
            k: v
            for (k, v) in request_body.items() if v is not None
        }  # None values aren't included

        if encoding:
            request_body['encoding'] = '/'.join(encoding).strip('/')

        if data_type:
            request_body['type'] = data_type

        if self.client_id:
            request_body['clientId'] = self.client_id

        if self.id:
            request_body['id'] = self.id

        if self.connection_id:
            request_body['connectionId'] = self.connection_id

        return request_body
コード例 #7
0
ファイル: authoptions.py プロジェクト: jdavid/ably-python
    def set_key(self, key):
        if key is None:
            return

        try:
            key_name, key_secret = key.split(':')
            self.auth_options['key_name'] = key_name
            self.auth_options['key_secret'] = key_secret
        except ValueError:
            raise AblyException(
                "key of not len 2 parameters: {0}".format(key.split(':')), 401,
                40101)
コード例 #8
0
    def as_dict(self, binary=False):
        data = self.data
        data_type = None
        encoding = self._encoding_array[:]

        if isinstance(data, (dict, list)):
            encoding.append('json')
            data = json.dumps(data)
            data = str(data)
        elif isinstance(data, str) and not binary:
            pass
        elif not binary and isinstance(data, (bytearray, bytes)):
            data = base64.b64encode(data).decode('ascii')
            encoding.append('base64')
        elif isinstance(data, CipherData):
            encoding.append(data.encoding_str)
            data_type = data.type
            if not binary:
                data = base64.b64encode(data.buffer).decode('ascii')
                encoding.append('base64')
            else:
                data = data.buffer
        elif binary and isinstance(data, bytearray):
            data = bytes(data)

        if not (isinstance(data, (bytes, str, list, dict, bytearray))
                or data is None):
            raise AblyException("Invalid data payload", 400, 40011)

        request_body = {
            'name': self.name,
            'data': data,
            'timestamp': self.timestamp or None,
            'type': data_type or None,
            'clientId': self.client_id or None,
            'id': self.id or None,
            'connectionId': self.connection_id or None,
            'connectionKey': self.connection_key or None,
            'extras': self.extras,
        }

        if encoding:
            request_body['encoding'] = '/'.join(encoding).strip('/')

        # None values aren't included
        request_body = {k: v for k, v in request_body.items() if v is not None}

        return request_body
コード例 #9
0
 def raise_ably_exception(*args, **kwargs):
     raise AblyException(message="", status_code=500, code=50000)
コード例 #10
0
ファイル: message.py プロジェクト: jdavid/ably-python
    def as_dict(self, binary=False):
        data = self.data
        data_type = None
        encoding = self._encoding_array[:]

        if isinstance(data, six.binary_type) and six.binary_type == str:
            # If using python 2, assume str payloads are intended as strings
            # if they decode to unicode. If it doesn't, treat as a binary
            try:
                data = six.text_type(data)
            except UnicodeDecodeError:
                pass

        if isinstance(data, dict) or isinstance(data, list):
            encoding.append('json')
            data = json.dumps(data)
            data = six.text_type(data)
        elif isinstance(data, six.text_type) and not binary:
            # text_type is always a unicode string
            pass
        elif (not binary and (isinstance(data, bytearray) or
                              # bytearray is always bytes
                              isinstance(data, six.binary_type))):
            # at this point binary_type is either a py3k bytes or a py2
            # str that failed to decode to unicode
            data = base64.b64encode(data).decode('ascii')
            encoding.append('base64')
        elif isinstance(data, CipherData):
            encoding.append(data.encoding_str)
            data_type = data.type
            if not binary:
                data = base64.b64encode(data.buffer).decode('ascii')
                encoding.append('base64')
            else:
                data = data.buffer
        elif binary and isinstance(data, bytearray):
            data = six.binary_type(data)

        if not (isinstance(data, (six.binary_type, six.text_type, list, dict,
                                  bytearray)) or data is None):
            raise AblyException("Invalid data payload", 400, 40011)

        request_body = {
            u'name': self.name,
            u'data': data,
            u'timestamp': self.timestamp or int(time.time() * 1000.0),
        }
        request_body = {
            k: v
            for (k, v) in request_body.items() if v is not None
        }  # None values aren't included

        if encoding:
            request_body[u'encoding'] = u'/'.join(encoding).strip(u'/')

        if data_type:
            request_body[u'type'] = data_type

        if self.client_id:
            request_body[u'clientId'] = self.client_id

        if self.id:
            request_body[u'id'] = self.id

        if self.connection_id:
            request_body[u'connectionId'] = self.connection_id

        if self.connection_key:
            request_body['connectionKey'] = self.connection_key

        if self.extras:
            request_body['extras'] = self.extras

        return request_body
コード例 #11
0
ファイル: http.py プロジェクト: vintasoftware/ably-python
    def make_request(self, method, path, headers=None, body=None,
                     native_data=None, skip_auth=False, timeout=None):
        fallback_hosts = Defaults.get_fallback_rest_hosts(self.__options)
        if fallback_hosts:
            fallback_hosts.insert(0, self.preferred_host)
            fallback_hosts = itertools.cycle(fallback_hosts)
        if native_data is not None and body is not None:
            raise ValueError("make_request takes either body or native_data")
        elif native_data is not None:
            body = self.dump_body(native_data)
        if body:
            all_headers = HttpUtils.default_post_headers(
                self.options.use_binary_protocol)
        else:
            all_headers = HttpUtils.default_get_headers(
                self.options.use_binary_protocol)

        if not skip_auth:
            if self.auth.auth_mechanism == Auth.Method.BASIC and self.preferred_scheme.lower() == 'http':
                raise AblyException(
                    "Cannot use Basic Auth over non-TLS connections",
                    401,
                    40103)
            all_headers.update(self.auth._get_auth_headers())
        if headers:
            all_headers.update(headers)

        http_open_timeout = self.http_open_timeout
        http_request_timeout = self.http_request_timeout
        if fallback_hosts:
            http_max_retry_count = self.http_max_retry_count
        else:
            http_max_retry_count = 1
        http_max_retry_duration = self.http_max_retry_duration
        requested_at = time.time()
        for retry_count in range(http_max_retry_count):
            host = next(fallback_hosts) if fallback_hosts else self.preferred_host
            if self.options.environment:
                host = self.options.environment + '-' + host

            base_url = "%s://%s:%d" % (self.preferred_scheme,
                                       host,
                                       self.preferred_port)
            url = urljoin(base_url, path)
            request = requests.Request(method, url, data=body, headers=all_headers)
            prepped = self.__session.prepare_request(request)
            try:
                response = self.__session.send(
                    prepped,
                    timeout=(http_open_timeout,
                             http_request_timeout))
            except Exception as e:
                # Need to catch `Exception`, see:
                # https://github.com/kennethreitz/requests/issues/1236#issuecomment-133312626

                # if last try or cumulative timeout is done, throw exception up
                time_passed = time.time() - requested_at
                if retry_count == http_max_retry_count - 1 or \
                   time_passed > http_max_retry_duration:
                    raise e
            else:
                try:
                    AblyException.raise_for_response(response)
                    return Response(response)
                except AblyException as e:
                    if not e.is_server_error:
                        raise e
コード例 #12
0
ファイル: http.py プロジェクト: ably/ably-python
    async def make_request(self,
                           method,
                           path,
                           headers=None,
                           body=None,
                           skip_auth=False,
                           timeout=None,
                           raise_on_error=True):

        if body is not None and type(body) not in (bytes, str):
            body = self.dump_body(body)

        if body:
            all_headers = HttpUtils.default_post_headers(
                self.options.use_binary_protocol)
        else:
            all_headers = HttpUtils.default_get_headers(
                self.options.use_binary_protocol)

        if not skip_auth:
            if self.auth.auth_mechanism == Auth.Method.BASIC and self.preferred_scheme.lower(
            ) == 'http':
                raise AblyException(
                    "Cannot use Basic Auth over non-TLS connections", 401,
                    40103)
            auth_headers = await self.auth._get_auth_headers()
            all_headers.update(auth_headers)
        if headers:
            all_headers.update(headers)

        timeout = (self.http_open_timeout, self.http_request_timeout)
        http_max_retry_duration = self.http_max_retry_duration
        requested_at = time.time()

        hosts = self.get_rest_hosts()
        for retry_count, host in enumerate(hosts):
            base_url = "%s://%s:%d" % (self.preferred_scheme, host,
                                       self.preferred_port)
            url = urljoin(base_url, path)

            request = self.__client.build_request(
                method=method,
                url=url,
                content=body,
                headers=all_headers,
                timeout=timeout,
            )
            try:
                response = await self.__client.send(request)
            except Exception as e:
                # if last try or cumulative timeout is done, throw exception up
                time_passed = time.time() - requested_at
                if retry_count == len(
                        hosts) - 1 or time_passed > http_max_retry_duration:
                    raise e
            else:
                try:
                    if raise_on_error:
                        AblyException.raise_for_response(response)

                    # Keep fallback host for later (RSC15f)
                    if retry_count > 0 and host != self.options.get_rest_host(
                    ):
                        self.__host = host
                        self.__host_expires = time.time() + (
                            self.options.fallback_retry_timeout / 1000.0)

                    return Response(response)
                except AblyException as e:
                    if not e.is_server_error:
                        raise e

                    # if last try or cumulative timeout is done, throw exception up
                    time_passed = time.time() - requested_at
                    if retry_count == len(
                            hosts
                    ) - 1 or time_passed > http_max_retry_duration:
                        raise e