def mock_livestatus(with_context=False): def enabled_and_disabled_sites(_user): return {'NO_SITE': {'socket': 'unix:'}}, {} live = MockLiveStatusConnection() env = EnvironBuilder().get_environ() req = http.Request(env) app_context: ContextManager req_context: ContextManager if with_context: app_context = AppContext(None) req_context = RequestContext( req=req, display_options=DisplayOptions(), prefix_logs_with_url=False, ) else: app_context = contextlib.nullcontext() req_context = contextlib.nullcontext() with app_context, req_context, \ mock.patch("cmk.gui.sites._get_enabled_and_disabled_sites", new=enabled_and_disabled_sites), \ mock.patch("livestatus.MultiSiteConnection.set_prepend_site", new=live.set_prepend_site), \ mock.patch("livestatus.MultiSiteConnection.expect_query", new=live.expect_query, create=True), \ mock.patch("livestatus.SingleSiteConnection._create_socket", new=live.create_socket), \ mock.patch.dict(os.environ, {'OMD_ROOT': '/', 'OMD_SITE': 'NO_SITE'}): yield live
def run(self): self._logger.log(VERBOSE, "Initializing application...") environ = dict(create_environ(), REQUEST_URI='') this_html = htmllib.html(Request(environ)) # Currently the htmllib.html constructor enables the timeout by default. This side effect # should really be cleaned up. this_html.disable_request_timeout() with AppContext(DummyApplication(environ, None)), \ RequestContext(this_html): self._initialize_gui_environment() self._logger.log(VERBOSE, "Updating Checkmk configuration...") for step_func, title in self._steps(): self._logger.log(VERBOSE, " + %s..." % title) try: step_func() except Exception: self._logger.log(VERBOSE, " + \"%s\" failed" % title, exc_info=True) if self._arguments.debug: raise self._logger.log(VERBOSE, "Done")
def test_write_and_read_host_attributes(tmp_path, attributes, monkeypatch): folder_path = str(tmp_path) # Write/Read operations always require a valid user monkeypatch.setattr(config, "user", config.LoggedInSuperUser()) # Used to write the data write_data_folder = watolib.Folder("testfolder", folder_path=folder_path, parent_folder=None) # Used to read the previously written data read_data_folder = watolib.Folder("testfolder", folder_path=folder_path, parent_folder=None) environ = dict(create_environ(), REQUEST_URI='') with AppContext(DummyApplication(environ, None)), \ RequestContext(htmllib.html(Request(environ))): # Write data # Note: The create_hosts function modifies the attributes dict, adding a meta_data key inplace write_data_folder.create_hosts([("testhost", attributes, [])]) write_folder_hosts = write_data_folder.hosts() assert len(write_folder_hosts) == 1 # Read data back read_folder_hosts = read_data_folder.hosts() assert len(read_folder_hosts) == 1 for _, host in read_folder_hosts.iteritems(): assert host.attributes() == attributes
def wsgi_app(self, environ, start_response): # pylint: disable=method-hidden """Is called by the WSGI server to serve the current page""" request = cmk.gui.http.Request(environ) response = cmk.gui.http.Response(is_secure=request.is_secure) with AppContext(self), RequestContext(cmk.gui.htmllib.html(request, response)),\ cleanup_locks(): self._process_request(request, response) return response(environ, start_response)
def with_context(environ, start_response): req = http.Request(environ) with AppContext(app), \ RequestContext(req=req, display_options=DisplayOptions()), \ cmk.utils.store.cleanup_locks(), \ sites.cleanup_connections(): config.initialize() return app(environ, start_response)
def _SearchContext(self) -> Iterator[None]: _request = Request(create_environ()) with RequestContext( html_obj=html(_request), req=_request, display_options=DisplayOptions(), ), UserContext(self._user_id): yield
def module_wide_request_context(): # This one is kind of an hack because some other test-fixtures touch the user object AFTER the # request context has already ended. If we increase our scope this won't matter, but it is of # course wrong. These other fixtures have to be fixed. environ = create_environ() with AppContext(DummyApplication(environ, None)), \ RequestContext(htmllib.html(Request(environ))): yield
def with_context(environ, start_response): req = cmk.gui.http.Request(environ) resp = cmk.gui.http.Response(is_secure=req.is_secure) with AppContext(app), RequestContext(cmk.gui.htmllib.html(req, resp)): config.initialize() html.init_modes() return app(environ, start_response)
def with_request_context(): environ = create_environ() resp = Response() with AppContext(DummyApplication(environ, None)), \ RequestContext(req=Request(environ), resp=resp, funnel=OutputFunnel(resp), display_options=DisplayOptions()): yield
def __call__(self, environ, start_response): req = http.Request(environ) with AppContext(self), RequestContext( req=req, html_obj=htmllib.html(req), display_options=DisplayOptions(), ): config.initialize() html.init_modes() return self.wsgi_app(environ, start_response)
def fixture_current_cookie(with_user, session_id): user_id = with_user[0] cookie_name = login.auth_cookie_name() cookie_value = login._auth_cookie_value(user_id, session_id) environ = dict(create_environ(), HTTP_COOKIE=f"{cookie_name}={cookie_value}".encode("utf-8")) with AppContext(DummyApplication(environ, None)), \ RequestContext(htmllib.html(http.Request(environ))): yield cookie_name
def fixture_pre_20_cookie(): environ = dict( create_environ(), HTTP_COOKIE= u"xyz=123; auth_stable=lärs:1534272374.61:1f59cac3fcd5bcc389e4f8397bed315b; abc=123".encode( "utf-8")) with AppContext(DummyApplication(environ, None)), \ RequestContext(htmllib.html(http.Request(environ))): yield "auth_stable"
def __call__(self, environ, start_response): req = http.Request(environ) resp = http.Response(is_secure=req.is_secure) with AppContext(self), RequestContext(req=req, resp=resp, html_obj=htmllib.html(req, resp)): config.initialize() html.init_modes() return self.wsgi_app(environ, start_response)
def mock_livestatus( with_context: bool = False, with_html: bool = False ) -> Generator[MockLiveStatusConnection, None, None]: live = MockLiveStatusConnection() env = EnvironBuilder().get_environ() req = http.Request(env) resp = http.Response() app_context: ContextManager req_context: ContextManager if with_html: html_obj = None else: html_obj = html( request=req, response=resp, output_funnel=OutputFunnel(resp), output_format="html", ) if with_context: app_context = AppContext(None) req_context = RequestContext( html_obj=html_obj, req=req, resp=resp, funnel=OutputFunnel(resp), config_obj=make_config_object(get_default_config()), user=LoggedInNobody(), display_options=DisplayOptions(), prefix_logs_with_url=False, ) else: app_context = contextlib.nullcontext() req_context = contextlib.nullcontext() with app_context, req_context, mock.patch( "cmk.gui.sites._get_enabled_and_disabled_sites", new=live.enabled_and_disabled_sites), mock.patch( "livestatus.MultiSiteConnection.expect_query", new=live.expect_query, create=True), mock.patch( "livestatus.SingleSiteConnection._create_socket", new=live.create_socket), mock.patch.dict( os.environ, { "OMD_ROOT": "/", "OMD_SITE": "NO_SITE" }): # We don't want to be polluted by other tests. omd_site.cache_clear() yield live # We don't want to pollute other tests. omd_site.cache_clear()
def with_request_context(): environ = create_environ() resp = Response() with AppContext(session_wsgi_app(debug=False)), RequestContext( req=Request(environ), resp=resp, funnel=OutputFunnel(resp), config_obj=make_config_object(get_default_config()), display_options=DisplayOptions(), ): yield
def with_context(environ, start_response): req = http.Request(environ) resp = http.Response() with AppContext(app), \ RequestContext(req=req, resp=resp, funnel=OutputFunnel(resp), config_obj=config.make_config_object(config.get_default_config()), display_options=DisplayOptions()), \ cmk.utils.store.cleanup_locks(), \ sites.cleanup_connections(): config.initialize() return app(environ, start_response)
def run(self): self._logger.log(VERBOSE, "Updating Checkmk configuration...") environ = dict(create_environ(), REQUEST_URI='') with AppContext(DummyApplication(environ, None)), \ RequestContext(htmllib.html(Request(environ), Response(is_secure=False))): self._initialize_gui_environment() for step_func, title in self._steps(): self._logger.log(VERBOSE, " + %s..." % title) step_func() self._logger.log(VERBOSE, "Done")
def test_web_server_auth_session(user_id): environ = dict(create_environ(), REMOTE_USER=str(user_id)) with AppContext(DummyApplication(environ, None)), \ RequestContext(htmllib.html(http.Request(environ))): assert user.id is None with login.authenticate(request) as authenticated: assert authenticated is True assert user.id == user_id assert session.user_id == user.id assert user.id is None
def request_context(environ: Mapping[str, Any]) -> Iterator[None]: this_html = html(Request(environ)) # Currently the htmllib.html constructor enables the timeout by default. This side effect # should really be cleaned up. this_html.disable_request_timeout() with RequestContext( this_html, display_options=DisplayOptions(), prefix_logs_with_url=False, ): yield
def is_permitted(self, url: str) -> bool: file_name, query_vars = file_name_and_query_vars_from_url(url) self._set_query_vars(query_vars) try: with RequestContext(html_obj=html(self._request), req=self._request): with UserContext(self._user_id): page_handler = get_page_handler(file_name) if page_handler: page_handler() return True except MKAuthException: return False
def request_context(environ: Mapping[str, Any]) -> Iterator[None]: req = Request(environ) resp = Response(mimetype="text/html") funnel = OutputFunnel(resp) with RequestContext( req=req, resp=resp, funnel=funnel, html_obj=html(req, resp, funnel, output_format="html"), display_options=DisplayOptions(), theme=Theme(), prefix_logs_with_url=False, ): yield
def is_permitted(self, url: str) -> bool: is_host_url = "mode=edit_host" in url file_name, query_vars = file_name_and_query_vars_from_url(url) self._set_query_vars(query_vars) try: with AppContext(current_app), \ RequestContext(html_obj=html(self._request), req=self._request), \ UserContext(self._user_id): if is_host_url: self._try_host() else: self._try_page(file_name) return True except MKAuthException: return False
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 make_request_context( environ: Optional[Mapping[str, Any]] = None) -> RequestContext: req = Request( dict(create_environ(), REQUEST_URI="") if environ is None else environ) resp = Response(mimetype="text/html") funnel = OutputFunnel(resp) return RequestContext( req=req, resp=resp, funnel=funnel, config_obj=make_config_object(get_default_config()), user=LoggedInNobody(), html_obj=html(req, resp, funnel, output_format="html"), display_options=DisplayOptions(), timeout_manager=TimeoutManager(), theme=Theme(), prefix_logs_with_url=False, )
def _SearchContext(self) -> Iterator[None]: _request = Request(create_environ()) _response = Response() _funnel = OutputFunnel(_response) _theme = Theme() _theme.from_config(config.ui_theme, config.theme_choices()) with RequestContext( req=_request, resp=_response, funnel=_funnel, html_obj=html(_request, _response, _funnel, output_format="html"), display_options=DisplayOptions(), theme=_theme, ), UserContext(self._user_id): yield
def run(self): self._logger.log(VERBOSE, "Initializing application...") environ = dict(create_environ(), REQUEST_URI='') this_html = htmllib.html(Request(environ), Response(is_secure=False)) # Currently the htmllib.html constructor enables the timeout by default. This side effect # should really be cleaned up. this_html.disable_request_timeout() with AppContext(DummyApplication(environ, None)), \ RequestContext(this_html): self._initialize_gui_environment() self._logger.log(VERBOSE, "Updating Checkmk configuration...") for step_func, title in self._steps(): self._logger.log(VERBOSE, " + %s..." % title) step_func() self._logger.log(VERBOSE, "Done")
def register_builtin_html(): """This fixture registers a global htmllib.html() instance just like the regular GUI""" environ = create_environ() with AppContext(DummyApplication(environ, None)), \ RequestContext(htmllib.html(Request(environ))): yield
def test_load_group_information(tmp_path): with open(cmk.utils.paths.check_mk_config_dir + "/wato/groups.mk", "w") as f: f.write("""# encoding: utf-8 if type(define_contactgroups) != dict: define_contactgroups = {} define_contactgroups.update({'all': u'Everything'}) if type(define_hostgroups) != dict: define_hostgroups = {} define_hostgroups.update({'all_hosts': u'All hosts :-)'}) if type(define_servicegroups) != dict: define_servicegroups = {} define_servicegroups.update({'all_services': u'All särvices'}) """) with open(cmk.utils.paths.default_config_dir + "/multisite.d/wato/groups.mk", "w") as f: f.write("""# encoding: utf-8 multisite_hostgroups = { "all_hosts": { "ding": "dong", }, } multisite_servicegroups = { "all_services": { "d1ng": "dong", }, } multisite_contactgroups = { "all": { "d!ng": "dong", }, } """) environ = dict(create_environ(), REQUEST_URI='') with AppContext(DummyApplication(environ, None)), \ RequestContext(htmllib.html(Request(environ))): assert groups.load_group_information() == { 'contact': { 'all': { 'alias': u'Everything', "d!ng": "dong", } }, 'host': { 'all_hosts': { 'alias': u'All hosts :-)', "ding": "dong", } }, 'service': { 'all_services': { 'alias': u'All s\xe4rvices', "d1ng": "dong", } }, } assert groups.load_contact_group_information() == { 'all': { 'alias': u'Everything', "d!ng": "dong", } } assert gui_groups.load_host_group_information() == { 'all_hosts': { 'alias': u'All hosts :-)', "ding": "dong", } } assert gui_groups.load_service_group_information() == { 'all_services': { 'alias': u'All s\xe4rvices', "d1ng": "dong", } }
def with_context(environ, start_response): req = http.Request(environ) with AppContext(app), RequestContext(req=req): return app(environ, start_response)
def _wsgi_app(self, environ: WSGIEnvironment, start_response: StartResponse) -> WSGIResponse: urls = self.url_map.bind_to_environ(environ) endpoint: Optional[Endpoint] = None try: result: Tuple[str, Mapping[str, Any]] = urls.match(return_rule=False) endpoint_ident, matched_path_args = result # pylint: disable=unpacking-non-sequence wsgi_app = self.endpoints[endpoint_ident] if isinstance(wsgi_app, Authenticate): endpoint = wsgi_app.endpoint # Remove _path again (see Submount above), so the validators don't go crazy. path_args = {key: value for key, value in matched_path_args.items() if key != "_path"} # This is an implicit dependency, as we only know the args at runtime, but the # function at setup-time. environ[ARGS_KEY] = path_args req = Request(environ) resp = Response() with AppContext(self), RequestContext( req=req, resp=resp, funnel=OutputFunnel(resp), config_obj=config.make_config_object(config.get_default_config()), endpoint=endpoint, user=LoggedInNobody(), display_options=DisplayOptions(), ), cmk.utils.store.cleanup_locks(), sites.cleanup_connections(): config.initialize() load_dynamic_permissions() return wsgi_app(environ, start_response) except ProblemException as exc: return exc(environ, start_response) except HTTPException as exc: # We don't want to log explicit HTTPExceptions as these are intentional. assert isinstance(exc.code, int) return problem( status=exc.code, title=http.client.responses[exc.code], detail=str(exc), )(environ, start_response) except MKException as exc: if self.debug: raise return problem( status=EXCEPTION_STATUS.get(type(exc), 500), title="An exception occurred.", detail=str(exc), )(environ, start_response) except Exception as exc: crash = APICrashReport.from_exception() crash_reporting.CrashReportStore().save(crash) logger.exception("Unhandled exception (Crash-ID: %s)", crash.ident_to_text()) if self.debug: raise request = Request(environ) site = config.omd_site() query_string = urllib.parse.urlencode( [ ("crash_id", (crash.ident_to_text())), ("site", site), ] ) crash_url = f"{request.host_url}{site}/check_mk/crash.py?{query_string}" crash_details = { "crash_id": (crash.ident_to_text()), "crash_report": { "href": crash_url, "method": "get", "rel": "cmk/crash-report", "type": "text/html", }, } if user.may("general.see_crash_reports"): crash_details["stack_trace"] = traceback.format_exc().split("\n") return problem( status=500, title=http.client.responses[500], detail=str(exc), ext=crash_details, )(environ, start_response)