def test_parse_xid_local(self): entity_type, entity_id, entity_host = lib_util.ParseXid("CIM_ComputerSystem.Name=Unknown-30-b5-c2-02-0c-b5-2") self.assertEqual(entity_type, "CIM_ComputerSystem") self.assertEqual(entity_id, "Name=Unknown-30-b5-c2-02-0c-b5-2") self.assertEqual(entity_host, "") entity_type, entity_id, entity_host = lib_util.ParseXid("oracle/table.Name=MY_TABLE") self.assertEqual(entity_type, "oracle/table") self.assertEqual(entity_id, "Name=MY_TABLE") self.assertEqual(entity_host, "") entity_type, entity_id, entity_host = lib_util.ParseXid( "CIM_DataFile.Name=anyfile.txt") self.assertEqual(entity_type, "CIM_DataFile") self.assertEqual(entity_id, "Name=anyfile.txt") self.assertEqual(entity_host, "") entity_type, entity_id, entity_host = lib_util.ParseXid( "CIM_DataFile.Name=C%3A%2F%2FUsers%2Fxyz%2FLes%20Ringards%20-%20Aldo%252C%20Mireille%252C%20Julien.txt") self.assertEqual(entity_type, "CIM_DataFile") self.assertEqual(entity_id, "Name=C://Users/xyz/Les Ringards - Aldo%2C Mireille%2C Julien.txt") self.assertEqual(entity_host, "") entity_type, entity_id, entity_host = lib_util.ParseXid( "CIM_DummyClass.Name=C%3A%2F%2FUsers%2Fxyz%2FLes%20Ringards%20-%20Aldo%252C%20Mireille%252C%20Julien.txt" + ",OtherArg=Something") self.assertEqual(entity_type, "CIM_DummyClass") self.assertEqual(entity_id, "Name=C://Users/xyz/Les Ringards - Aldo%2C Mireille%2C Julien.txt,OtherArg=Something") self.assertEqual(entity_host, "")
def test_parse_xid_wbem(self): entity_type, entity_id, entity_host = lib_util.ParseXid("https://*****:*****@acme.com:5959/cimv2:Win32_SoftwareFeature.Name=\"Havana\",ProductName=\"Havana\",Version=\"1.0\"") self.assertEqual(entity_type, "cimv2:Win32_SoftwareFeature") self.assertEqual(entity_id, "Name=\"Havana\",ProductName=\"Havana\",Version=\"1.0\"") self.assertEqual(entity_host, "https://*****:*****@acme.com:5959") entity_type, entity_id, entity_host = lib_util.ParseXid("http://192.168.1.88:5988/root/PG_Internal:PG_WBEMSLPTemplate") self.assertEqual(entity_type, "root/PG_Internal:PG_WBEMSLPTemplate") self.assertEqual(entity_id, "") self.assertEqual(entity_host, "http://192.168.1.88:5988") entity_type, entity_id, entity_host = lib_util.ParseXid("http://192.168.1.88:5988/.") self.assertEqual(entity_type, "") self.assertEqual(entity_id, "") self.assertEqual(entity_host, "http://192.168.1.88:5988")
def test_parse_xid_wmi(self): entity_type, entity_id, entity_host = lib_util.ParseXid(r"\\myhost-HP\root\CIMV2\Applications%3A.") self.assertEqual(entity_type, r"root\CIMV2\Applications:") self.assertEqual(entity_id, "") self.assertEqual(entity_host, "myhost-HP") entity_type, entity_id, entity_host = lib_util.ParseXid(r"\\myhost-HP\root\CIMV2%3AWin32_PerfFormattedData_Counters_IPHTTPSGlobal.") self.assertEqual(entity_type, r"root\CIMV2:Win32_PerfFormattedData_Counters_IPHTTPSGlobal") self.assertEqual(entity_id, "") self.assertEqual(entity_host, "myhost-HP") entity_type, entity_id, entity_host = lib_util.ParseXid(r"\\MYHOST-HP\root\CIMV2%3AWin32_PerfFormattedData_Counters_IPHTTPSGlobal.Name%3D%22Default%22") self.assertEqual(entity_type, r"root\CIMV2:Win32_PerfFormattedData_Counters_IPHTTPSGlobal") self.assertEqual(entity_id, 'Name="Default"') self.assertEqual(entity_host, "MYHOST-HP")
def ParseQuery(self): # "GET /?mode=stop HTTP/1.0" 200 # http://192.168.1.68/~rchateau/RevPython/survol/entity.py?xid=process:7775 self.LogMsg("ParseQuery path=" + self.path) parsed_url = lib_util.survol_urlparse(self.path) query_as_dict = cgi.parse_qs(parsed_url.query) try: (entity_type, entity_id, entity_host) = lib_util.ParseXid(query_as_dict["xid"][0]) except KeyError: entity_type = "Undefined_entity_type" entity_id = "Undefined_entity_id" entity_host = "Undefined_entity_host" self.LogMsg("ParseQuery entity_id=" + entity_id) self.server.FeederCreateOrGet(entity_id) try: arg_mode = query_as_dict["mode"][0] if arg_mode == "stop": self.StopServer(entity_id) except KeyError: # If no stop, proceed as usual. pass return (entity_type, entity_id)
def script_url_to_source(callingUrl): parse_url = lib_util.survol_urlparse(callingUrl) query = parse_url.query params = parse_qs(query) xidParam = params['xid'][0] # sys.stdout.write("script_url_to_source xidParam=%s\n"%xidParam) (entity_type,entity_id,entity_host) = lib_util.ParseXid(xidParam) # sys.stdout.write("script_url_to_source entity_id=%s\n"%entity_id) entity_id_dict = lib_util.SplitMoniker(entity_id) # sys.stdout.write("entity_id_dict=%s\n"%str(entity_id_dict)) # parse_url.path=/LocalExecution/sources_types/Win32_UserAccount/Win32_NetUserGetInfo.py # This is a very simple method to differentiate local from remote scripts if parse_url.path.startswith(lib_util.prefixLocalExecution): # This also chops the leading slash. pathScript = parse_url.path[len(lib_util.prefixLocalExecution) + 1:] objSource = SourceLocal(pathScript,entity_type,**entity_id_dict) # Note: This should be True: parse_url.netloc.startswith("LOCAL_MODE") else: objSource = SourceRemote(callingUrl,entity_type,**entity_id_dict) return objSource
def GetXid(self): try: # See variable xidCgiDelimiter. # TODO: Consider base64 encoding all arguments with "Xid=". # The benefit would be to have the same encoding for all arguments. xid = self.m_arguments["xid"].value except KeyError: # See function enter_edition_mode try: return ("", "", "") # TODO: Not finished, useless or debugging purpose ? entity_type = self.m_arguments["edimodtype"].value monik_delim = "" entity_id = "" for edi_key in self.m_arguments: if edi_key[:11] == "edimodargs_": monik_key = edi_key[11:] monik_val = self.m_arguments[edi_key].value entity_id += monik_delim + monik_key + "=" + monik_val monik_delim = "&" return (entity_type, entity_id, "") except KeyError: # No host, for the moment. return ("", "", "") return lib_util.ParseXid(xid)
def GetXid(self): try: xid = self.m_arguments["xid"].value except KeyError: # See function EditionMode try: return ( "", "", "" ) # TODO: Not finished, useless or debugging purpose ? entity_type = self.m_arguments["edimodtype"].value monikDelim = "" entity_id = "" for ediKey in self.m_arguments: if ediKey[:11] == "edimodargs_": monikKey = ediKey[11:] monikVal = self.m_arguments[ediKey].value entity_id += monikDelim + monikKey + "=" + monikVal monikDelim = "&" return ( entity_type, entity_id, "" ) except KeyError: # No host, for the moment. return ( "", "", "" ) return lib_util.ParseXid( xid )
def parse_entity_uri_with_host(uri_with_mode, long_display=True, force_entity_ip_addr=None): """ This does two different things from an instance URI: - Split an URL into its class, key-value params and host. - And calculate a displayable string for this instance. This is used notably when transforming RDF into dot documents. The returned entity type is used for example choosing graphic attributes and gives more information than the simple entity type. Example: (labText, entity_graphic_class, entity_id) = lib_naming.ParseEntityUri(the_url) TODO: It could be split into two different functions. """ # Maybe there is a host name before the entity type. It can contain letters, numbers, # hyphens, dots etc... but no ":" or "@". # THIS CANNOT WORK WITH IPV6 ADDRESSES... # WE MAY USE SCP SYNTAX: scp -6 osis@\[2001:db8:0:1\]:/home/osis/test.file ./test.file # This conversion because it might be called with rdflib.term.URIRef or rdflib.term.Literal # without explicit conversion, or unicode if py2. # This is not really in issue since this conversion is straightforward. non_str_type = six.binary_type if lib_util.is_py3 else six.text_type if isinstance(uri_with_mode, (rdflib.term.Literal, rdflib.term.URIRef, non_str_type)): uri_with_mode = str(uri_with_mode) assert isinstance(uri_with_mode, str) # This replaces "&" by "&" up to two times if needed. uri_with_mode_clean = lib_util.UrlNoAmp(uri_with_mode) uprs = lib_util.survol_urlparse(uri_with_mode_clean) uprs_query = uprs.query uprs_query_split_cgi = uprs_query.split("&") uprs_query_dict = {k: v for k, _, v in (l.partition("=") for l in uprs_query_split_cgi)} cgi_arg_xid = uprs_query_dict.get("xid", None) uri_mode = uprs_query_dict.get("mode", "") associator_attribute = uprs_query_dict.get("__associator_attribute__", None) # Default value. entity_host = "" fil_script = os.path.basename(uprs.path) # This works for the scripts: # entity.py xid=namespace/type:idGetNamespaceType # objtypes_wbem.py Just extracts the namespace, as it prefixes the type: xid=namespace/type:id # See variable lib_util.xidCgiDelimiter="?xid=" # Possibly, the "xid" parameter does not come at the beginning. # Only the first "=" delimiter counts for the CGI variable. # if uprs.query.startswith("xid="): if cgi_arg_xid is not None: # TODO: Maybe the chain contains HTML codes and therefore cannot be parsed. # Ex: "xid=%40%2F%3Aoracle_package." == "xid=@/:oracle_package." # entity_type, entity_id, entity_host = lib_util.ParseXid(uprs.query[4:]) entity_type, entity_id, entity_host = lib_util.ParseXid(cgi_arg_xid) entity_graphic_class = entity_type entity_label = _calc_label(entity_host, entity_type, entity_id, force_entity_ip_addr, fil_script) # TODO: Consider external_url_to_title, similar logic with different results. if long_display: entity_label = _known_script_to_title(fil_script, uri_mode, entity_host, entity_label) # Maybe an internal script, but not entity.py # It has a special entity type as a display parameter elif uri_with_mode_clean.startswith(lib_util.uriRoot): # This is a bit of a special case which allows to display something if we know only # the type of the entity but its id is undefined. Instead of displaying nothing, # this attempts to display all available entities of this given type. # source_top/enumerate_process.py etc... Not "." because this has a special role in Python. mtch_enumerate = re.match(r"^.*/enumerate_([a-z0-9A-Z_]*)\.py$", uri_with_mode_clean) if mtch_enumerate: entity_graphic_class = mtch_enumerate.group(1) entity_id = "" # TODO: Change this label, not very nice. # This indicates that a specific script can list all objects of a given entity type. entity_label = entity_graphic_class + " enumeration" else: entity_graphic_class = "provider_script" entity_id = "" entity_label = _known_script_to_title(fil_script, uri_mode) elif uri_with_mode_clean.split(':')[0] in ["ftp", "http", "https", "urn", "mail"]: # Standard URLs. Example: lib_common.NodeUrl( "http://www.google.com" ) entity_graphic_class = "" entity_id = "" # Display the complete URL, otherwise it is not clickable. entity_label = uri_with_mode else: entity_graphic_class = "" # This specific keyword used when no class is specified and there is no object. It is easy to spot. # It happens for example for blank nodes, BNode, used to created literal values with a key: # Arguments of a function, successive values with a time-stamp. entity_id = "PLAINTEXTONLY" # Maybe an external URI sending data in RDF, HTML etc... # We could also load the URL and gets its title if it is in HTML. basna = lib_util.EncodeUri(fil_script) if uprs.netloc != "": entity_label = uprs.netloc + "/" + basna else: entity_label = basna # TODO: " " are replaced by "%20". Why ? So change back. entity_label = entity_label.replace("%20", " ") assert isinstance(entity_graphic_class, str) if associator_attribute: entity_label = associator_attribute.replace(".", " ") + " of " + entity_label return entity_label, entity_graphic_class, entity_id, entity_host
def ParseEntityUri(uriWithMode, longDisplay=True, force_entity_ip_addr=None): #sys.stderr.write("ParseEntityUri uriWithMode=%s\n"%uriWithMode) # Maybe there is a host name before the entity type. It can contain letters, numbers, # hyphens, dots etc... but no ":" or "@". # THIS CANNOT WORK WITH IPV6 ADDRESSES... # WE MAY USE SCP SYNTAX: scp -6 osis@\[2001:db8:0:1\]:/home/osis/test.file ./test.file # In the URI, we might have the CGI parameter "&mode=json". It must be removed otherwise # it could be taken in entity_id, and the result of EntityToLabel() would be wrong. uriWithModeClean = lib_util.UrlNoAmp(uriWithMode) uri = lib_util.AnyUriModed(uriWithModeClean, "") uriMode = lib_util.GetModeFromUrl(uriWithModeClean) uprs = lib_util.survol_urlparse(uri) filScript = os.path.basename(uprs.path) # sys.stderr.write("ParseEntityUri filScript=%s\n"%filScript) # This works for the scripts: # entity.py xid=namespace/type:idGetNamespaceType # objtypes_wbem.py Just extracts the namespace, as it prefixes the type: xid=namespace/type:id # See variable lib_util.xidCgiDelimiter="?xid=" if uprs.query.startswith("xid="): # TODO: Maybe the chain contains HTML codes and therefore cannot be parsed. # Ex: "xid=%40%2F%3Aoracle_package." == "xid=@/:oracle_package." (entity_type, entity_id, entity_host) = lib_util.ParseXid(uprs.query[4:]) entity_graphic_class = entity_type entity_label = CalcLabel(entity_host, entity_type, entity_id, force_entity_ip_addr, filScript) # TODO: Consider external_url_to_title, similar logic with different results. if longDisplay: entity_label = KnownScriptToTitle(filScript, uriMode, entity_host, entity_label) # Maybe an internal script, but not entity.py # It has a special entity type as a display parameter elif uri.startswith(lib_util.uriRoot): # This is a bit of a special case which allows to display something if we know only # the type of the entity but its id is undefined. Instead of displaying nothing, # this attempts to display all available entities of this given type. # source_top/enumerate_process.py etc... Not "." because this has a special role in Python. mtch_enumerate = re.match(r"^.*/enumerate_([a-z0-9A-Z_]*)\.py$", uri) if mtch_enumerate: entity_graphic_class = mtch_enumerate.group(1) entity_id = "" # TODO: Change this label, not very nice. # This indicates that a specific script can list all objects of a given entity type. entity_label = entity_graphic_class + " enumeration" else: entity_graphic_class = "provider_script" entity_id = "" entity_label = KnownScriptToTitle(filScript, uriMode) elif uri.split(':')[0] in ["ftp", "http", "https", "urn", "mail"]: # Standard URLs. Example: lib_common.NodeUrl( "http://www.google.com" ) entity_graphic_class = "" entity_id = "" # Display the complete URL, otherwise it is not clickable. entity_label = uriWithMode # uri # uri.split('/')[2] else: entity_graphic_class = "" entity_id = "PLAINTEXTONLY" entity_label = UriToTitle(uprs) # TODO: " " are replaced by "%20". Why ? So change back. entity_label = entity_label.replace("%20", " ") return (entity_label, entity_graphic_class, entity_id)
def test_parse_xid_trivial(self): entity_type, entity_id, entity_host = lib_util.ParseXid("") self.assertEqual(entity_type, "") self.assertEqual(entity_id, "") self.assertEqual(entity_host, "")