def get_keyword_query(self, **kw):
        """Generates a query from the given keywords. Only known indexes make it
        into the generated query.

        :returns: Catalog query
        :rtype: dict
        """
        query = dict()

        # Only known indexes get observed
        indexes = self.catalog.get_indexes()

        # Handle additional keyword parameters
        for k, v in kw.iteritems():
            # handle uid in keywords
            if k.lower() == "uid":
                k = "UID"
            # handle portal_type in keywords
            if k.lower() == "portal_type":
                if v:
                    v = u.to_list(v)
            if k not in indexes:
                logger.warn("Skipping unknown keyword parameter '%s=%s'" % (k, v))
                continue
            if v is None:
                logger.warn("Skip None value in kw parameter '%s=%s'" % (k, v))
                continue
            logger.debug("Adding '%s=%s' to query" % (k, v))
            query[k] = v

        return query
示例#2
0
def get_object_by_record(record):
    """Find an object by a given record

    Inspects request the record to locate an object

    :param record: A dictionary representation of an object
    :type record: dict
    :returns: Found Object or None
    :rtype: object
    """

    # nothing to do here
    if not record:
        return None

    if record.get("uid"):
        return get_object_by_uid(record["uid"])
    if record.get("path"):
        return get_object_by_path(record["path"])
    if record.get("parent_path") and record.get("id"):
        path = "/".join([record["parent_path"], record["id"]])
        return get_object_by_path(path)

    logger.warn("get_object_by_record::No object found! record='%r'" % record)
    return None
示例#3
0
    def get_keyword_query(self, **kw):
        """Generates a query from the given keywords. Only known indexes make it
        into the generated query.

        :returns: Catalog query
        :rtype: dict
        """
        query = dict()

        # Only known indexes get observed
        indexes = self.catalog.get_indexes()

        # Handle additional keyword parameters
        for k, v in kw.iteritems():
            # handle uid in keywords
            if k.lower() == "uid":
                k = "UID"
            # handle portal_type in keywords
            if k.lower() == "portal_type":
                if v:
                    v = _.to_list(v)
            if k not in indexes:
                logger.warn("Skipping unknown keyword parameter '%s=%s'" %
                            (k, v))
                continue
            if v is None:
                logger.warn("Skip None value in kw parameter '%s=%s'" % (k, v))
                continue
            logger.debug("Adding '%s=%s' to query" % (k, v))
            query[k] = v

        return query
示例#4
0
def resource_to_portal_type(resource):
    """Converts a resource to a portal type

    :param resource: Resource name as it is used in the content route
    :type name: string
    :returns: Portal type name
    :rtype: string
    """
    if resource is None:
        return None

    resource_mapping = get_resource_mapping()
    portal_type = resource_mapping.get(resource.lower())

    # BBB: Handle pre 0.9.1 resource routes, e.g. folders, collections...
    if portal_type is None and resource.endswith("s"):
        new_resource = resource.rstrip("s")
        portal_type = resource_mapping.get(new_resource)
        if portal_type:
            logger.warn("Old style resources will be removed in 1.0. "
                        "Please use '{}' instead of '{}'".format(
                            new_resource, resource))

    if portal_type is None:
        logger.warn("Could not map the resource '{}' "
                    "to any known portal type".format(resource))

    return portal_type
示例#5
0
def get(context, request, resource=None, uid=None):
    """Get Plone contents, e.g.

    <Plonesite>/@@API/plone/api/1.0/folder -> returns all folders
    <Plonesite>/@@API/plone/api/1.0/folder/4711 -> returns the folder with UID 4711
    """

    # We have a UID, return the record
    if uid and not resource:
        return api.get_record(uid)

    # we have a UID as resource, return the record
    if api.is_uid(resource):
        return api.get_record(resource)

    # BBB
    if resource == "get":
        logger.warn(
            "The /get route is obsolete and will be removed in 1.0.0. Please use /<UID> instead"
        )
        return api.get_record(uid)

    portal_type = api.resource_to_portal_type(resource)
    if portal_type is None:
        raise APIError(404, "Not Found")
    return api.get_batched(portal_type=portal_type,
                           uid=uid,
                           endpoint="plone.jsonapi.routes.get")
    def set(self, instance, value, **kw):
        """Converts the value into a DateTime object before setting.
        """
        try:
            value = DateTime(value)
        except SyntaxError:
            logger.warn(
                "Value '{}' is not a valid DateTime string".format(value))
            return False

        self._set(instance, value, **kw)
    def set(self, instance, value, **kw):
        """Converts the value into a DateTime object before setting.
        """
        try:
            value = DateTime(value)
        except SyntaxError:
            logger.warn("Value '{}' is not a valid DateTime string"
                        .format(value))
            return False

        self._set(instance, value, **kw)
    def json_data(self, instance, default=None):
        """Get a JSON compatible value
        """
        value = self.get(instance)

        out = []
        for rel in value:
            if rel.isBroken():
                logger.warn("Skipping broken relation {}".format(repr(rel)))
                continue
            obj = rel.to_object
            out.append(api.get_url_info(obj))
        return out
    def json_data(self, instance, default=None):
        """Get a JSON compatible value
        """
        value = self.get(instance)

        out = []
        for rel in value:
            if rel.isBroken():
                logger.warn("Skipping broken relation {}".format(repr(rel)))
                continue
            obj = rel.to_object
            out.append(api.get_url_info(obj))
        return out
示例#10
0
def get_user_info(user):
    """Get the user information
    """
    user = api.get_user(user)
    current = api.get_current_user()

    if api.is_anonymous():
        return {
            "username":
            current.getUserName(),
            "authenticated":
            False,
            "roles":
            current.getRoles(),
            "api_url":
            api.url_for("plone.jsonapi.routes.users", username="******"),
        }

    # nothing to do
    if user is None:
        logger.warn("No user found for {}".format(user))
        return None

    # plone user
    pu = user.getUser()

    info = {
        "username":
        user.getUserName(),
        "roles":
        user.getRoles(),
        "groups":
        pu.getGroups(),
        "authenticated":
        current == user,
        "api_url":
        api.url_for("plone.jsonapi.routes.users", username=user.getId()),
    }

    for k, v in api.get_user_properties(user).items():
        if api.is_date(v):
            v = api.to_iso_date(v)
        if not api.is_json_serializable(v):
            logger.warn(
                "User property '{}' is not JSON serializable".format(k))
            continue
        info[k] = v

    return info
示例#11
0
def url_for(endpoint, **values):
    """Looks up the API URL for the given endpoint

    :param endpoint: The name of the registered route
    :type endpoint: string
    :returns: External URL for this endpoint
    :rtype: string/None
    """

    try:
        return router.url_for(endpoint, force_external=True, values=values)
    except Exception:
        # XXX plone.jsonapi.core should catch the BuildError of Werkzeug and
        #     throw another error which can be handled here.
        logger.warn("Could not build API URL for endpoint '%s'. "
                    "No route provider registered?" % endpoint)
        return None
示例#12
0
def update_object_with_data(content, record):
    """Update the content with the record data

    :param content: A single folderish catalog brain or content object
    :type content: ATContentType/DexterityContentType/CatalogBrain
    :param record: The data to update
    :type record: dict
    :returns: The updated content object
    :rtype: object
    :raises:
        APIError,
        :class:`~plone.jsonapi.routes.exceptions.APIError`
    """

    # ensure we have a full content object
    content = get_object(content)

    # get the proper data manager
    dm = IDataManager(content)

    if dm is None:
        fail(400, "Update for this object is not allowed")

    # https://github.com/collective/plone.jsonapi.routes/issues/77
    # filter out bogus keywords
    # XXX Maybe we should pass only values where we have identical field names?
    field_kwargs = u.omit(record, "file")

    # Iterate through record items
    for k, v in record.items():
        try:
            success = dm.set(k, v, **field_kwargs)
        except Unauthorized:
            fail(401, "Not allowed to set the field '%s'" % k)
        except ValueError, exc:
            fail(400, str(exc))

        if not success:
            logger.warn("update_object_with_data::skipping key=%r", k)
            continue

        logger.debug("update_object_with_data::field %r updated", k)
示例#13
0
def get_user_info(user):
    """Get the user information
    """
    user = api.get_user(user)
    current = api.get_current_user()

    if api.is_anonymous():
        return {
            "username": current.getUserName(),
            "authenticated": False,
            "roles": current.getRoles(),
            "api_url": api.url_for("plone.jsonapi.routes.users", username="******"),
        }

    # nothing to do
    if user is None:
        logger.warn("No user found for {}".format(user))
        return None

    # plone user
    pu = user.getUser()

    info = {
        "username": user.getUserName(),
        "roles": user.getRoles(),
        "groups": pu.getGroups(),
        "authenticated": current == user,
        "api_url": api.url_for("plone.jsonapi.routes.users", username=user.getId()),
    }

    for k, v in api.get_user_properties(user).items():
        if api.is_date(v):
            v = api.to_iso_date(v)
        if not api.is_json_serializable(v):
            logger.warn("User property '{}' is not JSON serializable".format(k))
            continue
        info[k] = v

    return info
示例#14
0
def to_json_value(obj, fieldname, value=_marker, default=None):
    """JSON save value encoding

    :param obj: Content object
    :type obj: ATContentType/DexterityContentType
    :param fieldname: Schema name of the field
    :type fieldname: str/unicode
    :param value: The field value
    :type value: depends on the field type
    :returns: JSON encoded field value
    :rtype: field dependent
    """

    # This function bridges the value of the field to a probably more complex
    # JSON structure to return to the client.

    # extract the value from the object if omitted
    if value is _marker:
        value = IDataManager(obj).json_data(fieldname)

    # convert objects
    if isinstance(value, ImplicitAcquisitionWrapper):
        return get_url_info(value)

    # convert dates
    if is_date(value):
        return to_iso_date(value)

    # check if the value is callable
    if callable(value):
        value = value()

    # check if the value is JSON serializable
    if not is_json_serializable(value):
        logger.warn("Output {} is not JSON serializable".format(repr(value)))
        return default

    return value
    def _set(self, instance, value, **kw):
        """Set the value of the field
        """
        logger.debug("DexterityFieldManager::set: value=%r" % value)

        # Check if the field is read only
        if self.field.readonly:
            raise Unauthorized("Field is read only")

        fieldname = self.get_field_name()
        # id fields take only strings
        if fieldname == "id":
            value = str(value)

        try:
            # Validate
            self.field.validate(value)

            # TODO: Check security on the field level
            return self.field.set(instance, value)
        except WrongType:
            logger.warn("WrongType: Field={} Value={}".format(self.field, value))
        except:
            logger.warn("Unknown Exception: Field={} Value={}".format(self.field, value))
示例#16
0
def get(context, request, resource=None, uid=None):
    """Get Plone contents, e.g.

    <Plonesite>/@@API/plone/api/1.0/folder -> returns all folders
    <Plonesite>/@@API/plone/api/1.0/folder/4711 -> returns the folder with UID 4711
    """

    # We have a UID, return the record
    if uid and not resource:
        return api.get_record(uid)

    # we have a UID as resource, return the record
    if api.is_uid(resource):
        return api.get_record(resource)

    # BBB
    if resource == "get":
        logger.warn("The /get route is obsolete and will be removed in 1.0.0. Please use /<UID> instead")
        return api.get_record(uid)

    portal_type = api.resource_to_portal_type(resource)
    if portal_type is None:
        raise APIError(404, "Not Found")
    return api.get_batched(portal_type=portal_type, uid=uid, endpoint="plone.jsonapi.routes.get")
 def set(self, name, value, **kw):
     """Setter is not used for catalog brains
     """
     logger.warn("Setting is not allowed on catalog brains")
示例#18
0
 def set(self, name, value, **kw):
     """Setter is not used for catalog brains
     """
     logger.warn("Setting is not allowed on catalog brains")