def test_flash_dont_escape_html(user_id, request_context): now = datetime.now() with login.UserSessionContext(user_id): on_succeeded_login(user_id, now) # Create and activate session flash(HTML("<script>aaa</script>")) assert get_flashed_messages() == [HTML("<script>aaa</script>")]
def test_flash_escape_html_in_str(user_id, module_wide_request_context): with login.UserContext(user_id): on_succeeded_login(user_id) # Create and activate session flash("<script>aaa</script>") assert get_flashed_messages() == [ HTML("<script>aaa</script>") ]
def test_on_failed_login_count_reset_on_succeeded_login(user_id): assert config.lock_on_logon_failures is False assert userdb._load_failed_logins(user_id) == 0 assert userdb._user_locked(user_id) is False userdb.on_failed_login(user_id) assert userdb._load_failed_logins(user_id) == 1 assert userdb._user_locked(user_id) is False userdb.on_succeeded_login(user_id) assert userdb._load_failed_logins(user_id) == 0 assert userdb._user_locked(user_id) is False
def test_on_failed_login_count_reset_on_succeeded_login( user_id: UserId) -> None: now = datetime.now() assert active_config.lock_on_logon_failures is None assert userdb._load_failed_logins(user_id) == 0 assert not userdb.user_locked(user_id) userdb.on_failed_login(user_id, now) assert userdb._load_failed_logins(user_id) == 1 assert not userdb.user_locked(user_id) userdb.on_succeeded_login(user_id, now) assert userdb._load_failed_logins(user_id) == 0 assert not userdb.user_locked(user_id)
def _check_auth_http_header() -> Optional[UserId]: """When http header auth is enabled, try to read the user_id from the var and when there is some available, set the auth cookie (for other addons) and proceed.""" assert isinstance(config.auth_by_http_header, str) user_id = html.request.get_request_header(config.auth_by_http_header) if not user_id: return None user_id = UserId(ensure_str(user_id)) set_auth_type("http_header") if auth_cookie_name() not in html.request.cookies: userdb.on_succeeded_login(user_id) return user_id
def _do_login(self) -> None: """handle the sent login form""" if not html.request.var('_login'): return try: if not config.user_login: raise MKUserError(None, _('Login is not allowed on this site.')) 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 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' % (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 test_flash(user_id): # Execute the first request flash some message with application_and_request_context(), login.UserSessionContext(user_id): session_id = on_succeeded_login(user_id) # Create and activate session assert session is not None flash("abc") assert session.session_info.flashes == ["abc"] # Now create the second request to get the previously flashed message with application_and_request_context(), login.UserSessionContext(user_id): on_access(user_id, session_id) assert session is not None assert session.session_info.flashes == ["abc"] # Get the flashed messages removes the messages from the session # and subsequent calls to get_flashed_messages return the messages # over and over. assert get_flashed_messages() == [HTML("abc")] assert get_flashed_messages() == [HTML("abc")] assert session.session_info.flashes == [] # Now create the third request that should not have access to the flashed messages since the # second one consumed them. with application_and_request_context(), login.UserSessionContext(user_id): on_access(user_id, session_id) assert session is not None assert session.session_info.flashes == [] assert get_flashed_messages() == []
def test_on_succeeded_login(user_id: UserId, zero_uuid: None) -> None: now = datetime.now() assert active_config.single_user_session is None # Never logged in before assert not userdb._load_session_infos(user_id) assert userdb._load_failed_logins(user_id) == 0 session_id = userdb.on_succeeded_login(user_id, now) assert session_id != "" # Verify the session was initialized session_infos = userdb._load_session_infos(user_id) assert session_infos == { session_id: userdb.SessionInfo( session_id=session_id, started_at=int(now.timestamp()), last_activity=int(now.timestamp()), flashes=[], csrf_token="00000000-0000-0000-0000-000000000000", ) } # Ensure the failed login count is 0 assert userdb._load_failed_logins(user_id) == 0
def test_access_denied_with_invalidated_session(user_id: UserId) -> None: session_id = userdb.on_succeeded_login(user_id) assert session_id in userdb._load_session_infos(user_id) userdb.on_access(user_id, session_id) userdb.on_logout(user_id, session_id) assert not userdb._load_session_infos(user_id) with pytest.raises(MKAuthException, match="Invalid user session"): userdb.on_access(user_id, session_id)
def _check_auth_cookie_for_web_server_auth(user_id: UserId): """Session handling also has to be initialized when the authentication is done by the web server. The authentication is already done on web server level. We accept the provided username as authenticated and create our cookie here. """ if auth_cookie_name() not in html.request.cookies: session_id = userdb.on_succeeded_login(user_id) _create_auth_session(user_id, session_id) return # Refresh the existing auth cookie and update the session info cookie_name = auth_cookie_name() try: _check_auth_cookie(cookie_name) except MKAuthException: # Suppress cookie validation errors from other sites cookies auth_logger.debug('Exception while checking cookie %s: %s' % (cookie_name, traceback.format_exc())) except Exception: auth_logger.debug('Exception while checking cookie %s: %s' % (cookie_name, traceback.format_exc()))
def test_on_succeeded_login(user_id): assert config.single_user_session is None # Never logged in before assert not userdb._load_session_infos(user_id) assert userdb._load_failed_logins(user_id) == 0 session_id = userdb.on_succeeded_login(user_id) assert session_id != "" # Verify the session was initialized session_infos = userdb._load_session_infos(user_id) assert session_infos == { session_id: userdb.SessionInfo( session_id=session_id, started_at=int(time.time()), last_activity=int(time.time()), ) } # Ensure the failed login count is 0 assert userdb._load_failed_logins(user_id) == 0
def test_flash(user_id): environ = create_environ() # Execute the first request flash some message with AppContext(DummyApplication(environ, None)), \ RequestContext(htmllib.html(http.Request(environ))) as request, \ login.UserContext(user_id): session_id = on_succeeded_login(user_id) # Create and activate session assert request.session is not None flash("abc") assert session.session_info.flashes == ["abc"] # Now create the second request to get the previously flashed message with AppContext(DummyApplication(environ, None)), \ RequestContext(htmllib.html(http.Request(environ))), \ login.UserContext(user_id): on_access(user_id, session_id) assert request.session is not None assert session.session_info.flashes == ["abc"] # Get the flashed messages removes the messages from the session # and subsequent calls to get_flashed_messages return the messages # over and over. assert get_flashed_messages() == [HTML("abc")] assert get_flashed_messages() == [HTML("abc")] assert session.session_info.flashes == [] # Now create the third request that should not have access to the flashed messages since the # second one consumed them. with AppContext(DummyApplication(environ, None)), \ RequestContext(htmllib.html(http.Request(environ))), \ login.UserContext(user_id): on_access(user_id, session_id) assert request.session is not None assert session.session_info.flashes == [] assert get_flashed_messages() == []
def test_on_succeeded_login_already_existing_session(user_id: UserId) -> None: now = datetime.now() make_valid_session(user_id, now) with pytest.raises(MKUserError, match="Another session"): assert userdb.on_succeeded_login(user_id, now)
def do_login(): # handle the sent login form if html.request.var('_login'): try: username = html.get_unicode_input('_username', '').rstrip() if username == '': raise MKUserError('_username', _('No username given.')) password = html.request.var('_password', '') if 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 # None -> User unknown, means continue with other connectors # '<user_id>' -> success # False -> failed result = userdb.hook_login(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 # 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 result = userdb.need_to_change_pw(username) if result: raise HTTPRedirect('user_change_pw.py?_origtarget=%s&reason=%s' % (html.urlencode(origtarget), result)) else: raise HTTPRedirect(origtarget) else: userdb.on_failed_login(username) raise MKUserError(None, _('Invalid credentials.')) except MKUserError as e: html.add_user_error(e.varname, e) return "%s" % e
def test_on_succeeded_login_already_existing_session( user_id: UserId, session_valid: str) -> None: with pytest.raises(MKUserError, match="Another session"): assert userdb.on_succeeded_login(user_id)
def test_on_logout_invalidate_session(user_id: UserId) -> None: session_id = userdb.on_succeeded_login(user_id) assert session_id in userdb._load_session_infos(user_id) userdb.on_logout(user_id, session_id) assert not userdb._load_session_infos(user_id)
def test_on_logout_no_session(user_id: UserId) -> None: assert userdb.on_succeeded_login(user_id) assert userdb._load_session_infos(user_id) userdb.on_logout(user_id, session_id="") assert userdb._load_session_infos(user_id)
def _do_login(self) -> None: """handle the sent login form""" if not request.var("_login"): return try: if not active_config.user_login: raise MKUserError(None, _("Login is not allowed on this site.")) username_var = request.get_str_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)) if userdb.is_two_factor_login_enabled(username): raise HTTPRedirect( "user_login_two_factor.py?_origtarget=%s" % urlencode(makeuri(request, []))) raise HTTPRedirect(origtarget) userdb.on_failed_login(username) raise MKUserError(None, _("Invalid login")) except MKUserError as e: user_errors.add(e)
def test_flash_dont_escape_html(user_id, module_wide_request_context): with login.UserSessionContext(user_id): on_succeeded_login(user_id) # Create and activate session flash(HTML("<script>aaa</script>")) assert get_flashed_messages() == [HTML("<script>aaa</script>")]