예제 #1
0
    def __call__(self, value, context):
        if not type(value) is dict:
            raise OperationError("invalid input: %s is not a dictionary" %
                                 context)

        specified_names = set(value.keys())

        class Missing:
            pass

        def read_with_suffixes(name, checker):
            try:
                if name in value:
                    specified_names.remove(name)
                    context.push("." + name)
                    return check(checker, value[name], context)
                for suffix, suffixed_checker in checker.getSuffixedCheckers():
                    suffixed_name = "%s_%s" % (name, suffix)
                    if suffixed_name in value:
                        specified_names.remove(suffixed_name)
                        context.push("." + suffixed_name)
                        if suffixed_checker is not None:
                            checker = suffixed_checker
                        return check(checker, value.pop(suffixed_name),
                                     context)
                context.push("." + name)
                return Missing
            finally:
                context.pop()

        for name, checker in self.__implicit:
            context.push("." + name)
            if name in value:
                raise OperationError(
                    "invalid input: %s should not be specified" % context)
            value[name] = checker(None, context)
            context.pop()

        def process_members(items, required):
            for name, checker in items:
                converted = read_with_suffixes(name, checker)
                if not converted is Missing:
                    value[name] = converted
                elif required:
                    context.push("." + name)
                    raise OperationError("invalid input: %s missing" % context)

        process_members(self.__prioritized, True)
        process_members(self.__required, True)
        process_members(self.__optional, False)

        if specified_names:
            context.push("." + specified_names.pop())
            raise OperationError("invalid input: %s was not used" % context)
예제 #2
0
 def __call__(self, value, context):
     if not type(value) is list:
         raise OperationError("%s is not a list" % context)
     for index, item in enumerate(value):
         context.push("[%d]" % index)
         value[index] = check(self.__checker, item, context)
         context.pop()
예제 #3
0
 def process_members(items, required):
     for name, checker in items:
         converted = read_with_suffixes(name, checker)
         if not converted is Missing:
             value[name] = converted
         elif required:
             context.push("." + name)
             raise OperationError("invalid input: %s missing" % context)
예제 #4
0
 def __call__(self, value, context):
     if not type(value) is dict:
         raise OperationError("invalid input: %s is not a dictionary" %
                              context)
     for key in value:
         context.push("." + key)
         self.__key_checker(key, context)
         value[key] = check(self.__value_checker, value[key], context)
         context.pop()
예제 #5
0
 def __call__(self, value, context):
     for checker in self.__checkers:
         try:
             variant_context = context.clone()
             value = checker(value, variant_context)
             context.copy_from(variant_context)
             return value
         except (OperationError, OperationFailure):
             pass
     raise OperationError("%s is of invalid type" % context)
예제 #6
0
def basic():
    from operation.basictypes import (OperationResult, OperationError,
                                      OperationFailure,
                                      OperationFailureMustLogin)

    def convert(value):
        return json.loads(str(value))

    #
    # OperationResult
    #

    # OperationResult has status=ok by default.
    assert convert(OperationResult()) == {"status": "ok"}

    # But status can be overridden.
    assert convert(OperationResult(status="bananas")) == {"status": "bananas"}

    # Other values can be set as well.
    assert convert(OperationResult(foo=10)) == {"status": "ok", "foo": 10}

    # Even to None/null.
    assert convert(OperationResult(foo=None)) == {"status": "ok", "foo": None}

    # And test OperationResult.set().
    result = OperationResult()
    result.set("foo", 10)
    assert convert(result) == {"status": "ok", "foo": 10}
    result.set("foo", [1, 2, 3])
    assert convert(result) == {"status": "ok", "foo": [1, 2, 3]}
    result.set("foo", None)
    assert convert(result) == {"status": "ok", "foo": None}

    #
    # OperationError
    #

    assert convert(OperationError("wrong!")) == {
        "status": "error",
        "error": "wrong!"
    }

    #
    # OperationFailure
    #

    assert (convert(OperationFailure("the code", "the title",
                                     "the message")) == {
                                         "status": "failure",
                                         "code": "the code",
                                         "title": "the title",
                                         "message": "the message"
                                     })

    # Check HTML escaping.
    assert (convert(OperationFailure("<code>", "<title>", "<message>")) == {
        "status": "failure",
        "code": "<code>",
        "title": "&lt;title&gt;",
        "message": "&lt;message&gt;"
    })

    # Check HTML escaping with is_html=True (title still escaped, but not the
    # message.)
    assert (convert(OperationFailure("<code>", "<title>", "<message>",
                                     True)) == {
                                         "status": "failure",
                                         "code": "<code>",
                                         "title": "&lt;title&gt;",
                                         "message": "<message>"
                                     })

    print "basic: ok"
예제 #7
0
 def __call__(self, value, context):
     if context.repository is None:
         raise OperationError("missing repository in context")
     return super(Commit, self).__call__(value, context)
예제 #8
0
 def __call__(self, value, context):
     import gitutils
     if context.repository is None:
         raise OperationError("missing repository in context")
     super(CommitSHA1, self).__call__(value, context)
     return gitutils.Commit.fromSHA1(context.db, context.repository, value)
예제 #9
0
 def __call__(self, value, context):
     self.__checker(value, context)
     if value not in self.__enumeration:
         raise OperationError("invalid input: %s is not valid" % context)
예제 #10
0
 def __call__(self, value, context):
     if not isinstance(value, int) or isinstance(value, bool):
         raise OperationError("invalid input: %s is not an integer" %
                              context)
예제 #11
0
 def __call__(self, value, context):
     if not isinstance(value, basestring):
         raise OperationError("invalid input: %s is not a string" % context)
예제 #12
0
    def __call__(self, req, db, user):
        from operation.typechecker import TypeCheckerContext

        if user.isAnonymous() and not self.__accept_anonymous_user:
            return OperationFailureMustLogin()

        if req.method == "POST": data = req.read()
        else: data = req.getParameter("data")

        if not data: raise OperationError("no input")

        try:
            value = json_decode(data)
        except ValueError as error:
            raise OperationError("invalid input: %s" % str(error))

        try:
            self.__checker(value, TypeCheckerContext(req, db, user))
            return self.process(db, user, **value)
        except OperationError as error:
            return error
        except OperationFailure as failure:
            return failure
        except dbutils.NoSuchUser as error:
            return OperationFailure(
                code="nosuchuser",
                title="Who is '%s'?" % error.name,
                message="There is no user in Critic's database named that.")
        except dbutils.NoSuchReview as error:
            return OperationFailure(
                code="nosuchreview",
                title="Invalid review ID",
                message="The review ID r/%d is not valid." % error.id)
        except dbutils.TransactionRollbackError:
            return OperationFailure(
                code="transactionrollback",
                title="Transaction rolled back",
                message=
                "Your database transaction rolled back, probably due to a deadlock.  Please try again."
            )
        except extensions.extension.ExtensionError as error:
            return OperationFailure(code="invalidextension",
                                    title="Invalid extension",
                                    message=error.message)
        except:
            # Decode value again since the type checkers might have modified it.
            value = json_decode(data)

            error_message = ("User: %s\nReferrer: %s\nData: %s\n\n%s" %
                             (user.name, req.getReferrer(),
                              json_encode(self.sanitize(value),
                                          indent=2), traceback.format_exc()))

            db.rollback()

            import mailutils
            import configuration

            if not user.hasRole(db, "developer"):
                mailutils.sendExceptionMessage(db, "wsgi[%s]" % req.path,
                                               error_message)

            if configuration.debug.IS_DEVELOPMENT or user.hasRole(
                    db, "developer"):
                return OperationError(error_message)
            else:
                return OperationError(
                    "An unexpected error occurred.  " +
                    "A message has been sent to the system administrator(s) " +
                    "with details about the problem.")
예제 #13
0
 def process(self, *args, **kwargs):
     raise OperationError("not implemented!?!")