Example #1
0
 def runTest(self):
     rapidrecdb.add_site(self.sitename)
     rrs = RapidRecSite(self.sitename)
     #rrs.set_field_analyzer('nonexistentfield', 4)
     # test inserting a duplicate record - this should be permitted
     rrs.insert_relation(src_group='user', src_name='5', tgt_group='item', tgt_name='10', field='rating')
     rrs.insert_relation(src_group='user', src_name='5', tgt_group='item', tgt_name='10', field='rating')
     #self.assertEqual(rrs.get_field_id('rating'), 2,
     #                 "Field id for rating should have been created when the first " +
     #                 "rating record was inserted into raw.")
     #rrs.set_field_analyzer('rating', 1)
     #self.assertEqual(rrs.get_field_id('rating'), 2,
     #                 "rating was created second; it should have rating = 2, even " +
     #                 "though it has been updated since creation.")
     #self.assertEqual(rrs.get_field_id('newfield'), -1,
     #                 "newfield does not exist and thus should have an invalid field_id")
     #self.assertEqual(rrs.get_field_id('nonexistentfield'), 1,
     #                 "nonexistentfield should have been created first and thus have id=1")
     rrs.insert_meta('user', 3, 'name', 'Bob')
Example #2
0
 def runTest(self):
     rapidrecdb.add_site(self.sitename)
     # test for good site names
     # whitespace before & after is okay (it is stripped during filtering)
     rrs = RapidRecSite('   ' + self.sitename)
     rrs = RapidRecSite(self.sitename + '   ')
     rrs = RapidRecSite(' \n  ' + self.sitename + ' \t \n')
     # this name is fine, but the database shouldn't exist
     self.assertRaises(dbAccess.ConnectionError, RapidRecSite, 'this1sitedoesntexist')
     # test for bad site names
     self.assertRaises(filters.RangeError, RapidRecSite, '1openingdigit')
     self.assertRaises(filters.RangeError, RapidRecSite, 'thisnameisjusttoolongtouseforasitename')
     self.assertRaises(filters.RangeError, RapidRecSite, 'test`;SELECT * FROM `raw`;')
     self.assertRaises(filters.RangeError, RapidRecSite, 'no spaces allowed')
     self.assertRaises(filters.RangeError, RapidRecSite, 'nopunctuation!')
     
     rrs = RapidRecSite(self.sitename)
     # test for good field names
     rrs.set_field_analyzer('item', 'goodname', 'filter2')
     rrs.set_field_analyzer('item', 'MixEdCaSEgeTsStRIpPed', 'filter2')
     rrs.set_field_analyzer('item', 'numbersarefine2', 'filter2')
     rrs.set_field_analyzer('item', 'm9857032985794fgf', 'filter2')
     rrs.set_field_analyzer('item', ' \tleadingandtrailingwhitespacesareokay  \n ', 'filter2')
     self.assertRaises(filters.RangeError, rrs.set_field_analyzer, 
                       'item', 'no whitespace inside', 'filter2')
     self.assertRaises(filters.RangeError, rrs.set_field_analyzer, 
                       'item', '`; select no sql hacking either;', 'filter2')
     self.assertRaises(filters.RangeError, rrs.set_field_analyzer, 
                       'item', '1cannotstartwithanumber', 'filter2')
Example #3
0
    def run(self):
        processing_start_time = time.time()

        self.root = "response"
        self.response = {}

        if not self.headers:
            return self.failure("Header 'host' required for all requests.")
        hostname = self.headers["host"].partition(":")[0]
        hostname_matches = re.findall("(\w+).(rapidrec.com|localhost)", hostname)
        if not hostname_matches:
            return self.failure(
                "Could not determine sitename.  Please use " + "[sitename].rapidrec.com for all requests."
            )
        else:
            self.sitename = hostname_matches[0][0]
        # Check the validity of the sitename
        try:
            self.sitename = filters.check_name(self.sitename, 32)
        except (filters.TypeError, filters.RangeError):
            return self.failure("Invalid site: %s" % self.sitename)
        # Check that the site exists by instantiating RapidRecSite
        try:
            rrsite = RapidRecSite(self.sitename)
        except RapidRecSite.ConnectionError:
            return self.failure("Unknown site: %s" % self.sitename)
        # Check the remote IP against the list of allowed IPs
        remoteip = self.request.getClientIP()
        # Break a comma-separated string into a list, with one tuple per IP ('IP', unused, 'cidr')
        try:
            iplist = str(rrsite.get_config_field("ip_allow")).split(",")
        except RapidRecSite.ConfigFieldNotFound:
            iplist = ["0.0.0.0/0"]
        while "" in iplist:
            iplist.remove("")
        iplist.append("127.0.0.1")
        if self.sitename.startswith("test"):
            iplist.append("68.9.232.69")  # for development only
        if not ipfilter.is_ip_in_list(remoteip, iplist):
            return self.failure("Access forbidden from your IP: %s is not in { %s }" % (remoteip, ", ".join(iplist)))
        # At this point, the request is considered authentic.
        # We now proceed to process the request.
        # Find the path list and query (if any) by breaking up the QUERY_STRING
        # (fullpath, unused, query) = self.path.partition('?')
        fullpath = self.path
        path = fullpath.split("/")
        # Remove empty strings from the path list caused
        # by duplicate and unnecessary slashes in the path
        while "" in path:
            path.remove("")
        depth = 0
        args = {}
        if self.method == "post":
            if "content-length" not in self.headers:
                return self.failure("content-length required when POSTing")
            self.contentLength = int(self.headers["content-length"])
            self.request.content.seek(0, 0)
            args["postdata"] = self.request.content.read(self.contentLength)
        elif self.method != "get":
            return self.failure("Method not supported. Only GET and POST operations are allowed.")
        objtypes = ["users", "items", "movies"]
        try:
            if len(path) <= depth:
                raise (res.errors.UnimplementedError)
            elif path[depth] == "config":
                # /config...
                depth += 1
                raise (res.errors.UnimplementedError)
            elif path[depth] in objtypes:
                # /objs...
                args["type"] = "user" if path[depth] == "users" else "item"
                depth += 1
                if len(path) <= depth:
                    # /objs
                    Handler = res.objs.Handler
                else:
                    # /objs/{obj}...
                    args["name"] = path[depth]
                    depth += 1
                    if len(path) <= depth:
                        # /objs/{obj}
                        Handler = res.obj.Handler
                    elif path[depth] in objtypes:
                        # /objs/{obj}/objs...
                        args["tgt_type"] = "user" if path[depth] == "users" else "item"
                        depth += 1
                        if len(path) <= depth:
                            # /objs/{obj}/objs
                            raise (res.errors.UnimplementedError)
                        else:
                            # /objs/{obj}/objs/{obj}...
                            args["tgt_name"] = path[depth]
                            depth += 1
                            if len(path) <= depth:
                                # /objs/{obj}/objs/{obj}
                                Handler = res.objobj.Handler
                            else:
                                # /objs/{obj}/objs/{obj}/{resource}...
                                args["resource"] = path[depth]
                                depth += 1
                                if len(path) <= depth:
                                    # /objs/{obj}/objs/{obj}/{resource}
                                    Handler = res.objobjres.Handler
                                else:
                                    # /objs/{obj}/objs/{obj}/{resource}/...
                                    raise (res.errors.UnsupportedError)
                    else:
                        # /objs/{obj}/resource
                        args["resource"] = path[depth]
                        depth += 1
                        if len(path) <= depth:
                            # /objs/{obj}/{resource}
                            Handler = res.objres.Handler
                        else:
                            # /objs/{obj}/{resource}/...
                            raise (res.errors.UnsupportedError)
            else:
                # /{not-supported}...
                raise (res.errors.UnsupportedError)
            # Here is where we actually service queries that look valid so far
            handler = Handler(rrsite, self.response, self.method, self.request.args, args)
            handler.run()
            xmlext.set_status(self.response, "OKAY", "Query completed successfully.")
        except res.errors.ContentLengthMissingError:
            xmlext.set_status(self.response, "ERROR", "Content-length missing.")
        except res.errors.MethodError:
            xmlext.set_status(self.response, "ERROR", "Method not supported.")
        except res.errors.QueryError:
            xmlext.set_status(self.response, "ERROR", "Invalid query.")
        except res.errors.UnsupportedError:
            xmlext.set_status(self.response, "ERROR", "Resource not supported.")
        except res.errors.UnimplementedError:
            xmlext.set_status(self.response, "ERROR", "Resource not implemented.")
        except res.errors.PostError:
            xmlext.set_status(self.response, "ERROR", "Could not understand request body.")
        except res.errors.IdError:
            xmlext.set_status(self.response, "ERROR", "Invalid user or item identifier.")
        except res.errors.UnknownError:
            xmlext.set_status(self.response, "ERROR", "Unknown Error.")

        processing_finish_time = time.time()
        processing_time_elapsed = processing_finish_time - processing_start_time
        treexml.insert_node(self.response, "system_usage", "%f" % processing_time_elapsed)
        # print response
        self.respXML()
        self.send(treexml.encode(self.root, self.response))
        return self.finishreq()