Exemplo n.º 1
0
 def get_role_permission(self,
                         role,
                         expectedCount,
                         model_name='Plot',
                         field_name='geom'):
     perms = role_permissions(role, self.instance, model_name)
     return self.get_permission(perms, field_name, expectedCount)
Exemplo n.º 2
0
    def test_adds_udf_to_role_when_created(self):
        body = {'udf.name': 'cool udf',
                'udf.model': 'Plot',
                'udf.type': 'string'}

        udf_create(body, self.instance)

        roles_in_instance = Role.objects.filter(instance=self.instance)

        self.assertGreater(len(roles_in_instance), 0)

        for role in roles_in_instance:
            perms = [perm.field_name
                     for perm in role_permissions(role, self.instance)]

            self.assertIn('udf:cool udf', perms)
Exemplo n.º 3
0
 def model_permissions(self, model_name):
     return role_permissions(self, self.instance, model_name)
Exemplo n.º 4
0
def instance_info(request, instance):
    """
    Get all the info we need about a given instance

    It also includes info about the fields available for the
    instance. If a user has been specified the field info
    will be tailored to that user
    """
    user = request.user

    role = instance.default_role
    if user and not user.is_anonymous():
        instance_user = user.get_instance_user(instance)
        if instance_user:
            role = instance_user.role

    collection_udfs = instance.userdefinedfielddefinition_set\
                              .filter(iscollection=True)
    collection_udf_dict = {
        "%s.%s" % (udf.model_type.lower(), udf.canonical_name): udf
        for udf in collection_udfs
    }

    # collect perms for the given role/instance into a serializable
    # dictionary. If a field isn't at least readable, it doesn't
    # get sent over at all.
    perms = {}
    for fp in role_permissions(role, instance):
        model = fp.model_name.lower()
        field_key = '%s.%s' % (model, fp.field_name)
        if fp.allows_reads:
            if field_key in collection_udf_dict:
                choices = []
                data_type = json.loads(collection_udf_dict[field_key].datatype)
            elif is_json_field_reference(fp.field_name):
                choices = None
                data_type = "string"
            else:
                model_inst = safe_get_model_class(
                    fp.model_name)(instance=instance)
                data_type, __, choices = field_type_label_choices(
                    model_inst, fp.field_name, fp.display_field_name)

            digits = get_digits_if_formattable(instance, model, fp.field_name)

            units = get_units_if_convertible(instance, model, fp.field_name)

            factor = 1.0

            try:
                factor = get_conversion_factor(instance, model, fp.field_name)
            except KeyError:
                pass

            perms[field_key] = {
                'data_type': data_type,
                'choices': choices,
                'units': units,
                'digits': digits,
                'canonical_units_factor': 1.0 / factor,
                'can_write': fp.allows_writes,
                'display_name': fp.display_field_name,
                'field_name': fp.field_name,
                'field_key': field_key,
                'is_collection': field_key in collection_udf_dict
            }

    def get_key_for_group(field_group):
        for key in ('collection_udf_keys', 'field_keys'):
            if key in field_group:
                return key
        return None

    # Remove fields from mobile_api_fields if they are not present in perms
    # (Generally because the user doesn't have read permissions)
    # If no fields are left in a group, remove the group
    mobile_api_fields = copy.deepcopy(instance.mobile_api_fields)

    for field_group in mobile_api_fields:
        # Field group headers are stored in English, and translated when they
        # are sent out to the client
        field_group['header'] = _(field_group['header'])
        key = get_key_for_group(field_group)
        if key:
            field_group[key] = [
                field for field in field_group[key] if field in perms
            ]

    readable_mobile_api_fields = [
        group for group in mobile_api_fields
        if group.get(get_key_for_group(group), None)
    ]

    info = _instance_info_dict(instance)
    info['fields'] = perms
    info['field_key_groups'] = readable_mobile_api_fields
    info['search'] = instance.mobile_search_fields
    info['date_format'] = _unicode_dateformat(instance.date_format)
    info['short_date_format'] = _unicode_dateformat(instance.short_date_format)

    info['meta_perms'] = {
        'can_add_tree': perms_lib.plot_is_creatable(role),
        'can_edit_tree': perms_lib.plot_is_writable(role),
        'can_edit_tree_photo': perms_lib.treephoto_is_writable(role),
    }

    public_config_keys = ['scss_variables']

    info['config'] = {
        x: instance.config[x]
        for x in instance.config if x in public_config_keys
    }

    if instance.logo:
        info['logoUrl'] = instance.logo.url

    return info
Exemplo n.º 5
0
def instance_info(request, instance):
    """
    Get all the info we need about a given instance

    It also includes info about the fields available for the
    instance. If a user has been specified the field info
    will be tailored to that user
    """
    user = request.user

    role = instance.default_role
    if user and not user.is_anonymous():
        instance_user = user.get_instance_user(instance)
        if instance_user:
            role = instance_user.role

    collection_udfs = instance.collection_udfs
    collection_udf_dict = {"%s.%s" % (udf.model_type.lower(),
                                      udf.canonical_name): udf
                           for udf in collection_udfs}

    # collect perms for the given role/instance into a serializable
    # dictionary. If a field isn't at least readable, it doesn't
    # get sent over at all.
    perms = {}
    for fp in role_permissions(role, instance):
        model = fp.model_name.lower()
        field_key = '%s.%s' % (model, fp.field_name)
        if fp.allows_reads:
            if field_key in collection_udf_dict:
                choices = []
                data_type = json.loads(collection_udf_dict[field_key].datatype)
            elif is_json_field_reference(fp.field_name):
                choices = None
                data_type = "string"
            else:
                model_inst = safe_get_model_class(fp.model_name)(
                    instance=instance)
                data_type, __, choices = field_type_label_choices(
                    model_inst, fp.field_name, fp.display_field_name)

            digits = get_digits_if_formattable(
                instance, model, fp.field_name)

            units = get_units_if_convertible(
                instance, model, fp.field_name)

            factor = 1.0

            try:
                factor = storage_to_instance_units_factor(
                    instance, model, fp.field_name)
            except KeyError:
                pass

            perms[field_key] = {
                'data_type': data_type,
                'choices': choices,
                'units': units,
                'digits': digits,
                'canonical_units_factor': 1.0 / factor,
                'can_write': fp.allows_writes,
                'display_name': fp.display_field_name,
                'field_name': fp.field_name,
                'field_key': field_key,
                'is_collection': field_key in collection_udf_dict
            }

    def get_key_for_group(field_group):
        for key in ('collection_udf_keys', 'field_keys'):
            if key in field_group:
                return key
        return None

    # Remove fields from mobile_api_fields if they are not present in perms
    # (Generally because the user doesn't have read permissions)
    # If no fields are left in a group, remove the group
    mobile_api_fields = copy.deepcopy(instance.mobile_api_fields)

    for field_group in mobile_api_fields:
        # Field group headers are stored in English, and translated when they
        # are sent out to the client
        field_group['header'] = _(field_group['header'])
        key = get_key_for_group(field_group)
        if key:
            field_group[key] = [field for field in field_group[key]
                                if field in perms]

    readable_mobile_api_fields = [group for group in mobile_api_fields
                                  if group.get(get_key_for_group(group), None)]

    info = _instance_info_dict(instance)
    info['fields'] = perms
    info['field_key_groups'] = readable_mobile_api_fields
    info['search'] = mobile_search_fields(instance)
    info['date_format'] = _unicode_dateformat(instance.date_format)
    info['short_date_format'] = _unicode_dateformat(instance.short_date_format)

    info['meta_perms'] = {
        'can_add_tree': perms_lib.plot_is_creatable(role),
        'can_edit_tree': perms_lib.plot_is_writable(role),
        'can_edit_tree_photo': perms_lib.treephoto_is_writable(role),
    }

    public_config_keys = ['scss_variables']

    info['config'] = {x: instance.config[x]
                      for x in instance.config
                      if x in public_config_keys}

    if instance.logo:
        info['logoUrl'] = instance.logo.url

    return info
Exemplo n.º 6
0
def instance_info(request, instance):
    """
    Get all the info we need about a given instance

    It also includes info about the fields available for the
    instance. If a user has been specified the field info
    will be tailored to that user
    """
    user = request.user

    role = instance.default_role
    if user and not user.is_anonymous():
        instance_user = user.get_instance_user(instance)
        if instance_user:
            role = instance_user.role

    collection_udfs = instance.userdefinedfielddefinition_set\
                              .filter(iscollection=True)
    collection_udf_dict = {"%s.%s" % (udf.model_type.lower(),
                                      udf.canonical_name): udf
                           for udf in collection_udfs}

    # collect perms for the given role/instance into a serializable
    # dictionary. If a field isn't at least readable, it doesn't
    # get sent over at all.
    perms = {}
    for fp in role_permissions(role, instance):
        model = fp.model_name.lower()
        field_key = '%s.%s' % (model, fp.field_name)
        if fp.allows_reads:
            if field_key in collection_udf_dict:
                choices = []
                data_type = collection_udf_dict[field_key].datatype
            elif is_json_field_reference(fp.field_name):
                choices = None
                data_type = "string"
            else:
                model_inst = safe_get_model_class(fp.model_name)(
                    instance=instance)
                data_type, _, choices = field_type_label_choices(
                    model_inst, fp.field_name, fp.display_field_name)

            digits = get_digits_if_formattable(
                instance, model, fp.field_name)

            units = get_units_if_convertible(
                instance, model, fp.field_name)

            factor = 1.0

            try:
                factor = get_conversion_factor(
                    instance, model, fp.field_name)
            except KeyError:
                pass

            perms[field_key] = {
                'data_type': data_type,
                'choices': choices,
                'units': units,
                'digits': digits,
                'canonical_units_factor': 1.0 / factor,
                'can_write': fp.allows_writes,
                'display_name': fp.display_field_name,
                'field_name': fp.field_name,
                'field_key': field_key,
                'is_collection': field_key in collection_udf_dict
            }

    info = _instance_info_dict(instance)
    info['fields'] = perms
    info['field_key_groups'] = instance.mobile_api_fields
    info['search'] = instance.mobile_search_fields
    info['date_format'] = _unicode_dateformat(instance.date_format)
    info['short_date_format'] = _unicode_dateformat(instance.short_date_format)

    info['meta_perms'] = {
        'can_add_tree': perms_lib.plot_is_creatable(role),
        'can_edit_tree': perms_lib.plot_is_writable(role),
        'can_edit_tree_photo': perms_lib.treephoto_is_writable(role),
    }

    public_config_keys = ['scss_variables']

    info['config'] = {x: instance.config[x]
                      for x in instance.config
                      if x in public_config_keys}

    if instance.logo:
        info['logoUrl'] = instance.logo.url

    return info
Exemplo n.º 7
0
def _allows_perm(role_related_obj, model_name,
                 predicate, perm_attr,
                 field=None,
                 fields=None,
                 feature_name=None):
    """
    The main permission testing function. This function should
    be called from exported (non-underscore) helper functions.

    role_related_obj can be a Role or InstanceUser (Add more types as needed)

    model_name is a ProperCamelCase string name of the model to test.

    predicate is the function used to set the minimum requirement for
    present permissions to pass the current test. Should be any, all,
    or a custom value.

    perm_attr is the minimum permission value necessary to consider
    the perm present in this context. Should correspond to an attr
    on the FieldPermission class.

    field/fields is the fields to use in conjunction with predicate and
    perm_attr.
    Together they form a truth statement like:
    "all of {'image', 'thumbnail'} have ALLOWS_WRITES"
    "any of {'id', 'mapfeature'} have ALLOWS_READS"

    feature_name checks if this feature is enabled for this instance. While
    not exactly connected to permissions, it's convenient to check this here
    as well.
    """
    role = _get_role_from_related_object(role_related_obj)
    if role is None:
        return False

    if feature_name and not role.instance.feature_enabled(feature_name):
        return False

    perms = {perm for perm in
             role_permissions(role, role.instance, model_name)}

    # process args
    if field and fields:
        raise ValueError("Cannot provide non-None values "
                         "to both 'field' and 'fields'. Pick One.")
    elif field and not fields:
        fields = {field}
    elif not fields:
        fields = set()

    # forcibly convert fields to a set of names (strings)
    # if they were passed in as objects.
    fields = {field.name if isinstance(field, Field) else field
              for field in fields}

    if fields:
        perms = {perm for perm in perms if perm.field_name in fields}

    perm_attrs = {getattr(perm, perm_attr) for perm in perms}

    # TODO: find a better way to support 'all'
    # this is a hack around a quirk, that all([]) == True.
    # Since all is such a common case, it's still nice to
    # support it out of the box.
    if predicate == all and not perm_attrs:
        return False
    else:
        return predicate(perm_attrs)
Exemplo n.º 8
0
 def get_role_permission(self, role, expectedCount, model_name='Plot',
                         field_name='geom'):
     perms = role_permissions(role, self.instance, model_name)
     return self.get_permission(perms, field_name, expectedCount)
Exemplo n.º 9
0
def _allows_perm(role_related_obj,
                 model_name,
                 predicate,
                 perm_attr,
                 field=None,
                 fields=None,
                 feature_name=None):
    """
    The main permission testing function. This function should
    be called from exported (non-underscore) helper functions.

    role_related_obj can be a Role or InstanceUser (Add more types as needed)

    model_name is a ProperCamelCase string name of the model to test.

    predicate is the function used to set the minimum requirement for
    present permissions to pass the current test. Should be any, all,
    or a custom value.

    perm_attr is the minimum permission value necessary to consider
    the perm present in this context. Should correspond to an attr
    on the FieldPermission class.

    field/fields is the fields to use in conjunction with predicate and
    perm_attr.
    Together they form a truth statement like:
    "all of {'image', 'thumbnail'} have ALLOWS_WRITES"
    "any of {'id', 'mapfeature'} have ALLOWS_READS"

    feature_name checks if this feature is enabled for this instance. While
    not exactly connected to permissions, it's convenient to check this here
    as well.
    """
    role = _get_role_from_related_object(role_related_obj)
    if role is None:
        return False

    if feature_name and not role.instance.feature_enabled(feature_name):
        return False

    perms = {
        perm
        for perm in role_permissions(role, role.instance, model_name)
    }

    # process args
    if field and fields:
        raise ValueError("Cannot provide non-None values "
                         "to both 'field' and 'fields'. Pick One.")
    elif field and not fields:
        fields = {field}
    elif not fields:
        fields = set()

    # forcibly convert fields to a set of names (strings)
    # if they were passed in as objects.
    fields = {
        field.name if isinstance(field, Field) else field
        for field in fields
    }

    if fields:
        perms = {perm for perm in perms if perm.field_name in fields}

    perm_attrs = {getattr(perm, perm_attr) for perm in perms}

    # TODO: find a better way to support 'all'
    # this is a hack around a quirk, that all([]) == True.
    # Since all is such a common case, it's still nice to
    # support it out of the box.
    if predicate == all and not perm_attrs:
        return False
    else:
        return predicate(perm_attrs)