def ignore_not_package_admin(key: FlattenKey, data: FlattenDataDict, errors: FlattenErrorDict, context: Context) -> Any: '''Ignore if the user is not allowed to administer the package specified.''' user = context.get('user') if 'ignore_auth' in context: return if user and authz.is_sysadmin(user): return authorized = False pkg = context.get('package') if pkg: try: logic.check_access('package_change_state', context) authorized = True except logic.NotAuthorized: authorized = False if (user and pkg and authorized): return # allow_state_change in the context will allow the state to be changed # FIXME is this the best way to cjeck for state only? if key == ('state', ) and context.get('allow_state_change'): return data.pop(key)
def ignore_empty(key: FlattenKey, data: FlattenDataDict, errors: FlattenErrorDict, context: Context) -> None: value = data.get(key) if value is missing or not value: data.pop(key, None) raise StopOnError
def owner_org_validator(key: FlattenKey, data: FlattenDataDict, errors: FlattenErrorDict, context: Context) -> Any: value = data.get(key) if value is missing or value is None: if not authz.check_config_permission('create_unowned_dataset'): raise Invalid(_('An organization must be provided')) data.pop(key, None) raise df.StopOnError model = context['model'] user = model.User.get(context['user']) package = context.get('package') if value == '': if not authz.check_config_permission('create_unowned_dataset'): raise Invalid(_('An organization must be provided')) return if (authz.check_config_permission('allow_dataset_collaborators') and not authz.check_config_permission( 'allow_collaborators_to_change_owner_org')): if package and user and not user.sysadmin: is_collaborator = authz.user_is_collaborator_on_dataset( user.id, package.id, ['admin', 'editor']) if is_collaborator: # User is a collaborator, check if it's also a member with # edit rights of the current organization (redundant, but possible) user_orgs = logic.get_action('organization_list_for_user')( { 'ignore_auth': True }, { 'id': user.id, 'permission': 'update_dataset' }) user_is_org_member = package.owner_org in [ org['id'] for org in user_orgs ] if data.get( key) != package.owner_org and not user_is_org_member: raise Invalid( _('You cannot move this dataset to another organization' )) group = model.Group.get(value) if not group: raise Invalid(_('Organization does not exist')) group_id = group.id if not package or (package and package.owner_org != group_id): # This is a new dataset or we are changing the organization if not context.get(u'ignore_auth', False) and (not user or not ( user.sysadmin or authz.has_user_permission_for_group_or_org( group_id, user.name, 'create_dataset'))): raise Invalid(_('You cannot add a dataset to this organization')) data[key] = group_id
def ignore_not_sysadmin(key: FlattenKey, data: FlattenDataDict, errors: FlattenErrorDict, context: Context) -> Any: '''Ignore the field if user not sysadmin or ignore_auth in context.''' user = context.get('user') ignore_auth = context.get('ignore_auth') if ignore_auth or (user and authz.is_sysadmin(user)): return data.pop(key)
def rename_field(key: FlattenKey, data: FlattenDataDict, errors: FlattenErrorDict, context: Context): index = max([int(k[1]) for k in data.keys() if len(k) == 3 and k[0] == new] + [-1]) for field_name in list(data.keys()): if field_name[0] == old and data.get(field_name): new_field_name = list(field_name) new_field_name[0] = new if len(new_field_name) > 1: new_field_name[1] = int(new_field_name[1]) + index + 1 data[tuple(new_field_name)] = data[field_name] data.pop(field_name)
def ignore(key: FlattenKey, data: FlattenDataDict, errors: FlattenErrorDict, context: Context) -> NoReturn: """Remove the value from the input and skip the rest of validators. .. code-block:: data, errors = tk.navl_validate( {"hello": 1}, {"hello": [ignore]} ) assert data == {} """ data.pop(key, None) raise StopOnError
def ignore_empty(key: FlattenKey, data: FlattenDataDict, errors: FlattenErrorDict, context: Context) -> None: """Skip the rest of validators if the value is empty or missing. .. code-block:: data, errors = tk.navl_validate( {"hello": ""}, {"hello": [ignore_empty, isodate]} ) assert data == {} assert not errors """ value = data.get(key) if value is missing or not value: data.pop(key, None) raise StopOnError
def ignore_missing(key: FlattenKey, data: FlattenDataDict, errors: FlattenErrorDict, context: Context) -> None: '''If the key is missing from the data, ignore the rest of the key's schema. By putting ignore_missing at the start of the schema list for a key, you can allow users to post a dict without the key and the dict will pass validation. But if they post a dict that does contain the key, then any validators after ignore_missing in the key's schema list will be applied. :raises ckan.lib.navl.dictization_functions.StopOnError: if ``data[key]`` is :py:data:`ckan.lib.navl.dictization_functions.missing` or ``None`` :returns: ``None`` ''' value = data.get(key) if value is missing or value is None: data.pop(key, None) raise StopOnError
def ignore_not_group_admin(key: FlattenKey, data: FlattenDataDict, errors: FlattenErrorDict, context: Context) -> Any: '''Ignore if the user is not allowed to administer for the group specified.''' user = context.get('user') if user and authz.is_sysadmin(user): return authorized = False group = context.get('group') if group: try: logic.check_access('group_change_state', context) authorized = True except logic.NotAuthorized: authorized = False if (user and group and authorized): return data.pop(key)
def empty(key: FlattenKey, data: FlattenDataDict, errors: FlattenErrorDict, context: Context) -> None: value = data.pop(key, None) if value and value is not missing: key_name = key[-1] if key_name == '__junk': # for junked fields, the field name is contained in the value key_name = list(value.keys()) errors[key].append( _('The input field %(name)s was not expected.') % {"name": key_name})
def keep_extras(key: FlattenKey, data: FlattenDataDict, errors: FlattenErrorDict, context: Context) -> None: """Convert dictionary into simple fields. .. code-block:: data, errors = tk.navl_validate( {"input": {"hello": 1, "world": 2}}, {"input": [keep_extras]} ) assert data == {"hello": 1, "world": 2} """ extras = data.pop(key, {}) for extras_key, value in extras.items(): data[key[:-1] + (extras_key,)] = value
def empty(key: FlattenKey, data: FlattenDataDict, errors: FlattenErrorDict, context: Context) -> None: """Ensure that value is not present in the input. .. code-block:: data, errors = tk.navl_validate( {"hello": 1}, {"hello": [empty]} ) assert errors == {"hello": [error_message]} """ value = data.pop(key, None) if value and value is not missing: key_name = key[-1] if key_name == '__junk': # for junked fields, the field name is contained in the value key_name = list(value.keys()) errors[key].append(_( 'The input field %(name)s was not expected.') % {"name": key_name})
def prefix_validator(key: FlattenKey, data: FlattenDataDict, errors: FlattenErrorDict, context: Context): out = {} extras = data.get(('__extras', ), {}) # values passed as lists of dicts will have been flattened into __junk junk = df.unflatten(data.get(('__junk', ), {})) for field_name in junk: if not field_name.startswith(prefix): continue extras[field_name] = junk[field_name] for field_name in list(extras): if not field_name.startswith(prefix): continue data[(field_name, )] = extras.pop(field_name) for v in validator_fns: try: df.convert(v, (field_name, ), data, errors, context) except df.StopOnError: break out[field_name[len(prefix):]] = data.pop((field_name, )) data[(prefix, )] = out
def ignore(key: FlattenKey, data: FlattenDataDict, errors: FlattenErrorDict, context: Context) -> NoReturn: data.pop(key, None) raise StopOnError
def keep_extras(key: FlattenKey, data: FlattenDataDict, errors: FlattenErrorDict, context: Context) -> None: extras = data.pop(key, {}) for extras_key, value in extras.items(): data[key[:-1] + (extras_key, )] = value