Exemplo n.º 1
0
    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")
Exemplo n.º 2
0
def test_load_group_information_empty(tmp_path):
    environ = dict(create_environ(), REQUEST_URI='')
    with AppContext(DummyApplication(environ, None)), \
         RequestContext(htmllib.html(Request(environ))):
        assert groups.load_contact_group_information() == {}
        assert gui_groups.load_host_group_information() == {}
        assert gui_groups.load_service_group_information() == {}
Exemplo n.º 3
0
 def test_get_request(
     self,
     monkeypatch: pytest.MonkeyPatch,
 ) -> None:
     request = Request({})
     request.set_var("site_id", "NO_SITE")
     request.set_var("to_delete", "['x/y/z.txt', 'abc.ending', '/ä/☃/☕']")
     request.set_var("config_generation", "123")
     request.files = werkzeug_datastructures.ImmutableMultiDict({
         "sync_archive":
         werkzeug_datastructures.FileStorage(
             stream=io.BytesIO(b"some data"),
             filename="sync_archive",
             name="sync_archive",
         )
     })
     monkeypatch.setattr(
         activate_changes,
         "_request",
         request,
     )
     assert (activate_changes.AutomationReceiveConfigSync().get_request() ==
             activate_changes.ReceiveConfigSyncRequest(
                 site_id=SiteId("NO_SITE"),
                 sync_archive=b"some data",
                 to_delete=["x/y/z.txt", "abc.ending", "/ä/☃/☕"],
                 config_generation=123,
             ))
Exemplo n.º 4
0
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.items():
            assert host.attributes() == attributes
Exemplo n.º 5
0
def test_del_vars():
    environ = dict(create_environ(),
                   REQUEST_URI='',
                   QUERY_STRING='foo=foo&_username=foo&_password=bar&bar=bar')
    with AppContext(DummyApplication(environ, None)), \
            RequestContext(htmllib.html(Request(environ))):
        # First we hit the cached property so we can see that the underlying Request object
        # actually got replaced later.
        _ = request.args
        _ = html.request.args

        html.request.set_var("foo", "123")

        html.del_var_from_env("_username")
        html.del_var_from_env("_password")

        # Make test independent of dict sorting
        assert html.request.query_string in [
            'foo=foo&bar=bar', 'bar=bar&foo=foo'
        ]

        assert '_password' not in html.request.args
        assert '_username' not in html.request.args

        # Check the request local proxied version too.
        # Make test independent of dict sorting
        assert request.query_string in ['foo=foo&bar=bar', 'bar=bar&foo=foo']
        assert '_password' not in request.args
        assert '_username' not in request.args

        assert html.request.var("foo") == "123"
Exemplo n.º 6
0
 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
Exemplo n.º 7
0
    def _initialize_gui_environment(self):
        environ = dict(create_environ(), REQUEST_URI='')
        current_app.set_current(DummyApplication(environ, None))
        html.set_current(htmllib.html(Request(environ), Response(is_secure=False)))

        cmk.gui.modules.load_all_plugins()
        cmk.gui.config.load_config()
        cmk.gui.config.set_super_user()
Exemplo n.º 8
0
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
Exemplo n.º 9
0
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
Exemplo n.º 10
0
def _verify_user(environ: WSGIEnvironment, now: datetime) -> RFC7662:
    verified: List[RFC7662] = []

    auth_header = environ.get("HTTP_AUTHORIZATION", "")
    basic_user = None
    if auth_header:
        auth_type, _ = auth_header.split(None, 1)
        if auth_type == "Bearer":
            user_id, secret = user_from_bearer_header(auth_header)
            automation_user = automation_auth(user_id, secret)
            if automation_user:
                verified.append(automation_user)
            else:
                # GUI user and Automation users are mutually exclusive. Checking only once is less
                # work for the system.
                gui_user = gui_user_auth(user_id, secret, now)
                if gui_user:
                    verified.append(gui_user)
        elif auth_type == "Basic":
            # We store this for sanity checking below, once we get a REMOTE_USER key.
            # If we don't get a REMOTE_USER key, this value will be ignored.
            basic_user = user_from_basic_header(auth_header)
        else:
            raise MKAuthException(f"Unsupported Auth Type: {auth_type}")

    remote_user = environ.get("REMOTE_USER", "")
    if remote_user and userdb.user_exists(UserId(remote_user)):
        if basic_user and basic_user[0] != remote_user:
            raise MKAuthException("Mismatch in authentication headers.")
        verified.append(rfc7662_subject(UserId(remote_user), "web_server"))

    cookie = Request(environ).cookies.get(f"auth_{omd_site()}")
    if cookie:
        user_id, session_id, cookie_hash = user_from_cookie(cookie)
        check_parsed_auth_cookie(user_id, session_id, cookie_hash)
        verified.append(rfc7662_subject(user_id, "cookie"))

    if not verified:
        raise MKAuthException(
            "You need to be authenticated to use the REST API.")

    # We pick the first successful authentication method, which means the precedence is the same
    # as the order in the code.
    final_candidate = verified[0]
    user_id = final_candidate["sub"]
    if not userdb.is_customer_user_allowed_to_login(user_id):
        raise MKAuthException(f"{user_id} may not log in here.")

    if userdb.user_locked(user_id):
        raise MKAuthException(f"{user_id} not authorized.")

    if change_reason := userdb.need_to_change_pw(user_id, now):
        raise MKAuthException(
            f"{user_id} needs to change the password ({change_reason}).")
Exemplo n.º 11
0
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
Exemplo n.º 12
0
    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")
Exemplo n.º 13
0
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
Exemplo n.º 14
0
def with_request_context():
    environ = create_environ()
    resp = Response()
    with AppContext(session_wsgi_app(debug=False), stack=app_stack()), RequestContext(
        req=Request(environ),
        resp=resp,
        funnel=OutputFunnel(resp),
        config_obj=make_config_object(get_default_config()),
        user=LoggedInNobody(),
        display_options=DisplayOptions(),
        stack=request_stack(),
        url_filter=PrependURLFilter(),
    ):
        yield
Exemplo n.º 15
0
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
Exemplo n.º 16
0
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,
    )
Exemplo n.º 17
0
 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
Exemplo n.º 18
0
    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")
Exemplo n.º 19
0
def test_generate_snapshot(edition_short, snapshot_manager_class, monkeypatch, tmp_path, with_user):
    user_id = with_user[0]
    monkeypatch.setattr(cmk_version, "edition_short", lambda: edition_short)

    environ = dict(create_environ(), REQUEST_URI='')
    with AppContext(DummyApplication(environ, None)), \
         RequestContext(htmllib.html(Request(environ))):
        login.login(user_id)
        _create_test_sync_config(monkeypatch)
        snapshot_settings = _create_sync_snapshot(snapshot_manager_class, monkeypatch, tmp_path)

    # And now check the resulting snapshot contents
    unpack_dir = tmp_path / "snapshot_unpack"
    with tarfile.open(snapshot_settings.snapshot_path, "r") as t:
        t.extractall(str(unpack_dir))

    expected_subtars = [
        "auth.secret.tar",
        "auth.serials.tar",
        "check_mk.tar",
        "diskspace.tar",
        "htpasswd.tar",
        "mkeventd_mkp.tar",
        "mkeventd.tar",
        "multisite.tar",
        "sitespecific.tar",
        "usersettings.tar",
    ]

    if is_enterprise_repo():
        expected_subtars += [
            "dcd.tar",
            "mknotify.tar",
        ]

    if not cmk_version.is_raw_edition():
        expected_subtars.append("liveproxyd.tar")

    assert sorted(f.name for f in unpack_dir.iterdir()) == sorted(expected_subtars)

    expected_files = {
        'mkeventd_mkp.tar': [],
        'multisite.tar': ["global.mk", "users.mk"],
        'usersettings.tar': [user_id],
        'mkeventd.tar': [],
        'check_mk.tar': ["hosts.mk", "contacts.mk"],
        'htpasswd.tar': ["htpasswd"],
        'liveproxyd.tar': [],
        'sitespecific.tar': ['sitespecific.mk'],
        'auth.secret.tar': [],
        'dcd.tar': [],
        'auth.serials.tar': ["auth.serials"],
        'mknotify.tar': [],
        'diskspace.tar': [],
    }

    # TODO: Shouldn't we clean up these subtle differences?
    if cmk_version.is_managed_edition():
        expected_files.update({
            "mkeventd.tar": ["rules.mk"],
            'check_mk.tar': ["groups.mk", "contacts.mk"],
            'multisite.tar': [
                "bi.mk",
                "customers.mk",
                "global.mk",
                "groups.mk",
                "user_connections.mk",
                "users.mk",
            ],
        })

    if not cmk_version.is_raw_edition():
        expected_files['liveproxyd.tar'] = []

    # And now check the subtar contents
    for subtar in unpack_dir.iterdir():
        subtar_unpack_dir = unpack_dir / subtar.stem
        subtar_unpack_dir.mkdir(parents=True, exist_ok=True)

        with tarfile.open(str(subtar), "r") as s:
            s.extractall(str(subtar_unpack_dir))

        files = sorted(str(f.relative_to(subtar_unpack_dir)) for f in subtar_unpack_dir.iterdir())

        assert sorted(expected_files[subtar.name]) == files, \
            "Subtar %s has wrong files" % subtar.name
Exemplo n.º 20
0
 def __init__(self):
     self._user_id = user.ident
     self._request = Request(create_environ())
     from cmk.gui.wato.pages.hosts import ModeEditHost
     self._mode_edit_host = ModeEditHost
Exemplo n.º 21
0
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
Exemplo n.º 22
0
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",
            }
        }
Exemplo n.º 23
0
def test_apply_sync_snapshot(edition_short, snapshot_manager_class, monkeypatch, tmp_path,
                             with_user):
    user_id = with_user[0]
    monkeypatch.setattr(cmk_version, "edition_short", lambda: edition_short)

    environ = dict(create_environ(), REQUEST_URI='')
    with AppContext(DummyApplication(environ, None)), \
         RequestContext(htmllib.html(Request(environ))):
        login.login(user_id)

        _create_test_sync_config(monkeypatch)
        snapshot_settings = _create_sync_snapshot(snapshot_manager_class, monkeypatch, tmp_path)

        # Change unpack target directory from "unit test site" paths to a test specific path
        unpack_dir = tmp_path / "snapshot_unpack"
        components = [
            activate_changes._replace_omd_root(str(unpack_dir), p)
            for p in activate_changes.get_replication_paths()
        ]

        with open(snapshot_settings.snapshot_path, "rb") as f:
            activate_changes.apply_sync_snapshot("unit_remote_1", f.read(), components)

    expected_paths = [
        'etc',
        'var',
        'etc/check_mk',
        'etc/check_mk/conf.d',
        'etc/check_mk/mkeventd.d',
        'etc/check_mk/multisite.d',
        'etc/check_mk/conf.d/wato',
        'etc/check_mk/conf.d/wato/hosts.mk',
        'etc/check_mk/conf.d/wato/contacts.mk',
        'etc/check_mk/mkeventd.d/mkp',
        'etc/check_mk/mkeventd.d/wato',
        'etc/check_mk/mkeventd.d/mkp/rule_packs',
        'etc/check_mk/multisite.d/wato',
        'etc/check_mk/multisite.d/wato/global.mk',
        'var/check_mk',
        'var/check_mk/web',
        "etc/htpasswd",
        "etc/auth.serials",
        "etc/check_mk/multisite.d/wato/users.mk",
        six.ensure_str('var/check_mk/web/%s' % user_id),
        six.ensure_str('var/check_mk/web/%s/cached_profile.mk' % user_id),
        six.ensure_str('var/check_mk/web/%s/enforce_pw_change.mk' % user_id),
        six.ensure_str('var/check_mk/web/%s/last_pw_change.mk' % user_id),
        six.ensure_str('var/check_mk/web/%s/num_failed_logins.mk' % user_id),
        six.ensure_str('var/check_mk/web/%s/serial.mk' % user_id),
    ]

    # The paths are registered once the enterprise plugins are available, independent of the
    # cmk_version.edition_short() value.
    if is_enterprise_repo():
        expected_paths += [
            'etc/check_mk/dcd.d',
            'etc/check_mk/mknotifyd.d',
            'etc/check_mk/mknotifyd.d/wato',
            'etc/check_mk/dcd.d/wato',
        ]

    # TODO: Shouldn't we clean up these subtle differences?
    if cmk_version.is_managed_edition():
        expected_paths += [
            "etc/check_mk/conf.d/wato/groups.mk",
            "etc/check_mk/mkeventd.d/wato/rules.mk",
            "etc/check_mk/multisite.d/wato/bi.mk",
            "etc/check_mk/multisite.d/wato/customers.mk",
            "etc/check_mk/multisite.d/wato/groups.mk",
            "etc/check_mk/multisite.d/wato/user_connections.mk",
            #"etc/check_mk/conf.d/wato/sitespecific.mk",
            #"etc/check_mk/dcd.d/wato/distributed.mk",
            #"etc/check_mk/dcd.d/wato/sitespecific.mk",
            #"etc/check_mk/mkeventd.d/wato/sitespecific.mk",
            #"etc/check_mk/mknotifyd.d/wato/sitespecific.mk",
            #"etc/check_mk/multisite.d/wato/sitespecific.mk",
        ]

        expected_paths.remove("etc/check_mk/conf.d/wato/hosts.mk")

    if not cmk_version.is_raw_edition():
        expected_paths += [
            'etc/check_mk/liveproxyd.d',
            'etc/check_mk/liveproxyd.d/wato',
            #'etc/check_mk/multisite.d/wato/ca-certificates_sitespecific.mk',
        ]

    paths = [str(p.relative_to(unpack_dir)) for p in unpack_dir.glob("**/*")]
    assert sorted(paths) == sorted(expected_paths)
Exemplo n.º 24
0
def register_builtin_html():
    """This fixture registers a global htmllib.html() instance just like the regular GUI"""
    environ = dict(create_environ(), REQUEST_URI='')
    with AppContext(DummyApplication(environ, None)), \
         RequestContext(htmllib.html(Request(environ), Response(is_secure=False))):
        yield
Exemplo n.º 25
0
    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, stack=app_stack()), 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(),
                    stack=request_stack(),
                    url_filter=PrependURLFilter(),
            ), 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)
Exemplo n.º 26
0
 def __init__(self):
     self._user_id = user.ident
     self._request = Request(create_environ())