use of org.xwiki.query.SecureQuery in project xwiki-platform by xwiki.
the class XWQLQueryExecutor method execute.
@Override
public <T> List<T> execute(Query query) throws QueryException {
EntityReference currentEntityReference = this.context.getCurrentEntityReference();
Query nativeQuery;
try {
this.progress.startStep(query, "query.xwql.progress.execute", "Execute XWQL query [{}]", query);
if (query.getWiki() != null) {
if (currentEntityReference.getType() == EntityType.WIKI) {
this.context.setCurrentEntityReference(new WikiReference(query.getWiki()));
} else {
this.context.setCurrentEntityReference(currentEntityReference.replaceParent(currentEntityReference.extractReference(EntityType.WIKI), new WikiReference(query.getWiki())));
}
}
nativeQuery = getQueryManager().createQuery(this.translator.translate(query.getStatement()), this.translator.getOutputLanguage());
nativeQuery.setLimit(query.getLimit());
nativeQuery.setOffset(query.getOffset());
nativeQuery.setWiki(query.getWiki());
if (query.getFilters() != null) {
for (QueryFilter filter : query.getFilters()) {
nativeQuery.addFilter(filter);
}
}
for (Entry<String, Object> e : query.getNamedParameters().entrySet()) {
nativeQuery.bindValue(e.getKey(), e.getValue());
}
for (Entry<Integer, Object> e : query.getPositionalParameters().entrySet()) {
nativeQuery.bindValue(e.getKey(), e.getValue());
}
if (nativeQuery instanceof SecureQuery && query instanceof SecureQuery) {
// No need to validate the HQL query for short XWQL queries
if (((SecureQuery) query).isCurrentAuthorChecked() && !isShortFormStatement(query.getStatement())) {
((SecureQuery) nativeQuery).checkCurrentAuthor(true);
}
// Let HQL module take care of that is supported
((SecureQuery) nativeQuery).checkCurrentUser(((SecureQuery) query).isCurrentUserChecked());
}
return nativeQuery.execute();
} catch (Exception e) {
if (e instanceof QueryException) {
throw (QueryException) e;
}
throw new QueryException("Exception while translating [" + query.getStatement() + "] XWQL query to the [" + this.translator.getOutputLanguage() + "] language", query, e);
} finally {
this.context.setCurrentEntityReference(currentEntityReference);
this.progress.endStep(query);
}
}
use of org.xwiki.query.SecureQuery in project xwiki-platform by xwiki.
the class QueryManagerScriptService method createQuery.
private Query createQuery(String statement, String language, boolean checkCurrentUser) throws QueryException {
Query query = this.secureQueryManager.createQuery(statement, language);
if (query instanceof SecureQuery) {
((SecureQuery) query).checkCurrentAuthor(true);
((SecureQuery) query).checkCurrentUser(checkCurrentUser);
}
return new ScriptQuery(query, this.componentManager);
}
use of org.xwiki.query.SecureQuery in project xwiki-platform by xwiki.
the class SecureQueryExecutorManager method execute.
@Override
public <T> List<T> execute(Query query) throws QueryException {
if (query instanceof SecureQuery) {
SecureQuery secureQuery = (SecureQuery) query;
// Force checking current author rights
secureQuery.checkCurrentAuthor(true);
} else if (!this.authorization.hasAccess(Right.PROGRAM)) {
throw new QueryException("Unsecure query require programming right", query, null);
}
return this.defaultQueryExecutorManager.execute(query);
}
use of org.xwiki.query.SecureQuery in project xwiki-platform by xwiki.
the class SOLRSearchSource method search.
@Override
public List<SearchResult> search(String queryString, String defaultWikiName, String wikis, boolean hasProgrammingRights, String orderField, String order, boolean distinct, int number, int start, Boolean withPrettyNames, String className, UriInfo uriInfo) throws Exception {
List<SearchResult> result = new ArrayList<SearchResult>();
if (queryString == null) {
return result;
}
/*
* One of the two must be non-null. If default wiki name is non-null and wikis is null, then it's a local search
* in a specific wiki. If wiki name is null and wikis is non-null it's a global query on different wikis. If
* both of them are non-null then the wikis parameter takes the precedence.
*/
if (defaultWikiName == null && wikis == null) {
return result;
}
Query query = this.queryManager.createQuery(queryString, SolrQueryExecutor.SOLR);
if (query instanceof SecureQuery) {
// Show only what the current user has the right to see
((SecureQuery) query).checkCurrentUser(true);
}
List<String> fq = new ArrayList<String>();
// We want only documents
fq.add("{!tag=type}type:(\"DOCUMENT\")");
// Additional filter for non PR users
if (!hasProgrammingRights) {
fq.add("{!tag=hidden}hidden:(false)");
}
// Wikis
if (StringUtils.isNotBlank(wikis)) {
String[] strings = StringUtils.split(wikis, ',');
if (strings.length == 1) {
fq.add("{!tag=wiki}wiki:(\"" + strings[0] + "\")");
} else if (strings.length > 1) {
StringBuilder builder = new StringBuilder();
for (String str : strings) {
if (builder.length() > 0) {
builder.append(" OR ");
}
builder.append('\'');
builder.append(str);
builder.append('\'');
}
fq.add("{!tag=wiki}wiki:(" + builder + ")");
}
}
// TODO: current locale filtering ?
query.bindValue("fq", fq);
// Boost
// FIXME: take it from configuration
query.bindValue("qf", "title^10.0 name^10.0 doccontent^2.0 objcontent^0.4 filename^0.4 attcontent^0.4 doccontentraw^0.4 " + "author_display^0.08 creator_display^0.08 " + "comment^0.016 attauthor_display^0.016 space^0.016");
// Order
if (!StringUtils.isBlank(orderField)) {
if ("desc".equals(order)) {
query.bindValue("sort", orderField + " desc");
} else {
query.bindValue("sort", orderField + " asc");
}
}
// Limit
query.setLimit(number).setOffset(start);
try {
QueryResponse response = (QueryResponse) query.execute().get(0);
SolrDocumentList documents = response.getResults();
for (SolrDocument document : documents) {
SearchResult searchResult = this.objectFactory.createSearchResult();
DocumentReference documentReference = this.solrDocumentReferenceResolver.resolve(document);
searchResult.setPageFullName(this.localEntityReferenceSerializer.serialize(documentReference));
searchResult.setWiki(documentReference.getWikiReference().getName());
searchResult.setSpace(this.localEntityReferenceSerializer.serialize(documentReference.getParent()));
searchResult.setPageName(documentReference.getName());
searchResult.setVersion((String) document.get(FieldUtils.VERSION));
searchResult.setType("page");
searchResult.setId(Utils.getPageId(searchResult.getWiki(), Utils.getSpacesFromSpaceId(searchResult.getSpace()), searchResult.getPageName()));
searchResult.setScore(((Number) document.get(FieldUtils.SCORE)).floatValue());
searchResult.setAuthor((String) document.get(FieldUtils.AUTHOR));
Calendar calendar = Calendar.getInstance();
calendar.setTime((Date) document.get(FieldUtils.DATE));
searchResult.setModified(calendar);
if (withPrettyNames) {
searchResult.setAuthorName((String) document.get(FieldUtils.AUTHOR_DISPLAY));
}
Locale docLocale = LocaleUtils.toLocale((String) document.get(FieldUtils.DOCUMENT_LOCALE));
Locale locale = LocaleUtils.toLocale((String) document.get(FieldUtils.LOCALE));
searchResult.setTitle((String) document.getFirstValue(FieldUtils.getFieldName(FieldUtils.TITLE, locale)));
List<String> spaces = Utils.getSpacesHierarchy(documentReference.getLastSpaceReference());
String pageUri = null;
if (Locale.ROOT == docLocale) {
pageUri = Utils.createURI(uriInfo.getBaseUri(), PageResource.class, searchResult.getWiki(), spaces, searchResult.getPageName()).toString();
} else {
searchResult.setLanguage(docLocale.toString());
pageUri = Utils.createURI(uriInfo.getBaseUri(), PageTranslationResource.class, spaces, searchResult.getPageName(), docLocale).toString();
}
Link pageLink = new Link();
pageLink.setHref(pageUri);
pageLink.setRel(Relations.PAGE);
searchResult.getLinks().add(pageLink);
result.add(searchResult);
}
} catch (Exception e) {
throw new XWikiException(XWikiException.MODULE_XWIKI, XWikiException.ERROR_XWIKI_UNKNOWN, "Error performing solr search", e);
}
return result;
}
use of org.xwiki.query.SecureQuery in project xwiki-platform by xwiki.
the class SolrQueryExecutor method execute.
@Override
public <T> List<T> execute(Query query) throws QueryException {
this.progress.startStep(query, "query.solr.progress.execute", "Execute Solr query [{}]", query);
this.progress.pushLevelProgress(3, query);
try {
this.progress.startStep(query, "query.solr.progress.execute.prepare", "Prepare");
SolrInstance solrInstance = solrInstanceProvider.get();
SolrQuery solrQuery = createSolrQuery(query);
this.progress.startStep(query, "query.solr.progress.execute.execute", "Execute");
QueryResponse response = solrInstance.query(solrQuery);
this.progress.startStep(query, "query.solr.progress.execute.filter", "Filter");
// Check access rights need to be checked before returning the response.
// FIXME: this is not really the best way, mostly because at this point all grouping operations
// have already been performed and any change on the result will not ensure that the grouping
// information (facets, highlighting, maxScore, etc.) is still relevant.
// A better way would be using a PostFilter as described in this article:
// http://java.dzone.com/articles/custom-security-filtering-solr
// Basically, we would be asking
List<DocumentReference> usersToCheck = new ArrayList<>(2);
if (query instanceof SecureQuery) {
if (((SecureQuery) query).isCurrentUserChecked()) {
usersToCheck.add(xcontextProvider.get().getUserReference());
}
if (((SecureQuery) query).isCurrentAuthorChecked()) {
usersToCheck.add(xcontextProvider.get().getAuthorReference());
}
} else {
usersToCheck.add(xcontextProvider.get().getUserReference());
usersToCheck.add(xcontextProvider.get().getAuthorReference());
}
if (!usersToCheck.isEmpty()) {
filterResponse(response, usersToCheck);
}
return (List<T>) Arrays.asList(response);
} catch (Exception e) {
throw new QueryException("Exception while executing query", query, e);
} finally {
this.progress.popLevelProgress(query);
this.progress.endStep(query);
}
}
Aggregations