Source code for ska.utils

__title__ = 'ska.utils'
__author__ = 'Artur Barseghyan'
__copyright__ = 'Copyright (c) 2013-2014 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'
__all__ = ('RequestHelper',)

from six import PY3

try:
    from six.moves.urllib.parse import urlencode
except ImportError as e:
    if PY3:
        from urllib.parse import urlencode
    else:
        from urllib import urlencode

from ska.helpers import (
    dict_keys, extract_signed_data as extract_signed_data
    )
from ska.exceptions import InvalidData, ImproperlyConfigured
from ska.defaults import (
    DEFAULT_URL_SUFFIX, DEFAULT_EXTRA_PARAM, DEFAULT_SIGNATURE_PARAM,
    DEFAULT_AUTH_USER_PARAM, DEFAULT_VALID_UNTIL_PARAM,
    )
from ska.signatures import Signature

_ = lambda x: x # For future integrations with gettext

# *******************************************************************************************************
# *******************************************************************************************************
# **************************************** Request helper ***********************************************
# *******************************************************************************************************
# *******************************************************************************************************

[docs]class RequestHelper(object): """ Request helper for easy put/extract of signature params from URLs. :param str signature_param: :param str auth_user_param: :param str valid_until_param: :param str extra_param: """ def __init__(self, signature_param=DEFAULT_SIGNATURE_PARAM, auth_user_param=DEFAULT_AUTH_USER_PARAM, valid_until_param=DEFAULT_VALID_UNTIL_PARAM, extra_param=DEFAULT_EXTRA_PARAM, signature_cls=Signature): self.signature_param = signature_param self.auth_user_param = auth_user_param self.valid_until_param = valid_until_param self.extra_param = extra_param self.signature_cls = signature_cls
[docs] def signature_to_url(self, signature, endpoint_url='', suffix=DEFAULT_URL_SUFFIX): """ URL encodes the signature params. :param ska.Signature signature: :param str endpoint_url: :param str suffix: Suffix to add after the ``endpoint_url`` and before the appended signature params. :return str: :example: Required imports. >>> from ska import Signature, RequestHelper Generate signature. >>> signature = Signature.generate_signature( >>> auth_user = 'user', >>> secret_key = 'your-secret-key' >>> ) Create a request helper. >>> request_helper = RequestHelper( >>> signature_param = 'signature', >>> auth_user_param = 'auth_user', >>> valid_until_param = 'valid_until' >>> ) Appending signature params to the endpoint URL. >>> url = request_helper.signature_to_url( >>> signature = signature, >>> endpoint_url = 'http://e.com/api/' >>> ) http://e.com/api/?valid_until=1378045287.0&auth_user=user&signature=YlZpLFsjUKBalL4x5trhkeEgqE8%3D """ params = { self.signature_param: signature.signature, self.auth_user_param: signature.auth_user, self.valid_until_param: signature.valid_until, self.extra_param: dict_keys(signature.extra, return_string=True), } # Make some check that params used do not overlap with names reserved (`auth_user`, `signature`, etc). params.update(signature.extra) return "{0}{1}{2}".format(endpoint_url, suffix, urlencode(params))
[docs] def signature_to_dict(self, signature): """ Puts signature into a dictionary, which can later on be used to send when sending (POST) requests to the server. :param ska.Signature signature: :return dict: :example: Required imports. >>> from ska import Signature, RequestHelper Generate signature. >>> signature = Signature.generate_signature( >>> auth_user = 'user', >>> secret_key = 'your-secret-key' >>> ) Create a request helper. >>> request_helper = RequestHelper( >>> signature_param = 'signature', >>> auth_user_param = 'auth_user', >>> valid_until_param = 'valid_until' >>> ) Appending signature params to the endpoint URL. >>> signed_dict = request_helper.signature_to_dict( >>> signature = signature >>> ) { 'signature': 'YlZpLFsjUKBalL4x5trhkeEgqE8=', 'auth_user': 'user', 'valid_until': '1378045287.0' } """ d = { self.signature_param: signature.signature, self.auth_user_param: signature.auth_user, self.valid_until_param: signature.valid_until, self.extra_param: dict_keys(signature.extra, return_string=True), } d.update(signature.extra) return d
[docs] def validate_request_data(self, data, secret_key): """ Validates the request data. :param dict data: :param str secret_key: :return ska.SignatureValidationResult: :example: If your imaginary ``HttpRequest`` object has ``GET`` property (dict), then you would validate the request data as follows. Create a ``RequestHelper`` object with param names expected. Required imports. >>> from ska import RequestHelper Create a request helper. >>> request_helper = RequestHelper( >>> signature_param = 'signature', >>> auth_user_param = 'auth_user', >>> valid_until_param = 'valid_until' >>> ) Validate the request data. >>> validation_result = request_helper.validate_request_data( >>> data = request.GET, >>> secret_key = 'your-secret-key' >>> ) """ signature = data.get(self.signature_param, '') auth_user = data.get(self.auth_user_param, '') valid_until = data.get(self.valid_until_param, '') extra = extract_signed_data(data=data, extra=data.get(self.extra_param, '').split(',')) validation_result = self.signature_cls.validate_signature( signature = signature, auth_user = auth_user, secret_key = secret_key, valid_until = valid_until, return_object = True, extra = extra ) return validation_result
[docs] def extract_signed_data(self, data, secret_key=None, validate=False, fail_silently=False): """ Extracts signed data from the request. """ if validate: if not secret_key: if fail_silently: return {} raise ImproperlyConfigured("You should provide `secret_key` if `validate` is set to True.") validation_result = self.validate_request_data(data, secret_key) if not validation_result.result: if fail_silently: return {} raise InvalidData(validation_result.message) return extract_signed_data(data=data, extra=data.get(self.extra_param, '').split(','))