def config_action_post(page_name, action): bottle.SimpleTemplate.defaults["active_config_page_key"] = page_name bottle.Jinja2Template.defaults["active_config_page_key"] = page_name ConfigPage = get_config_page(page_name) config_page = ConfigPage(request.POST.decode()) if request.is_xhr: if request.POST.pop("_update", None): # if update was requested, just render the page - otherwise handle actions as usual return config_page.render(is_xhr=True) # check if the button click wasn't any sub-action subaction = request.POST.pop("action", None) if subaction: return config_action_post(page_name, subaction) try: result = config_page.call_action(action) try: if not result: bottle.redirect(reverse("config_page", page_name=page_name)) except TypeError: # raised by Validator - could happen when the form is posted with wrong fields messages.error(_("Configuration could not be saved due to an internal error.")) logger.exception("Error when saving form.") logger.warning("Form not saved.") return result except ValueError: raise bottle.HTTPError(404, "Unknown action.")
def top_index(): session = bottle.request.environ["foris.session"] if bottle.request.method == "POST": next = bottle.request.POST.get("next", None) login(next, session) # if login passes it will redirect to a proper page # otherwise it contains next parameter messages.error(_("The password you entered was not valid.")) response.status = 403 else: next = bottle.request.GET.get("next", None) if not current_state.password_set: # auto login if no password is set if session.is_anonymous: session.recreate() session["user_authenticated"] = True session.save() if session.get("user_authenticated"): login_redirect() return dict( luci_path="//%(host)s/%(path)s" % {"host": bottle.request.get_header("host"), "path": "cgi-bin/luci"}, next=next, )
def _action_download_config(self): """Handle POST requesting download of the openvpn client config :return: response with token with appropriate HTTP headers """ form = self.get_address_form(bottle.request.POST) res = current_state.backend.perform( "openvpn", "get_client_config", { "id": self.data['download-config'], "hostname": form.data["server-address"] if form.data["server-address"] else "", }) if res["status"] != "valid": messages.error(_("Unable to get OpenVPN client config.")) bottle.redirect(reverse("config_page", page_name="openvpn")) bottle.response.set_header("Content-Type", "text/plain") # TODO .ovpn for windows bottle.response.set_header("Content-Disposition", 'attachment; filename="turris.conf"') bottle.response.set_header("Content-Length", len(res["config"])) return res["config"]
def save(self, *args, **kwargs): result = super(NetworksConfigPage, self).save(no_messages=True, *args, **kwargs) if self.form.callback_results["result"]: messages.success(_("Network configuration was sucessfully updated.")) else: messages.error(_("Unable to update your network configuration.")) return result
def form_callback(data): msg = {"enabled": data['enabled']} if msg["enabled"]: msg["network"], prefix = data['network'].split("/") mask = prefix_to_mask_4(int(prefix)) msg["network_netmask"] = mask msg["route_all"] = data['default_route'] msg["use_dns"] = data['dns'] msg["ipv6"] = data['ipv6'] msg["protocol"] = data['protocol'] res = current_state.backend.perform("openvpn", "update_settings", msg) if res["result"]: messages.success( _('OpenVPN server configuration was successfully %s.') % (_('enabled') if msg["enabled"] else _('disabled'))) else: messages.error( _('Failed to %s OpenVPN server configuration.') % (_('enable') if msg["enabled"] else _('disable'))) return "none", None
def save(self, *args, **kwargs): result = super(UpdaterConfigPage, self).save(no_messages=True, *args, **kwargs) target = self.form.callback_results.get("target", None) if target in ["deny", "grant"]: result = self.form.callback_results["result"] if result: if target == "grant": messages.success(_("Update was approved.")) elif target == "deny": messages.success(_("Update was postponed.")) else: if target == "grant": messages.error(_("Failed to approve the update.")) elif target == "deny": messages.error(_("Failed to postpone the update.")) return result if result: if self.form.callback_results.get("enabled", False): messages.success( _("Configuration was successfully saved. Selected " "packages should be installed or removed shortly.")) else: messages.success(_("Configuration was successfully saved.")) else: messages.warning(_("There were some errors in your input.")) return result
def save(self, *args, **kwargs): result = super(ProfileConfigPage, self).save(no_messages=True, *args, **kwargs) if self.form.callback_results["result"]: messages.success(_("Guide workflow was sucessfully set.")) else: messages.error(_("Failed to set guide workflow.")) return result
def config_action_post(page_name, action): bottle.SimpleTemplate.defaults["active_config_page_key"] = page_name bottle.Jinja2Template.defaults["active_config_page_key"] = page_name ConfigPage = get_config_page(page_name) config_page = ConfigPage(request.POST.decode()) if request.is_xhr: if request.POST.pop("_update", None): # if update was requested, just render the page - otherwise handle actions as usual return config_page.render(is_xhr=True) # check if the button click wasn't any sub-action subaction = request.POST.pop("action", None) if subaction: return config_action_post(page_name, subaction) try: result = config_page.call_action(action) try: if not result: bottle.redirect(reverse("config_page", page_name=page_name)) except TypeError: # raised by Validator - could happen when the form is posted with wrong fields messages.error( _("Configuration could not be saved due to an internal error.") ) logger.exception("Error when saving form.") logger.warning("Form not saved.") return result except ValueError: raise bottle.HTTPError(404, "Unknown action.")
def top_index(): session = bottle.request.environ["foris.session"] if bottle.request.method == "POST": next = bottle.request.POST.get("next", None) login(next, session) # if login passes it will redirect to a proper page # otherwise it contains next parameter messages.error(_("The password you entered was not valid.")) response.status = 403 else: next = bottle.request.GET.get("next", None) if not current_state.password_set: # auto login if no password is set if session.is_anonymous: session.recreate() session["user_authenticated"] = True session.save() if session.get("user_authenticated"): login_redirect() return dict( luci_path="//%(host)s/%(path)s" % { "host": bottle.request.get_header("host"), "path": "cgi-bin/luci" }, next=next, )
def save(self, *args, **kwargs): result = super(UpdaterConfigPage, self).save(no_messages=True, *args, **kwargs) target = self.form.callback_results.get("target", None) if target in ["deny", "grant"]: result = self.form.callback_results["result"] if result: if target == "grant": messages.success(_("Update was approved.")) elif target == "deny": messages.success(_("Update was postponed.")) else: if target == "grant": messages.error(_("Failed to approve the update.")) elif target == "deny": messages.error(_("Failed to postpone the update.")) return result if result: messages.success( _( "Configuration was successfully saved. Selected " "packages should be installed or removed shortly." ) ) else: messages.warning(_("There were some errors in your input.")) return result
def _action_delete_ca(self): self._check_post() data = current_state.backend.perform("remote", "delete_ca") if data["result"]: messages.success(_("CA for remote access was sucessfully deleted.")) else: messages.error(_("Failed to delete CA for remote access.")) bottle.redirect(reverse("config_page", page_name="remote"))
def _check_and_get_controller_id(self): if bottle.request.method != "POST": messages.error(_("Wrong HTTP method.")) bottle.redirect(reverse("config_page", page_name="remote")) form = self.get_controller_id_form(bottle.request.POST.decode()) if not form.data["controller_id"]: raise bottle.HTTPError(404, "controller_id not found") return form.data["controller_id"]
def _action_check_registration(self): handler = RegistrationCheckHandler(bottle.request.POST.decode()) if not handler.save(): messages.warning(_("There were some errors in your input.")) return self.render(registration_check_form=handler.form) email = handler.data["email"] result = handler.form.callback_results kwargs = {} if not result["success"]: messages.error( _("An error ocurred when checking the registration: " "<br><pre>%(error)s</pre>" % dict(error=result["error"]))) return self.render() else: if result["status"] == "owned": messages.success( _("Registration for the entered email is valid. " "Now you can enable the data collection.")) collection_toggle_handler = CollectionToggleHandler( bottle.request.POST.decode()) kwargs[ 'collection_toggle_form'] = collection_toggle_handler.form elif result["status"] == "foreign": messages.warning( _('This router is currently assigned to a different email address. Please ' 'continue to the <a href="%(url)s">Turris website</a> and use the ' 'registration code <strong>%(reg_num)s</strong> for a re-assignment to your ' 'email address.') % dict(url=result["url"], reg_num=result["registration_number"])) bottle.redirect( reverse("config_page", page_name="data_collect") + "?" + urlencode({"email": email})) elif result["status"] == "free": messages.info( _('This email address is not registered yet. Please continue to the ' '<a href="%(url)s">Turris website</a> and use the registration code ' '<strong>%(reg_num)s</strong> to create a new account.') % dict(url=result["url"], reg_num=result["registration_number"])) bottle.redirect( reverse("config_page", page_name="data_collect") + "?" + urlencode({"email": email})) elif result["status"] == "not_found": messages.error( _('Router failed to authorize. Please try to validate our email later.' )) bottle.redirect( reverse("config_page", page_name="data_collect") + "?" + urlencode({"email": email})) return self.render(status=result["status"], registration_url=result["url"], reg_num=result["registration_number"], **kwargs)
def _action_save_notifications(self): if bottle.request.method != "POST": messages.error(_("Wrong HTTP method.")) bottle.redirect(reverse("config_page", page_name="maintenance")) handler = notifications.NotificationsHandler(bottle.request.POST.decode()) if handler.save(): messages.success(_("Configuration was successfully saved.")) bottle.redirect(reverse("config_page", page_name="maintenance")) messages.warning(_("There were some errors in your input.")) return super(MaintenanceConfigPage, self).render(notifications_form=handler.form)
def save(self, *args, **kwargs): super().save(no_messages=True, *args, **kwargs) result = self.form.callback_results.get('result', False) if result: messages.success(_("Configuration was successfully saved.")) else: messages.error( _("Failed to update emulated services. Note that you might need to wait till " "ucollect is properly installed.")) return result
def _action_save_notifications(self): if bottle.request.method != 'POST': messages.error(_("Wrong HTTP method.")) bottle.redirect(reverse("config_page", page_name="maintenance")) handler = notifications.NotificationsHandler(request.POST.decode()) if handler.save(): messages.success(_("Configuration was successfully saved.")) bottle.redirect(reverse("config_page", page_name="maintenance")) messages.warning(_("There were some errors in your input.")) return super(MaintenanceConfigPage, self).render(notifications_form=handler.form)
def call_action(self, action): if bottle.request.method != 'POST': messages.error("Wrong HTTP method.") bottle.redirect(reverse("config_page", page_name="netmetr")) if action == "redownload": self._action_download_data() elif action == "start": self._action_measure_and_download_data() raise bottle.HTTPError(404, "Unknown action.")
def maintenance_form_cb(data): client_name = data['client_name'] if new_client(client_name): messages.success( _("Request for creating a new client \"%s\" was succesfully submitted. " "Client token should be available for download in a minute." ) % client_name) else: messages.error( _("An error occurred when creating client \"%s\".") % client_name) return "none", None
def _action_toggle_collecting(self): if bottle.request.method != 'POST': messages.error(_("Wrong HTTP method.")) bottle.redirect(reverse("config_page", page_name="data_collect")) handler = CollectionToggleHandler(bottle.request.POST.decode()) if handler.save(): messages.success(_("Configuration was successfully saved.")) bottle.redirect(reverse("config_page", page_name="data_collect")) messages.warning(_("There were some errors in your input.")) return super().render(collection_toggle_form=handler.form)
def _action_revoke(self): """Handle POST requesting revoking client certificate config :return: response with token with appropriate HTTP headers """ res = current_state.backend.perform("openvpn", "revoke", {"id": self.data['revoke-client']}) if res["result"]: messages.success( _("The client certificate was successfully revoked.")) else: messages.error(_("Failed to revoke the client certificate.")) return bottle.redirect(reverse("config_page", page_name="openvpn"))
def _action_reset(self): if bottle.request.method != "POST": messages.error(_("Wrong HTTP method.")) bottle.redirect(reverse("config_page", page_name="wifi")) data = current_state.backend.perform("wifi", "reset") if "result" in data and data["result"] is True: messages.success(_("Wi-Fi reset was successful.")) else: messages.error(_("Failed to perform Wi-Fi reset.")) bottle.redirect(reverse("config_page", page_name="wifi"))
def _action_reset_ca(self): """Call RPC for resetting the CA and redirect back. :return: redirect to plugin's main page """ if reset_ca(): messages.success( _("Reset of the certification authority was successfully submitted." )) else: messages.error(_("An error occurred when trying to reset the CA.")) bottle.redirect(reverse("config_page", page_name="tls"))
def _action_generic(self, action): if bottle.request.method != "POST": messages.error(_("Wrong HTTP method.")) bottle.redirect(reverse("config_page", page_name="remote")) form = self.get_serial_form(bottle.request.POST.decode()) if not form.data["serial"]: raise bottle.HTTPError(404, "serial not found") res = current_state.backend.perform("netboot", action, {"serial": form.data["serial"]}) bottle.response.set_header("Content-Type", "application/json") return res
def make_token_response(client_name): token = get_token(client_name) if not token: messages.error( _("Unable to get token for user \"%s\".") % client_name) bottle.redirect(reverse("config_page", page_name="tls")) bottle.response.set_header("Content-Type", "application/x-pem-file") bottle.response.set_header( "Content-Disposition", 'attachment; filename="%s.pem' % client_name) bottle.response.set_header("Content-Length", len(token)) return token
def call_action(self, action): if bottle.request.method != 'POST': # all actions here require POST messages.error("Wrong HTTP method.") bottle.redirect(reverse("config_page", page_name="tls")) if action == "get-token": if bottle.request.POST.get("qrcode"): # Button for QR token generation has been clicked return self._action_generate_token_qrcode_data() return self._action_get_token() elif action == "reset-ca": return self._action_reset_ca() raise bottle.HTTPError(404, "Unknown action.")
def save(self, *args, **kwargs): super(SubordinatesSetupPage, self).save(no_messages=True, *args, **kwargs) data = self.form.callback_results if data["result"]: messages.success( _("Token was successfully added and client '%(controller_id)s' " "should be visible in a moment.") % dict(controller_id=data["controller_id"])) else: messages.error(_("Failed to add token.")) return data["result"]
def call_action(self, action): if bottle.request.method != 'POST': # all actions here require POST messages.error("Wrong HTTP method.") bottle.redirect(reverse("config_page", page_name="openvpn")) if action == "download-config": return self._action_download_config_or_revoke() elif action == "generate-ca": return self._action_generate_ca() elif action == "generate-client": return self._action_generate_client() elif action == "delete-ca": return self._action_delete_ca() raise bottle.HTTPError(404, "Unknown action.")
def save(self, *args, **kwargs): result = super(PasswordConfigPage, self).save(no_messages=True, *args, **kwargs) wrong_old_password = self.form.callback_results.get( "wrong_old_password", False) system_password_no_error = self.form.callback_results.get( "system_password_no_error", None) foris_password_no_error = self.form.callback_results.get( "foris_password_no_error", None) compromised = self.form.callback_results.get("compromised") if compromised: messages.error( _("The password you've entered has been compromised. " "It appears %(count)d times in '%(list)s' list.") % dict(count=compromised["count"], list=compromised["list"])) return result if wrong_old_password: messages.error(_("Old password you entered was not valid.")) return result if system_password_no_error is not None: if system_password_no_error: messages.success(_("System password was successfully saved.")) else: messages.error(_("Failed to save system password.")) if foris_password_no_error is not None: if foris_password_no_error: messages.success(_("Foris password was successfully saved.")) else: messages.error(_("Failed to save Foris password.")) return result
def save(self, *args, **kwargs): result = super(PasswordConfigPage, self).save(no_messages=True, *args, **kwargs) wrong_old_password = self.form.callback_results.get("wrong_old_password", False) system_password_no_error = self.form.callback_results.get("system_password_no_error", None) foris_password_no_error = self.form.callback_results.get("foris_password_no_error", None) compromised = self.form.callback_results.get("compromised") if compromised: messages.error( _( "The password you've entered has been compromised. " "It appears %(count)d times in '%(list)s' list." ) % dict(count=compromised["count"], list=compromised["list"]) ) return result if wrong_old_password: messages.error(_("Old password you entered was not valid.")) return result if system_password_no_error is not None: if system_password_no_error: messages.success(_("System password was successfully saved.")) else: messages.error(_("Failed to save system password.")) if foris_password_no_error is not None: if foris_password_no_error: messages.success(_("Foris password was successfully saved.")) else: messages.error(_("Failed to save Foris password.")) return result
def save(self, *args, **kwargs): kwargs["no_messages"] = True result = super().save(*args, **kwargs) if self.form.callback_results["enabled"]: if self.form.callback_results["result"]: messages.success(_("Remote access was sucessfully enabled.")) else: messages.error( _("Failed to enable the remote access. You are probably using " "a message bus which doesn't support the remote access or " "the CA for remote access hasn't been generated yet.")) else: if self.form.callback_results["result"]: messages.success(_("Remote access was sucessfully disabled.")) else: messages.error(_("Failed to disable remote access.")) return result
def _action_test_notifications(self): if bottle.request.method != 'POST': messages.error(_("Wrong HTTP method.")) bottle.redirect(reverse("config_page", page_name="maintenance")) data = current_state.backend.perform( "router_notifications", "create", { "msg": "_(This is a testing notification. Please ignore me.)", "severity": "news", "immediate": True, } ) if data["result"]: messages.success(_("Testing message was sent, please check your inbox.")) else: messages.error(_( "Sending of the testing message failed, your configuration is possibly wrong." )) bottle.redirect(reverse("config_page", page_name="maintenance"))
def config_page_post(page_name): bottle.SimpleTemplate.defaults['active_config_page_key'] = page_name bottle.Jinja2Template.defaults['active_config_page_key'] = page_name ConfigPage = get_config_page(page_name) config_page = ConfigPage(request.POST.decode()) if request.is_xhr: if request.POST.pop("update", None): # if update was requested, just render the page - otherwise handle actions as usual pass else: config_page.save() return config_page.render(is_xhr=True) try: if config_page.save(): bottle.redirect(request.fullpath) except TypeError: # raised by Validator - could happen when the form is posted with wrong fields messages.error(_("Configuration could not be saved due to an internal error.")) logger.exception("Error when saving form.") logger.warning("Form not saved.") return config_page.render(active_config_page_key=page_name)
def _action_test_notifications(self): if bottle.request.method != "POST": messages.error(_("Wrong HTTP method.")) bottle.redirect(reverse("config_page", page_name="maintenance")) data = current_state.backend.perform( "router_notifications", "create", { "msg": "_(This is a testing notification. Please ignore me.)", "severity": "news", "immediate": True, }, ) if data["result"]: messages.success(_("Testing message was sent, please check your inbox.")) else: messages.error( _("Sending of the testing message failed, your configuration is possibly wrong.") ) bottle.redirect(reverse("config_page", page_name="maintenance"))
def config_page_post(page_name): bottle.SimpleTemplate.defaults["active_config_page_key"] = page_name bottle.Jinja2Template.defaults["active_config_page_key"] = page_name ConfigPage = get_config_page(page_name) config_page = ConfigPage(request.POST.decode()) if request.is_xhr: if request.POST.pop("_update", None): # if update was requested, just render the page - otherwise handle actions as usual pass else: config_page.save() return config_page.render(is_xhr=True) try: if config_page.save(): bottle.redirect(request.fullpath) except TypeError: # raised by Validator - could happen when the form is posted with wrong fields messages.error(_("Configuration could not be saved due to an internal error.")) logger.exception("Error when saving form.") logger.warning("Form not saved.") return config_page.render(active_config_page_key=page_name)
def save(self, *args, **kwargs): result = super(PasswordConfigPage, self).save(no_messages=True, *args, **kwargs) wrong_old_password = self.form.callback_results.get('wrong_old_password', False) system_password_no_error = self.form.callback_results.get('system_password_no_error', None) foris_password_no_error = self.form.callback_results.get('foris_password_no_error', None) if wrong_old_password: messages.error(_("Old password you entered was not valid.")) return result if system_password_no_error is not None: if system_password_no_error: messages.success(_("System password was successfully saved.")) else: messages.error(_("Failed to save system password")) if foris_password_no_error is not None: if foris_password_no_error: messages.success(_("Foris password was successfully saved.")) else: messages.error(_("Failed to save Foris password")) return result
def _check_post(self): if bottle.request.method != "POST": messages.error(_("Wrong HTTP method.")) bottle.redirect(reverse("config_page", page_name="remote"))
def save(self, *args, **kwargs): result = super().save(no_messages=True, *args, **kwargs) if not self.form.callback_results["result"]: messages.error(_("Failed to finish the guide.")) return result