def insert_meta(self, group, name, field, value): filters.check_group(group) filters.check_identifier(name, 64) field = filters.check_name(field, maxlen=64) filters.check_text(value, maxlenbits=16) #id = self.get_object_id(group, name, create=1) self.db.insert(self.sitename, (group, name), ('meta', field), value)
def runTest(self): # test for correct filtering self.check_filtered_value(filters.check_name, 'bob', 'bob') self.check_filtered_value(filters.check_name, ' bob \n\t', 'bob') self.check_filtered_value(filters.check_name, ' bob', 'bob') self.check_filtered_value(filters.check_name, 'bob1', 'bob1') self.check_filtered_value(filters.check_name, 'bob43654', 'bob43654') self.check_filtered_value(filters.check_name, 'bob1r2t3yt', 'bob1r2t3yt') self.check_filtered_value(filters.check_name, 'Bob', 'bob') self.check_filtered_value(filters.check_name, 'Underscores_OKAY', 'underscores_okay') self.check_filtered_value(filters.check_name, 'MiXeDcAsE', 'mixedcase') self.check_filtered_value(filters.check_name, 'MiXeD1234567890cAsE', 'mixed1234567890case') self.check_filtered_value(filters.check_name, '\t\n r4Y9PklgR32L \t \t \n', 'r4y9pklgr32l') # test for bad types self.assertRaises(filters.TypeError, filters.check_name, 4) self.assertRaises(filters.TypeError, filters.check_name, 5.6) self.assertRaises(filters.TypeError, filters.check_name, ['list']) self.assertRaises(filters.TypeError, filters.check_name, {'dict':4}) self.assertRaises(filters.TypeError, filters.check_name, self) # test for proper detection of long strings filters.check_name('bob', maxlen=3) filters.check_name(' bob\n\t\t ', maxlen=3) filters.check_name('b', maxlen=1) filters.check_name(' bobandsallydotcom ', maxlen=17) self.assertRaises(filters.RangeError, filters.check_name, 'b', maxlen=0) self.assertRaises(filters.RangeError, filters.check_name, 'bob', maxlen=2) self.assertRaises(filters.RangeError, filters.check_name, 'BobMartin', maxlen=6) self.assertRaises(filters.RangeError, filters.check_name, ' Bob4567890\n\n\n', maxlen=9) # test for proper detection of invalid strings self.assertRaises(filters.RangeError, filters.check_name, '') self.assertRaises(filters.RangeError, filters.check_name, '1') self.assertRaises(filters.RangeError, filters.check_name, '1bob') self.assertRaises(filters.RangeError, filters.check_name, 'bob martin') self.assertRaises(filters.RangeError, filters.check_name, 'BOB NUMBER THREE') self.assertRaises(filters.RangeError, filters.check_name, ' 4') self.assertRaises(filters.RangeError, filters.check_name, ' hi there') self.assertRaises(filters.RangeError, filters.check_name, 'test`;SELECT * FROM `raw`;') self.assertRaises(filters.RangeError, filters.check_name, 'nopunctuation!') self.assertRaises(filters.RangeError, filters.check_name, 'nothing-else-either') self.assertRaises(filters.RangeError, filters.check_name, "isn't that funny") self.assertRaises(filters.RangeError, filters.check_name, '\n\n\n\n\n9') self.assertRaises(filters.RangeError, filters.check_name, 'bobhas$1,000,000') self.assertRaises(filters.RangeError, filters.check_name, 'iwantbritish#s') self.assertRaises(filters.RangeError, filters.check_name, 'hello\ttab') self.assertRaises(filters.RangeError, filters.check_name, 'new\nline') self.assertRaises(filters.RangeError, filters.check_name, 'what?is?this') self.assertRaises(filters.RangeError, filters.check_name, 'whatisthis?') self.assertRaises(filters.RangeError, filters.check_name, 'hi!') self.assertRaises(filters.RangeError, filters.check_name, 'hello999^')
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()
def get_config_field(self, field): field_name = filters.check_name(field, maxlen=64) values = self.db.get_subkey(self.sitename, 'config', field) if not values: raise RapidRecSite.ConfigFieldNotFound("No value found for configuration field `%s`" % field) return self.recent_first(values)[0]
def __init__(self, sitename): self.sitename = filters.check_name(sitename, 32) #self.site = cachedb.cachedb.get(sitename) self.db = cachedb.CacheDB()