def delete(self): """ Deletes the Ip represented by this model in database. Also deletes the tools associated with this ip Also deletes the ports associated with this ip Also deletes the defects associated with this ip and its ports """ mongoInstance = MongoCalendar.getInstance() tools = mongoInstance.find("tools", {"ip": self.ip}, True) for tool in tools: tool_model = Tool(tool) tool_model.delete() defects = mongoInstance.find( "defects", { "ip": self.ip, "$or": [{ "port": { "$exists": False } }, { "port": None }] }, True) for defect in defects: defect_model = Defect(defect) defect_model.delete() ports = mongoInstance.find("ports", {"ip": self.ip}, True) for port in ports: port_model = Port(port) port_model.delete() mongoInstance.delete("ips", {"_id": self._id})
def removeItem(self, toDeleteIid): """ Remove defect from given iid in defect treeview Args: toDeleteIid: database ID of defect to delete """ item = self.treevw.item(toDeleteIid) dialog = ChildDialogQuestion( self.parent, "DELETE WARNING", "Are you sure you want to delete defect " + str(item["text"]) + " ?", ["Delete", "Cancel"]) self.parent.wait_window(dialog.app) if dialog.rvalue != "Delete": return self.treevw.delete(toDeleteIid) defectToDelete = Defect.fetchObject({ "title": item["text"], "ip": "", "port": "", "proto": "" }) if defectToDelete is not None: if defectToDelete.index is not None: index = int(defectToDelete.index) children = self.treevw.get_children() for i in range(index + 1, len(children), 1): d_o = Defect({"_id": children[i]}) d_o.update({"index": str(i)}) defectToDelete.delete() self.resizeDefectTreeview()
def addDefect(self, defect_o): """ Add the given defect object in the treeview Args: defect_o: a Models.Defect object to be inserted in treeview """ if defect_o is None: return children = self.treevw.get_children() if defect_o.index is None or str(defect_o.index) == "": indToInsert = self.findInsertIndex(defect_o) if str(indToInsert) != "end": for i in range(int(indToInsert), len(children), 1): d_o = Defect({"_id": children[i]}) d_o.update({"index": str(i + 1)}) else: indToInsert = defect_o.index types = defect_o.mtype types = ", ".join(defect_o.mtype) new_values = (defect_o.ease, defect_o.impact, defect_o.risk, types, defect_o.redactor if defect_o.redactor != "N/A" else self.mainRedac) already_inserted = False already_inserted_iid = None for child in children: title = self.treevw.item(child)["text"] if title == defect_o.title: already_inserted = True already_inserted_iid = child break if not already_inserted: try: self.treevw.insert('', indToInsert, defect_o.getId(), text=defect_o.title, values=new_values, tags=(defect_o.risk)) defect_o.update({"index": str(indToInsert)}) except tk.TclError: # The defect already exists already_inserted = True already_inserted_iid = defect_o.getId() if already_inserted: existing = self.treevw.item(already_inserted_iid) values = existing["values"] if values[4].strip() == "N/A": values[4] = defect_o.redactor elif defect_o.redactor not in values[4].split(", "): values[4] += ", " + defect_o.redactor self.treevw.item(already_inserted_iid, values=values) # mongoInstance.insert("defects_table",{""}) self.resizeDefectTreeview()
def fillWithDefects(self): """ Fetch defects that are global (not assigned to an ip) and fill the defect table with them. """ defects = Defect.fetchObjects({"ip":""}) d_list = {} end_defect = [] for defect in defects: if defect.index is None: end_defect.append(defect) elif str(defect.index) == "end": end_defect.append(defect) else: ind = int(defect.index) if ind not in d_list: d_list[ind] = defect else: new_ind = ind + 1 while new_ind in d_list: new_ind += 1 d_list[new_ind] = defect defect.index = new_ind defect.update({"index":str(new_ind)}) # Fix dict order to index between 0 and * keys_ordered = sorted(list(d_list.keys())) for i in range(len(keys_ordered)): self.addDefect(d_list[keys_ordered[i]]) for defect in end_defect: self.addDefect(defect)
def _insertChildrenDefects(self): """Insert every children defect in database as DefectView under this node""" defects = self.controller.getDefects() for defect in defects: defect_o = DefectController(Defect(defect)) defect_vw = DefectView(self.appliTw, self.appliViewFrame, self.mainApp, defect_o) defect_vw.addInTreeview(str(self.controller.getDbId()))
def delete(self): """ Deletes the Port represented by this model in database. Also deletes the tools associated with this port Also deletes the defects associated with this port """ mongoInstance = MongoCalendar.getInstance() tools = mongoInstance.find("tools", {"port": self.port, "proto": self.proto, "ip": self.ip}, True) for tool in tools: tool_model = Tool(tool) tool_model.delete() defects = mongoInstance.find("defects", {"port": self.port, "proto": self.proto, "ip": self.ip}, True) for defect in defects: defect_model = Defect(defect) defect_model.delete() mongoInstance.delete("ports", {"_id": ObjectId(self._id)})
def setMainRedactor(self): """Sets a main redactor for a pentest. Each not assigned defect will be assigned to him/her""" self.settings.reloadSettings() dialog = ChildDialogCombo(self.parent, self.settings.getPentesters()+["N/A"], "Set main redactor", "N/A") newVal = self.parent.wait_window(dialog.app) if newVal is None: return if not newVal or newVal.strip() == "": return columnRedactor = self.treevw['columns'].index("redactor") for it in self.treevw.get_children(): oldValues = self.treevw.item(it)["values"] if oldValues[columnRedactor] == "N/A": oldValues[columnRedactor] = newVal self.treevw.item(it, values=oldValues) d_o = Defect({"_id":it}) d_o.update({"redactor":newVal}) self.mainRedac = newVal
def updateRiskBox(self, _event=None): """Callback when ease or impact is modified. Calculate new resulting risk value Args _event: mandatory but not used """ ease = self.easeForm.getValue() impact = self.impactForm.getValue() risk = Defect.getRisk(ease, impact) self.riskForm.setValue(risk)
def createDefectCallback(self, _event=None): """Callback for tool click #TODO move to ToolController Creates an empty defect view and open it's insert window with notes = tools notes. """ modelData = self.controller.getData() toExport = modelData["notes"] for widget in self.appliViewFrame.winfo_children(): widget.destroy() dv = DefectView(self.appliTw, self.appliViewFrame, self.mainApp, DefectController(Defect(modelData))) dv.openInsertWindow(toExport)
def OnDoubleClick(self, event): """ Callback for double click on treeview. Opens a window to update the double clicked defect view. Args: event: automatically created with the event catch. stores data about line in treeview that was double clicked. """ item = self.treevw.identify("item", event.x, event.y) defect_m = Defect.fetchObject({"_id": ObjectId(item)}) dialog = ChildDialogDefectView(self.parent, self.settings, defect_m) self.parent.wait_window(dialog.app) self.updateDefectInTreevw(defect_m)
def Parse(self, file_opened, **kwargs): """ Parse a opened file to extract information Example file: 10.0.0.1 - UNKNOWN - no connection - timeout 10.0.0.2 - VULNERABLE - ?? - ???? Args: file_opened: the open file kwargs: port("") and proto("") are valid Returns: a tuple with 4 values (All set to None if Parsing wrong file): 0. notes: notes to be inserted in tool giving direct info to pentester 1. tags: a list of tags to be added to tool 2. lvl: the level of the command executed to assign to given targets 3. targets: a list of composed keys allowing retrieve/insert from/into database targerted objects. """ # 5. Parse the file has you want. # Here add a note to the tool's notes of each warnings issued by this testssl run. notes = "" tags = ["Neutral"] targets = {} for line in file_opened: # Auto Detect infos = line.split(" - ") if len(infos) < 3: return None, None, None, None if not Ip.isIp(infos[0]): return None, None, None, None if infos[1] not in ["UNKNOWN", "SAFE", "VULNERABLE"]: return None, None, None, None # Parse ip = line.split(" ")[0].strip() Ip().initialize(ip).addInDb() p_o = Port.fetchObject({"ip": ip, "port": kwargs.get( "port", None), "proto": kwargs.get("proto", None)}) if p_o is not None: targets[str(p_o.getId())] = {"ip": ip, "port": kwargs.get( "port", None), "proto": kwargs.get("proto", None)} if "VULNERABLE" in line: Defect().initialize(ip, kwargs.get("port", None), kwargs.get("proto", None), "Serveur vulnérable à BlueKeep", "Difficile", "Critique", "Critique", "N/A", ["Socle"], notes=notes, proofs=[]).addInDb() tags=["P0wned!"] if p_o is not None: p_o.addTag("P0wned!") ip_o = Ip.fetchObject({"ip": ip}) if ip_o is not None: ip_o.addTag("P0wned!") elif "UNKNOWN" in line: tags = ["todo"] notes += line return notes, tags, "port", targets
def Parse(self, file_opened, **kwargs): """ Parse a opened file to extract information Args: file_opened: the open file _kwargs: not used Returns: a tuple with 4 values (All set to None if Parsing wrong file): 0. notes: notes to be inserted in tool giving direct info to pentester 1. tags: a list of tags to be added to tool 2. lvl: the level of the command executed to assign to given targets 3. targets: a list of composed keys allowing retrieve/insert from/into database targerted objects. """ targets = {} notes = file_opened.read() regex_ip = r"Nmap scan report for (\S+)" ip_group = re.search(regex_ip, notes) if ip_group is None: return None, None, None, None # Auto Detect: if "smb-vuln-ms17-010:" not in notes: return None, None, None, None # Parsing ip = ip_group.group(1).strip() Ip().initialize(ip).addInDb() port_re = r"(\d+)\/(\S+)\s+open\s+microsoft-ds" res_search = re.search(port_re, notes) res_insert = None if res_search is None: port = None proto = None else: port = res_search.group(1) proto = res_search.group(2) p_o = Port() p_o.initialize(ip, port, proto, "microsoft-ds") res_insert = p_o.addInDb() targets[str(p_o.getId())] = { "ip": ip, "port": port, "proto": proto } if "VULNERABLE" in notes: d_o = Defect() d_o.initialize(ip, port, proto, "Serveur vulnérable à EternalBlue", "Difficile", "Critique", "Critique", "N/A", ["Socle"], notes=notes, proofs=[]) d_o.addInDb() tags = ["P0wned!"] if res_insert is not None: p_o.addTag("P0wned!") return notes, tags, "port", targets
def addDefectCallback(self, _event): """ Create an empty defect model and its attached view. Open this view insert window. Args: _event: Automatically generated with a button Callback, not used. """ for widget in self.appliViewFrame.winfo_children(): widget.destroy() modelData = self.controller.getData() dv = DefectView(self.appliTw, self.appliViewFrame, self.mainApp, DefectController(Defect(modelData))) dv.openInsertWindow(modelData.get("notes", ""))
def addInTreeview(self, parentNode=None, addChildren=True): """Add this view in treeview. Also stores infos in application treeview. Args: parentNode: if None, will calculate the parent. If setted, forces the node to be inserted inside given parentNode. addChildren: If False, skip the tool and defects insert. Useful when displaying search results """ if parentNode is None: parentNode = self.getParent() nodeText = str(self.controller.getModelRepr()) elif parentNode == '': nodeText = self.controller.getDetailedString() else: nodeText = str(self.controller.getModelRepr()) self.appliTw.views[str(self.controller.getDbId())] = {"view": self} try: self.appliTw.insert(parentNode, "end", str(self.controller.getDbId()), text=nodeText, tags=self.controller.getTags(), image=self.getClassIcon()) except TclError: pass if addChildren: defects = self.controller.getDefects() for defect in defects: defect_o = DefectController(Defect(defect)) defect_vw = DefectView(self.appliTw, self.appliViewFrame, self.mainApp, defect_o) defect_vw.addInTreeview(str(self.controller.getDbId())) tools = self.controller.getTools() for tool in tools: tool_o = ToolController(Tool(tool)) tool_vw = ToolView(self.appliTw, self.appliViewFrame, self.mainApp, tool_o) tool_vw.addInTreeview(str(self.controller.getDbId())) tools = self.controller.getTools() atleastone = False for tool in tools: # SALE atleastone = True break if not atleastone: if len(self.controller.getTags()) == 0: self.controller.addTag("unscanned") self.appliTw.sort(parentNode) if "hidden" in self.controller.getTags(): self.hide()
def Parse(self, file_opened, **_kwargs): """ Parse a opened file to extract information Args: file_opened: the open file _kwargs: not used Returns: a tuple with 4 values (All set to None if Parsing wrong file): 0. notes: notes to be inserted in tool giving direct info to pentester 1. tags: a list of tags to be added to tool 2. lvl: the level of the command executed to assign to given targets 3. targets: a list of composed keys allowing retrieve/insert from/into database targerted objects. """ notes = file_opened.read() targets = {} tags = [] if "| http-methods:" not in notes: return None, None, None, None host, port, proto, service, risky_methods, supported_methods = parse( notes) if host == "": return None, None, None, None Ip().initialize(host).addInDb() p_o = Port().initialize(host, port, proto, service) res, iid = p_o.addInDb() if not res: p_o = Port.fetchObject({"_id": iid}) p_o.updateInfos({"Methods": ", ".join(supported_methods)}) targets[str(p_o.getId())] = {"ip": host, "port": port, "proto": proto} if "TRACE" in risky_methods: Defect().initialize(host, port, proto, "Méthode TRACE activée", "Difficile", "Important", "Important", "N/A", ["Socle"], notes="TRACE detected", proofs=[]).addInDb() risky_methods.remove("TRACE") if len(risky_methods) > 0: notes = "RISKY HTTP METHODS ALLOWED : " + " ".join(risky_methods) tags = [] tags.append("Interesting") return notes, tags, "port", targets
def __init__(self, parent, settings, defectModel=None): """ Open a child dialog of a tkinter application to choose autoscan settings. Args: parent: the tkinter parent view to use for this window construction. defectModel : A Defect Model object to load default values. None to have empty fields, default is None. """ self.app = tk.Toplevel(parent) self.app.title("Add a security defect") self.app.resizable(False, False) self.rvalue = None appFrame = ttk.Frame(self.app) self.isInsert = defectModel is None if self.isInsert: defectModel = Defect() self.defect_vw = DefectView(None, appFrame, DummyMainApp(settings), DefectController(defectModel)) if self.isInsert: self.defect_vw.openInsertWindow(addButtons=False) else: self.defect_vw.openModifyWindow(addButtons=False) ok_button = ttk.Button(appFrame, text="OK") ok_button.pack(side="right", padx=5, pady=10) ok_button.bind('<Button-1>', self.okCallback) cancel_button = ttk.Button(appFrame, text="Cancel") cancel_button.pack(side="right", padx=5, pady=10) cancel_button.bind('<Button-1>', self.cancel) appFrame.pack(fill=tk.BOTH, ipady=10, ipadx=10) self.app.transient(parent) try: self.app.wait_visibility() self.app.grab_set() except tk.TclError: pass
def getDefectsAsDict(self): """ Returns a dictionnary with treeview defects stored inside Returns: The returned dict will be formed this way (shown as json): { "Risk level describer 1":{ "defect title 1": { "description":{ "title": "defect title 1", "risk": "Risk level 1", "ease": "Ease of exploitation 1", "impact": "Impact 1", "redactor": "Redactor name", "type": ['D', 'T', ...] }, "defects_ids":[ id 1, id 2... ] }, "defect title 2":{ ... } ... }, "Risk level describer 2":{ ... } ... } """ defects_dict = dict() defects_dict["Critique"] = dict() defects_dict["Majeur"] = dict() defects_dict["Important"] = dict() defects_dict["Mineur"] = dict() columnEase = self.treevw['columns'].index("ease") columnImpact = self.treevw['columns'].index("impact") columnType = self.treevw['columns'].index("type") columnRisk = self.treevw['columns'].index("risk") columnRedactor = self.treevw['columns'].index("redactor") for children_id in self.treevw.get_children(): children = self.treevw.item(children_id) title = children["text"] defect_recap = dict() defect_recap["title"] = title defect_recap["risk"] = children["values"][columnRisk] defect_recap["ease"] = children["values"][columnEase] defect_recap["impact"] = children["values"][columnImpact] defect_recap["redactor"] = children["values"][columnRedactor] types = children["values"][columnType].split(",") d_types = [] for d_type in types: d_types.append(d_type.strip()) defect_recap["type"] = d_types defects_dict[defect_recap["risk"]][title] = dict() defects_dict[defect_recap["risk"] ][title]["description"] = defect_recap defects_dict[defect_recap["risk"]][title]["defects_ids"] = [] defects = Defect.fetchObjects({"title": title}) for defect in defects: defects_dict[defect_recap["risk"] ][title]["defects_ids"].append(defect.getId()) return defects_dict
def parseWarnings(file_opened): """ Parse the result of a testssl json output file Args: file_opened: the opened file reference Returns: Returns a tuple with (None values if not matching a testssl output): - a list of string for each testssl NOT ok, WARN, or MEDIUM warnings - a dict of targeted objects with database id as key and a unique key as a mongo search pipeline ({}) """ targets = {} missconfiguredHosts = {} firstLine = True for line in file_opened: if firstLine: if line.strip() != '"id", "fqdn/ip", "port", "severity", "finding", "cve", "cwe"' and \ line.strip() != '"id","fqdn/ip","port","severity","finding","cve","cwe"': return None, None firstLine = False continue # Search ip in file warn = re.search( r"^\"[^\"]*\", ?\"([^\"]*)\", ?\"([^\"]*)\", ?\"(OK|INFO|NOT ok|WARN|LOW|MEDIUM|HIGH|CRITICAL)\", ?\"[^\"]*\", ?\"[^\"]*\", ?\"[^\"]*\"$", line) if warn is not None: ip = warn.group(1) domain = None port = warn.group(2) notes = warn.group(3) if "/" in ip: domain = ip.split("/")[0] ip = "/".join(ip.split("/")[1:]) Ip().initialize(domain).addInDb() Port().initialize(domain, port, "tcp", "ssl").addInDb() Ip().initialize(ip).addInDb() Port().initialize(ip, port, "tcp", "ssl").addInDb() if notes not in ["OK", "INFO"]: missconfiguredHosts[ip] = missconfiguredHosts.get(ip, {}) missconfiguredHosts[ip][port] = missconfiguredHosts[ip].get( port, []) missconfiguredHosts[ip][port].append(notes + " : " + line) if domain is not None: missconfiguredHosts[domain] = missconfiguredHosts.get( domain, {}) missconfiguredHosts[domain][port] = missconfiguredHosts[ domain].get(port, []) missconfiguredHosts[domain][port].append(notes + " : " + line) for ip in missconfiguredHosts.keys(): for port in missconfiguredHosts[ip].keys(): p_o = Port.fetchObject({"ip": ip, "port": port, "proto": "tcp"}) targets[str(p_o.getId())] = { "ip": ip, "port": port, "proto": "tcp" } missconfiguredHosts[ip][port].sort() notes = "\n".join(missconfiguredHosts[ip][port]) res, _ = Defect().initialize(ip, port, "tcp", "Défauts d'implémentation du SSL/TLS", "Très difficile", "Majeur", "Important", "N/A", ["Socle"], notes=notes, proofs=[]).addInDb() if not res: p_o.updateInfos({"compliant": "False"}) defect_o = Defect.fetchObject({ "ip": ip, "title": "Défauts d'implémentation du SSL/TLS", "port": port, "proto": "tcp" }) defect_o.notes += notes defect_o.update() if firstLine: return None, None return str(len(missconfiguredHosts.keys()) ) + " misconfigured hosts found. Defects created.", targets
def Parse(self, file_opened, **_kwargs): """ Parse a opened file to extract information Args: file_opened: the open file _kwargs: not used Returns: a tuple with 4 values (All set to None if Parsing wrong file): 0. notes: notes to be inserted in tool giving direct info to pentester 1. tags: a list of tags to be added to tool 2. lvl: the level of the command executed to assign to given targets 3. targets: a list of composed keys allowing retrieve/insert from/into database targerted objects. """ notes = "" tags = [] content = file_opened.read() targets = {} try: notes_json = json.loads(content) except json.decoder.JSONDecodeError: return None, None, None, None oneScanIsValid = False for scan in notes_json: try: if scan.get('ssh_scan_version', None) is None: continue ips = [scan["hostname"], scan["ip"]] port = str(scan["port"]) for ip in ips: if ip.strip() == "": continue Ip().initialize(ip).addInDb() port_o = Port().initialize(ip, port, "tcp", "ssh") res, iid = port_o.addInDb() if not res: port_o = Port.fetchObject({"_id": iid}) notes = "\n".join(scan["compliance"].get( "recommendations", [])) targets[str(port_o.getId())] = { "ip": ip, "port": port, "proto": "tcp" } oneScanIsValid = True if "nopassword" in scan["auth_methods"]: tags = ["P0wned!"] # Will not exit if port was not ssh is_ok = scan["compliance"]["compliant"] if str(is_ok) == "False": port_o.updateInfos({"compliant": "False"}) port_o.updateInfos( {"auth_methods": scan["auth_methods"]}) Defect().initialize( ip, port, "tcp", "Défauts d’implémentation de la configuration SSH", "Très difficile", "Majeur", "Important", "N/A", ["Socle"], notes=notes, proofs=[]).addInDb() except KeyError: continue if not oneScanIsValid: return None, None, None, None return notes, tags, "port", targets
def notify(self, db, collection, iid, action, _parent): """ Callback for the observer implemented in mongo.py. Each time an object is inserted, updated or deleted the standard way, this function will be called. Args: collection: the collection that has been modified iid: the mongo ObjectId _id that was modified/inserted/deleted action: string "update" or "insert" or "delete". It was the action performed on the iid _parent: Not used. the mongo ObjectId of the parent. Only if action in an insert. Not used anymore """ mongoInstance = MongoCalendar.getInstance() if not mongoInstance.hasACalendarOpen(): return if mongoInstance.calendarName != db: return # Delete if action == "delete": if collection == "defects": view = self.getViewFromId(str(iid)) if view is not None: view.beforeDelete() self.appli.statusbar.notify([],view.controller.getTags()) try: self.delete(ObjectId(iid)) except tk.TclError: pass # item was not inserted in the treeview # Insert if action == "insert": view = None res = mongoInstance.find(collection, {"_id": ObjectId(iid)}, False) if collection == "tools": view = ToolView(self, self.appli.viewframe, self.appli, ToolController(Tool(res))) elif collection == "waves": view = WaveView(self, self.appli.viewframe, self.appli, WaveController(Wave(res))) elif collection == "scopes": view = ScopeView(self, self.appli.viewframe, self.appli, ScopeController(Scope(res))) elif collection == "ports": view = PortView(self, self.appli.viewframe, self.appli, PortController(Port(res))) elif collection == "ips": view = IpView(self, self.appli.viewframe, self.appli, IpController(Ip(res))) elif collection == "intervals": view = IntervalView(self, self.appli.viewframe, self.appli, IntervalController(Interval(res))) elif collection == "defects": view = DefectView(self, self.appli.viewframe, self.appli, DefectController(Defect(res))) try: if view is not None: view.addInTreeview() view.insertReceived() self.appli.statusbar.notify(view.controller.getTags()) except tk.TclError: pass if action == "update": try: view = self.getViewFromId(str(iid)) if view is not None: oldTags = self.item(str(iid))["tags"] view.controller.actualize() self.appli.statusbar.notify(view.controller.getTags(), oldTags) self.item(str(iid), text=str( view.controller.getModelRepr()), image=view.getIcon()) except tk.TclError: if view is not None: view.addInTreeview() if str(self.appli.openedViewFrameId) == str(iid): for widget in self.appli.viewframe.winfo_children(): widget.destroy() view.openModifyWindow() if view is not None: view.updateReceived() self.appli.statusbar.update()
def _load(self): """ Load the treeview with database information """ mongoInstance = MongoCalendar.getInstance() dialog = ChildDialogProgress(self.appli, "Loading "+str( mongoInstance.calendarName), "Opening "+str(mongoInstance.calendarName) + ". Please wait for a few seconds.", 200, "determinate") step = 0 dialog.show(100) nbObjects = mongoInstance.find("waves").count() nbObjects += mongoInstance.find("scopes").count() nbObjects += mongoInstance.find("intervals").count() nbObjects += mongoInstance.find("scopes").count() nbObjects += mongoInstance.find("ips").count() nbObjects += mongoInstance.find("ports").count() nbObjects += mongoInstance.find("tools").count() onePercentNbObject = nbObjects//100 if nbObjects > 100 else 1 nbObjectTreated = 0 for child in self.get_children(): self.delete(child) self._hidden = [] self._detached = [] self.waves_node = self.insert("", "end", str( "waves"), text="Waves", image=WaveView.getClassIcon()) # Loading every category separatly is faster than recursivly. # This is due to cursor.next function calls in pymongo # Adding wave objects waves = Wave.fetchObjects({}) for wave in waves: wave_o = WaveController(wave) wave_vw = WaveView(self, self.appli.viewframe, self.appli, wave_o) wave_vw.addInTreeview(self.waves_node, False) nbObjectTreated += 1 if nbObjectTreated % onePercentNbObject == 0: step += 1 dialog.update(step) scopes = Scope.fetchObjects({}) for scope in scopes: scope_o = ScopeController(scope) scope_vw = ScopeView(self, self.appli.viewframe, self.appli, scope_o) scope_vw.addInTreeview(None, False) nbObjectTreated += 1 if nbObjectTreated % onePercentNbObject == 0: step += 1 dialog.update(step) intervals = Interval.fetchObjects({}) for interval in intervals: interval_o = IntervalController(interval) interval_vw = IntervalView(self, self.appli.viewframe, self.appli, interval_o) interval_vw.addInTreeview(None, False) nbObjectTreated += 1 if nbObjectTreated % onePercentNbObject == 0: step += 1 dialog.update(step) # Adding ip objects self.ips_node = self.insert("", "end", str( "ips"), text="IPs", image=IpView.getClassIcon()) ips = Ip.fetchObjects({}) for ip in ips: ip_o = IpController(ip) ip_vw = IpView(self, self.appli.viewframe, self.appli, ip_o) ip_vw.addInTreeview(None, False) self.appli.statusbar.notify(ip_vw.controller.getTags()) nbObjectTreated += 1 if nbObjectTreated % onePercentNbObject == 0: step += 1 dialog.update(step) # Adding port objects ports = Port.fetchObjects({}) for port in ports: port_o = PortController(port) port_vw = PortView(self, self.appli.viewframe, self.appli, port_o) port_vw.addInTreeview(None, False) self.appli.statusbar.notify(port_vw.controller.getTags()) nbObjectTreated += 1 if nbObjectTreated % onePercentNbObject == 0: step += 1 dialog.update(step) # Adding defect objects defects = Defect.fetchObjects({"ip":{"$ne":""}}) for defect in defects: defect_o = DefectController(defect) defect_vw = DefectView( self, self.appli.viewframe, self.appli, defect_o) defect_vw.addInTreeview(None) nbObjectTreated += 1 if nbObjectTreated % onePercentNbObject == 0: step += 1 dialog.update(step) # Adding tool objects tools = Tool.fetchObjects({}) for tool in tools: tool_o = ToolController(tool) tool_vw = ToolView(self, self.appli.viewframe, self.appli, tool_o) tool_vw.addInTreeview(None, False) self.appli.statusbar.notify(tool_vw.controller.getTags()) nbObjectTreated += 1 if nbObjectTreated % onePercentNbObject == 0: step += 1 dialog.update(step) self.sort(self.ips_node) self.appli.statusbar.update() dialog.destroy()