Commit eb895a62 by Madhan Neethiraj

ATLAS-2765: updated authorization model to scrub search-results (clear…

ATLAS-2765: updated authorization model to scrub search-results (clear entity-attributes, classifications) for entities the user doesn't have read access to
parent 80f556a7
......@@ -62,6 +62,23 @@ public class AtlasAuthorizationUtils {
}
}
public static void scrubSearchResults(AtlasSearchResultScrubRequest request) throws AtlasBaseException {
String userName = getCurrentUserName();
if (StringUtils.isNotEmpty(userName)) {
try {
AtlasAuthorizer authorizer = AtlasAuthorizerFactory.getAtlasAuthorizer();
request.setUser(userName, getCurrentUserGroups());
request.setClientIPAddress(RequestContext.get().getClientIPAddress());
authorizer.scrubSearchResults(request);
} catch (AtlasAuthorizationException e) {
LOG.error("Unable to obtain AtlasAuthorizer", e);
}
}
}
public static boolean isAccessAllowed(AtlasAdminAccessRequest request) {
boolean ret = false;
String userName = getCurrentUserName();
......
......@@ -19,6 +19,8 @@
package org.apache.atlas.authorize;
import org.apache.atlas.model.instance.AtlasEntityHeader;
public interface AtlasAuthorizer {
/**
* initialization of authorizer implementation
......@@ -55,4 +57,40 @@ public interface AtlasAuthorizer {
* @throws AtlasAuthorizationException
*/
boolean isAccessAllowed(AtlasTypeAccessRequest request) throws AtlasAuthorizationException;
/**
* scrub search-results to handle entities for which the user doesn't have access
* @param request
* @return
* @throws AtlasAuthorizationException
*/
default
void scrubSearchResults(AtlasSearchResultScrubRequest request) throws AtlasAuthorizationException {
}
default
void scrubEntityHeader(AtlasEntityHeader entity) {
entity.setGuid("-1");
if(entity.getAttributes() != null) {
entity.getAttributes().clear();
}
if(entity.getClassifications() != null) {
entity.getClassifications().clear();
}
if(entity.getClassificationNames() != null) {
entity.getClassificationNames().clear();
}
if(entity.getMeanings() != null) {
entity.getMeanings().clear();
}
if(entity.getMeaningNames() != null) {
entity.getMeaningNames().clear();
}
}
}
......@@ -44,4 +44,8 @@ public class AtlasNoneAuthorizer implements AtlasAuthorizer {
public boolean isAccessAllowed(AtlasTypeAccessRequest request) throws AtlasAuthorizationException {
return true;
}
public void scrubSearchResults(AtlasSearchResultScrubRequest request) throws AtlasAuthorizationException {
}
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.atlas.authorize;
import org.apache.atlas.model.discovery.AtlasSearchResult;
import org.apache.atlas.type.AtlasTypeRegistry;
import java.util.Set;
public class AtlasSearchResultScrubRequest extends AtlasAccessRequest {
private final AtlasTypeRegistry typeRegistry;
private final AtlasSearchResult searchResult;
public AtlasSearchResultScrubRequest(AtlasTypeRegistry typeRegistry, AtlasSearchResult searchResult) {
this(typeRegistry, searchResult, null, null);
}
public AtlasSearchResultScrubRequest(AtlasTypeRegistry typeRegistry, AtlasSearchResult searchResult, String userName, Set<String> userGroups) {
super(AtlasPrivilege.ENTITY_READ, userName, userGroups);
this.typeRegistry = typeRegistry;
this.searchResult = searchResult;
}
public AtlasTypeRegistry getTypeRegistry() { return typeRegistry; }
public AtlasSearchResult getSearchResult() {
return searchResult;
}
@Override
public String toString() {
return "AtlasSearchResultScrubRequest[searchResult=" + searchResult + ", action=" + getAction() + ", accessTime=" + getAccessTime() + ", user=" + getUser() +
", userGroups=" + getUserGroups() + ", clientIPAddress=" + getClientIPAddress() + "]";
}
}
......@@ -31,10 +31,16 @@ import org.apache.atlas.authorize.AtlasAdminAccessRequest;
import org.apache.atlas.authorize.AtlasAuthorizer;
import org.apache.atlas.authorize.AtlasAuthorizationException;
import org.apache.atlas.authorize.AtlasEntityAccessRequest;
import org.apache.atlas.authorize.AtlasPrivilege;
import org.apache.atlas.authorize.AtlasSearchResultScrubRequest;
import org.apache.atlas.authorize.AtlasTypeAccessRequest;
import org.apache.atlas.authorize.simple.AtlasSimpleAuthzPolicy.*;
import org.apache.atlas.model.discovery.AtlasSearchResult;
import org.apache.atlas.model.discovery.AtlasSearchResult.AtlasFullTextResult;
import org.apache.atlas.model.instance.AtlasEntityHeader;
import org.apache.atlas.utils.AtlasJson;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -219,6 +225,38 @@ public final class AtlasSimpleAuthorizer implements AtlasAuthorizer {
return ret;
}
@Override
public void scrubSearchResults(AtlasSearchResultScrubRequest request) throws AtlasAuthorizationException {
if (LOG.isDebugEnabled()) {
LOG.debug("==> SimpleAtlasAuthorizer.scrubSearchResults({})", request);
}
final AtlasSearchResult result = request.getSearchResult();
if (CollectionUtils.isNotEmpty(result.getEntities())) {
for (AtlasEntityHeader entity : result.getEntities()) {
checkAccessAndScrub(entity, request);
}
}
if (CollectionUtils.isNotEmpty(result.getFullTextResult())) {
for (AtlasFullTextResult fullTextResult : result.getFullTextResult()) {
if (fullTextResult != null) {
checkAccessAndScrub(fullTextResult.getEntity(), request);
}
}
}
if (MapUtils.isNotEmpty(result.getReferredEntities())) {
for (AtlasEntityHeader entity : result.getReferredEntities().values()) {
checkAccessAndScrub(entity, request);
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== SimpleAtlasAuthorizer.scrubSearchResults({}): {}", request, result);
}
}
private Set<String> getRoles(String userName, Set<String> userGroups) {
Set<String> ret = new HashSet<>();
......@@ -341,6 +379,18 @@ public final class AtlasSimpleAuthorizer implements AtlasAuthorizer {
return ret;
}
private void checkAccessAndScrub(AtlasEntityHeader entity, AtlasSearchResultScrubRequest request) throws AtlasAuthorizationException {
if (entity != null && request != null) {
final AtlasEntityAccessRequest entityAccessRequest = new AtlasEntityAccessRequest(request.getTypeRegistry(), AtlasPrivilege.ENTITY_READ, entity, request.getUser(), request.getUserGroups());
entityAccessRequest.setClientIPAddress(request.getClientIPAddress());
if (!isAccessAllowed(entityAccessRequest)) {
scrubEntityHeader(entity);
}
}
}
}
......@@ -23,6 +23,8 @@ import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.AtlasException;
import org.apache.atlas.SortOrder;
import org.apache.atlas.annotation.GraphTransaction;
import org.apache.atlas.authorize.AtlasAuthorizationUtils;
import org.apache.atlas.authorize.AtlasSearchResultScrubRequest;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.discovery.AtlasSearchResult;
import org.apache.atlas.model.discovery.AtlasSearchResult.AtlasFullTextResult;
......@@ -167,6 +169,8 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
}
}
scrubSearchResults(ret);
return ret;
}
......@@ -183,6 +187,8 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
}
ret.setFullTextResult(getIndexQueryResults(idxQuery, params, excludeDeletedEntities));
scrubSearchResults(ret);
return ret;
}
......@@ -408,6 +414,8 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
}
}
scrubSearchResults(ret);
return ret;
}
......@@ -504,6 +512,8 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
searchTracker.remove(searchID);
}
scrubSearchResults(ret);
return ret;
}
......@@ -612,6 +622,8 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
graph.releaseGremlinScriptEngine(scriptEngine);
}
scrubSearchResults(ret);
return ret;
}
......@@ -929,4 +941,8 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "invalid data");
}
}
private void scrubSearchResults(AtlasSearchResult result) throws AtlasBaseException {
AtlasAuthorizationUtils.scrubSearchResults(new AtlasSearchResultScrubRequest(typeRegistry, result));
}
}
......@@ -1026,13 +1026,17 @@ public class GlossaryService {
Map<String, AtlasGlossaryTerm> termMap = new HashMap<>();
dataAccess.load(terms).iterator().forEachRemaining(t -> termMap.put(t.getGuid(), t));
termHeaders.forEach(t -> t.setDisplayText(termMap.get(t.getTermGuid()).getName()));
termHeaders.forEach(t -> t.setDisplayText(getDisplayText(termMap.get(t.getTermGuid()))));
}
private boolean isNameInvalid(String name) {
return StringUtils.containsAny(name, invalidNameChars);
}
private String getDisplayText(AtlasGlossaryTerm term) {
return term != null ? term.getName() : null;
}
static class PaginationHelper<T> {
private int pageStart;
private int pageEnd;
......
......@@ -525,7 +525,7 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore {
AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(guid);
AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ_CLASSIFICATION, entityHeader), "get classifications: guid=", guid);
AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ, entityHeader), "get classifications: guid=", guid);
return entityHeader.getClassifications();
}
......@@ -541,7 +541,7 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore {
AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(guid);
if (CollectionUtils.isNotEmpty(entityHeader.getClassifications())) {
AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ_CLASSIFICATION, entityHeader), "get classification: guid=", guid, ", classification=", classificationName);
AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ, entityHeader), "get classification: guid=", guid, ", classification=", classificationName);
for (AtlasClassification classification : entityHeader.getClassifications()) {
if (!StringUtils.equalsIgnoreCase(classification.getTypeName(), classificationName)) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment