示例#1
0
def user_roles_get(context, data_dict):
    '''Get user roles parameter.

            :param user_id: id of the user you want to get roles for.
            :type user_id: string

            '''
    l.check_access('user_roles', context, data_dict)
    data, errors = df.validate(data_dict, user_roles_delete_schema(), context)

    if errors:
        raise t.ValidationError(errors)

    m = context.get('model')
    user_obj = m.User.get(data.get('user_id'))

    if user_obj is None:
        raise l.NotFound("No such user")

    user_id = user_obj.id
    user_role = UserRoles.get(user_id)
    if user_role is None:
        return user_role

    if not user_role:
        raise l.NotFound("User has no roles")

    out = table_dictize(user_role, context)

    return out
示例#2
0
def member_request(context, data_dict):
    logic.check_access('member_request_show', context, data_dict)
    mrequest_id = data_dict.get('mrequest_id', None)

    membership = model.Session.query(model.Member).get(mrequest_id)
    if not membership:
        raise logic.NotFound("Member request not found")

    # Return most current instance from memberrequest table
    member_request = model.Session.query(MemberRequest).filter(
        MemberRequest.membership_id == mrequest_id).order_by(
            desc(MemberRequest.request_date)).limit(1).first()
    if not member_request:
        raise logic.NotFound(
            "Member request associated with membership not found")

    member_dict = {}
    member_dict['id'] = mrequest_id
    member_dict['organization_name'] = membership.group.name
    member_dict['group_id'] = membership.group_id
    member_dict['role'] = member_request.role
    member_dict['state'] = member_request.status
    member_dict['request_date'] = member_request.request_date.strftime(
        "%d - %b - %Y")
    member_dict['user_id'] = membership.table_id
    return member_dict
示例#3
0
def member_request(context, data_dict):
    """
    :param context: context object
    :param data_dict: data dictionary
    :type context: dict
    :type data_dict: dict
    """
    logic.check_access('member_request_show', context, data_dict)
    mrequest_id = data_dict.get('mrequest_id', None)

    membership = model.Session.query(model.Member).get(mrequest_id)
    if not membership or membership.state != 'pending':
        raise logic.NotFound("Member request not found")

    # Return most current instance from memberrequest table
    member_request_obj = model.Session.query(MemberRequest).filter(
        MemberRequest.membership_id == mrequest_id).order_by(
            'request_date desc').limit(1).first()
    if not member_request_obj or member_request_obj.status != 'pending':
        raise logic.NotFound(
            "Member request associated with membership not found")

    member_dict = {
        'id': mrequest_id,
        'organization_name': membership.group.name,
        'group_id': membership.group_id,
        'role': member_request_obj.role,
        'state': 'pending',
        'request_date':
        member_request_obj.request_date.strftime("%d - %b - %Y"),
        'user_id': membership.table_id
    }
    return member_dict
示例#4
0
def resource_create(context, data_dict):
    model = context['model']
    user = context.get('user')

    package_id = data_dict.get('package_id')
    if not package_id and data_dict.get('id'):
        # This can happen when auth is deferred, eg from `resource_view_create`
        resource = logic_auth.get_resource_object(context, data_dict)
        package_id = resource.package_id

    if not package_id:
        raise logic.NotFound(
            _('No dataset id provided, cannot check auth.')
        )

    # check authentication against package
    pkg = model.Package.get(package_id)
    if not pkg:
        raise logic.NotFound(
            _('No package found for this resource, cannot check auth.')
        )

    pkg_dict = {'id': pkg.id}
    authorized = authz.is_authorized('package_update', context, pkg_dict).get('success')

    if not authorized:
        return {'success': False,
                'msg': _('User %s not authorized to create resources on dataset %s') %
                        (str(user), package_id)}
    else:
        return {'success': True}
示例#5
0
def taxonomy_delete(context, data_dict):
    """
    Delete the specific taxonomy, and as a result, all of the terms within
    it.

    :returns: The newly deleted taxonomy
    :rtype: A dictionary
    """
    _check_access('taxonomy_delete', context, data_dict)

    model = context['model']

    name = logic.get_or_bust(data_dict, 'id')

    taxonomy = Taxonomy.get(name)
    if not taxonomy:
        raise logic.NotFound()

    terms = model.Session.query(TaxonomyTerm)\
        .filter(TaxonomyTerm.taxonomy == taxonomy)
    map(model.Session.delete, terms.all())

    model.Session.delete(taxonomy)
    model.Session.commit()

    return taxonomy.as_dict()
示例#6
0
def resource_delete(context, data_dict):
    model = context['model']
    user = context.get('user')
    resource = get_resource_object(context, data_dict)

    # check authentication against package
    pkg = model.Package.get(resource.package_id)
    if not pkg:
        raise logic.NotFound(
            _('No package found for this resource, cannot check auth.'))

    pkg_dict = {'id': pkg.id}
    authorized = authz.is_authorized('package_delete', context,
                                     pkg_dict).get('success')

    if not authorized:
        return {
            'success':
            False,
            'msg':
            _('User %s not authorized to delete resource %s') %
            (user, resource.id)
        }
    else:
        return {'success': True}
示例#7
0
def inventory_resource_show(context, data_dict):
    model = context['model']
    user = User.by_name(context.get('user'))
    resource = get_resource_object(context, data_dict)

    # check authentication against package
    pkg = model.Package.get(resource.package_id)
    if not pkg:
        raise logic.NotFound(
            _('No package found for this resource,'
              ' cannot check auth.'))

    if user is None:
        if pkg.private:
            return {'success': False}
        else:
            return {'success': True}
    else:
        pkg_dict = {'id': pkg.id}
        authorized = authz.is_authorized('package_show', context, pkg_dict) \
            .get('success')

        if not authorized:
            return {
                'success':
                False,
                'msg':
                _('User %s not authorized to read resource %s') %
                (user, resource.id)
            }
        else:
            return {'success': True}
示例#8
0
def taxonomy_update(context, data_dict):
    """
    Updates an existing taxonomy.

    title, name and uri are required

    :returns: The newly updated taxonomy
    :rtype: A dictionary
    """
    _check_access('taxonomy_update', context, data_dict)

    model = context['model']

    id = logic.get_or_bust(data_dict, 'id')
    name = logic.get_or_bust(data_dict, 'name')
    title = logic.get_or_bust(data_dict, 'title')
    uri = logic.get_or_bust(data_dict, 'uri')

    tax = Taxonomy.get(id)
    if not tax:
        raise logic.NotFound()

    tax.name = name
    tax.title = title
    tax.uri = uri

    model.Session.add(tax)
    model.Session.commit()

    return tax.as_dict()
示例#9
0
def taxonomy_show(context, data_dict):
    """ Shows a single taxonomy.

    :param id: The name of id of the taxonomy

    :returns: A single taxonomy
    :rtype: A dictionary
    """
    _check_access('taxonomy_show', context, data_dict)

    model = context['model']
    id = data_dict.get('id')
    uri = data_dict.get('uri')
    name = data_dict.get('name')

    if not id and not uri and not name:
        raise logic.ValidationError("Neither id, name or uri were provided")

    item = Taxonomy.get(id or name)
    if not item and uri:
        item = Taxonomy.by_uri(uri)

    if not item:
        raise logic.NotFound()

    return item.as_dict(with_terms=True)
示例#10
0
def taxonomy_term_update(context, data_dict):
    """ Allows a taxonomy term to be updated.

    :returns: The newly updated term
    :rtype: A dictionary
    """
    _check_access('taxonomy_term_update', context, data_dict)
    model = context['model']

    id = logic.get_or_bust(data_dict, 'id')

    term = TaxonomyTerm.get(id)
    if not term:
        raise logic.NotFound()

    term.label = data_dict.get('label', term.label)
    term.parent_id = data_dict.get('parent_id', term.parent_id)
    term.uri = logic.get_or_bust(data_dict, 'uri')
    term.description = data_dict.get('description', '')
    term.extras = data_dict.get('extras', '')

    model.Session.add(term)
    model.Session.commit()

    return term.as_dict()
示例#11
0
 def delete(cls, filter):
     obj = Session.query(cls).filter_by(**filter).first()
     if obj:
         Session.delete(obj)
         Session.commit()
     else:
         raise logic.NotFound(_(u'Theme'))
示例#12
0
def like_delete(context, data_dict):
    '''Deletes a like from a given object for the current user.

    This action is only available for an authenticated user.

    :param ref: `str`, the ID of the object (for example news feed post ID).
    '''
    check_access('like_delete', context, data_dict)

    if 'ref' not in data_dict:
        raise ValidationError({'ref': [_('Missing value')]})

    ref = data_dict['ref']
    user = context.get('auth_user_obj')

    try:
        model.Session.begin(subtransactions=True)

        like_ref = LikesRef.get(user.id, ref)
        if not like_ref:
            raise logic.NotFound(_('Not found'))
        like_ref.delete()

        count = LikesCount.get(ref)
        if count and count.count:
            count.count -= 1
        count.save()

        model.Session.commit()
    except Exception as e:
        log.error('Failed to delete a like. Error: %s', str(e))
        log.exception(e)
        model.Session.rollback()
示例#13
0
def taxonomy_term_show_all(context, data_dict):
    """
    Shows a single taxonomy term and its children, the taxonomy id is not
    required, just a term_id.

    :returns: A single taxonomy term
    :rtype: A dictionary
    """
    _check_access('taxonomy_term_show', context, data_dict)

    label = data_dict.get('label')
    taxonomy_id = data_dict.get('taxonomy_id')

    if not label:
        raise logic.ValidationError("Either id, uri or label is required")

    if (taxonomy_id):
        term = TaxonomyTerm.get_from_taxonomy(label, taxonomy_id)
    else:
        term = TaxonomyTerm.get_all(label)

    if not term:
        raise logic.NotFound()

    return [u.as_dict() for u in term]
示例#14
0
def taxonomy_update(context, data_dict):
    """
    Updates an existing taxonomy.

    title, name and uri are required

    :returns: The newly updated taxonomy
    :rtype: A dictionary
    """
    _check_access('taxonomy_update', context, data_dict)

    model = context['model']

    id = logic.get_or_bust(data_dict, 'id')

    tax = Taxonomy.get(id)
    if not tax:
        raise logic.NotFound()

    tax.name = data_dict.get('name', tax.name)
    tax.title = data_dict.get('title', tax.title)
    tax.uri = data_dict.get('name', tax.uri)
    last_modified = data_dict.get('last_modified', tax.last_modified)

    if tax.last_modified != last_modified:
        tax.last_modified = isodate(last_modified, context)

    model.Session.add(tax)
    model.Session.commit()

    return tax.as_dict()
示例#15
0
def resource_delete(context, data_dict):
    """Auth function override of ckan.logic.auth.delete.resource_delete function
    Re-implement the resource_delete auth function so that we check the
    protected status of a function before allowing deletion.

    :param context: dict
    :param data_dict: dict
    :return: success_dict: dict
    """
    model = context['model']
    resource = get_resource_object(context, data_dict).as_dict()

    # check authentication against package
    pkg = model.Package.get(resource['package_id'])
    if not pkg:
        raise logic.NotFound(
            'No package found for this resource, cannot check auth.')

    pkg_dict = {'id': pkg.id}

    # if you can update a package then you can delete it
    can_update = tk.check_access('package_update', context, pkg_dict)
    if can_update:
        if helpers.resource_has_protected_status(resource['id']):
            return {
                'success': False,
                'msg': 'Contact a system administrator to delete this resource'
            }
    else:
        return {'success': False, 'msg': 'Resource delete is not allowed'}
    return {'success': True}
示例#16
0
def user_roles_create(context, data_dict):
    l.check_access('user_roles', context, data_dict)
    data, errors = df.validate(data_dict, user_roles_schema(), context)

    if errors:
        raise t.ValidationError(errors)

    m = context.get('model')
    user_obj = m.User.get(data.get('user_id'))

    if user_obj is None:
        raise l.NotFound("No such user")

    user_id = user_obj.id
    role = data.get('role')

    user_roles = UserRoles.get(user_id)
    if user_roles:
        user_roles.role = role
        user_roles.save()
    else:
        user_roles = UserRoles(user_id=user_id, role=role)
        user_roles.save()

    out = table_dictize(user_roles, context)

    return out
示例#17
0
def resource_update(context, data_dict):
    model = context['model']
    user = context.get('user')
    resource = logic_auth.get_resource_object(context, data_dict)

    # check authentication against package
    query = model.Session.query(model.Package)\
        .join(model.ResourceGroup)\
        .join(model.Resource)\
        .filter(model.ResourceGroup.id == resource.resource_group_id)
    pkg = query.first()
    if not pkg:
        raise logic.NotFound(
            _('No package found for this resource, cannot check auth.')
        )

    pkg_dict = {'id': pkg.id}
    authorized = new_authz.is_authorized('package_update', context, pkg_dict).get('success')

    if not authorized:
        return {'success': False,
                'msg': _('User %s not authorized to edit resource %s') %
                        (str(user), resource.id)}
    else:
        return {'success': True}
示例#18
0
def resource_show(context, data_dict):
    model = context['model']
    user = context.get('user')
    log.info('user resource show: %s', user)  
    resource = get_resource_object(context, data_dict)
        
    # check authentication against package
    query = model.Session.query(model.Package)\
        .join(model.ResourceGroup)\
        .join(model.Resource)\
        .filter(model.ResourceGroup.id == resource.resource_group_id)
    pkg = query.first()
    if not pkg:
        raise logic.NotFound(_('No package found for this resource, cannot check auth.'))
    
    user_roles = user_custom_roles(context, data_dict)
    if Roles.MOD_R_DATA in user_roles:
        return {'success': True}
    
    pkg_dict = {'id': pkg.id}
    authorized = package_show(context, pkg_dict).get('success')

    if not authorized:
        return {'success': False, 'msg': _('User %s not authorized to read resource %s') % (user, resource.id)}
    else:
        #check resource status, if private just org members may see it
        if not toolkit.get_action('is_resource_public')(context, resource.extras):
            authorized_read = package_update(context, pkg_dict).get('success')
            if not authorized_read:
                return {'success': False, 'msg': _('User %s not authorized to read resource %s') % (user, resource.id)}
        return {'success': True}
示例#19
0
def _update_harvest_source_object(context, data_dict):
    '''
        Updates an actual HarvestSource object with the data dict
        of the harvest_source dataset. All validation and authorization
        checks should be used by now, so this function is not to be used
        directly to update harvest sources.

        :param data_dict: A standard package data_dict

        :returns: The created HarvestSource object
        :rtype: HarvestSource object
    '''

    source_id = data_dict.get('id')

    log.info('Harvest source %s update: %r', source_id, data_dict)
    source = HarvestSource.get(source_id)
    if not source:
        log.error('Harvest source %s does not exist', source_id)
        raise logic.NotFound('Harvest source %s does not exist' % source_id)

    fields = [
        'url', 'title', 'description', 'user_id', 'publisher_id', 'frequency',
        'time'
    ]
    for f in fields:
        if f in data_dict and data_dict[f] is not None:
            if f == 'url':
                data_dict[f] = data_dict[f].strip()
            source.__setattr__(f, data_dict[f])

    # Avoids clashes with the dataset type
    if 'source_type' in data_dict:
        source.type = data_dict['source_type']

    if 'config' in data_dict:
        source.config = data_dict['config']

    # Don't change state unless explicitly set in the dict
    if 'state' in data_dict:
        source.active = data_dict.get('state') == 'active'

    # Don't commit yet, let package_create do it
    source.add()

    # Abort any pending jobs
    if not source.active:
        jobs = HarvestJob.filter(source=source, status=u'New')
        log.info(
            'Harvest source %s not active, so aborting %i outstanding jobs',
            source_id, jobs.count())
        if jobs:
            for job in jobs:
                job.status = u'Aborted'
                job.add()

    return source
示例#20
0
def saml2_user_delete(context, data_dict):
    if not data_dict.get('id') and data_dict.get('nameid'):
        saml2_user_id = saml2_get_userid_by_name_id(data_dict['nameid'])
        if saml2_user_id is not None:
            data_dict['id'] = saml2_user_id
        else:
            raise logic.NotFound(
                'NameID "{id}" was not found.'.format(id=data_dict['nameid']))
    ckan_user_delete(context, data_dict)
示例#21
0
def resource_view_delete(context: Context, data_dict: DataDict) -> AuthResult:
    model = context['model']

    resource_view = model.ResourceView.get(data_dict['id'])
    if not resource_view:
        raise logic.NotFound(_('Resource view not found, cannot check auth.'))
    resource_id = resource_view.resource_id

    return authz.is_authorized('resource_delete', context, {'id': resource_id})
示例#22
0
def _request_token(user_id):
    if toolkit.c.user:
        # Don't offer the reset form if already logged in
        log.warning("User already logged in {}".format(toolkit.c.user))
        raise toolkit.NotAuthorized('user already logged in, logout first')

    context = {'user': toolkit.c.user}

    data_dict = {'id': user_id}
    user_obj = None
    try:
        user_dict = toolkit.get_action('user_show')(context, data_dict)
        user_obj = context['user_obj']
    except logic.NotFound:
        # Try searching the user
        del data_dict['id']
        data_dict['q'] = user_id

        if user_id and len(user_id) > 2:
            user_list = toolkit.get_action('user_list')(context, data_dict)
            if len(user_list) == 1:
                # This is ugly, but we need the user object for the mailer,
                # and user_list does not return them
                del data_dict['q']
                data_dict['id'] = user_list[0]['id']
                user_dict = toolkit.get_action('user_show')(context, data_dict)
                user_obj = context['user_obj']
            elif len(user_list) > 1:
                raise logic.NotFound('"%s" matched several users' % user_id)
            else:
                raise logic.NotFound('No such user: %s' % user_id)
        else:
            raise logic.NotFound('No such user: %s' % user_id)

    if user_obj:
        try:
            passwordless_send_reset_link(user_obj)

        except mailer.MailerException as e:
            log.error('Could not send token link: %s' % str(e))
            raise mailer.MailerException(
                'could not send token link by mail: %s' % str(e))

    return
示例#23
0
def resource_view_show(context, data_dict):

    model = context['model']

    resource_view = model.ResourceView.get(data_dict['id'])
    if not resource_view:
        raise logic.NotFound(_('Resource view not found, cannot check auth.'))
    resource = model.Resource.get(resource_view.resource_id)

    return authz.is_authorized('resource_show', context, {'id': resource.id})
示例#24
0
def purge_revision_history(context, data_dict):
    '''
    Purge a given publisher's unused revision history.

    :param group: the name or id of the publisher
    :type group: string

    :returns: number of resources and revisions purged.
    :rtype: dictionary
    '''
    logic.check_access('purge_revision_history', context, data_dict)

    model = context['model']
    engine = model.meta.engine
    group_id = logic.get_or_bust(data_dict, 'group')
    group = model.Group.get(group_id)

    if not group:
        raise logic.NotFound('Publisher {0} not found'.format(group_id))

    RESOURCE_IDS_SQL = '''
        SELECT resource.id FROM resource
        JOIN resource_group ON resource.resource_group_id = resource_group.id
        JOIN member ON member.table_id = resource_group.package_id
        JOIN "group" ON "group".id = member.group_id
        WHERE "group".name      = %s
          AND "group".type      = 'organization'
          AND member.table_name = 'package'
          AND resource.state    = 'deleted'
    '''

    DELETE_REVISIONS_SQL = '''
        DELETE FROM resource_revision
            WHERE id IN ({sql})
    '''.format(sql=RESOURCE_IDS_SQL)

    # Not necessary to use a sub-select, but it allows re-use of sql statement
    # and this isn't performance critical code.
    DELETE_RESOURCES_SQL = '''
        DELETE FROM resource WHERE id IN ({sql})
    '''.format(sql=RESOURCE_IDS_SQL)

    try:
        number_revisions_deleted = engine.execute(
            DELETE_REVISIONS_SQL,
            group.name
        ).rowcount

        number_resources_deleted = engine.execute(
            DELETE_RESOURCES_SQL,
            group.name
        ).rowcount

    except Exception, e:
        raise logic.ActionError('Error executing sql: %s' % e)
示例#25
0
文件: create.py 项目: zhubx007/ckan
def _check_group_auth(context, data_dict):
    '''Has this user got update permission for all of the given groups?
    If there is a package in the context then ignore that package's groups.
    (owner_org is checked elsewhere.)
    :returns: False if not allowed to update one (or more) of the given groups.
              True otherwise. i.e. True is the default. A blank data_dict
              mentions no groups, so it returns True.

    '''
    # FIXME This code is shared amoung other logic.auth files and should be
    # somewhere better
    if not data_dict:
        return True

    model = context['model']
    user = context['user']
    pkg = context.get("package")

    api_version = context.get('api_version') or '1'

    group_blobs = data_dict.get('groups', [])
    groups = set()
    for group_blob in group_blobs:
        # group_blob might be a dict or a group_ref
        if isinstance(group_blob, dict):
            if api_version == '1':
                id = group_blob.get('name')
            else:
                id = group_blob.get('id')
            if not id:
                continue
        else:
            id = group_blob
        grp = model.Group.get(id)
        if grp is None:
            raise logic.NotFound(_('Group was not found.'))
        groups.add(grp)

    if pkg:
        pkg_groups = pkg.get_groups()

        groups = groups - set(pkg_groups)

    for group in groups:
        if not authz.has_user_permission_for_group_or_org(
                group.id, user, 'update'):
            return False

    return True
示例#26
0
文件: delete.py 项目: Pilchards/ckan
def resource_view_delete(context, data_dict):

    if context.get('resource'):
        return authz.is_authorized('resource_delete', context, {})
    if context.get('resource_view'):
        return authz.is_authorized('resource_delete', context, {'id': context['resource_view'].resource_id})

    resource_id = data_dict.get('resource_id')
    if not resource_id:
        resource_view = context['model'].ResourceView.get(data_dict['id'])
        if not resource_view:
            raise logic.NotFound(_('Resource view not found, cannot check auth.'))
        resource_id = resource_view.resource_id

    return authz.is_authorized('resource_delete', context, {'id': resource_id})
示例#27
0
def all_tags(vocab_id_or_name=None):
    if vocab_id_or_name:
        vocab = vocabulary.Vocabulary.get(vocab_id_or_name)
        if vocab is None:
            # The user specified an invalid vocab.
            raise logic.NotFound("could not find vocabulary '%s'" %
                                 vocab_id_or_name)
        query = meta.Session.query(Tag).join(CeonTagExtra).filter(
            Tag.vocabulary_id == vocab.id).order_by(CeonTagExtra.position)
    else:
        query = meta.Session.query(Tag).join(CeonTagExtra).filter(
            Tag.vocabulary_id == None)
        query = query.distinct().join(PackageTag)
        query = query.filter_by(state='active')
        query = query.order_by(CeonTagExtra.position)
    return query
示例#28
0
def resource_show_ext(context, data_dict):
    model = context['model']
    user = context.get('user')
    userobj = context.get('auth_user_obj')
    resource = get_resource_object(context, data_dict)

    # check authentication against package
    pkg = model.Package.get(resource.package_id)
    if not pkg:
        raise logic.NotFound(
            _('No package found for this resource, cannot check auth.'))

    pkg_dict = {'id': pkg.id}
    authorized = authz.is_authorized('package_show', context,
                                     pkg_dict).get('success')

    if not authorized:
        return {
            'success':
            False,
            'msg':
            _('User %s not authorized to read resource %s') %
            (user, resource.id)
        }

    if 'res_access' in data_dict:
        res_access = data_dict['res_access']
    else:
        res_access = True

    if userobj == None:
        mydataset = False
    else:
        mydataset = (userobj.id == pkg.creator_user_id)

    if not (mydataset or res_access):
        return {
            'success':
            False,
            'msg':
            _('User %s not authorized to read resource (access not public) %s')
            % (user, resource.id)
        }

    return {'success': True}
示例#29
0
def resource_view_delete(context, data_dict):

    if context.get('resource'):
        return resource_delete(context, {})
    if context.get('resource_view'):
        return resource_delete(context, {'id': context['resource_view'].resource_id})

    resource_id = data_dict.get('resource_id')
    if not resource_id:
        resource_view = context['model'].ResourceView.get(data_dict['id'])
        if not resource_view:
            raise logic.NotFound(_('Resource view not found, cannot check auth.'))
        resource_id = resource_view.resource_id

    if authz.config.get('ckan.gov_theme.is_back'):
        return resource_delete(context, {'id': resource_id})
    else:
        return {'success': False}
示例#30
0
def unfollow_search(context, data_dict):
    '''Stop following a search.

    You must provide your API key in the Authorization header.

    :param id: the id of the saved search
    :type id: string

    '''

    if 'user' not in context:
        raise logic.NotAuthorized(
            _("You must be logged in to follow a search."))

    if not paste.deploy.converters.asbool(
            config.get('ckan.follow_searches_enabled', 'false')):
        raise logic.NotFound(_("Following searches not supported"))

    model = context['model']
    session = context['session']

    userobj = model.User.get(context['user'])
    if not userobj:
        raise logic.NotAuthorized(
            _("You must be logged in to unfollow a search."))

    follower = userobj.id

    if not data_dict.get('id'):
        errors = {"id": [_("Not provided and search_string not found")]}
        raise ValidationError(errors)

    id = data_dict['id']

    obj = session.query(model.SavedSearch).get(id)

    if obj.user_id != follower:
        raise NotFound(_('You are not following this search'))

    obj.delete()

    model.repo.commit()