ATLAS-2459: Authorization enhancements to support instance level access controls
Signed-off-by: Madhan Neethiraj <madhan@apache.org>
This commit is contained in:
parent
be9b39bf53
commit
afbc6975b3
|
|
@ -115,10 +115,13 @@ atlas.server.ha.enabled=false
|
|||
#atlas.server.ids=id1
|
||||
#atlas.server.address.id1=localhost:21000
|
||||
|
||||
#########POLICY FILE PATH #########
|
||||
# atlas.auth.policy.file=policy-store.txt
|
||||
######### Atlas Authorization #########
|
||||
atlas.authorizer.impl=none
|
||||
# atlas.authorizer.impl=simple
|
||||
# atlas.authorizer.simple.authz.policy.file=atlas-simple-authz-policy.json
|
||||
|
||||
######### Atlas Authentication #########
|
||||
atlas.authentication.method.file=true
|
||||
atlas.authentication.method.ldap.type=none
|
||||
atlas.authentication.method.kerberos=false
|
||||
# atlas.authentication.method.file.filename=users-credentials.properties
|
||||
atlas.authentication.method.kerberos=false
|
||||
|
|
@ -115,10 +115,13 @@ atlas.server.ha.enabled=false
|
|||
#atlas.server.ids=id1
|
||||
#atlas.server.address.id1=localhost:21000
|
||||
|
||||
#########POLICY FILE PATH #########
|
||||
# atlas.auth.policy.file=policy-store.txt
|
||||
######### Atlas Authorization #########
|
||||
atlas.authorizer.impl=none
|
||||
# atlas.authorizer.impl=simple
|
||||
# atlas.authorizer.simple.authz.policy.file=atlas-simple-authz-policy.json
|
||||
|
||||
######### Atlas Authentication #########
|
||||
atlas.authentication.method.file=true
|
||||
atlas.authentication.method.ldap.type=none
|
||||
atlas.authentication.method.kerberos=false
|
||||
# atlas.authentication.method.file.filename=users-credentials.properties
|
||||
atlas.authentication.method.kerberos=false
|
||||
|
|
@ -115,10 +115,13 @@ atlas.server.ha.enabled=false
|
|||
#atlas.server.ids=id1
|
||||
#atlas.server.address.id1=localhost:21000
|
||||
|
||||
#########POLICY FILE PATH #########
|
||||
# atlas.auth.policy.file=policy-store.txt
|
||||
######### Atlas Authorization #########
|
||||
atlas.authorizer.impl=none
|
||||
# atlas.authorizer.impl=simple
|
||||
# atlas.authorizer.simple.authz.policy.file=atlas-simple-authz-policy.json
|
||||
|
||||
######### Atlas Authentication #########
|
||||
atlas.authentication.method.file=true
|
||||
atlas.authentication.method.ldap.type=none
|
||||
atlas.authentication.method.kerberos=false
|
||||
# atlas.authentication.method.file.filename=users-credentials.properties
|
||||
atlas.authentication.method.kerberos=false
|
||||
|
|
@ -115,10 +115,13 @@ atlas.server.ha.enabled=false
|
|||
#atlas.server.ids=id1
|
||||
#atlas.server.address.id1=localhost:21000
|
||||
|
||||
#########POLICY FILE PATH #########
|
||||
# atlas.auth.policy.file=policy-store.txt
|
||||
######### Atlas Authorization #########
|
||||
atlas.authorizer.impl=none
|
||||
# atlas.authorizer.impl=simple
|
||||
# atlas.authorizer.simple.authz.policy.file=atlas-simple-authz-policy.json
|
||||
|
||||
######### Atlas Authentication #########
|
||||
atlas.authentication.method.file=true
|
||||
atlas.authentication.method.ldap.type=none
|
||||
atlas.authentication.method.kerberos=false
|
||||
# atlas.authentication.method.file.filename=users-credentials.properties
|
||||
atlas.authentication.method.kerberos=false
|
||||
|
|
@ -117,10 +117,13 @@ atlas.server.ha.enabled=false
|
|||
#atlas.server.ids=id1
|
||||
#atlas.server.address.id1=localhost:21000
|
||||
|
||||
#########POLICY FILE PATH #########
|
||||
# atlas.auth.policy.file=policy-store.txt
|
||||
######### Atlas Authorization #########
|
||||
atlas.authorizer.impl=none
|
||||
# atlas.authorizer.impl=simple
|
||||
# atlas.authorizer.simple.authz.policy.file=atlas-simple-authz-policy.json
|
||||
|
||||
######### Atlas Authentication #########
|
||||
atlas.authentication.method.file=true
|
||||
atlas.authentication.method.ldap.type=none
|
||||
atlas.authentication.method.kerberos=false
|
||||
# atlas.authentication.method.file.filename=users-credentials.properties
|
||||
atlas.authentication.method.kerberos=false
|
||||
|
|
@ -35,11 +35,21 @@
|
|||
<artifactId>atlas-common</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.atlas</groupId>
|
||||
<artifactId>atlas-intg</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>${javax.servlet.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
|
|
|
|||
|
|
@ -17,94 +17,57 @@
|
|||
*/
|
||||
package org.apache.atlas.authorize;
|
||||
|
||||
import org.apache.atlas.authorize.simple.AtlasAuthorizationUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
|
||||
public class AtlasAccessRequest {
|
||||
|
||||
private static Logger LOG = LoggerFactory.getLogger(AtlasAccessRequest.class);
|
||||
private static boolean isDebugEnabled = LOG.isDebugEnabled();
|
||||
private Set<AtlasResourceTypes> resourceType = null;
|
||||
private String resource = null;
|
||||
private AtlasActionTypes action = null;
|
||||
private String user = null;
|
||||
private Set<String> userGroups = null;
|
||||
private Date accessTime = null;
|
||||
private String clientIPAddress = null;
|
||||
|
||||
public AtlasAccessRequest(HttpServletRequest request, String user, Set<String> userGroups) {
|
||||
// Spring Security 4 Change => request.getServletPath() -> request.getPathInfo()
|
||||
this(AtlasAuthorizationUtils.getAtlasResourceType(request.getPathInfo()), "*", AtlasAuthorizationUtils
|
||||
.getAtlasAction(request.getMethod(),request.getPathInfo()), user, userGroups,AtlasAuthorizationUtils.getRequestIpAddress(request));
|
||||
private final AtlasPrivilege action;
|
||||
private final Date accessTime;
|
||||
private String user = null;
|
||||
private Set<String> userGroups = null;
|
||||
private String clientIPAddress = null;
|
||||
|
||||
|
||||
protected AtlasAccessRequest(AtlasPrivilege action) {
|
||||
this(action, null, null, new Date(), null);
|
||||
}
|
||||
|
||||
public AtlasAccessRequest(Set<AtlasResourceTypes> resourceType, String resource, AtlasActionTypes action,
|
||||
String user, Set<String> userGroups, String clientIPAddress) {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("==> AtlasAccessRequestImpl-- Initializing AtlasAccessRequest");
|
||||
}
|
||||
setResource(resource);
|
||||
setAction(action);
|
||||
setUser(user);
|
||||
setUserGroups(userGroups);
|
||||
setResourceType(resourceType);
|
||||
|
||||
// set remaining fields to default value
|
||||
setAccessTime(null);
|
||||
setClientIPAddress(clientIPAddress);
|
||||
protected AtlasAccessRequest(AtlasPrivilege action, String user, Set<String> userGroups) {
|
||||
this(action, user, userGroups, new Date(), null);
|
||||
}
|
||||
|
||||
public Set<AtlasResourceTypes> getResourceTypes() {
|
||||
return resourceType;
|
||||
protected AtlasAccessRequest(AtlasPrivilege action, String user, Set<String> userGroups, Date accessTime, String clientIPAddress) {
|
||||
this.action = action;
|
||||
this.user = user;
|
||||
this.userGroups = userGroups;
|
||||
this.accessTime = accessTime;
|
||||
this.clientIPAddress = clientIPAddress;
|
||||
}
|
||||
|
||||
public void setResourceType(Set<AtlasResourceTypes> resourceType) {
|
||||
this.resourceType = resourceType;
|
||||
}
|
||||
|
||||
public String getResource() {
|
||||
return resource;
|
||||
}
|
||||
|
||||
public void setResource(String resource) {
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
public AtlasActionTypes getAction() {
|
||||
public AtlasPrivilege getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public void setAction(AtlasActionTypes action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public String getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(String user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public void setUserGroups(Set<String> userGroups) {
|
||||
this.userGroups = userGroups;
|
||||
}
|
||||
|
||||
public Set<String> getUserGroups() {
|
||||
return userGroups;
|
||||
}
|
||||
|
||||
public Date getAccessTime() {
|
||||
return accessTime;
|
||||
}
|
||||
|
||||
public void setAccessTime(Date accessTime) {
|
||||
this.accessTime = accessTime;
|
||||
public String getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public Set<String> getUserGroups() {
|
||||
return userGroups;
|
||||
}
|
||||
|
||||
public void setUser(String user, Set<String> userGroups) {
|
||||
this.user = user;
|
||||
this.userGroups = userGroups;
|
||||
}
|
||||
|
||||
public String getClientIPAddress() {
|
||||
|
|
@ -117,9 +80,7 @@ public class AtlasAccessRequest {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AtlasAccessRequest [resourceType=" + resourceType + ", resource=" + resource + ", action=" + action
|
||||
+ ", user=" + user + ", userGroups=" + userGroups + ", accessTime=" + accessTime + ", clientIPAddress="
|
||||
+ clientIPAddress + "]";
|
||||
return "AtlasAccessRequest[action=" + action + ", accessTime=" + accessTime + ", user=" + user +
|
||||
", userGroups=" + userGroups + ", clientIPAddress=" + clientIPAddress + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,9 +15,24 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.atlas.authorize;
|
||||
|
||||
public enum AtlasResourceTypes {
|
||||
UNKNOWN, ENTITY, TYPE, OPERATION, RELATIONSHIP
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class AtlasAdminAccessRequest extends AtlasAccessRequest {
|
||||
|
||||
public AtlasAdminAccessRequest(AtlasPrivilege action) {
|
||||
super(action);
|
||||
}
|
||||
|
||||
public AtlasAdminAccessRequest(AtlasPrivilege action, String userName, Set<String> usergroups) {
|
||||
super(action, userName, usergroups);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AtlasAdminAccessRequest[action=" + getAction() + ", accessTime=" + getAccessTime() + ", user=" + getUser() +
|
||||
", userGroups=" + getUserGroups() + ", clientIPAddress=" + getClientIPAddress() + "]";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
/**
|
||||
/**
|
||||
* 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.AtlasErrorCode;
|
||||
import org.apache.atlas.exception.AtlasBaseException;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
public class AtlasAuthorizationUtils {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AtlasAuthorizationUtils.class);
|
||||
|
||||
public static void verifyAccess(AtlasAdminAccessRequest request, Object... errorMsgParams) throws AtlasBaseException {
|
||||
if (! isAccessAllowed(request)) {
|
||||
String message = (errorMsgParams != null && errorMsgParams.length > 0) ? StringUtils.join(errorMsgParams) : "";
|
||||
|
||||
throw new AtlasBaseException(AtlasErrorCode.UNAUTHORIZED_ACCESS, request.getUser(), message);
|
||||
}
|
||||
}
|
||||
|
||||
public static void verifyAccess(AtlasTypeAccessRequest request, Object... errorMsgParams) throws AtlasBaseException {
|
||||
if (! isAccessAllowed(request)) {
|
||||
String message = (errorMsgParams != null && errorMsgParams.length > 0) ? StringUtils.join(errorMsgParams) : "";
|
||||
|
||||
throw new AtlasBaseException(AtlasErrorCode.UNAUTHORIZED_ACCESS, request.getUser(), message);
|
||||
}
|
||||
}
|
||||
|
||||
public static void verifyAccess(AtlasEntityAccessRequest request, Object... errorMsgParams) throws AtlasBaseException {
|
||||
if (! isAccessAllowed(request)) {
|
||||
String message = (errorMsgParams != null && errorMsgParams.length > 0) ? StringUtils.join(errorMsgParams) : "";
|
||||
|
||||
throw new AtlasBaseException(AtlasErrorCode.UNAUTHORIZED_ACCESS, request.getUser(), message);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isAccessAllowed(AtlasAdminAccessRequest request) {
|
||||
boolean ret = false;
|
||||
String userName = getCurrentUserName();
|
||||
|
||||
if (StringUtils.isNotEmpty(userName)) {
|
||||
try {
|
||||
AtlasAuthorizer authorizer = AtlasAuthorizerFactory.getAtlasAuthorizer();
|
||||
|
||||
request.setUser(userName, getCurrentUserGroups());
|
||||
|
||||
ret = authorizer.isAccessAllowed(request);
|
||||
} catch (AtlasAuthorizationException e) {
|
||||
LOG.error("Unable to obtain AtlasAuthorizer", e);
|
||||
}
|
||||
} else {
|
||||
ret = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static boolean isAccessAllowed(AtlasEntityAccessRequest request) {
|
||||
boolean ret = false;
|
||||
String userName = getCurrentUserName();
|
||||
|
||||
if (StringUtils.isNotEmpty(userName)) {
|
||||
try {
|
||||
AtlasAuthorizer authorizer = AtlasAuthorizerFactory.getAtlasAuthorizer();
|
||||
|
||||
request.setUser(getCurrentUserName(), getCurrentUserGroups());
|
||||
|
||||
ret = authorizer.isAccessAllowed(request);
|
||||
} catch (AtlasAuthorizationException e) {
|
||||
LOG.error("Unable to obtain AtlasAuthorizer", e);
|
||||
}
|
||||
} else {
|
||||
ret = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static boolean isAccessAllowed(AtlasTypeAccessRequest request) {
|
||||
boolean ret = false;
|
||||
String userName = getCurrentUserName();
|
||||
|
||||
if (StringUtils.isNotEmpty(userName)) {
|
||||
try {
|
||||
AtlasAuthorizer authorizer = AtlasAuthorizerFactory.getAtlasAuthorizer();
|
||||
|
||||
request.setUser(getCurrentUserName(), getCurrentUserGroups());
|
||||
|
||||
ret = authorizer.isAccessAllowed(request);
|
||||
} catch (AtlasAuthorizationException e) {
|
||||
LOG.error("Unable to obtain AtlasAuthorizer", e);
|
||||
}
|
||||
} else {
|
||||
ret = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static String getRequestIpAddress(HttpServletRequest httpServletRequest) {
|
||||
String ret = "";
|
||||
|
||||
try {
|
||||
InetAddress inetAddr = InetAddress.getByName(httpServletRequest.getRemoteAddr());
|
||||
|
||||
ret = inetAddr.getHostAddress();
|
||||
} catch (UnknownHostException ex) {
|
||||
LOG.error("Failed to retrieve client IP address", ex);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static String getCurrentUserName() {
|
||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
|
||||
return auth != null ? auth.getName() : "";
|
||||
}
|
||||
|
||||
public static Set<String> getCurrentUserGroups() {
|
||||
Set<String> ret = new HashSet<>();
|
||||
|
||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
|
||||
if (auth != null) {
|
||||
for (GrantedAuthority c : auth.getAuthorities()) {
|
||||
ret.add(c.getAuthority());
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
@ -20,23 +20,39 @@ package org.apache.atlas.authorize;
|
|||
|
||||
|
||||
public interface AtlasAuthorizer {
|
||||
|
||||
|
||||
/**
|
||||
* This method will load the policy file and would initialize the required data-structures.
|
||||
* initialization of authorizer implementation
|
||||
*/
|
||||
void init();
|
||||
|
||||
/**
|
||||
* This method is responsible to perform the actual authorization for every REST API call. It will check if
|
||||
* user can perform action on resource.
|
||||
*/
|
||||
boolean isAccessAllowed(AtlasAccessRequest request) throws AtlasAuthorizationException;
|
||||
|
||||
/**
|
||||
* This method is responsible to perform the cleanup and release activities. It must be called when you are done
|
||||
* with the Authorization activity and once it's called a restart would be required. Try to invoke this while
|
||||
* destroying the context.
|
||||
* cleanup of authorizer implementation
|
||||
*/
|
||||
void cleanUp();
|
||||
|
||||
/**
|
||||
* authorize admin operations
|
||||
* @param request
|
||||
* @return
|
||||
* @throws AtlasAuthorizationException
|
||||
*/
|
||||
boolean isAccessAllowed(AtlasAdminAccessRequest request) throws AtlasAuthorizationException;
|
||||
|
||||
/**
|
||||
* authorize operations on an entity
|
||||
* @param request
|
||||
* @return
|
||||
* @throws AtlasAuthorizationException
|
||||
*/
|
||||
boolean isAccessAllowed(AtlasEntityAccessRequest request) throws AtlasAuthorizationException;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* authorize operations on a type
|
||||
* @param request
|
||||
* @return
|
||||
* @throws AtlasAuthorizationException
|
||||
*/
|
||||
boolean isAccessAllowed(AtlasTypeAccessRequest request) throws AtlasAuthorizationException;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,65 +20,71 @@ package org.apache.atlas.authorize;
|
|||
|
||||
import org.apache.atlas.ApplicationProperties;
|
||||
import org.apache.atlas.AtlasException;
|
||||
import org.apache.atlas.authorize.simple.AtlasSimpleAuthorizer;
|
||||
import org.apache.commons.configuration.Configuration;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class AtlasAuthorizerFactory {
|
||||
|
||||
public class AtlasAuthorizerFactory {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AtlasAuthorizerFactory.class);
|
||||
private static final String SIMPLE_AUTHORIZER = "org.apache.atlas.authorize.simple.SimpleAtlasAuthorizer";
|
||||
private static final String RANGER_AUTHORIZER =
|
||||
"org.apache.ranger.authorization.atlas.authorizer.RangerAtlasAuthorizer";
|
||||
|
||||
private static final String NONE_AUTHORIZER = AtlasNoneAuthorizer.class.getName();
|
||||
private static final String SIMPLE_AUTHORIZER = AtlasSimpleAuthorizer.class.getName();
|
||||
private static final String RANGER_AUTHORIZER = "org.apache.ranger.authorization.atlas.authorizer.RangerAtlasAuthorizer";
|
||||
|
||||
private static volatile AtlasAuthorizer INSTANCE = null;
|
||||
private static boolean isDebugEnabled = LOG.isDebugEnabled();
|
||||
|
||||
public static AtlasAuthorizer getAtlasAuthorizer() throws AtlasAuthorizationException {
|
||||
Configuration configuration = null;
|
||||
try {
|
||||
configuration = ApplicationProperties.get();
|
||||
} catch (AtlasException e) {
|
||||
if (LOG.isErrorEnabled()) {
|
||||
LOG.error("Exception while fetching configuration. ", e);
|
||||
}
|
||||
}
|
||||
AtlasAuthorizer ret = INSTANCE;
|
||||
|
||||
if (ret == null) {
|
||||
synchronized (AtlasAuthorizerFactory.class) {
|
||||
if (INSTANCE == null) {
|
||||
String authorizerClass =
|
||||
configuration != null ? configuration.getString("atlas.authorizer.impl") : "SIMPLE";
|
||||
Configuration configuration = null;
|
||||
|
||||
try {
|
||||
configuration = ApplicationProperties.get();
|
||||
} catch (AtlasException e) {
|
||||
LOG.error("Exception while fetching configuration", e);
|
||||
}
|
||||
|
||||
String authorizerClass = configuration != null ? configuration.getString("atlas.authorizer.impl") : "SIMPLE";
|
||||
|
||||
if (StringUtils.isNotEmpty(authorizerClass)) {
|
||||
if (StringUtils.equalsIgnoreCase(authorizerClass, "SIMPLE")) {
|
||||
authorizerClass = SIMPLE_AUTHORIZER;
|
||||
} else if (StringUtils.equalsIgnoreCase(authorizerClass, "RANGER")) {
|
||||
authorizerClass = RANGER_AUTHORIZER;
|
||||
} else if (StringUtils.equalsIgnoreCase(authorizerClass, "NONE")) {
|
||||
authorizerClass = NONE_AUTHORIZER;
|
||||
}
|
||||
} else {
|
||||
authorizerClass = SIMPLE_AUTHORIZER;
|
||||
}
|
||||
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("Initializing Authorizer :: {}", authorizerClass);
|
||||
}
|
||||
LOG.info("Initializing Authorizer {}", authorizerClass);
|
||||
|
||||
try {
|
||||
Class authorizerMetaObject = Class.forName(authorizerClass);
|
||||
|
||||
if (authorizerMetaObject != null) {
|
||||
INSTANCE = (AtlasAuthorizer) authorizerMetaObject.newInstance();
|
||||
|
||||
INSTANCE.init();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error while creating authorizer of type '{}", authorizerClass, e);
|
||||
throw new AtlasAuthorizationException("Error while creating authorizer of type '"
|
||||
+ authorizerClass + "'", e);
|
||||
LOG.error("Error while creating authorizer of type {}", authorizerClass, e);
|
||||
|
||||
throw new AtlasAuthorizationException("Error while creating authorizer of type '" + authorizerClass + "'", e);
|
||||
}
|
||||
ret = INSTANCE;
|
||||
}
|
||||
|
||||
ret = INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,146 @@
|
|||
/**
|
||||
* 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.instance.AtlasClassification;
|
||||
import org.apache.atlas.model.instance.AtlasEntityHeader;
|
||||
import org.apache.atlas.type.AtlasClassificationType;
|
||||
import org.apache.atlas.type.AtlasEntityType;
|
||||
import org.apache.atlas.type.AtlasTypeRegistry;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class AtlasEntityAccessRequest extends AtlasAccessRequest {
|
||||
private final AtlasEntityHeader entity;
|
||||
private final String entityId;
|
||||
private final AtlasClassification classification;
|
||||
private final String attributeName;
|
||||
private final AtlasTypeRegistry typeRegistry;
|
||||
private final Set<String> entityClassifications;
|
||||
|
||||
|
||||
public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action) {
|
||||
this(typeRegistry, action, null, null, null, null, null);
|
||||
}
|
||||
|
||||
public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity) {
|
||||
this(typeRegistry, action, entity, null, null, null, null);
|
||||
}
|
||||
|
||||
public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, AtlasClassification classification) {
|
||||
this(typeRegistry, action, entity, classification, null, null, null);
|
||||
}
|
||||
|
||||
public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, String attributeName) {
|
||||
this(typeRegistry, action, entity, null, attributeName, null, null);
|
||||
}
|
||||
|
||||
public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, String userName, Set<String> userGroups) {
|
||||
this(typeRegistry, action, entity, null, null, userName, userGroups);
|
||||
}
|
||||
|
||||
public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, AtlasClassification classification, String userName, Set<String> userGroups) {
|
||||
this(typeRegistry, action, entity, classification, null, userName, userGroups);
|
||||
}
|
||||
|
||||
public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, String attributeName, String userName, Set<String> userGroups) {
|
||||
this(typeRegistry, action, entity, null, attributeName, userName, userGroups);
|
||||
}
|
||||
|
||||
public AtlasEntityAccessRequest(AtlasTypeRegistry typeRegistry, AtlasPrivilege action, AtlasEntityHeader entity, AtlasClassification classification, String attributeName, String userName, Set<String> userGroups) {
|
||||
super(action, userName, userGroups);
|
||||
|
||||
this.entity = entity;
|
||||
this.entityId = entity != null ? (String) entity.getAttribute("qualifiedName") : null;
|
||||
this.classification = classification;
|
||||
this.attributeName = attributeName;
|
||||
this.typeRegistry = typeRegistry;
|
||||
|
||||
if (entity == null || entity.getClassifications() == null) {
|
||||
this.entityClassifications = Collections.emptySet();
|
||||
} else {
|
||||
this.entityClassifications = new HashSet<>();
|
||||
|
||||
for (AtlasClassification classify : entity.getClassifications()) {
|
||||
this.entityClassifications.add(classify.getTypeName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public AtlasEntityHeader getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
public String getEntityId() {
|
||||
return entityId;
|
||||
}
|
||||
|
||||
public AtlasClassification getClassification() {
|
||||
return classification;
|
||||
}
|
||||
|
||||
public String getAttributeName() {
|
||||
return attributeName;
|
||||
}
|
||||
|
||||
public String getEntityType() {
|
||||
return entity == null ? StringUtils.EMPTY : entity.getTypeName();
|
||||
}
|
||||
|
||||
public Set<String> getEntityClassifications() {
|
||||
return entityClassifications;
|
||||
}
|
||||
|
||||
public Set<String> getEntityTypeAndAllSuperTypes() {
|
||||
final Set<String> ret;
|
||||
|
||||
if (entity == null) {
|
||||
ret = Collections.emptySet();
|
||||
} else if (typeRegistry == null) {
|
||||
ret = Collections.singleton(entity.getTypeName());
|
||||
} else {
|
||||
AtlasEntityType entityType = typeRegistry.getEntityTypeByName(entity.getTypeName());
|
||||
|
||||
ret = entityType != null ? entityType.getTypeAndAllSuperTypes() : Collections.singleton(entity.getTypeName());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Set<String> getClassificationTypeAndAllSuperTypes(String classificationName) {
|
||||
if (typeRegistry != null && classificationName != null) {
|
||||
AtlasClassificationType classificationType = typeRegistry.getClassificationTypeByName(classificationName);
|
||||
|
||||
return classificationType == null ? Collections.emptySet() : classificationType.getTypeAndAllSuperTypes();
|
||||
}
|
||||
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AtlasEntityAccessRequest[entity=" + entity + ", classification=" + classification + ", attributeName" + attributeName +
|
||||
", action=" + getAction() + ", accessTime=" + getAccessTime() + ", user=" + getUser() +
|
||||
", userGroups=" + getUserGroups() + ", clientIPAddress=" + getClientIPAddress() + "]";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/*
|
||||
* 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
|
||||
|
|
@ -15,26 +15,33 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.atlas.exception;
|
||||
|
||||
public class SchemaNotFoundException extends NotFoundException {
|
||||
public SchemaNotFoundException() {
|
||||
package org.apache.atlas.authorize;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
public class AtlasNoneAuthorizer implements AtlasAuthorizer {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AtlasNoneAuthorizer.class);
|
||||
|
||||
public void init() {
|
||||
LOG.info("AtlasNoneAuthorizer.init()");
|
||||
}
|
||||
|
||||
public SchemaNotFoundException(String message) {
|
||||
super(message);
|
||||
public void cleanUp() {
|
||||
LOG.info("AtlasNoneAuthorizer.cleanUp()");
|
||||
}
|
||||
|
||||
public SchemaNotFoundException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
public boolean isAccessAllowed(AtlasAdminAccessRequest request) throws AtlasAuthorizationException {
|
||||
return true;
|
||||
}
|
||||
|
||||
public SchemaNotFoundException(Throwable cause) {
|
||||
super(cause);
|
||||
public boolean isAccessAllowed(AtlasEntityAccessRequest request) throws AtlasAuthorizationException {
|
||||
return true;
|
||||
}
|
||||
|
||||
public SchemaNotFoundException(String message, Throwable cause, boolean enableSuppression,
|
||||
boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
public boolean isAccessAllowed(AtlasTypeAccessRequest request) throws AtlasAuthorizationException {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,30 @@
|
|||
*/
|
||||
package org.apache.atlas.authorize;
|
||||
|
||||
public enum AtlasActionTypes {
|
||||
READ, CREATE, UPDATE, DELETE
|
||||
public enum AtlasPrivilege {
|
||||
TYPE_CREATE("type-create"),
|
||||
TYPE_UPDATE("type-update"),
|
||||
TYPE_DELETE("type-delete"),
|
||||
|
||||
ENTITY_READ("entity-read"),
|
||||
ENTITY_CREATE("entity-create"),
|
||||
ENTITY_UPDATE("entity-update"),
|
||||
ENTITY_DELETE("entity-delete"),
|
||||
ENTITY_READ_CLASSIFICATION("entity-read-classification"),
|
||||
ENTITY_ADD_CLASSIFICATION("entity-add-classification"),
|
||||
ENTITY_UPDATE_CLASSIFICATION("entity-update-classification"),
|
||||
ENTITY_REMOVE_CLASSIFICATION("entity-remove-classification"),
|
||||
|
||||
ADMIN_EXPORT("admin-export"),
|
||||
ADMIN_IMPORT("admin-import");
|
||||
|
||||
private final String type;
|
||||
|
||||
AtlasPrivilege(String actionType){
|
||||
this.type = actionType;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* 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.typedef.AtlasBaseTypeDef;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class AtlasTypeAccessRequest extends AtlasAccessRequest {
|
||||
private final AtlasBaseTypeDef typeDef;
|
||||
|
||||
|
||||
public AtlasTypeAccessRequest(AtlasPrivilege action, AtlasBaseTypeDef typeDef) {
|
||||
super(action);
|
||||
|
||||
this.typeDef = typeDef;
|
||||
}
|
||||
|
||||
public AtlasTypeAccessRequest(AtlasPrivilege action, AtlasBaseTypeDef typeDef, String userName, Set<String> usergroups) {
|
||||
super(action, userName, usergroups);
|
||||
|
||||
this.typeDef = typeDef;
|
||||
}
|
||||
|
||||
public AtlasBaseTypeDef getTypeDef() {
|
||||
return typeDef;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AtlasEntityAccessRequest[typeDef=" + typeDef + ", action=" + getAction() + ", accessTime=" + getAccessTime() +
|
||||
", user=" + getUser() + ", userGroups=" + getUserGroups() + ", clientIPAddress=" + getClientIPAddress() + "]";
|
||||
}
|
||||
}
|
||||
|
|
@ -1,182 +0,0 @@
|
|||
/**
|
||||
/**
|
||||
* 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.simple;
|
||||
|
||||
import org.apache.atlas.authorize.AtlasAccessRequest;
|
||||
import org.apache.atlas.authorize.AtlasActionTypes;
|
||||
import org.apache.atlas.authorize.AtlasAuthorizationException;
|
||||
import org.apache.atlas.authorize.AtlasAuthorizer;
|
||||
import org.apache.atlas.authorize.AtlasAuthorizerFactory;
|
||||
import org.apache.atlas.authorize.AtlasResourceTypes;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class AtlasAuthorizationUtils {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AtlasAuthorizationUtils.class);
|
||||
private static boolean isDebugEnabled = LOG.isDebugEnabled();
|
||||
private static final String BASE_URL = "/api/atlas/";
|
||||
|
||||
public static String getApi(String contextPath) {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("==> getApi({})", contextPath);
|
||||
}
|
||||
|
||||
if(contextPath == null){
|
||||
contextPath = "";
|
||||
}
|
||||
|
||||
if (contextPath.startsWith(BASE_URL)) {
|
||||
contextPath = contextPath.substring(BASE_URL.length());
|
||||
} else {
|
||||
// strip of leading '/'
|
||||
if (contextPath.startsWith("/")) {
|
||||
contextPath = contextPath.substring(1);
|
||||
}
|
||||
}
|
||||
String[] split = contextPath.split("/", 3);
|
||||
|
||||
String api = split[0];
|
||||
if (Pattern.matches("v\\d", api)) {
|
||||
api = split[1];
|
||||
}
|
||||
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("<== getApi({}): {}", contextPath, api);
|
||||
}
|
||||
|
||||
return api;
|
||||
}
|
||||
|
||||
public static AtlasActionTypes getAtlasAction(String method, String contextPath) {
|
||||
AtlasActionTypes action = null;
|
||||
|
||||
switch (method.toUpperCase()) {
|
||||
case "POST":
|
||||
String api = getApi(contextPath);
|
||||
if (api != null && api.startsWith("search")) { // exceptional case for basic search api with POST method
|
||||
action = AtlasActionTypes.READ;
|
||||
} else {
|
||||
action = AtlasActionTypes.CREATE;
|
||||
}
|
||||
break;
|
||||
case "GET":
|
||||
action = AtlasActionTypes.READ;
|
||||
break;
|
||||
case "PUT":
|
||||
action = AtlasActionTypes.UPDATE;
|
||||
break;
|
||||
case "DELETE":
|
||||
action = AtlasActionTypes.DELETE;
|
||||
break;
|
||||
default:
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("getAtlasAction(): Invalid HTTP method '{}", method);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("<== AtlasAuthorizationFilter getAtlasAction HTTP Method {} mapped to AtlasAction : {}",
|
||||
method, action);
|
||||
}
|
||||
return action;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param contextPath
|
||||
* @return set of AtlasResourceTypes types api mapped with AtlasResourceTypes.TYPE eg :- /api/atlas/types/*
|
||||
*
|
||||
* gremlin discovery,admin,graph apis are mapped with AtlasResourceTypes.OPERATION eg :-/api/atlas/admin/*
|
||||
* /api/atlas/discovery/search/gremlin /api/atlas/graph/*
|
||||
*
|
||||
* entities,lineage and discovery apis are mapped with AtlasResourceTypes.ENTITY eg :- /api/atlas/lineage/hive/table/*
|
||||
* /api/atlas/entities/{guid}* /api/atlas/discovery/*
|
||||
*
|
||||
* unprotected types are mapped with AtlasResourceTypes.UNKNOWN, access to these are allowed.
|
||||
*/
|
||||
public static Set<AtlasResourceTypes> getAtlasResourceType(String contextPath) {
|
||||
Set<AtlasResourceTypes> resourceTypes = new HashSet<>();
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("==> getAtlasResourceType for {}", contextPath);
|
||||
}
|
||||
String api = getApi(contextPath);
|
||||
if (api.startsWith("types")) {
|
||||
resourceTypes.add(AtlasResourceTypes.TYPE);
|
||||
} else if (api.startsWith("admin") && (contextPath.contains("/session") || contextPath.contains("/version"))) {
|
||||
resourceTypes.add(AtlasResourceTypes.UNKNOWN);
|
||||
} else if ((api.startsWith("discovery") && contextPath.contains("/gremlin")) || api.startsWith("admin")
|
||||
|| api.startsWith("graph")) {
|
||||
resourceTypes.add(AtlasResourceTypes.OPERATION);
|
||||
} else if (api.startsWith("entities") || api.startsWith("lineage") ||
|
||||
api.startsWith("discovery") || api.startsWith("entity") || api.startsWith("search")) {
|
||||
resourceTypes.add(AtlasResourceTypes.ENTITY);
|
||||
} else if (api.startsWith("relationship")) {
|
||||
resourceTypes.add(AtlasResourceTypes.RELATIONSHIP);
|
||||
} else {
|
||||
LOG.error("Unable to find Atlas Resource corresponding to : {}\nSetting {}"
|
||||
, api, AtlasResourceTypes.UNKNOWN.name());
|
||||
resourceTypes.add(AtlasResourceTypes.UNKNOWN);
|
||||
}
|
||||
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("<== Returning AtlasResources {} for api {}", resourceTypes, api);
|
||||
}
|
||||
return resourceTypes;
|
||||
}
|
||||
|
||||
public static boolean isAccessAllowed(AtlasResourceTypes resourcetype, AtlasActionTypes actionType, String userName, Set<String> groups, HttpServletRequest request) {
|
||||
AtlasAuthorizer authorizer = null;
|
||||
boolean isaccessAllowed = false;
|
||||
|
||||
Set<AtlasResourceTypes> resourceTypes = new HashSet<>();
|
||||
resourceTypes.add(resourcetype);
|
||||
AtlasAccessRequest atlasRequest = new AtlasAccessRequest(resourceTypes, "*", actionType, userName, groups, AtlasAuthorizationUtils.getRequestIpAddress(request));
|
||||
try {
|
||||
authorizer = AtlasAuthorizerFactory.getAtlasAuthorizer();
|
||||
if (authorizer != null) {
|
||||
isaccessAllowed = authorizer.isAccessAllowed(atlasRequest);
|
||||
}
|
||||
} catch (AtlasAuthorizationException e) {
|
||||
LOG.error("Unable to obtain AtlasAuthorizer. ", e);
|
||||
}
|
||||
|
||||
return isaccessAllowed;
|
||||
}
|
||||
|
||||
public static String getRequestIpAddress(HttpServletRequest httpServletRequest) {
|
||||
try {
|
||||
InetAddress inetAddr = InetAddress.getByName(httpServletRequest.getRemoteAddr());
|
||||
|
||||
String ip = inetAddr.getHostAddress();
|
||||
|
||||
return ip;
|
||||
} catch (UnknownHostException ex) {
|
||||
LOG.error("Error occured when retrieving IP address", ex);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,346 @@
|
|||
/**
|
||||
* 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.simple;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.atlas.ApplicationProperties;
|
||||
import org.apache.atlas.AtlasException;
|
||||
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.AtlasTypeAccessRequest;
|
||||
import org.apache.atlas.authorize.simple.AtlasSimpleAuthzPolicy.*;
|
||||
import org.apache.atlas.utils.AtlasJson;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
public final class AtlasSimpleAuthorizer implements AtlasAuthorizer {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AtlasSimpleAuthorizer.class);
|
||||
|
||||
private final static String WILDCARD_ASTERISK = "*";
|
||||
|
||||
private AtlasSimpleAuthzPolicy authzPolicy;
|
||||
|
||||
|
||||
public AtlasSimpleAuthorizer() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
LOG.info("==> SimpleAtlasAuthorizer.init()");
|
||||
|
||||
InputStream inputStream = null;
|
||||
|
||||
try {
|
||||
inputStream = ApplicationProperties.getFileAsInputStream(ApplicationProperties.get(), "atlas.authorizer.simple.authz.policy.file", "atlas-simple-authz-policy.json");
|
||||
|
||||
authzPolicy = AtlasJson.fromJson(inputStream, AtlasSimpleAuthzPolicy.class);
|
||||
} catch (IOException | AtlasException e) {
|
||||
LOG.error("SimpleAtlasAuthorizer.init(): initialization failed", e);
|
||||
|
||||
throw new RuntimeException(e);
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException excp) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOG.info("<== SimpleAtlasAuthorizer.init()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanUp() {
|
||||
LOG.info("==> SimpleAtlasAuthorizer.cleanUp()");
|
||||
|
||||
authzPolicy = null;
|
||||
|
||||
LOG.info("<== SimpleAtlasAuthorizer.cleanUp()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccessAllowed(AtlasAdminAccessRequest request) throws AtlasAuthorizationException {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("==> SimpleAtlasAuthorizer.isAccessAllowed({})", request);
|
||||
}
|
||||
|
||||
boolean ret = false;
|
||||
|
||||
Set<String> roles = getRoles(request.getUser(), request.getUserGroups());
|
||||
|
||||
for (String role : roles) {
|
||||
List<AtlasAdminPermission> permissions = getAdminPermissionsForRole(role);
|
||||
|
||||
if (permissions != null) {
|
||||
final String action = request.getAction() != null ? request.getAction().getType() : null;
|
||||
|
||||
for (AtlasAdminPermission permission : permissions) {
|
||||
if (isMatch(action, permission.getPrivileges())) {
|
||||
ret = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("<== SimpleAtlasAuthorizer.isAccessAllowed({}): {}", request, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccessAllowed(AtlasTypeAccessRequest request) throws AtlasAuthorizationException {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("==> SimpleAtlasAuthorizer.isAccessAllowed({})", request);
|
||||
}
|
||||
|
||||
boolean ret = false;
|
||||
|
||||
Set<String> roles = getRoles(request.getUser(), request.getUserGroups());
|
||||
|
||||
for (String role : roles) {
|
||||
List<AtlasTypePermission> permissions = getTypePermissionsForRole(role);
|
||||
|
||||
if (permissions != null) {
|
||||
final String action = request.getAction() != null ? request.getAction().getType() : null;
|
||||
final String typeCategory = request.getTypeDef() != null ? request.getTypeDef().getCategory().name() : null;
|
||||
final String typeName = request.getTypeDef() != null ? request.getTypeDef().getName() : null;
|
||||
|
||||
for (AtlasTypePermission permission : permissions) {
|
||||
if (isMatch(action, permission.getPrivileges()) &&
|
||||
isMatch(typeCategory, permission.getTypeCategories()) &&
|
||||
isMatch(typeName, permission.getTypeNames())) {
|
||||
ret = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("<== SimpleAtlasAuthorizer.isAccessAllowed({}): {}", request, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccessAllowed(AtlasEntityAccessRequest request) throws AtlasAuthorizationException {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("==> SimpleAtlasAuthorizer.isAccessAllowed({})", request);
|
||||
}
|
||||
|
||||
final String action = request.getAction() != null ? request.getAction().getType() : null;
|
||||
final Set<String> entityTypes = request.getEntityTypeAndAllSuperTypes();
|
||||
final String entityId = request.getEntityId();
|
||||
final String classification = request.getClassification() != null ? request.getClassification().getTypeName() : null;
|
||||
final String attribute = request.getAttributeName();
|
||||
final Set<String> entClsToAuthz = new HashSet<>(request.getEntityClassifications());
|
||||
final Set<String> roles = getRoles(request.getUser(), request.getUserGroups());
|
||||
boolean hasEntityAccess = false;
|
||||
boolean hasClassificationsAccess = false;
|
||||
|
||||
for (String role : roles) {
|
||||
List<AtlasEntityPermission> permissions = getEntityPermissionsForRole(role);
|
||||
|
||||
if (permissions != null) {
|
||||
for (AtlasEntityPermission permission : permissions) {
|
||||
// match entity-type/entity-id/attribute
|
||||
if (isMatchAny(entityTypes, permission.getEntityTypes()) && isMatch(entityId, permission.getEntityIds()) && isMatch(attribute, permission.getAttributes())) {
|
||||
// match permission/classification
|
||||
if (!hasEntityAccess) {
|
||||
if (isMatch(action, permission.getPrivileges()) && isMatch(classification, permission.getClassifications())) {
|
||||
hasEntityAccess = true;
|
||||
}
|
||||
}
|
||||
|
||||
// match entity-classifications
|
||||
for (Iterator<String> iter = entClsToAuthz.iterator(); iter.hasNext();) {
|
||||
String entityClassification = iter.next();
|
||||
|
||||
if (isMatchAny(request.getClassificationTypeAndAllSuperTypes(entityClassification), permission.getClassifications())) {
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
|
||||
hasClassificationsAccess = CollectionUtils.isEmpty(entClsToAuthz);
|
||||
|
||||
if (hasEntityAccess && hasClassificationsAccess) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean ret = hasEntityAccess && hasClassificationsAccess;
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
if (!ret) {
|
||||
LOG.debug("hasEntityAccess={}; hasClassificationsAccess={}, classificationsWithNoAccess={}", hasEntityAccess, hasClassificationsAccess, entClsToAuthz);
|
||||
}
|
||||
|
||||
LOG.debug("<== SimpleAtlasAuthorizer.isAccessAllowed({}): {}", request, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
private Set<String> getRoles(String userName, Set<String> userGroups) {
|
||||
Set<String> ret = new HashSet<>();
|
||||
|
||||
if (authzPolicy != null) {
|
||||
if (userName != null && authzPolicy.getUserRoles() != null) {
|
||||
List<String> userRoles = authzPolicy.getUserRoles().get(userName);
|
||||
|
||||
if (userRoles != null) {
|
||||
ret.addAll(userRoles);
|
||||
}
|
||||
}
|
||||
|
||||
if (userGroups != null && authzPolicy.getGroupRoles() != null) {
|
||||
for (String groupName : userGroups) {
|
||||
List<String> groupRoles = authzPolicy.getGroupRoles().get(groupName);
|
||||
|
||||
if (groupRoles != null) {
|
||||
ret.addAll(groupRoles);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("<== getRoles({}, {}): {}", userName, userGroups, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private List<AtlasAdminPermission> getAdminPermissionsForRole(String roleName) {
|
||||
List<AtlasAdminPermission> ret = null;
|
||||
|
||||
if (authzPolicy != null && roleName != null) {
|
||||
AtlasAuthzRole role = authzPolicy.getRoles().get(roleName);
|
||||
|
||||
ret = role != null ? role.getAdminPermissions() : null;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private List<AtlasTypePermission> getTypePermissionsForRole(String roleName) {
|
||||
List<AtlasTypePermission> ret = null;
|
||||
|
||||
if (authzPolicy != null && roleName != null) {
|
||||
AtlasAuthzRole role = authzPolicy.getRoles().get(roleName);
|
||||
|
||||
ret = role != null ? role.getTypePermissions() : null;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private List<AtlasEntityPermission> getEntityPermissionsForRole(String roleName) {
|
||||
List<AtlasEntityPermission> ret = null;
|
||||
|
||||
if (authzPolicy != null && roleName != null) {
|
||||
AtlasAuthzRole role = authzPolicy.getRoles().get(roleName);
|
||||
|
||||
ret = role != null ? role.getEntityPermissions() : null;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private boolean isMatch(String value, List<String> patterns) {
|
||||
boolean ret = false;
|
||||
|
||||
if (value == null) {
|
||||
ret = true;
|
||||
} if (CollectionUtils.isNotEmpty(patterns)) {
|
||||
for (String pattern : patterns) {
|
||||
if (isMatch(value, pattern)) {
|
||||
ret = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret && LOG.isDebugEnabled()) {
|
||||
LOG.debug("<== isMatch({}, {}): {}", value, patterns, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private boolean isMatchAny(Set<String> values, List<String> patterns) {
|
||||
boolean ret = false;
|
||||
|
||||
if (CollectionUtils.isEmpty(values)) {
|
||||
ret = true;
|
||||
}if (CollectionUtils.isNotEmpty(patterns)) {
|
||||
for (String value : values) {
|
||||
if (isMatch(value, patterns)) {
|
||||
ret = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret && LOG.isDebugEnabled()) {
|
||||
LOG.debug("<== isMatchAny({}, {}): {}", values, patterns, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private boolean isMatch(String value, String pattern) {
|
||||
boolean ret;
|
||||
|
||||
if (value == null) {
|
||||
ret = true;
|
||||
} else {
|
||||
ret = StringUtils.equalsIgnoreCase(value, pattern) || value.matches(pattern);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,255 @@
|
|||
/** 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.simple;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE;
|
||||
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.PUBLIC_ONLY;
|
||||
|
||||
@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE)
|
||||
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
|
||||
@JsonIgnoreProperties(ignoreUnknown=true)
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.PROPERTY)
|
||||
public class AtlasSimpleAuthzPolicy implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Map<String, AtlasAuthzRole> roles;
|
||||
private Map<String, List<String>> userRoles;
|
||||
private Map<String, List<String>> groupRoles;
|
||||
|
||||
|
||||
public Map<String, AtlasAuthzRole> getRoles() {
|
||||
return roles;
|
||||
}
|
||||
|
||||
public void setRoles(Map<String, AtlasAuthzRole> roles) {
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
public Map<String, List<String>> getUserRoles() {
|
||||
return userRoles;
|
||||
}
|
||||
|
||||
public void setUserRoles(Map<String, List<String>> userRoles) {
|
||||
this.userRoles = userRoles;
|
||||
}
|
||||
|
||||
public Map<String, List<String>> getGroupRoles() {
|
||||
return groupRoles;
|
||||
}
|
||||
|
||||
public void setGroupRoles(Map<String, List<String>> groupRoles) {
|
||||
this.groupRoles = groupRoles;
|
||||
}
|
||||
|
||||
|
||||
@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE)
|
||||
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
|
||||
@JsonIgnoreProperties(ignoreUnknown=true)
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.PROPERTY)
|
||||
public static class AtlasAuthzRole implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private List<AtlasAdminPermission> adminPermissions;
|
||||
private List<AtlasEntityPermission> entityPermissions;
|
||||
private List<AtlasTypePermission> typePermissions;
|
||||
|
||||
public AtlasAuthzRole() {
|
||||
}
|
||||
|
||||
public AtlasAuthzRole(List<AtlasAdminPermission> adminPermissions, List<AtlasEntityPermission> entityPermissions, List<AtlasTypePermission> typePermissions) {
|
||||
this.adminPermissions = adminPermissions;
|
||||
this.entityPermissions = entityPermissions;
|
||||
this.typePermissions = typePermissions;
|
||||
}
|
||||
|
||||
public List<AtlasAdminPermission> getAdminPermissions() {
|
||||
return adminPermissions;
|
||||
}
|
||||
|
||||
public void setAdminPermissions(List<AtlasAdminPermission> adminPermissions) {
|
||||
this.adminPermissions = adminPermissions;
|
||||
}
|
||||
|
||||
public List<AtlasEntityPermission> getEntityPermissions() {
|
||||
return entityPermissions;
|
||||
}
|
||||
|
||||
public void setEntityPermissions(List<AtlasEntityPermission> entityPermissions) {
|
||||
this.entityPermissions = entityPermissions;
|
||||
}
|
||||
|
||||
public List<AtlasTypePermission> getTypePermissions() {
|
||||
return typePermissions;
|
||||
}
|
||||
|
||||
public void setTypePermissions(List<AtlasTypePermission> typePermissions) {
|
||||
this.typePermissions = typePermissions;
|
||||
}
|
||||
}
|
||||
|
||||
@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE)
|
||||
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
|
||||
@JsonIgnoreProperties(ignoreUnknown=true)
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.PROPERTY)
|
||||
public static class AtlasAdminPermission implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private List<String> privileges; // name of AtlasPrivilege enum, wildcards supported
|
||||
|
||||
public AtlasAdminPermission() {
|
||||
}
|
||||
|
||||
public AtlasAdminPermission(List<String> privileges) {
|
||||
this.privileges = privileges;
|
||||
}
|
||||
|
||||
public List<String> getPrivileges() {
|
||||
return privileges;
|
||||
}
|
||||
|
||||
public void setPrivileges(List<String> privileges) {
|
||||
this.privileges = privileges;
|
||||
}
|
||||
}
|
||||
|
||||
@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE)
|
||||
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
|
||||
@JsonIgnoreProperties(ignoreUnknown=true)
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.PROPERTY)
|
||||
public static class AtlasTypePermission implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private List<String> privileges; // name of AtlasPrivilege enum, wildcards supported
|
||||
private List<String> typeCategories; // category of the type (entity, classification, struct, enum, relationship), wildcards supported
|
||||
private List<String> typeNames; // name of type, wildcards supported
|
||||
|
||||
public AtlasTypePermission() {
|
||||
}
|
||||
|
||||
public AtlasTypePermission(List<String> privileges, List<String> typeCategories, List<String> typeNames) {
|
||||
this.privileges = privileges;
|
||||
this.typeCategories = typeCategories;
|
||||
this.typeNames = typeNames;
|
||||
}
|
||||
|
||||
public List<String> getPrivileges() {
|
||||
return privileges;
|
||||
}
|
||||
|
||||
public void setPrivileges(List<String> privileges) {
|
||||
this.privileges = privileges;
|
||||
}
|
||||
|
||||
public List<String> getTypeCategories() {
|
||||
return typeCategories;
|
||||
}
|
||||
|
||||
public void setTypeCategories(List<String> typeCategories) {
|
||||
this.typeCategories = typeCategories;
|
||||
}
|
||||
|
||||
public List<String> getTypeNames() {
|
||||
return typeNames;
|
||||
}
|
||||
|
||||
public void setTypeNames(List<String> typeNames) {
|
||||
this.typeNames = typeNames;
|
||||
}
|
||||
}
|
||||
|
||||
@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE)
|
||||
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
|
||||
@JsonIgnoreProperties(ignoreUnknown=true)
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.PROPERTY)
|
||||
public static class AtlasEntityPermission implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private List<String> privileges; // name of AtlasPrivilege enum, wildcards supported
|
||||
private List<String> entityTypes; // name of entity-type, wildcards supported
|
||||
private List<String> entityIds; // value of entity-unique attribute, wildcards supported
|
||||
private List<String> classifications; // name of classification-type, wildcards supported
|
||||
private List<String> attributes; // name of entity-attribute, wildcards supported
|
||||
|
||||
public AtlasEntityPermission() {
|
||||
}
|
||||
|
||||
public AtlasEntityPermission(List<String> privileges, List<String> entityTypes, List<String> entityIds, List<String> classifications, List<String> attributes) {
|
||||
this.privileges = privileges;
|
||||
this.entityTypes = entityTypes;
|
||||
this.entityIds = entityIds;
|
||||
this.classifications = classifications;
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
public List<String> getPrivileges() {
|
||||
return privileges;
|
||||
}
|
||||
|
||||
public void setPrivileges(List<String> privileges) {
|
||||
this.privileges = privileges;
|
||||
}
|
||||
|
||||
public List<String> getEntityTypes() {
|
||||
return entityTypes;
|
||||
}
|
||||
|
||||
public void setEntityTypes(List<String> entityTypes) {
|
||||
this.entityTypes = entityTypes;
|
||||
}
|
||||
|
||||
public List<String> getEntityIds() {
|
||||
return entityIds;
|
||||
}
|
||||
|
||||
public void setEntityIds(List<String> entityIds) {
|
||||
this.entityIds = entityIds;
|
||||
}
|
||||
|
||||
public List<String> getClassifications() {
|
||||
return classifications;
|
||||
}
|
||||
|
||||
public void setClassifications(List<String> classifications) {
|
||||
this.classifications = classifications;
|
||||
}
|
||||
|
||||
public List<String> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public void setAttributes(List<String> attributes) {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
/**
|
||||
* 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.simple;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class FileReaderUtil {
|
||||
private static Logger LOG = LoggerFactory.getLogger(FileReaderUtil.class);
|
||||
private static boolean isDebugEnabled = LOG.isDebugEnabled();
|
||||
|
||||
public static List<String> readFile(InputStream policyStoreStream) throws IOException {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("==> FileReaderUtil readFile()");
|
||||
}
|
||||
List<String> list = new ArrayList<>();
|
||||
List<String> fileLines = IOUtils.readLines(policyStoreStream, StandardCharsets.UTF_8);
|
||||
if (fileLines != null) {
|
||||
for (String line : fileLines) {
|
||||
if ((!line.startsWith("#")) && Pattern.matches(".+;;.*;;.*;;.+", line))
|
||||
list.add(line);
|
||||
}
|
||||
}
|
||||
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("<== FileReaderUtil readFile()");
|
||||
LOG.debug("Policies read :: " + list);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
/** 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.simple;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.atlas.authorize.AtlasActionTypes;
|
||||
import org.apache.atlas.authorize.AtlasResourceTypes;
|
||||
|
||||
public class PolicyDef {
|
||||
|
||||
private String policyName;
|
||||
private Map<String, List<AtlasActionTypes>> users;
|
||||
private Map<String, List<AtlasActionTypes>> groups;
|
||||
private Map<AtlasResourceTypes, List<String>> resources;
|
||||
|
||||
public String getPolicyName() {
|
||||
return policyName;
|
||||
}
|
||||
|
||||
public void setPolicyName(String policyName) {
|
||||
this.policyName = policyName;
|
||||
}
|
||||
|
||||
public Map<String, List<AtlasActionTypes>> getUsers() {
|
||||
return users;
|
||||
}
|
||||
|
||||
public void setUsers(Map<String, List<AtlasActionTypes>> users) {
|
||||
this.users = users;
|
||||
}
|
||||
|
||||
public Map<String, List<AtlasActionTypes>> getGroups() {
|
||||
return groups;
|
||||
}
|
||||
|
||||
public void setGroups(Map<String, List<AtlasActionTypes>> groups) {
|
||||
this.groups = groups;
|
||||
}
|
||||
|
||||
public Map<AtlasResourceTypes, List<String>> getResources() {
|
||||
return resources;
|
||||
}
|
||||
|
||||
public void setResources(Map<AtlasResourceTypes, List<String>> resources) {
|
||||
this.resources = resources;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PolicyDef [policyName=" + policyName + ", users=" + users + ", groups=" + groups + ", resources="
|
||||
+ resources + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,252 +0,0 @@
|
|||
/**
|
||||
* 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.simple;
|
||||
|
||||
import org.apache.atlas.authorize.AtlasActionTypes;
|
||||
import org.apache.atlas.authorize.AtlasResourceTypes;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class PolicyParser {
|
||||
|
||||
private static Logger LOG = LoggerFactory.getLogger(PolicyParser.class);
|
||||
private static boolean isDebugEnabled = LOG.isDebugEnabled();
|
||||
public static final int POLICYNAME = 0;
|
||||
|
||||
public static final int USER_INDEX = 1;
|
||||
public static final int USERNAME = 0;
|
||||
public static final int USER_AUTHORITIES = 1;
|
||||
|
||||
public static final int GROUP_INDEX = 2;
|
||||
public static final int GROUPNAME = 0;
|
||||
public static final int GROUP_AUTHORITIES = 1;
|
||||
|
||||
public static final int RESOURCE_INDEX = 3;
|
||||
public static final int RESOURCE_TYPE = 0;
|
||||
public static final int RESOURCE_NAME = 1;
|
||||
|
||||
private List<AtlasActionTypes> getListOfAutorities(String auth) {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("==> PolicyParser getListOfAutorities");
|
||||
}
|
||||
List<AtlasActionTypes> authorities = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < auth.length(); i++) {
|
||||
char access = auth.toLowerCase().charAt(i);
|
||||
switch (access) {
|
||||
case 'r':
|
||||
authorities.add(AtlasActionTypes.READ);
|
||||
break;
|
||||
case 'w':
|
||||
authorities.add(AtlasActionTypes.CREATE);
|
||||
break;
|
||||
case 'u':
|
||||
authorities.add(AtlasActionTypes.UPDATE);
|
||||
break;
|
||||
case 'd':
|
||||
authorities.add(AtlasActionTypes.DELETE);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (LOG.isErrorEnabled()) {
|
||||
LOG.error("Invalid action: '{}'", access);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("<== PolicyParser getListOfAutorities");
|
||||
}
|
||||
return authorities;
|
||||
}
|
||||
|
||||
public List<PolicyDef> parsePolicies(List<String> policies) {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("==> PolicyParser parsePolicies");
|
||||
}
|
||||
List<PolicyDef> policyDefs = new ArrayList<>();
|
||||
for (String policy : policies) {
|
||||
PolicyDef policyDef = parsePolicy(policy);
|
||||
if (policyDef != null) {
|
||||
policyDefs.add(policyDef);
|
||||
}
|
||||
}
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("<== PolicyParser parsePolicies");
|
||||
LOG.debug(policyDefs.toString());
|
||||
}
|
||||
return policyDefs;
|
||||
}
|
||||
|
||||
private PolicyDef parsePolicy(String data) {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("==> PolicyParser parsePolicy");
|
||||
}
|
||||
PolicyDef def = null;
|
||||
String[] props = data.split(";;");
|
||||
|
||||
if (props.length < RESOURCE_INDEX) {
|
||||
LOG.warn("skipping invalid policy line: {}", data);
|
||||
} else {
|
||||
def = new PolicyDef();
|
||||
def.setPolicyName(props[POLICYNAME]);
|
||||
parseUsers(props[USER_INDEX], def);
|
||||
parseGroups(props[GROUP_INDEX], def);
|
||||
parseResources(props[RESOURCE_INDEX], def);
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("policy successfully parsed!!!");
|
||||
LOG.debug("<== PolicyParser parsePolicy");
|
||||
}
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
private boolean validateEntity(String entity) {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("==> PolicyParser validateEntity");
|
||||
}
|
||||
boolean isValidEntity = Pattern.matches("(.+:.+)+", entity);
|
||||
boolean isEmpty = entity.isEmpty();
|
||||
if (!isValidEntity || isEmpty) {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("group/user/resource not properly define in Policy");
|
||||
LOG.debug("<== PolicyParser validateEntity");
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("<== PolicyParser validateEntity");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void parseUsers(String usersDef, PolicyDef def) {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("==> PolicyParser parseUsers");
|
||||
}
|
||||
String[] users = usersDef.split(",");
|
||||
String[] userAndRole = null;
|
||||
Map<String, List<AtlasActionTypes>> usersMap = new HashMap<>();
|
||||
if (validateEntity(usersDef)) {
|
||||
for (String user : users) {
|
||||
if (!Pattern.matches("(.+:.+)+", user)) {
|
||||
continue;
|
||||
}
|
||||
userAndRole = user.split(":");
|
||||
if (def.getUsers() != null) {
|
||||
usersMap = def.getUsers();
|
||||
}
|
||||
List<AtlasActionTypes> userAutorities = getListOfAutorities(userAndRole[USER_AUTHORITIES]);
|
||||
usersMap.put(userAndRole[USERNAME], userAutorities);
|
||||
def.setUsers(usersMap);
|
||||
}
|
||||
|
||||
} else {
|
||||
def.setUsers(usersMap);
|
||||
}
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("<== PolicyParser parseUsers");
|
||||
}
|
||||
}
|
||||
|
||||
private void parseGroups(String groupsDef, PolicyDef def) {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("==> PolicyParser parseGroups");
|
||||
}
|
||||
String[] groups = groupsDef.split("\\,");
|
||||
String[] groupAndRole = null;
|
||||
Map<String, List<AtlasActionTypes>> groupsMap = new HashMap<>();
|
||||
if (validateEntity(groupsDef.trim())) {
|
||||
for (String group : groups) {
|
||||
if (!Pattern.matches("(.+:.+)+", group)) {
|
||||
continue;
|
||||
}
|
||||
groupAndRole = group.split("[:]");
|
||||
if (def.getGroups() != null) {
|
||||
groupsMap = def.getGroups();
|
||||
}
|
||||
List<AtlasActionTypes> groupAutorities = getListOfAutorities(groupAndRole[GROUP_AUTHORITIES]);
|
||||
groupsMap.put(groupAndRole[GROUPNAME], groupAutorities);
|
||||
def.setGroups(groupsMap);
|
||||
}
|
||||
|
||||
} else {
|
||||
def.setGroups(groupsMap);
|
||||
}
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("<== PolicyParser parseGroups");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void parseResources(String resourceDef, PolicyDef def) {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("==> PolicyParser parseResources");
|
||||
}
|
||||
String[] resources = resourceDef.split(",");
|
||||
String[] resourceTypeAndName = null;
|
||||
Map<AtlasResourceTypes, List<String>> resourcesMap = new HashMap<>();
|
||||
if (validateEntity(resourceDef)) {
|
||||
for (String resource : resources) {
|
||||
if (!Pattern.matches("(.+:.+)+", resource)) {
|
||||
continue;
|
||||
}
|
||||
resourceTypeAndName = resource.split("[:]");
|
||||
if (def.getResources() != null) {
|
||||
resourcesMap = def.getResources();
|
||||
}
|
||||
AtlasResourceTypes resourceType = null;
|
||||
String type = resourceTypeAndName[RESOURCE_TYPE].toUpperCase();
|
||||
if (type.equalsIgnoreCase("ENTITY")) {
|
||||
resourceType = AtlasResourceTypes.ENTITY;
|
||||
} else if (type.equalsIgnoreCase("OPERATION")) {
|
||||
resourceType = AtlasResourceTypes.OPERATION;
|
||||
} else if (type.equalsIgnoreCase("TYPE")) {
|
||||
resourceType = AtlasResourceTypes.TYPE;
|
||||
} else if (type.equalsIgnoreCase("RELATIONSHIP")) {
|
||||
resourceType = AtlasResourceTypes.RELATIONSHIP;
|
||||
} else {
|
||||
LOG.warn(type + " is invalid resource please check PolicyStore file");
|
||||
continue;
|
||||
}
|
||||
|
||||
List<String> resourceList = resourcesMap.get(resourceType);
|
||||
if (resourceList == null) {
|
||||
resourceList = new ArrayList<>();
|
||||
}
|
||||
resourceList.add(resourceTypeAndName[RESOURCE_NAME]);
|
||||
resourcesMap.put(resourceType, resourceList);
|
||||
def.setResources(resourcesMap);
|
||||
}
|
||||
} else {
|
||||
def.setResources(resourcesMap);
|
||||
}
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("<== PolicyParser parseResources");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
/** 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.simple;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.atlas.authorize.AtlasActionTypes;
|
||||
import org.apache.atlas.authorize.AtlasResourceTypes;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class PolicyUtil {
|
||||
|
||||
private static Logger LOG = LoggerFactory.getLogger(PolicyUtil.class);
|
||||
private static boolean isDebugEnabled = LOG.isDebugEnabled();
|
||||
|
||||
|
||||
public static Map<String, Map<AtlasResourceTypes, List<String>>> createPermissionMap(List<PolicyDef> policyDefList,
|
||||
AtlasActionTypes permissionType, SimpleAtlasAuthorizer.AtlasAccessorTypes principalType) {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("==> PolicyUtil createPermissionMap\nCreating Permission Map for :: {} & {}", permissionType, principalType);
|
||||
}
|
||||
Map<String, Map<AtlasResourceTypes, List<String>>> userReadMap =
|
||||
new HashMap<>();
|
||||
|
||||
// Iterate over the list of policies to create map
|
||||
for (PolicyDef policyDef : policyDefList) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Processing policy def : {}", policyDef);
|
||||
}
|
||||
|
||||
Map<String, List<AtlasActionTypes>> principalMap =
|
||||
principalType.equals(SimpleAtlasAuthorizer.AtlasAccessorTypes.USER) ? policyDef.getUsers() : policyDef
|
||||
.getGroups();
|
||||
// For every policy extract the resource list and populate the user map
|
||||
for (Entry<String, List<AtlasActionTypes>> e : principalMap.entrySet()) {
|
||||
// Check if the user has passed permission type like READ
|
||||
if (!e.getValue().contains(permissionType)) {
|
||||
continue;
|
||||
}
|
||||
// See if the current user is already added to map
|
||||
String username = e.getKey();
|
||||
Map<AtlasResourceTypes, List<String>> userResourceList = userReadMap.get(username);
|
||||
|
||||
// If its not added then create a new resource list
|
||||
if (userResourceList == null) {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("Resource list not found for {}, creating it", username);
|
||||
}
|
||||
userResourceList = new HashMap<>();
|
||||
}
|
||||
/*
|
||||
* Iterate over resources from the current policy def and update the resource list for the current user
|
||||
*/
|
||||
for (Entry<AtlasResourceTypes, List<String>> resourceTypeMap : policyDef.getResources().entrySet()) {
|
||||
// For the current resourceType in the policyDef, get the
|
||||
// current list of resources already added
|
||||
AtlasResourceTypes type = resourceTypeMap.getKey();
|
||||
List<String> resourceList = userResourceList.get(type);
|
||||
|
||||
if (resourceList == null) {
|
||||
// if the resource list was not added for this type then
|
||||
// create and add all the resources in this policy
|
||||
resourceList = new ArrayList<>();
|
||||
resourceList.addAll(resourceTypeMap.getValue());
|
||||
} else {
|
||||
// if the resource list is present then merge both the
|
||||
// list
|
||||
resourceList.removeAll(resourceTypeMap.getValue());
|
||||
resourceList.addAll(resourceTypeMap.getValue());
|
||||
}
|
||||
|
||||
userResourceList.put(type, resourceList);
|
||||
}
|
||||
userReadMap.put(username, userResourceList);
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("userReadMap {}", userReadMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("Returning Map for {} :: {}", principalType, userReadMap);
|
||||
LOG.debug("<== PolicyUtil createPermissionMap");
|
||||
}
|
||||
return userReadMap;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,381 +0,0 @@
|
|||
/**
|
||||
* 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.simple;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.atlas.ApplicationProperties;
|
||||
import org.apache.atlas.AtlasException;
|
||||
import org.apache.atlas.authorize.AtlasAccessRequest;
|
||||
import org.apache.atlas.authorize.AtlasActionTypes;
|
||||
import org.apache.atlas.authorize.AtlasAuthorizationException;
|
||||
import org.apache.atlas.authorize.AtlasAuthorizer;
|
||||
import org.apache.atlas.authorize.AtlasResourceTypes;
|
||||
import org.apache.atlas.utils.PropertiesUtil;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.io.IOCase;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
public final class SimpleAtlasAuthorizer implements AtlasAuthorizer {
|
||||
|
||||
public enum AtlasAccessorTypes {
|
||||
USER, GROUP
|
||||
}
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SimpleAtlasAuthorizer.class);
|
||||
private boolean isDebugEnabled = LOG.isDebugEnabled();
|
||||
private final static String WILDCARD_ASTERISK = "*";
|
||||
private final static String WILDCARDS = "*?";
|
||||
private boolean optIgnoreCase = false;
|
||||
|
||||
private Map<String, Map<AtlasResourceTypes, List<String>>> userReadMap = null;
|
||||
private Map<String, Map<AtlasResourceTypes, List<String>>> userWriteMap = null;
|
||||
private Map<String, Map<AtlasResourceTypes, List<String>>> userUpdateMap = null;
|
||||
private Map<String, Map<AtlasResourceTypes, List<String>>> userDeleteMap = null;
|
||||
private Map<String, Map<AtlasResourceTypes, List<String>>> groupReadMap = null;
|
||||
private Map<String, Map<AtlasResourceTypes, List<String>>> groupWriteMap = null;
|
||||
private Map<String, Map<AtlasResourceTypes, List<String>>> groupUpdateMap = null;
|
||||
private Map<String, Map<AtlasResourceTypes, List<String>>> groupDeleteMap = null;
|
||||
|
||||
public SimpleAtlasAuthorizer() {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("==> SimpleAtlasAuthorizer init");
|
||||
}
|
||||
try {
|
||||
|
||||
PolicyParser parser = new PolicyParser();
|
||||
optIgnoreCase = Boolean.valueOf(PropertiesUtil.getProperty("optIgnoreCase", "false"));
|
||||
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("Read from PropertiesUtil --> optIgnoreCase :: {}", optIgnoreCase);
|
||||
}
|
||||
|
||||
InputStream policyStoreStream = ApplicationProperties.getFileAsInputStream(ApplicationProperties.get(), "atlas.auth.policy.file", "policy-store.txt");
|
||||
List<String> policies = null;
|
||||
try {
|
||||
policies = FileReaderUtil.readFile(policyStoreStream);
|
||||
}
|
||||
finally {
|
||||
policyStoreStream.close();
|
||||
}
|
||||
List<PolicyDef> policyDef = parser.parsePolicies(policies);
|
||||
|
||||
userReadMap = PolicyUtil.createPermissionMap(policyDef, AtlasActionTypes.READ, AtlasAccessorTypes.USER);
|
||||
userWriteMap = PolicyUtil.createPermissionMap(policyDef, AtlasActionTypes.CREATE, AtlasAccessorTypes.USER);
|
||||
userUpdateMap = PolicyUtil.createPermissionMap(policyDef, AtlasActionTypes.UPDATE, AtlasAccessorTypes.USER);
|
||||
userDeleteMap = PolicyUtil.createPermissionMap(policyDef, AtlasActionTypes.DELETE, AtlasAccessorTypes.USER);
|
||||
|
||||
groupReadMap = PolicyUtil.createPermissionMap(policyDef, AtlasActionTypes.READ, AtlasAccessorTypes.GROUP);
|
||||
groupWriteMap = PolicyUtil.createPermissionMap(policyDef, AtlasActionTypes.CREATE, AtlasAccessorTypes.GROUP);
|
||||
groupUpdateMap = PolicyUtil.createPermissionMap(policyDef, AtlasActionTypes.UPDATE, AtlasAccessorTypes.GROUP);
|
||||
groupDeleteMap = PolicyUtil.createPermissionMap(policyDef, AtlasActionTypes.DELETE, AtlasAccessorTypes.GROUP);
|
||||
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("\n\nUserReadMap :: {}\nGroupReadMap :: {}", userReadMap, groupReadMap);
|
||||
LOG.debug("\n\nUserWriteMap :: {}\nGroupWriteMap :: {}", userWriteMap, groupWriteMap);
|
||||
LOG.debug("\n\nUserUpdateMap :: {}\nGroupUpdateMap :: {}", userUpdateMap, groupUpdateMap);
|
||||
LOG.debug("\n\nUserDeleteMap :: {}\nGroupDeleteMap :: {}", userDeleteMap, groupDeleteMap);
|
||||
}
|
||||
|
||||
} catch (IOException | AtlasException e) {
|
||||
if (LOG.isErrorEnabled()) {
|
||||
LOG.error("SimpleAtlasAuthorizer could not be initialized properly due to : ", e);
|
||||
}
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccessAllowed(AtlasAccessRequest request) throws AtlasAuthorizationException {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("==> SimpleAtlasAuthorizer isAccessAllowed");
|
||||
LOG.debug("isAccessAllowd({})", request);
|
||||
}
|
||||
String user = request.getUser();
|
||||
Set<String> groups = request.getUserGroups();
|
||||
AtlasActionTypes action = request.getAction();
|
||||
String resource = request.getResource();
|
||||
Set<AtlasResourceTypes> resourceTypes = request.getResourceTypes();
|
||||
if (isDebugEnabled)
|
||||
LOG.debug("Checking for :: \nUser :: {}\nGroups :: {}\nAction :: {}\nResource :: {}", user, groups, action, resource);
|
||||
|
||||
boolean isAccessAllowed = false;
|
||||
boolean isUser = user != null;
|
||||
boolean isGroup = groups != null;
|
||||
|
||||
if ((!isUser && !isGroup) || action == null || resource == null) {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("Please check the formation AtlasAccessRequest.");
|
||||
}
|
||||
return isAccessAllowed;
|
||||
} else {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("checkAccess for Operation :: {} on Resource {}:{}", action, resourceTypes, resource);
|
||||
}
|
||||
switch (action) {
|
||||
case READ:
|
||||
isAccessAllowed = checkAccess(user, resourceTypes, resource, userReadMap);
|
||||
isAccessAllowed =
|
||||
isAccessAllowed || checkAccessForGroups(groups, resourceTypes, resource, groupReadMap);
|
||||
break;
|
||||
case CREATE:
|
||||
isAccessAllowed = checkAccess(user, resourceTypes, resource, userWriteMap);
|
||||
isAccessAllowed =
|
||||
isAccessAllowed || checkAccessForGroups(groups, resourceTypes, resource, groupWriteMap);
|
||||
break;
|
||||
case UPDATE:
|
||||
isAccessAllowed = checkAccess(user, resourceTypes, resource, userUpdateMap);
|
||||
isAccessAllowed =
|
||||
isAccessAllowed || checkAccessForGroups(groups, resourceTypes, resource, groupUpdateMap);
|
||||
break;
|
||||
case DELETE:
|
||||
isAccessAllowed = checkAccess(user, resourceTypes, resource, userDeleteMap);
|
||||
isAccessAllowed =
|
||||
isAccessAllowed || checkAccessForGroups(groups, resourceTypes, resource, groupDeleteMap);
|
||||
break;
|
||||
default:
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("Invalid Action {}\nRaising AtlasAuthorizationException!!!", action);
|
||||
}
|
||||
throw new AtlasAuthorizationException("Invalid Action :: " + action);
|
||||
}
|
||||
}
|
||||
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("<== SimpleAtlasAuthorizer isAccessAllowed = {}", isAccessAllowed);
|
||||
}
|
||||
|
||||
return isAccessAllowed;
|
||||
}
|
||||
|
||||
private boolean checkAccess(String accessor, Set<AtlasResourceTypes> resourceTypes, String resource,
|
||||
Map<String, Map<AtlasResourceTypes, List<String>>> map) {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("==> SimpleAtlasAuthorizer checkAccess");
|
||||
LOG.debug("Now checking access for accessor : {}\nResource Types : {}\nResource : {}\nMap : {}", accessor, resourceTypes, resource, map);
|
||||
}
|
||||
boolean result = true;
|
||||
Map<AtlasResourceTypes, List<String>> rescMap = map.get(accessor);
|
||||
if (rescMap != null) {
|
||||
for (AtlasResourceTypes resourceType : resourceTypes) {
|
||||
List<String> accessList = rescMap.get(resourceType);
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("\nChecking for resource : {} in list : {}\n", resource, accessList);
|
||||
}
|
||||
if (accessList != null) {
|
||||
result = result && isMatch(resource, accessList);
|
||||
} else {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result = false;
|
||||
if (isDebugEnabled)
|
||||
LOG.debug("Key {} missing. Returning with result : {}", accessor, result);
|
||||
}
|
||||
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("Check for {} :: {}", accessor, result);
|
||||
LOG.debug("<== SimpleAtlasAuthorizer checkAccess");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean checkAccessForGroups(Set<String> groups, Set<AtlasResourceTypes> resourceType, String resource,
|
||||
Map<String, Map<AtlasResourceTypes, List<String>>> map) {
|
||||
boolean isAccessAllowed = false;
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("==> SimpleAtlasAuthorizer checkAccessForGroups");
|
||||
}
|
||||
|
||||
if(CollectionUtils.isNotEmpty(groups)) {
|
||||
for (String group : groups) {
|
||||
isAccessAllowed = checkAccess(group, resourceType, resource, map);
|
||||
if (isAccessAllowed) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("<== SimpleAtlasAuthorizer checkAccessForGroups");
|
||||
}
|
||||
return isAccessAllowed;
|
||||
}
|
||||
|
||||
private boolean resourceMatchHelper(List<String> policyResource) {
|
||||
boolean isMatchAny = false;
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("==> SimpleAtlasAuthorizer resourceMatchHelper");
|
||||
}
|
||||
|
||||
boolean optWildCard = true;
|
||||
|
||||
List<String> policyValues = new ArrayList<>();
|
||||
|
||||
if (policyResource != null) {
|
||||
boolean isWildCardPresent = !optWildCard;
|
||||
for (String policyValue : policyResource) {
|
||||
if (StringUtils.isEmpty(policyValue)) {
|
||||
continue;
|
||||
}
|
||||
if (StringUtils.containsOnly(policyValue, WILDCARD_ASTERISK)) {
|
||||
isMatchAny = true;
|
||||
} else if (!isWildCardPresent && StringUtils.containsAny(policyValue, WILDCARDS)) {
|
||||
isWildCardPresent = true;
|
||||
}
|
||||
policyValues.add(policyValue);
|
||||
}
|
||||
optWildCard = optWildCard && isWildCardPresent;
|
||||
} else {
|
||||
isMatchAny = false;
|
||||
}
|
||||
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("<== SimpleAtlasAuthorizer resourceMatchHelper");
|
||||
}
|
||||
return isMatchAny;
|
||||
}
|
||||
|
||||
private boolean isMatch(String resource, List<String> policyValues) {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("==> SimpleAtlasAuthorizer isMatch");
|
||||
}
|
||||
boolean isMatchAny = resourceMatchHelper(policyValues);
|
||||
boolean isMatch = false;
|
||||
boolean allValuesRequested = isAllValuesRequested(resource);
|
||||
|
||||
if (allValuesRequested || isMatchAny) {
|
||||
isMatch = isMatchAny;
|
||||
} else {
|
||||
for (String policyValue : policyValues) {
|
||||
if (policyValue.contains("*")) {
|
||||
isMatch =
|
||||
optIgnoreCase ? FilenameUtils.wildcardMatch(resource, policyValue, IOCase.INSENSITIVE)
|
||||
: FilenameUtils.wildcardMatch(resource, policyValue, IOCase.SENSITIVE);
|
||||
} else {
|
||||
isMatch =
|
||||
optIgnoreCase ? StringUtils.equalsIgnoreCase(resource, policyValue) : StringUtils.equals(
|
||||
resource, policyValue);
|
||||
}
|
||||
if (isMatch) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isMatch) {
|
||||
if (isDebugEnabled) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("[");
|
||||
for (String policyValue : policyValues) {
|
||||
sb.append(policyValue);
|
||||
sb.append(" ");
|
||||
}
|
||||
sb.append("]");
|
||||
|
||||
LOG.debug("AtlasDefaultResourceMatcher.isMatch returns FALSE, (resource={}, policyValues={})", resource, sb.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("<== SimpleAtlasAuthorizer isMatch({}): {}", resource, isMatch);
|
||||
}
|
||||
|
||||
return isMatch;
|
||||
}
|
||||
|
||||
private boolean isAllValuesRequested(String resource) {
|
||||
return StringUtils.isEmpty(resource) || WILDCARD_ASTERISK.equals(resource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanUp() {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("==> +SimpleAtlasAuthorizer cleanUp");
|
||||
}
|
||||
userReadMap = null;
|
||||
userWriteMap = null;
|
||||
userUpdateMap = null;
|
||||
userDeleteMap = null;
|
||||
groupReadMap = null;
|
||||
groupWriteMap = null;
|
||||
groupUpdateMap = null;
|
||||
groupDeleteMap = null;
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("<== +SimpleAtlasAuthorizer cleanUp");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE :: This method is added for setting the maps for testing purpose.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public void setResourcesForTesting(Map<String, Map<AtlasResourceTypes, List<String>>> userMap,
|
||||
Map<String, Map<AtlasResourceTypes, List<String>>> groupMap, AtlasActionTypes actionTypes) {
|
||||
|
||||
switch (actionTypes) {
|
||||
case READ:
|
||||
this.userReadMap = userMap;
|
||||
this.groupReadMap = groupMap;
|
||||
break;
|
||||
|
||||
case CREATE:
|
||||
|
||||
this.userWriteMap = userMap;
|
||||
this.groupWriteMap = groupMap;
|
||||
break;
|
||||
case UPDATE:
|
||||
|
||||
this.userUpdateMap = userMap;
|
||||
this.groupUpdateMap = groupMap;
|
||||
break;
|
||||
case DELETE:
|
||||
|
||||
this.userDeleteMap = userMap;
|
||||
this.groupDeleteMap = groupMap;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("No such action available");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
{
|
||||
"roles": {
|
||||
"ROLE_ADMIN": {
|
||||
"adminPermissions": [
|
||||
{
|
||||
"privileges": [ ".*" ]
|
||||
}
|
||||
],
|
||||
|
||||
"entityPermissions": [
|
||||
{
|
||||
"privileges": [ ".*" ],
|
||||
"entityTypes": [ ".*" ],
|
||||
"entityIds": [ ".*" ],
|
||||
"classifications": [ ".*" ]
|
||||
}
|
||||
],
|
||||
|
||||
"typePermissions": [
|
||||
{
|
||||
"privileges": [ ".*" ],
|
||||
"typeCategories": [ ".*" ],
|
||||
"typeNames": [ ".*" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"DATA_SCIENTIST": {
|
||||
"entityPermissions": [
|
||||
{
|
||||
"privileges": [ "entity-read", "entity-read-classification" ],
|
||||
"entityTypes": [ ".*" ],
|
||||
"entityIds": [ ".*" ],
|
||||
"classifications": [ ".*" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"DATA_STEWARD": {
|
||||
"entityPermissions": [
|
||||
{
|
||||
"privileges": [ "entity-read", "entity-create", "entity-update", "entity-read-classification", "entity-add-classification", "entity-update-classification", "entity-remove-classification" ],
|
||||
"entityTypes": [ ".*" ],
|
||||
"entityIds": [ ".*" ],
|
||||
"classifications": [ ".*" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
"userRoles": {
|
||||
"admin": [ "ROLE_ADMIN" ]
|
||||
},
|
||||
|
||||
"groupRoles": {
|
||||
"ROLE_ADMIN": [ "ROLE_ADMIN" ],
|
||||
"hadoop": [ "DATA_STEWARD" ],
|
||||
"DATA_STEWARD": [ "DATA_STEWARD" ],
|
||||
"RANGER_TAG_SYNC": [ "DATA_SCIENTIST" ]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
/**
|
||||
* 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.simple;
|
||||
|
||||
import org.apache.atlas.authorize.AtlasResourceTypes;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Unit tests for AtlasAuthorizationUtils.
|
||||
*/
|
||||
public class AtlasAuthorizationUtilsTest {
|
||||
@Test
|
||||
public void testGetApi() {
|
||||
String contextPath = "/api/atlas/entities";
|
||||
assertEquals(AtlasAuthorizationUtils.getApi(contextPath), "entities");
|
||||
|
||||
contextPath = "/api/atlas/entities/111/traits";
|
||||
assertEquals(AtlasAuthorizationUtils.getApi(contextPath), "entities");
|
||||
|
||||
contextPath = "/api/atlas/v1/entities";
|
||||
assertEquals(AtlasAuthorizationUtils.getApi(contextPath), "entities");
|
||||
|
||||
contextPath = "/api/atlas/v1/entities/111/tags";
|
||||
assertEquals(AtlasAuthorizationUtils.getApi(contextPath), "entities");
|
||||
|
||||
// not sure of this use case but the code appears to support url's that don't
|
||||
// begin with base url.
|
||||
contextPath = "/foo/bar";
|
||||
assertEquals(AtlasAuthorizationUtils.getApi(contextPath), "foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAtlasResourceType() throws Exception {
|
||||
String contextPath = "/api/atlas/types";
|
||||
Set<AtlasResourceTypes> resourceTypes = AtlasAuthorizationUtils.getAtlasResourceType(contextPath);
|
||||
assertEquals(resourceTypes.size(), 1);
|
||||
assertTrue(resourceTypes.contains(AtlasResourceTypes.TYPE));
|
||||
|
||||
contextPath = "/api/atlas/admin/foo";
|
||||
resourceTypes = AtlasAuthorizationUtils.getAtlasResourceType(contextPath);
|
||||
assertEquals(resourceTypes.size(), 1);
|
||||
assertTrue(resourceTypes.contains(AtlasResourceTypes.OPERATION));
|
||||
|
||||
contextPath = "/api/atlas/graph/foo";
|
||||
resourceTypes = AtlasAuthorizationUtils.getAtlasResourceType(contextPath);
|
||||
assertEquals(resourceTypes.size(), 1);
|
||||
assertTrue(resourceTypes.contains(AtlasResourceTypes.OPERATION));
|
||||
|
||||
contextPath = "/api/atlas/discovery/search/gremlin";
|
||||
resourceTypes = AtlasAuthorizationUtils.getAtlasResourceType(contextPath);
|
||||
assertEquals(resourceTypes.size(), 1);
|
||||
assertTrue(resourceTypes.contains(AtlasResourceTypes.OPERATION));
|
||||
|
||||
contextPath = "/api/atlas/entities/111/traits";
|
||||
resourceTypes = AtlasAuthorizationUtils.getAtlasResourceType(contextPath);
|
||||
assertEquals(resourceTypes.size(), 1);
|
||||
assertTrue(resourceTypes.contains(AtlasResourceTypes.ENTITY));
|
||||
|
||||
contextPath = "/api/atlas/discovery/search";
|
||||
resourceTypes = AtlasAuthorizationUtils.getAtlasResourceType(contextPath);
|
||||
assertEquals(resourceTypes.size(), 1);
|
||||
assertTrue(resourceTypes.contains(AtlasResourceTypes.ENTITY));
|
||||
|
||||
contextPath = "/api/atlas/entities?type=Column";
|
||||
resourceTypes = AtlasAuthorizationUtils.getAtlasResourceType(contextPath);
|
||||
assertEquals(resourceTypes.size(), 1);
|
||||
assertTrue(resourceTypes.contains(AtlasResourceTypes.ENTITY));
|
||||
|
||||
contextPath = "/api/atlas/lineage";
|
||||
resourceTypes = AtlasAuthorizationUtils.getAtlasResourceType(contextPath);
|
||||
assertEquals(resourceTypes.size(), 1);
|
||||
assertTrue(resourceTypes.contains(AtlasResourceTypes.ENTITY));
|
||||
|
||||
contextPath = "/api/atlas/v1/entities/111";
|
||||
resourceTypes = AtlasAuthorizationUtils.getAtlasResourceType(contextPath);
|
||||
assertEquals(resourceTypes.size(), 1);
|
||||
assertTrue(resourceTypes.contains(AtlasResourceTypes.ENTITY));
|
||||
|
||||
contextPath = "/api/atlas/v1/entities/111/tags/foo";
|
||||
resourceTypes = AtlasAuthorizationUtils.getAtlasResourceType(contextPath);
|
||||
assertEquals(resourceTypes.size(), 1);
|
||||
assertTrue(resourceTypes.contains(AtlasResourceTypes.ENTITY));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* 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.simple;
|
||||
|
||||
import org.apache.atlas.authorize.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
import org.testng.AssertJUnit;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
public class AtlasSimpleAuthorizerTest {
|
||||
private static Logger LOG = LoggerFactory.getLogger(AtlasSimpleAuthorizerTest.class);
|
||||
|
||||
private String originalConf;
|
||||
private AtlasAuthorizer authorizer;
|
||||
|
||||
@BeforeMethod
|
||||
public void setup1() {
|
||||
originalConf = System.getProperty("atlas.conf");
|
||||
|
||||
System.setProperty("atlas.conf", "src/test/resources");
|
||||
|
||||
try {
|
||||
authorizer = AtlasAuthorizerFactory.getAtlasAuthorizer();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Exception in AtlasSimpleAuthorizerTest setup failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public void tearDown() throws Exception {
|
||||
if (originalConf != null) {
|
||||
System.setProperty("atlas.conf", originalConf);
|
||||
}
|
||||
|
||||
authorizer = null;
|
||||
}
|
||||
|
||||
@Test(enabled = true)
|
||||
public void testAccessAllowedForUserAndGroup() {
|
||||
try {
|
||||
AtlasEntityAccessRequest request = new AtlasEntityAccessRequest(null, AtlasPrivilege.ENTITY_UPDATE);
|
||||
|
||||
request.setUser("admin", Collections.singleton("ROLE_ADMIN"));
|
||||
|
||||
boolean isAccessAllowed = authorizer.isAccessAllowed(request);
|
||||
|
||||
AssertJUnit.assertEquals(true, isAccessAllowed);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Exception in AtlasSimpleAuthorizerTest", e);
|
||||
|
||||
AssertJUnit.fail();
|
||||
}
|
||||
}
|
||||
|
||||
@Test(enabled = true)
|
||||
public void testAccessAllowedForGroup() {
|
||||
try {
|
||||
AtlasEntityAccessRequest request = new AtlasEntityAccessRequest(null, AtlasPrivilege.ENTITY_UPDATE);
|
||||
|
||||
request.setUser("nonmappeduser", Collections.singleton("ROLE_ADMIN"));
|
||||
|
||||
boolean isAccessAllowed = authorizer.isAccessAllowed(request);
|
||||
|
||||
AssertJUnit.assertEquals(true, isAccessAllowed);
|
||||
} catch (AtlasAuthorizationException e) {
|
||||
LOG.error("Exception in AtlasSimpleAuthorizerTest", e);
|
||||
|
||||
AssertJUnit.fail();
|
||||
}
|
||||
}
|
||||
|
||||
@Test(enabled = true)
|
||||
public void testAccessNotAllowedForUserAndGroup() {
|
||||
try {
|
||||
AtlasEntityAccessRequest request = new AtlasEntityAccessRequest(null, AtlasPrivilege.ENTITY_UPDATE);
|
||||
|
||||
request.setUser("nonmappeduser", Collections.singleton("GROUP-NOT-IN-POLICYFILE"));
|
||||
|
||||
boolean isAccessAllowed = authorizer.isAccessAllowed(request);
|
||||
|
||||
AssertJUnit.assertEquals(false, isAccessAllowed);
|
||||
} catch (AtlasAuthorizationException e) {
|
||||
LOG.error("Exception in AtlasSimpleAuthorizerTest", e);
|
||||
|
||||
AssertJUnit.fail();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,172 +0,0 @@
|
|||
/*
|
||||
* 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.simple;
|
||||
|
||||
import static org.testng.AssertJUnit.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.atlas.authorize.AtlasActionTypes;
|
||||
import org.apache.atlas.authorize.AtlasResourceTypes;
|
||||
import org.apache.atlas.authorize.simple.PolicyDef;
|
||||
import org.apache.atlas.authorize.simple.PolicyParser;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class PolicyParserTest {
|
||||
|
||||
@Test
|
||||
public void testParsePoliciesWithAllProperties() {
|
||||
List<String> policies = new ArrayList<>();
|
||||
policies.add("hivePolicy;;usr1:r,usr2:rw;;grp1:rwu,grp2:u;;entity:*abc,operation:*xyz,type:PII");
|
||||
/* Creating group data */
|
||||
Map<String, List<AtlasActionTypes>> groupMap = new HashMap<>();
|
||||
List<AtlasActionTypes> accessList1 = new ArrayList<>();
|
||||
accessList1.add(AtlasActionTypes.READ);
|
||||
accessList1.add(AtlasActionTypes.CREATE);
|
||||
accessList1.add(AtlasActionTypes.UPDATE);
|
||||
|
||||
groupMap.put("grp1", accessList1);
|
||||
List<AtlasActionTypes> accessList2 = new ArrayList<>();
|
||||
accessList2.add(AtlasActionTypes.UPDATE);
|
||||
groupMap.put("grp2", accessList2);
|
||||
|
||||
/* Creating user data */
|
||||
Map<String, List<AtlasActionTypes>> usersMap = new HashMap<>();
|
||||
List<AtlasActionTypes> usr1AccessList = new ArrayList<>();
|
||||
usr1AccessList.add(AtlasActionTypes.READ);
|
||||
usersMap.put("usr1", usr1AccessList);
|
||||
|
||||
List<AtlasActionTypes> usr2AccessList = new ArrayList<>();
|
||||
usr2AccessList.add(AtlasActionTypes.READ);
|
||||
usr2AccessList.add(AtlasActionTypes.CREATE);
|
||||
usersMap.put("usr2", usr2AccessList);
|
||||
|
||||
/* Creating resources data */
|
||||
Map<AtlasResourceTypes, List<String>> resourceMap = new HashMap<>();
|
||||
List<String> resource1List = new ArrayList<>();
|
||||
resource1List.add("*abc");
|
||||
resourceMap.put(AtlasResourceTypes.ENTITY, resource1List);
|
||||
|
||||
List<String> resource2List = new ArrayList<>();
|
||||
resource2List.add("*xyz");
|
||||
resourceMap.put(AtlasResourceTypes.OPERATION, resource2List);
|
||||
|
||||
List<String> resource3List = new ArrayList<>();
|
||||
resource3List.add("PII");
|
||||
resourceMap.put(AtlasResourceTypes.TYPE, resource3List);
|
||||
|
||||
List<PolicyDef> policyDefs = new PolicyParser().parsePolicies(policies);
|
||||
for (PolicyDef def : policyDefs) {
|
||||
|
||||
assertEquals(def.getPolicyName(), "hivePolicy");
|
||||
assertEquals(def.getGroups(), groupMap);
|
||||
assertEquals(def.getUsers(), usersMap);
|
||||
assertEquals(def.getResources(), resourceMap);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParsePoliciesWithOutUserProperties() {
|
||||
List<String> policies = new ArrayList<>();
|
||||
policies.add("hivePolicy;;;;grp1:rwu,grp2:u;;entity:*abc,operation:*xyz,type:PII");
|
||||
// Creating group data
|
||||
Map<String, List<AtlasActionTypes>> groupMap = new HashMap<>();
|
||||
List<AtlasActionTypes> accessList1 = new ArrayList<>();
|
||||
accessList1.add(AtlasActionTypes.READ);
|
||||
accessList1.add(AtlasActionTypes.CREATE);
|
||||
accessList1.add(AtlasActionTypes.UPDATE);
|
||||
|
||||
groupMap.put("grp1", accessList1);
|
||||
List<AtlasActionTypes> accessList2 = new ArrayList<>();
|
||||
accessList2.add(AtlasActionTypes.UPDATE);
|
||||
groupMap.put("grp2", accessList2);
|
||||
|
||||
// Creating user data
|
||||
Map<String, List<AtlasActionTypes>> usersMap = new HashMap<>();
|
||||
|
||||
// Creating resources data
|
||||
Map<AtlasResourceTypes, List<String>> resourceMap = new HashMap<>();
|
||||
List<String> resource1List = new ArrayList<>();
|
||||
resource1List.add("*abc");
|
||||
resourceMap.put(AtlasResourceTypes.ENTITY, resource1List);
|
||||
|
||||
List<String> resource2List = new ArrayList<>();
|
||||
resource2List.add("*xyz");
|
||||
resourceMap.put(AtlasResourceTypes.OPERATION, resource2List);
|
||||
|
||||
List<String> resource3List = new ArrayList<>();
|
||||
resource3List.add("PII");
|
||||
resourceMap.put(AtlasResourceTypes.TYPE, resource3List);
|
||||
|
||||
List<PolicyDef> policyDefs = new PolicyParser().parsePolicies(policies);
|
||||
for (PolicyDef def : policyDefs) {
|
||||
|
||||
assertEquals(def.getPolicyName(), "hivePolicy");
|
||||
assertEquals(def.getGroups(), groupMap);
|
||||
assertEquals(def.getUsers(), usersMap);
|
||||
assertEquals(def.getResources(), resourceMap);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParsePoliciesWithOutGroupProperties() {
|
||||
List<String> policies = new ArrayList<>();
|
||||
policies.add("hivePolicy;;usr1:r,usr2:rw;;;;entity:*abc,operation:*xyz,type:PII");
|
||||
// Creating group data
|
||||
Map<String, List<AtlasActionTypes>> groupMap = new HashMap<>();
|
||||
|
||||
// Creating user data
|
||||
Map<String, List<AtlasActionTypes>> usersMap = new HashMap<>();
|
||||
List<AtlasActionTypes> usr1AccessList = new ArrayList<>();
|
||||
usr1AccessList.add(AtlasActionTypes.READ);
|
||||
usersMap.put("usr1", usr1AccessList);
|
||||
|
||||
List<AtlasActionTypes> usr2AccessList = new ArrayList<>();
|
||||
usr2AccessList.add(AtlasActionTypes.READ);
|
||||
usr2AccessList.add(AtlasActionTypes.CREATE);
|
||||
usersMap.put("usr2", usr2AccessList);
|
||||
|
||||
// Creating resources data
|
||||
Map<AtlasResourceTypes, List<String>> resourceMap = new HashMap<>();
|
||||
List<String> resource1List = new ArrayList<>();
|
||||
resource1List.add("*abc");
|
||||
resourceMap.put(AtlasResourceTypes.ENTITY, resource1List);
|
||||
|
||||
List<String> resource2List = new ArrayList<>();
|
||||
resource2List.add("*xyz");
|
||||
resourceMap.put(AtlasResourceTypes.OPERATION, resource2List);
|
||||
|
||||
List<String> resource3List = new ArrayList<>();
|
||||
resource3List.add("PII");
|
||||
resourceMap.put(AtlasResourceTypes.TYPE, resource3List);
|
||||
|
||||
List<PolicyDef> policyDefs = new PolicyParser().parsePolicies(policies);
|
||||
for (PolicyDef def : policyDefs) {
|
||||
assertEquals(def.getPolicyName(), "hivePolicy");
|
||||
assertEquals(def.getGroups(), groupMap);
|
||||
assertEquals(def.getUsers(), usersMap);
|
||||
assertEquals(def.getResources(), resourceMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
/*
|
||||
* 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.simple;
|
||||
|
||||
import static org.testng.AssertJUnit.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.apache.atlas.authorize.simple.SimpleAtlasAuthorizer;
|
||||
import org.apache.atlas.authorize.AtlasActionTypes;
|
||||
import org.apache.atlas.authorize.AtlasResourceTypes;
|
||||
import org.apache.atlas.authorize.simple.PolicyDef;
|
||||
import org.apache.atlas.authorize.simple.PolicyParser;
|
||||
import org.apache.atlas.authorize.simple.PolicyUtil;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class PolicyUtilTest {
|
||||
|
||||
@Test
|
||||
public void testCreatePermissionMap() {
|
||||
|
||||
HashMap<AtlasResourceTypes, List<String>> resourceMap = new HashMap<>();
|
||||
List<String> resource1List = new ArrayList<>();
|
||||
resource1List.add("*abc");
|
||||
resourceMap.put(AtlasResourceTypes.ENTITY, resource1List);
|
||||
|
||||
List<String> resource2List = new ArrayList<>();
|
||||
resource2List.add("*xyz");
|
||||
resourceMap.put(AtlasResourceTypes.OPERATION, resource2List);
|
||||
|
||||
List<String> resource3List = new ArrayList<>();
|
||||
resource3List.add("PII");
|
||||
resourceMap.put(AtlasResourceTypes.TYPE, resource3List);
|
||||
|
||||
Map<String, HashMap<AtlasResourceTypes, List<String>>> permissionMap =
|
||||
new HashMap<>();
|
||||
permissionMap.put("grp1", resourceMap);
|
||||
|
||||
List<String> policies = new ArrayList<>();
|
||||
policies.add("hivePolicy;;usr1:r,usr2:rw;;grp1:rwu,grp2:u;;entity:*abc,operation:*xyz,type:PII");
|
||||
List<PolicyDef> policyDefList = new PolicyParser().parsePolicies(policies);
|
||||
|
||||
Map<String, Map<AtlasResourceTypes, List<String>>> createdPermissionMap =
|
||||
new PolicyUtil().createPermissionMap(policyDefList, AtlasActionTypes.READ, SimpleAtlasAuthorizer.AtlasAccessorTypes.GROUP);
|
||||
|
||||
assertEquals(permissionMap, createdPermissionMap);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergeCreatePermissionMap() {
|
||||
|
||||
HashMap<AtlasResourceTypes, List<String>> resourceMap = new HashMap<>();
|
||||
List<String> resource1List = new ArrayList<>();
|
||||
resource1List.add("*abc");
|
||||
resourceMap.put(AtlasResourceTypes.ENTITY, resource1List);
|
||||
|
||||
List<String> resource2List = new ArrayList<>();
|
||||
resource2List.add("*x");
|
||||
resource2List.add("*xyz");
|
||||
resourceMap.put(AtlasResourceTypes.OPERATION, resource2List);
|
||||
|
||||
List<String> resource3List = new ArrayList<>();
|
||||
resource3List.add("PII");
|
||||
resourceMap.put(AtlasResourceTypes.TYPE, resource3List);
|
||||
|
||||
Map<String, HashMap<AtlasResourceTypes, List<String>>> permissionMap =
|
||||
new HashMap<>();
|
||||
permissionMap.put("grp1", resourceMap);
|
||||
|
||||
List<String> policies = new ArrayList<>();
|
||||
policies.add("hivePolicys;;;;grp1:rwu;;entity:*abc,operation:*xyz,operation:*x");
|
||||
policies.add("hivePolicy;;;;grp1:rwu;;entity:*abc,operation:*xyz");
|
||||
policies.add("hivePolicy;;usr1:r,usr2:rw;;grp1:rwu;;entity:*abc,operation:*xyz");
|
||||
policies.add("hivePolicy;;usr1:r,usr2:rw;;grp1:rwu,grp2:u;;entity:*abc,operation:*xyz,type:PII");
|
||||
List<PolicyDef> policyDefList = new PolicyParser().parsePolicies(policies);
|
||||
|
||||
Map<String, Map<AtlasResourceTypes, List<String>>> createdPermissionMap =
|
||||
new PolicyUtil().createPermissionMap(policyDefList, AtlasActionTypes.READ, SimpleAtlasAuthorizer.AtlasAccessorTypes.GROUP);
|
||||
|
||||
assertEquals(permissionMap, createdPermissionMap);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,208 +0,0 @@
|
|||
/*
|
||||
* 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.simple;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.atlas.authorize.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.testng.AssertJUnit;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class SimpleAtlasAuthorizerTest {
|
||||
|
||||
private static Logger LOG = LoggerFactory
|
||||
.getLogger(SimpleAtlasAuthorizerTest.class);
|
||||
|
||||
@Test
|
||||
public void testAccessAllowedForUserAndGroup() {
|
||||
|
||||
Map<String, Map<AtlasResourceTypes, List<String>>> userReadMap = null;
|
||||
Map<String, Map<AtlasResourceTypes, List<String>>> groupReadMap = null;
|
||||
List<String> policies = new ArrayList<>();
|
||||
policies.add("hivePolicy;;usr1:r,usr2:rw;;grp1:rwu,grp2:u;;type:*abc,type:PII");
|
||||
|
||||
List<PolicyDef> policyDefs = new PolicyParser().parsePolicies(policies);
|
||||
PolicyUtil policyUtil = new PolicyUtil();
|
||||
// group read map
|
||||
groupReadMap = policyUtil.createPermissionMap(policyDefs,
|
||||
AtlasActionTypes.READ, SimpleAtlasAuthorizer.AtlasAccessorTypes.GROUP);
|
||||
// creating user readMap
|
||||
userReadMap = policyUtil.createPermissionMap(policyDefs,
|
||||
AtlasActionTypes.READ, SimpleAtlasAuthorizer.AtlasAccessorTypes.USER);
|
||||
|
||||
Set<AtlasResourceTypes> resourceType = new HashSet<>();
|
||||
resourceType.add(AtlasResourceTypes.TYPE);
|
||||
String resource = "xsdfhjabc";
|
||||
AtlasActionTypes action = AtlasActionTypes.READ;
|
||||
String user = "usr1";
|
||||
|
||||
Set<String> userGroups = new HashSet<>();
|
||||
userGroups.add("grp3");
|
||||
try {
|
||||
AtlasAccessRequest request = new AtlasAccessRequest(resourceType,
|
||||
resource, action, user, userGroups,"127.0.0.1");
|
||||
SimpleAtlasAuthorizer authorizer = (SimpleAtlasAuthorizer) AtlasAuthorizerFactory
|
||||
.getAtlasAuthorizer();
|
||||
|
||||
authorizer
|
||||
.setResourcesForTesting(userReadMap, groupReadMap, action);
|
||||
|
||||
boolean isAccessAllowed = authorizer.isAccessAllowed(request);
|
||||
// getUserReadMap
|
||||
AssertJUnit.assertEquals(true, isAccessAllowed);
|
||||
} catch (AtlasAuthorizationException e) {
|
||||
if (LOG.isErrorEnabled()) {
|
||||
LOG.error("AtlasAuthorizationException in Unit Test", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAccessAllowedForGroup() {
|
||||
|
||||
Map<String, Map<AtlasResourceTypes, List<String>>> userReadMap = null;
|
||||
Map<String, Map<AtlasResourceTypes, List<String>>> groupReadMap = null;
|
||||
List<String> policies = new ArrayList<>();
|
||||
policies.add("hivePolicy;;usr1:r,usr2:rw;;grp1:rwu,grp2:u;;type:PII");
|
||||
|
||||
List<PolicyDef> policyDefs = new PolicyParser().parsePolicies(policies);
|
||||
PolicyUtil policyUtil = new PolicyUtil();
|
||||
// creating group read map
|
||||
groupReadMap = policyUtil.createPermissionMap(policyDefs,
|
||||
AtlasActionTypes.READ, SimpleAtlasAuthorizer.AtlasAccessorTypes.GROUP);
|
||||
// creating user readMap
|
||||
userReadMap = policyUtil.createPermissionMap(policyDefs,
|
||||
AtlasActionTypes.READ, SimpleAtlasAuthorizer.AtlasAccessorTypes.USER);
|
||||
|
||||
Set<AtlasResourceTypes> resourceType = new HashSet<>();
|
||||
resourceType.add(AtlasResourceTypes.TYPE);
|
||||
String resource = "PII";
|
||||
AtlasActionTypes action = AtlasActionTypes.READ;
|
||||
String user = "usr3";
|
||||
Set<String> userGroups = new HashSet<>();
|
||||
userGroups.add("grp1");
|
||||
AtlasAccessRequest request = new AtlasAccessRequest(resourceType,
|
||||
resource, action, user, userGroups,"127.0.0.1");
|
||||
try {
|
||||
SimpleAtlasAuthorizer authorizer = (SimpleAtlasAuthorizer) AtlasAuthorizerFactory
|
||||
.getAtlasAuthorizer();
|
||||
authorizer
|
||||
.setResourcesForTesting(userReadMap, groupReadMap, action);
|
||||
|
||||
boolean isAccessAllowed = authorizer.isAccessAllowed(request);
|
||||
AssertJUnit.assertEquals(true, isAccessAllowed);
|
||||
} catch (AtlasAuthorizationException e) {
|
||||
if (LOG.isErrorEnabled()) {
|
||||
LOG.error("AtlasAuthorizationException in Unit Test", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResourceNotAvailableInPolicy() {
|
||||
|
||||
Map<String, Map<AtlasResourceTypes, List<String>>> userReadMap = null;
|
||||
Map<String, Map<AtlasResourceTypes, List<String>>> groupReadMap = null;
|
||||
List<String> policies = new ArrayList<>();
|
||||
policies.add("hivePolicy;;usr1:r,usr2:rw;;grp1:rwu,grp2:u;;type:PII");
|
||||
|
||||
List<PolicyDef> policyDefs = new PolicyParser().parsePolicies(policies);
|
||||
PolicyUtil policyUtil = new PolicyUtil();
|
||||
// group read map
|
||||
groupReadMap = policyUtil.createPermissionMap(policyDefs,
|
||||
AtlasActionTypes.READ, SimpleAtlasAuthorizer.AtlasAccessorTypes.GROUP);
|
||||
// creating user readMap
|
||||
userReadMap = policyUtil.createPermissionMap(policyDefs,
|
||||
AtlasActionTypes.READ, SimpleAtlasAuthorizer.AtlasAccessorTypes.USER);
|
||||
|
||||
Set<AtlasResourceTypes> resourceType = new HashSet<>();
|
||||
resourceType.add(AtlasResourceTypes.TYPE);
|
||||
String resource = "abc";
|
||||
AtlasActionTypes action = AtlasActionTypes.READ;
|
||||
String user = "usr1";
|
||||
Set<String> userGroups = new HashSet<>();
|
||||
userGroups.add("grp1");
|
||||
AtlasAccessRequest request = new AtlasAccessRequest(resourceType,
|
||||
resource, action, user, userGroups,"127.0.0.1");
|
||||
try {
|
||||
SimpleAtlasAuthorizer authorizer = (SimpleAtlasAuthorizer) AtlasAuthorizerFactory
|
||||
.getAtlasAuthorizer();
|
||||
authorizer
|
||||
.setResourcesForTesting(userReadMap, groupReadMap, action);
|
||||
|
||||
boolean isAccessAllowed = authorizer.isAccessAllowed(request);
|
||||
AssertJUnit.assertEquals(false, isAccessAllowed);
|
||||
} catch (AtlasAuthorizationException e) {
|
||||
if (LOG.isErrorEnabled()) {
|
||||
LOG.error("AtlasAuthorizationException in Unit Test", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAccessNotAllowedForUserAndGroup() {
|
||||
|
||||
Map<String, Map<AtlasResourceTypes, List<String>>> userReadMap = null;
|
||||
Map<String, Map<AtlasResourceTypes, List<String>>> groupReadMap = null;
|
||||
List<String> policies = new ArrayList<>();
|
||||
policies.add("hivePolicy;;usr1:r,usr2:rw;;grp1:rwu,grp2:u;;type:PII");
|
||||
|
||||
List<PolicyDef> policyDefs = new PolicyParser().parsePolicies(policies);
|
||||
PolicyUtil policyUtil = new PolicyUtil();
|
||||
// group read map
|
||||
groupReadMap = policyUtil.createPermissionMap(policyDefs,
|
||||
AtlasActionTypes.READ, SimpleAtlasAuthorizer.AtlasAccessorTypes.GROUP);
|
||||
// creating user readMap
|
||||
userReadMap = policyUtil.createPermissionMap(policyDefs,
|
||||
AtlasActionTypes.READ, SimpleAtlasAuthorizer.AtlasAccessorTypes.USER);
|
||||
|
||||
Set<AtlasResourceTypes> resourceType = new HashSet<>();
|
||||
resourceType.add(AtlasResourceTypes.TYPE);
|
||||
String resource = "PII";
|
||||
AtlasActionTypes action = AtlasActionTypes.READ;
|
||||
String user = "usr3";
|
||||
Set<String> userGroups = new HashSet<>();
|
||||
userGroups.add("grp3");
|
||||
AtlasAccessRequest request = new AtlasAccessRequest(resourceType,
|
||||
resource, action, user, userGroups,"127.0.0.1");
|
||||
try {
|
||||
SimpleAtlasAuthorizer authorizer = (SimpleAtlasAuthorizer) AtlasAuthorizerFactory
|
||||
.getAtlasAuthorizer();
|
||||
authorizer
|
||||
.setResourcesForTesting(userReadMap, groupReadMap, action);
|
||||
|
||||
boolean isAccessAllowed = authorizer.isAccessAllowed(request);
|
||||
AssertJUnit.assertEquals(false, isAccessAllowed);
|
||||
} catch (AtlasAuthorizationException e) {
|
||||
if (LOG.isErrorEnabled()) {
|
||||
LOG.error("AtlasAuthorizationException in Unit Test", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
#system property
|
||||
atlas.data=${sys:user.dir}/target/data
|
||||
|
||||
|
||||
|
||||
#re-use existing property
|
||||
atlas.graph.data=${atlas.data}/graph
|
||||
|
||||
#plain property
|
||||
atlas.service=atlas
|
||||
|
||||
#invalid system property
|
||||
atlas.db=${atlasdb}
|
||||
|
||||
atlas.TypeSystem.impl=org.apache.atlas.typesystem.types.TypeSystem
|
||||
|
||||
|
||||
|
||||
######### Atlas Server Configs #########
|
||||
atlas.rest.address=http://localhost:31000
|
||||
|
||||
######### Graph Database Configs #########
|
||||
|
||||
|
||||
# Graph database implementation. Value inserted by maven.
|
||||
atlas.graphdb.backend=${graphdb.backend.impl}
|
||||
|
||||
# Graph Storage
|
||||
atlas.graph.storage.backend=${graph.storage.backend}
|
||||
|
||||
# Entity repository implementation
|
||||
atlas.EntityAuditRepository.impl=${entity.repository.impl}
|
||||
|
||||
# Graph Search Index Backend
|
||||
atlas.graph.index.search.backend=${graph.index.backend}
|
||||
|
||||
#Berkeley storage directory
|
||||
atlas.graph.storage.directory=${sys:atlas.data}/berkley
|
||||
|
||||
#hbase
|
||||
#For standalone mode , specify localhost
|
||||
#for distributed mode, specify zookeeper quorum here - For more information refer http://s3.thinkaurelius.com/docs/titan/current/hbase.html#_remote_server_mode_2
|
||||
|
||||
atlas.graph.storage.hostname=${graph.storage.hostname}
|
||||
atlas.graph.storage.hbase.regions-per-server=1
|
||||
atlas.graph.storage.lock.wait-time=10000
|
||||
|
||||
#ElasticSearch
|
||||
atlas.graph.index.search.directory=${sys:atlas.data}/es
|
||||
atlas.graph.index.search.elasticsearch.client-only=false
|
||||
atlas.graph.index.search.elasticsearch.local-mode=true
|
||||
atlas.graph.index.search.elasticsearch.create.sleep=2000
|
||||
|
||||
# Solr cloud mode properties
|
||||
atlas.graph.index.search.solr.mode=cloud
|
||||
atlas.graph.index.search.solr.zookeeper-url=${solr.zk.address}
|
||||
atlas.graph.index.search.solr.embedded=${tests.solr.embedded}
|
||||
atlas.graph.index.search.max-result-set-size=150
|
||||
|
||||
######### Hive Lineage Configs #########
|
||||
## Schema
|
||||
atlas.lineage.schema.query.hive_table=hive_table where __guid='%s'\, columns
|
||||
atlas.lineage.schema.query.hive_table_v1=hive_table_v1 where __guid='%s'\, columns
|
||||
|
||||
######### Notification Configs #########
|
||||
atlas.notification.embedded=true
|
||||
|
||||
atlas.kafka.zookeeper.connect=localhost:19026
|
||||
atlas.kafka.bootstrap.servers=localhost:19027
|
||||
atlas.kafka.data=${sys:atlas.data}/kafka
|
||||
atlas.kafka.zookeeper.session.timeout.ms=4000
|
||||
atlas.kafka.zookeeper.sync.time.ms=20
|
||||
atlas.kafka.consumer.timeout.ms=4000
|
||||
atlas.kafka.auto.commit.interval.ms=100
|
||||
atlas.kafka.hook.group.id=atlas
|
||||
atlas.kafka.entities.group.id=atlas_entities
|
||||
#atlas.kafka.auto.commit.enable=false
|
||||
|
||||
atlas.kafka.enable.auto.commit=false
|
||||
atlas.kafka.auto.offset.reset=earliest
|
||||
atlas.kafka.session.timeout.ms=30000
|
||||
|
||||
|
||||
|
||||
######### Entity Audit Configs #########
|
||||
atlas.audit.hbase.tablename=ATLAS_ENTITY_AUDIT_EVENTS
|
||||
atlas.audit.zookeeper.session.timeout.ms=1000
|
||||
atlas.audit.hbase.zookeeper.quorum=localhost
|
||||
atlas.audit.hbase.zookeeper.property.clientPort=19026
|
||||
|
||||
######### Security Properties #########
|
||||
|
||||
# SSL config
|
||||
atlas.enableTLS=false
|
||||
atlas.server.https.port=31443
|
||||
|
||||
######### Security Properties #########
|
||||
|
||||
hbase.security.authentication=simple
|
||||
|
||||
atlas.hook.falcon.synchronous=true
|
||||
|
||||
######### JAAS Configuration ########
|
||||
|
||||
atlas.jaas.KafkaClient.loginModuleName = com.sun.security.auth.module.Krb5LoginModule
|
||||
atlas.jaas.KafkaClient.loginModuleControlFlag = required
|
||||
atlas.jaas.KafkaClient.option.useKeyTab = true
|
||||
atlas.jaas.KafkaClient.option.storeKey = true
|
||||
atlas.jaas.KafkaClient.option.serviceName = kafka
|
||||
atlas.jaas.KafkaClient.option.keyTab = /etc/security/keytabs/atlas.service.keytab
|
||||
atlas.jaas.KafkaClient.option.principal = atlas/_HOST@EXAMPLE.COM
|
||||
|
||||
######### High Availability Configuration ########
|
||||
atlas.server.ha.enabled=false
|
||||
#atlas.server.ids=id1
|
||||
#atlas.server.address.id1=localhost:21000
|
||||
|
||||
######### Atlas Authorization #########
|
||||
#atlas.authorizer.impl=none
|
||||
atlas.authorizer.impl=simple
|
||||
# atlas.authorizer.simple.authz.policy.file=atlas-simple-authz-policy.json
|
||||
|
||||
######### Atlas Authentication #########
|
||||
atlas.authentication.method.file=true
|
||||
atlas.authentication.method.ldap.type=none
|
||||
atlas.authentication.method.kerberos=false
|
||||
# atlas.authentication.method.file.filename=users-credentials.properties
|
||||
|
||||
######### Gremlin Search Configuration #########
|
||||
# Set to false to disable gremlin search.
|
||||
atlas.search.gremlin.enable=true
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
{
|
||||
"roles": {
|
||||
"ROLE_ADMIN": {
|
||||
"adminPermissions": [
|
||||
{
|
||||
"privileges": [ ".*" ]
|
||||
}
|
||||
],
|
||||
|
||||
"entityPermissions": [
|
||||
{
|
||||
"privileges": [ ".*" ],
|
||||
"entityTypes": [ ".*" ],
|
||||
"entityIds": [ ".*" ],
|
||||
"classifications": [ ".*" ]
|
||||
}
|
||||
],
|
||||
|
||||
"typePermissions": [
|
||||
{
|
||||
"privileges": [ ".*" ],
|
||||
"typeCategories": [ ".*" ],
|
||||
"typeNames": [ ".*" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"DATA_SCIENTIST": {
|
||||
"entityPermissions": [
|
||||
{
|
||||
"privileges": [ "entity-read", "entity-read-classification" ],
|
||||
"entityTypes": [ ".*" ],
|
||||
"entityIds": [ ".*" ],
|
||||
"classifications": [ ".*" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"DATA_STEWARD": {
|
||||
"entityPermissions": [
|
||||
{
|
||||
"privileges": [ "entity-read", "entity-create", "entity-update", "entity-read-classification", "entity-add-classification", "entity-update-classification", "entity-remove-classification" ],
|
||||
"entityTypes": [ ".*" ],
|
||||
"entityIds": [ ".*" ],
|
||||
"classifications": [ ".*" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
"userRoles": {
|
||||
"admin": [ "ROLE_ADMIN" ]
|
||||
},
|
||||
|
||||
"groupRoles": {
|
||||
"ROLE_ADMIN": [ "ROLE_ADMIN" ],
|
||||
"hadoop": [ "DATA_STEWARD" ],
|
||||
"DATA_STEWARD": [ "DATA_STEWARD" ],
|
||||
"RANGER_TAG_SYNC": [ "DATA_SCIENTIST" ]
|
||||
}
|
||||
}
|
||||
|
|
@ -184,8 +184,9 @@ atlas.server.ha.enabled=false
|
|||
|
||||
|
||||
|
||||
#########POLICY FILE PATH #########
|
||||
atlas.auth.policy.file=${sys:atlas.home}/conf/policy-store.txt
|
||||
######### Atlas Authorization #########
|
||||
atlas.authorizer.impl=simple
|
||||
atlas.authorizer.simple.authz.policy.file=atlas-simple-authz-policy.json
|
||||
|
||||
######### Type Cache Implementation ########
|
||||
# A type cache class which implements
|
||||
|
|
@ -193,9 +194,6 @@ atlas.auth.policy.file=${sys:atlas.home}/conf/policy-store.txt
|
|||
# The default implementation is org.apache.atlas.typesystem.types.cache.DefaultTypeCache which is a local in-memory type cache.
|
||||
#atlas.TypeCache.impl=
|
||||
|
||||
#########authorizer impl class #########
|
||||
atlas.authorizer.impl=SIMPLE
|
||||
|
||||
######### Performance Configs #########
|
||||
#atlas.graph.storage.lock.retries=10
|
||||
#atlas.graph.storage.cache.db-cache-time=120000
|
||||
|
|
|
|||
|
|
@ -174,57 +174,57 @@ public final class ApplicationProperties extends PropertiesConfiguration {
|
|||
* @throws AtlasException if no file was found or if there was an error loading the file
|
||||
*/
|
||||
public static InputStream getFileAsInputStream(Configuration configuration, String propertyName, String defaultFileName) throws AtlasException {
|
||||
File fileToLoad = null;
|
||||
String fileName = configuration.getString(propertyName);
|
||||
File fileToLoad = null;
|
||||
String fileName = configuration.getString(propertyName);
|
||||
|
||||
if (fileName == null) {
|
||||
if (defaultFileName == null) {
|
||||
throw new AtlasException(propertyName + " property not set and no default value specified");
|
||||
}
|
||||
|
||||
LOG.info("{} property not set; defaulting to {}", propertyName, defaultFileName);
|
||||
|
||||
fileName = defaultFileName;
|
||||
|
||||
String atlasConfDir = System.getProperty(ATLAS_CONFIGURATION_DIRECTORY_PROPERTY);
|
||||
|
||||
if (atlasConfDir != null) {
|
||||
// Look for default filename in Atlas config directory
|
||||
fileToLoad = new File(atlasConfDir, fileName);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Look for default filename under the working directory
|
||||
fileToLoad = new File(fileName);
|
||||
}
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("{} property not set - defaulting to {}", propertyName, fileToLoad.getPath());
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Look for configured filename
|
||||
fileToLoad = new File(fileName);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Using {} property setting: {}", propertyName, fileToLoad.getPath());
|
||||
}
|
||||
}
|
||||
|
||||
InputStream inStr = null;
|
||||
|
||||
if (fileToLoad.exists()) {
|
||||
try {
|
||||
LOG.info("Loading file {} from {}", fileName, fileToLoad.getPath());
|
||||
|
||||
inStr = new FileInputStream(fileToLoad);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new AtlasException("Error loading file " + fileName, e);
|
||||
}
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Loaded file from : {}", fileToLoad.getPath());
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Look for file as class loader resource
|
||||
inStr = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
|
||||
|
||||
if (inStr == null) {
|
||||
String msg = fileName + " not found in file system or as class loader resource";
|
||||
|
||||
LOG.error(msg);
|
||||
|
||||
throw new AtlasException(msg);
|
||||
}
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Loaded {} as resource from : {}", fileName, Thread.currentThread().getContextClassLoader().getResource(fileName).toString());
|
||||
}
|
||||
|
||||
LOG.info("Loaded {} as resource from {}", fileName, Thread.currentThread().getContextClassLoader().getResource(fileName).toString());
|
||||
}
|
||||
|
||||
return inStr;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -126,6 +126,8 @@ public enum AtlasErrorCode {
|
|||
CLASSIFICATION_DELETE_FROM_PROPAGATED_ENTITY(400, "ATLAS-400-00-06C", "Delete of classification {0} is not allowed from propagated entity"),
|
||||
CLASSIFICATION_NOT_ASSOCIATED_WITH_ENTITY(400, "ATLAS-400-00-06D", "Classification {0} is not associated with entity"),
|
||||
|
||||
UNAUTHORIZED_ACCESS(403, "ATLAS-403-00-001", "{0} is not authorized to perform {1}"),
|
||||
|
||||
// All Not found enums go here
|
||||
TYPE_NAME_NOT_FOUND(404, "ATLAS-404-00-001", "Given typename {0} was invalid"),
|
||||
TYPE_GUID_NOT_FOUND(404, "ATLAS-404-00-002", "Given type guid {0} was invalid"),
|
||||
|
|
@ -142,6 +144,7 @@ public enum AtlasErrorCode {
|
|||
RELATIONSHIPDEF_END_TYPE_NAME_NOT_FOUND(404, "ATLAS-404-00-00E", "RelationshipDef {0} endDef typename {0} cannot be found"),
|
||||
RELATIONSHIP_ALREADY_DELETED(404, "ATLAS-404-00-00F", "Attempting to delete a relationship which is already deleted : {0}"),
|
||||
INVALID_ENTITY_GUID_FOR_CLASSIFICATION_UPDATE(404, "ATLAS-404-00-010", "Updating entityGuid of classification is not allowed."),
|
||||
INSTANCE_GUID_NOT_DATASET(404, "ATLAS-404-00-011", "Given instance guid {0} is not a dataset"),
|
||||
|
||||
// All data conflict errors go here
|
||||
TYPE_ALREADY_EXISTS(409, "ATLAS-409-00-001", "Given type {0} already exists"),
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
|||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
|
@ -36,6 +37,7 @@ import org.apache.atlas.model.PList;
|
|||
import org.apache.atlas.model.SearchFilter.SortType;
|
||||
import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
|
||||
import org.apache.atlas.model.typedef.AtlasEntityDef;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE;
|
||||
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.PUBLIC_ONLY;
|
||||
|
|
@ -98,6 +100,20 @@ public class AtlasEntityHeader extends AtlasStruct implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
public AtlasEntityHeader(AtlasEntity entity){
|
||||
super(entity.getTypeName(), entity.getAttributes());
|
||||
setGuid(entity.getGuid());
|
||||
setClassifications(entity.getClassifications());
|
||||
|
||||
if (CollectionUtils.isNotEmpty(entity.getClassifications())) {
|
||||
this.classificationNames = new ArrayList<>(entity.getClassifications().size());
|
||||
|
||||
for (AtlasClassification classification : entity.getClassifications()) {
|
||||
this.classificationNames.add(classification.getTypeName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getGuid() {
|
||||
return guid;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ public class AtlasClassificationType extends AtlasStructType {
|
|||
private Set<String> subTypes = Collections.emptySet();
|
||||
private Set<String> allSubTypes = Collections.emptySet();
|
||||
private Set<String> typeAndAllSubTypes = Collections.emptySet();
|
||||
private Set<String> typeAndAllSuperTypes = Collections.emptySet();
|
||||
private String typeAndAllSubTypesQryStr = "";
|
||||
|
||||
// we need to store the entityTypes specified in our supertypes. i.e. our parent classificationDefs may specify more entityTypes
|
||||
|
|
@ -113,6 +114,10 @@ public class AtlasClassificationType extends AtlasStructType {
|
|||
this.entityTypes = new HashSet<>(); // this will be populated in resolveReferencesPhase3()
|
||||
|
||||
this.typeAndAllSubTypes.add(this.getTypeName());
|
||||
|
||||
this.typeAndAllSuperTypes = new HashSet<>(this.allSuperTypes);
|
||||
this.typeAndAllSuperTypes.add(this.getTypeName());
|
||||
this.typeAndAllSuperTypes = Collections.unmodifiableSet(this.typeAndAllSuperTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -241,6 +246,8 @@ public class AtlasClassificationType extends AtlasStructType {
|
|||
|
||||
public Set<String> getTypeAndAllSubTypes() { return typeAndAllSubTypes; }
|
||||
|
||||
public Set<String> getTypeAndAllSuperTypes() { return typeAndAllSuperTypes; }
|
||||
|
||||
public String getTypeQryStr() { return typeQryStr; }
|
||||
|
||||
public String getTypeAndAllSubTypesQryStr() {
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
|
@ -156,6 +157,20 @@ public class AtlasJson {
|
|||
return ret;
|
||||
}
|
||||
|
||||
public static <T> T fromJson(InputStream inputStream, Class<T> type) throws IOException {
|
||||
T ret = null;
|
||||
|
||||
if (inputStream != null) {
|
||||
ret = mapper.readValue(inputStream, type);
|
||||
|
||||
if (ret instanceof Struct) {
|
||||
((Struct) ret).normalize();
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static String toV1Json(Object obj) {
|
||||
return toJson(obj);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,14 +133,17 @@ atlas.server.ha.enabled=false
|
|||
#atlas.server.ids=id1
|
||||
#atlas.server.address.id1=localhost:21000
|
||||
|
||||
#########POLICY FILE PATH #########
|
||||
# atlas.auth.policy.file=policy-store.txt
|
||||
######### Atlas Authorization #########
|
||||
atlas.authorizer.impl=none
|
||||
# atlas.authorizer.impl=simple
|
||||
# atlas.authorizer.simple.authz.policy.file=atlas-simple-authz-policy.json
|
||||
|
||||
######### Atlas Authentication #########
|
||||
atlas.authentication.method.file=true
|
||||
atlas.authentication.method.ldap.type=none
|
||||
# atlas.authentication.method.file.filename=users-credentials.properties
|
||||
atlas.authentication.method.kerberos=false
|
||||
# atlas.authentication.method.file.filename=users-credentials.properties
|
||||
|
||||
######### Gremlin Search Configuration #########
|
||||
# Set to false to disable gremlin search.
|
||||
atlas.search.gremlin.enable=true
|
||||
atlas.search.gremlin.enable=true
|
||||
|
|
|
|||
|
|
@ -112,6 +112,12 @@
|
|||
<type>pom</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.atlas</groupId>
|
||||
<artifactId>atlas-authorization</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.atlas</groupId>
|
||||
|
|
|
|||
|
|
@ -22,15 +22,17 @@ package org.apache.atlas.discovery;
|
|||
import org.apache.atlas.AtlasClient;
|
||||
import org.apache.atlas.AtlasErrorCode;
|
||||
import org.apache.atlas.annotation.GraphTransaction;
|
||||
import org.apache.atlas.authorize.AtlasAuthorizationUtils;
|
||||
import org.apache.atlas.authorize.AtlasEntityAccessRequest;
|
||||
import org.apache.atlas.authorize.AtlasPrivilege;
|
||||
import org.apache.atlas.exception.AtlasBaseException;
|
||||
import org.apache.atlas.model.instance.AtlasEntity;
|
||||
import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo;
|
||||
import org.apache.atlas.model.instance.AtlasEntityHeader;
|
||||
import org.apache.atlas.model.instance.AtlasObjectId;
|
||||
import org.apache.atlas.model.lineage.AtlasLineageInfo;
|
||||
import org.apache.atlas.model.lineage.AtlasLineageInfo.LineageDirection;
|
||||
import org.apache.atlas.model.lineage.AtlasLineageInfo.LineageRelation;
|
||||
import org.apache.atlas.repository.Constants;
|
||||
import org.apache.atlas.repository.graph.GraphHelper;
|
||||
import org.apache.atlas.repository.graphdb.AtlasGraph;
|
||||
import org.apache.atlas.repository.graphdb.AtlasVertex;
|
||||
import org.apache.atlas.repository.store.graph.v1.AtlasGraphUtilsV1;
|
||||
|
|
@ -80,8 +82,14 @@ public class EntityLineageService implements AtlasLineageService {
|
|||
public AtlasLineageInfo getAtlasLineageInfo(String guid, LineageDirection direction, int depth) throws AtlasBaseException {
|
||||
AtlasLineageInfo lineageInfo;
|
||||
|
||||
if (!entityExists(guid)) {
|
||||
throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
|
||||
AtlasEntityHeader entity = entityRetriever.toAtlasEntityHeaderWithClassifications(guid);
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(atlasTypeRegistry, AtlasPrivilege.ENTITY_READ, entity), "read entity lineage: guid=", guid);
|
||||
|
||||
AtlasEntityType entityType = atlasTypeRegistry.getEntityTypeByName(entity.getTypeName());
|
||||
|
||||
if (entityType == null || !entityType.getTypeAndAllSuperTypes().contains(AtlasClient.DATA_SET_SUPER_TYPE)) {
|
||||
throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_DATASET, guid);
|
||||
}
|
||||
|
||||
if (direction != null) {
|
||||
|
|
@ -129,10 +137,14 @@ public class EntityLineageService implements AtlasLineageService {
|
|||
|
||||
ret.setDataType(AtlasTypeUtil.toClassTypeDefinition(hive_column));
|
||||
|
||||
AtlasEntity.AtlasEntityWithExtInfo entityWithExtInfo = entityRetriever.toAtlasEntityWithExtInfo(guid);
|
||||
AtlasEntity entity = entityWithExtInfo.getEntity();
|
||||
Map<String, AtlasEntity> referredEntities = entityWithExtInfo.getReferredEntities();
|
||||
List<String> columnIds = getColumnIds(entity);
|
||||
AtlasEntityWithExtInfo entityWithExtInfo = entityRetriever.toAtlasEntityWithExtInfo(guid);
|
||||
AtlasEntity entity = entityWithExtInfo.getEntity();
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(atlasTypeRegistry, AtlasPrivilege.ENTITY_READ, new AtlasEntityHeader(entity)),
|
||||
"read entity schema: guid=", guid);
|
||||
|
||||
Map<String, AtlasEntity> referredEntities = entityWithExtInfo.getReferredEntities();
|
||||
List<String> columnIds = getColumnIds(entity);
|
||||
|
||||
if (MapUtils.isNotEmpty(referredEntities)) {
|
||||
List<Map<String, Object>> rows = referredEntities.entrySet()
|
||||
|
|
@ -244,21 +256,4 @@ public class EntityLineageService implements AtlasLineageService {
|
|||
}
|
||||
return lineageQuery;
|
||||
}
|
||||
|
||||
private boolean entityExists(String guid) {
|
||||
boolean ret = false;
|
||||
Iterator<AtlasVertex> results = graph.query()
|
||||
.has(Constants.GUID_PROPERTY_KEY, guid)
|
||||
.vertices().iterator();
|
||||
|
||||
while (results.hasNext()) {
|
||||
AtlasVertex entityVertex = results.next();
|
||||
List<String> superTypes = GraphHelper.getSuperTypeNames(entityVertex);
|
||||
|
||||
ret = (CollectionUtils.isNotEmpty(superTypes)) && superTypes.contains(AtlasClient.DATA_SET_SUPER_TYPE);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -19,6 +19,9 @@ package org.apache.atlas.repository.store.graph.v1;
|
|||
|
||||
|
||||
import org.apache.atlas.AtlasErrorCode;
|
||||
import org.apache.atlas.authorize.AtlasPrivilege;
|
||||
import org.apache.atlas.authorize.AtlasAuthorizationUtils;
|
||||
import org.apache.atlas.authorize.AtlasTypeAccessRequest;
|
||||
import org.apache.atlas.exception.AtlasBaseException;
|
||||
import org.apache.atlas.model.typedef.AtlasClassificationDef;
|
||||
import org.apache.atlas.repository.Constants;
|
||||
|
|
@ -83,12 +86,13 @@ class AtlasClassificationDefStoreV1 extends AtlasAbstractDefStoreV1<AtlasClassif
|
|||
}
|
||||
|
||||
@Override
|
||||
public AtlasClassificationDef create(AtlasClassificationDef classificationDef, AtlasVertex preCreateResult)
|
||||
throws AtlasBaseException {
|
||||
public AtlasClassificationDef create(AtlasClassificationDef classificationDef, AtlasVertex preCreateResult) throws AtlasBaseException {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("==> AtlasClassificationDefStoreV1.create({}, {})", classificationDef, preCreateResult);
|
||||
}
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_CREATE, classificationDef), "create classification-def ", classificationDef.getName());
|
||||
|
||||
AtlasVertex vertex = (preCreateResult == null) ? preCreate(classificationDef) : preCreateResult;
|
||||
|
||||
updateVertexAddReferences(classificationDef, vertex);
|
||||
|
|
@ -190,6 +194,10 @@ class AtlasClassificationDefStoreV1 extends AtlasAbstractDefStoreV1<AtlasClassif
|
|||
LOG.debug("==> AtlasClassificationDefStoreV1.updateByName({}, {})", name, classificationDef);
|
||||
}
|
||||
|
||||
AtlasClassificationDef existingDef = typeRegistry.getClassificationDefByName(name);
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_UPDATE, existingDef), "update classification-def ", name);
|
||||
|
||||
validateType(classificationDef);
|
||||
|
||||
AtlasType type = typeRegistry.getType(classificationDef.getName());
|
||||
|
|
@ -222,6 +230,10 @@ class AtlasClassificationDefStoreV1 extends AtlasAbstractDefStoreV1<AtlasClassif
|
|||
LOG.debug("==> AtlasClassificationDefStoreV1.updateByGuid({})", guid);
|
||||
}
|
||||
|
||||
AtlasClassificationDef existingDef = typeRegistry.getClassificationDefByGuid(guid);
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_UPDATE, existingDef), "update classification-def ", (existingDef != null ? existingDef.getName() : guid));
|
||||
|
||||
validateType(classificationDef);
|
||||
|
||||
AtlasType type = typeRegistry.getTypeByGuid(guid);
|
||||
|
|
@ -254,6 +266,10 @@ class AtlasClassificationDefStoreV1 extends AtlasAbstractDefStoreV1<AtlasClassif
|
|||
LOG.debug("==> AtlasClassificationDefStoreV1.preDeleteByName({})", name);
|
||||
}
|
||||
|
||||
AtlasClassificationDef existingDef = typeRegistry.getClassificationDefByName(name);
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_DELETE, existingDef), "delete classification-def ", name);
|
||||
|
||||
AtlasVertex ret = typeDefStore.findTypeVertexByNameAndCategory(name, TypeCategory.TRAIT);
|
||||
|
||||
if (AtlasGraphUtilsV1.typeHasInstanceVertex(name)) {
|
||||
|
|
@ -279,6 +295,10 @@ class AtlasClassificationDefStoreV1 extends AtlasAbstractDefStoreV1<AtlasClassif
|
|||
LOG.debug("==> AtlasClassificationDefStoreV1.preDeleteByGuid({})", guid);
|
||||
}
|
||||
|
||||
AtlasClassificationDef existingDef = typeRegistry.getClassificationDefByGuid(guid);
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_DELETE, existingDef), "delete classification-def ", (existingDef != null ? existingDef.getName() : guid));
|
||||
|
||||
AtlasVertex ret = typeDefStore.findTypeVertexByGuidAndCategory(guid, TypeCategory.TRAIT);
|
||||
|
||||
String typeName = AtlasGraphUtilsV1.getProperty(ret, Constants.TYPENAME_PROPERTY_KEY, String.class);
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@
|
|||
package org.apache.atlas.repository.store.graph.v1;
|
||||
|
||||
import org.apache.atlas.AtlasErrorCode;
|
||||
import org.apache.atlas.authorize.AtlasPrivilege;
|
||||
import org.apache.atlas.authorize.AtlasTypeAccessRequest;
|
||||
import org.apache.atlas.authorize.AtlasAuthorizationUtils;
|
||||
import org.apache.atlas.exception.AtlasBaseException;
|
||||
import org.apache.atlas.model.typedef.AtlasEntityDef;
|
||||
import org.apache.atlas.repository.Constants;
|
||||
|
|
@ -60,6 +63,8 @@ public class AtlasEntityDefStoreV1 extends AtlasAbstractDefStoreV1<AtlasEntityDe
|
|||
throw new AtlasBaseException(AtlasErrorCode.TYPE_MATCH_FAILED, entityDef.getName(), TypeCategory.CLASS.name());
|
||||
}
|
||||
|
||||
|
||||
|
||||
AtlasVertex ret = typeDefStore.findTypeVertexByName(entityDef.getName());
|
||||
|
||||
if (ret != null) {
|
||||
|
|
@ -83,6 +88,8 @@ public class AtlasEntityDefStoreV1 extends AtlasAbstractDefStoreV1<AtlasEntityDe
|
|||
LOG.debug("==> AtlasEntityDefStoreV1.create({}, {})", entityDef, preCreateResult);
|
||||
}
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_CREATE, entityDef), "create entity-def ", entityDef.getName());
|
||||
|
||||
AtlasVertex vertex = (preCreateResult == null) ? preCreate(entityDef) : preCreateResult;
|
||||
|
||||
updateVertexAddReferences(entityDef, vertex);
|
||||
|
|
@ -184,6 +191,10 @@ public class AtlasEntityDefStoreV1 extends AtlasAbstractDefStoreV1<AtlasEntityDe
|
|||
LOG.debug("==> AtlasEntityDefStoreV1.updateByName({}, {})", name, entityDef);
|
||||
}
|
||||
|
||||
AtlasEntityDef existingDef = typeRegistry.getEntityDefByName(name);
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_UPDATE, existingDef), "update entity-def ", name);
|
||||
|
||||
validateType(entityDef);
|
||||
|
||||
AtlasType type = typeRegistry.getType(entityDef.getName());
|
||||
|
|
@ -216,6 +227,10 @@ public class AtlasEntityDefStoreV1 extends AtlasAbstractDefStoreV1<AtlasEntityDe
|
|||
LOG.debug("==> AtlasEntityDefStoreV1.updateByGuid({})", guid);
|
||||
}
|
||||
|
||||
AtlasEntityDef existingDef = typeRegistry.getEntityDefByGuid(guid);
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_UPDATE, existingDef), "update entity-def ", (existingDef != null ? existingDef.getName() : guid));
|
||||
|
||||
validateType(entityDef);
|
||||
|
||||
AtlasType type = typeRegistry.getTypeByGuid(guid);
|
||||
|
|
@ -248,6 +263,10 @@ public class AtlasEntityDefStoreV1 extends AtlasAbstractDefStoreV1<AtlasEntityDe
|
|||
LOG.debug("==> AtlasEntityDefStoreV1.preDeleteByName({})", name);
|
||||
}
|
||||
|
||||
AtlasEntityDef existingDef = typeRegistry.getEntityDefByName(name);
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_DELETE, existingDef), "delete entity-def ", name);
|
||||
|
||||
AtlasVertex ret = typeDefStore.findTypeVertexByNameAndCategory(name, TypeCategory.CLASS);
|
||||
|
||||
if (AtlasGraphUtilsV1.typeHasInstanceVertex(name)) {
|
||||
|
|
@ -278,6 +297,10 @@ public class AtlasEntityDefStoreV1 extends AtlasAbstractDefStoreV1<AtlasEntityDe
|
|||
LOG.debug("==> AtlasEntityDefStoreV1.preDeleteByGuid({})", guid);
|
||||
}
|
||||
|
||||
AtlasEntityDef existingDef = typeRegistry.getEntityDefByGuid(guid);
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_DELETE, existingDef), "delete entity-def ", (existingDef != null ? existingDef.getName() : guid));
|
||||
|
||||
AtlasVertex ret = typeDefStore.findTypeVertexByGuidAndCategory(guid, TypeCategory.CLASS);
|
||||
|
||||
String typeName = AtlasGraphUtilsV1.getProperty(ret, Constants.TYPENAME_PROPERTY_KEY, String.class);
|
||||
|
|
|
|||
|
|
@ -22,13 +22,13 @@ import org.apache.atlas.AtlasErrorCode;
|
|||
import org.apache.atlas.GraphTransactionInterceptor;
|
||||
import org.apache.atlas.RequestContextV1;
|
||||
import org.apache.atlas.annotation.GraphTransaction;
|
||||
import org.apache.atlas.authorize.AtlasEntityAccessRequest;
|
||||
import org.apache.atlas.authorize.AtlasPrivilege;
|
||||
import org.apache.atlas.authorize.AtlasAuthorizationUtils;
|
||||
import org.apache.atlas.exception.AtlasBaseException;
|
||||
import org.apache.atlas.model.instance.AtlasClassification;
|
||||
import org.apache.atlas.model.instance.AtlasEntity;
|
||||
import org.apache.atlas.model.instance.*;
|
||||
import org.apache.atlas.model.instance.AtlasEntity.AtlasEntitiesWithExtInfo;
|
||||
import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo;
|
||||
import org.apache.atlas.model.instance.AtlasObjectId;
|
||||
import org.apache.atlas.model.instance.EntityMutationResponse;
|
||||
import org.apache.atlas.repository.graphdb.AtlasVertex;
|
||||
import org.apache.atlas.repository.store.graph.AtlasEntityStore;
|
||||
import org.apache.atlas.repository.store.graph.EntityGraphDiscovery;
|
||||
|
|
@ -65,6 +65,7 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
|
|||
private final AtlasTypeRegistry typeRegistry;
|
||||
private final AtlasEntityChangeNotifier entityChangeNotifier;
|
||||
private final EntityGraphMapper entityGraphMapper;
|
||||
private final EntityGraphRetriever entityRetriever;
|
||||
|
||||
@Inject
|
||||
public AtlasEntityStoreV1(DeleteHandlerV1 deleteHandler, AtlasTypeRegistry typeRegistry,
|
||||
|
|
@ -73,6 +74,7 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
|
|||
this.typeRegistry = typeRegistry;
|
||||
this.entityChangeNotifier = entityChangeNotifier;
|
||||
this.entityGraphMapper = entityGraphMapper;
|
||||
this.entityRetriever = new EntityGraphRetriever(typeRegistry);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -102,13 +104,9 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
|
|||
LOG.debug("==> getById({})", guid);
|
||||
}
|
||||
|
||||
EntityGraphRetriever entityRetriever = new EntityGraphRetriever(typeRegistry);
|
||||
|
||||
AtlasEntityWithExtInfo ret = entityRetriever.toAtlasEntityWithExtInfo(guid);
|
||||
|
||||
if (ret == null) {
|
||||
throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
|
||||
}
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ, new AtlasEntityHeader(ret.getEntity())), "read entity: guid=", guid);
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("<== getById({}): {}", guid, ret);
|
||||
|
|
@ -124,10 +122,17 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
|
|||
LOG.debug("==> getByIds({})", guids);
|
||||
}
|
||||
|
||||
EntityGraphRetriever entityRetriever = new EntityGraphRetriever(typeRegistry);
|
||||
|
||||
AtlasEntitiesWithExtInfo ret = entityRetriever.toAtlasEntitiesWithExtInfo(guids);
|
||||
|
||||
// verify authorization to read the entities
|
||||
if(ret != null){
|
||||
for(String guid : guids){
|
||||
AtlasEntity entity = ret.getEntity(guid);
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ, new AtlasEntityHeader(entity)), "read entity: guid=", guid);
|
||||
}
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("<== getByIds({}): {}", guids, ret);
|
||||
}
|
||||
|
|
@ -137,22 +142,15 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
|
|||
|
||||
@Override
|
||||
@GraphTransaction
|
||||
public AtlasEntityWithExtInfo getByUniqueAttributes(AtlasEntityType entityType, Map<String, Object> uniqAttributes)
|
||||
throws AtlasBaseException {
|
||||
public AtlasEntityWithExtInfo getByUniqueAttributes(AtlasEntityType entityType, Map<String, Object> uniqAttributes) throws AtlasBaseException {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("==> getByUniqueAttribute({}, {})", entityType.getTypeName(), uniqAttributes);
|
||||
}
|
||||
|
||||
AtlasVertex entityVertex = AtlasGraphUtilsV1.getVertexByUniqueAttributes(entityType, uniqAttributes);
|
||||
AtlasVertex entityVertex = AtlasGraphUtilsV1.getVertexByUniqueAttributes(entityType, uniqAttributes);
|
||||
AtlasEntityWithExtInfo ret = entityRetriever.toAtlasEntityWithExtInfo(entityVertex);
|
||||
|
||||
EntityGraphRetriever entityRetriever = new EntityGraphRetriever(typeRegistry);
|
||||
|
||||
AtlasEntityWithExtInfo ret = entityRetriever.toAtlasEntityWithExtInfo(entityVertex);
|
||||
|
||||
if (ret == null) {
|
||||
throw new AtlasBaseException(AtlasErrorCode.INSTANCE_BY_UNIQUE_ATTRIBUTE_NOT_FOUND, entityType.getTypeName(),
|
||||
uniqAttributes.toString());
|
||||
}
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ, new AtlasEntityHeader(ret.getEntity())), "read entity: typeName=", entityType.getTypeName(), ", uniqueAttributes=", uniqAttributes);
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("<== getByUniqueAttribute({}, {}): {}", entityType.getTypeName(), uniqAttributes, ret);
|
||||
|
|
@ -161,70 +159,6 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
|
|||
return ret;
|
||||
}
|
||||
|
||||
private EntityMutationResponse createOrUpdate(EntityStream entityStream, boolean isPartialUpdate, boolean replaceClassifications) throws AtlasBaseException {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("==> createOrUpdate()");
|
||||
}
|
||||
|
||||
if (entityStream == null || !entityStream.hasNext()) {
|
||||
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "no entities to create/update.");
|
||||
}
|
||||
|
||||
AtlasPerfTracer perf = null;
|
||||
|
||||
if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
|
||||
perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "createOrUpdate()");
|
||||
}
|
||||
|
||||
try {
|
||||
// Create/Update entities
|
||||
EntityMutationContext context = preCreateOrUpdate(entityStream, entityGraphMapper, isPartialUpdate);
|
||||
|
||||
// for existing entities, skip update if incoming entity doesn't have any change
|
||||
if (CollectionUtils.isNotEmpty(context.getUpdatedEntities())) {
|
||||
EntityGraphRetriever entityRetriever = new EntityGraphRetriever(typeRegistry);
|
||||
|
||||
List<AtlasEntity> entitiesToSkipUpdate = null;
|
||||
for (AtlasEntity entity : context.getUpdatedEntities()) {
|
||||
String guid = entity.getGuid();
|
||||
AtlasVertex vertex = context.getVertex(guid);
|
||||
AtlasEntity entityInStore = entityRetriever.toAtlasEntity(vertex);
|
||||
AtlasEntityType entityType = typeRegistry.getEntityTypeByName(entity.getTypeName());
|
||||
|
||||
if (!AtlasEntityUtil.hasAnyAttributeUpdate(entityType, entity, entityInStore)) {
|
||||
// if classifications are to be replaced as well, then skip updates only when no change in classifications as well
|
||||
if (!replaceClassifications || Objects.equals(entity.getClassifications(), entityInStore.getClassifications())) {
|
||||
if (entitiesToSkipUpdate == null) {
|
||||
entitiesToSkipUpdate = new ArrayList<>();
|
||||
}
|
||||
|
||||
entitiesToSkipUpdate.add(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entitiesToSkipUpdate != null) {
|
||||
context.getUpdatedEntities().removeAll(entitiesToSkipUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
EntityMutationResponse ret = entityGraphMapper.mapAttributesAndClassifications(context, isPartialUpdate, replaceClassifications);
|
||||
|
||||
ret.setGuidAssignments(context.getGuidAssignments());
|
||||
|
||||
// Notify the change listeners
|
||||
entityChangeNotifier.onEntitiesMutated(ret, entityStream instanceof EntityImportStream);
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("<== createOrUpdate()");
|
||||
}
|
||||
|
||||
return ret;
|
||||
} finally {
|
||||
AtlasPerfTracer.log(perf);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@GraphTransaction
|
||||
public EntityMutationResponse createOrUpdate(EntityStream entityStream, boolean isPartialUpdate) throws AtlasBaseException {
|
||||
|
|
@ -273,7 +207,6 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
|
|||
@GraphTransaction
|
||||
public EntityMutationResponse updateByUniqueAttributes(AtlasEntityType entityType, Map<String, Object> uniqAttributes,
|
||||
AtlasEntityWithExtInfo updatedEntityInfo) throws AtlasBaseException {
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("==> updateByUniqueAttributes({}, {})", entityType.getTypeName(), uniqAttributes);
|
||||
}
|
||||
|
|
@ -282,8 +215,7 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
|
|||
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "no entity to update.");
|
||||
}
|
||||
|
||||
String guid = AtlasGraphUtilsV1.getGuidByUniqueAttributes(entityType, uniqAttributes);
|
||||
|
||||
String guid = AtlasGraphUtilsV1.getGuidByUniqueAttributes(entityType, uniqAttributes);
|
||||
AtlasEntity entity = updatedEntityInfo.getEntity();
|
||||
|
||||
entity.setGuid(guid);
|
||||
|
|
@ -299,15 +231,9 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
|
|||
LOG.debug("==> updateEntityAttributeByGuid({}, {}, {})", guid, attrName, attrValue);
|
||||
}
|
||||
|
||||
AtlasEntityWithExtInfo entityInfo = getById(guid);
|
||||
|
||||
if (entityInfo == null || entityInfo.getEntity() == null) {
|
||||
throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
|
||||
}
|
||||
|
||||
AtlasEntity entity = entityInfo.getEntity();
|
||||
AtlasEntityType entityType = (AtlasEntityType) typeRegistry.getType(entity.getTypeName());
|
||||
AtlasAttribute attr = entityType.getAttribute(attrName);
|
||||
AtlasEntityHeader entity = entityRetriever.toAtlasEntityHeaderWithClassifications(guid);
|
||||
AtlasEntityType entityType = (AtlasEntityType) typeRegistry.getType(entity.getTypeName());
|
||||
AtlasAttribute attr = entityType.getAttribute(attrName);
|
||||
|
||||
if (attr == null) {
|
||||
throw new AtlasBaseException(AtlasErrorCode.UNKNOWN_ATTRIBUTE, attrName, entity.getTypeName());
|
||||
|
|
@ -345,17 +271,18 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
|
|||
@Override
|
||||
@GraphTransaction
|
||||
public EntityMutationResponse deleteById(final String guid) throws AtlasBaseException {
|
||||
|
||||
if (StringUtils.isEmpty(guid)) {
|
||||
throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
|
||||
}
|
||||
|
||||
// Retrieve vertices for requested guids.
|
||||
AtlasVertex vertex = AtlasGraphUtilsV1.findByGuid(guid);
|
||||
|
||||
Collection<AtlasVertex> deletionCandidates = new ArrayList<>();
|
||||
AtlasVertex vertex = AtlasGraphUtilsV1.findByGuid(guid);
|
||||
|
||||
if (vertex != null) {
|
||||
AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(vertex);
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_DELETE, entityHeader), "delete entity: guid=", guid);
|
||||
|
||||
deletionCandidates.add(vertex);
|
||||
} else {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
|
|
@ -383,18 +310,23 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
|
|||
Collection<AtlasVertex> deletionCandidates = new ArrayList<>();
|
||||
|
||||
for (String guid : guids) {
|
||||
// Retrieve vertices for requested guids.
|
||||
AtlasVertex vertex = AtlasGraphUtilsV1.findByGuid(guid);
|
||||
|
||||
if (vertex != null) {
|
||||
deletionCandidates.add(vertex);
|
||||
} else {
|
||||
if (vertex == null) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
// Entity does not exist - treat as non-error, since the caller
|
||||
// wanted to delete the entity and it's already gone.
|
||||
LOG.debug("Deletion request ignored for non-existent entity with guid " + guid);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(vertex);
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_DELETE, entityHeader), "delete entity: guid=", guid);
|
||||
|
||||
deletionCandidates.add(vertex);
|
||||
}
|
||||
|
||||
if (deletionCandidates.isEmpty()) {
|
||||
|
|
@ -411,17 +343,19 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
|
|||
|
||||
@Override
|
||||
@GraphTransaction
|
||||
public EntityMutationResponse deleteByUniqueAttributes(AtlasEntityType entityType, Map<String, Object> uniqAttributes)
|
||||
throws AtlasBaseException {
|
||||
|
||||
public EntityMutationResponse deleteByUniqueAttributes(AtlasEntityType entityType, Map<String, Object> uniqAttributes) throws AtlasBaseException {
|
||||
if (MapUtils.isEmpty(uniqAttributes)) {
|
||||
throw new AtlasBaseException(AtlasErrorCode.INSTANCE_BY_UNIQUE_ATTRIBUTE_NOT_FOUND, uniqAttributes.toString());
|
||||
}
|
||||
|
||||
final AtlasVertex vertex = AtlasGraphUtilsV1.findByUniqueAttributes(entityType, uniqAttributes);
|
||||
Collection<AtlasVertex> deletionCandidates = new ArrayList<>();
|
||||
AtlasVertex vertex = AtlasGraphUtilsV1.findByUniqueAttributes(entityType, uniqAttributes);
|
||||
|
||||
if (vertex != null) {
|
||||
AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(vertex);
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_DELETE, entityHeader), "delete entity: typeName=", entityType.getTypeName(), ", uniqueAttributes=", uniqAttributes);
|
||||
|
||||
deletionCandidates.add(vertex);
|
||||
} else {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
|
|
@ -445,6 +379,7 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
|
|||
if (StringUtils.isEmpty(guid)) {
|
||||
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "Guid(s) not specified");
|
||||
}
|
||||
|
||||
if (CollectionUtils.isEmpty(classifications)) {
|
||||
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "classifications(s) not specified");
|
||||
}
|
||||
|
|
@ -453,6 +388,13 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
|
|||
LOG.debug("Adding classifications={} to entity={}", classifications, guid);
|
||||
}
|
||||
|
||||
AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(guid);
|
||||
|
||||
for (AtlasClassification classification : classifications) {
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_ADD_CLASSIFICATION, entityHeader, classification),
|
||||
"add classification: guid=", guid, ", classification=", classification.getTypeName());
|
||||
}
|
||||
|
||||
GraphTransactionInterceptor.lockObjectAndReleasePostCommit(guid);
|
||||
for (AtlasClassification classification : classifications) {
|
||||
validateAndNormalize(classification);
|
||||
|
|
@ -479,6 +421,12 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
|
|||
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "classifications(s) not specified");
|
||||
}
|
||||
|
||||
AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(guid);
|
||||
|
||||
for (AtlasClassification classification : classifications) {
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_UPDATE_CLASSIFICATION, entityHeader, classification), "update classification: guid=", guid, ", classification=", classification.getTypeName());
|
||||
}
|
||||
|
||||
GraphTransactionInterceptor.lockObjectAndReleasePostCommit(guid);
|
||||
|
||||
entityGraphMapper.updateClassifications(new EntityMutationContext(), guid, classifications);
|
||||
|
|
@ -494,6 +442,13 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
|
|||
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "classification not specified");
|
||||
}
|
||||
|
||||
for (String guid : guids) {
|
||||
AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(guid);
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_ADD_CLASSIFICATION, entityHeader, classification),
|
||||
"add classification: guid=", guid, ", classification=", classification.getTypeName());
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Adding classification={} to entities={}", classification, guids);
|
||||
}
|
||||
|
|
@ -521,6 +476,12 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
|
|||
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "classifications(s) not specified");
|
||||
}
|
||||
|
||||
AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(guid);
|
||||
|
||||
for (String classification : classificationNames) {
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_UPDATE_CLASSIFICATION, entityHeader, new AtlasClassification(classification)), "remove classification: guid=", guid, ", classification=", classification);
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Deleting classifications={} from entity={}", classificationNames, guid);
|
||||
}
|
||||
|
|
@ -537,8 +498,11 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
|
|||
LOG.debug("Getting classifications for entity={}", guid);
|
||||
}
|
||||
|
||||
EntityGraphRetriever graphRetriever = new EntityGraphRetriever(typeRegistry);
|
||||
return graphRetriever.getClassifications(guid);
|
||||
AtlasEntityHeader entityHeader = entityRetriever.toAtlasEntityHeaderWithClassifications(guid);
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ_CLASSIFICATION, entityHeader), "get classifications: guid=", guid);
|
||||
|
||||
return entityHeader.getClassifications();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -548,8 +512,110 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
|
|||
LOG.debug("Getting classifications for entities={}", guid);
|
||||
}
|
||||
|
||||
EntityGraphRetriever graphRetriever = new EntityGraphRetriever(typeRegistry);
|
||||
return graphRetriever.getClassification(guid, classificationName);
|
||||
AtlasClassification ret = null;
|
||||
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);
|
||||
|
||||
for (AtlasClassification classification : entityHeader.getClassifications()) {
|
||||
if (!StringUtils.equalsIgnoreCase(classification.getTypeName(), classificationName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty(classification.getEntityGuid()) || StringUtils.equalsIgnoreCase(classification.getEntityGuid(), guid)) {
|
||||
ret = classification;
|
||||
break;
|
||||
} else if (ret == null) {
|
||||
ret = classification;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == null) {
|
||||
throw new AtlasBaseException(AtlasErrorCode.CLASSIFICATION_NOT_FOUND, classificationName);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private EntityMutationResponse createOrUpdate(EntityStream entityStream, boolean isPartialUpdate, boolean replaceClassifications) throws AtlasBaseException {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("==> createOrUpdate()");
|
||||
}
|
||||
|
||||
if (entityStream == null || !entityStream.hasNext()) {
|
||||
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "no entities to create/update.");
|
||||
}
|
||||
|
||||
AtlasPerfTracer perf = null;
|
||||
|
||||
if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
|
||||
perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "createOrUpdate()");
|
||||
}
|
||||
|
||||
try {
|
||||
final boolean isImport = entityStream instanceof EntityImportStream;
|
||||
final EntityMutationContext context = preCreateOrUpdate(entityStream, entityGraphMapper, isPartialUpdate);
|
||||
|
||||
// Check if authorized to create entities
|
||||
if (!isImport && CollectionUtils.isNotEmpty(context.getCreatedEntities())) {
|
||||
for (AtlasEntity entity : context.getCreatedEntities()) {
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_CREATE, new AtlasEntityHeader(entity)),
|
||||
"create entity: type=", entity.getTypeName());
|
||||
}
|
||||
}
|
||||
|
||||
// for existing entities, skip update if incoming entity doesn't have any change
|
||||
if (CollectionUtils.isNotEmpty(context.getUpdatedEntities())) {
|
||||
List<AtlasEntity> entitiesToSkipUpdate = null;
|
||||
|
||||
for (AtlasEntity entity : context.getUpdatedEntities()) {
|
||||
String guid = entity.getGuid();
|
||||
AtlasVertex vertex = context.getVertex(guid);
|
||||
AtlasEntity entityInStore = entityRetriever.toAtlasEntity(vertex);
|
||||
AtlasEntityType entityType = typeRegistry.getEntityTypeByName(entity.getTypeName());
|
||||
|
||||
if (!AtlasEntityUtil.hasAnyAttributeUpdate(entityType, entity, entityInStore)) {
|
||||
// if classifications are to be replaced as well, then skip updates only when no change in classifications as well
|
||||
if (!replaceClassifications || Objects.equals(entity.getClassifications(), entityInStore.getClassifications())) {
|
||||
if (entitiesToSkipUpdate == null) {
|
||||
entitiesToSkipUpdate = new ArrayList<>();
|
||||
}
|
||||
|
||||
entitiesToSkipUpdate.add(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entitiesToSkipUpdate != null) {
|
||||
context.getUpdatedEntities().removeAll(entitiesToSkipUpdate);
|
||||
}
|
||||
|
||||
// Check if authorized to update entities
|
||||
if (!isImport) {
|
||||
for (AtlasEntity entity : context.getUpdatedEntities()) {
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_UPDATE, new AtlasEntityHeader(entity)),
|
||||
"update entity: type=", entity.getTypeName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EntityMutationResponse ret = entityGraphMapper.mapAttributesAndClassifications(context, isPartialUpdate, replaceClassifications);
|
||||
|
||||
ret.setGuidAssignments(context.getGuidAssignments());
|
||||
|
||||
// Notify the change listeners
|
||||
entityChangeNotifier.onEntitiesMutated(ret, isImport);
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("<== createOrUpdate()");
|
||||
}
|
||||
|
||||
return ret;
|
||||
} finally {
|
||||
AtlasPerfTracer.log(perf);
|
||||
}
|
||||
}
|
||||
|
||||
private EntityMutationContext preCreateOrUpdate(EntityStream entityStream, EntityGraphMapper entityGraphMapper, boolean isPartialUpdate) throws AtlasBaseException {
|
||||
|
|
@ -583,11 +649,12 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
|
|||
|
||||
AtlasEntityType entityType = typeRegistry.getEntityTypeByName(entity.getTypeName());
|
||||
|
||||
|
||||
//Create vertices which do not exist in the repository
|
||||
if ((entityStream instanceof EntityImportStream) && AtlasTypeUtil.isAssignedGuid(entity.getGuid())) {
|
||||
vertex = entityGraphMapper.createVertexWithGuid(entity, entity.getGuid());
|
||||
} else {
|
||||
vertex = entityGraphMapper.createVertex(entity);
|
||||
vertex = entityGraphMapper.createVertex(entity);
|
||||
}
|
||||
|
||||
discoveryContext.addResolvedGuid(guid, vertex);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@ package org.apache.atlas.repository.store.graph.v1;
|
|||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.apache.atlas.AtlasErrorCode;
|
||||
import org.apache.atlas.authorize.AtlasPrivilege;
|
||||
import org.apache.atlas.authorize.AtlasTypeAccessRequest;
|
||||
import org.apache.atlas.authorize.AtlasAuthorizationUtils;
|
||||
import org.apache.atlas.exception.AtlasBaseException;
|
||||
import org.apache.atlas.model.typedef.AtlasStructDef;
|
||||
import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
|
||||
|
|
@ -93,12 +96,14 @@ public class AtlasStructDefStoreV1 extends AtlasAbstractDefStoreV1<AtlasStructDe
|
|||
LOG.debug("==> AtlasStructDefStoreV1.create({}, {})", structDef, preCreateResult);
|
||||
}
|
||||
|
||||
AtlasVertex vertex = (preCreateResult == null) ? preCreate(structDef) : preCreateResult;
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_CREATE, structDef), "create struct-def ", structDef.getName());
|
||||
|
||||
if (CollectionUtils.isEmpty(structDef.getAttributeDefs())) {
|
||||
throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "Missing attributes for structdef");
|
||||
}
|
||||
|
||||
AtlasVertex vertex = (preCreateResult == null) ? preCreate(structDef) : preCreateResult;
|
||||
|
||||
AtlasStructDefStoreV1.updateVertexAddReferences(structDef, vertex, typeDefStore);
|
||||
|
||||
AtlasStructDef ret = toStructDef(vertex);
|
||||
|
|
@ -197,6 +202,10 @@ public class AtlasStructDefStoreV1 extends AtlasAbstractDefStoreV1<AtlasStructDe
|
|||
LOG.debug("==> AtlasStructDefStoreV1.updateByName({}, {})", name, structDef);
|
||||
}
|
||||
|
||||
AtlasStructDef existingDef = typeRegistry.getStructDefByName(name);
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_UPDATE, existingDef), "update struct-def ", name);
|
||||
|
||||
validateType(structDef);
|
||||
|
||||
AtlasType type = typeRegistry.getType(structDef.getName());
|
||||
|
|
@ -229,6 +238,10 @@ public class AtlasStructDefStoreV1 extends AtlasAbstractDefStoreV1<AtlasStructDe
|
|||
LOG.debug("==> AtlasStructDefStoreV1.updateByGuid({})", guid);
|
||||
}
|
||||
|
||||
AtlasStructDef existingDef = typeRegistry.getStructDefByGuid(guid);
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_UPDATE, existingDef), "update struct-def ", (existingDef != null ? existingDef.getName() : guid));
|
||||
|
||||
validateType(structDef);
|
||||
|
||||
AtlasType type = typeRegistry.getTypeByGuid(guid);
|
||||
|
|
@ -261,6 +274,10 @@ public class AtlasStructDefStoreV1 extends AtlasAbstractDefStoreV1<AtlasStructDe
|
|||
LOG.debug("==> AtlasStructDefStoreV1.preDeleteByName({})", name);
|
||||
}
|
||||
|
||||
AtlasStructDef existingDef = typeRegistry.getStructDefByName(name);
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_DELETE, existingDef), "delete struct-def ", name);
|
||||
|
||||
AtlasVertex ret = typeDefStore.findTypeVertexByNameAndCategory(name, TypeCategory.STRUCT);
|
||||
|
||||
if (AtlasGraphUtilsV1.typeHasInstanceVertex(name)) {
|
||||
|
|
@ -286,6 +303,10 @@ public class AtlasStructDefStoreV1 extends AtlasAbstractDefStoreV1<AtlasStructDe
|
|||
LOG.debug("==> AtlasStructDefStoreV1.preDeleteByGuid({})", guid);
|
||||
}
|
||||
|
||||
AtlasStructDef existingDef = typeRegistry.getStructDefByGuid(guid);
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_DELETE, existingDef), "delete struct-def ", (existingDef != null ? existingDef.getName() : guid));
|
||||
|
||||
AtlasVertex ret = typeDefStore.findTypeVertexByGuidAndCategory(guid, TypeCategory.STRUCT);
|
||||
|
||||
String typeName = AtlasGraphUtilsV1.getProperty(ret, Constants.TYPENAME_PROPERTY_KEY, String.class);
|
||||
|
|
|
|||
|
|
@ -170,6 +170,22 @@ public final class EntityGraphRetriever {
|
|||
return atlasVertex != null ? mapVertexToAtlasEntityHeader(atlasVertex, attributes) : null;
|
||||
}
|
||||
|
||||
public AtlasEntityHeader toAtlasEntityHeaderWithClassifications(String guid) throws AtlasBaseException {
|
||||
return toAtlasEntityHeaderWithClassifications(getEntityVertex(guid), Collections.emptySet());
|
||||
}
|
||||
|
||||
public AtlasEntityHeader toAtlasEntityHeaderWithClassifications(AtlasVertex entityVertex) throws AtlasBaseException {
|
||||
return toAtlasEntityHeaderWithClassifications(entityVertex, Collections.emptySet());
|
||||
}
|
||||
|
||||
public AtlasEntityHeader toAtlasEntityHeaderWithClassifications(AtlasVertex entityVertex, Set<String> attributes) throws AtlasBaseException {
|
||||
AtlasEntityHeader ret = toAtlasEntityHeader(entityVertex, attributes);
|
||||
|
||||
ret.setClassifications(getClassifications(entityVertex));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public AtlasEntityHeader toAtlasEntityHeader(AtlasEntity entity) {
|
||||
AtlasEntityHeader ret = null;
|
||||
String typeName = entity.getTypeName();
|
||||
|
|
@ -187,6 +203,19 @@ public final class EntityGraphRetriever {
|
|||
}
|
||||
|
||||
ret = new AtlasEntityHeader(entity.getTypeName(), entity.getGuid(), uniqueAttributes);
|
||||
|
||||
if (CollectionUtils.isNotEmpty(entity.getClassifications())) {
|
||||
List<AtlasClassification> classifications = new ArrayList<>(entity.getClassifications().size());
|
||||
List<String> classificationNames = new ArrayList<>(entity.getClassifications().size());
|
||||
|
||||
for (AtlasClassification classification : entity.getClassifications()) {
|
||||
classifications.add(classification);
|
||||
classificationNames.add(classification.getTypeName());
|
||||
}
|
||||
|
||||
ret.setClassifications(classifications);
|
||||
ret.setClassificationNames(classificationNames);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
@ -218,7 +247,7 @@ public final class EntityGraphRetriever {
|
|||
AtlasClassification ret = new AtlasClassification(getTypeName(classificationVertex));
|
||||
|
||||
ret.setEntityGuid(AtlasGraphUtilsV1.getProperty(classificationVertex, CLASSIFICATION_ENTITY_GUID, String.class));
|
||||
ret.setPropagate(AtlasGraphUtilsV1.getProperty(classificationVertex, CLASSIFICATION_PROPAGATE_KEY, Boolean.class));
|
||||
ret.setPropagate(isPropagationEnabled(classificationVertex));
|
||||
|
||||
String strValidityPeriods = AtlasGraphUtilsV1.getProperty(classificationVertex, CLASSIFICATION_VALIDITY_PERIODS_KEY, String.class);
|
||||
|
||||
|
|
|
|||
|
|
@ -173,30 +173,32 @@ public class AtlasRepositoryConfiguration {
|
|||
* @throws AtlasException
|
||||
*/
|
||||
public static List<String> getAuditExcludedOperations(Configuration config) throws AtlasException {
|
||||
if (config == null) {
|
||||
try {
|
||||
config = ApplicationProperties.get();
|
||||
} catch (AtlasException e) {
|
||||
LOG.error(" Error reading operations for auditing ", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
if (skippedOperations == null) {
|
||||
skippedOperations = new ArrayList<String>();
|
||||
String[] skipAuditForOperations = config
|
||||
.getStringArray(AUDIT_EXCLUDED_OPERATIONS);
|
||||
if (skipAuditForOperations != null
|
||||
&& skipAuditForOperations.length > 0) {
|
||||
for (String skippedOperation : skipAuditForOperations) {
|
||||
String[] excludedOperations = skippedOperation.trim().toLowerCase().split(SEPARATOR);
|
||||
if (excludedOperations!= null && excludedOperations.length == 2) {
|
||||
skippedOperations.add(skippedOperation.toLowerCase());
|
||||
} else {
|
||||
LOG.error("Invalid format for skipped operation {}. Valid format is HttpMethod:URL eg: GET:Version", skippedOperation);
|
||||
}
|
||||
if (config == null) {
|
||||
try {
|
||||
config = ApplicationProperties.get();
|
||||
} catch (AtlasException e) {
|
||||
LOG.error(" Error reading operations for auditing ", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
skippedOperations = new ArrayList<>();
|
||||
|
||||
String[] skipAuditForOperations = config.getStringArray(AUDIT_EXCLUDED_OPERATIONS);
|
||||
|
||||
if (skipAuditForOperations != null && skipAuditForOperations.length > 0) {
|
||||
for (String skippedOperation : skipAuditForOperations) {
|
||||
String[] excludedOperations = skippedOperation.trim().toLowerCase().split(SEPARATOR);
|
||||
if (excludedOperations!= null && excludedOperations.length == 2) {
|
||||
skippedOperations.add(skippedOperation.toLowerCase());
|
||||
} else {
|
||||
LOG.error("Invalid format for skipped operation {}. Valid format is HttpMethod:URL eg: GET:Version", skippedOperation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return skippedOperations;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ public class ExportServiceTest {
|
|||
@BeforeTest
|
||||
public void setupTest() {
|
||||
RequestContextV1.clear();
|
||||
RequestContextV1.get().setUser(TestUtilsV2.TEST_USER);
|
||||
RequestContextV1.get().setUser(TestUtilsV2.TEST_USER, null);
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ public class ImportServiceTest {
|
|||
@BeforeTest
|
||||
public void setupTest() {
|
||||
RequestContextV1.clear();
|
||||
RequestContextV1.get().setUser(TestUtilsV2.TEST_USER);
|
||||
RequestContextV1.get().setUser(TestUtilsV2.TEST_USER, null);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ public class ZipFileResourceTestUtils {
|
|||
List<String> creationOrder = zipSource.getCreationOrder();
|
||||
|
||||
RequestContextV1.clear();
|
||||
RequestContextV1.get().setUser(TestUtilsV2.TEST_USER);
|
||||
RequestContextV1.get().setUser(TestUtilsV2.TEST_USER, null);
|
||||
|
||||
AtlasImportRequest request = getDefaultImportRequest();
|
||||
AtlasImportResult result = runImportWithParameters(importService, request, zipSource);
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ public class AtlasTypeDefGraphStoreTest {
|
|||
@BeforeTest
|
||||
public void setupTest() {
|
||||
RequestContextV1.clear();
|
||||
RequestContextV1.get().setUser(TestUtilsV2.TEST_USER);
|
||||
RequestContextV1.get().setUser(TestUtilsV2.TEST_USER, null);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ public class AtlasEntityStoreV1Test {
|
|||
@BeforeClass
|
||||
public void setUp() throws Exception {
|
||||
RequestContextV1.clear();
|
||||
RequestContextV1.get().setUser(TestUtilsV2.TEST_USER);
|
||||
RequestContextV1.get().setUser(TestUtilsV2.TEST_USER, null);
|
||||
|
||||
new GraphBackedSearchIndexer(typeRegistry);
|
||||
|
||||
|
|
@ -156,7 +156,7 @@ public class AtlasEntityStoreV1Test {
|
|||
public void init() throws Exception {
|
||||
entityStore = new AtlasEntityStoreV1(deleteHandler, typeRegistry, mockChangeNotifier, graphMapper);
|
||||
RequestContextV1.clear();
|
||||
RequestContextV1.get().setUser(TestUtilsV2.TEST_USER);
|
||||
RequestContextV1.get().setUser(TestUtilsV2.TEST_USER, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ public abstract class AtlasRelationshipStoreV1Test {
|
|||
relationshipStore = new AtlasRelationshipStoreV1(typeRegistry, deleteHandler);
|
||||
|
||||
RequestContextV1.clear();
|
||||
RequestContextV1.get().setUser(TestUtilsV2.TEST_USER);
|
||||
RequestContextV1.get().setUser(TestUtilsV2.TEST_USER, null);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ public abstract class InverseReferenceUpdateV1Test {
|
|||
@BeforeClass
|
||||
public void setUp() throws Exception {
|
||||
RequestContextV1.clear();
|
||||
RequestContextV1.get().setUser(TestUtilsV2.TEST_USER);
|
||||
RequestContextV1.get().setUser(TestUtilsV2.TEST_USER, null);
|
||||
|
||||
AtlasTypesDef[] testTypesDefs = new AtlasTypesDef[] { TestUtilsV2.defineDeptEmployeeTypes(),
|
||||
TestUtilsV2.defineInverseReferenceTestTypes()
|
||||
|
|
@ -109,7 +109,7 @@ public abstract class InverseReferenceUpdateV1Test {
|
|||
@BeforeMethod
|
||||
public void init() throws Exception {
|
||||
RequestContextV1.clear();
|
||||
RequestContextV1.get().setUser(TestUtilsV2.TEST_USER);
|
||||
RequestContextV1.get().setUser(TestUtilsV2.TEST_USER, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
package org.apache.atlas;
|
||||
|
||||
import org.apache.atlas.metrics.Metrics;
|
||||
import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo;
|
||||
import org.apache.atlas.model.instance.AtlasObjectId;
|
||||
import org.slf4j.Logger;
|
||||
|
|
@ -34,10 +33,10 @@ public class RequestContextV1 {
|
|||
private final Map<String, AtlasObjectId> updatedEntities = new HashMap<>();
|
||||
private final Map<String, AtlasObjectId> deletedEntities = new HashMap<>();
|
||||
private final Map<String, AtlasEntityWithExtInfo> entityCacheV2 = new HashMap<>();
|
||||
private final Metrics metrics = new Metrics();
|
||||
private final long requestTime = System.currentTimeMillis();
|
||||
|
||||
private String user;
|
||||
private String user;
|
||||
private Set<String> userGroups;
|
||||
|
||||
private RequestContextV1() {
|
||||
}
|
||||
|
|
@ -71,8 +70,13 @@ public class RequestContextV1 {
|
|||
return user;
|
||||
}
|
||||
|
||||
public void setUser(String user) {
|
||||
this.user = user;
|
||||
public Set<String> getUserGroups() {
|
||||
return userGroups;
|
||||
}
|
||||
|
||||
public void setUser(String user, Set<String> userGroups) {
|
||||
this.user = user;
|
||||
this.userGroups = userGroups;
|
||||
}
|
||||
|
||||
public void recordEntityUpdate(AtlasObjectId entity) {
|
||||
|
|
@ -127,8 +131,4 @@ public class RequestContextV1 {
|
|||
public boolean isDeletedEntity(String guid) {
|
||||
return deletedEntities.containsKey(guid);
|
||||
}
|
||||
|
||||
public static Metrics getMetrics() {
|
||||
return get().metrics;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +0,0 @@
|
|||
/**
|
||||
* 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
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* 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.aspect;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface Loggable {
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
/**
|
||||
* 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
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* 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.aspect;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface Monitored {
|
||||
}
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
/**
|
||||
* 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.discovery;
|
||||
|
||||
import org.apache.atlas.AtlasException;
|
||||
|
||||
import java.security.PrivilegedActionException;
|
||||
|
||||
public class DiscoveryException extends AtlasException {
|
||||
|
||||
/**
|
||||
* Constructs a new exception with the specified detail message. The
|
||||
* cause is not initialized, and may subsequently be initialized by
|
||||
* a call to {@link #initCause}.
|
||||
*
|
||||
* @param message the detail message. The detail message is saved for
|
||||
* later retrieval by the {@link #getMessage()} method.
|
||||
*/
|
||||
public DiscoveryException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new exception with the specified detail message and
|
||||
* cause. <p>Note that the detail message associated with
|
||||
* {@code cause} is <i>not</i> automatically incorporated in
|
||||
* this exception's detail message.
|
||||
*
|
||||
* @param message the detail message (which is saved for later retrieval
|
||||
* by the {@link #getMessage()} method).
|
||||
* @param cause the cause (which is saved for later retrieval by the
|
||||
* {@link #getCause()} method). (A <tt>null</tt> value is
|
||||
* permitted, and indicates that the cause is nonexistent or
|
||||
* unknown.)
|
||||
* @since 1.4
|
||||
*/
|
||||
public DiscoveryException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new exception with the specified cause and a detail
|
||||
* message of <tt>(cause==null ? null : cause.toString())</tt> (which
|
||||
* typically contains the class and detail message of <tt>cause</tt>).
|
||||
* This constructor is useful for exceptions that are little more than
|
||||
* wrappers for other throwables (for example, {@link
|
||||
* PrivilegedActionException}).
|
||||
*
|
||||
* @param cause the cause (which is saved for later retrieval by the
|
||||
* {@link #getCause()} method). (A <tt>null</tt> value is
|
||||
* permitted, and indicates that the cause is nonexistent or
|
||||
* unknown.)
|
||||
* @since 1.4
|
||||
*/
|
||||
public DiscoveryException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
/**
|
||||
* 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.exception;
|
||||
|
||||
/**
|
||||
* A simple wrapper for 404.
|
||||
* Thrown when a requested trait can not be found.
|
||||
*/
|
||||
public class TraitNotFoundException extends NotFoundException {
|
||||
public TraitNotFoundException() {
|
||||
}
|
||||
|
||||
public TraitNotFoundException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public TraitNotFoundException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public TraitNotFoundException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public TraitNotFoundException(String message, Throwable cause, boolean enableSuppression,
|
||||
boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
/**
|
||||
* 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
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* 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.metrics;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Metrics {
|
||||
public static class Counters {
|
||||
private short invocations = 0;
|
||||
private long totalTimeMSecs = 0;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[count=" + invocations + ", totalTimeMSec=" + totalTimeMSecs + "]";
|
||||
}
|
||||
|
||||
public short getInvocations() {
|
||||
return invocations;
|
||||
}
|
||||
|
||||
public long getTotalTimeMSecs() {
|
||||
return totalTimeMSecs;
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Counters> countersMap = new LinkedHashMap<>();
|
||||
|
||||
public void record(String name, long timeMsecs) {
|
||||
Counters counter = countersMap.get(name);
|
||||
if (counter == null) {
|
||||
counter = new Counters();
|
||||
countersMap.put(name, counter);
|
||||
}
|
||||
|
||||
counter.invocations++;
|
||||
counter.totalTimeMSecs += timeMsecs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return countersMap.toString();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return countersMap.isEmpty();
|
||||
}
|
||||
|
||||
public Counters getCounters(String name) {
|
||||
return countersMap.get(name);
|
||||
}
|
||||
}
|
||||
|
|
@ -21,7 +21,6 @@ import com.google.common.annotations.VisibleForTesting;
|
|||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import kafka.utils.ShutdownableThread;
|
||||
import org.apache.atlas.ApplicationProperties;
|
||||
import org.apache.atlas.AtlasBaseClient;
|
||||
import org.apache.atlas.AtlasClient;
|
||||
import org.apache.atlas.AtlasClientV2;
|
||||
import org.apache.atlas.AtlasException;
|
||||
|
|
@ -53,8 +52,8 @@ import org.apache.atlas.type.AtlasEntityType;
|
|||
import org.apache.atlas.type.AtlasTypeRegistry;
|
||||
import org.apache.atlas.utils.AtlasPerfTracer;
|
||||
import org.apache.atlas.web.filters.AuditFilter;
|
||||
import org.apache.atlas.web.filters.AuditFilter.AuditLog;
|
||||
import org.apache.atlas.web.service.ServiceState;
|
||||
import org.apache.atlas.web.util.DateTimeHelper;
|
||||
import org.apache.commons.configuration.Configuration;
|
||||
import org.apache.kafka.common.TopicPartition;
|
||||
import org.slf4j.Logger;
|
||||
|
|
@ -70,10 +69,6 @@ import java.util.concurrent.Executors;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static org.apache.atlas.AtlasClientV2.API_V2.DELETE_ENTITY_BY_ATTRIBUTE;
|
||||
import static org.apache.atlas.AtlasClientV2.API_V2.UPDATE_ENTITY;
|
||||
import static org.apache.atlas.AtlasClientV2.API_V2.UPDATE_ENTITY_BY_ATTRIBUTE;
|
||||
|
||||
/**
|
||||
* Consumer of notifications from hooks e.g., hive hook etc.
|
||||
*/
|
||||
|
|
@ -85,7 +80,8 @@ public class NotificationHookConsumer implements Service, ActiveStateChangeHandl
|
|||
private static final Logger PERF_LOG = AtlasPerfTracer.getPerfLogger(NotificationHookConsumer.class);
|
||||
private static final Logger FAILED_LOG = LoggerFactory.getLogger("FAILED");
|
||||
|
||||
private static final String LOCALHOST = "localhost";
|
||||
private static final int SC_OK = 200;
|
||||
private static final int SC_BAD_REQUEST = 400;
|
||||
private static final String THREADNAME_PREFIX = NotificationHookConsumer.class.getSimpleName();
|
||||
|
||||
public static final String CONSUMER_THREADS_PROPERTY = "atlas.notification.hook.numthreads";
|
||||
|
|
@ -353,6 +349,9 @@ public class NotificationHookConsumer implements Service, ActiveStateChangeHandl
|
|||
AtlasPerfTracer perf = null;
|
||||
HookNotification message = kafkaMsg.getMessage();
|
||||
String messageUser = message.getUser();
|
||||
long startTime = System.currentTimeMillis();
|
||||
boolean isFailedMsg = false;
|
||||
AuditLog auditLog = null;
|
||||
|
||||
if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
|
||||
perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, message.getType().name());
|
||||
|
|
@ -368,17 +367,17 @@ public class NotificationHookConsumer implements Service, ActiveStateChangeHandl
|
|||
try {
|
||||
RequestContextV1 requestContext = RequestContextV1.get();
|
||||
|
||||
requestContext.setUser(messageUser);
|
||||
requestContext.setUser(messageUser, null);
|
||||
|
||||
switch (message.getType()) {
|
||||
case ENTITY_CREATE: {
|
||||
final EntityCreateRequest createRequest = (EntityCreateRequest) message;
|
||||
final AtlasEntitiesWithExtInfo entities = instanceConverter.toAtlasEntities(createRequest.getEntities());
|
||||
|
||||
if (numRetries == 0) { // audit only on the first attempt
|
||||
AtlasBaseClient.API api = AtlasClient.API_V1.CREATE_ENTITY;
|
||||
|
||||
audit(messageUser, api.getMethod(), api.getNormalizedPath());
|
||||
if (auditLog == null) {
|
||||
auditLog = new AuditLog(messageUser, THREADNAME_PREFIX,
|
||||
AtlasClient.API_V1.CREATE_ENTITY.getMethod(),
|
||||
AtlasClient.API_V1.CREATE_ENTITY.getNormalizedPath());
|
||||
}
|
||||
|
||||
atlasEntityStore.createOrUpdate(new AtlasEntityStream(entities), false);
|
||||
|
|
@ -390,9 +389,10 @@ public class NotificationHookConsumer implements Service, ActiveStateChangeHandl
|
|||
final Referenceable referenceable = partialUpdateRequest.getEntity();
|
||||
final AtlasEntitiesWithExtInfo entities = instanceConverter.toAtlasEntity(referenceable);
|
||||
|
||||
if (numRetries == 0) { // audit only on the first attempt
|
||||
AtlasBaseClient.API api = UPDATE_ENTITY_BY_ATTRIBUTE;
|
||||
audit(messageUser, api.getMethod(), String.format(api.getNormalizedPath(), partialUpdateRequest.getTypeName()));
|
||||
if (auditLog == null) {
|
||||
auditLog = new AuditLog(messageUser, THREADNAME_PREFIX,
|
||||
AtlasClientV2.API_V2.UPDATE_ENTITY_BY_ATTRIBUTE.getMethod(),
|
||||
String.format(AtlasClientV2.API_V2.UPDATE_ENTITY_BY_ATTRIBUTE.getNormalizedPath(), partialUpdateRequest.getTypeName()));
|
||||
}
|
||||
|
||||
AtlasEntityType entityType = typeRegistry.getEntityTypeByName(partialUpdateRequest.getTypeName());
|
||||
|
|
@ -408,9 +408,10 @@ public class NotificationHookConsumer implements Service, ActiveStateChangeHandl
|
|||
case ENTITY_DELETE: {
|
||||
final EntityDeleteRequest deleteRequest = (EntityDeleteRequest) message;
|
||||
|
||||
if (numRetries == 0) { // audit only on the first attempt
|
||||
AtlasBaseClient.API api = DELETE_ENTITY_BY_ATTRIBUTE;
|
||||
audit(messageUser, api.getMethod(), String.format(api.getNormalizedPath(), deleteRequest.getTypeName()));
|
||||
if (auditLog == null) {
|
||||
auditLog = new AuditLog(messageUser, THREADNAME_PREFIX,
|
||||
AtlasClientV2.API_V2.DELETE_ENTITY_BY_ATTRIBUTE.getMethod(),
|
||||
String.format(AtlasClientV2.API_V2.DELETE_ENTITY_BY_ATTRIBUTE.getNormalizedPath(), deleteRequest.getTypeName()));
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
@ -427,10 +428,10 @@ public class NotificationHookConsumer implements Service, ActiveStateChangeHandl
|
|||
final EntityUpdateRequest updateRequest = (EntityUpdateRequest) message;
|
||||
final AtlasEntitiesWithExtInfo entities = instanceConverter.toAtlasEntities(updateRequest.getEntities());
|
||||
|
||||
if (numRetries == 0) { // audit only on the first attempt
|
||||
AtlasBaseClient.API api = UPDATE_ENTITY;
|
||||
|
||||
audit(messageUser, api.getMethod(), api.getNormalizedPath());
|
||||
if (auditLog == null) {
|
||||
auditLog = new AuditLog(messageUser, THREADNAME_PREFIX,
|
||||
AtlasClientV2.API_V2.UPDATE_ENTITY.getMethod(),
|
||||
AtlasClientV2.API_V2.UPDATE_ENTITY.getNormalizedPath());
|
||||
}
|
||||
|
||||
atlasEntityStore.createOrUpdate(new AtlasEntityStream(entities), false);
|
||||
|
|
@ -441,9 +442,10 @@ public class NotificationHookConsumer implements Service, ActiveStateChangeHandl
|
|||
final EntityCreateRequestV2 createRequestV2 = (EntityCreateRequestV2) message;
|
||||
final AtlasEntitiesWithExtInfo entities = createRequestV2.getEntities();
|
||||
|
||||
if (numRetries == 0) { // audit only on the first attempt
|
||||
AtlasBaseClient.API api = AtlasClientV2.API_V2.CREATE_ENTITY;
|
||||
audit(messageUser, api.getMethod(), api.getNormalizedPath());
|
||||
if (auditLog == null) {
|
||||
auditLog = new AuditLog(messageUser, THREADNAME_PREFIX,
|
||||
AtlasClientV2.API_V2.CREATE_ENTITY.getMethod(),
|
||||
AtlasClientV2.API_V2.CREATE_ENTITY.getNormalizedPath());
|
||||
}
|
||||
|
||||
atlasEntityStore.createOrUpdate(new AtlasEntityStream(entities), false);
|
||||
|
|
@ -455,9 +457,10 @@ public class NotificationHookConsumer implements Service, ActiveStateChangeHandl
|
|||
final AtlasObjectId entityId = partialUpdateRequest.getEntityId();
|
||||
final AtlasEntityWithExtInfo entity = partialUpdateRequest.getEntity();
|
||||
|
||||
if (numRetries == 0) { // audit only on the first attempt
|
||||
AtlasBaseClient.API api = AtlasClientV2.API_V2.UPDATE_ENTITY;
|
||||
audit(messageUser, api.getMethod(), api.getNormalizedPath());
|
||||
if (auditLog == null) {
|
||||
auditLog = new AuditLog(messageUser, THREADNAME_PREFIX,
|
||||
AtlasClientV2.API_V2.UPDATE_ENTITY.getMethod(),
|
||||
AtlasClientV2.API_V2.UPDATE_ENTITY.getNormalizedPath());
|
||||
}
|
||||
|
||||
atlasEntityStore.updateEntity(entityId, entity, true);
|
||||
|
|
@ -468,9 +471,10 @@ public class NotificationHookConsumer implements Service, ActiveStateChangeHandl
|
|||
final EntityUpdateRequestV2 updateRequest = (EntityUpdateRequestV2) message;
|
||||
final AtlasEntitiesWithExtInfo entities = updateRequest.getEntities();
|
||||
|
||||
if (numRetries == 0) { // audit only on the first attempt
|
||||
AtlasBaseClient.API api = AtlasClientV2.API_V2.UPDATE_ENTITY;
|
||||
audit(messageUser, api.getMethod(), api.getNormalizedPath());
|
||||
if (auditLog == null) {
|
||||
auditLog = new AuditLog(messageUser, THREADNAME_PREFIX,
|
||||
AtlasClientV2.API_V2.UPDATE_ENTITY.getMethod(),
|
||||
AtlasClientV2.API_V2.UPDATE_ENTITY.getNormalizedPath());
|
||||
}
|
||||
|
||||
atlasEntityStore.createOrUpdate(new AtlasEntityStream(entities), false);
|
||||
|
|
@ -483,9 +487,10 @@ public class NotificationHookConsumer implements Service, ActiveStateChangeHandl
|
|||
|
||||
try {
|
||||
for (AtlasObjectId entity : entities) {
|
||||
if (numRetries == 0) { // audit only on the first attempt
|
||||
AtlasBaseClient.API api = AtlasClientV2.API_V2.DELETE_ENTITY_BY_ATTRIBUTE;
|
||||
audit(messageUser, api.getMethod(), String.format(api.getNormalizedPath(), entity.getTypeName()));
|
||||
if (auditLog == null) {
|
||||
auditLog = new AuditLog(messageUser, THREADNAME_PREFIX,
|
||||
AtlasClientV2.API_V2.DELETE_ENTITY_BY_ATTRIBUTE.getMethod(),
|
||||
String.format(AtlasClientV2.API_V2.DELETE_ENTITY_BY_ATTRIBUTE.getNormalizedPath(), entity.getTypeName()));
|
||||
}
|
||||
|
||||
AtlasEntityType type = (AtlasEntityType) typeRegistry.getType(entity.getTypeName());
|
||||
|
|
@ -516,6 +521,8 @@ public class NotificationHookConsumer implements Service, ActiveStateChangeHandl
|
|||
if (numRetries == (maxRetries - 1)) {
|
||||
LOG.warn("Max retries exceeded for message {}", message, e);
|
||||
|
||||
isFailedMsg = true;
|
||||
|
||||
failedMessages.add(message);
|
||||
|
||||
if (failedMessages.size() >= failedMsgCacheSize) {
|
||||
|
|
@ -527,9 +534,17 @@ public class NotificationHookConsumer implements Service, ActiveStateChangeHandl
|
|||
RequestContextV1.clear();
|
||||
}
|
||||
}
|
||||
|
||||
commit(kafkaMsg);
|
||||
} finally {
|
||||
AtlasPerfTracer.log(perf);
|
||||
|
||||
if (auditLog != null) {
|
||||
auditLog.setHttpStatus(isFailedMsg ? SC_BAD_REQUEST : SC_OK);
|
||||
auditLog.setTimeTaken(System.currentTimeMillis() - startTime);
|
||||
|
||||
AuditFilter.audit(auditLog);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -597,12 +612,4 @@ public class NotificationHookConsumer implements Service, ActiveStateChangeHandl
|
|||
LOG.info("<== HookConsumer shutdown()");
|
||||
}
|
||||
}
|
||||
|
||||
private void audit(String messageUser, String method, String path) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("==> audit({},{}, {})", messageUser, method, path);
|
||||
}
|
||||
|
||||
AuditFilter.audit(messageUser, THREADNAME_PREFIX, method, LOCALHOST, path, LOCALHOST, DateTimeHelper.formatDateUTC(new Date()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -328,10 +328,7 @@ public class AtlasAuthenticationFilter extends AuthenticationFilter {
|
|||
try {
|
||||
String requestUser = httpRequest.getRemoteUser();
|
||||
NDC.push(requestUser + ":" + httpRequest.getMethod() + httpRequest.getRequestURI());
|
||||
RequestContextV1 requestContext = RequestContextV1.get();
|
||||
if (requestContext != null) {
|
||||
requestContext.setUser(requestUser);
|
||||
}
|
||||
|
||||
LOG.info("Request from authenticated user: {}, URL={}", requestUser,
|
||||
Servlets.getRequestURI(httpRequest));
|
||||
|
||||
|
|
|
|||
|
|
@ -1,180 +0,0 @@
|
|||
/*
|
||||
* 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.web.filters;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import org.apache.atlas.AtlasClient;
|
||||
import org.apache.atlas.authorize.AtlasAccessRequest;
|
||||
import org.apache.atlas.authorize.AtlasAuthorizationException;
|
||||
import org.apache.atlas.authorize.AtlasAuthorizer;
|
||||
import org.apache.atlas.authorize.AtlasAuthorizerFactory;
|
||||
import org.apache.atlas.authorize.AtlasResourceTypes;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.GenericFilterBean;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@Component
|
||||
public class AtlasAuthorizationFilter extends GenericFilterBean {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AtlasAuthorizationFilter.class);
|
||||
private static boolean isDebugEnabled = LOG.isDebugEnabled();
|
||||
private AtlasAuthorizer authorizer = null;
|
||||
|
||||
private final String BASE_URL = "/" + AtlasClient.BASE_URI;
|
||||
|
||||
public AtlasAuthorizationFilter() {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("==> AtlasAuthorizationFilter() -- " + "Now initializing the Apache Atlas Authorizer!!!");
|
||||
}
|
||||
|
||||
try {
|
||||
authorizer = AtlasAuthorizerFactory.getAtlasAuthorizer();
|
||||
if (authorizer != null) {
|
||||
authorizer.init();
|
||||
} else {
|
||||
LOG.warn("AtlasAuthorizer not initialized properly, please check the application logs and add proper configurations.");
|
||||
}
|
||||
} catch (AtlasAuthorizationException e) {
|
||||
LOG.error("Unable to obtain AtlasAuthorizer. ", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("==> AtlasAuthorizationFilter destroy");
|
||||
}
|
||||
if (authorizer != null) {
|
||||
authorizer.cleanUp();
|
||||
}
|
||||
super.destroy();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,
|
||||
ServletException {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("==> AuthorizationFilter.doFilter");
|
||||
}
|
||||
|
||||
HttpServletRequest request = (HttpServletRequest) req;
|
||||
HttpServletResponse response = (HttpServletResponse) res;
|
||||
AtlasResponseRequestWrapper responseWrapper = new AtlasResponseRequestWrapper(response);
|
||||
responseWrapper.setHeader("X-Frame-Options", "DENY");
|
||||
|
||||
String pathInfo = request.getServletPath();
|
||||
if (!Strings.isNullOrEmpty(pathInfo) && (pathInfo.startsWith(BASE_URL) || BASE_URL.startsWith(pathInfo))) {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("{} is a valid REST API request!!!", pathInfo);
|
||||
}
|
||||
|
||||
String userName = null;
|
||||
Set<String> groups = new HashSet<>();
|
||||
|
||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
|
||||
if (auth != null) {
|
||||
userName = auth.getName();
|
||||
Collection<? extends GrantedAuthority> authorities = auth.getAuthorities();
|
||||
for (GrantedAuthority c : authorities) {
|
||||
groups.add(c.getAuthority());
|
||||
}
|
||||
} else {
|
||||
if (LOG.isErrorEnabled()) {
|
||||
LOG.error("Cannot obtain Security Context");
|
||||
}
|
||||
throw new ServletException("Cannot obtain Security Context");
|
||||
}
|
||||
|
||||
AtlasAccessRequest atlasRequest = new AtlasAccessRequest(request, userName, groups);
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("============================\nUserName :: {}\nGroups :: {}\nURL :: {}\nAction :: {}\nrequest.getServletPath() :: {}\n============================\n", atlasRequest.getUser(), atlasRequest.getUserGroups(), request.getRequestURL(), atlasRequest.getAction(), pathInfo);
|
||||
}
|
||||
|
||||
boolean accessAllowed = false;
|
||||
|
||||
Set<AtlasResourceTypes> atlasResourceTypes = atlasRequest.getResourceTypes();
|
||||
if (atlasResourceTypes.size() == 1 && atlasResourceTypes.contains(AtlasResourceTypes.UNKNOWN)) {
|
||||
// Allowing access to unprotected resource types
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Allowing access to unprotected resource types {}", atlasResourceTypes);
|
||||
}
|
||||
accessAllowed = true;
|
||||
} else {
|
||||
|
||||
try {
|
||||
if (authorizer != null) {
|
||||
accessAllowed = authorizer.isAccessAllowed(atlasRequest);
|
||||
}
|
||||
} catch (AtlasAuthorizationException e) {
|
||||
if (LOG.isErrorEnabled()) {
|
||||
LOG.error("Access Restricted. Could not process the request :: {}", e);
|
||||
}
|
||||
}
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("Authorizer result :: {}", accessAllowed);
|
||||
}
|
||||
}
|
||||
|
||||
if (accessAllowed) {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("Access is allowed so forwarding the request!!!");
|
||||
}
|
||||
chain.doFilter(req, res);
|
||||
} else {
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("AuthorizationError", "You are not authorized for " + atlasRequest.getAction().name() + " on "
|
||||
+ atlasResourceTypes + " : " + atlasRequest.getResource());
|
||||
|
||||
response.setContentType("application/json");
|
||||
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
|
||||
|
||||
response.sendError(HttpServletResponse.SC_FORBIDDEN, json.toString());
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("You are not authorized for {} on {} : {}\nReturning 403 since the access is blocked update!!!!", atlasRequest.getAction().name(), atlasResourceTypes, atlasRequest.getResource());
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (isDebugEnabled) {
|
||||
LOG.debug("Ignoring request {}", pathInfo);
|
||||
}
|
||||
chain.doFilter(req, res);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@ package org.apache.atlas.web.filters;
|
|||
import org.apache.atlas.AtlasClient;
|
||||
import org.apache.atlas.AtlasException;
|
||||
import org.apache.atlas.RequestContextV1;
|
||||
import org.apache.atlas.metrics.Metrics;
|
||||
import org.apache.atlas.authorize.AtlasAuthorizationUtils;
|
||||
import org.apache.atlas.util.AtlasRepositoryConfiguration;
|
||||
import org.apache.atlas.web.util.DateTimeHelper;
|
||||
import org.apache.atlas.web.util.Servlets;
|
||||
|
|
@ -40,6 +40,7 @@ import javax.servlet.http.HttpServletRequest;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
|
|
@ -48,9 +49,8 @@ import java.util.UUID;
|
|||
*/
|
||||
@Component
|
||||
public class AuditFilter implements Filter {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AuditFilter.class);
|
||||
private static final Logger AUDIT_LOG = LoggerFactory.getLogger("AUDIT");
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AuditFilter.class);
|
||||
private static final Logger METRICS_LOG = LoggerFactory.getLogger("METRICS");
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
|
|
@ -60,25 +60,32 @@ public class AuditFilter implements Filter {
|
|||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
|
||||
throws IOException, ServletException {
|
||||
final String requestTimeISO9601 = DateTimeHelper.formatDateUTC(new Date());
|
||||
final HttpServletRequest httpRequest = (HttpServletRequest) request;
|
||||
final String requestId = UUID.randomUUID().toString();
|
||||
final Thread currentThread = Thread.currentThread();
|
||||
final String oldName = currentThread.getName();
|
||||
String user = getUserFromRequest(httpRequest);
|
||||
final long startTime = System.currentTimeMillis();
|
||||
final Date requestTime = new Date();
|
||||
final HttpServletRequest httpRequest = (HttpServletRequest) request;
|
||||
final HttpServletResponse httpResponse = (HttpServletResponse) response;
|
||||
final String requestId = UUID.randomUUID().toString();
|
||||
final Thread currentThread = Thread.currentThread();
|
||||
final String oldName = currentThread.getName();
|
||||
final String user = AtlasAuthorizationUtils.getCurrentUserName();
|
||||
final Set<String> userGroups = AtlasAuthorizationUtils.getCurrentUserGroups();
|
||||
|
||||
try {
|
||||
currentThread.setName(formatName(oldName, requestId));
|
||||
|
||||
RequestContextV1.clear();
|
||||
RequestContextV1 requestContext = RequestContextV1.get();
|
||||
requestContext.setUser(user);
|
||||
recordAudit(httpRequest, requestTimeISO9601, user);
|
||||
requestContext.setUser(user, userGroups);
|
||||
|
||||
filterChain.doFilter(request, response);
|
||||
} finally {
|
||||
long timeTaken = System.currentTimeMillis() - startTime;
|
||||
|
||||
recordAudit(httpRequest, requestTime, user, httpResponse.getStatus(), timeTaken);
|
||||
|
||||
// put the request id into the response so users can trace logs for this request
|
||||
((HttpServletResponse) response).setHeader(AtlasClient.REQUEST_ID, requestId);
|
||||
httpResponse.setHeader(AtlasClient.REQUEST_ID, requestId);
|
||||
currentThread.setName(oldName);
|
||||
recordMetrics();
|
||||
RequestContextV1.clear();
|
||||
}
|
||||
}
|
||||
|
|
@ -87,17 +94,14 @@ public class AuditFilter implements Filter {
|
|||
return oldName + " - " + requestId;
|
||||
}
|
||||
|
||||
private void recordAudit(HttpServletRequest httpRequest, String whenISO9601, String who) {
|
||||
final String fromHost = httpRequest.getRemoteHost();
|
||||
private void recordAudit(HttpServletRequest httpRequest, Date when, String who, int httpStatus, long timeTaken) {
|
||||
final String fromAddress = httpRequest.getRemoteAddr();
|
||||
final String whatRequest = httpRequest.getMethod();
|
||||
final String whatURL = Servlets.getRequestURL(httpRequest);
|
||||
final String whatAddrs = httpRequest.getLocalAddr();
|
||||
|
||||
final String whatUrlPath = httpRequest.getRequestURL().toString();//url path without query string
|
||||
final String whatURL = Servlets.getRequestURL(httpRequest);
|
||||
final String whatUrlPath = httpRequest.getRequestURL().toString(); //url path without query string
|
||||
|
||||
if (!isOperationExcludedFromAudit(whatRequest, whatUrlPath.toLowerCase(), null)) {
|
||||
audit(who, fromAddress, whatRequest, fromHost, whatURL, whatAddrs, whenISO9601);
|
||||
audit(new AuditLog(who, fromAddress, whatRequest, whatURL, when, httpStatus, timeTaken));
|
||||
} else {
|
||||
if(LOG.isDebugEnabled()) {
|
||||
LOG.debug(" Skipping Audit for {} ", whatURL);
|
||||
|
|
@ -105,25 +109,11 @@ public class AuditFilter implements Filter {
|
|||
}
|
||||
}
|
||||
|
||||
private String getUserFromRequest(HttpServletRequest httpRequest) {
|
||||
// look for the user in the request
|
||||
final String userFromRequest = Servlets.getUserFromRequest(httpRequest);
|
||||
return userFromRequest == null ? "UNKNOWN" : userFromRequest;
|
||||
}
|
||||
|
||||
public static void audit(String who, String fromAddress, String whatRequest, String fromHost, String whatURL, String whatAddrs,
|
||||
String whenISO9601) {
|
||||
AUDIT_LOG.info("Audit: {}/{}-{} performed request {} {} ({}) at time {}", who, fromAddress, fromHost, whatRequest, whatURL,
|
||||
whatAddrs, whenISO9601);
|
||||
}
|
||||
|
||||
public static void recordMetrics() {
|
||||
//record metrics
|
||||
Metrics requestMetrics = RequestContextV1.getMetrics();
|
||||
if (!requestMetrics.isEmpty()) {
|
||||
METRICS_LOG.info("{}", requestMetrics);
|
||||
public static void audit(AuditLog auditLog) {
|
||||
if (AUDIT_LOG.isInfoEnabled() && auditLog != null) {
|
||||
AUDIT_LOG.info(auditLog.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean isOperationExcludedFromAudit(String requestHttpMethod, String requestOperation, Configuration config) {
|
||||
try {
|
||||
|
|
@ -137,4 +127,53 @@ public class AuditFilter implements Filter {
|
|||
public void destroy() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public static class AuditLog {
|
||||
private static final char FIELD_SEP = '|';
|
||||
|
||||
private final String userName;
|
||||
private final String fromAddress;
|
||||
private final String requestMethod;
|
||||
private final String requestUrl;
|
||||
private final Date requestTime;
|
||||
private int httpStatus;
|
||||
private long timeTaken;
|
||||
|
||||
public AuditLog(String userName, String fromAddress, String requestMethod, String requestUrl) {
|
||||
this(userName, fromAddress, requestMethod, requestUrl, new Date());
|
||||
}
|
||||
|
||||
public AuditLog(String userName, String fromAddress, String requestMethod, String requestUrl, Date requestTime) {
|
||||
this(userName, fromAddress, requestMethod, requestUrl, requestTime, HttpServletResponse.SC_OK, 0);
|
||||
}
|
||||
|
||||
public AuditLog(String userName, String fromAddress, String requestMethod, String requestUrl, Date requestTime, int httpStatus, long timeTaken) {
|
||||
this.userName = userName;
|
||||
this.fromAddress = fromAddress;
|
||||
this.requestMethod = requestMethod;
|
||||
this.requestUrl = requestUrl;
|
||||
this.requestTime = requestTime;
|
||||
this.httpStatus = httpStatus;
|
||||
this.timeTaken = timeTaken;
|
||||
}
|
||||
|
||||
public void setHttpStatus(int httpStatus) { this.httpStatus = httpStatus; }
|
||||
|
||||
public void setTimeTaken(long timeTaken) { this.timeTaken = timeTaken; }
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append(DateTimeHelper.formatDateUTC(requestTime))
|
||||
.append(FIELD_SEP).append(userName)
|
||||
.append(FIELD_SEP).append(fromAddress)
|
||||
.append(FIELD_SEP).append(requestMethod)
|
||||
.append(FIELD_SEP).append(requestUrl)
|
||||
.append(FIELD_SEP).append(httpStatus)
|
||||
.append(FIELD_SEP).append(timeTaken);
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,9 +22,10 @@ import com.sun.jersey.multipart.FormDataParam;
|
|||
import org.apache.atlas.ApplicationProperties;
|
||||
import org.apache.atlas.AtlasClient;
|
||||
import org.apache.atlas.AtlasErrorCode;
|
||||
import org.apache.atlas.authorize.AtlasActionTypes;
|
||||
import org.apache.atlas.authorize.AtlasResourceTypes;
|
||||
import org.apache.atlas.authorize.simple.AtlasAuthorizationUtils;
|
||||
import org.apache.atlas.authorize.AtlasAdminAccessRequest;
|
||||
import org.apache.atlas.authorize.AtlasEntityAccessRequest;
|
||||
import org.apache.atlas.authorize.AtlasPrivilege;
|
||||
import org.apache.atlas.authorize.AtlasAuthorizationUtils;
|
||||
import org.apache.atlas.discovery.SearchContext;
|
||||
import org.apache.atlas.exception.AtlasBaseException;
|
||||
import org.apache.atlas.model.impexp.AtlasExportRequest;
|
||||
|
|
@ -38,6 +39,7 @@ import org.apache.atlas.repository.impexp.ZipSink;
|
|||
import org.apache.atlas.repository.impexp.ZipSource;
|
||||
import org.apache.atlas.services.MetricsService;
|
||||
import org.apache.atlas.type.AtlasType;
|
||||
import org.apache.atlas.type.AtlasTypeRegistry;
|
||||
import org.apache.atlas.util.SearchTracker;
|
||||
import org.apache.atlas.utils.AtlasJson;
|
||||
import org.apache.atlas.web.filters.AtlasCSRFPreventionFilter;
|
||||
|
|
@ -97,6 +99,8 @@ public class AdminResource {
|
|||
@Context
|
||||
private HttpServletResponse httpServletResponse;
|
||||
|
||||
private final AtlasTypeRegistry typeRegistry;
|
||||
|
||||
private final ReentrantLock importExportOperationLock;
|
||||
|
||||
private static final String isCSRF_ENABLED = "atlas.rest-csrf.enabled";
|
||||
|
|
@ -126,12 +130,14 @@ public class AdminResource {
|
|||
|
||||
@Inject
|
||||
public AdminResource(ServiceState serviceState, MetricsService metricsService,
|
||||
ExportService exportService, ImportService importService, SearchTracker activeSearches) {
|
||||
ExportService exportService, ImportService importService,
|
||||
SearchTracker activeSearches, AtlasTypeRegistry typeRegistry) {
|
||||
this.serviceState = serviceState;
|
||||
this.metricsService = metricsService;
|
||||
this.exportService = exportService;
|
||||
this.importService = importService;
|
||||
this.activeSearches = activeSearches;
|
||||
this.typeRegistry = typeRegistry;
|
||||
importExportOperationLock = new ReentrantLock();
|
||||
}
|
||||
|
||||
|
|
@ -249,10 +255,8 @@ public class AdminResource {
|
|||
groups.add(c.getAuthority());
|
||||
}
|
||||
|
||||
isEntityUpdateAccessAllowed = AtlasAuthorizationUtils.isAccessAllowed(AtlasResourceTypes.ENTITY,
|
||||
AtlasActionTypes.UPDATE, userName, groups, httpServletRequest);
|
||||
isEntityCreateAccessAllowed = AtlasAuthorizationUtils.isAccessAllowed(AtlasResourceTypes.ENTITY,
|
||||
AtlasActionTypes.CREATE, userName, groups, httpServletRequest);
|
||||
isEntityUpdateAccessAllowed = AtlasAuthorizationUtils.isAccessAllowed(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_UPDATE));
|
||||
isEntityCreateAccessAllowed = AtlasAuthorizationUtils.isAccessAllowed(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_CREATE));
|
||||
}
|
||||
|
||||
Map<String, Object> responseData = new HashMap<>();
|
||||
|
|
@ -305,6 +309,8 @@ public class AdminResource {
|
|||
LOG.debug("==> AdminResource.export()");
|
||||
}
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasAdminAccessRequest(AtlasPrivilege.ADMIN_EXPORT), "export");
|
||||
|
||||
acquireExportImportLock("export");
|
||||
|
||||
ZipSink exportSink = null;
|
||||
|
|
@ -351,6 +357,8 @@ public class AdminResource {
|
|||
LOG.debug("==> AdminResource.importData(jsonData={}, inputStream={})", jsonData, (inputStream != null));
|
||||
}
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasAdminAccessRequest(AtlasPrivilege.ADMIN_IMPORT), "importData");
|
||||
|
||||
acquireExportImportLock("import");
|
||||
AtlasImportResult result;
|
||||
|
||||
|
|
@ -384,6 +392,8 @@ public class AdminResource {
|
|||
LOG.debug("==> AdminResource.importFile()");
|
||||
}
|
||||
|
||||
AtlasAuthorizationUtils.verifyAccess(new AtlasAdminAccessRequest(AtlasPrivilege.ADMIN_IMPORT), "importFile");
|
||||
|
||||
acquireExportImportLock("importFile");
|
||||
|
||||
AtlasImportResult result;
|
||||
|
|
|
|||
|
|
@ -401,6 +401,8 @@ public class TypesREST {
|
|||
AtlasTypeUtil.toDebugString(typesDef) + ")");
|
||||
}
|
||||
|
||||
|
||||
|
||||
typeDefStore.deleteTypesDef(typesDef);
|
||||
} finally {
|
||||
AtlasPerfTracer.log(perf);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ package org.apache.atlas.web.security;
|
|||
import org.apache.atlas.web.filters.ActiveServerFilter;
|
||||
import org.apache.atlas.web.filters.AtlasAuthenticationEntryPoint;
|
||||
import org.apache.atlas.web.filters.AtlasAuthenticationFilter;
|
||||
import org.apache.atlas.web.filters.AtlasAuthorizationFilter;
|
||||
import org.apache.atlas.web.filters.AtlasCSRFPreventionFilter;
|
||||
import org.apache.atlas.web.filters.AtlasKnoxSSOAuthenticationFilter;
|
||||
import org.apache.atlas.web.filters.StaleTransactionCleanupFilter;
|
||||
|
|
@ -35,7 +34,6 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
|
|||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
|
||||
import org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint;
|
||||
import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
|
||||
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
||||
|
|
@ -54,7 +52,6 @@ public class AtlasSecurityConfig extends WebSecurityConfigurerAdapter {
|
|||
private final AtlasAuthenticationProvider authenticationProvider;
|
||||
private final AtlasAuthenticationSuccessHandler successHandler;
|
||||
private final AtlasAuthenticationFailureHandler failureHandler;
|
||||
private final AtlasAuthorizationFilter atlasAuthorizationFilter;
|
||||
private final AtlasKnoxSSOAuthenticationFilter ssoAuthenticationFilter;
|
||||
private final AtlasAuthenticationFilter atlasAuthenticationFilter;
|
||||
private final AtlasCSRFPreventionFilter csrfPreventionFilter;
|
||||
|
|
@ -72,7 +69,6 @@ public class AtlasSecurityConfig extends WebSecurityConfigurerAdapter {
|
|||
AtlasAuthenticationProvider authenticationProvider,
|
||||
AtlasAuthenticationSuccessHandler successHandler,
|
||||
AtlasAuthenticationFailureHandler failureHandler,
|
||||
AtlasAuthorizationFilter atlasAuthorizationFilter,
|
||||
AtlasAuthenticationEntryPoint atlasAuthenticationEntryPoint,
|
||||
Configuration configuration,
|
||||
StaleTransactionCleanupFilter staleTransactionCleanupFilter,
|
||||
|
|
@ -83,7 +79,6 @@ public class AtlasSecurityConfig extends WebSecurityConfigurerAdapter {
|
|||
this.authenticationProvider = authenticationProvider;
|
||||
this.successHandler = successHandler;
|
||||
this.failureHandler = failureHandler;
|
||||
this.atlasAuthorizationFilter = atlasAuthorizationFilter;
|
||||
this.atlasAuthenticationEntryPoint = atlasAuthenticationEntryPoint;
|
||||
this.configuration = configuration;
|
||||
this.staleTransactionCleanupFilter = staleTransactionCleanupFilter;
|
||||
|
|
@ -164,7 +159,6 @@ public class AtlasSecurityConfig extends WebSecurityConfigurerAdapter {
|
|||
.addFilterAfter(staleTransactionCleanupFilter, BasicAuthenticationFilter.class)
|
||||
.addFilterBefore(ssoAuthenticationFilter, BasicAuthenticationFilter.class)
|
||||
.addFilterAfter(atlasAuthenticationFilter, SecurityContextHolderAwareRequestFilter.class)
|
||||
.addFilterAfter(csrfPreventionFilter, AtlasAuthenticationFilter.class)
|
||||
.addFilterAfter(atlasAuthorizationFilter, FilterSecurityInterceptor.class);
|
||||
.addFilterAfter(csrfPreventionFilter, AtlasAuthenticationFilter.class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,11 +19,9 @@
|
|||
package org.apache.atlas.web.util;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
|
|
@ -31,88 +29,28 @@ import java.util.regex.Pattern;
|
|||
*/
|
||||
public final class DateTimeHelper {
|
||||
|
||||
public static final String ISO8601_FORMAT = "yyyy-MM-dd'T'HH:mm'Z'";
|
||||
public static final String ISO8601_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
|
||||
private static final String DATE_PATTERN =
|
||||
"(2\\d\\d\\d|19\\d\\d)-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])T" + "([0-1][0-9]|2[0-3]):([0-5][0-9])Z";
|
||||
private static final Pattern PATTERN = Pattern.compile(DATE_PATTERN);
|
||||
|
||||
private static ThreadLocal<DateFormat> DATE_FORMAT = new ThreadLocal<DateFormat>() {
|
||||
@Override
|
||||
public DateFormat initialValue() {
|
||||
DateFormat dateFormat = new SimpleDateFormat(ISO8601_FORMAT);
|
||||
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
return dateFormat;
|
||||
}
|
||||
};
|
||||
|
||||
private DateTimeHelper() {
|
||||
}
|
||||
|
||||
public static String getTimeZoneId(TimeZone tz) {
|
||||
return tz.getID();
|
||||
}
|
||||
|
||||
public static DateFormat getDateFormat() {
|
||||
DateFormat dateFormat = new SimpleDateFormat(ISO8601_FORMAT);
|
||||
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
return dateFormat;
|
||||
return DATE_FORMAT.get();
|
||||
}
|
||||
|
||||
public static String formatDateUTC(Date date) {
|
||||
return (date != null) ? getDateFormat().format(date) : null;
|
||||
}
|
||||
|
||||
public static Date parseDateUTC(String dateStr) {
|
||||
if (!validate(dateStr)) {
|
||||
throw new IllegalArgumentException(dateStr + " is not a valid UTC string");
|
||||
}
|
||||
try {
|
||||
return getDateFormat().parse(dateStr);
|
||||
} catch (ParseException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String formatDateUTCToISO8601(final String dateString, final String dateStringFormat) {
|
||||
|
||||
try {
|
||||
DateFormat dateFormat = new SimpleDateFormat(dateStringFormat.substring(0, dateString.length()));
|
||||
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
return DateTimeHelper.formatDateUTC(dateFormat.parse(dateString));
|
||||
} catch (ParseException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate date format with regular expression.
|
||||
*
|
||||
* @param date date address for validation
|
||||
* @return true valid date fromat, false invalid date format
|
||||
*/
|
||||
public static boolean validate(final String date) {
|
||||
|
||||
Matcher matcher = PATTERN.matcher(date);
|
||||
|
||||
if (matcher.matches()) {
|
||||
|
||||
matcher.reset();
|
||||
|
||||
if (matcher.find()) {
|
||||
|
||||
int year = Integer.parseInt(matcher.group(1));
|
||||
String month = matcher.group(2);
|
||||
String day = matcher.group(3);
|
||||
|
||||
if (day.equals("31") && (month.equals("4") || month.equals("6") || month.equals("9") || month
|
||||
.equals("11") || month.equals("04") || month.equals("06") || month.equals("09"))) {
|
||||
return false; // only 1,3,5,7,8,10,12 has 31 days
|
||||
} else if (month.equals("2") || month.equals("02")) {
|
||||
// leap year
|
||||
if (year % 4 == 0) {
|
||||
return !(day.equals("30") || day.equals("31"));
|
||||
} else {
|
||||
return !(day.equals("29") || day.equals("30") || day.equals("31"));
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -51,7 +51,6 @@
|
|||
<http-basic />
|
||||
<headers disabled="true"/>
|
||||
<csrf disabled="true"/>
|
||||
<security:custom-filter position="LAST" ref="atlasAuthorizationFilter"/>
|
||||
</security:http>
|
||||
|
||||
<beans:bean id="krbAuthenticationFilter" class="org.apache.atlas.web.filters.AtlasAuthenticationFilter">
|
||||
|
|
@ -102,6 +101,4 @@
|
|||
|
||||
<security:global-method-security
|
||||
pre-post-annotations="enabled" />
|
||||
|
||||
<beans:bean id = "atlasAuthorizationFilter" class="org.apache.atlas.web.filters.AtlasAuthorizationFilter"/>
|
||||
</beans:beans>
|
||||
</beans:beans>
|
||||
|
|
|
|||
|
|
@ -59,24 +59,6 @@ public class AtlasAuthenticationSimpleFilterIT extends BaseSecurityTest {
|
|||
}
|
||||
|
||||
|
||||
@Test(enabled = true)
|
||||
public void testSimpleLoginAndAuthorizationWithValidCrendentialsAndInvalidAccessToResource()
|
||||
throws Exception {
|
||||
try {
|
||||
URL url = new URL("http://localhost:31000/api/atlas/admin/stack");
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod("GET");
|
||||
String userpassword = "rangertagsync:rangertagsync"; //right password with no policy for taxonomies api
|
||||
String encodedAuthorization = enc.encodeToString(userpassword.getBytes());
|
||||
connection.setRequestProperty("Authorization", "Basic " +
|
||||
encodedAuthorization);
|
||||
connection.connect();
|
||||
assertEquals(connection.getResponseCode(), 403);
|
||||
|
||||
} catch (Exception e) {
|
||||
Assert.fail("Failed with exception " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test(enabled = true)
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ public class AdminResourceTest {
|
|||
|
||||
when(serviceState.getState()).thenReturn(ServiceState.ServiceStateValue.ACTIVE);
|
||||
|
||||
AdminResource adminResource = new AdminResource(serviceState, null, null, null, null);
|
||||
AdminResource adminResource = new AdminResource(serviceState, null, null, null, null, null);
|
||||
Response response = adminResource.getStatus();
|
||||
assertEquals(response.getStatus(), HttpServletResponse.SC_OK);
|
||||
JsonNode entity = AtlasJson.parseToV1JsonNode((String) response.getEntity());
|
||||
|
|
@ -62,7 +62,7 @@ public class AdminResourceTest {
|
|||
public void testResourceGetsValueFromServiceState() throws IOException {
|
||||
when(serviceState.getState()).thenReturn(ServiceState.ServiceStateValue.PASSIVE);
|
||||
|
||||
AdminResource adminResource = new AdminResource(serviceState, null, null, null, null);
|
||||
AdminResource adminResource = new AdminResource(serviceState, null, null, null, null, null);
|
||||
Response response = adminResource.getStatus();
|
||||
|
||||
verify(serviceState).getState();
|
||||
|
|
|
|||
|
|
@ -116,14 +116,17 @@ atlas.server.ha.enabled=false
|
|||
#atlas.server.ids=id1
|
||||
#atlas.server.address.id1=localhost:21000
|
||||
|
||||
#########POLICY FILE PATH #########
|
||||
# atlas.auth.policy.file=policy-store.txt
|
||||
######### Atlas Authorization #########
|
||||
atlas.authorizer.impl=none
|
||||
# atlas.authorizer.impl=simple
|
||||
# atlas.authorizer.simple.authz.policy.file=atlas-simple-authz-policy.json
|
||||
|
||||
######### Atlas Authentication #########
|
||||
atlas.authentication.method.file=true
|
||||
atlas.authentication.method.ldap.type=none
|
||||
# atlas.authentication.method.file.filename=users-credentials.properties
|
||||
atlas.authentication.method.kerberos=false
|
||||
# atlas.authentication.method.file.filename=users-credentials.properties
|
||||
|
||||
######### Gremlin Search Configuration #########
|
||||
# Set to false to disable gremlin search.
|
||||
atlas.search.gremlin.enable=true
|
||||
atlas.search.gremlin.enable=true
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@
|
|||
<http-basic />
|
||||
<headers disabled="true"/>
|
||||
<csrf disabled="true"/>
|
||||
<security:custom-filter position="LAST" ref="atlasAuthorizationFilter"/>
|
||||
</security:http>
|
||||
|
||||
<beans:bean id="userDAO" class="org.apache.atlas.web.dao.UserDao" init-method="init"/>
|
||||
|
|
@ -113,6 +112,4 @@
|
|||
</security:authentication-manager>
|
||||
|
||||
<security:global-method-security pre-post-annotations="enabled" />
|
||||
|
||||
<beans:bean id = "atlasAuthorizationFilter" class="org.apache.atlas.web.filters.AtlasAuthorizationFilter"/>
|
||||
</beans:beans>
|
||||
|
|
|
|||
Loading…
Reference in New Issue