blob: 93d988e668ac4865621472b50724ead38406fee1 [file] [log] [blame]
/**
* 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 javax.servlet.http.HttpServletRequest;
import org.apache.atlas.AtlasClient;
import org.apache.atlas.authorize.AtlasActionTypes;
import org.apache.atlas.authorize.AtlasResourceTypes;
import org.apache.atlas.authorize.AtlasAuthorizationException;
import org.apache.atlas.authorize.AtlasAuthorizer;
import org.apache.atlas.authorize.AtlasAccessRequest;
import org.apache.atlas.authorize.AtlasAuthorizerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashSet;
import java.util.Objects;
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 = "/" + AtlasClient.BASE_URI;
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) {
AtlasActionTypes action = null;
switch (method.toUpperCase()) {
case "POST":
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/*
*
* taxonomy API are also mapped to AtlasResourceTypes.TAXONOMY & AtlasResourceTypes.ENTITY and its terms APIs have
* added AtlasResourceTypes.TERM associations.
*
* 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("taxonomies")) {
resourceTypes.add(AtlasResourceTypes.TAXONOMY);
// taxonomies are modeled as entities
resourceTypes.add(AtlasResourceTypes.ENTITY);
if (contextPath.contains("/terms")) {
resourceTypes.add(AtlasResourceTypes.TERM);
}
} 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 "";
}
}
}