def _page_search_open(self): # type: () -> None q = _maybe_strip(html.request.var('q')) if not q: return url = generate_search_results(q) raise HTTPRedirect(url)
def page_index() -> None: # Redirect to mobile GUI if we are a mobile device and the index is requested if is_mobile(request, response): raise HTTPRedirect(makeuri(request, [], filename="mobile.py")) title = get_page_heading() content = HTMLWriter.render_iframe("", src=_get_start_url(), name="main") SidebarRenderer().show(title, content)
def _page_search_open(self) -> None: """Generate the URL to the view that is opened when confirming the search field""" query = _maybe_strip(html.request.var('q')) if not query: return raise HTTPRedirect( self._quicksearch_manager.generate_search_url(query))
def _show_form(self, profile_changed: bool) -> None: assert config.user.id is not None users = userdb.load_users() change_reason = html.request.get_ascii_input('reason') if change_reason == 'expired': html.p( _('Your password is too old, you need to choose a new password.' )) elif change_reason == 'enforced': html.p( _('You are required to change your password before proceeding.' )) if profile_changed: html.show_message(_("Your password has been changed.")) if change_reason: raise HTTPRedirect( html.request.get_str_input_mandatory( '_origtarget', 'index.py')) if html.has_user_errors(): html.show_user_errors() user = users.get(config.user.id) if user is None: html.show_warning(_("Sorry, your user account does not exist.")) html.footer() return locked_attributes = userdb.locked_attributes(user.get('connector')) if "password" in locked_attributes: raise MKUserError( "cur_password", _("You can not change your password, because it is " "managed by another system.")) html.begin_form("profile", method="POST") html.prevent_password_auto_completion() html.open_div(class_="wato") forms.header(self._page_title()) forms.section(_("Current Password")) html.password_input('cur_password', autocomplete="new-password") forms.section(_("New Password")) html.password_input('password', autocomplete="new-password") forms.section(_("New Password Confirmation")) html.password_input('password2', autocomplete="new-password") forms.end() html.close_div() html.hidden_fields() html.end_form() html.footer()
def page(self) -> None: assert config.user.id is not None _invalidate_auth_session() session_id = _get_session_id_from_cookie(config.user.id) userdb.on_logout(config.user.id, session_id) if auth_type == 'cookie': raise HTTPRedirect(config.url_prefix() + 'check_mk/login.py') # Implement HTTP logout with cookie hack if not html.request.has_cookie('logout'): html.response.headers['WWW-Authenticate'] = ( 'Basic realm="OMD Monitoring Site %s"' % config.omd_site()) html.response.set_http_cookie('logout', '1') raise FinalizeRequest(http.client.UNAUTHORIZED) html.response.delete_cookie('logout') raise HTTPRedirect(config.url_prefix() + 'check_mk/')
def _redirect_for_two_factor_authentication(user_id: UserId) -> None: if requested_file_name(request) in ( "user_login_two_factor", "user_webauthn_login_begin", "user_webauthn_login_complete", ): return if userdb.is_two_factor_login_enabled( user_id) and not userdb.is_two_factor_completed(): raise HTTPRedirect("user_login_two_factor.py?_origtarget=%s" % urlencode(makeuri(request, [])))
def page(self) -> None: assert user.id is not None _invalidate_auth_session() session_id = _get_session_id_from_cookie(user.id, revalidate_cookie=True) userdb.on_logout(user.id, session_id) if auth_type == "cookie": # type: ignore[has-type] raise HTTPRedirect(url_prefix() + "check_mk/login.py") # Implement HTTP logout with cookie hack if not request.has_cookie("logout"): response.headers["WWW-Authenticate"] = ( 'Basic realm="OMD Monitoring Site %s"' % omd_site()) response.set_http_cookie("logout", "1", secure=request.is_secure) raise FinalizeRequest(http.client.UNAUTHORIZED) response.delete_cookie("logout") raise HTTPRedirect(url_prefix() + "check_mk/")
def page(self) -> None: job_status_snapshot = self._job.get_status_snapshot() if job_status_snapshot.is_active(): raise HTTPRedirect(self._job.detail_url()) html.begin_form("diagnostics", method="POST") vs_diagnostics = self._vs_diagnostics() vs_diagnostics.render_input("diagnostics", {}) html.hidden_fields() html.end_form()
def _action(self): if not html.transaction_valid(): return action_handler = gui_background_job.ActionHandler() if action_handler.handle_actions() and action_handler.did_delete_job(): raise HTTPRedirect( html.makeuri_contextless([ ("host", self._request.host.name()), ("type", self._request.agent_type), ("back_url", self._back_url), ]))
def show_create_view_dialog(next_url=None): vs_ds = DatasourceSelection() ds = "services" # Default selection title = _("Create view") breadcrumb = visuals.visual_page_breadcrumb("views", title, "create") make_header( html, title, breadcrumb, make_simple_form_page_menu( _("View"), breadcrumb, form_name="create_view", button_name="_save", save_title=_("Continue"), ), ) if request.var("_save") and transactions.check_transaction(): try: ds = vs_ds.from_html_vars("ds") vs_ds.validate_value(ds, "ds") if not next_url: next_url = makeuri( request, [("datasource", ds)], filename="create_view_infos.py", ) else: next_url = next_url + "&datasource=%s" % ds raise HTTPRedirect(next_url) except MKUserError as e: html.user_error(e) html.begin_form("create_view") html.hidden_field("mode", "create") forms.header(_("Select Datasource")) forms.section(vs_ds.title()) vs_ds.render_input("ds", ds) html.help(vs_ds.help()) forms.end() html.hidden_fields() html.end_form() html.footer()
def action(self) -> ActionResult: try: transactions.check_transaction() user.save_file("parentscan", dict(self._settings._asdict())) self._job.set_function(self._job.do_execute, self._settings, self._get_tasks()) self._job.start() except Exception as e: if active_config.debug: raise logger.exception("Failed to start parent scan") raise MKUserError( None, _("Failed to start parent scan: %s") % ("%s" % e).replace("\n", "\n<br>") ) raise HTTPRedirect(self._job.detail_url())
def _action(self) -> None: if not transactions.transaction_valid(): return action_handler = gui_background_job.ActionHandler(self._breadcrumb(self._title())) if action_handler.handle_actions() and action_handler.did_delete_job(): raise HTTPRedirect( makeuri_contextless( global_request, [ ("host", self._request.host.name()), ("type", self._request.agent_type), ("back_url", self._back_url), ], ))
def _handle_not_authenticated(): if _fail_silently(): # While api call don't show the login dialog raise MKUnauthenticatedException(_('You are not authenticated.')) # Redirect to the login-dialog with the current url as original target # Never render the login form directly when accessing urls like "index.py" # or "dashboard.py". This results in strange problems. if html.myfile != 'login': raise HTTPRedirect( '%scheck_mk/login.py?_origtarget=%s' % (config.url_prefix(), html.urlencode(html.makeuri([])))) # This either displays the login page or validates the information submitted # to the login form. After successful login a http redirect to the originally # requested page is performed. login_page = login.LoginPage() login_page.set_no_html_output(_plain_error()) login_page.handle_page()
def action(self): config.user.need_permission("wato.services") tasks = get_tasks(self._get_hosts_to_discover(), self._bulk_size) try: html.check_transaction() self._job.set_function(self._job.do_execute, self._mode, self._use_cache, self._do_scan, self._error_handling, tasks) self._job.start() except Exception as e: if config.debug: raise logger.exception("Failed to start bulk discovery") raise MKUserError( None, _("Failed to start discovery: %s") % ("%s" % e).replace("\n", "\n<br>")) raise HTTPRedirect(self._job.detail_url())
def action(self) -> ActionResult: if transactions.check_transaction(): value = self._vs_key().from_html_vars("key") # Remove the secret key from known URL vars. Otherwise later constructed URLs # which use the current page context will contain the passphrase which could # leak the secret information request.del_var("key_p_passphrase") self._vs_key().validate_value(value, "key") self._create_key(value["alias"], value["passphrase"]) # FIXME: This leads to a circular import otherwise. This module (cmk.gui.key_mgmt) is # clearly outside of either cmk.gui.plugins.wato and cmk.gui.cee.plugins.wato so this # is obviously a very simple module-layer violation. This whole module should either # * be moved into cmk.gui.cee.plugins.wato # * or cmk.gui.cee.plugins.wato.module_registry should be moved up # Either way, this is outside my scope right now and shall be fixed. from cmk.gui.plugins.wato.utils.base_modes import mode_url return HTTPRedirect(mode_url(self.back_mode)) return None
def action(self): renaming_config = self._vs_renaming_config().from_html_vars("") self._vs_renaming_config().validate_value(renaming_config, "") renamings = self._collect_host_renamings(renaming_config) if not renamings: return None, _("No matching host names") warning = self._renaming_collision_error(renamings) if warning: return None, warning message = _( "<b>Do you really want to rename to following hosts? This involves a restart of the monitoring core!</b>" ) message += "<table>" for _folder, host_name, target_name in renamings: message += u"<tr><td>%s</td><td> → %s</td></tr>" % (host_name, target_name) message += "</table>" c = wato_confirm( _("Confirm renaming of %d hosts") % len(renamings), HTML(message)) if c: title = _("Renaming of %s") % ", ".join(u"%s → %s" % x[1:] for x in renamings) host_renaming_job = RenameHostsBackgroundJob(title=title) host_renaming_job.set_function(rename_hosts_background_job, renamings) try: host_renaming_job.start() except background_job.BackgroundJobAlreadyRunning as e: raise MKGeneralException( _("Another host renaming job is already running: %s") % e) raise HTTPRedirect(host_renaming_job.detail_url()) elif c is False: # not yet confirmed return "" else: return None # browser reload
def _check_auth_cookie(cookie_name: str) -> Optional[UserId]: username, session_id, cookie_hash = _parse_auth_cookie(cookie_name) _check_parsed_auth_cookie(username, session_id, cookie_hash) try: userdb.on_access(username, session_id) except MKAuthException: del_auth_cookie() raise # Once reached this the cookie is a good one. Renew it! _renew_cookie(cookie_name, username, session_id) if html.myfile != 'user_change_pw': result = userdb.need_to_change_pw(username) if result: raise HTTPRedirect('user_change_pw.py?_origtarget=%s&reason=%s' % (html.urlencode(html.makeuri([])), result)) # Return the authenticated username return username
def page(self) -> None: assert user.id is not None html.render_headfoot = False html.add_body_css_class("login") html.add_body_css_class("two_factor") make_header(html, _("Two-factor authentication"), Breadcrumb(), javascripts=[]) html.open_div(id_="login") html.open_div(id_="login_window") html.open_a(href="https://checkmk.com") html.img( src=theme.detect_icon_path(icon_name="logo", prefix="mk-"), id_="logo", class_="custom" if theme.has_custom_logo() else None, ) html.close_a() if not is_two_factor_login_enabled(user.id): raise MKGeneralException( _("Two-factor authentication not enabled")) html.begin_form("two_factor_login", method="POST", add_transid=False, action="user_login_two_factor.py") html.prevent_password_auto_completion() html.hidden_field( "_origtarget", origtarget := request.get_url_input("_origtarget", "index.py")) if backup_code := request.get_ascii_input("_backup_code"): if is_two_factor_backup_code_valid(user.id, backup_code): set_two_factor_completed() raise HTTPRedirect(origtarget)
def action(self): if not html.transaction_valid(): return "folder" attributes = watolib.collect_attributes(self._host_type_name(), new=True) cluster_nodes = self._get_cluster_nodes() hostname = html.request.get_ascii_input_mandatory("host") Hostname().validate_value(hostname, "host") if html.check_transaction(): watolib.Folder.current().create_hosts([(hostname, attributes, cluster_nodes)]) self._host = watolib.Folder.current().host(hostname) inventory_url = watolib.folder_preserving_link([ ("mode", "inventory"), ("host", self._host.name()), ("_scan", "1"), ]) if not self._host.is_ping_host(): create_msg = _( 'Successfully created the host. Now you should do a ' '<a href="%s">service discovery</a> in order to auto-configure ' 'all services to be checked on this host.') % inventory_url else: create_msg = None if html.request.var("services"): raise HTTPRedirect(inventory_url) if html.request.var("diag_host"): html.request.set_var("_try", "1") return "diag_host", create_msg return "folder", create_msg
def _check_auth_cookie(cookie_name: str) -> Optional[UserId]: username, session_id, cookie_hash = user_from_cookie( _fetch_cookie(cookie_name)) check_parsed_auth_cookie(username, session_id, cookie_hash) try: userdb.on_access(username, session_id) except MKAuthException: del_auth_cookie() raise # Once reached this the cookie is a good one. Renew it! _renew_cookie(cookie_name, username, session_id) if requested_file_name(request) != "user_change_pw": result = userdb.need_to_change_pw(username) if result: raise HTTPRedirect("user_change_pw.py?_origtarget=%s&reason=%s" % (urlencode(makeuri(request, [])), result)) # Return the authenticated username return username
def action(self) -> ActionResult: user.need_permission("wato.services") try: transactions.check_transaction() start_bulk_discovery( self._job, self._get_hosts_to_discover(), self._mode, self._do_full_scan, self._ignore_errors, self._bulk_size, ) except Exception as e: if active_config.debug: raise logger.exception("Failed to start bulk discovery") raise MKUserError( None, _("Failed to start discovery: %s") % ("%s" % e).replace("\n", "\n<br>")) raise HTTPRedirect(self._job.detail_url())
def _show_login_page(self) -> None: html.set_render_headfoot(False) html.add_body_css_class("login") html.header(config.get_page_heading(), Breadcrumb(), javascripts=[]) default_origtarget = ("index.py" if html.myfile in ["login", "logout"] else makeuri(global_request, [])) origtarget = html.get_url_input("_origtarget", default_origtarget) # Never allow the login page to be opened in the iframe. Redirect top page to login page. # This will result in a full screen login page. html.javascript('''if(top != self) { window.top.location.href = location; }''') # When someone calls the login page directly and is already authed redirect to main page if html.myfile == 'login' and _check_auth(html.request): raise HTTPRedirect(origtarget) html.open_div(id_="login") html.open_div(id_="login_window") html.div("" if "hide_version" in config.login_screen else cmk_version.__version__, id_="version") html.begin_form("login", method='POST', add_transid=False, action='login.py') html.hidden_field('_login', '1') html.hidden_field('_origtarget', origtarget) html.label("%s:" % _('Username'), id_="label_user", class_=["legend"], for_="_username") html.br() html.text_input("_username", id_="input_user") html.label("%s:" % _('Password'), id_="label_pass", class_=["legend"], for_="_password") html.br() html.password_input("_password", id_="input_pass", size=None) if html.has_user_errors(): html.open_div(id_="login_error") html.show_user_errors() html.close_div() html.open_div(id_="button_text") html.button("_login", _('Login')) html.close_div() html.close_div() html.open_div(id_="foot") if config.login_screen.get("login_message"): html.open_div(id_="login_message") html.show_message(config.login_screen["login_message"]) html.close_div() footer: List[Union[HTML, str]] = [] for title, url, target in config.login_screen.get("footer_links", []): footer.append(html.render_a(title, href=url, target=target)) if "hide_version" not in config.login_screen: footer.append("Version: %s" % cmk_version.__version__) footer.append("© %s" % html.render_a( "tribe29 GmbH", href="https://checkmk.com", target="_blank")) html.write(HTML(" - ").join(footer)) if cmk_version.is_raw_edition(): html.br() html.br() html.write( _('You can use, modify and distribute Check_MK under the terms of the <a href="%s" target="_blank">' 'GNU GPL Version 2</a>.') % "https://checkmk.com/gpl.html") html.close_div() html.set_focus('_username') html.hidden_fields() html.end_form() html.close_div() html.footer()
def _do_login(self) -> None: """handle the sent login form""" if not html.request.var('_login'): return try: username_var = html.request.get_unicode_input('_username', '') assert username_var is not None username = UserId(username_var.rstrip()) if not username: raise MKUserError('_username', _('No username given.')) password = html.request.var('_password', '') if not password: raise MKUserError('_password', _('No password given.')) default_origtarget = config.url_prefix() + "check_mk/" origtarget = html.get_url_input("_origtarget", default_origtarget) # Disallow redirections to: # - logout.py: Happens after login # - side.py: Happens when invalid login is detected during sidebar refresh if "logout.py" in origtarget or 'side.py' in origtarget: origtarget = default_origtarget # '<user_id>' -> success # False -> failed result = userdb.hook_login(username, password) if result: assert isinstance(result, str) # use the username provided by the successful login function, this function # might have transformed the username provided by the user. e.g. switched # from mixed case to lower case. username = result # When single user session mode is enabled, check that there is not another # active session userdb.ensure_user_can_init_session(username) # reset failed login counts userdb.on_succeeded_login(username) # The login succeeded! Now: # a) Set the auth cookie # b) Unset the login vars in further processing # c) Redirect to really requested page _create_auth_session(username) # Never use inplace redirect handling anymore as used in the past. This results # in some unexpected situations. We simpy use 302 redirects now. So we have a # clear situation. # userdb.need_to_change_pw returns either False or the reason description why the # password needs to be changed change_pw_result = userdb.need_to_change_pw(username) if change_pw_result: raise HTTPRedirect( 'user_change_pw.py?_origtarget=%s&reason=%s' % (html.urlencode(origtarget), change_pw_result)) raise HTTPRedirect(origtarget) userdb.on_failed_login(username) raise MKUserError(None, _('Invalid credentials.')) except MKUserError as e: html.add_user_error(e.varname, e)
def redirect(location: str, code: int = http.client.FOUND) -> HTTPRedirect: """Returns an object triggering a redirect to another page Similar to flasks redirect method. """ return HTTPRedirect(location, code=code)
def _show_page_user_profile(change_pw): start_async_replication = False if not config.user.id: raise MKUserError(None, _('Not logged in.')) if not config.user.may('general.edit_profile') and not config.user.may( 'general.change_password'): raise MKAuthException( _("You are not allowed to edit your user profile.")) if not config.wato_enabled: raise MKAuthException( _('User profiles can not be edited (WATO is disabled).')) success = None if html.request.has_var('_save') and html.check_transaction(): users = userdb.load_users(lock=True) try: # Profile edit (user options like language etc.) if config.user.may('general.edit_profile'): if not change_pw: set_lang = html.get_checkbox('_set_lang') language = html.request.var('language') # Set the users language if requested if set_lang: if language == '': language = None # Set custom language users[config.user.id]['language'] = language config.user.language = language html.set_language_cookie(language) else: # Remove the customized language if 'language' in users[config.user.id]: del users[config.user.id]['language'] config.user.reset_language() # load the new language cmk.gui.i18n.localize(config.user.language) user = users.get(config.user.id) if config.user.may('general.edit_notifications' ) and user.get("notifications_enabled"): value = forms.get_input( watolib.get_vs_flexible_notifications(), "notification_method") users[config.user.id]["notification_method"] = value # Custom attributes if config.user.may('general.edit_user_attributes'): for name, attr in userdb.get_user_attributes(): if attr.user_editable(): if not attr.permission() or config.user.may( attr.permission()): vs = attr.valuespec() value = vs.from_html_vars('ua_' + name) vs.validate_value(value, "ua_" + name) users[config.user.id][name] = value # Change the password if requested password_changed = False if config.user.may('general.change_password'): cur_password = html.request.var('cur_password') password = html.request.var('password') password2 = html.request.var('password2', '') if change_pw: # Force change pw mode if not cur_password: raise MKUserError( "cur_password", _("You need to provide your current password.")) if not password: raise MKUserError( "password", _("You need to change your password.")) if cur_password == password: raise MKUserError( "password", _("The new password must differ from your current one." )) if cur_password and password: if userdb.hook_login(config.user.id, cur_password) is False: raise MKUserError("cur_password", _("Your old password is wrong.")) if password2 and password != password2: raise MKUserError( "password2", _("The both new passwords do not match.")) watolib.verify_password_policy(password) users[config.user.id]['password'] = hash_password(password) users[config.user.id]['last_pw_change'] = int(time.time()) if change_pw: # Has been changed, remove enforcement flag del users[config.user.id]['enforce_pw_change'] # Increase serial to invalidate old cookies if 'serial' not in users[config.user.id]: users[config.user.id]['serial'] = 1 else: users[config.user.id]['serial'] += 1 password_changed = True # Now, if in distributed environment where users can login to remote sites, # set the trigger for pushing the new auth information to the slave sites # asynchronous if config.user.authorized_login_sites(): start_async_replication = True userdb.save_users(users) if password_changed: # Set the new cookie to prevent logout for the current user login.set_auth_cookie(config.user.id) success = True except MKUserError as e: html.add_user_error(e.varname, e) else: users = userdb.load_users() watolib.init_wato_datastructures(with_wato_lock=True) # When in distributed setup, display the replication dialog instead of the normal # profile edit dialog after changing the password. if start_async_replication: user_profile_async_replication_page() return if change_pw: title = _("Change Password") else: title = _("Edit User Profile") html.header(title) # Rule based notifications: The user currently cannot simply call the according # WATO module due to WATO permission issues. So we cannot show this button # right now. if not change_pw: rulebased_notifications = watolib.load_configuration_settings().get( "enable_rulebased_notifications") if rulebased_notifications and config.user.may( 'general.edit_notifications'): html.begin_context_buttons() url = "wato.py?mode=user_notifications_p" html.context_button(_("Notifications"), url, "notifications") html.end_context_buttons() else: reason = html.request.var('reason') if reason == 'expired': html.p( _('Your password is too old, you need to choose a new password.' )) else: html.p( _('You are required to change your password before proceeding.' )) if success: html.reload_sidebar() if change_pw: html.show_message(_("Your password has been changed.")) raise HTTPRedirect(html.request.var('_origtarget', 'index.py')) else: html.show_message(_("Successfully updated user profile.")) # Ensure theme changes are applied without additional user interaction html.immediate_browser_redirect(0.5, html.makeuri([])) if html.has_user_errors(): html.show_user_errors() user = users.get(config.user.id) if user is None: html.show_warning(_("Sorry, your user account does not exist.")) html.footer() return # Returns true if an attribute is locked and should be read only. Is only # checked when modifying an existing user locked_attributes = userdb.locked_attributes(user.get('connector')) def is_locked(attr): return attr in locked_attributes html.begin_form("profile", method="POST") html.prevent_password_auto_completion() html.open_div(class_="wato") forms.header(_("Personal Settings")) if not change_pw: forms.section(_("Name"), simple=True) html.write_text(user.get("alias", config.user.id)) if config.user.may( 'general.change_password') and not is_locked('password'): forms.section(_("Current Password")) html.password_input('cur_password', autocomplete="new-password") forms.section(_("New Password")) html.password_input('password', autocomplete="new-password") forms.section(_("New Password Confirmation")) html.password_input('password2', autocomplete="new-password") if not change_pw and config.user.may('general.edit_profile'): select_language(user) # Let the user configure how he wants to be notified if not rulebased_notifications \ and config.user.may('general.edit_notifications') \ and user.get("notifications_enabled"): forms.section(_("Notifications")) html.help( _("Here you can configure how you want to be notified about host and service problems and " "other monitoring events.")) watolib.get_vs_flexible_notifications().render_input( "notification_method", user.get("notification_method")) if config.user.may('general.edit_user_attributes'): for name, attr in userdb.get_user_attributes(): if attr.user_editable(): vs = attr.valuespec() forms.section(_u(vs.title())) value = user.get(name, vs.default_value()) if not attr.permission() or config.user.may( attr.permission()): vs.render_input("ua_" + name, value) html.help(_u(vs.help())) else: html.write(vs.value_to_text(value)) # Save button forms.end() html.button("_save", _("Save")) html.close_div() html.hidden_fields() html.end_form() html.footer()
def _action(self) -> None: assert config.user.id is not None users = userdb.load_users(lock=True) user = users[config.user.id] cur_password = html.request.get_str_input_mandatory('cur_password') password = html.request.get_str_input_mandatory('password') password2 = html.request.get_str_input_mandatory('password2', '') # Force change pw mode if not cur_password: raise MKUserError("cur_password", _("You need to provide your current password.")) if not password: raise MKUserError("password", _("You need to change your password.")) if cur_password == password: raise MKUserError( "password", _("The new password must differ from your current one.")) if userdb.check_credentials(config.user.id, cur_password) is False: raise MKUserError("cur_password", _("Your old password is wrong.")) if password2 and password != password2: raise MKUserError("password2", _("The both new passwords do not match.")) watolib.verify_password_policy(password) user['password'] = hash_password(password) user['last_pw_change'] = int(time.time()) # In case the user was enforced to change it's password, remove the flag try: del user['enforce_pw_change'] except KeyError: pass # Increase serial to invalidate old authentication cookies if 'serial' not in user: user['serial'] = 1 else: user['serial'] += 1 userdb.save_users(users) # Set the new cookie to prevent logout for the current user login.update_auth_cookie(config.user.id) # In distributed setups with remote sites where the user can login, start the # user profile replication now which will redirect the user to the destination # page after completion. Otherwise directly open up the destination page. origtarget = html.request.get_str_input_mandatory( '_origtarget', 'user_change_pw.py') if config.user.authorized_login_sites(): raise HTTPRedirect( makeuri_contextless(request, [("back", origtarget)], filename="user_profile_replicate.py")) raise HTTPRedirect(origtarget)
def _redirect_for_password_change(user_id: UserId) -> None: if requested_file_name(request) != "user_change_pw": result = userdb.need_to_change_pw(user_id) if result: raise HTTPRedirect("user_change_pw.py?_origtarget=%s&reason=%s" % (urlencode(makeuri(request, [])), result))
def _show_login_page(self) -> None: html.set_render_headfoot(False) html.add_body_css_class("login") html.header(get_page_heading(), Breadcrumb(), javascripts=[]) default_origtarget = ("index.py" if requested_file_name(request) in ["login", "logout"] else makeuri(request, [])) origtarget = request.get_url_input("_origtarget", default_origtarget) # Never allow the login page to be opened in the iframe. Redirect top page to login page. # This will result in a full screen login page. html.javascript("""if(top != self) { window.top.location.href = location; }""") # When someone calls the login page directly and is already authed redirect to main page if requested_file_name(request) == "login" and _check_auth(request): raise HTTPRedirect(origtarget) html.open_div(id_="login") html.open_div(id_="login_window") html.open_a(href="https://checkmk.com") html.img( src=theme.detect_icon_path(icon_name="logo", prefix="mk-"), id_="logo", class_="custom" if theme.has_custom_logo() else None, ) html.close_a() html.begin_form("login", method="POST", add_transid=False, action="login.py") html.hidden_field("_login", "1") html.hidden_field("_origtarget", origtarget) html.label("%s:" % _("Username"), id_="label_user", class_=["legend"], for_="_username") html.br() html.text_input("_username", id_="input_user") html.label("%s:" % _("Password"), id_="label_pass", class_=["legend"], for_="_password") html.br() html.password_input("_password", id_="input_pass", size=None) if user_errors: html.open_div(id_="login_error") html.show_user_errors() html.close_div() html.open_div(id_="button_text") html.button("_login", _("Login"), cssclass="hot") html.close_div() html.close_div() html.open_div(id_="foot") if config.login_screen.get("login_message"): html.open_div(id_="login_message") html.show_message(config.login_screen["login_message"]) html.close_div() footer: List[HTML] = [] for title, url, target in config.login_screen.get("footer_links", []): footer.append(html.render_a(title, href=url, target=target)) if "hide_version" not in config.login_screen: footer.append(escape_html("Version: %s" % cmk_version.__version__)) footer.append( HTML("© %s" % html.render_a( "tribe29 GmbH", href="https://tribe29.com", target="_blank"))) html.write_html(HTML(" - ").join(footer)) if cmk_version.is_raw_edition(): html.br() html.br() html.write_text( _('You can use, modify and distribute Check_MK under the terms of the <a href="%s" target="_blank">' "GNU GPL Version 2</a>.") % "https://checkmk.com/gpl.html") html.close_div() html.set_focus("_username") html.hidden_fields() html.end_form() html.close_div() html.footer()
def _do_login(self) -> None: """handle the sent login form""" if not request.var("_login"): return try: if not config.user_login: raise MKUserError(None, _("Login is not allowed on this site.")) username_var = request.get_unicode_input("_username", "") assert username_var is not None username = UserId(username_var.rstrip()) if not username: raise MKUserError("_username", _("Missing username")) password = request.var("_password", "") if not password: raise MKUserError("_password", _("Missing password")) default_origtarget = url_prefix() + "check_mk/" origtarget = request.get_url_input("_origtarget", default_origtarget) # Disallow redirections to: # - logout.py: Happens after login # - side.py: Happens when invalid login is detected during sidebar refresh if "logout.py" in origtarget or "side.py" in origtarget: origtarget = default_origtarget result = userdb.check_credentials(username, password) if result: # use the username provided by the successful login function, this function # might have transformed the username provided by the user. e.g. switched # from mixed case to lower case. username = result session_id = userdb.on_succeeded_login(username) # The login succeeded! Now: # a) Set the auth cookie # b) Unset the login vars in further processing # c) Redirect to really requested page _create_auth_session(username, session_id) # Never use inplace redirect handling anymore as used in the past. This results # in some unexpected situations. We simpy use 302 redirects now. So we have a # clear situation. # userdb.need_to_change_pw returns either False or the reason description why the # password needs to be changed change_pw_result = userdb.need_to_change_pw(username) if change_pw_result: raise HTTPRedirect( "user_change_pw.py?_origtarget=%s&reason=%s" % (urlencode(origtarget), change_pw_result)) raise HTTPRedirect(origtarget) userdb.on_failed_login(username) raise MKUserError(None, _("Invalid login")) except MKUserError as e: user_errors.add(e)