from django.shortcuts import render from django.views import View from rest_framework.parsers import FormParser from rest_framework.views import APIView from core.lib.manage import threshold from core.views.manage.permissions import SuperUserRequiredMixin class ThresholdIRCStats(SuperUserRequiredMixin, View): stats_template = "manage/threshold/irc/overview/stats.html" def get(self, request): stats = threshold.get_irc_stats() context = {"stats": stats} return render(request, self.stats_template, context) class ThresholdIRCOverviewAlerts(SuperUserRequiredMixin, View): stats_template = "manage/threshold/irc/overview/alerts.html" def get(self, request): alerts = threshold.get_irc_alerts(request.user) context = {"alerts": alerts} return render(request, self.stats_template, context) class ThresholdIRCNetworks(SuperUserRequiredMixin, View): template_name = "manage/threshold/irc/overview/networks.html" def get(self, request): networks = threshold.get_irc_networks() context = {"networks": networks} return render(request, self.template_name, context) class ThresholdIRCNetworkDel(SuperUserRequiredMixin, View): template_name = "manage/threshold/irc/overview/networks.html" def delete(self, request, net): deleted = threshold.del_network(net) message = f"Deleted network {net}" message_class = "success" if not deleted["success"]: message = deleted["reason"] message_class = "danger" networks = threshold.get_irc_networks() context = { "networks": networks, "message": message, "class": message_class, } return render(request, self.template_name, context) class ThresholdIRCNetworkInfo(SuperUserRequiredMixin, View): template_name = "manage/threshold/irc/network/info.html" def get(self, request, net): network = threshold.get_irc_network(net) context = {"network": network} return render(request, self.template_name, context) class ThresholdIRCNetworkInfoEdit(SuperUserRequiredMixin, APIView): template_name = "manage/threshold/irc/network/edit-network.html" parser_classes = [FormParser] def get(self, request, net): """ Return the form to edit a network. """ network = threshold.get_irc_network(net) editable = ["auth", "host", "last", "port", "security", "chanlimit"] context = { "net": net, "network": {k: v for k, v in network.items() if k in editable}, } return render(request, self.template_name, context) def post(self, request, net): """ Actually edit the network. Returns the info pane with a message about the success. """ template_name = "manage/threshold/irc/network/info.html" edited = threshold.edit_irc_network(net, request.data) if edited["success"]: message = "Successfully edited!" message_class = "success" else: if "reason" in edited: message = f"Error editing network: {edited['reason']}" else: message = "Error editing network" message_class = "danger" network = threshold.get_irc_network(net) context = {"network": network, "message": message, "class": message_class} return render(request, template_name, context) class ThresholdIRCNetworkRelays(SuperUserRequiredMixin, View): template_name = "manage/threshold/irc/network/relays.html" def get(self, request, net): relays = threshold.get_irc_relays(net) context = {"net": net, "relays": relays["relays"]} return render(request, self.template_name, context) class ThresholdIRCNetworkRelayDel(SuperUserRequiredMixin, APIView): template_name = "manage/threshold/irc/network/relays.html" def delete(self, request, net, num): """ Delete a relay """ deleted = threshold.del_relay(net, num) if deleted["success"]: message = f"Deleted relay {num}" message_class = "success" else: message = deleted["reason"] message_class = "danger" relays = threshold.get_irc_relays(net) context = { "net": net, "message": message, "class": message_class, "relays": relays["relays"], } return render(request, self.template_name, context) class ThresholdIRCNetworkRelayProvision(SuperUserRequiredMixin, APIView): template_name = "manage/threshold/irc/network/relays.html" def post(self, request, net, num): """ Provision a relay """ provisioned = threshold.irc_provision_relay(net, num) if provisioned["success"]: message = f"Provisioned relay {num}" message_class = "success" else: message = provisioned["reason"] message_class = "danger" relays = threshold.get_irc_relays(net) context = { "net": net, "message": message, "class": message_class, "relays": relays["relays"], } return render(request, self.template_name, context) class ThresholdIRCNetworkRelayAuth(SuperUserRequiredMixin, APIView): template_name = "manage/threshold/irc/network/relays.html" def post(self, request, net, num): """ Provision a relay """ provisioned = threshold.irc_enable_auth(net, num) if provisioned["success"]: message = f"Enabled authentication on relay {num}" message_class = "success" else: message = provisioned["reason"] message_class = "danger" relays = threshold.get_irc_relays(net) context = { "net": net, "message": message, "class": message_class, "relays": relays["relays"], } return render(request, self.template_name, context) class ThresholdIRCNetworkRelayStatus(SuperUserRequiredMixin, APIView): template_name = "manage/threshold/irc/network/relays.html" def get(self, request, net, num, status): """ Change the status of a relay. """ edited = threshold.change_network_status(net, num, status) if edited["success"]: message = "Successfully completed!" message_class = "success" else: if "reason" in edited: message = f"Error updating status: {edited['reason']}" else: message = "Error updating status" message_class = "danger" relays = threshold.get_irc_relays(net) context = { "relays": relays["relays"], "message": message, "class": message_class, } return render(request, self.template_name, context) class ThresholdIRCNetworkChannelsAPI(SuperUserRequiredMixin, APIView): template_name = "manage/threshold/irc/network/channels.html" parser_classes = [FormParser] def delete(self, request, net): """ Part a channel. :param net: network name :param channel: channel name """ channel = request.data["channel"] parted = threshold.part_channel(net, channel) if parted["success"]: message = f"Requested part on relays: {', '.join(parted['relays'])}" message_class = "success" else: message = parted["reason"] message_class = "danger" channels = threshold.get_irc_channels(net) context = { "net": net, "channels": channels["channels"], "message": message, "class": message_class, } return render(request, self.template_name, context) def put(self, request, net): """ Join a channel. :param net: network name """ if "channel" not in request.data: message = "No channel specified" message_class = "danger" else: channel = request.data["channel"] joined = threshold.join_channel(net, channel) if joined["success"]: message = f"Requested join on relay: {joined['relays']}" message_class = "success" else: message = joined["reason"] message_class = "danger" channels = threshold.get_irc_channels(net) context = { "net": net, "channels": channels["channels"], "message": message, "class": message_class, } return render(request, self.template_name, context) class ThresholdIRCNetworkChannels(SuperUserRequiredMixin, APIView): """ List the channels a network is on. Allow parting and joining new ones. Re-render the same template if we join/part to make it simple. """ template_name = "manage/threshold/irc/network/channels.html" parser_classes = [FormParser] def get(self, request, net): """ Get list of channels for network. :param net: network name """ channels = threshold.get_irc_channels(net) context = {"net": net, "channels": channels["channels"]} return render(request, self.template_name, context) def delete(self, request, net, channel): """ Part a channel. :param net: network name :param channel: channel name """ parted = threshold.part_channel(net, channel) if parted["success"]: message = f"Requested part on relays: {', '.join(parted['relays'])}" message_class = "success" else: message = parted["reason"] message_class = "danger" channels = threshold.get_irc_channels(net) context = { "net": net, "channels": channels["channels"], "message": message, "class": message_class, } return render(request, self.template_name, context) def put(self, request, net): """ Join a channel. :param net: network name """ if "channel" not in request.data: message = "No channel specified" message_class = "danger" else: channel = request.data["channel"] joined = threshold.join_channel(net, channel) if joined["success"]: message = f"Requested join on relay: {joined['relays']}" message_class = "success" else: message = joined["reason"] message_class = "danger" channels = threshold.get_irc_channels(net) context = { "net": net, "channels": channels["channels"], "message": message, "class": message_class, } return render(request, self.template_name, context) class ThresholdIRCAliases(SuperUserRequiredMixin, APIView): template_name = "manage/threshold/irc/overview/aliases.html" def get(self, request): """ Get aliases. """ aliases = threshold.get_aliases() context = { "aliases": aliases["aliases"], } return render(request, self.template_name, context) class ThresholdIRCActions(SuperUserRequiredMixin, APIView): template_name = "manage/threshold/irc/overview/actions.html" def get(self, request): """ Get actions pane. """ return render(request, self.template_name) class ThresholdIRCActionsAddNetwork(SuperUserRequiredMixin, APIView): template_name = "manage/threshold/irc/overview/modals/add-network.html" parser_classes = [FormParser] def get(self, request): """ Get actions pane. """ return render(request, self.template_name) def put(self, request): """ Create a network. """ template_name = "manage/threshold/irc/overview/networks.html" created = threshold.create_network(request.data) message = "Network created successfully." message_class = "success" if not created["success"]: message = created["reason"] message_class = "danger" networks = threshold.get_irc_networks() context = { "networks": networks, "message": message, "class": message_class, } return render(request, template_name, context) class ThresholdIRCActionsRegistration(SuperUserRequiredMixin, APIView): template_name = "manage/threshold/irc/network/modals/registration.html" parser_classes = [FormParser] def get(self, request, net=None): """ Get registration modal """ message = None message_class = None if net == "None": net = None unreg = threshold.irc_get_unreg(net) if not unreg: message = "Could not get registration status." message_class = "danger" elif not unreg["success"]: if "reason" in unreg: message = unreg["reason"] message_class = "danger" else: message = "Getting registration status failed." message_class = "danger" context = { "net": net, "message": message, "class": message_class, } if "unreg" in unreg: context["unreg"] = unreg["unreg"] return render(request, self.template_name, context) def put(self, request, net=None): """ Confirm registration for networks. """ message = None message_class = None if net == "None": net = None if request.resolver_match.url_name == "threshold_irc_actions_registration_net": template_name = "manage/threshold/irc/network/actions.html" else: template_name = "manage/threshold/irc/overview/actions.html" updated = threshold.irc_confirm_accounts(request.data) message = "Registration confirmed successfully." message_class = "success" if not updated["success"]: message = updated["reason"] message_class = "danger" unreg = threshold.irc_get_unreg(net) if not unreg: message = "Could not get registration status." message_class = "danger" elif not unreg["success"]: if "reason" in unreg: message = unreg["reason"] message_class = "danger" else: message = "Getting registration status failed." message_class = "danger" context = { "net": net, "message": message, "class": message_class, } if "unreg" in unreg: context["unreg"] = unreg["unreg"] return render(request, template_name, context) class ThresholdIRCActionsRegistrationAuth(SuperUserRequiredMixin, APIView): template_name = "manage/threshold/irc/network/modals/registration.html" parser_classes = [FormParser] def post(self, request): """ Confirm registration for networks. """ updated = threshold.irc_check_auth(request.data) message = "Re-checked authentication successfully." message_class = "success" if not updated["success"]: message = updated["reason"] message_class = "danger" if "net" in request.data: if request.data["net"] != "None": net = request.data["net"] else: net = None else: net = None unreg = threshold.irc_get_unreg(net) if not unreg: message = "Could not get registration status." message_class = "danger" elif not unreg["success"]: if "reason" in unreg: message = unreg["reason"] message_class = "danger" else: message = "Getting registration status failed." message_class = "danger" context = { "net": net, "message": message, "class": message_class, } if "unreg" in unreg: context["unreg"] = unreg["unreg"] return render(request, self.template_name, context) class ThresholdIRCAliasesEdit(SuperUserRequiredMixin, APIView): template_name = "manage/threshold/irc/overview/modals/edit-aliases.html" parser_classes = [FormParser] def get(self, request): """ Get aliases edit form. """ aliases = threshold.get_aliases() context = { "aliases": aliases["aliases"], } return render(request, self.template_name, context) def post(self, request): """ Set the aliases """ message = "Successfully updated aliases" message_class = "success" new_aliases = {} for item in request.data: if "|" not in item: continue spl = item.split("|") if len(spl) != 2: message = f"Invalid item: {item}" message_class = "danger" break num, field = spl value = request.data[item] if field == "emails": value = request.data[item].split("\n") for email in value: # Check field isn't just empty if len(email) != 0: # Simple check for valid email if "@" not in email: message = f"Invalid email: {email}" message_class = "danger" break if num not in new_aliases: new_aliases[num] = {field: value} else: new_aliases[num][field] = value if not message_class == "danger": updated = threshold.update_aliases(new_aliases) if not updated: message = updated["reason"] message_class = "danger" template_name = "manage/threshold/irc/overview/aliases.html" aliases = threshold.get_aliases() context = { "aliases": aliases["aliases"], "message": message, "class": message_class, } return render(request, template_name, context) class ThresholdIRCNetworkActions(SuperUserRequiredMixin, View): template_name = "manage/threshold/irc/network/actions.html" def get(self, request, net): """ Get actions page. """ context = {"net": net} return render(request, self.template_name, context) class ThresholdIRCNetworkActionsAuto(SuperUserRequiredMixin, View): template_name = "manage/threshold/irc/network/actions.html" def post(self, request, net): """ Run network automation. """ ran = threshold.run_auto(net) if ran["success"]: message = f"Ran auto on network {net}" message_class = "success" if "message" in ran: message = ran["message"] else: message = ran["reason"] message_class = "danger" context = { "net": net, "message": message, "class": message_class, } return render(request, self.template_name, context) class ThresholdIRCNetworkList(SuperUserRequiredMixin, View): template_name = "manage/threshold/irc/network/actions.html" def post(self, request, net): """ Run LIST on network. """ ran = threshold.run_list(net) if ran["success"]: message = f"Ran list on network {net}" message_class = "success" if "message" in ran: message = ran["message"] else: message = ran["reason"] message_class = "danger" context = { "net": net, "message": message, "class": message_class, } return render(request, self.template_name, context) def get(self, request, net): """ Get list results from network. """ template_name = "manage/threshold/irc/network/stats.html" listinfo = threshold.get_irc_list_info(net) if not listinfo["success"]: if "reason" in listinfo: message = listinfo["reason"] else: message = "Could not get list info." message = listinfo["reason"] message_class = "danger" context = {"message": message, "class": message_class} return render(request, template_name, context) context = { "net": net, "list": listinfo["listinfo"], } return render(request, template_name, context) class ThresholdIRCNetworkActionsRelay(SuperUserRequiredMixin, APIView): template_name = "manage/threshold/irc/network/actions.html" parser_classes = [FormParser] def put(self, request, net): """ Create a relay """ if "num" not in request.data: num = 0 else: num = request.data["num"] if not num.isdigit(): message = "Num is not an integer" message_class = "danger" else: num = int(num) created = threshold.add_relay(net, num) if created["success"]: id = created["id"] alias = created["alias"] message = f"Created new relay {id} with alias {alias}" message_class = "success" else: message = created["reason"] message_class = "danger" context = { "net": net, "message": message, "class": message_class, } return render(request, self.template_name, context) class ThresholdIRCSendMessage(SuperUserRequiredMixin, APIView): parser_classes = [FormParser] template_name = "partials/context-input.html" def put(self, request, net, num, nick=None): """ Send a message """ if "msg" not in request.data: message = "No message to send" message_class = "danger" return render( request, self.template_name, {"message": message, "class": message_class}, ) if "channel" not in request.data: message = "No channel" message_class = "danger" return render( request, self.template_name, {"message": message, "class": message_class}, ) if nick: messaged = threshold.send_irc_message( net, num, request.data["channel"], request.data["msg"], nick=nick ) else: messaged = threshold.send_irc_message( net, num, request.data["channel"], request.data["msg"] ) if not messaged: message = "Failed to send message" message_class = "danger" elif messaged["success"]: message = "Send message" message_class = "success" else: message = messaged["reason"] message_class = "danger" context = { "net": net, "message": message, "class": message_class, } return render(request, self.template_name, context)