def test_rainbarrel_photo_is_not_addable(self): self._add_builtin_permission(self.role_no, RainBarrel, 'add_rainbarrel') self._add_builtin_permission(self.role_no, Bioswale, 'add_bioswale') self._add_builtin_permission(self.role_no, MapFeaturePhoto, 'add_bioswalephoto') rainbarrel = self._create_rainbarrel_return_map_feature() self.assertFalse(perms.photo_is_addable(self.role_no, rainbarrel))
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 = Role.objects.get_role(instance, user) collection_udfs = instance.collection_udfs collection_udf_dict = { "%s.%s" % (udf.model_type.lower(), udf.canonical_name): udf for udf in collection_udfs } def add_perms(field_permissions, perms): for fp in field_permissions: 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 } # 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. field_perms = role_field_permissions(role, instance) always_writable = [ FieldPermission(model_name=Model.__name__, field_name=field_name, permission_level=FieldPermission.WRITE_DIRECTLY) for Model in {Tree, Plot} for field_name in Model.always_writable ] perms = {} add_perms(field_perms, perms) add_perms(always_writable, perms) # Legacy iOS app versions (<= 2.6.0) enforce photo permissions using # the `treephoto.image` field, so set it. This can be removed when we # think all users are on a later version. perms['treephoto.image'] = { 'can_write': perms_lib.photo_is_addable(role, Plot), 'data_type': 'string' } # These identifiers are not included in `perms` for instances # created after the transtion to model-level permissions, but the # identifiers are referenced in the default mobile search # configuration. Versions of the iOS application depend on all the # identifiers in the search config being respresented in the # `perms` dictionary if the user is allowed to see the field # value. Species and photos are always visible, so we can hard # code a non-None value for these identifiers. for identifier in ('species.id', 'mapFeaturePhoto.id'): if identifier not in perms: perms[identifier] = {'data_type': 'string'} 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) or perms_lib.tree_is_writable(role)), 'can_edit_tree_photo': perms_lib.photo_is_addable(role, Plot), } 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
def test_tree_photo_is_not_addable(self): self._add_builtin_permission(self.role_no, Tree, 'add_tree') self._add_builtin_permission(self.role_no, Plot, 'add_plot') plot = Plot(instance=self.instance) self.assertFalse(perms.photo_is_addable(self.role_no, plot))
def test_tree_photo_is_addable(self): self._add_builtin_permission(self.role_yes, TreePhoto, 'add_treephoto') plot = Plot(instance=self.instance) self.assertTrue(perms.photo_is_addable(self.role_yes, plot))
def test_rainbarrel_photo_is_addable(self): self._add_builtin_permission(self.role_yes, MapFeaturePhoto, 'add_rainbarrelphoto') rainbarrel = self._create_rainbarrel_return_map_feature() self.assertTrue(perms.photo_is_addable(self.role_yes, rainbarrel))
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 = Role.objects.get_role(instance, user) collection_udfs = instance.collection_udfs collection_udf_dict = {"%s.%s" % (udf.model_type.lower(), udf.canonical_name): udf for udf in collection_udfs} def add_perms(field_permissions, perms): for fp in field_permissions: 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 } # 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. field_perms = role_field_permissions(role, instance) always_writable = [ FieldPermission( model_name=Model.__name__, field_name=field_name, permission_level=FieldPermission.WRITE_DIRECTLY ) for Model in {Tree, Plot} for field_name in Model.always_writable] perms = {} add_perms(field_perms, perms) add_perms(always_writable, perms) # Legacy iOS app versions (<= 2.6.0) enforce photo permissions using # the `treephoto.image` field, so set it. This can be removed when we # think all users are on a later version. perms['treephoto.image'] = { 'can_write': perms_lib.photo_is_addable(role, Plot), 'data_type': 'string' } # These identifiers are not included in `perms` for instances # created after the transtion to model-level permissions, but the # identifiers are referenced in the default mobile search # configuration. Versions of the iOS application depend on all the # identifiers in the search config being respresented in the # `perms` dictionary if the user is allowed to see the field # value. Species and photos are always visible, so we can hard # code a non-None value for these identifiers. for identifier in ('species.id', 'mapFeaturePhoto.id'): if identifier not in perms: perms[identifier] = { 'data_type': 'string' } 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) or perms_lib.tree_is_writable(role)), 'can_edit_tree_photo': perms_lib.photo_is_addable(role, Plot), } 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
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 = Role.objects.get_role(instance, user) 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_field_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.photo_is_addable(role, Plot), } 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