Esempio n. 1
0
    def extractValue(self, request: IRequest) -> Any:
        """
        Extract a value from the request.

        In the case of key/value form posts, this attempts to reliably make the
        value into str.  In the case of a JSON post, however, it will simply
        extract the value from the top-level dictionary, which means it could
        be any arrangement of JSON-serializiable objects.
        """
        fieldName = self.formFieldName
        if fieldName is None:
            raise ValueError("Cannot extract unnamed form field.")
        contentType = request.getHeader(b"content-type")
        if contentType is not None and contentType.startswith(
                b"application/json"):
            # TODO: parse only once, please.
            parsed = request.getComponent(IParsedJSONBody)
            if parsed is None:
                request.content.seek(0)
                octets = request.content.read()
                characters = octets.decode("utf-8")
                parsed = json.loads(characters)
                request.setComponent(IParsedJSONBody, parsed)
            if fieldName not in parsed:
                return None
            return parsed[fieldName]
        allValues = request.args.get(fieldName.encode("utf-8"))
        if allValues:
            return allValues[0].decode("utf-8")
        else:
            return None
Esempio n. 2
0
    def populateRequestValues(
        self,
        injectionComponents: Componentized,
        instance: Any,
        request: IRequest,
    ) -> Deferred:
        """
        Extract the values present in this request and populate a
        L{FieldValues} object.
        """
        assert IFieldValues(request, None) is None

        validationErrors = {}
        prevalidationValues = {}
        arguments = {}

        checkCSRF(request)

        for field in self.fields:
            text = field.extractValue(request)
            prevalidationValues[field] = text
            try:
                value = field.validateValue(text)
                argName = field.pythonArgumentName
                if argName is None:
                    raise ValidationError("Form fields must all have names.")
            except ValidationError as ve:
                validationErrors[field] = ve
            else:
                arguments[argName] = value
        values = FieldValues(
            self,
            arguments,
            prevalidationValues,
            validationErrors,
            injectionComponents,
        )
        yield values.validate(instance, request)
        request.setComponent(IFieldValues, values)
Esempio n. 3
0
    def procureSession(self,
                       request: IRequest,
                       forceInsecure: bool = False) -> Any:
        alreadyProcured = request.getComponent(ISession)
        if alreadyProcured is not None:
            if not forceInsecure or not request.isSecure():
                returnValue(alreadyProcured)

        if request.isSecure():
            if forceInsecure:
                tokenHeader = self._insecureTokenHeader
                cookieName: Union[str, bytes] = self._insecureCookie
                sentSecurely = False
            else:
                tokenHeader = self._secureTokenHeader
                cookieName = self._secureCookie
                sentSecurely = True
        else:
            # Have we inadvertently disclosed a secure token over an insecure
            # transport, for example, due to a buggy client?
            allPossibleSentTokens: Sequence[str] = sum(
                [
                    request.requestHeaders.getRawHeaders(header, [])
                    for header in [
                        self._secureTokenHeader,
                        self._insecureTokenHeader,
                    ]
                ],
                [],
            ) + [
                it for it in [
                    request.getCookie(cookie)
                    for cookie in [self._secureCookie, self._insecureCookie]
                ] if it
            ]
            # Does it seem like this check is expensive? It sure is! Don't want
            # to do it? Turn on your dang HTTPS!
            yield self._store.sentInsecurely(allPossibleSentTokens)
            tokenHeader = self._insecureTokenHeader
            cookieName = self._insecureCookie
            sentSecurely = False
            # Fun future feature: honeypot that does this over HTTPS, but sets
            # isSecure() to return false because it serves up a cert for the
            # wrong hostname or an invalid cert, to keep API clients honest
            # about chain validation.
        sentHeader = (request.getHeader(tokenHeader) or b"").decode("utf-8")
        sentCookie = (request.getCookie(cookieName) or b"").decode("utf-8")
        if sentHeader:
            mechanism = SessionMechanism.Header
        else:
            mechanism = SessionMechanism.Cookie
        if not (sentHeader or sentCookie):
            session = None
        else:
            try:
                session = yield self._store.loadSession(
                    sentHeader or sentCookie, sentSecurely, mechanism)
            except NoSuchSession:
                if mechanism == SessionMechanism.Header:
                    raise
                session = None
        if mechanism == SessionMechanism.Cookie and (
                session is None or session.identifier != sentCookie):
            if session is None:
                if request.startedWriting:
                    # At this point, if the mechanism is Header, we either have
                    # a valid session or we bailed after NoSuchSession above.
                    raise TooLateForCookies(
                        "You tried initializing a cookie-based session too"
                        " late in the request pipeline; the headers"
                        " were already sent.")
                if request.method != b"GET":
                    # Sessions should only ever be auto-created by GET
                    # requests; there's no way that any meaningful data
                    # manipulation could succeed (no CSRF token check could
                    # ever succeed, for example).
                    raise NoSuchSession(
                        "Can't initialize a session on a "
                        "{method} request.".format(
                            method=request.method.decode("ascii")))
                if not self._setCookieOnGET:
                    # We don't have a session ID at all, and we're not allowed
                    # by policy to set a cookie on the client.
                    raise NoSuchSession(
                        "Cannot auto-initialize a session for this request.")
                session = yield self._store.newSession(sentSecurely, mechanism)
            identifierInCookie = session.identifier
            if not isinstance(identifierInCookie, str):
                identifierInCookie = identifierInCookie.encode("ascii")
            if not isinstance(cookieName, str):
                cookieName = cookieName.decode("ascii")
            request.addCookie(
                cookieName,
                identifierInCookie,
                max_age=str(self._maxAge),
                domain=self._cookieDomain,
                path=self._cookiePath,
                secure=sentSecurely,
                httpOnly=True,
            )
        if sentSecurely or not request.isSecure():
            # Do not cache the insecure session on the secure request, thanks.
            request.setComponent(ISession, session)
        returnValue(session)
Esempio n. 4
0
def provideSample(request: IRequest) -> None:
    """
    This requirer prerequisite installs a string as the provider of ISample.
    """
    request.setComponent(ISample, "sample component")