예제 #1
0
def filter_by_patron_search_factory(self, search, query_parser=None):
    """Filter search queries to only show records for the logged in patron.

    If the logged in  user has backoffice permissions do not filter by patron.

    :param self: REST view.
    :param search: Elastic search DSL search instance.
    :returns: Tuple with search instance and URL arguments.
    """
    def _default_parser(qstr=None):
        """Return default parser that uses the Q() from elasticsearch_dsl."""
        if qstr:
            return Q('query_string', query=qstr)
        return Q()

    from invenio_records_rest.facets import default_facets_factory
    from invenio_records_rest.sorter import default_sorter_factory

    query_string = request.values.get('q', '')

    if not current_user.is_authenticated:
        raise UnauthorizedSearchError(query_string)

    parser = query_parser or _default_parser
    query = parser(qstr=query_string)

    # if the logged in user in not librarian or admin, validate the query
    if has_request_context() and not backoffice_permission().allows(g.identity):
        # patron can find only his document requests
        if not query_string:
            # force query to be patron_pid:<logged in user>
            patron_pid_filter = 'patron_pid:{}'.format(g.identity.id)
            query = _default_parser(qstr=patron_pid_filter)
        else:
            # check for patron_pid query value
            match = re.match(r"patron_pid:(?P<pid>\d)", query_string)
            if match and match.group('pid') != str(g.identity.id):
                raise UnauthorizedSearchError(query_string, g.identity.id)
    try:
        search = search.query(query)
    except SyntaxError:
        raise SearchQueryError(query_string)

    search_index = search._index[0]
    search, urlkwargs = default_facets_factory(search, search_index)
    search, sortkwargs = default_sorter_factory(search, search_index)
    for key, value in sortkwargs.items():
        urlkwargs.add(key, value)

    urlkwargs.add('q', query_string)
    return search, urlkwargs
예제 #2
0
def _filter_by_patron(patron_id, search, query_string=None):
    """Filter search results by patron_pid."""
    match = re.search(r"patron_pid:\s?(?P<pid>\d+)", query_string or "")
    if match and match.group("pid") != str(patron_id):
        raise UnauthorizedSearchError(query_string, patron_id)

    search = search.filter("term", patron_pid=str(patron_id))
    return search, query_string
예제 #3
0
def test_unauthorized_search_without_patron_pid(app):
    """Test UnauthorizedSearchError without patron_pid defined."""
    query = "test query"
    msg = "Search `{query}` not allowed by `patron_pid:None`"
    with pytest.raises(UnauthorizedSearchError) as ex:
        raise UnauthorizedSearchError(query=query)
    assert ex.value.code == 401
    assert ex.value.description == msg.format(query=query)
예제 #4
0
    def filter_by_patron(query_string):
        """Filter search results by patron_pid."""
        if not current_user.is_authenticated:
            raise UnauthorizedSearchError(query_string)

        # if the logged in user is not librarian or admin, validate the query
        if has_request_context() and not backoffice_permission().allows(
                g.identity):
            # patron can find only his records
            if not query_string:
                # force query to be patron_pid:<logged in user>
                query_string = "patron_pid:{}".format(g.identity.id)
            else:
                # check for patron_pid query value
                match = re.match(r"patron_pid:(?P<pid>\d+)", query_string)
                if match and match.group("pid") != str(g.identity.id):
                    raise UnauthorizedSearchError(query_string, g.identity.id)
        return query_string
예제 #5
0
def test_unauthorized_search_with_patron_pid(app):
    """Test UnauthorizedSearchError with patron_pid defined."""
    query = "test query"
    pid = "1"
    msg = "Search '{query}' not allowed by 'patron_pid:{patron_pid}'"
    with pytest.raises(UnauthorizedSearchError) as ex:
        raise UnauthorizedSearchError(query=query, patron_pid=pid)
    assert ex.value.code == 403
    assert ex.value.description == msg.format(query=query, patron_pid=pid)