Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 7 additions & 17 deletions annotator/annotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,18 @@ def save(self, *args, **kwargs):
super(Annotation, self).save(*args, **kwargs)

@classmethod
def search_raw(cls, query=None, params=None, user=None,
authorization_enabled=None, **kwargs):
def search_raw(cls, query=None, user=None, authorization_enabled=None,
**kwargs):
"""Perform a raw Elasticsearch query

Any ElasticsearchExceptions are to be caught by the caller.

Keyword arguments:
query -- Query to send to Elasticsearch
params -- Extra keyword arguments to pass to Elasticsearch.search
user -- The user to filter the results for according to permissions
authorization_enabled -- Overrides Annotation.es.authorization_enabled
raw_result -- Return Elasticsearch's response as is
Extra keyword arguments are passed to Elasticsearch.search
"""
if query is None:
query = {}
Expand All @@ -85,7 +85,7 @@ def search_raw(cls, query=None, params=None, user=None,
if authorization_enabled:
f = authz.permissions_filter(user)
if not f:
raise RunTimeError("Authorization filter creation failed")
raise RuntimeError("Authorization filter creation failed")
filtered_query = {
'filtered': {
'filter': f
Expand All @@ -97,18 +97,15 @@ def search_raw(cls, query=None, params=None, user=None,
# Use the filtered query instead of the original
query['query'] = filtered_query

res = super(Annotation, cls).search_raw(query=query,
params=params,
**kwargs)
res = super(Annotation, cls).search_raw(query=query, **kwargs)
return res

@classmethod
def _build_query(cls, query=None, offset=None, limit=None,
user=None, **kwargs):
def _build_query(cls, query=None, offset=None, limit=None):
if query is None:
query = {}

q = super(Annotation, cls)._build_query(query, offset, limit, **kwargs)
q = super(Annotation, cls)._build_query(query, offset, limit)

# attempt to expand query to include uris for other representations
# using information we may have on hand about the Document
Expand All @@ -128,13 +125,6 @@ def _build_query(cls, query=None, offset=None, limit=None,
'minimum_should_match': 1
}

if es.authorization_enabled:
# Apply a filter to the results.
f = authz.permissions_filter(user)
if not f:
return False # Refuse to perform the query
q['query'] = {'filtered': {'query': q['query'], 'filter': f}}

return q


Expand Down
40 changes: 10 additions & 30 deletions annotator/elasticsearch.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def fetch(cls, id):
return cls(doc['_source'], id=id)

@classmethod
def _build_query(cls, query=None, offset=None, limit=None, **kwargs):
def _build_query(cls, query=None, offset=None, limit=None):
if offset is None:
offset = 0
if limit is None:
Expand All @@ -143,61 +143,41 @@ def _build_query(cls, query=None, offset=None, limit=None, **kwargs):
query = {}
return _build_query(query, offset, limit)

@classmethod
def _build_query_raw(cls, request, **kwargs):
return _build_query_raw(request)

@classmethod
def search(cls, query=None, offset=0, limit=RESULTS_DEFAULT_SIZE, **kwargs):
q = cls._build_query(query=query, offset=offset, limit=limit, **kwargs)
q = cls._build_query(query=query, offset=offset, limit=limit)
if not q:
return []
log.debug("doing search: %s", q)
res = cls.es.conn.search(index=cls.es.index,
doc_type=cls.__type__,
body=q)
docs = res['hits']['hits']
return [cls(d['_source'], id=d['_id']) for d in docs]
return cls.search_raw(q, **kwargs)

@classmethod
def search_raw(cls, query=None, params=None, raw_result=False, **kwargs):
def search_raw(cls, query=None, raw_result=False, **kwargs):
"""Perform a raw Elasticsearch query

Any ElasticsearchExceptions are to be caught by the caller.

Keyword arguments:
query -- Query to send to Elasticsearch
params -- Extra keyword arguments to pass to Elasticsearch.search
raw_result -- Return Elasticsearch's response as is
Extra keyword arguments are passed to Elasticsearch.search
"""
if query is None:
query = {}
if params is None:
params = {}
res = cls.es.conn.search(index=cls.es.index,
doc_type=cls.__type__,
body=query,
**params)
**kwargs)
if not raw_result:
docs = res['hits']['hits']
res = [cls(d['_source'], id=d['_id']) for d in docs]
return res

@classmethod
def count(cls, **kwargs):
q = cls._build_query(**kwargs)
if not q:
return 0

# Extract the query, and wrap it in the expected object. This has the
# effect of removing sort or paging parameters that aren't allowed by
# the count API.
q = {'query': q['query']}

res = cls.es.conn.count(index=cls.es.index,
doc_type=cls.__type__,
body=q)
return res['count']
"""Like search, but only count the number of matches."""
kwargs['search_type'] = 'count'
res = cls.search(raw_result=True, **kwargs)
return res['hits']['total']

def save(self, refresh=True):
_add_created(self)
Expand Down
6 changes: 2 additions & 4 deletions annotator/store.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,18 +292,16 @@ def search_annotations():
def search_annotations_raw():

try:
query, params = _build_query_raw(request)
query, kwargs = _build_query_raw(request)
except ValueError:
return jsonify('Could not parse request payload!',
status=400)

kwargs = dict()
if current_app.config.get('AUTHZ_ON'):
kwargs['user'] = g.user

try:
res = g.annotation_class.search_raw(query, params, raw_result=True,
**kwargs)
res = g.annotation_class.search_raw(query, raw_result=True, **kwargs)
except TransportError as err:
if err.status_code is not 'N/A':
status_code = err.status_code
Expand Down
4 changes: 2 additions & 2 deletions tests/test_annotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,8 @@ def test_search_permissions_malicious(self):

# Any user whose username starts with "group:" must be refused any results
user = h.MockUser('group:anyone', 'testconsumer')
res = Annotation.search(user=user)
assert_equal(len(res), 0)
search_action = lambda: Annotation.search(user=user)
assert_raises(RuntimeError, search_action)

def test_search_permissions_admin(self):
anno = Annotation(text='Foobar',
Expand Down
2 changes: 1 addition & 1 deletion tests/test_document.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def test_search(self):
],
})
d.save()
res = Document.search(title='document')
res = Document.search(query={'title': 'document'})
assert_equal(len(res), 1)

def test_get_by_uri(self):
Expand Down