Esempio n. 1
0
def parse_ticket(secret, ticket, ip):
    """
    Parse the ticket, returning (timestamp, userid, tokens, user_data).

    If the ticket cannot be parsed, a ``BadTicket`` exception will be raised
    with an explanation.
    """
    ticket = ticket.strip('"')
    digest = ticket[:32]
    try:
        timestamp = int(ticket[32:40], 16)
    except ValueError as e:
        raise BadTicket('Timestamp is not a hex integer: %s' % e)
    try:
        userid, data = ticket[40:].split('!', 1)
    except ValueError:
        raise BadTicket('userid is not followed by !')
    userid = url_unquote(userid)
    if '!' in data:
        tokens, user_data = data.split('!', 1)
    else: # pragma: no cover (never generated)
        # @@: Is this the right order?
        tokens = ''
        user_data = data

    expected = calculate_digest(ip, timestamp, secret,
                                userid, tokens, user_data)

    if expected != digest:
        raise BadTicket('Digest signature is not correct',
                        expected=(expected, digest))

    tokens = tokens.split(',')

    return (timestamp, userid, tokens, user_data)
Esempio n. 2
0
    def resource_to_url(self, resource, quote=False):
        """
        Returns the URL for the given resource.

        :param resource: Resource to create a URL for.
        :param bool quote: If set, the URL returned will be quoted.
        :raises ValueError: If the given resource is floating (i.e., has
          the parent attribute set to `None`)
        """
        ifc = provided_by(resource)
        if not IResource in ifc:
            raise TypeError('Can not generate URL for non-resource "%s".' %
                            resource)
        elif resource.__parent__ is None:
            raise ValueError('Can not generate URL for floating resource '
                             '"%s".' % resource)
        if ICollectionResource in ifc:
            query = {}
            if not resource.filter is None:
                query['q'] = \
                    UrlPartsConverter.make_filter_string(resource.filter)
            if not resource.order is None:
                query['sort'] = \
                    UrlPartsConverter.make_order_string(resource.order)
            if not resource.slice is None:
                query['start'], query['size'] = \
                    UrlPartsConverter.make_slice_strings(resource.slice)
            if query != {}:
                options = dict(query=query)
            else:
                options = dict()
            if not resource.is_root_collection:
                # For nested collections, we check if the referenced root
                # collection is exposed (i.e., has the service as parent).
                # If yes, we return an absolute URL, else a nested URL.
                root_coll = get_root_collection(resource)
                if not root_coll.has_parent:
                    url = self.__request.resource_url(resource)
                else:
                    url = self.__request.resource_url(root_coll, **options)
            else:
                url = self.__request.resource_url(resource, **options)
        else:
            if not resource.is_root_member:
                # For nested members, we check if the referenced root
                # collection is exposed (i.e., has the service as parent).
                # If yes, we return an absolute URL, else a nested URL.
                root_coll = get_root_collection(resource)
                if not root_coll.has_parent:
                    url = self.__request.resource_url(resource)
                else:
                    par_url = self.__request.resource_url(root_coll)
                    url = "%s%s/" % (par_url, resource.__name__)
            else:
                url = self.__request.resource_url(resource)
        if not quote:
            url = url_unquote(url)
        return url
Esempio n. 3
0
File: url.py Progetto: b8va/everest
    def resource_to_url(self, resource, quote=False):
        """
        Returns the URL for the given resource.

        :param resource: Resource to create a URL for.
        :param bool quote: If set, the URL returned will be quoted.
        :raises ValueError: If the given resource is floating (i.e., has
          the parent attribute set to `None`)
        """
        ifc = provided_by(resource)
        if not IResource in ifc:
            raise TypeError('Can not generate URL for non-resource "%s".'
                            % resource)
        elif resource.__parent__ is None:
            raise ValueError('Can not generate URL for floating resource '
                             '"%s".' % resource)
        if ICollectionResource in ifc:
            query = {}
            if not resource.filter is None:
                query['q'] = \
                    UrlPartsConverter.make_filter_string(resource.filter)
            if not resource.order is None:
                query['sort'] = \
                    UrlPartsConverter.make_order_string(resource.order)
            if not resource.slice is None:
                query['start'], query['size'] = \
                    UrlPartsConverter.make_slice_strings(resource.slice)
            if query != {}:
                options = dict(query=query)
            else:
                options = dict()
            if not resource.is_root_collection:
                # For nested collections, we check if the referenced root
                # collection is exposed (i.e., has the service as parent).
                # If yes, we return an absolute URL, else a nested URL.
                root_coll = get_root_collection(resource)
                if not root_coll.has_parent:
                    url = self.__request.resource_url(resource, **options)
                else:
                    url = self.__request.resource_url(root_coll, **options)
            else:
                url = self.__request.resource_url(resource, **options)
        else:
            if not resource.is_root_member:
                # For nested members, we check if the referenced root
                # collection is exposed (i.e., has the service as parent).
                # If yes, we return an absolute URL, else a nested URL.
                root_coll = get_root_collection(resource)
                if not root_coll.has_parent:
                    par_url = self.__request.resource_url(resource)
                else:
                    par_url = self.__request.resource_url(root_coll)
                url = "%s%s/" % (par_url, resource.__name__)
            else:
                url = self.__request.resource_url(resource)
        if not quote:
            url = url_unquote(url)
        return url
Esempio n. 4
0
def parse_ticket(secret, ticket, ip, hashalg='md5'):
    """
    Parse the ticket, returning (timestamp, userid, tokens, user_data).

    If the ticket cannot be parsed, a ``BadTicket`` exception will be raised
    with an explanation.
    """
    ticket = native_(ticket).strip('"')
    digest_size = hashlib.new(hashalg).digest_size * 2
    digest = ticket[:digest_size]
    try:
        timestamp = int(ticket[digest_size:digest_size + 8], 16)
    except ValueError as e:
        raise BadTicket('Timestamp is not a hex integer: %s' % e)
    try:
        userid, data = ticket[digest_size + 8:].split('!', 1)
    except ValueError:
        raise BadTicket('userid is not followed by !')
    userid = url_unquote(userid)
    if '!' in data:
        tokens, user_data = data.split('!', 1)
    else: # pragma: no cover (never generated)
        # @@: Is this the right order?
        tokens = ''
        user_data = data

    expected = calculate_digest(ip, timestamp, secret,
                                userid, tokens, user_data, hashalg)

    # Avoid timing attacks (see
    # http://seb.dbzteam.org/crypto/python-oauth-timing-hmac.pdf)
    if strings_differ(expected, digest):
        raise BadTicket('Digest signature is not correct',
                        expected=(expected, digest))

    tokens = tokens.split(',')

    return (timestamp, userid, tokens, user_data)
Esempio n. 5
0
    def run(self):
        if not len(self.args) >= 2:
            self.out('You must provide at least two arguments')
            return 2
        app_spec = self.args[0]
        path = self.args[1]
        if not path.startswith('/'):
            path = '/' + path

        try:
            path, qs = path.split('?', 1)
        except ValueError:
            qs = ''

        path = url_unquote(path)

        headers = {}
        if self.options.headers:
            for item in self.options.headers:
                if ':' not in item:
                    self.out(
                        "Bad --header=%s option, value must be in the form "
                        "'name:value'" % item)
                    return 2
                name, value = item.split(':', 1)
                headers[name] = value.strip()

        app = self.get_app(app_spec,
                           self.options.app_name,
                           options=parse_vars(self.args[2:]))

        request_method = (self.options.method or 'GET').upper()

        environ = {
            'REQUEST_METHOD': request_method,
            'SCRIPT_NAME': '',  # may be empty if app is at the root
            'PATH_INFO': path,
            'SERVER_NAME': 'localhost',  # always mandatory
            'SERVER_PORT': '80',  # always mandatory 
            'SERVER_PROTOCOL': 'HTTP/1.0',
            'CONTENT_TYPE': 'text/plain',
            'REMOTE_ADDR': '127.0.0.1',
            'wsgi.run_once': True,
            'wsgi.multithread': False,
            'wsgi.multiprocess': False,
            'wsgi.errors': sys.stderr,
            'wsgi.url_scheme': 'http',
            'wsgi.version': (1, 0),
            'QUERY_STRING': qs,
            'HTTP_ACCEPT': 'text/plain;q=1.0, */*;q=0.1',
            'paste.command_request': True,
        }

        if request_method == 'POST':
            environ['wsgi.input'] = self.stdin
            environ['CONTENT_LENGTH'] = '-1'

        for name, value in headers.items():
            if name.lower() == 'content-type':
                name = 'CONTENT_TYPE'
            else:
                name = 'HTTP_' + name.upper().replace('-', '_')
            environ[name] = value

        request = Request.blank(path, environ=environ)
        response = request.get_response(app)
        if self.options.display_headers:
            self.out(response.status)
            for name, value in response.headerlist:
                self.out('%s: %s' % (name, value))
        if response.charset:
            self.out(response.ubody)
        else:
            self.out(response.body)
        return 0
Esempio n. 6
0
    def run(self):
        if not self.args.config_uri or not self.args.path_info:
            self.out('You must provide at least two arguments')
            return 2
        app_spec = self.args.config_uri
        path = self.args.path_info

        self.configure_logging(app_spec)

        if not path.startswith('/'):
            path = '/' + path

        try:
            path, qs = path.split('?', 1)
        except ValueError:
            qs = ''

        path = url_unquote(path)

        headers = {}
        if self.args.login:
            enc = base64.b64encode(self.args.login.encode('ascii'))
            headers['Authorization'] = 'Basic ' + enc.decode('ascii')

        if self.args.headers:
            for item in self.args.headers:
                if ':' not in item:
                    self.out(
                        "Bad --header=%s option, value must be in the form "
                        "'name:value'" % item)
                    return 2
                name, value = item.split(':', 1)
                headers[name] = value.strip()

        app = self.get_app(app_spec, self.args.app_name,
                options=parse_vars(self.args.config_vars))

        request_method = (self.args.method or 'GET').upper()

        environ = {
            'REQUEST_METHOD': request_method,
            'SCRIPT_NAME': '',           # may be empty if app is at the root
            'PATH_INFO': path,
            'SERVER_NAME': 'localhost',  # always mandatory
            'SERVER_PORT': '80',         # always mandatory
            'SERVER_PROTOCOL': 'HTTP/1.0',
            'CONTENT_TYPE': 'text/plain',
            'REMOTE_ADDR':'127.0.0.1',
            'wsgi.run_once': True,
            'wsgi.multithread': False,
            'wsgi.multiprocess': False,
            'wsgi.errors': sys.stderr,
            'wsgi.url_scheme': 'http',
            'wsgi.version': (1, 0),
            'QUERY_STRING': qs,
            'HTTP_ACCEPT': 'text/plain;q=1.0, */*;q=0.1',
            'paste.command_request': True,
            }

        if request_method in ('POST', 'PUT', 'PATCH'):
            environ['wsgi.input'] = self.stdin
            environ['CONTENT_LENGTH'] = '-1'

        for name, value in headers.items():
            if name.lower() == 'content-type':
                name = 'CONTENT_TYPE'
            else:
                name = 'HTTP_' + name.upper().replace('-', '_')
            environ[name] = value

        request = Request.blank(path, environ=environ)
        response = request.get_response(app)
        if self.args.display_headers:
            self.out(response.status)
            for name, value in response.headerlist:
                self.out('%s: %s' % (name, value))
        if response.charset:
            self.out(response.ubody)
        else:
            self.out(response.body)
        return 0
Esempio n. 7
0
    def __getitem__(self, key):
        key = url_unquote(key)
        if key in self.request.registry.introspector.categories():
            return Introspector(key, self, self.request)

        raise KeyError(key)
Esempio n. 8
0
    def run(self):
        if not len(self.args) >= 2:
            self.out("You must provide at least two arguments")
            return 2
        app_spec = self.args[0]
        path = self.args[1]
        if not path.startswith("/"):
            path = "/" + path

        try:
            path, qs = path.split("?", 1)
        except ValueError:
            qs = ""

        path = url_unquote(path)

        headers = {}
        if self.options.headers:
            for item in self.options.headers:
                if ":" not in item:
                    self.out("Bad --header=%s option, value must be in the form " "'name:value'" % item)
                    return 2
                name, value = item.split(":", 1)
                headers[name] = value.strip()

        app = self.get_app(app_spec, self.options.app_name)
        request_method = (self.options.method or "GET").upper()

        environ = {
            "REQUEST_METHOD": request_method,
            "SCRIPT_NAME": "",  # may be empty if app is at the root
            "PATH_INFO": path,
            "SERVER_NAME": "localhost",  # always mandatory
            "SERVER_PORT": "80",  # always mandatory
            "SERVER_PROTOCOL": "HTTP/1.0",
            "CONTENT_TYPE": "text/plain",
            "REMOTE_ADDR": "127.0.0.1",
            "wsgi.run_once": True,
            "wsgi.multithread": False,
            "wsgi.multiprocess": False,
            "wsgi.errors": sys.stderr,
            "wsgi.url_scheme": "http",
            "wsgi.version": (1, 0),
            "QUERY_STRING": qs,
            "HTTP_ACCEPT": "text/plain;q=1.0, */*;q=0.1",
            "paste.command_request": True,
        }

        if request_method == "POST":
            environ["wsgi.input"] = self.stdin
            environ["CONTENT_LENGTH"] = "-1"

        for name, value in headers.items():
            if name.lower() == "content-type":
                name = "CONTENT_TYPE"
            else:
                name = "HTTP_" + name.upper().replace("-", "_")
            environ[name] = value

        request = Request.blank(path, environ=environ)
        response = request.get_response(app)
        if self.options.display_headers:
            self.out(response.status)
            for name, value in response.headerlist:
                self.out("%s: %s" % (name, value))
        if response.charset:
            self.out(response.ubody)
        else:
            self.out(response.body)
        return 0
Esempio n. 9
0
    def __getitem__(self, key):
        key = url_unquote(key)
        if key in self.request.registry.introspector.categories():
            return Introspector(key, self, self.request)

        raise KeyError(key)