예제 #1
0
 async def concentric_street_name_by_id(self, request: IRequest,
                                        tag: Tag) -> KleinRenderable:
     """
     JSON dictionary: concentric streets by ID.
     """
     namesByID = await self.config.store.concentricStreets(self.event)
     return jsonTextFromObject(namesByID)
예제 #2
0
    async def readIncidentResource(
        self, request: IRequest, eventID: str, number: int
    ) -> KleinRenderable:
        """
        Incident endpoint.
        """
        event = Event(id=eventID)

        await self.config.authProvider.authorizeRequest(
            request, event, Authorization.readIncidents
        )

        try:
            number = int(number)
        except ValueError:
            return notFoundResponse(request)

        try:
            incident = await self.config.store.incidentWithNumber(
                event, number
            )
        except NoSuchIncidentError:
            return notFoundResponse(request)

        data = (
            jsonTextFromObject(jsonObjectFromModelObject(incident))
            .encode("utf-8")
        )

        return jsonBytes(request, data)
예제 #3
0
 async def events_list(self, request: IRequest,
                       tag: Tag) -> KleinRenderable:
     """
     JSON list of strings: events IDs.
     """
     return jsonTextFromObject(e.id
                               for e in await self.config.store.events())
예제 #4
0
    async def eventsResource(self, request: IRequest) -> KleinRenderable:
        """
        Events endpoint.
        """
        self.config.authProvider.authenticateRequest(request)

        authorizationsForUser = partial(
            self.config.authProvider.authorizationsForUser, request.user
        )

        events = sorted(
            [
                event
                for event in await self.config.store.events()
                if Authorization.readIncidents
                & await authorizationsForUser(event)
            ]
        )

        stream = buildJSONArray(
            jsonTextFromObject(event).encode("utf-8") for event in events
        )

        writeJSONStream(request, stream, None)
        return None
예제 #5
0
    async def readIncidentResource(
        self, request: IRequest, eventID: str, number: str
    ) -> KleinRenderable:
        """
        Incident endpoint.
        """
        event = Event(id=eventID)
        del eventID

        await self.config.authProvider.authorizeRequest(
            request, event, Authorization.readIncidents
        )

        try:
            incidentNumber = int(number)
        except ValueError:
            return notFoundResponse(request)
        del number

        try:
            incident = await self.config.store.incidentWithNumber(
                event, incidentNumber
            )
        except NoSuchIncidentError:
            return notFoundResponse(request)

        data = jsonTextFromObject(jsonObjectFromModelObject(incident)).encode(
            "utf-8"
        )

        return jsonBytes(request, data)
예제 #6
0
    async def readIncidentReportResource(
        self, request: IRequest, eventID: str, number: str
    ) -> KleinRenderable:
        """
        Incident report endpoint.
        """
        try:
            incidentReportNumber = int(number)
        except ValueError:
            self.config.authProvider.authenticateRequest(request)
            return notFoundResponse(request)
        del number

        event = Event(id=eventID)
        del eventID

        incidentReport = await self.config.store.incidentReportWithNumber(
            event, incidentReportNumber
        )

        await self.config.authProvider.authorizeRequestForIncidentReport(
            request, incidentReport
        )

        text = jsonTextFromObject(jsonObjectFromModelObject(incidentReport))

        return jsonBytes(request, text.encode("utf-8"))
예제 #7
0
 async def asText(self) -> str:
     """
     Export data store as text.
     """
     json = await self.asJSON()
     self._log.info("Encoding exported data as JSON text...")
     return jsonTextFromObject(json)
예제 #8
0
 def incident_report_number(
     self, request: IRequest, tag: Tag
 ) -> KleinRenderable:
     """
     JSON integer: incident report number.
     """
     return jsonTextFromObject(self.number)
예제 #9
0
 async def concentric_street_name_by_id(
     self, request: IRequest, tag: Tag
 ) -> KleinRenderable:
     """
     JSON dictionary: concentric streets by ID.
     """
     namesByID = await self.config.store.concentricStreets(self.event)
     return jsonTextFromObject(namesByID)
예제 #10
0
 def incidents_url(self, request: IRequest, tag: Tag) -> KleinRenderable:
     """
     JSON string: URL for incidents endpoint for the event.
     """
     return jsonTextFromObject(
         self.config.urls.incidents.asText()
         .replace("<eventID>", self.event.id)
     )
예제 #11
0
    async def listIncidentReportsResource(
        self, request: IRequest
    ) -> KleinRenderable:
        """
        Incident reports endpoint.
        """
        store = self.config.store

        eventID = queryValue(request, "event")
        incidentNumberText = queryValue(request, "incident")

        if eventID is None:
            return invalidQueryResponse(request, "event")

        if eventID == incidentNumberText == "":
            await self.config.authProvider.authorizeRequest(
                request, None, Authorization.readIncidentReports
            )
            incidentReports = await store.detachedIncidentReports()

        else:
            try:
                event = Event(id=eventID)
            except ValueError:
                return invalidQueryResponse(
                    request, "event", eventID
                )

            await self.config.authProvider.authorizeRequest(
                request, event, Authorization.readIncidents
            )

            if incidentNumberText is None:
                incidentReports = await store.incidentReports(event=event)
            else:
                try:
                    incidentNumber = int(incidentNumberText)
                except ValueError:
                    return invalidQueryResponse(
                        request, "incident", incidentNumberText
                    )

                incidentReports = (
                    await store.incidentReportsAttachedToIncident(
                        event=event, incidentNumber=incidentNumber
                    )
                )

        stream = buildJSONArray(
            jsonTextFromObject(
                jsonObjectFromModelObject(incidentReport)
            ).encode("utf-8")
            for incidentReport in incidentReports
        )

        writeJSONStream(request, stream, None)
        return None
예제 #12
0
    async def listIncidentReportsResource(
        self, request: IRequest, eventID: str
    ) -> KleinRenderable:
        """
        Incident reports endpoint.
        """
        event = Event(id=eventID)
        del eventID

        try:
            await self.config.authProvider.authorizeRequest(
                request, event, Authorization.readIncidents
            )
            limitedAccess = False
        except NotAuthorizedError:
            await self.config.authProvider.authorizeRequest(
                request, event, Authorization.writeIncidentReports
            )
            limitedAccess = True

        incidentNumberText = queryValue(request, "incident")

        store = self.config.store

        incidentReports: Iterable[IncidentReport]
        if limitedAccess:
            incidentReports = (
                incidentReport
                for incidentReport in await store.incidentReports(event=event)
                if request.user.rangerHandle
                in (entry.author for entry in incidentReport.reportEntries)
            )
        elif incidentNumberText is None:
            incidentReports = await store.incidentReports(event=event)
        else:
            try:
                incidentNumber = int(incidentNumberText)
            except ValueError:
                return invalidQueryResponse(
                    request, "incident", incidentNumberText
                )

            incidentReports = await store.incidentReportsAttachedToIncident(
                event=event, incidentNumber=incidentNumber
            )

        stream = buildJSONArray(
            jsonTextFromObject(
                jsonObjectFromModelObject(incidentReport)
            ).encode("utf-8")
            for incidentReport in incidentReports
        )

        writeJSONStream(request, stream, None)
        return None
예제 #13
0
    async def readStreetsResource(self, request: IRequest) -> KleinRenderable:
        """
        Street list endpoint.
        """
        await self.config.authProvider.authorizeRequest(
            request, None, Authorization.imsAdmin)

        store = self.config.store

        streets = {}
        for event in await store.events():
            streets[event.id] = await store.concentricStreets(event)
        return jsonTextFromObject(streets)
예제 #14
0
    def urlsEndpoint(self, request: IRequest) -> KleinRenderable:
        """
        JavaScript variables for service URLs.
        """
        urls = {
            k: getattr(URLs, k).asText()
            for k in URLs.__dict__ if not k.startswith("_")
        }

        request.setHeader(HeaderName.contentType.value,
                          ContentType.javascript.value)

        return "\n".join(("var url_{} = {};".format(k, jsonTextFromObject(v))
                          for k, v in urls.items()))
예제 #15
0
    async def readStreetsResource(self, request: IRequest) -> KleinRenderable:
        """
        Street list endpoint.
        """
        await self.config.authProvider.authorizeRequest(
            request, None, Authorization.imsAdmin
        )

        store = self.config.store

        streets = {}
        for event in await store.events():
            streets[event.id] = await store.concentricStreets(event)
        return jsonTextFromObject(streets)
예제 #16
0
    async def listIncidentsResource(self, request: IRequest,
                                    eventID: str) -> None:
        """
        Incident list endpoint.
        """
        event = Event(id=eventID)

        await self.config.authProvider.authorizeRequest(
            request, event, Authorization.readIncidents)

        stream = buildJSONArray(
            jsonTextFromObject(jsonObjectFromModelObject(incident)).encode(
                "utf-8")
            for incident in await self.config.store.incidents(event))

        writeJSONStream(request, stream, None)
예제 #17
0
    async def incidentTypesResource(self, request: IRequest) -> None:
        """
        Incident types endpoint.
        """
        self.config.authProvider.authenticateRequest(request)

        hidden = queryValue(request, "hidden") == "true"

        incidentTypes = tuple(
            await self.config.store.incidentTypes(includeHidden=hidden))

        stream = buildJSONArray(
            jsonTextFromObject(incidentType).encode("utf-8")
            for incidentType in incidentTypes)

        writeJSONStream(request, stream, None)
예제 #18
0
    async def personnelData(self) -> Tuple[Iterable[bytes], str]:
        """
        Data for personnel endpoint.
        """
        try:
            personnel = await self.config.dms.personnel()
        except DMSError as e:
            self._log.error("Unable to vend personnel: {failure}", failure=e)
            personnel = ()

        return (
            buildJSONArray(
                jsonTextFromObject(jsonObjectFromModelObject(ranger)).encode(
                    "utf-8") for ranger in personnel),
            str(hash(personnel)),
        )
예제 #19
0
    def urlsEndpoint(self, request: IRequest) -> KleinRenderable:
        """
        JavaScript variables for service URLs.
        """
        urls = {
            k: getattr(URLs, k).asText() for k in URLs.__dict__
            if not k.startswith("_")
        }

        request.setHeader(
            HeaderName.contentType.value, ContentType.javascript.value
        )

        return "\n".join((
            "var url_{} = {};".format(k, jsonTextFromObject(v))
            for k, v in urls.items()
        ))
예제 #20
0
    async def readAdminAccessResource(self,
                                      request: IRequest) -> KleinRenderable:
        """
        Admin access control endpoint.
        """
        await self.config.authProvider.authorizeRequest(
            request, None, Authorization.imsAdmin)

        store = self.config.store

        acl = {}
        for event in await store.events():
            acl[event.id] = dict(
                readers=await store.readers(event),
                writers=await store.writers(event),
            )
        return jsonTextFromObject(acl)
예제 #21
0
    async def listIncidentReportsResource(
            self, request: IRequest) -> KleinRenderable:
        """
        Incident reports endpoint.
        """
        store = self.config.store

        eventID = queryValue(request, "event")
        incidentNumberText = queryValue(request, "incident")

        if eventID is None:
            return invalidQueryResponse(request, "event")

        if incidentNumberText is None:
            return invalidQueryResponse(request, "incident")

        if eventID == incidentNumberText == "":
            await self.config.authProvider.authorizeRequest(
                request, None, Authorization.readIncidentReports)
            incidentReports = await store.detachedIncidentReports()

        else:
            try:
                event = Event(id=eventID)
            except ValueError:
                return invalidQueryResponse(request, "event", eventID)

            try:
                incidentNumber = int(incidentNumberText)
            except ValueError:
                return invalidQueryResponse(request, "incident",
                                            incidentNumberText)

            await self.config.authProvider.authorizeRequest(
                request, event, Authorization.readIncidents)
            incidentReports = await store.incidentReportsAttachedToIncident(
                event=event, incidentNumber=incidentNumber)

        stream = buildJSONArray(
            jsonTextFromObject(jsonObjectFromModelObject(
                incidentReport)).encode("utf-8")
            for incidentReport in incidentReports)

        writeJSONStream(request, stream, None)
        return None
예제 #22
0
    def _transmogrify(self, loggerEvent: Mapping,
                      eventID: int) -> Optional[Event]:
        """
        Convert a logger event into an EventSource event.
        """
        eventClass = loggerEvent.get("storeWriteClass", None)

        if eventClass is None:
            # Not a data store event
            return None

        elif eventClass is Incident:
            incident = loggerEvent.get("incident", None)

            if incident is None:
                incidentNumber = loggerEvent.get("incidentNumber", None)
            else:
                incidentNumber = incident.number

            if incidentNumber is None:
                self._log.critical(
                    "Unable to determine incident number from store event: "
                    "{event}",
                    event=loggerEvent,
                )
                return None

            message = dict(incident_number=incidentNumber)

        else:
            self._log.critical(
                "Unknown data store event class {eventClass} "
                "sent event: {event}",
                eventClass=eventClass,
                event=loggerEvent,
            )
            return None

        eventSourceEvent = Event(
            eventID=eventID,
            eventClass=eventClass.__name__,
            message=jsonTextFromObject(message),
        )
        return eventSourceEvent
    def _transmogrify(
        self, loggerEvent: Mapping, eventID: int
    ) -> Optional[Event]:
        """
        Convert a logger event into an EventSource event.
        """
        eventClass = loggerEvent.get("storeWriteClass", None)

        if eventClass is None:
            # Not a data store event
            return None

        elif eventClass is Incident:
            incident = loggerEvent.get("incident", None)

            if incident is None:
                incidentNumber = loggerEvent.get("incidentNumber", None)
            else:
                incidentNumber = incident.number

            if incidentNumber is None:
                self.log.critical(
                    "Unable to determine incident number from store event: "
                    "{event}",
                    event=loggerEvent,
                )
                return None

            message = dict(incident_number=incidentNumber)

        else:
            self.log.debug(
                "Unknown data store event class: {eventClass}",
                eventClass=eventClass
            )
            return None

        eventSourceEvent = Event(
            eventID=eventID,
            eventClass=eventClass.__name__,
            message=jsonTextFromObject(message),
        )
        return eventSourceEvent
예제 #24
0
    async def personnelData(self) -> Tuple[Iterable[bytes], str]:
        """
        Data for personnel endpoint.
        """
        try:
            personnel = await self.config.dms.personnel()
        except DMSError as e:
            self._log.error("Unable to vend personnel: {failure}", failure=e)
            personnel = ()

        return (
            buildJSONArray(
                jsonTextFromObject(
                    jsonObjectFromModelObject(ranger)
                ).encode("utf-8")
                for ranger in personnel
            ),
            str(hash(personnel)),
        )
예제 #25
0
    async def readAdminAccessResource(
        self, request: IRequest
    ) -> KleinRenderable:
        """
        Admin access control endpoint.
        """
        await self.config.authProvider.authorizeRequest(
            request, None, Authorization.imsAdmin
        )

        store = self.config.store

        acl = {}
        for event in await store.events():
            acl[event.id] = dict(
                readers=await store.readers(event),
                writers=await store.writers(event),
            )
        return jsonTextFromObject(acl)
예제 #26
0
    async def incidentTypesResource(
        self, request: IRequest
    ) -> KleinRenderable:
        """
        Incident types endpoint.
        """
        self.config.authProvider.authenticateRequest(request)

        hidden = queryValue(request, "hidden") == "true"

        incidentTypes = tuple(
            await self.config.store.incidentTypes(includeHidden=hidden)
        )

        stream = buildJSONArray(
            jsonTextFromObject(incidentType).encode("utf-8")
            for incidentType in incidentTypes
        )

        writeJSONStream(request, stream, None)
        return None
예제 #27
0
    async def listIncidentsResource(
        self, request: IRequest, eventID: str
    ) -> None:
        """
        Incident list endpoint.
        """
        event = Event(id=eventID)

        await self.config.authProvider.authorizeRequest(
            request, event, Authorization.readIncidents
        )

        stream = buildJSONArray(
            jsonTextFromObject(
                jsonObjectFromModelObject(incident)
            ).encode("utf-8")
            for incident in await self.config.store.incidents(event)
        )

        writeJSONStream(request, stream, None)
        return None
예제 #28
0
    def url(self, request: IRequest, tag: Tag) -> KleinRenderable:
        """
        Look up a URL with the name specified by the given tag's C{"url"}
        attribute, which will be removed.
        If the tag has an C{"attr"} attribute, remove it and add the URL to the
        tag in the attribute named by the (removed) C{"attr"} attribute and
        return the tag.
        For C{"a"} tags, C{"attr"} defaults to C{"href"}.
        For C{"img"} tags, C{"attr"} defaults to C{"src"}.
        If the C{"attr"} attribute is defined C{""}, return the URL as text.
        """
        name = tag.attributes.pop("url", None)

        if name is None:
            raise ValueError("Rendered URL must have a url attribute")

        try:
            url = getattr(self.config.urls, name)
        except AttributeError:
            raise ValueError(f"Unknown URL name: {name}")

        text = url.asText()

        if tag.tagName == "json":
            return jsonTextFromObject(text)

        attributeName = tag.attributes.pop("attr", None)
        if attributeName is None:
            if tag.tagName in ("a", "link"):
                attributeName = "href"
            elif tag.tagName in ("script", "img"):
                attributeName = "src"
            else:
                raise ValueError("Rendered URL must have an attr attribute")

        if attributeName == "":
            return text
        else:
            tag.attributes[attributeName] = text
            return tag
예제 #29
0
    async def eventsResource(self, request: IRequest) -> KleinRenderable:
        """
        Events endpoint.
        """
        self.config.authProvider.authenticateRequest(request)

        authorizationsForUser = partial(
            self.config.authProvider.authorizationsForUser, request.user
        )

        events = sorted([
            event for event in
            await self.config.store.events()
            if Authorization.readIncidents & await authorizationsForUser(event)
        ])

        stream = buildJSONArray(
            jsonTextFromObject(event).encode("utf-8")
            for event in events
        )

        writeJSONStream(request, stream, None)
        return None
예제 #30
0
    async def readIncidentReportResource(
        self, request: IRequest, number: int
    ) -> KleinRenderable:
        """
        Incident report endpoint.
        """
        try:
            number = int(number)
        except ValueError:
            self.config.authProvider.authenticateRequest(request)
            return notFoundResponse(request)

        incidentReport = await self.config.store.incidentReportWithNumber(
            number
        )

        await self.config.authProvider.authorizeRequestForIncidentReport(
            request, incidentReport
        )

        text = jsonTextFromObject(jsonObjectFromModelObject(incidentReport))

        return jsonBytes(request, text.encode("utf-8"))
예제 #31
0
    """

    name: str = title
    number: Optional[int]


    @renderer
    def editing_allowed(self, request: IRequest, tag: Tag) -> KleinRenderable:
        """
        JSON boolean, true if editing is allowed.
        """
        if (request.authorizations & Authorization.writeIncidentReports):
            return jsonTrue
        else:
            return jsonFalse


    @renderer
    def incident_report_number(
        self, request: IRequest, tag: Tag
    ) -> KleinRenderable:
        """
        JSON integer: incident report number.
        """
        return jsonTextFromObject(self.number)



jsonTrue  = jsonTextFromObject(True)
jsonFalse = jsonTextFromObject(False)
예제 #32
0
    def load(self) -> None:
        """
        Load the configuration.
        """
        command = basename(argv[0])

        configParser = ConfigParser()

        def readConfig(path: Optional[Path]) -> None:
            if path is None:
                self._log.info("No configuration file specified.")
                return

            for _okFile in configParser.read(str(path)):
                self._log.info(
                    "Read configuration file: {path}", path=path
                )
                break
            else:
                self._log.error(
                    "Unable to read configuration file: {path}", path=path
                )

        def valueFromConfig(
            section: str, option: str, default: Optional[str]
        ) -> Optional[str]:
            try:
                value = configParser.get(section, option)
                if value:
                    return value
                else:
                    return default
            except (NoSectionError, NoOptionError):
                return default

        def pathFromConfig(
            section: str, option: str, root: Path, segments: Tuple[str]
        ) -> Path:
            if section is None:
                text = None
            else:
                text = valueFromConfig(section, option, None)

            if text is None:
                path = root
                for segment in segments:
                    path = path / segment

            elif text.startswith("/"):
                path = Path(text)

            else:
                path = root
                for segment in text.split(pathsep):
                    path = path / segment

            return path

        readConfig(self.ConfigFile)

        if self.ConfigFile is None:
            defaultRoot = Path(getcwd())
        else:
            defaultRoot = self.ConfigFile.parent.parent

        self.HostName = valueFromConfig("Core", "Host", "localhost")
        self._log.info("HostName: {hostName}", hostName=self.HostName)

        self.Port = int(cast(str, valueFromConfig("Core", "Port", "8080")))
        self._log.info("Port: {port}", port=self.Port)

        self.ServerRoot = pathFromConfig(
            "Core", "ServerRoot", defaultRoot, cast(Tuple[str], ())
        )
        self._log.info("Server root: {path}", path=self.ServerRoot)

        self.ConfigRoot = pathFromConfig(
            "Core", "ConfigRoot", self.ServerRoot, ("conf",)
        )
        self._log.info("Config root: {path}", path=self.ConfigRoot)

        self.DataRoot = pathFromConfig(
            "Core", "DataRoot", self.ServerRoot, ("data",)
        )
        self._log.info("Data root: {path}", path=self.DataRoot)

        self.DatabasePath = pathFromConfig(
            "Core", "Database", self.DataRoot, ("db.sqlite",)
        )
        self._log.info("Database: {path}", path=self.DatabasePath)

        self.CachedResourcesPath = pathFromConfig(
            "Core", "CachedResources", self.DataRoot, ("cache",)
        )
        self._log.info(
            "CachedResourcesPath: {path}", path=self.CachedResourcesPath
        )

        self.LogLevelName = valueFromConfig("Core", "LogLevel", "info")
        self._log.info("LogLevel: {logLevel}", logLevel=self.LogLevelName)

        self.LogFormat = valueFromConfig("Core", "LogFormat", "text")
        self._log.info("LogFormat: {logFormat}", logFormat=self.LogFormat)

        self.LogFilePath = pathFromConfig(
            "Core", "LogFile", self.DataRoot, (f"{command}.log",)
        )
        self._log.info("LogFile: {path}", path=self.LogFilePath)

        admins = cast(str, valueFromConfig("Core", "Admins", ""))
        self.IMSAdmins: FrozenSet[str] = frozenset(
            a.strip() for a in admins.split(",")
        )
        self._log.info("Admins: {admins}", admins=self.IMSAdmins)

        active = (
            cast(str, valueFromConfig("Core", "RequireActive", "true")).lower()
        )
        if active in ("false", "no", "0"):
            self.RequireActive = False
        else:
            self.RequireActive = True
        self._log.info(
            "RequireActive: {active}", active=self.RequireActive
        )

        self.DMSHost     = valueFromConfig("DMS", "Hostname", None)
        self.DMSDatabase = valueFromConfig("DMS", "Database", None)
        self.DMSUsername = valueFromConfig("DMS", "Username", None)
        self.DMSPassword = valueFromConfig("DMS", "Password", None)

        self._log.info(
            "Database: {user}@{host}/{db}",
            user=self.DMSUsername, host=self.DMSHost, db=self.DMSDatabase,
        )

        self.MasterKey = valueFromConfig("Core", "MasterKey", None)

        #
        # Persist some objects
        #

        self.dms = DutyManagementSystem(
            host=self.DMSHost,
            database=self.DMSDatabase,
            username=self.DMSUsername,
            password=self.DMSPassword,
        )

        self.store: IMSDataStore = DataStore(dbPath=self.DatabasePath)

        self.authProvider = AuthProvider(
            store=self.store,
            dms=self.dms,
            requireActive=self.RequireActive,
            adminUsers=self.IMSAdmins,
            masterKey=self.MasterKey,
        )

        locationsPath = self.DataRoot / "locations.json"

        if locationsPath.is_file():
            with locationsPath.open() as jsonStrem:
                json = objectFromJSONBytesIO(jsonStrem)
            self._log.info("{count} locations", count=len(json))
            self.locationsJSONBytes = jsonTextFromObject(json).encode("utf-8")
        else:
            self._log.info("No locations file: {path}", path=locationsPath)
            self.locationsJSONBytes = jsonTextFromObject([]).encode("utf-8")
예제 #33
0
 def event_id(self, request: IRequest, tag: Tag) -> KleinRenderable:
     """
     JSON string: event ID.
     """
     return jsonTextFromObject(self.event.id)
예제 #34
0
 def event_id(self, request: IRequest, tag: Tag) -> KleinRenderable:
     """
     JSON string: event ID.
     """
     return jsonTextFromObject(self.event.id)
예제 #35
0
class IncidentReportPage(Page):
    """
    Incident report page.
    """
    def __init__(self, config: Configuration, number: Optional[int]) -> None:
        super().__init__(config=config, title=title)
        self.number = number

    @renderer
    def editing_allowed(self, request: IRequest, tag: Tag) -> KleinRenderable:
        """
        JSON boolean, true if editing is allowed.
        """
        if (request.authorizations & Authorization.writeIncidentReports):
            return jsonTrue
        else:
            return jsonFalse

    @renderer
    def incident_report_number(self, request: IRequest,
                               tag: Tag) -> KleinRenderable:
        """
        JSON integer: incident report number.
        """
        return jsonTextFromObject(self.number)


jsonTrue = jsonTextFromObject(True)
jsonFalse = jsonTextFromObject(False)
예제 #36
0
 def incident_number(self, request: IRequest, tag: Tag) -> KleinRenderable:
     """
     JSON integer: incident number.
     """
     return jsonTextFromObject(self.number)