blob: 63ad2819977a5c157d3b227e7f7f0b4e76ffbcc6 [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.ranger.rest;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.Objects;
import javax.annotation.Nonnull;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ranger.admin.client.datatype.RESTResponse;
import org.apache.ranger.authorization.hadoop.config.RangerAdminConfig;
import org.apache.ranger.authorization.utils.StringUtil;
import org.apache.ranger.biz.AssetMgr;
import org.apache.ranger.biz.PolicyRefUpdater;
import org.apache.ranger.biz.RangerPolicyAdmin;
import org.apache.ranger.biz.RangerBizUtil;
import org.apache.ranger.biz.RangerPolicyAdminCache;
import org.apache.ranger.biz.RangerPolicyAdminCacheForEngineOptions;
import org.apache.ranger.biz.RoleDBStore;
import org.apache.ranger.biz.SecurityZoneDBStore;
import org.apache.ranger.biz.ServiceDBStore;
import org.apache.ranger.biz.ServiceMgr;
import org.apache.ranger.biz.TagDBStore;
import org.apache.ranger.biz.XUserMgr;
import org.apache.ranger.common.AppConstants;
import org.apache.ranger.common.ContextUtil;
import org.apache.ranger.common.GUIDUtil;
import org.apache.ranger.common.MessageEnums;
import org.apache.ranger.common.PropertiesUtil;
import org.apache.ranger.common.RESTErrorUtil;
import org.apache.ranger.common.RangerConstants;
import org.apache.ranger.common.RangerSearchUtil;
import org.apache.ranger.common.RangerValidatorFactory;
import org.apache.ranger.common.ServiceUtil;
import org.apache.ranger.common.UserSessionBase;
import org.apache.ranger.common.db.RangerTransactionSynchronizationAdapter;
import org.apache.ranger.db.RangerDaoManager;
import org.apache.ranger.entity.XXPolicy;
import org.apache.ranger.entity.XXPolicyExportAudit;
import org.apache.ranger.entity.XXSecurityZone;
import org.apache.ranger.entity.XXSecurityZoneRefService;
import org.apache.ranger.entity.XXSecurityZoneRefTagService;
import org.apache.ranger.entity.XXService;
import org.apache.ranger.entity.XXServiceDef;
import org.apache.ranger.entity.XXTrxLog;
import org.apache.ranger.entity.XXRole;
import org.apache.ranger.plugin.model.RangerPluginInfo;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
import org.apache.ranger.plugin.model.RangerPolicyDelta;
import org.apache.ranger.plugin.model.RangerPolicyResourceSignature;
import org.apache.ranger.plugin.model.RangerSecurityZone;
import org.apache.ranger.plugin.model.RangerService;
import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.model.ServiceDeleteResponse;
import org.apache.ranger.plugin.model.validation.RangerPolicyValidator;
import org.apache.ranger.plugin.model.validation.RangerServiceDefHelper;
import org.apache.ranger.plugin.model.validation.RangerServiceDefValidator;
import org.apache.ranger.plugin.model.validation.RangerServiceValidator;
import org.apache.ranger.plugin.model.validation.RangerValidator.Action;
import org.apache.ranger.plugin.policyengine.RangerAccessResource;
import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl;
import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
import org.apache.ranger.plugin.service.ResourceLookupContext;
import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
import org.apache.ranger.plugin.store.PList;
import org.apache.ranger.plugin.store.ServiceStore;
import org.apache.ranger.plugin.util.GrantRevokeRequest;
import org.apache.ranger.plugin.util.JsonUtilsV2;
import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
import org.apache.ranger.plugin.util.RangerPerfTracer;
import org.apache.ranger.plugin.util.SearchFilter;
import org.apache.ranger.plugin.util.ServicePolicies;
import org.apache.ranger.security.context.RangerAPIList;
import org.apache.ranger.security.context.RangerAdminOpContext;
import org.apache.ranger.security.context.RangerContextHolder;
import org.apache.ranger.security.web.filter.RangerCSRFPreventionFilter;
import org.apache.ranger.service.RangerPluginInfoService;
import org.apache.ranger.service.RangerPolicyLabelsService;
import org.apache.ranger.service.RangerPolicyService;
import org.apache.ranger.service.RangerServiceDefService;
import org.apache.ranger.service.RangerServiceService;
import org.apache.ranger.service.RangerTransactionService;
import org.apache.ranger.service.XUserService;
import org.apache.ranger.view.RangerExportPolicyList;
import org.apache.ranger.view.RangerPluginInfoList;
import org.apache.ranger.view.RangerPolicyList;
import org.apache.ranger.view.RangerServiceDefList;
import org.apache.ranger.view.RangerServiceList;
import org.apache.ranger.view.VXGroup;
import org.apache.ranger.view.VXResponse;
import org.apache.ranger.view.VXString;
import org.apache.ranger.view.VXUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.google.gson.JsonSyntaxException;
import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataParam;
@Path("plugins")
@Component
@Scope("request")
@Transactional(propagation = Propagation.REQUIRES_NEW)
public class ServiceREST {
private static final Log LOG = LogFactory.getLog(ServiceREST.class);
private static final Log PERF_LOG = RangerPerfTracer.getPerfLogger("rest.ServiceREST");
final static public String PARAM_SERVICE_NAME = "serviceName";
final static public String PARAM_SERVICE_TYPE = "serviceType";
final static public String PARAM_POLICY_NAME = "policyName";
final static public String PARAM_ZONE_NAME = "zoneName";
final static public String PARAM_UPDATE_IF_EXISTS = "updateIfExists";
final static public String PARAM_MERGE_IF_EXISTS = "mergeIfExists";
final static public String PARAM_DELETE_IF_EXISTS = "deleteIfExists";
final static public String PARAM_IMPORT_IN_PROGRESS = "importInProgress";
public static final String Allowed_User_List_For_Download = "policy.download.auth.users";
public static final String Allowed_User_List_For_Grant_Revoke = "policy.grantrevoke.auth.users";
public static final String isCSRF_ENABLED = "ranger.rest-csrf.enabled";
public static final String BROWSER_USER_AGENT_PARAM = "ranger.rest-csrf.browser-useragents-regex";
public static final String CUSTOM_METHODS_TO_IGNORE_PARAM = "ranger.rest-csrf.methods-to-ignore";
public static final String CUSTOM_HEADER_PARAM = "ranger.rest-csrf.custom-header";
final static public String POLICY_MATCHING_ALGO_BY_POLICYNAME = "matchByName";
final static public String POLICY_MATCHING_ALGO_BY_RESOURCE = "matchByPolicySignature";
final static public String PARAM_POLICY_MATCHING_ALGORITHM = "policyMatchingAlgorithm";
@Autowired
RESTErrorUtil restErrorUtil;
@Autowired
ServiceMgr serviceMgr;
@Autowired
XUserService xUserService;
@Autowired
AssetMgr assetMgr;
@Autowired
XUserMgr userMgr;
@Autowired
ServiceDBStore svcStore;
@Autowired
RoleDBStore roleDBStore;
@Autowired
SecurityZoneDBStore zoneStore;
@Autowired
ServiceUtil serviceUtil;
@Autowired
RangerPolicyService policyService;
@Autowired
RangerPolicyLabelsService policyLabelsService;
@Autowired
RangerServiceService svcService;
@Autowired
RangerServiceDefService serviceDefService;
@Autowired
RangerPluginInfoService pluginInfoService;
@Autowired
RangerSearchUtil searchUtil;
@Autowired
RangerBizUtil bizUtil;
@Autowired
GUIDUtil guidUtil;
@Autowired
RangerValidatorFactory validatorFactory;
@Autowired
RangerDaoManager daoManager;
@Autowired
TagDBStore tagStore;
@Autowired
RangerTransactionService transactionService;
@Autowired
RangerTransactionSynchronizationAdapter rangerTransactionSynchronizationAdapter;
private RangerPolicyEngineOptions delegateAdminOptions;
private RangerPolicyEngineOptions policySearchAdminOptions;
private RangerPolicyEngineOptions defaultAdminOptions;
private final RangerAdminConfig config = RangerAdminConfig.getInstance();
public ServiceREST() {
}
@PostConstruct
public void initStore() {
tagStore.setServiceStore(svcStore);
delegateAdminOptions = getDelegatedAdminPolicyEngineOptions();
policySearchAdminOptions = getPolicySearchRangerAdminPolicyEngineOptions();
defaultAdminOptions = getDefaultRangerAdminPolicyEngineOptions();
}
@POST
@Path("/definitions")
@Produces({ "application/json", "application/xml" })
@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.CREATE_SERVICE_DEF + "\")")
public RangerServiceDef createServiceDef(RangerServiceDef serviceDef) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.createServiceDef(" + serviceDef + ")");
}
RangerServiceDef ret = null;
RangerPerfTracer perf = null;
/**
* If display name is blank (EMPTY String or NULL), use name.
*/
if (StringUtils.isBlank(serviceDef.getDisplayName())) {
serviceDef.setDisplayName(serviceDef.getName());
}
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.createServiceDef(serviceDefName=" + serviceDef.getName() + ")");
}
RangerServiceDefValidator validator = validatorFactory.getServiceDefValidator(svcStore);
validator.validate(serviceDef, Action.CREATE);
bizUtil.hasAdminPermissions("Service-Def");
bizUtil.hasKMSPermissions("Service-Def", serviceDef.getImplClass());
bizUtil.blockAuditorRoleUser();
ret = svcStore.createServiceDef(serviceDef);
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("createServiceDef(" + serviceDef + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.createServiceDef(" + serviceDef + "): " + ret);
}
return ret;
}
@PUT
@Path("/definitions/{id}")
@Produces({ "application/json", "application/xml" })
@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.UPDATE_SERVICE_DEF + "\")")
public RangerServiceDef updateServiceDef(RangerServiceDef serviceDef) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.updateServiceDef(serviceDefName=" + serviceDef.getName() + ")");
}
RangerServiceDef ret = null;
RangerPerfTracer perf = null;
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.updateServiceDef(" + serviceDef.getName() + ")");
}
/**
* If display name is blank (EMPTY String or NULL), use previous display name.
*/
if (StringUtils.isBlank(serviceDef.getDisplayName())) {
RangerServiceDef rangerServiceDef = svcStore.getServiceDef(serviceDef.getId());
// If previous display name is blank (EMPTY String or NULL), user name.
if (Objects.isNull(rangerServiceDef) || StringUtils.isBlank(rangerServiceDef.getDisplayName())) {
serviceDef.setDisplayName(serviceDef.getName());
} else {
serviceDef.setDisplayName(rangerServiceDef.getDisplayName());
}
}
RangerServiceDefValidator validator = validatorFactory.getServiceDefValidator(svcStore);
validator.validate(serviceDef, Action.UPDATE);
bizUtil.hasAdminPermissions("Service-Def");
bizUtil.hasKMSPermissions("Service-Def", serviceDef.getImplClass());
bizUtil.blockAuditorRoleUser();
ret = svcStore.updateServiceDef(serviceDef);
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("updateServiceDef(" + serviceDef + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.updateServiceDef(" + serviceDef + "): " + ret);
}
return ret;
}
@DELETE
@Path("/definitions/{id}")
@Produces({ "application/json", "application/xml" })
@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.DELETE_SERVICE_DEF + "\")")
public void deleteServiceDef(@PathParam("id") Long id, @Context HttpServletRequest request) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.deleteServiceDef(" + id + ")");
}
RangerPerfTracer perf = null;
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.deleteServiceDef(serviceDefId=" + id + ")");
}
RangerServiceDefValidator validator = validatorFactory.getServiceDefValidator(svcStore);
validator.validate(id, Action.DELETE);
bizUtil.hasAdminPermissions("Service-Def");
XXServiceDef xServiceDef = daoManager.getXXServiceDef().getById(id);
if (xServiceDef != null) {
bizUtil.hasKMSPermissions("Service-Def", xServiceDef.getImplclassname());
String forceDeleteStr = request.getParameter("forceDelete");
boolean forceDelete = false;
if (!StringUtils.isEmpty(forceDeleteStr) && "true".equalsIgnoreCase(forceDeleteStr)) {
forceDelete = true;
}
svcStore.deleteServiceDef(id, forceDelete);
} else {
LOG.error("Cannot retrieve service-definition:[" + id + "] for deletion");
throw new Exception("deleteServiceDef(" + id + ") failed");
}
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("deleteServiceDef(" + id + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.deleteServiceDef(" + id + ")");
}
}
@GET
@Path("/definitions/{id}")
@Produces({ "application/json", "application/xml" })
@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.GET_SERVICE_DEF + "\")")
public RangerServiceDef getServiceDef(@PathParam("id") Long id) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getServiceDef(" + id + ")");
}
RangerServiceDef ret = null;
RangerPerfTracer perf = null;
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getServiceDef(serviceDefId=" + id + ")");
}
XXServiceDef xServiceDef = daoManager.getXXServiceDef().getById(id);
if(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_TAG_NAME.equals(xServiceDef.getName())) {
if (!bizUtil.hasModuleAccess(RangerConstants.MODULE_TAG_BASED_POLICIES)) {
throw restErrorUtil.createRESTException(HttpServletResponse.SC_FORBIDDEN, "User is not having permissions on the tag module.", true);
}
}
if (!bizUtil.hasAccess(xServiceDef, null)) {
throw restErrorUtil.createRESTException(
"User is not allowed to access service-def, id: " + xServiceDef.getId(),
MessageEnums.OPER_NO_PERMISSION);
}
ret = svcStore.getServiceDef(id);
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("getServiceDef(" + id + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if(ret == null) {
throw restErrorUtil.createRESTException(HttpServletResponse.SC_NOT_FOUND, "Not found", true);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getServiceDef(" + id + "): " + ret);
}
return ret;
}
@GET
@Path("/definitions/name/{name}")
@Produces({ "application/json", "application/xml" })
@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.GET_SERVICE_DEF_BY_NAME + "\")")
public RangerServiceDef getServiceDefByName(@PathParam("name") String name) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getServiceDefByName(serviceDefName=" + name + ")");
}
RangerServiceDef ret = null;
RangerPerfTracer perf = null;
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getServiceDefByName(" + name + ")");
}
XXServiceDef xServiceDef = daoManager.getXXServiceDef().findByName(name);
if (xServiceDef != null) {
if(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_TAG_NAME.equals(xServiceDef.getName())) {
if (!bizUtil.hasModuleAccess(RangerConstants.MODULE_TAG_BASED_POLICIES)) {
throw restErrorUtil.createRESTException(HttpServletResponse.SC_FORBIDDEN, "User is not having permissions on the tag module", true);
}
}
if (!bizUtil.hasAccess(xServiceDef, null)) {
throw restErrorUtil.createRESTException(
"User is not allowed to access service-def: " + xServiceDef.getName(),
MessageEnums.OPER_NO_PERMISSION);
}
}
ret = svcStore.getServiceDefByName(name);
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("getServiceDefByName(" + name + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if(ret == null) {
throw restErrorUtil.createRESTException(HttpServletResponse.SC_NOT_FOUND, "Not found", true);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getServiceDefByName(" + name + "): " + ret);
}
return ret;
}
@GET
@Path("/definitions")
@Produces({ "application/json", "application/xml" })
@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.GET_SERVICE_DEFS + "\")")
public RangerServiceDefList getServiceDefs(@Context HttpServletRequest request) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getServiceDefs()");
}
if (!bizUtil.hasModuleAccess(RangerConstants.MODULE_RESOURCE_BASED_POLICIES)) {
throw restErrorUtil.createRESTException(HttpServletResponse.SC_FORBIDDEN, "User is not having permissions on the "+RangerConstants.MODULE_RESOURCE_BASED_POLICIES+" module.", true);
}
RangerServiceDefList ret = null;
RangerPerfTracer perf = null;
PList<RangerServiceDef> paginatedSvcDefs = null;
SearchFilter filter = searchUtil.getSearchFilter(request, serviceDefService.sortFields);
String pageSource= null;
pageSource=request.getParameter("pageSource");
if(pageSource!=null)
filter.setParam("pageSource",pageSource);
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getServiceDefs()");
}
paginatedSvcDefs = svcStore.getPaginatedServiceDefs(filter);
if(paginatedSvcDefs != null) {
ret = new RangerServiceDefList();
ret.setServiceDefs(paginatedSvcDefs.getList());
ret.setPageSize(paginatedSvcDefs.getPageSize());
ret.setResultSize(paginatedSvcDefs.getResultSize());
ret.setStartIndex(paginatedSvcDefs.getStartIndex());
ret.setTotalCount(paginatedSvcDefs.getTotalCount());
ret.setSortBy(paginatedSvcDefs.getSortBy());
ret.setSortType(paginatedSvcDefs.getSortType());
}
} catch(WebApplicationException excp) {
throw excp;
} catch (Throwable excp) {
LOG.error("getServiceDefs() failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getServiceDefs(): count=" + (ret == null ? 0 : ret.getListSize()));
}
return ret;
}
@GET
@Path("/policies/{serviceDefName}/for-resource")
@Produces({ "application/json", "application/xml" })
public List<RangerPolicy> getPoliciesForResource(@PathParam("serviceDefName") String serviceDefName,
@DefaultValue("") @QueryParam("serviceName") String serviceName,
@Context HttpServletRequest request) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getPoliciesForResource(service-type=" + serviceDefName + ", service-name=" + serviceName + ")");
}
List<RangerPolicy> ret = new ArrayList<>();
List<RangerService> services = new ArrayList<>();
Map<String, Object> resource = new HashMap<>();
String validationMessage = validateResourcePoliciesRequest(serviceDefName, serviceName, request, services, resource);
if (StringUtils.isNotEmpty(validationMessage)) {
LOG.error("Invalid request: [" + validationMessage + "]");
throw restErrorUtil.createRESTException(validationMessage,
MessageEnums.INVALID_INPUT_DATA);
} else {
RangerService service = services.get(0);
if (LOG.isDebugEnabled()) {
LOG.debug("getServicePolicies with service-name=" + service.getName());
}
RangerPolicyAdmin policyAdmin = null;
try {
policyAdmin = getPolicyAdminForSearch(service.getName());
} catch (Exception e) {
LOG.error("Cannot initialize Policy-Engine", e);
throw restErrorUtil.createRESTException("Cannot initialize Policy Engine",
MessageEnums.ERROR_SYSTEM);
}
if (policyAdmin != null) {
ret = policyAdmin.getMatchingPolicies(new RangerAccessResourceImpl(resource));
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getPoliciesForResource(service-type=" + serviceDefName + ", service-name=" + serviceName + ") : " + ret.toString());
}
return ret;
}
private String validateResourcePoliciesRequest(String serviceDefName, String serviceName, HttpServletRequest request, List<RangerService> services, Map<String, Object> resource) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.validatePoliciesForResourceRequest(service-type=" + serviceDefName + ", service-name=" + serviceName + ")");
}
final String ret;
if (MapUtils.isNotEmpty(request.getParameterMap())) {
for (Map.Entry<String, String[]> e : request.getParameterMap().entrySet()) {
String name = e.getKey();
String[] values = e.getValue();
if (!StringUtils.isEmpty(name) && !ArrayUtils.isEmpty(values)
&& name.startsWith(SearchFilter.RESOURCE_PREFIX)) {
resource.put(name.substring(SearchFilter.RESOURCE_PREFIX.length()), values[0]);
}
}
}
if (MapUtils.isEmpty(resource)) {
ret = "No resource specified";
} else {
RangerServiceDef serviceDef = null;
try {
serviceDef = svcStore.getServiceDefByName(serviceDefName);
} catch (Exception e) {
LOG.error("Invalid service-type:[" + serviceDefName + "]", e);
}
if (serviceDef == null) {
ret = "Invalid service-type:[" + serviceDefName + "]";
} else {
Set<String> resourceDefNames = resource.keySet();
RangerServiceDefHelper serviceDefHelper = new RangerServiceDefHelper(serviceDef);
Set<List<RangerServiceDef.RangerResourceDef>> resourceHierarchies = serviceDefHelper.getResourceHierarchies(RangerPolicy.POLICY_TYPE_ACCESS, resourceDefNames);
if (CollectionUtils.isEmpty(resourceHierarchies)) {
ret = "Invalid resource specified: resource-names:" + resourceDefNames +" are not part of any valid resource hierarchy for service-type:[" + serviceDefName + "]";
} else {
if (StringUtils.isNotBlank(serviceName)) {
RangerService service = null;
try {
service = svcStore.getServiceByName(serviceName);
} catch (Exception e) {
LOG.error("Invalid service-name:[" + serviceName + "]");
}
if (service == null || !StringUtils.equals(service.getType(), serviceDefName)) {
ret = "Invalid service-name:[" + serviceName + "] or service-name is not of service-type:[" + serviceDefName + "]";
} else {
services.add(service);
ret = StringUtils.EMPTY;
}
} else {
SearchFilter filter = new SearchFilter();
filter.setParam(SearchFilter.SERVICE_TYPE, serviceDefName);
List<RangerService> serviceList = null;
try {
serviceList = svcStore.getServices(filter);
} catch (Exception e) {
LOG.error("Cannot find service of service-type:[" + serviceDefName + "]");
}
if (CollectionUtils.isEmpty(serviceList) || serviceList.size() != 1) {
ret = "Either 0 or more than 1 services found for service-type :[" + serviceDefName + "]";
} else {
services.add(serviceList.get(0));
ret = StringUtils.EMPTY;
}
}
}
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.validatePoliciesForResourceRequest(service-type=" + serviceDefName + ", service-name=" + serviceName + ") : " + ret);
}
return ret;
}
@POST
@Path("/services")
@Produces({ "application/json", "application/xml" })
@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.CREATE_SERVICE + "\")")
public RangerService createService(RangerService service) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.createService(" + service + ")");
}
RangerService ret = null;
RangerPerfTracer perf = null;
/**
* If display name is blank (EMPTY String or NULL), use name.
*/
if (StringUtils.isBlank(service.getDisplayName())) {
service.setDisplayName(service.getName());
}
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.createService(serviceName=" + service.getName() + ")");
}
RangerServiceValidator validator = validatorFactory.getServiceValidator(svcStore);
validator.validate(service, Action.CREATE);
if(!StringUtils.isEmpty(service.getName().trim())){
service.setName(service.getName().trim());
}
if(!StringUtils.isEmpty(service.getDisplayName().trim())){
service.setDisplayName(service.getDisplayName().trim());
}
UserSessionBase session = ContextUtil.getCurrentUserSession();
XXServiceDef xxServiceDef = daoManager.getXXServiceDef().findByName(service.getType());
if(session != null && !session.isSpnegoEnabled()){
bizUtil.hasAdminPermissions("Services");
// TODO: As of now we are allowing SYS_ADMIN to create all the
// services including KMS
bizUtil.hasKMSPermissions("Service", xxServiceDef.getImplclassname());
}
if(session != null && session.isSpnegoEnabled()){
if (session.isKeyAdmin() && !EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME.equals(xxServiceDef.getImplclassname())) {
throw restErrorUtil.createRESTException("KeyAdmin can create/update/delete only KMS ",
MessageEnums.OPER_NO_PERMISSION);
}
if ((!session.isKeyAdmin() && !session.isUserAdmin()) && EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME.equals(xxServiceDef.getImplclassname())) {
throw restErrorUtil.createRESTException("User cannot create/update/delete KMS Service",
MessageEnums.OPER_NO_PERMISSION);
}
}
bizUtil.blockAuditorRoleUser();
if (StringUtils.isBlank(service.getTagService())
&& xxServiceDef != null
&& !StringUtils.equals(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_TAG_NAME, xxServiceDef.getName())
&& !StringUtils.equals(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_KMS_NAME , xxServiceDef.getName())) {
if (LOG.isDebugEnabled()) {
LOG.debug("Tag service may need to be created and linked with this service:[" + service.getName() + "]");
}
scheduleCreateOrGetTagService(service);
}
ret = svcStore.createService(service);
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("createService(" + service + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.createService(" + service + "): " + ret);
}
return ret;
}
@PUT
@Path("/services/{id}")
@Produces({ "application/json", "application/xml" })
@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.UPDATE_SERVICE + "\")")
public RangerService updateService(RangerService service,
@Context HttpServletRequest request) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.updateService(): " + service);
}
RangerService ret = null;
RangerPerfTracer perf = null;
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.updateService(serviceName=" + service.getName() + ")");
}
/**
* If display name is blank (EMPTY String or NULL), use previous display name.
*/
if (StringUtils.isBlank(service.getDisplayName())) {
RangerService rangerService = svcStore.getService(service.getId());
// If previous display name is blank (EMPTY String or NULL), user name.
if (Objects.isNull(rangerService) || StringUtils.isBlank(rangerService.getDisplayName())) {
service.setDisplayName(service.getName());
} else {
service.setDisplayName(rangerService.getDisplayName());
}
}
RangerServiceValidator validator = validatorFactory.getServiceValidator(svcStore);
validator.validate(service, Action.UPDATE);
if(!StringUtils.isEmpty(service.getName().trim())){
service.setName(service.getName().trim());
}
if(!StringUtils.isEmpty(service.getDisplayName().trim())){
service.setDisplayName(service.getDisplayName().trim());
}
bizUtil.hasAdminPermissions("Services");
// TODO: As of now we are allowing SYS_ADMIN to create all the
// services including KMS
XXServiceDef xxServiceDef = daoManager.getXXServiceDef().findByName(service.getType());
bizUtil.hasKMSPermissions("Service", xxServiceDef.getImplclassname());
bizUtil.blockAuditorRoleUser();
Map<String, Object> options = getOptions(request);
ret = svcStore.updateService(service, options);
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("updateService(" + service + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.updateService(" + service + "): " + ret);
}
return ret;
}
@DELETE
@Path("/services/{id}")
@Produces({ "application/json", "application/xml" })
@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.DELETE_SERVICE + "\")")
public void deleteService(@PathParam("id") Long id) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.deleteService(" + id + ")");
}
String deletedServiceName = deleteServiceById(id);
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.deleteService() - [id="+deletedServiceName + "],[deletedServiceName="+deletedServiceName+"]");
}
}
@GET
@Path("/services/{id}")
@Produces({ "application/json", "application/xml" })
@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.GET_SERVICE + "\")")
public RangerService getService(@PathParam("id") Long id) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getService(" + id + ")");
}
RangerService ret = null;
RangerPerfTracer perf = null;
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getService(serviceId=" + id + ")");
}
ret = svcStore.getService(id);
if (ret != null) {
UserSessionBase userSession = ContextUtil
.getCurrentUserSession();
if (userSession != null && userSession.getLoginId() != null) {
VXUser loggedInVXUser = xUserService
.getXUserByUserName(userSession.getLoginId());
if (loggedInVXUser != null) {
if (loggedInVXUser.getUserRoleList().size() == 1
&& loggedInVXUser.getUserRoleList().contains(
RangerConstants.ROLE_USER)) {
ret = hideCriticalServiceDetailsForRoleUser(ret);
}
}
}
}
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("getService(" + id + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if(ret == null) {
throw restErrorUtil.createRESTException(HttpServletResponse.SC_NOT_FOUND, "Not found", true);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getService(" + id + "): " + ret);
}
return ret;
}
@GET
@Path("/services/name/{name}")
@Produces({ "application/json", "application/xml" })
@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.GET_SERVICE_BY_NAME + "\")")
public RangerService getServiceByName(@PathParam("name") String name) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getServiceByName(" + name + ")");
}
RangerService ret = null;
RangerPerfTracer perf = null;
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getService(serviceName=" + name + ")");
}
ret = svcStore.getServiceByName(name);
if (ret != null) {
UserSessionBase userSession = ContextUtil
.getCurrentUserSession();
if (userSession != null && userSession.getLoginId() != null) {
VXUser loggedInVXUser = xUserService
.getXUserByUserName(userSession.getLoginId());
if (loggedInVXUser != null) {
if (loggedInVXUser.getUserRoleList().size() == 1
&& loggedInVXUser.getUserRoleList().contains(
RangerConstants.ROLE_USER)) {
ret = hideCriticalServiceDetailsForRoleUser(ret);
}
}
}
}
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("getServiceByName(" + name + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if(ret == null) {
throw restErrorUtil.createRESTException(HttpServletResponse.SC_NOT_FOUND, "Not found", true);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getServiceByName(" + name + "): " + ret);
}
return ret;
}
@GET
@Path("/services")
@Produces({ "application/json", "application/xml" })
@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.GET_SERVICES + "\")")
public RangerServiceList getServices(@Context HttpServletRequest request) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getServices()");
}
RangerServiceList ret = null;
RangerPerfTracer perf = null;
PList<RangerService> paginatedSvcs = null;
SearchFilter filter = searchUtil.getSearchFilter(request, svcService.sortFields);
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getServices()");
}
paginatedSvcs = svcStore.getPaginatedServices(filter);
if(paginatedSvcs!= null && !paginatedSvcs.getList().isEmpty()){
UserSessionBase userSession = ContextUtil
.getCurrentUserSession();
if (userSession != null && userSession.getLoginId() != null) {
VXUser loggedInVXUser = xUserService
.getXUserByUserName(userSession.getLoginId());
if (loggedInVXUser != null) {
if (loggedInVXUser.getUserRoleList().size() == 1
&& loggedInVXUser.getUserRoleList().contains(
RangerConstants.ROLE_USER)) {
List<RangerService> updateServiceList = new ArrayList<RangerService>();
for(RangerService rangerService : paginatedSvcs.getList()){
if(rangerService != null){
updateServiceList.add(hideCriticalServiceDetailsForRoleUser(rangerService));
}
}
if(updateServiceList != null && !updateServiceList.isEmpty()){
paginatedSvcs.setList(updateServiceList);
}
}
}
}
}
if(paginatedSvcs != null) {
ret = new RangerServiceList();
ret.setServices(paginatedSvcs.getList());
ret.setPageSize(paginatedSvcs.getPageSize());
ret.setResultSize(paginatedSvcs.getResultSize());
ret.setStartIndex(paginatedSvcs.getStartIndex());
ret.setTotalCount(paginatedSvcs.getTotalCount());
ret.setSortBy(paginatedSvcs.getSortBy());
ret.setSortType(paginatedSvcs.getSortType());
}
} catch(WebApplicationException excp) {
throw excp;
} catch (Throwable excp) {
LOG.error("getServices() failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getServices(): count=" + (ret == null ? 0 : ret.getListSize()));
}
return ret;
}
public List<RangerService> getServices(SearchFilter filter) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getServices():");
}
List<RangerService> ret = null;
RangerPerfTracer perf = null;
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getServices()");
}
ret = svcStore.getServices(filter);
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("getServices() failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getServices(): count=" + (ret == null ? 0 : ret.size()));
}
return ret;
}
@GET
@Path("/services/count")
@Produces({ "application/json", "application/xml" })
@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.COUNT_SERVICES + "\")")
public Long countServices(@Context HttpServletRequest request) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.countServices():");
}
Long ret = null;
RangerPerfTracer perf = null;
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.countService()");
}
List<RangerService> services = getServices(request).getServices();
ret = Long.valueOf(services == null ? 0 : services.size());
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("countServices() failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.countServices(): " + ret);
}
return ret;
}
@POST
@Path("/services/validateConfig")
@Produces({ "application/json", "application/xml" })
@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.VALIDATE_CONFIG + "\")")
public VXResponse validateConfig(RangerService service) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.validateConfig(" + service + ")");
}
VXResponse ret = new VXResponse();
RangerPerfTracer perf = null;
try {
if (RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.validateConfig(serviceName=" + service.getName() + ")");
}
ret = serviceMgr.validateConfig(service, svcStore);
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("validateConfig(" + service + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.validateConfig(" + service + "): " + ret);
}
return ret;
}
@POST
@Path("/services/lookupResource/{serviceName}")
@Produces({ "application/json", "application/xml" })
@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.LOOKUP_RESOURCE + "\")")
public List<String> lookupResource(@PathParam("serviceName") String serviceName, ResourceLookupContext context) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.lookupResource(" + serviceName + ")");
}
List<String> ret = new ArrayList<String>();
RangerPerfTracer perf = null;
try {
if (RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.lookupResource(serviceName=" + serviceName + ")");
}
ret = serviceMgr.lookupResource(serviceName, context, svcStore);
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("lookupResource(" + serviceName + ", " + context + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.lookupResource(" + serviceName + "): " + ret);
}
return ret;
}
@POST
@Path("/services/grant/{serviceName}")
@Produces({ "application/json", "application/xml" })
public RESTResponse grantAccess(@PathParam("serviceName") String serviceName, GrantRevokeRequest grantRequest, @Context HttpServletRequest request) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.grantAccess(" + serviceName + ", " + grantRequest + ")");
}
RESTResponse ret = new RESTResponse();
RangerPerfTracer perf = null;
if(grantRequest!=null){
if (serviceUtil.isValidateHttpsAuthentication(serviceName, request)) {
try {
bizUtil.failUnauthenticatedIfNotAllowed();
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.grantAccess(serviceName=" + serviceName + ")");
}
// This is an open API - dont care about who calls it. Caller is treated as privileged user
boolean hasAdminPrivilege = true;
String loggedInUser = null;
validateGrantRevokeRequest(grantRequest, hasAdminPrivilege, loggedInUser);
String userName = grantRequest.getGrantor();
Set<String> userGroups = CollectionUtils.isNotEmpty(grantRequest.getGrantorGroups()) ? grantRequest.getGrantorGroups() : userMgr.getGroupsForUser(userName);
String ownerUser = grantRequest.getOwnerUser();
RangerAccessResource resource = new RangerAccessResourceImpl(StringUtil.toStringObjectMap(grantRequest.getResource()), ownerUser);
Set<String> accessTypes = grantRequest.getAccessTypes();
VXUser vxUser = xUserService.getXUserByUserName(userName);
if (vxUser.getUserRoleList().contains(RangerConstants.ROLE_ADMIN_AUDITOR) || vxUser.getUserRoleList().contains(RangerConstants.ROLE_KEY_ADMIN_AUDITOR)) {
VXResponse vXResponse = new VXResponse();
vXResponse.setStatusCode(HttpServletResponse.SC_UNAUTHORIZED);
vXResponse.setMsgDesc("Operation denied. LoggedInUser=" + vxUser.getId() + " is not permitted to perform the action.");
throw restErrorUtil.generateRESTException(vXResponse);
}
RangerService rangerService = svcStore.getServiceByName(serviceName);
String zoneName = getRangerAdminZoneName(serviceName, grantRequest);
boolean isAdmin = bizUtil.isUserRangerAdmin(userName) || bizUtil.isUserServiceAdmin(rangerService, userName) || hasAdminAccess(serviceName, zoneName, userName, userGroups, resource, accessTypes);
if(!isAdmin) {
throw restErrorUtil.createGrantRevokeRESTException( "User doesn't have necessary permission to grant access");
}
RangerPolicy policy = getExactMatchPolicyForResource(serviceName, resource, zoneName, userName);
if(policy != null) {
boolean policyUpdated = false;
policyUpdated = ServiceRESTUtil.processGrantRequest(policy, grantRequest);
if(policyUpdated) {
policy.setZoneName(zoneName);
svcStore.updatePolicy(policy);
} else {
LOG.error("processGrantRequest processing failed");
throw new Exception("processGrantRequest processing failed");
}
} else {
policy = new RangerPolicy();
policy.setService(serviceName);
policy.setName("grant-" + System.currentTimeMillis()); // TODO: better policy name
policy.setDescription("created by grant");
policy.setIsAuditEnabled(grantRequest.getEnableAudit());
policy.setCreatedBy(userName);
Map<String, RangerPolicyResource> policyResources = new HashMap<String, RangerPolicyResource>();
Set<String> resourceNames = resource.getKeys();
if(! CollectionUtils.isEmpty(resourceNames)) {
for(String resourceName : resourceNames) {
RangerPolicyResource policyResource = new RangerPolicyResource((String) resource.getValue(resourceName));
policyResource.setIsRecursive(grantRequest.getIsRecursive());
policyResources.put(resourceName, policyResource);
}
}
policy.setResources(policyResources);
RangerPolicyItem policyItem = new RangerPolicyItem();
policyItem.setDelegateAdmin(grantRequest.getDelegateAdmin());
policyItem.getUsers().addAll(grantRequest.getUsers());
policyItem.getGroups().addAll(grantRequest.getGroups());
policyItem.getRoles().addAll(grantRequest.getRoles());
for(String accessType : grantRequest.getAccessTypes()) {
policyItem.getAccesses().add(new RangerPolicyItemAccess(accessType, Boolean.TRUE));
}
policy.getPolicyItems().add(policyItem);
policy.setZoneName(zoneName);
svcStore.createPolicy(policy);
}
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("grantAccess(" + serviceName + ", " + grantRequest + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
ret.setStatusCode(RESTResponse.STATUS_SUCCESS);
}
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.grantAccess(" + serviceName + ", " + grantRequest + "): " + ret);
}
return ret;
}
@POST
@Path("/secure/services/grant/{serviceName}")
@Produces({ "application/json", "application/xml" })
public RESTResponse secureGrantAccess(@PathParam("serviceName") String serviceName, GrantRevokeRequest grantRequest, @Context HttpServletRequest request) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.secureGrantAccess(" + serviceName + ", " + grantRequest + ")");
}
RESTResponse ret = new RESTResponse();
RangerPerfTracer perf = null;
bizUtil.blockAuditorRoleUser();
if(grantRequest != null) {
if (serviceUtil.isValidService(serviceName, request)) {
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.scureGrantAccess(serviceName=" + serviceName + ")");
}
XXService xService = daoManager.getXXService().findByName(serviceName);
XXServiceDef xServiceDef = daoManager.getXXServiceDef().getById(xService.getType());
RangerService rangerService = svcStore.getServiceByName(serviceName);
String loggedInUser = bizUtil.getCurrentUserLoginId();
boolean hasAdminPrivilege = bizUtil.isAdmin() || bizUtil.isUserServiceAdmin(rangerService, loggedInUser) || bizUtil.isUserAllowedForGrantRevoke(rangerService, loggedInUser);
validateGrantRevokeRequest(grantRequest, hasAdminPrivilege, loggedInUser);
String userName = grantRequest.getGrantor();
Set<String> userGroups = grantRequest.getGrantorGroups();
String ownerUser = grantRequest.getOwnerUser();
RangerAccessResource resource = new RangerAccessResourceImpl(StringUtil.toStringObjectMap(grantRequest.getResource()), ownerUser);
Set<String> accessTypes = grantRequest.getAccessTypes();
String zoneName = getRangerAdminZoneName(serviceName, grantRequest);
boolean isAllowed = false;
if (StringUtils.equals(xServiceDef.getImplclassname(), EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME)) {
if (bizUtil.isKeyAdmin() || bizUtil.isUserAllowedForGrantRevoke(rangerService, loggedInUser)) {
isAllowed = true;
}
} else {
isAllowed = bizUtil.isUserRangerAdmin(userName) || bizUtil.isUserServiceAdmin(rangerService, userName) || hasAdminAccess(serviceName, zoneName, userName, userGroups, resource, accessTypes);
}
if (isAllowed) {
RangerPolicy policy = getExactMatchPolicyForResource(serviceName, resource, zoneName, userName);
if(policy != null) {
boolean policyUpdated = false;
policyUpdated = ServiceRESTUtil.processGrantRequest(policy, grantRequest);
if(policyUpdated) {
policy.setZoneName(zoneName);
svcStore.updatePolicy(policy);
} else {
LOG.error("processSecureGrantRequest processing failed");
throw new Exception("processSecureGrantRequest processing failed");
}
} else {
policy = new RangerPolicy();
policy.setService(serviceName);
policy.setName("grant-" + System.currentTimeMillis()); // TODO: better policy name
policy.setDescription("created by grant");
policy.setIsAuditEnabled(grantRequest.getEnableAudit());
policy.setCreatedBy(userName);
Map<String, RangerPolicyResource> policyResources = new HashMap<String, RangerPolicyResource>();
Set<String> resourceNames = resource.getKeys();
if(! CollectionUtils.isEmpty(resourceNames)) {
for(String resourceName : resourceNames) {
RangerPolicyResource policyResource = new RangerPolicyResource((String) resource.getValue(resourceName));
policyResource.setIsRecursive(grantRequest.getIsRecursive());
policyResources.put(resourceName, policyResource);
}
}
policy.setResources(policyResources);
RangerPolicyItem policyItem = new RangerPolicyItem();
policyItem.setDelegateAdmin(grantRequest.getDelegateAdmin());
policyItem.getUsers().addAll(grantRequest.getUsers());
policyItem.getGroups().addAll(grantRequest.getGroups());
policyItem.getRoles().addAll(grantRequest.getRoles());
for(String accessType : grantRequest.getAccessTypes()) {
policyItem.getAccesses().add(new RangerPolicyItemAccess(accessType, Boolean.TRUE));
}
policy.getPolicyItems().add(policyItem);
policy.setZoneName(zoneName);
svcStore.createPolicy(policy);
}
}else{
LOG.error("secureGrantAccess(" + serviceName + ", " + grantRequest + ") failed as User doesn't have permission to grant Policy");
throw restErrorUtil.createGrantRevokeRESTException( "User doesn't have necessary permission to grant access");
}
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("secureGrantAccess(" + serviceName + ", " + grantRequest + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
ret.setStatusCode(RESTResponse.STATUS_SUCCESS);
}
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.secureGrantAccess(" + serviceName + ", " + grantRequest + "): " + ret);
}
return ret;
}
@POST
@Path("/services/revoke/{serviceName}")
@Produces({ "application/json", "application/xml" })
public RESTResponse revokeAccess(@PathParam("serviceName") String serviceName, GrantRevokeRequest revokeRequest, @Context HttpServletRequest request) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.revokeAccess(" + serviceName + ", " + revokeRequest + ")");
}
RESTResponse ret = new RESTResponse();
RangerPerfTracer perf = null;
if(revokeRequest!=null){
if (serviceUtil.isValidateHttpsAuthentication(serviceName,request)) {
try {
bizUtil.failUnauthenticatedIfNotAllowed();
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.revokeAccess(serviceName=" + serviceName + ")");
}
// This is an open API - dont care about who calls it. Caller is treated as privileged user
boolean hasAdminPrivilege = true;
String loggedInUser = null;
validateGrantRevokeRequest(revokeRequest, hasAdminPrivilege, loggedInUser);
String userName = revokeRequest.getGrantor();
Set<String> userGroups = CollectionUtils.isNotEmpty(revokeRequest.getGrantorGroups()) ? revokeRequest.getGrantorGroups() : userMgr.getGroupsForUser(userName);
String ownerUser = revokeRequest.getOwnerUser();
RangerAccessResource resource = new RangerAccessResourceImpl(StringUtil.toStringObjectMap(revokeRequest.getResource()), ownerUser);
Set<String> accessTypes = revokeRequest.getAccessTypes();
VXUser vxUser = xUserService.getXUserByUserName(userName);
if (vxUser.getUserRoleList().contains(RangerConstants.ROLE_ADMIN_AUDITOR) || vxUser.getUserRoleList().contains(RangerConstants.ROLE_KEY_ADMIN_AUDITOR)) {
VXResponse vXResponse = new VXResponse();
vXResponse.setStatusCode(HttpServletResponse.SC_UNAUTHORIZED);
vXResponse.setMsgDesc("Operation denied. LoggedInUser=" + vxUser.getId() + " is not permitted to perform the action.");
throw restErrorUtil.generateRESTException(vXResponse);
}
RangerService rangerService = svcStore.getServiceByName(serviceName);
String zoneName = getRangerAdminZoneName(serviceName, revokeRequest);
boolean isAdmin = bizUtil.isUserRangerAdmin(userName) || bizUtil.isUserServiceAdmin(rangerService, userName) || hasAdminAccess(serviceName, zoneName, userName, userGroups, resource, accessTypes);
if(!isAdmin) {
throw restErrorUtil.createGrantRevokeRESTException("User doesn't have necessary permission to revoke access");
}
RangerPolicy policy = getExactMatchPolicyForResource(serviceName, resource, zoneName, userName);
if(policy != null) {
boolean policyUpdated = false;
policyUpdated = ServiceRESTUtil.processRevokeRequest(policy, revokeRequest);
if(policyUpdated) {
policy.setZoneName(zoneName);
svcStore.updatePolicy(policy);
} else {
LOG.error("processRevokeRequest processing failed");
throw new Exception("processRevokeRequest processing failed");
}
}
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("revokeAccess(" + serviceName + ", " + revokeRequest + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
ret.setStatusCode(RESTResponse.STATUS_SUCCESS);
}
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.revokeAccess(" + serviceName + ", " + revokeRequest + "): " + ret);
}
return ret;
}
@POST
@Path("/secure/services/revoke/{serviceName}")
@Produces({ "application/json", "application/xml" })
public RESTResponse secureRevokeAccess(@PathParam("serviceName") String serviceName, GrantRevokeRequest revokeRequest, @Context HttpServletRequest request) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.secureRevokeAccess(" + serviceName + ", " + revokeRequest + ")");
}
RESTResponse ret = new RESTResponse();
RangerPerfTracer perf = null;
bizUtil.blockAuditorRoleUser();
if (revokeRequest != null) {
if (serviceUtil.isValidService(serviceName,request)) {
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.secureRevokeAccess(serviceName=" + serviceName + ")");
}
XXService xService = daoManager.getXXService().findByName(serviceName);
XXServiceDef xServiceDef = daoManager.getXXServiceDef().getById(xService.getType());
RangerService rangerService = svcStore.getServiceByName(serviceName);
String loggedInUser = bizUtil.getCurrentUserLoginId();
boolean hasAdminPrivilege = bizUtil.isAdmin() || bizUtil.isUserServiceAdmin(rangerService, loggedInUser) || bizUtil.isUserAllowedForGrantRevoke(rangerService, loggedInUser);
validateGrantRevokeRequest(revokeRequest, hasAdminPrivilege, loggedInUser);
String userName = revokeRequest.getGrantor();
Set<String> userGroups = revokeRequest.getGrantorGroups();
String ownerUser = revokeRequest.getOwnerUser();
RangerAccessResource resource = new RangerAccessResourceImpl(StringUtil.toStringObjectMap(revokeRequest.getResource()), ownerUser);
Set<String> accessTypes = revokeRequest.getAccessTypes();
String zoneName = getRangerAdminZoneName(serviceName, revokeRequest);
boolean isAllowed = false;
if (StringUtils.equals(xServiceDef.getImplclassname(), EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME)) {
if (bizUtil.isKeyAdmin() || bizUtil.isUserAllowedForGrantRevoke(rangerService, loggedInUser)) {
isAllowed = true;
}
} else {
isAllowed = bizUtil.isUserRangerAdmin(userName) || bizUtil.isUserServiceAdmin(rangerService, userName) || hasAdminAccess(serviceName, zoneName, userName, userGroups, resource, accessTypes);
}
if (isAllowed) {
RangerPolicy policy = getExactMatchPolicyForResource(serviceName, resource, zoneName, userName);
if(policy != null) {
boolean policyUpdated = false;
policyUpdated = ServiceRESTUtil.processRevokeRequest(policy, revokeRequest);
if(policyUpdated) {
policy.setZoneName(zoneName);
svcStore.updatePolicy(policy);
} else {
LOG.error("processSecureRevokeRequest processing failed");
throw new Exception("processSecureRevokeRequest processing failed");
}
}
}else{
LOG.error("secureRevokeAccess(" + serviceName + ", " + revokeRequest + ") failed as User doesn't have permission to revoke Policy");
throw restErrorUtil.createGrantRevokeRESTException("User doesn't have necessary permission to revoke access");
}
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("secureRevokeAccess(" + serviceName + ", " + revokeRequest + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
ret.setStatusCode(RESTResponse.STATUS_SUCCESS);
}
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.secureRevokeAccess(" + serviceName + ", " + revokeRequest + "): " + ret);
}
return ret;
}
@POST
@Path("/policies")
@Produces({ "application/json", "application/xml" })
public RangerPolicy createPolicy(RangerPolicy policy, @Context HttpServletRequest request) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.createPolicy(" + policy + ")");
}
RangerPolicy ret = null;
RangerPerfTracer perf = null;
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.createPolicy(policyName=" + policy.getName() + ")");
}
if(request != null) {
boolean deleteIfExists=("true".equalsIgnoreCase(StringUtils.trimToEmpty(request.getParameter(PARAM_DELETE_IF_EXISTS)))) ? true : false ;
if(deleteIfExists) {
boolean importInProgress=("true".equalsIgnoreCase(StringUtils.trimToEmpty(String.valueOf(request.getAttribute(PARAM_IMPORT_IN_PROGRESS))))) ? true : false ;
if (!importInProgress) {
List<RangerPolicy> policies=new ArrayList<RangerPolicy>() { { add(policy); } };
deleteExactMatchPolicyForResource(policies, request.getRemoteUser(), null);
}
}
boolean updateIfExists=("true".equalsIgnoreCase(StringUtils.trimToEmpty(request.getParameter(PARAM_UPDATE_IF_EXISTS)))) ? true : false ;
boolean mergeIfExists = "true".equalsIgnoreCase(StringUtils.trimToEmpty(request.getParameter(PARAM_MERGE_IF_EXISTS))) ? true : false;
// Default POLICY_MATCHING_ALGO_BY_RESOURCE
String policyMatchingAlgo = POLICY_MATCHING_ALGO_BY_POLICYNAME.equalsIgnoreCase(StringUtils.trimToEmpty(request.getParameter(PARAM_POLICY_MATCHING_ALGORITHM))) ? POLICY_MATCHING_ALGO_BY_POLICYNAME : POLICY_MATCHING_ALGO_BY_RESOURCE;
if(LOG.isDebugEnabled()) {
LOG.debug(" policyMatchingAlgo : "+policyMatchingAlgo + " updateIfExists : " +updateIfExists + " mergeIfExists: "+mergeIfExists + " deleteIfExists : "+deleteIfExists);
}
if (mergeIfExists && updateIfExists) {
LOG.warn("Cannot use both updateIfExists and mergeIfExists for a createPolicy. mergeIfExists will override updateIfExists for policy :[" + policy.getName() + "]");
}
if (!mergeIfExists && !updateIfExists) {
ret = createPolicyUnconditionally(policy);
} else if (mergeIfExists) {
ret = applyPolicy(policy, request);
} else if (policyMatchingAlgo.equalsIgnoreCase(POLICY_MATCHING_ALGO_BY_RESOURCE)) {
ret = applyPolicy(policy, request);
} else if (policyMatchingAlgo.equalsIgnoreCase(POLICY_MATCHING_ALGO_BY_POLICYNAME)) {
RangerPolicy existingPolicy = getPolicyMatchByName(policy, request);
if (existingPolicy != null) {
policy.setId(existingPolicy.getId());
ret = updatePolicy(policy);
} else {
ret = createPolicyUnconditionally(policy);
}
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.createPolicy(" + policy + "): " + ret);
}
return ret;
}
if(ret == null) {
ret = createPolicyUnconditionally(policy);
}
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("createPolicy(" + policy + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.createPolicy(" + policy + "): " + ret);
}
return ret;
}
/*
The verb for applyPolicy is POST as it could be partial update or a create
*/
@POST
@Path("/policies/apply")
@Produces({ "application/json", "application/xml" })
public RangerPolicy applyPolicy(RangerPolicy policy, @Context HttpServletRequest request) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.applyPolicy(" + policy + ")");
}
RangerPolicy ret = null;
if (policy != null && StringUtils.isNotBlank(policy.getService())) {
try {
final RangerPolicy existingPolicy;
String signature = (new RangerPolicyResourceSignature(policy)).getSignature();
List<RangerPolicy> policiesWithMatchingSignature = svcStore.getPoliciesByResourceSignature(policy.getService(), signature, true);
if (CollectionUtils.isNotEmpty(policiesWithMatchingSignature)) {
if (policiesWithMatchingSignature.size() == 1) {
existingPolicy = policiesWithMatchingSignature.get(0);
} else {
throw new Exception("Multiple policies with matching policy-signature are found. Cannot determine target for applying policy");
}
} else {
existingPolicy = null;
}
if (existingPolicy == null) {
if (StringUtils.isNotEmpty(policy.getName())) {
String policyName = StringUtils.isNotBlank(policy.getName()) ? policy.getName() : null;
String serviceName = StringUtils.isNotBlank(policy.getService()) ? policy.getService() : null;
String zoneName = StringUtils.isNotBlank(policy.getZoneName()) ? policy.getZoneName() : null;
XXPolicy dbPolicy = daoManager.getXXPolicy().findPolicy(policyName, serviceName, zoneName);
//XXPolicy dbPolicy = daoManager.getXXPolicy().findPolicy(policy.getName(), policy.getService(), policy.getZoneName());
if (dbPolicy != null) {
policy.setName(policy.getName() + System.currentTimeMillis());
}
}
ret = createPolicy(policy, null);
} else {
boolean mergeIfExists = "true".equalsIgnoreCase(StringUtils.trimToEmpty(request.getParameter(PARAM_MERGE_IF_EXISTS)));
if (!mergeIfExists) {
boolean updateIfExists = "true".equalsIgnoreCase(StringUtils.trimToEmpty(request.getParameter(PARAM_UPDATE_IF_EXISTS)));
if (updateIfExists) {
// Called with explicit intent of updating an existing policy
mergeIfExists = false;
} else {
// Invoked through REST API. Merge with existing policy unless 'mergeIfExists' is explicitly set to false in HttpServletRequest
mergeIfExists = !"false".equalsIgnoreCase(StringUtils.trimToEmpty(request.getParameter(PARAM_MERGE_IF_EXISTS)));
}
}
if(mergeIfExists) {
ServiceRESTUtil.processApplyPolicy(existingPolicy, policy);
policy = existingPolicy;
} else {
policy.setId(existingPolicy.getId());
}
ret = updatePolicy(policy);
}
} catch(WebApplicationException excp) {
throw excp;
} catch (Exception exception) {
LOG.error("Failed to apply policy:", exception);
throw restErrorUtil.createRESTException(exception.getMessage());
}
} else {
throw restErrorUtil.createRESTException("Non-existing service specified:");
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.applyPolicy(" + policy + ") : " + ret);
}
return ret;
}
@PUT
@Path("/policies/{id}")
@Produces({ "application/json", "application/xml" })
public RangerPolicy updatePolicy(RangerPolicy policy) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.updatePolicy(" + policy + ")");
}
RangerPolicy ret = null;
RangerPerfTracer perf = null;
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.updatePolicy(policyId=" + policy.getId() + ")");
}
RangerPolicyValidator validator = validatorFactory.getPolicyValidator(svcStore);
validator.validate(policy, Action.UPDATE, bizUtil.isAdmin());
ensureAdminAccess(policy);
bizUtil.blockAuditorRoleUser();
ret = svcStore.updatePolicy(policy);
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("updatePolicy(" + policy + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.updatePolicy(" + policy + "): " + ret);
}
return ret;
}
@DELETE
@Path("/policies/{id}")
@Produces({ "application/json", "application/xml" })
public void deletePolicy(@PathParam("id") Long id) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.deletePolicy(" + id + ")");
}
RangerPerfTracer perf = null;
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.deletePolicy(policyId=" + id + ")");
}
RangerPolicyValidator validator = validatorFactory.getPolicyValidator(svcStore);
validator.validate(id, Action.DELETE);
RangerPolicy policy = svcStore.getPolicy(id);
ensureAdminAccess(policy);
bizUtil.blockAuditorRoleUser();
svcStore.deletePolicy(policy);
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("deletePolicy(" + id + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.deletePolicy(" + id + ")");
}
}
@GET
@Path("/policies/{id}")
@Produces({ "application/json", "application/xml" })
public RangerPolicy getPolicy(@PathParam("id") Long id) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getPolicy(" + id + ")");
}
RangerPolicy ret = null;
RangerPerfTracer perf = null;
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getPolicy(policyId=" + id + ")");
}
ret = svcStore.getPolicy(id);
if(ret != null) {
ensureAdminAndAuditAccess(ret);
}
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("getPolicy(" + id + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if(ret == null) {
throw restErrorUtil.createRESTException(HttpServletResponse.SC_NOT_FOUND, "Not found", true);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getPolicy(" + id + "): " + ret);
}
return ret;
}
@GET
@Path("/policyLabels")
@Produces({ "application/json", "application/xml" })
public List<String> getPolicyLabels(@Context HttpServletRequest request) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getPolicyLabels()");
}
List<String> ret = new ArrayList<String>();
RangerPerfTracer perf = null;
try {
if (RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getPolicyLabels()");
}
SearchFilter filter = searchUtil.getSearchFilter(request, policyLabelsService.sortFields);
ret = svcStore.getPolicyLabels(filter);
} catch (WebApplicationException excp) {
throw excp;
} catch (Throwable excp) {
LOG.error("getPolicyLabels() failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getPolicyLabels()");
}
return ret;
}
@GET
@Path("/policies")
@Produces({ "application/json", "application/xml" })
public RangerPolicyList getPolicies(@Context HttpServletRequest request) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getPolicies()");
}
RangerPolicyList ret = new RangerPolicyList();
RangerPerfTracer perf = null;
SearchFilter filter = searchUtil.getSearchFilter(request, policyService.sortFields);
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getPolicies()");
}
// get all policies from the store; pick the page to return after applying filter
final int savedStartIndex = filter.getStartIndex();
final int savedMaxRows = filter.getMaxRows();
filter.setStartIndex(0);
filter.setMaxRows(Integer.MAX_VALUE);
List<RangerPolicy> policies = svcStore.getPolicies(filter);
filter.setStartIndex(savedStartIndex);
filter.setMaxRows(savedMaxRows);
policies = applyAdminAccessFilter(policies);
ret = toRangerPolicyList(policies, filter);
} catch(WebApplicationException excp) {
throw excp;
} catch (Throwable excp) {
LOG.error("getPolicies() failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getPolicies(): count=" + (ret == null ? 0 : ret.getListSize()));
}
return ret;
}
@GET
@Path("/policies/downloadExcel")
@Produces("application/ms-excel")
public void getPoliciesInExcel(@Context HttpServletRequest request,
@Context HttpServletResponse response) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getPoliciesInExcel()");
}
RangerPerfTracer perf = null;
SearchFilter filter = searchUtil.getSearchFilter(request, policyService.sortFields);
try {
if (RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getPoliciesInExcel()");
}
List<RangerPolicy> policyLists = new ArrayList<RangerPolicy>();
policyLists = getAllFilteredPolicyList(filter, request, policyLists);
if (CollectionUtils.isNotEmpty(policyLists)){
for (RangerPolicy rangerPolicy : policyLists) {
if (rangerPolicy != null) {
ensureAdminAndAuditAccess(rangerPolicy);
}
}
svcStore.getPoliciesInExcel(policyLists, response);
}else{
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
LOG.error("No policies found to download!");
}
RangerExportPolicyList rangerExportPolicyList = new RangerExportPolicyList();
svcStore.putMetaDataInfo(rangerExportPolicyList);
String metaDataInfo = JsonUtilsV2.mapToJson(rangerExportPolicyList.getMetaDataInfo());
List<XXTrxLog> trxLogList = new ArrayList<XXTrxLog>();
XXTrxLog xxTrxLog = new XXTrxLog();
xxTrxLog.setAction("EXPORT EXCEL");
xxTrxLog.setObjectClassType(AppConstants.CLASS_TYPE_RANGER_POLICY);
xxTrxLog.setPreviousValue(metaDataInfo);
trxLogList.add(xxTrxLog);
bizUtil.createTrxLog(trxLogList);
} catch (WebApplicationException excp) {
throw excp;
} catch (Throwable excp) {
LOG.error("Error while downloading policy report", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
}
@GET
@Path("/policies/csv")
@Produces("text/csv")
public void getPoliciesInCsv(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException {
if (LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getPoliciesInCsv()");
}
RangerPerfTracer perf = null;
SearchFilter filter = searchUtil.getSearchFilter(request, policyService.sortFields);
try {
if (RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getPoliciesInCsv()");
}
List<RangerPolicy> policyLists = new ArrayList<RangerPolicy>();
policyLists = getAllFilteredPolicyList(filter, request, policyLists);
if (CollectionUtils.isNotEmpty(policyLists)){
for (RangerPolicy rangerPolicy : policyLists) {
if (rangerPolicy != null) {
ensureAdminAndAuditAccess(rangerPolicy);
}
}
svcStore.getPoliciesInCSV(policyLists, response);
}else{
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
LOG.error("No policies found to download!");
}
RangerExportPolicyList rangerExportPolicyList = new RangerExportPolicyList();
svcStore.putMetaDataInfo(rangerExportPolicyList);
String metaDataInfo = JsonUtilsV2.mapToJson(rangerExportPolicyList.getMetaDataInfo());
List<XXTrxLog> trxLogList = new ArrayList<XXTrxLog>();
XXTrxLog xxTrxLog = new XXTrxLog();
xxTrxLog.setAction("EXPORT CSV");
xxTrxLog.setObjectClassType(AppConstants.CLASS_TYPE_RANGER_POLICY);
xxTrxLog.setPreviousValue(metaDataInfo);
trxLogList.add(xxTrxLog);
bizUtil.createTrxLog(trxLogList);
} catch (WebApplicationException excp) {
throw excp;
} catch (Throwable excp) {
LOG.error("Error while downloading policy report", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
}
@GET
@Path("/policies/exportJson")
@Produces("text/json")
public void getPoliciesInJson(@Context HttpServletRequest request,
@Context HttpServletResponse response,
@QueryParam("checkPoliciesExists") Boolean checkPoliciesExists) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getPoliciesInJson()");
}
RangerPerfTracer perf = null;
SearchFilter filter = searchUtil.getSearchFilter(request,policyService.sortFields);
requestParamsValidation(filter);
try {
if (RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG,"ServiceREST.getPoliciesInJson()");
}
if (checkPoliciesExists == null){
checkPoliciesExists = false;
}
List<RangerPolicy> policyLists = new ArrayList<RangerPolicy>();
policyLists = getAllFilteredPolicyList(filter, request, policyLists);
if (CollectionUtils.isNotEmpty(policyLists)) {
for (RangerPolicy rangerPolicy : policyLists) {
if (rangerPolicy != null) {
ensureAdminAndAuditAccess(rangerPolicy);
}
}
bizUtil.blockAuditorRoleUser();
svcStore.getPoliciesInJson(policyLists, response);
} else {
checkPoliciesExists = true;
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
LOG.error("There is no Policy to Export!!");
}
if(!checkPoliciesExists){
RangerExportPolicyList rangerExportPolicyList = new RangerExportPolicyList();
svcStore.putMetaDataInfo(rangerExportPolicyList);
String metaDataInfo = JsonUtilsV2.mapToJson(rangerExportPolicyList.getMetaDataInfo());
List<XXTrxLog> trxLogList = new ArrayList<XXTrxLog>();
XXTrxLog xxTrxLog = new XXTrxLog();
xxTrxLog.setAction("EXPORT JSON");
xxTrxLog.setObjectClassType(AppConstants.CLASS_TYPE_RANGER_POLICY);
xxTrxLog.setPreviousValue(metaDataInfo);
trxLogList.add(xxTrxLog);
bizUtil.createTrxLog(trxLogList);
}
} catch (WebApplicationException excp) {
throw excp;
} catch (Throwable excp) {
LOG.error("Error while exporting policy file!!", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
}
private void requestParamsValidation(SearchFilter filter) {
Boolean fetchAllZonePolicies = Boolean.valueOf(filter.getParam(SearchFilter.FETCH_ZONE_UNZONE_POLICIES));
String zoneName = filter.getParam(SearchFilter.ZONE_NAME);
if (fetchAllZonePolicies && StringUtils.isNotEmpty(zoneName)) {
throw restErrorUtil.createRESTException("Invalid parameter: " + SearchFilter.ZONE_NAME + " can not be provided, along with " + SearchFilter.FETCH_ZONE_UNZONE_POLICIES + "=true");
}
}
@POST
@Path("/policies/importPoliciesFromFile")
@Consumes({MediaType.MULTIPART_FORM_DATA, MediaType.APPLICATION_JSON})
@Produces({ "application/json", "application/xml" })
@PreAuthorize("@rangerPreAuthSecurityHandler.isAdminOrKeyAdminRole()")
public void importPoliciesFromFile(
@Context HttpServletRequest request,
@FormDataParam("servicesMapJson") InputStream serviceMapStream,
@FormDataParam("zoneMapJson") InputStream zoneMapStream,
@FormDataParam("file") InputStream uploadedInputStream,
@FormDataParam("file") FormDataContentDisposition fileDetail,
@QueryParam("isOverride") Boolean isOverride,
@QueryParam("importType") String importType) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.importPoliciesFromFile()");
}
RangerAdminOpContext opContext = new RangerAdminOpContext();
opContext.setBulkModeContext(true);
RangerContextHolder.setOpContext(opContext);
RangerPerfTracer perf = null;
String metaDataInfo = null;
List<XXTrxLog> trxLogListError = new ArrayList<XXTrxLog>();
XXTrxLog xxTrxLogError = new XXTrxLog();
request.setAttribute(PARAM_IMPORT_IN_PROGRESS, true);
try {
if (RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG,"ServiceREST.importPoliciesFromFile()");
}
List<XXTrxLog> trxLogList = new ArrayList<XXTrxLog>();
XXTrxLog xxTrxLog = new XXTrxLog();
xxTrxLog.setAction("IMPORT START");
xxTrxLog.setObjectClassType(AppConstants.CLASS_TYPE_RANGER_POLICY);
xxTrxLog.setPreviousValue("IMPORT START");
trxLogList.add(xxTrxLog);
bizUtil.createTrxLog(trxLogList);
if (isOverride == null){
isOverride = false;
}
List<String> serviceNameList = new ArrayList<String>();
getServiceNameList(request,serviceNameList);
Map<String, String> servicesMappingMap = new LinkedHashMap<String, String>();
List<String> sourceServices = new ArrayList<String>();
List<String> destinationServices = new ArrayList<String>();
Map<String, String> zoneMappingMap = new LinkedHashMap<String, String>();
List<String> sourceZones = new ArrayList<String>();
List<String> destinationZones = new ArrayList<String>();
if (zoneMapStream != null) {
zoneMappingMap = svcStore.getMapFromInputStream(zoneMapStream);
processZoneMapping(zoneMappingMap, sourceZones, destinationZones);
}
if (serviceMapStream != null){
servicesMappingMap = svcStore.getMapFromInputStream(serviceMapStream);
processServiceMapping(servicesMappingMap, sourceServices, destinationServices);
}
String fileName = fileDetail.getFileName();
int totalPolicyCreate = 0;
String zoneNameInJson = null;
Map<String, RangerPolicy> policiesMap = new LinkedHashMap<String, RangerPolicy>();
List<String> dataFileSourceServices = new ArrayList<String>();
if (fileName.endsWith("json")) {
try {
RangerExportPolicyList rangerExportPolicyList = null;
List<RangerPolicy> policies = null;
rangerExportPolicyList = processPolicyInputJsonForMetaData(uploadedInputStream,rangerExportPolicyList);
if (rangerExportPolicyList != null && !CollectionUtils.sizeIsEmpty(rangerExportPolicyList.getMetaDataInfo())) {
metaDataInfo = JsonUtilsV2.mapToJson(rangerExportPolicyList.getMetaDataInfo());
} else {
LOG.info("metadata info is not provided!!");
}
policies = getPoliciesFromProvidedJson(rangerExportPolicyList);
int i = 0;
if (CollectionUtils.sizeIsEmpty(servicesMappingMap) && isOverride){
if(policies != null && !CollectionUtils.sizeIsEmpty(policies)){
for (RangerPolicy policyInJson: policies){
if (policyInJson != null ) {
if (i == 0 && StringUtils.isNotBlank(policyInJson.getZoneName())) {
zoneNameInJson = policyInJson.getZoneName().trim();
}
if (StringUtils.isNotEmpty(policyInJson.getService().trim())) {
String serviceName = policyInJson.getService().trim();
if (CollectionUtils.isNotEmpty(serviceNameList) && serviceNameList.contains(serviceName) && !sourceServices.contains(serviceName) && !destinationServices.contains(serviceName)) {
sourceServices.add(serviceName);
destinationServices.add(serviceName);
} else if (CollectionUtils.isEmpty(serviceNameList)
&& !sourceServices.contains(serviceName)
&& !destinationServices.contains(serviceName)) {
sourceServices.add(serviceName);
destinationServices.add(serviceName);
}
}else{
LOG.error("Service Name or Policy Name is not provided!!");
throw restErrorUtil.createRESTException("Service Name or Policy Name is not provided!!");
}
}
i++;
}
}
}else if (!CollectionUtils.sizeIsEmpty(servicesMappingMap)) {
if (policies != null && !CollectionUtils.sizeIsEmpty(policies)){
i = 0;
for (RangerPolicy policyInJson: policies){
if (policyInJson != null){
if (i == 0 && StringUtils.isNotBlank(policyInJson.getZoneName())) {
zoneNameInJson = policyInJson.getZoneName().trim();
}
if (StringUtils.isNotEmpty(policyInJson.getService().trim())) {
dataFileSourceServices.add(policyInJson.getService().trim());
}else{
LOG.error("Service Name or Policy Name is not provided!!");
throw restErrorUtil.createRESTException("Service Name or Policy Name is not provided!!");
}
i++;
}
}
if(!dataFileSourceServices.containsAll(sourceServices)){
LOG.error("Json File does not contain sepcified source service name.");
throw restErrorUtil.createRESTException("Json File does not contain sepcified source service name.");
}
}
}
boolean deleteIfExists=("true".equalsIgnoreCase(StringUtils.trimToEmpty(request.getParameter(PARAM_DELETE_IF_EXISTS)))) ? true : false ;
boolean updateIfExists=("true".equalsIgnoreCase(StringUtils.trimToEmpty(request.getParameter(PARAM_UPDATE_IF_EXISTS)))) ? true : false ;
String polResource = request.getParameter(SearchFilter.POL_RESOURCE);
if (updateIfExists) {
isOverride = false;
}
String destinationZoneName = getDestinationZoneName(destinationZones,zoneNameInJson);
if (isOverride && !updateIfExists && StringUtils.isEmpty(polResource)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Deleting Policy from provided services in servicesMapJson file...");
}
if (CollectionUtils.isNotEmpty(sourceServices) && CollectionUtils.isNotEmpty(destinationServices)) {
deletePoliciesProvidedInServiceMap(sourceServices, destinationServices,destinationZoneName);//In order to delete Zone specific policies from service
}
} else if (updateIfExists && StringUtils.isNotEmpty(polResource)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Deleting Policy from provided services in servicesMapJson file for specific resource...");
}
if (CollectionUtils.isNotEmpty(sourceServices) && CollectionUtils.isNotEmpty(destinationServices)){
deletePoliciesForResource(sourceServices, destinationServices, request, policies,destinationZoneName);//In order to delete Zone specific policies from service
}
}
if (policies != null && !CollectionUtils.sizeIsEmpty(policies)){
for (RangerPolicy policyInJson: policies){
if (policyInJson != null){
if (StringUtils.isNotBlank(destinationZoneName)) {
boolean isZoneServiceExistAtDestination = validateDestZoneServiceMapping(destinationZoneName, policyInJson, servicesMappingMap);
if(!isZoneServiceExistAtDestination) {
LOG.warn("provided service of policy in File is not associated with zone");
continue;
}
}
policiesMap = svcStore.createPolicyMap(zoneMappingMap, sourceZones, destinationZoneName,
servicesMappingMap, sourceServices, destinationServices, policyInJson,
policiesMap);// zone Info is also sent for creating policy map
}
}
if (deleteIfExists) {
//deleting target policies if already exist
deleteExactMatchPolicyForResource(policies, request.getRemoteUser(), destinationZoneName);
}
}
totalPolicyCreate = createPolicesBasedOnPolicyMap(request,policiesMap, serviceNameList, updateIfExists, totalPolicyCreate);
if(!(totalPolicyCreate > 0)){
LOG.error("zero policy is created from provided data file!!");
throw restErrorUtil.createRESTException("zero policy is created from provided data file!!");
}
} catch (IOException e) {
LOG.error(e.getMessage());
throw restErrorUtil.createRESTException(e.getMessage());
}
}else{
LOG.error("Provided file format is not supported!!");
throw restErrorUtil.createRESTException("Provided file format is not supported!!");
}
} catch(JsonSyntaxException ex) {
LOG.error("Provided json file is not valid!!", ex);
xxTrxLogError.setAction("IMPORT ERROR");
xxTrxLogError.setObjectClassType(AppConstants.CLASS_TYPE_RANGER_POLICY);
if(StringUtils.isNotEmpty(metaDataInfo)){
xxTrxLogError.setPreviousValue(metaDataInfo);
}
trxLogListError.add(xxTrxLogError);
bizUtil.createTrxLog(trxLogListError);
throw restErrorUtil.createRESTException(ex.getMessage());
}catch (WebApplicationException excp) {
LOG.error("Error while importing policy from file!!", excp);
xxTrxLogError.setAction("IMPORT ERROR");
xxTrxLogError.setObjectClassType(AppConstants.CLASS_TYPE_RANGER_POLICY);
if(StringUtils.isNotEmpty(metaDataInfo)){
xxTrxLogError.setPreviousValue(metaDataInfo);
}
trxLogListError.add(xxTrxLogError);
bizUtil.createTrxLog(trxLogListError);
throw excp;
} catch (Throwable excp) {
LOG.error("Error while importing policy from file!!", excp);
xxTrxLogError.setAction("IMPORT ERROR");
xxTrxLogError.setObjectClassType(AppConstants.CLASS_TYPE_RANGER_POLICY);
if(StringUtils.isNotEmpty(metaDataInfo)){
xxTrxLogError.setPreviousValue(metaDataInfo);
}
trxLogListError.add(xxTrxLogError);
bizUtil.createTrxLog(trxLogListError);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
List<XXTrxLog> trxLogListEnd = new ArrayList<XXTrxLog>();
XXTrxLog xxTrxLogEnd = new XXTrxLog();
xxTrxLogEnd.setAction("IMPORT END");
xxTrxLogEnd.setObjectClassType(AppConstants.CLASS_TYPE_RANGER_POLICY);
if(StringUtils.isNotEmpty(metaDataInfo)){
xxTrxLogEnd.setPreviousValue(metaDataInfo);
}
trxLogListEnd.add(xxTrxLogEnd);
bizUtil.createTrxLog(trxLogListEnd);
if (LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.importPoliciesFromFile()");
}
}
}
private int createPolicesBasedOnPolicyMap(HttpServletRequest request, Map<String, RangerPolicy> policiesMap,
List<String> serviceNameList, boolean updateIfExists, int totalPolicyCreate) {
boolean mergeIfExists = "true".equalsIgnoreCase(StringUtils.trimToEmpty(request.getParameter(PARAM_MERGE_IF_EXISTS))) ? true : false;
boolean deleteIfExists = "true".equalsIgnoreCase(StringUtils.trimToEmpty(request.getParameter(PARAM_DELETE_IF_EXISTS))) ? true : false;
if (!CollectionUtils.sizeIsEmpty(policiesMap.entrySet())) {
for (Entry<String, RangerPolicy> entry : policiesMap.entrySet()) {
RangerPolicy policy = entry.getValue();
if (policy != null){
if (!CollectionUtils.isEmpty(serviceNameList)) {
for (String service : serviceNameList) {
if (StringUtils.isNotEmpty(service.trim()) && StringUtils.isNotEmpty(policy.getService().trim())){
if (policy.getService().trim().equalsIgnoreCase(service.trim())) {
if (updateIfExists || mergeIfExists || deleteIfExists) {
request.setAttribute(PARAM_SERVICE_NAME, policy.getService());
request.setAttribute(PARAM_POLICY_NAME, policy.getName());
request.setAttribute(PARAM_ZONE_NAME, policy.getZoneName());
if(mergeIfExists && !ServiceRESTUtil.containsRangerCondition(policy)) {
String user = request.getRemoteUser();
RangerPolicy existingPolicy;
try {
existingPolicy = getExactMatchPolicyForResource(policy, StringUtils.isNotBlank(user) ? user :"admin");
} catch (Exception e) {
existingPolicy=null;
}
if (existingPolicy == null) {
createPolicy(policy, request);
} else {
ServiceRESTUtil.mergeExactMatchPolicyForResource(existingPolicy, policy);
updatePolicy(existingPolicy);
}
} else {
createPolicy(policy, request);
}
} else {
createPolicy(policy, request);
}
totalPolicyCreate = totalPolicyCreate + 1;
if (LOG.isDebugEnabled()) {
LOG.debug("Policy " + policy.getName() + " created successfully.");
}
break;
}
} else {
LOG.error("Service Name or Policy Name is not provided!!");
throw restErrorUtil.createRESTException("Service Name or Policy Name is not provided!!");
}
}
} else {
if (updateIfExists || mergeIfExists || deleteIfExists) {
request.setAttribute(PARAM_SERVICE_NAME, policy.getService());
request.setAttribute(PARAM_POLICY_NAME, policy.getName());
request.setAttribute(PARAM_ZONE_NAME, policy.getZoneName());
if(mergeIfExists && !ServiceRESTUtil.containsRangerCondition(policy)) {
String user = request.getRemoteUser();
RangerPolicy existingPolicy;
try {
existingPolicy = getExactMatchPolicyForResource(policy, StringUtils.isNotBlank(user) ? user :"admin");
} catch (Exception e) {
existingPolicy=null;
}
if (existingPolicy == null) {
createPolicy(policy, request);
} else {
ServiceRESTUtil.mergeExactMatchPolicyForResource(existingPolicy, policy);
updatePolicy(existingPolicy);
}
} else {
createPolicy(policy, request);
}
} else {
createPolicy(policy, request);
}
totalPolicyCreate = totalPolicyCreate + 1;
if (LOG.isDebugEnabled()) {
LOG.debug("Policy " + policy.getName() + " created successfully.");
}
}
}
if(totalPolicyCreate % RangerBizUtil.policyBatchSize == 0) {
bizUtil.bulkModeOnlyFlushAndClear();
}
}
bizUtil.bulkModeOnlyFlushAndClear();
if (LOG.isDebugEnabled()) {
LOG.debug("Total Policy Created From Json file : " + totalPolicyCreate);
}
}
return totalPolicyCreate;
}
private List<RangerPolicy> getPoliciesFromProvidedJson(RangerExportPolicyList rangerExportPolicyList) {
List<RangerPolicy> policies = null;
if (rangerExportPolicyList != null && !CollectionUtils.sizeIsEmpty(rangerExportPolicyList.getPolicies())) {
policies = rangerExportPolicyList.getPolicies();
} else {
LOG.error("Provided json file does not contain any policy!!");
throw restErrorUtil.createRESTException("Provided json file does not contain any policy!!");
}
return policies;
}
private RangerExportPolicyList processPolicyInputJsonForMetaData(InputStream uploadedInputStream,
RangerExportPolicyList rangerExportPolicyList) throws Exception {
String policiesString = IOUtils.toString(uploadedInputStream);
policiesString = policiesString.trim();
if (StringUtils.isNotEmpty(policiesString)) {
rangerExportPolicyList = JsonUtilsV2.jsonToObj(policiesString, RangerExportPolicyList.class);
} else {
LOG.error("Provided json file is empty!!");
throw restErrorUtil.createRESTException("Provided json file is empty!!");
}
return rangerExportPolicyList;
}
private void getServiceNameList(HttpServletRequest request, List<String> serviceNameList) {
SearchFilter filter = searchUtil.getSearchFilter(request,policyService.sortFields);
String serviceType = null;
List<String> serviceTypeList = null;
if (StringUtils.isNotEmpty(request.getParameter(PARAM_SERVICE_TYPE))){
serviceType = request.getParameter(PARAM_SERVICE_TYPE);
}
if(StringUtils.isNotEmpty(serviceType)){
serviceTypeList = new ArrayList<String>(Arrays.asList(serviceType.split(",")));
}
List<RangerService> rangerServiceList = null;
List<RangerService> rangerServiceLists = new ArrayList<RangerService>();
if (CollectionUtils.isNotEmpty(serviceTypeList)){
for (String s : serviceTypeList) {
filter.removeParam(PARAM_SERVICE_TYPE);
filter.setParam(PARAM_SERVICE_TYPE, s.trim());
rangerServiceList = getServices(filter);
rangerServiceLists.addAll(rangerServiceList);
}
}
if(!CollectionUtils.sizeIsEmpty(rangerServiceLists)){
for(RangerService rService : rangerServiceLists){
if (StringUtils.isNotEmpty(rService.getName())){
serviceNameList.add(rService.getName());
}
}
}
}
private boolean validateDestZoneServiceMapping(String destinationZoneName, RangerPolicy policyInJson,
Map<String, String> servicesMappingMap) {
boolean isZoneServiceExistAtDestination = false;
XXSecurityZone xdestZone = daoManager.getXXSecurityZoneDao().findByZoneName(destinationZoneName);
if (xdestZone == null) {
LOG.error("destination zone provided does not exist");
throw restErrorUtil.createRESTException("destination zone provided does not exist");
}
// CHECK IF json policies service is there on destination and asscioated with
// destination zone.
String serviceNameToCheck = policyInJson.getService();
if (StringUtils.isNotBlank(serviceNameToCheck) && servicesMappingMap.containsKey(serviceNameToCheck)) {
serviceNameToCheck = servicesMappingMap.get(policyInJson.getService());
}
List<XXSecurityZoneRefService> serviceZoneMapping = daoManager.getXXSecurityZoneRefService()
.findByServiceNameAndZoneId(serviceNameToCheck, xdestZone.getId());
List<XXSecurityZoneRefTagService> tagServiceZoneMapping = daoManager.getXXSecurityZoneRefTagService()
.findByTagServiceNameAndZoneId(serviceNameToCheck, xdestZone.getId());
if (!CollectionUtils.isEmpty(serviceZoneMapping) || !CollectionUtils.isEmpty(tagServiceZoneMapping)) {
isZoneServiceExistAtDestination = true;
}
return isZoneServiceExistAtDestination;
}
private String getDestinationZoneName(List<String> destinationZones, String zoneNameInJson) {
String destinationZoneName = null;
if (CollectionUtils.isNotEmpty(destinationZones)) {
destinationZoneName = destinationZones.get(0);
} else {
destinationZoneName = zoneNameInJson;
}
return destinationZoneName;
}
private void processServiceMapping(Map<String, String> servicesMappingMap, List<String> sourceServices,
List<String> destinationServices) {
if (!CollectionUtils.sizeIsEmpty(servicesMappingMap)) {
for (Entry<String, String> map : servicesMappingMap.entrySet()) {
String sourceServiceName = null;
String destinationServiceName = null;
if (StringUtils.isNotEmpty(map.getKey().trim()) && StringUtils.isNotEmpty(map.getValue().trim())) {
sourceServiceName = map.getKey().trim();
destinationServiceName = map.getValue().trim();
} else {
LOG.error("Source service or destination service name is not provided!!");
throw restErrorUtil
.createRESTException("Source service or destonation service name is not provided!!");
}
if (StringUtils.isNotEmpty(sourceServiceName) && StringUtils.isNotEmpty(destinationServiceName)) {
sourceServices.add(sourceServiceName);
destinationServices.add(destinationServiceName);
}
}
}
}
private void processZoneMapping(Map<String, String> zoneMappingMap, List<String> sourceZones,
List<String> destinationZones) {
if (!CollectionUtils.sizeIsEmpty(zoneMappingMap)) {
for (Entry<String, String> map : zoneMappingMap.entrySet()) {
String sourceZoneName = null;
String destinationZoneName = null;
if (StringUtils.isNotEmpty(map.getKey().trim()) || StringUtils.isNotEmpty(map.getValue().trim())) {
// zone to zone
// zone to unzone
// unzone to zone
sourceZoneName = map.getKey().trim();
destinationZoneName = map.getValue().trim();
LOG.info("sourceZoneName =" + sourceZoneName + "destinationZoneName = " + destinationZoneName);
} else if (StringUtils.isEmpty(map.getKey().trim()) && StringUtils.isEmpty(map.getValue().trim())) {
LOG.info("Unzone to unzone policies import");
} else {
LOG.error("Source zone or destination zone name is not provided!!");
throw restErrorUtil.createRESTException("Source zone or destination zone name is not provided!!");
}
if (StringUtils.isNotEmpty(sourceZoneName) || StringUtils.isNotEmpty(destinationZoneName)) {
sourceZones.add(sourceZoneName);
destinationZones.add(destinationZoneName);
}
}
}
}
private List<RangerPolicy> getAllFilteredPolicyList(SearchFilter filter,
HttpServletRequest request, List<RangerPolicy> policyLists) {
String serviceNames = null;
String serviceType = null;
List<String> serviceNameList = null;
List<String> serviceTypeList = null;
List<String> serviceNameInServiceTypeList = new ArrayList<String>();
boolean isServiceExists = false;
if (request.getParameter(PARAM_SERVICE_NAME) != null){
serviceNames = request.getParameter(PARAM_SERVICE_NAME);
}
if (StringUtils.isNotEmpty(serviceNames)) {
serviceNameList = new ArrayList<String>(Arrays.asList(serviceNames.split(",")));
}
if (request.getParameter(PARAM_SERVICE_TYPE) != null){
serviceType = request.getParameter(PARAM_SERVICE_TYPE);
}
if(StringUtils.isNotEmpty(serviceType)){
serviceTypeList = new ArrayList<String>(Arrays.asList(serviceType.split(",")));
}
List<RangerPolicy> policyList = new ArrayList<RangerPolicy>();
List<RangerPolicy> policyListByServiceName = new ArrayList<RangerPolicy>();
if (filter != null) {
filter.setStartIndex(0);
filter.setMaxRows(Integer.MAX_VALUE);
if (!CollectionUtils.isEmpty(serviceTypeList)) {
for (String s : serviceTypeList) {
filter.removeParam(PARAM_SERVICE_TYPE);
if (request.getParameter(PARAM_SERVICE_NAME) != null){
filter.removeParam(PARAM_SERVICE_NAME);
}
filter.setParam(PARAM_SERVICE_TYPE, s.trim());
policyList = getPolicies(filter);
policyLists.addAll(policyList);
}
if(!CollectionUtils.sizeIsEmpty(policyLists)){
for (RangerPolicy rangerPolicy:policyLists){
if (StringUtils.isNotEmpty(rangerPolicy.getService())){
serviceNameInServiceTypeList.add(rangerPolicy.getService());
}
}
}
}
if (!CollectionUtils.isEmpty(serviceNameList) && !CollectionUtils.isEmpty(serviceTypeList)){
isServiceExists = serviceNameInServiceTypeList.containsAll(serviceNameList);
if(isServiceExists){
for (String s : serviceNameList) {
filter.removeParam(PARAM_SERVICE_NAME);
filter.removeParam(PARAM_SERVICE_TYPE);
filter.setParam(PARAM_SERVICE_NAME, s.trim());
policyList = getPolicies(filter);
policyListByServiceName.addAll(policyList);
}
policyLists = policyListByServiceName;
}else{
policyLists = new ArrayList<RangerPolicy>();
}
}else if (CollectionUtils.isEmpty(serviceNameList) && CollectionUtils.isEmpty(serviceTypeList)){
policyLists = getPolicies(filter);
}
if (!CollectionUtils.isEmpty(serviceNameList) && CollectionUtils.isEmpty(serviceTypeList)) {
for (String s : serviceNameList) {
filter.removeParam(PARAM_SERVICE_NAME);
filter.setParam(PARAM_SERVICE_NAME, s.trim());
policyList = getPolicies(filter);
policyLists.addAll(policyList);
}
}
}
if (StringUtils.isNotEmpty(request.getParameter("resourceMatch"))
&& "full".equalsIgnoreCase(request.getParameter("resourceMatch"))) {
policyLists = serviceUtil.getMatchingPoliciesForResource(request, policyLists);
}
Map<Long, RangerPolicy> orderedPolicies = new TreeMap<Long, RangerPolicy>();
if (!CollectionUtils.isEmpty(policyLists)) {
for (RangerPolicy policy : policyLists) {
if (policy != null) {
//set createTime & updateTime Time as null since exported policies dont need this
policy.setCreateTime(null);
policy.setUpdateTime(null);
orderedPolicies.put(policy.getId(), policy);
}
}
if (!orderedPolicies.isEmpty()) {
policyLists.clear();
policyLists.addAll(orderedPolicies.values());
}
}
return policyLists;
}
private void deletePoliciesProvidedInServiceMap(List<String> sourceServices, List<String> destinationServices, String zoneName) throws Exception {
int totalDeletedPolicies = 0;
if (CollectionUtils.isNotEmpty(sourceServices)
&& CollectionUtils.isNotEmpty(destinationServices)) {
RangerPolicyValidator validator = validatorFactory.getPolicyValidator(svcStore);
for (int i = 0; i < sourceServices.size(); i++) {
if (!destinationServices.get(i).isEmpty() ) {
SearchFilter filter = new SearchFilter();
filter.setParam(SearchFilter.ZONE_NAME, zoneName);
filter.setParam(SearchFilter.SERVICE_NAME, destinationServices.get(i));
RangerService service=getServiceByName(destinationServices.get(i));
final RangerPolicyList servicePolicies = getServicePolicies(destinationServices.get(i),filter);
if (servicePolicies != null) {
List<RangerPolicy> rangerPolicyList = servicePolicies.getPolicies();
if (CollectionUtils.isNotEmpty(rangerPolicyList)) {
for (RangerPolicy rangerPolicy : rangerPolicyList) {
if (rangerPolicy != null) {
validator.validate(rangerPolicy.getId(), Action.DELETE);
ensureAdminAccess(rangerPolicy);
bizUtil.blockAuditorRoleUser();
svcStore.deletePolicy(rangerPolicy, service);
totalDeletedPolicies = totalDeletedPolicies + 1;
if (totalDeletedPolicies % RangerBizUtil.policyBatchSize == 0) {
bizUtil.bulkModeOnlyFlushAndClear();
}
if (LOG.isDebugEnabled()) {
LOG.debug("Policy " + rangerPolicy.getName() + " deleted successfully.");
LOG.debug("TotalDeletedPilicies: " + totalDeletedPolicies);
}
}
}
bizUtil.bulkModeOnlyFlushAndClear();
}
}
}
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("Total Deleted Policy : " + totalDeletedPolicies);
}
}
private void deletePoliciesForResource(List<String> sourceServices, List<String> destinationServices, HttpServletRequest request, List<RangerPolicy> exportPolicies, String zoneName) throws Exception {
int totalDeletedPolicies = 0;
if (CollectionUtils.isNotEmpty(sourceServices)
&& CollectionUtils.isNotEmpty(destinationServices)) {
Set<String> exportedPolicyNames=new HashSet<String>();
if (CollectionUtils.isNotEmpty(exportPolicies)) {
for (RangerPolicy rangerPolicy : exportPolicies) {
if (rangerPolicy!=null) {
exportedPolicyNames.add(rangerPolicy.getName());
}
}
}
for (int i = 0; i < sourceServices.size(); i++) {
if (!destinationServices.get(i).isEmpty()) {
RangerPolicyList servicePolicies = null;
SearchFilter filter = searchUtil.getSearchFilter(request,policyService.sortFields);
filter.setParam("zoneName", zoneName);
servicePolicies = getServicePolicies(destinationServices.get(i), filter);
RangerService service=getServiceByName(destinationServices.get(i));
if (servicePolicies != null) {
List<RangerPolicy> rangerPolicyList = servicePolicies.getPolicies();
if (CollectionUtils.isNotEmpty(rangerPolicyList)) {
List<RangerPolicy> policiesToBeDeleted = new ArrayList<RangerPolicy>();
for (RangerPolicy rangerPolicy : rangerPolicyList) {
if (rangerPolicy != null) {
Map<String, RangerPolicy.RangerPolicyResource> rangerPolicyResourceMap=rangerPolicy.getResources();
if (rangerPolicyResourceMap!=null) {
RangerPolicy.RangerPolicyResource rangerPolicyResource=null;
if (rangerPolicyResourceMap.containsKey("path")) {
rangerPolicyResource=rangerPolicyResourceMap.get("path");
} else if (rangerPolicyResourceMap.containsKey("database")) {
rangerPolicyResource=rangerPolicyResourceMap.get("database");
}
if (rangerPolicyResource!=null) {
if (CollectionUtils.isNotEmpty(rangerPolicyResource.getValues()) && rangerPolicyResource.getValues().size()>1) {
continue;
}
}
}
if (rangerPolicy.getId() != null) {
if (!exportedPolicyNames.contains(rangerPolicy.getName())) {
policiesToBeDeleted.add(rangerPolicy);
}
}
}
}
if (CollectionUtils.isNotEmpty(policiesToBeDeleted)) {
for (RangerPolicy rangerPolicy : policiesToBeDeleted) {
svcStore.deletePolicy(rangerPolicy, service);
if (LOG.isDebugEnabled()) {
LOG.debug("Policy " + rangerPolicy.getName() + " deleted successfully.");
}
totalDeletedPolicies = totalDeletedPolicies + 1;
if (totalDeletedPolicies % RangerBizUtil.policyBatchSize == 0) {
bizUtil.bulkModeOnlyFlushAndClear();
}
}
bizUtil.bulkModeOnlyFlushAndClear();
}
}
}
}
}
}
}
public List<RangerPolicy> getPolicies(SearchFilter filter) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getPolicies(filter)");
}
List<RangerPolicy> ret = null;
RangerPerfTracer perf = null;
try {
if (RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getPolicies()");
}
ret = svcStore.getPolicies(filter);
ret = applyAdminAccessFilter(ret);
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("getPolicies() failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getPolicies(filter): count=" + (ret == null ? 0 : ret.size()));
}
return ret;
}
@GET
@Path("/policies/count")
@Produces({ "application/json", "application/xml" })
public Long countPolicies( @Context HttpServletRequest request) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.countPolicies():");
}
Long ret = null;
RangerPerfTracer perf = null;
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.countPolicies()");
}
List<RangerPolicy> policies = getPolicies(request).getPolicies();
policies = applyAdminAccessFilter(policies);
ret = Long.valueOf(policies == null ? 0 : policies.size());
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("countPolicies() failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.countPolicies(): " + ret);
}
return ret;
}
@GET
@Path("/policies/service/{id}")
@Produces({ "application/json", "application/xml" })
public RangerPolicyList getServicePolicies(@PathParam("id") Long serviceId,
@Context HttpServletRequest request) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getServicePolicies(" + serviceId + ")");
}
RangerPolicyList ret = new RangerPolicyList();
RangerPerfTracer perf = null;
SearchFilter filter = searchUtil.getSearchFilter(request, policyService.sortFields);
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getServicePolicies(serviceId=" + serviceId + ")");
}
// get all policies from the store; pick the page to return after applying filter
int savedStartIndex = filter == null ? 0 : filter.getStartIndex();
int savedMaxRows = filter == null ? Integer.MAX_VALUE : filter.getMaxRows();
if(filter != null) {
filter.setStartIndex(0);
filter.setMaxRows(Integer.MAX_VALUE);
}
List<RangerPolicy> servicePolicies = svcStore.getServicePolicies(serviceId, filter);
if(filter != null) {
filter.setStartIndex(savedStartIndex);
filter.setMaxRows(savedMaxRows);
}
servicePolicies = applyAdminAccessFilter(servicePolicies);
ret = toRangerPolicyList(servicePolicies, filter);
} catch(WebApplicationException excp) {
throw excp;
} catch (Throwable excp) {
LOG.error("getServicePolicies(" + serviceId + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getServicePolicies(" + serviceId + "): count="
+ (ret == null ? 0 : ret.getListSize()));
}
return ret;
}
@GET
@Path("/policies/service/name/{name}")
@Produces({ "application/json", "application/xml" })
public RangerPolicyList getServicePoliciesByName(@PathParam("name") String serviceName,
@Context HttpServletRequest request) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getServicePolicies(" + serviceName + ")");
}
SearchFilter filter = searchUtil.getSearchFilter(request, policyService.sortFields);
RangerPolicyList ret = getServicePolicies(serviceName, filter);
if (LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getServicePolicies(" + serviceName + "): count="
+ (ret == null ? 0 : ret.getListSize()));
}
return ret;
}
private RangerPolicyList getServicePolicies(String serviceName, SearchFilter filter) {
RangerPerfTracer perf = null;
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getServicePolicies(serviceName=" + serviceName + ")");
}
// get all policies from the store; pick the page to return after applying filter
int savedStartIndex = filter == null ? 0 : filter.getStartIndex();
int savedMaxRows = filter == null ? Integer.MAX_VALUE : filter.getMaxRows();
if(filter != null) {
filter.setStartIndex(0);
filter.setMaxRows(Integer.MAX_VALUE);
}
List<RangerPolicy> servicePolicies = svcStore.getServicePolicies(serviceName, filter);
if(filter != null) {
filter.setStartIndex(savedStartIndex);
filter.setMaxRows(savedMaxRows);
}
servicePolicies = applyAdminAccessFilter(servicePolicies);
return toRangerPolicyList(servicePolicies, filter);
} catch(WebApplicationException excp) {
throw excp;
} catch (Throwable excp) {
LOG.error("getServicePolicies(" + serviceName + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
}
@GET
@Path("/policies/download/{serviceName}")
@Produces({ "application/json", "application/xml" })
public ServicePolicies getServicePoliciesIfUpdated(
@PathParam("serviceName") String serviceName,
@QueryParam("lastKnownVersion") Long lastKnownVersion,
@DefaultValue("0") @QueryParam("lastActivationTime") Long lastActivationTime,
@QueryParam("pluginId") String pluginId,
@DefaultValue("") @QueryParam("clusterName") String clusterName,
@DefaultValue("") @QueryParam("zoneName") String zoneName,
@DefaultValue("false") @QueryParam("supportsPolicyDeltas") Boolean supportsPolicyDeltas,
@DefaultValue("") @QueryParam("pluginCapabilities") String pluginCapabilities,
@Context HttpServletRequest request) throws Exception {
if (LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getServicePoliciesIfUpdated("
+ serviceName + ", " + lastKnownVersion + ", "
+ lastActivationTime + ", " + pluginId + ", "
+ clusterName + ", " + supportsPolicyDeltas + ")");
}
ServicePolicies ret = null;
int httpCode = HttpServletResponse.SC_OK;
String logMsg = null;
RangerPerfTracer perf = null;
Long downloadedVersion = null;
boolean isValid = false;
try {
bizUtil.failUnauthenticatedIfNotAllowed();
isValid = serviceUtil.isValidateHttpsAuthentication(serviceName, request);
} catch (WebApplicationException webException) {
httpCode = webException.getResponse().getStatus();
logMsg = webException.getResponse().getEntity().toString();
} catch (Exception e) {
httpCode = HttpServletResponse.SC_BAD_REQUEST;
logMsg = e.getMessage();
}
if (isValid) {
if (lastKnownVersion == null) {
lastKnownVersion = Long.valueOf(-1);
}
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getServicePoliciesIfUpdated(serviceName=" + serviceName + ",lastKnownVersion=" + lastKnownVersion + ",lastActivationTime=" + lastActivationTime + ")");
}
ServicePolicies servicePolicies = svcStore.getServicePoliciesIfUpdated(serviceName, lastKnownVersion, !supportsPolicyDeltas);
if (servicePolicies == null) {
downloadedVersion = lastKnownVersion;
httpCode = HttpServletResponse.SC_NOT_MODIFIED;
logMsg = "No change since last update";
} else {
Map<String, RangerSecurityZone.RangerSecurityZoneService> securityZones = zoneStore.getSecurityZonesForService(serviceName);
ServicePolicies updatedServicePolicies = servicePolicies;
if (MapUtils.isNotEmpty(securityZones)) {
updatedServicePolicies = RangerPolicyAdminCache.getUpdatedServicePoliciesForZones(servicePolicies, securityZones);
patchAssociatedTagServiceInSecurityZoneInfos(updatedServicePolicies);
}
downloadedVersion = updatedServicePolicies.getPolicyVersion();
if (lastKnownVersion == -1L || !supportsPolicyDeltas) {
ret = filterServicePolicies(updatedServicePolicies);
} else {
ret = updatedServicePolicies;
}
ret.setServiceConfig(svcStore.getServiceConfigForPlugin(ret.getServiceId()));
if (ret.getTagPolicies() != null && ret.getTagPolicies().getServiceId() != null) {
ret.getTagPolicies().setServiceConfig(svcStore.getServiceConfigForPlugin(ret.getTagPolicies().getServiceId()));
}
httpCode = HttpServletResponse.SC_OK;
logMsg = "Returning " + (ret.getPolicies() != null ? ret.getPolicies().size() : (ret.getPolicyDeltas() != null ? ret.getPolicyDeltas().size() : 0)) + " policies. Policy version=" + ret.getPolicyVersion();
}
} catch (Throwable excp) {
LOG.error("getServicePoliciesIfUpdated(" + serviceName + ", " + lastKnownVersion + ", " + lastActivationTime + ") failed", excp);
httpCode = HttpServletResponse.SC_BAD_REQUEST;
logMsg = excp.getMessage();
} finally {
createPolicyDownloadAudit(serviceName, lastKnownVersion, pluginId, httpCode, clusterName, zoneName, request);
RangerPerfTracer.log(perf);
}
}
assetMgr.createPluginInfo(serviceName, pluginId, request, RangerPluginInfo.ENTITY_TYPE_POLICIES, downloadedVersion, lastKnownVersion, lastActivationTime, httpCode, clusterName, pluginCapabilities);
if(httpCode != HttpServletResponse.SC_OK) {
boolean logError = httpCode != HttpServletResponse.SC_NOT_MODIFIED;
throw restErrorUtil.createRESTException(httpCode, logMsg, logError);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getServicePoliciesIfUpdated(" + serviceName + ", " + lastKnownVersion + ", " + lastActivationTime + ", " + pluginId + ", " + clusterName + ", " + supportsPolicyDeltas + "): count=" + ((ret == null || ret.getPolicies() == null) ? 0 : ret.getPolicies().size()));
}
return ret;
}
@GET
@Path("/secure/policies/download/{serviceName}")
@Produces({ "application/json", "application/xml" })
public ServicePolicies getSecureServicePoliciesIfUpdated(
@PathParam("serviceName") String serviceName,
@QueryParam("lastKnownVersion") Long lastKnownVersion,
@DefaultValue("0") @QueryParam("lastActivationTime") Long lastActivationTime,
@QueryParam("pluginId") String pluginId,
@DefaultValue("") @QueryParam("clusterName") String clusterName,
@DefaultValue("") @QueryParam("zoneName") String zoneName,
@DefaultValue("false") @QueryParam("supportsPolicyDeltas") Boolean supportsPolicyDeltas,
@DefaultValue("") @QueryParam("pluginCapabilities") String pluginCapabilities,
@Context HttpServletRequest request) throws Exception {
if (LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getSecureServicePoliciesIfUpdated("
+ serviceName + ", " + lastKnownVersion + ", "
+ lastActivationTime + ", " + pluginId + ", "
+ clusterName + ", " + supportsPolicyDeltas + ")");
}
ServicePolicies ret = null;
int httpCode = HttpServletResponse.SC_OK;
String logMsg = null;
RangerPerfTracer perf = null;
boolean isAllowed = false;
boolean isAdmin = bizUtil.isAdmin();
boolean isKeyAdmin = bizUtil.isKeyAdmin();
request.setAttribute("downloadPolicy", "secure");
Long downloadedVersion = null;
boolean isValid = false;
try {
isValid = serviceUtil.isValidService(serviceName, request);
} catch (WebApplicationException webException) {
httpCode = webException.getResponse().getStatus();
logMsg = webException.getResponse().getEntity().toString();
} catch (Exception e) {
httpCode = HttpServletResponse.SC_BAD_REQUEST;
logMsg = e.getMessage();
}
if (isValid) {
if (lastKnownVersion == null) {
lastKnownVersion = Long.valueOf(-1);
}
try {
if (RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getSecureServicePoliciesIfUpdated(serviceName=" + serviceName + ",lastKnownVersion=" + lastKnownVersion + ",lastActivationTime=" + lastActivationTime + ")");
}
XXService xService = daoManager.getXXService().findByName(serviceName);
XXServiceDef xServiceDef = daoManager.getXXServiceDef().getById(xService.getType());
RangerService rangerService = null;
if (StringUtils.equals(xServiceDef.getImplclassname(), EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME)) {
rangerService = svcStore.getServiceByNameForDP(serviceName);
if (isKeyAdmin) {
isAllowed = true;
} else {
if (rangerService != null) {
isAllowed = bizUtil.isUserAllowed(rangerService, Allowed_User_List_For_Download);
if (!isAllowed) {
isAllowed = bizUtil.isUserAllowed(rangerService, Allowed_User_List_For_Grant_Revoke);
}
}
}
} else {
rangerService = svcStore.getServiceByName(serviceName);
if (isAdmin) {
isAllowed = true;
} else {
if (rangerService != null) {
isAllowed = bizUtil.isUserAllowed(rangerService, Allowed_User_List_For_Download);
if (!isAllowed) {
isAllowed = bizUtil.isUserAllowed(rangerService, Allowed_User_List_For_Grant_Revoke);
}
}
}
}
if (isAllowed) {
ServicePolicies servicePolicies = svcStore.getServicePoliciesIfUpdated(serviceName, lastKnownVersion, !supportsPolicyDeltas);
if (servicePolicies == null) {
downloadedVersion = lastKnownVersion;
httpCode = HttpServletResponse.SC_NOT_MODIFIED;
logMsg = "No change since last update";
} else {
Map<String, RangerSecurityZone.RangerSecurityZoneService> securityZones = zoneStore.getSecurityZonesForService(serviceName);
ServicePolicies updatedServicePolicies = servicePolicies;
if (MapUtils.isNotEmpty(securityZones)) {
updatedServicePolicies = RangerPolicyAdminCache.getUpdatedServicePoliciesForZones(servicePolicies, securityZones);
patchAssociatedTagServiceInSecurityZoneInfos(updatedServicePolicies);
}
downloadedVersion = updatedServicePolicies.getPolicyVersion();
if (lastKnownVersion == -1L || !supportsPolicyDeltas) {
ret = filterServicePolicies(updatedServicePolicies);
} else {
ret = updatedServicePolicies;
}
ret.setServiceConfig(svcStore.getServiceConfigForPlugin(ret.getServiceId()));
if (ret.getTagPolicies() != null && ret.getTagPolicies().getServiceId() != null) {
ret.getTagPolicies().setServiceConfig(svcStore.getServiceConfigForPlugin(ret.getTagPolicies().getServiceId()));
}
httpCode = HttpServletResponse.SC_OK;
logMsg = "Returning " + (ret.getPolicies() != null ? ret.getPolicies().size() : (ret.getPolicyDeltas() != null ? ret.getPolicyDeltas().size() : 0)) + " policies. Policy version=" + ret.getPolicyVersion();
}
} else {
LOG.error("getSecureServicePoliciesIfUpdated(" + serviceName + ", " + lastKnownVersion + ") failed as User doesn't have permission to download Policy");
httpCode = HttpServletResponse.SC_UNAUTHORIZED;
logMsg = "User doesn't have permission to download policy";
}
} catch (Throwable excp) {
LOG.error("getSecureServicePoliciesIfUpdated(" + serviceName + ", " + lastKnownVersion + ", " + lastActivationTime + ") failed", excp);
httpCode = HttpServletResponse.SC_BAD_REQUEST;
logMsg = excp.getMessage();
} finally {
createPolicyDownloadAudit(serviceName, lastKnownVersion, pluginId, httpCode, clusterName, zoneName, request);
RangerPerfTracer.log(perf);
}
}
assetMgr.createPluginInfo(serviceName, pluginId, request, RangerPluginInfo.ENTITY_TYPE_POLICIES, downloadedVersion, lastKnownVersion, lastActivationTime, httpCode, clusterName, pluginCapabilities);
if (httpCode != HttpServletResponse.SC_OK) {
boolean logError = httpCode != HttpServletResponse.SC_NOT_MODIFIED;
throw restErrorUtil.createRESTException(httpCode, logMsg, logError);
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getSecureServicePoliciesIfUpdated(" + serviceName + ", " + lastKnownVersion + ", " + lastActivationTime + ", " + pluginId + ", " + clusterName + ", " + supportsPolicyDeltas + "): count=" + ((ret == null || ret.getPolicies() == null) ? 0 : ret.getPolicies().size()));
}
return ret;
}
@DELETE
@Path("/server/policydeltas")
@PreAuthorize("hasRole('ROLE_SYS_ADMIN')")
public void deletePolicyDeltas(@DefaultValue("7") @QueryParam("days") Integer olderThan, @Context HttpServletRequest request) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.deletePolicyDeltas(" + olderThan + ")");
}
svcStore.resetPolicyUpdateLog(olderThan, RangerPolicyDelta.CHANGE_TYPE_INVALIDATE_POLICY_DELTAS);
if (LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.deletePolicyDeltas(" + olderThan + ")");
}
}
@DELETE
@Path("/server/purgepolicies/{serviceName}")
@PreAuthorize("hasRole('ROLE_SYS_ADMIN')")
public void purgeEmptyPolicies(@PathParam("serviceName") String serviceName, @Context HttpServletRequest request) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.purgeEmptyPolicies(" + serviceName + ")");
}
if (serviceName == null) {
throw restErrorUtil.createRESTException(HttpServletResponse.SC_BAD_REQUEST , "Invalid service name", true);
}
RangerPerfTracer perf = null;
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.purgeEmptyPolicies(serviceName=" + serviceName + ")");
}
if (svcStore.getServiceByName(serviceName) == null) {
throw new Exception("service does not exist - name=" + serviceName);
}
ServicePolicies servicePolicies = svcStore.getServicePolicies(serviceName, -1L);
if (servicePolicies != null && CollectionUtils.isNotEmpty(servicePolicies.getPolicies())) {
for (RangerPolicy policy : servicePolicies.getPolicies()) {
if (CollectionUtils.isEmpty(PolicyRefUpdater.getAllPolicyItems(policy))) {
deletePolicy(policy.getId());
}
}
}
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("purgeEmptyPolicies(" + serviceName + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.purgeEmptyPolicies(" + serviceName + ")");
}
}
private void createPolicyDownloadAudit(String serviceName, Long lastKnownVersion, String pluginId, int httpRespCode, String clusterName, String zoneName, HttpServletRequest request) {
try {
String ipAddress = request.getHeader("X-FORWARDED-FOR");
if (ipAddress == null) {
ipAddress = request.getRemoteAddr();
}
XXPolicyExportAudit policyExportAudit = new XXPolicyExportAudit();
policyExportAudit.setRepositoryName(serviceName);
policyExportAudit.setAgentId(pluginId);
policyExportAudit.setClientIP(ipAddress);
policyExportAudit.setRequestedEpoch(lastKnownVersion);
policyExportAudit.setHttpRetCode(httpRespCode);
policyExportAudit.setClusterName(clusterName);
policyExportAudit.setZoneName(zoneName);
assetMgr.createPolicyAudit(policyExportAudit);
} catch(Exception excp) {
LOG.error("error while creating policy download audit", excp);
}
}
private RangerPolicy getExactMatchPolicyForResource(String serviceName, RangerAccessResource resource, String zoneName, String user) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getExactMatchPolicyForResource(" + resource + ", " + zoneName + ", " + user + ")");
}
RangerPolicy ret = null;
RangerPolicyAdmin policyAdmin = getPolicyAdmin(serviceName);
List<RangerPolicy> policies = policyAdmin != null ? policyAdmin.getExactMatchPolicies(resource, zoneName, null) : null;
if(CollectionUtils.isNotEmpty(policies)) {
// at this point, ret is a policy in policy-engine; the caller might update the policy (for grant/revoke); so get a copy from the store
ret = svcStore.getPolicy(policies.get(0).getId());
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getExactMatchPolicyForResource(" + resource + ", " + zoneName + ", " + user + "): " + ret);
}
return ret;
}
private RangerPolicy getExactMatchPolicyForResource(RangerPolicy policy, String user) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getExactMatchPolicyForResource(" + policy + ", " + user + ")");
}
RangerPolicy ret = null;
RangerPolicyAdmin policyAdmin = getPolicyAdmin(policy.getService());
List<RangerPolicy> policies = policyAdmin != null ? policyAdmin.getExactMatchPolicies(policy, null) : null;
if(CollectionUtils.isNotEmpty(policies)) {
// at this point, ret is a policy in policy-engine; the caller might update the policy (for grant/revoke); so get a copy from the store
if(policies.size()==1) {
ret = svcStore.getPolicy(policies.get(0).getId());
} else {
if (StringUtils.isNotEmpty(policy.getZoneName())) {
for(RangerPolicy existingPolicy:policies) {
if (StringUtils.equals(policy.getZoneName(), existingPolicy.getZoneName())) {
ret = svcStore.getPolicy(existingPolicy.getId());
break;
}
}
}
}
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getExactMatchPolicyForResource(" + policy + ", " + user + "): " + ret);
}
return ret;
}
@GET
@Path("/policies/eventTime")
@Produces({ "application/json", "application/xml" })
@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.GET_POLICY_FROM_EVENT_TIME + "\")")
public RangerPolicy getPolicyFromEventTime(@Context HttpServletRequest request) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getPolicyFromEventTime()");
}
String eventTimeStr = request.getParameter("eventTime");
String policyIdStr = request.getParameter("policyId");
String versionNoStr = request.getParameter("versionNo");
if (StringUtils.isEmpty(eventTimeStr) || StringUtils.isEmpty(policyIdStr)) {
throw restErrorUtil.createRESTException("EventTime or policyId cannot be null or empty string.",
MessageEnums.INVALID_INPUT_DATA);
}
Long policyId = Long.parseLong(policyIdStr);
RangerPolicy policy=null;
if (!StringUtil.isEmpty(versionNoStr)) {
int policyVersion = Integer.parseInt(versionNoStr);
try {
policy = svcStore.getPolicyForVersionNumber(policyId, policyVersion);
if (policy != null) {
ensureAdminAndAuditAccess(policy);
}
} catch (WebApplicationException excp) {
throw excp;
} catch (Throwable excp) {
// Ignore any other exception and go for fetching the policy by eventTime
}
}
if (policy == null) {
try {
policy = svcStore.getPolicyFromEventTime(eventTimeStr, policyId);
if (policy != null) {
ensureAdminAndAuditAccess(policy);
}
} catch (WebApplicationException excp) {
throw excp;
} catch (Throwable excp) {
LOG.error("getPolicy(" + policyId + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
}
}
if(policy == null) {
throw restErrorUtil.createRESTException(HttpServletResponse.SC_NOT_FOUND, "Not found", true);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getPolicy(" + policyId + "): " + policy);
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getPolicyFromEventTime()");
}
return policy;
}
@GET
@Path("/policy/{policyId}/versionList")
@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.GET_POLICY_VERSION_LIST + "\")")
public VXString getPolicyVersionList(@PathParam("policyId") Long policyId) {
VXString policyVersionListStr = svcStore.getPolicyVersionList(policyId);
return policyVersionListStr;
}
@GET
@Path("/policy/{policyId}/version/{versionNo}")
@Produces({ "application/json", "application/xml" })
@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.GET_POLICY_FOR_VERSION_NO + "\")")
public RangerPolicy getPolicyForVersionNumber(@PathParam("policyId") Long policyId,
@PathParam("versionNo") int versionNo) {
return svcStore.getPolicyForVersionNumber(policyId, versionNo);
}
@GET
@Path("/plugins/info")
@Produces({ "application/json", "application/xml" })
@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.GET_PLUGINS_INFO + "\")")
public RangerPluginInfoList getPluginsInfo(@Context HttpServletRequest request) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getPluginsInfo()");
}
RangerPluginInfoList ret = null;
SearchFilter filter = searchUtil.getSearchFilter(request, pluginInfoService.getSortFields());
try {
PList<RangerPluginInfo> paginatedPluginsInfo = pluginInfoService.searchRangerPluginInfo(filter);
if (paginatedPluginsInfo != null) {
ret = new RangerPluginInfoList();
ret.setPluginInfoList(paginatedPluginsInfo.getList());
ret.setPageSize(paginatedPluginsInfo.getPageSize());
ret.setResultSize(paginatedPluginsInfo.getResultSize());
ret.setStartIndex(paginatedPluginsInfo.getStartIndex());
ret.setTotalCount(paginatedPluginsInfo.getTotalCount());
ret.setSortBy(paginatedPluginsInfo.getSortBy());
ret.setSortType(paginatedPluginsInfo.getSortType());
}
} catch (WebApplicationException excp) {
throw excp;
} catch (Throwable excp) {
LOG.error("getPluginsInfo() failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getPluginsInfo()");
}
return ret;
}
private List<RangerPolicy> applyAdminAccessFilter(List<RangerPolicy> policies) {
List<RangerPolicy> ret = new ArrayList<RangerPolicy>();
RangerPerfTracer perf = null;
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.applyAdminAccessFilter(policyCount=" + (policies == null ? 0 : policies.size()) + ")");
}
if (CollectionUtils.isNotEmpty(policies)) {
boolean isAdmin = bizUtil.isAdmin();
boolean isKeyAdmin = bizUtil.isKeyAdmin();
String userName = bizUtil.getCurrentUserLoginId();
boolean isAuditAdmin = bizUtil.isAuditAdmin();
boolean isAuditKeyAdmin = bizUtil.isAuditKeyAdmin();
Set<String> userGroups = null;
Map<String, List<RangerPolicy>> servicePoliciesMap = new HashMap<String, List<RangerPolicy>>();
Map<String, Object> evalContext = new HashMap<>();
RangerAccessRequestUtil.setCurrentUserInContext(evalContext, userName);
for (int i = 0; i < policies.size(); i++) {
RangerPolicy policy = policies.get(i);
String serviceName = policy.getService();
List<RangerPolicy> policyList = servicePoliciesMap.get(serviceName);
if (policyList == null) {
policyList = new ArrayList<RangerPolicy>();
servicePoliciesMap.put(serviceName, policyList);
}
policyList.add(policy);
}
for (Map.Entry<String, List<RangerPolicy>> entry : servicePoliciesMap.entrySet()) {
String serviceName = entry.getKey();
List<RangerPolicy> listToFilter = entry.getValue();
if (CollectionUtils.isNotEmpty(listToFilter)) {
boolean isServiceAdminUser = svcStore.isServiceAdminUser(serviceName, userName);
if (isServiceAdminUser) {
ret.addAll(listToFilter);
} else if (isAdmin || isKeyAdmin || isAuditAdmin || isAuditKeyAdmin) {
XXService xService = daoManager.getXXService().findByName(serviceName);
Long serviceDefId = xService.getType();
boolean isKmsService = serviceDefId.equals(EmbeddedServiceDefsUtil.instance().getKmsServiceDefId());
if (isAdmin) {
if (!isKmsService) {
ret.addAll(listToFilter);
}
} else if (isAuditAdmin) {
if (!isKmsService) {
ret.addAll(listToFilter);
}
} else if (isAuditKeyAdmin) {
if (isKmsService) {
ret.addAll(listToFilter);
}
} else if (isKeyAdmin) {
if (isKmsService) {
ret.addAll(listToFilter);
}
}
continue;
}
RangerPolicyAdmin policyAdmin = getPolicyAdminForDelegatedAdmin(serviceName);
if (policyAdmin != null) {
if(userGroups == null) {
userGroups = daoManager.getXXGroupUser().findGroupNamesByUserName(userName);
}
Set<String> roles = policyAdmin.getRolesFromUserAndGroups(userName, userGroups);
for (RangerPolicy policy : listToFilter) {
if ((policyAdmin.isDelegatedAdminAccessAllowed(policy, userName, userGroups, roles, evalContext))
|| (!StringUtils.isEmpty(policy.getZoneName()) && (serviceMgr.isZoneAdmin(policy.getZoneName()) || serviceMgr.isZoneAuditor(policy.getZoneName())))) {
ret.add(policy);
}
}
}
}
}
}
RangerPerfTracer.log(perf);
return ret;
}
void ensureAdminAccess(RangerPolicy policy) {
boolean isAdmin = bizUtil.isAdmin();
boolean isKeyAdmin = bizUtil.isKeyAdmin();
String userName = bizUtil.getCurrentUserLoginId();
boolean isSvcAdmin = isAdmin || svcStore.isServiceAdminUser(policy.getService(), userName);
if (!isAdmin && !isKeyAdmin && !isSvcAdmin) {
boolean isAllowed = false;
Set<String> userGroups = userMgr.getGroupsForUser(userName);
//for zone policy create /update / delete
if(!StringUtils.isEmpty(policy.getZoneName()) && serviceMgr.isZoneAdmin(policy.getZoneName())){
isAllowed = true;
}else{
isAllowed = hasAdminAccess(policy, userName, userGroups);
}
if (!isAllowed) {
throw restErrorUtil.createRESTException(HttpServletResponse.SC_UNAUTHORIZED,
"User '" + userName + "' does not have delegated-admin privilege on given resources", true);
}
} else {
XXService xService = daoManager.getXXService().findByName(policy.getService());
XXServiceDef xServiceDef = daoManager.getXXServiceDef().getById(xService.getType());
if (isAdmin) {
if (EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME.equals(xServiceDef.getImplclassname())) {
throw restErrorUtil.createRESTException(
"KMS Policies/Services/Service-Defs are not accessible for user '" + userName + "'.",
MessageEnums.OPER_NO_PERMISSION);
}
} else if (isKeyAdmin) {
if (!EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME.equals(xServiceDef.getImplclassname())) {
throw restErrorUtil.createRESTException(
"Only KMS Policies/Services/Service-Defs are accessible for user '" + userName + "'.",
MessageEnums.OPER_NO_PERMISSION);
}
}
}
}
private RangerPolicyEngineOptions getDelegatedAdminPolicyEngineOptions() {
RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();
final String propertyPrefix = "ranger.admin";
opts.configureDelegateAdmin(config, propertyPrefix);
return opts;
}
private RangerPolicyEngineOptions getPolicySearchRangerAdminPolicyEngineOptions() {
RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();
final String propertyPrefix = "ranger.admin";
opts.configureRangerAdminForPolicySearch(config, propertyPrefix);
return opts;
}
private RangerPolicyEngineOptions getDefaultRangerAdminPolicyEngineOptions() {
RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();
final String propertyPrefix = "ranger.admin";
opts.configureDefaultRangerAdmin(config, propertyPrefix);
return opts;
}
private boolean hasAdminAccess(RangerPolicy policy, String userName, Set<String> userGroups) {
boolean isAllowed = false;
RangerPolicyAdmin policyAdmin = getPolicyAdminForDelegatedAdmin(policy.getService());
if(policyAdmin != null) {
Map evalContext = new HashMap<>();
RangerAccessRequestUtil.setCurrentUserInContext(evalContext, userName);
Set<String> roles = policyAdmin.getRolesFromUserAndGroups(userName, userGroups);
isAllowed = policyAdmin.isDelegatedAdminAccessAllowed(policy, userName, userGroups, roles, evalContext);
}
return isAllowed;
}
private boolean hasAdminAccess(String serviceName, String zoneName, String userName, Set<String> userGroups, RangerAccessResource resource, Set<String> accessTypes) {
boolean isAllowed = false;
RangerPolicyAdmin policyAdmin = getPolicyAdminForDelegatedAdmin(serviceName);
if(policyAdmin != null) {
isAllowed = CollectionUtils.isNotEmpty(accessTypes) && policyAdmin.isDelegatedAdminAccessAllowed(resource, zoneName, userName, userGroups, accessTypes);
}
return isAllowed;
}
public RangerPolicyAdmin getPolicyAdminForDelegatedAdmin(String serviceName) {
return RangerPolicyAdminCacheForEngineOptions.getInstance().getServicePoliciesAdmin(serviceName, svcStore, zoneStore, roleDBStore, delegateAdminOptions);
}
private RangerPolicyAdmin getPolicyAdminForSearch(String serviceName) {
return RangerPolicyAdminCacheForEngineOptions.getInstance().getServicePoliciesAdmin(serviceName, svcStore, zoneStore, roleDBStore, policySearchAdminOptions);
}
private RangerPolicyAdmin getPolicyAdmin(String serviceName) {
return RangerPolicyAdminCacheForEngineOptions.getInstance().getServicePoliciesAdmin(serviceName, svcStore, zoneStore,roleDBStore, defaultAdminOptions);
}
@GET
@Path("/checksso")
@Produces(MediaType.TEXT_PLAIN)
public String checkSSO() {
return String.valueOf(bizUtil.isSSOEnabled());
}
@GET
@Path("/csrfconf")
@Produces({ "application/json"})
public HashMap<String, Object> getCSRFProperties() {
return getCSRFPropertiesMap();
}
@GET
@Path("/metrics/type/{type}")
@Produces({ "application/json", "application/xml" })
@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\""+ RangerAPIList.GET_METRICS_BY_TYPE + "\")")
public String getMetricByType(@PathParam("type") String type) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getMetricByType(serviceDefName=" + type + ")");
}
// as of now we are allowing only users with Admin role to access this
// API
bizUtil.checkSystemAdminAccess();
bizUtil.blockAuditorRoleUser();
String ret = null;
try {
ret = svcStore.getMetricByType(type);
} catch (WebApplicationException excp) {
throw excp;
} catch (Throwable excp) {
LOG.error("getMetricByType(" + type + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
}
if (ret == null) {
throw restErrorUtil.createRESTException(HttpServletResponse.SC_NOT_FOUND, "Not found", true);
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getMetricByType(" + type + "): " + ret);
}
return ret;
}
/**
* Delete services/ repos associated with cluster.
* Only users with Ranger UserAdmin OR KeyAdmin are allowed to access this API.
* @param clusterName
* @return List of {@link ServiceDeleteResponse serviceDeleteResponse}.
*/
@DELETE
@Path("/cluster-services/{clusterName}")
@Produces({ "application/json", "application/xml" })
@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.DELETE_CLUSTER_SERVICES + "\")")
public ResponseEntity<List<ServiceDeleteResponse>> deleteClusterServices(@PathParam("clusterName") String clusterName) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.deleteClusterServices("+ clusterName +")");
}
List<ServiceDeleteResponse> deletedServices = new ArrayList<>();
HttpStatus responseStatus = HttpStatus.OK;
try {
//check if user has ADMIN privileges
bizUtil.hasAdminPermissions("Services");
//get all service/ repo IDs to delete
List<Long> serviceIdsToBeDeleted = daoManager.getXXServiceConfigMap().findServiceIdsByClusterName(clusterName);
if (serviceIdsToBeDeleted.isEmpty()) {
responseStatus = HttpStatus.NOT_FOUND;
} else {
//delete each service/ repo one by one
for (Long serviceId : serviceIdsToBeDeleted) {
ServiceDeleteResponse deleteResponse = new ServiceDeleteResponse(serviceId);
try {
String serviceName = this.deleteServiceById(serviceId);
deleteResponse.setServiceName(serviceName);
deleteResponse.setIsDeleted(Boolean.TRUE);
} catch (Throwable e) {
//log and proceed
LOG.warn("Skipping deletion of service with ID="+serviceId);
e.printStackTrace();
deleteResponse.setIsDeleted(Boolean.FALSE);
deleteResponse.setErrorMsg(e.getMessage());
}
deletedServices.add(deleteResponse);
}
}
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("Deleting services associated with cluster=" + clusterName + " failed.", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.deleteClusterServices() - deletedServices: " +deletedServices);
}
return new ResponseEntity<>(deletedServices, responseStatus);
}
private HashMap<String, Object> getCSRFPropertiesMap() {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put(isCSRF_ENABLED, PropertiesUtil.getBooleanProperty(isCSRF_ENABLED, true));
map.put(CUSTOM_HEADER_PARAM, PropertiesUtil.getProperty(CUSTOM_HEADER_PARAM, RangerCSRFPreventionFilter.HEADER_DEFAULT));
map.put(BROWSER_USER_AGENT_PARAM, PropertiesUtil.getProperty(BROWSER_USER_AGENT_PARAM, RangerCSRFPreventionFilter.BROWSER_USER_AGENTS_DEFAULT));
map.put(CUSTOM_METHODS_TO_IGNORE_PARAM, PropertiesUtil.getProperty(CUSTOM_METHODS_TO_IGNORE_PARAM, RangerCSRFPreventionFilter.METHODS_TO_IGNORE_DEFAULT));
return map;
}
private RangerPolicyList toRangerPolicyList(List<RangerPolicy> policyList, SearchFilter filter) {
RangerPolicyList ret = new RangerPolicyList();
if(CollectionUtils.isNotEmpty(policyList)) {
int totalCount = policyList.size();
int startIndex = filter.getStartIndex();
int pageSize = filter.getMaxRows();
int toIndex = Math.min(startIndex + pageSize, totalCount);
String sortType = filter.getSortType();
String sortBy = filter.getSortBy();
List<RangerPolicy> retList = new ArrayList<RangerPolicy>();
for(int i = startIndex; i < toIndex; i++) {
retList.add(policyList.get(i));
}
ret.setPolicies(retList);
ret.setPageSize(pageSize);
ret.setResultSize(retList.size());
ret.setStartIndex(startIndex);
ret.setTotalCount(totalCount);
ret.setSortBy(sortBy);
ret.setSortType(sortType);
}
return ret;
}
private ServicePolicies filterServicePolicies(ServicePolicies servicePolicies) {
ServicePolicies ret = null;
boolean containsDisabledResourcePolicies = false;
boolean containsDisabledTagPolicies = false;
if (servicePolicies != null) {
List<RangerPolicy> policies = null;
policies = servicePolicies.getPolicies();
if (CollectionUtils.isNotEmpty(policies)) {
for (RangerPolicy policy : policies) {
if (!policy.getIsEnabled()) {
containsDisabledResourcePolicies = true;
break;
}
}
}
if (servicePolicies.getTagPolicies() != null) {
policies = servicePolicies.getTagPolicies().getPolicies();
if (CollectionUtils.isNotEmpty(policies)) {
for (RangerPolicy policy : policies) {
if (!policy.getIsEnabled()) {
containsDisabledTagPolicies = true;
break;
}
}
}
}
if (!containsDisabledResourcePolicies && !containsDisabledTagPolicies) {
ret = servicePolicies;
} else {
ret = new ServicePolicies();
ret.setServiceDef(servicePolicies.getServiceDef());
ret.setServiceId(servicePolicies.getServiceId());
ret.setServiceName(servicePolicies.getServiceName());
ret.setPolicyVersion(servicePolicies.getPolicyVersion());
ret.setPolicyUpdateTime(servicePolicies.getPolicyUpdateTime());
ret.setPolicies(servicePolicies.getPolicies());
ret.setTagPolicies(servicePolicies.getTagPolicies());
ret.setSecurityZones(servicePolicies.getSecurityZones());
if (containsDisabledResourcePolicies) {
List<RangerPolicy> filteredPolicies = new ArrayList<RangerPolicy>();
for (RangerPolicy policy : servicePolicies.getPolicies()) {
if (policy.getIsEnabled()) {
filteredPolicies.add(policy);
}
}
ret.setPolicies(filteredPolicies);
}
if (containsDisabledTagPolicies) {
ServicePolicies.TagPolicies tagPolicies = new ServicePolicies.TagPolicies();
tagPolicies.setServiceDef(servicePolicies.getTagPolicies().getServiceDef());
tagPolicies.setServiceId(servicePolicies.getTagPolicies().getServiceId());
tagPolicies.setServiceName(servicePolicies.getTagPolicies().getServiceName());
tagPolicies.setPolicyVersion(servicePolicies.getTagPolicies().getPolicyVersion());
tagPolicies.setPolicyUpdateTime(servicePolicies.getTagPolicies().getPolicyUpdateTime());
List<RangerPolicy> filteredPolicies = new ArrayList<RangerPolicy>();
for (RangerPolicy policy : servicePolicies.getTagPolicies().getPolicies()) {
if (policy.getIsEnabled()) {
filteredPolicies.add(policy);
}
}
tagPolicies.setPolicies(filteredPolicies);
ret.setTagPolicies(tagPolicies);
}
}
}
return ret;
}
private void validateGrantRevokeRequest(GrantRevokeRequest request, final boolean hasAdminPrivilege, final String loggedInUser) {
if (request != null) {
validateUsersGroupsAndRoles(request.getUsers(),request.getGroups(), request.getRoles());
validateGrantor(request.getGrantor());
validateGrantees(request.getUsers());
validateGroups(request.getGroups());
validateRoles(request.getRoles());
if (!hasAdminPrivilege) {
if (!StringUtils.equals(request.getGrantor(), loggedInUser) || StringUtils.isNotBlank(request.getOwnerUser())) {
throw restErrorUtil.createGrantRevokeRESTException("Invalid grant/revoke request - contains grantor or userOwner specification");
}
request.setGrantorGroups(userMgr.getGroupsForUser(request.getGrantor()));
}
}
}
private void validateUsersGroupsAndRoles(Set<String> users, Set<String> groups, Set<String> roles){
if(CollectionUtils.isEmpty(users) && CollectionUtils.isEmpty(groups) && CollectionUtils.isEmpty(roles)) {
throw restErrorUtil.createGrantRevokeRESTException("Grantee users/groups/roles list is empty");
}
}
private void validateGrantor(String grantor) {
VXUser vxUser = null;
if (grantor != null) {
try {
vxUser = userMgr.getXUserByUserName(grantor);
if (vxUser == null) {
throw restErrorUtil.createGrantRevokeRESTException("Grantor user " + grantor + " doesn't exist");
}
} catch (Exception e) {
throw restErrorUtil.createGrantRevokeRESTException("Grantor user " + grantor + " doesn't exist");
}
}
}
private void validateGrantees(Set<String> grantees) {
VXUser vxUser = null;
for (String userName : grantees) {
try {
vxUser = userMgr.getXUserByUserName(userName);
if (vxUser == null) {
throw restErrorUtil.createGrantRevokeRESTException("Grantee user " + userName + " doesn't exist");
}
} catch (Exception e) {
throw restErrorUtil.createGrantRevokeRESTException("Grantee user " + userName + " doesn't exist");
}
}
}
private void validateGroups(Set<String> groups) {
VXGroup vxGroup = null;
for (String groupName : groups) {
try {
vxGroup = userMgr.getGroupByGroupName(groupName);
if (vxGroup == null) {
throw restErrorUtil.createGrantRevokeRESTException( "Grantee group "+ groupName +" doesn't exist");
}
} catch (Exception e) {
throw restErrorUtil.createGrantRevokeRESTException( "Grantee group "+ groupName +" doesn't exist");
}
}
}
private void validateRoles(Set<String> roles) {
XXRole xxRole = null;
for (String role : roles) {
try {
xxRole = daoManager.getXXRole().findByRoleName(role);
if (xxRole == null) {
throw restErrorUtil.createGrantRevokeRESTException( "Grantee role "+ role +" doesn't exist");
}
} catch (Exception e) {
throw restErrorUtil.createGrantRevokeRESTException( "Grantee role "+ role +" doesn't exist");
}
}
}
private Map<String, Object> getOptions(HttpServletRequest request) {
Map<String, Object> ret = null;
if (request != null) {
String isForceRenameOption = request.getParameter(ServiceStore.OPTION_FORCE_RENAME);
if (StringUtils.isNotBlank(isForceRenameOption)) {
ret = new HashMap<String, Object>();
ret.put(ServiceStore.OPTION_FORCE_RENAME, Boolean.valueOf(isForceRenameOption));
}
}
return ret;
}
private RangerService hideCriticalServiceDetailsForRoleUser(RangerService rangerService){
RangerService ret = rangerService;
ret.setConfigs(null);
ret.setDescription(null);
ret.setCreatedBy(null);
ret.setUpdatedBy(null);
ret.setCreateTime(null);
ret.setUpdateTime(null);
ret.setPolicyVersion(null);
ret.setPolicyUpdateTime(null);
ret.setTagVersion(null);
ret.setTagUpdateTime(null);
ret.setVersion(null);
return ret;
}
void ensureAdminAndAuditAccess(RangerPolicy policy) {
boolean isAdmin = bizUtil.isAdmin();
boolean isKeyAdmin = bizUtil.isKeyAdmin();
String userName = bizUtil.getCurrentUserLoginId();
boolean isAuditAdmin = bizUtil.isAuditAdmin();
boolean isAuditKeyAdmin = bizUtil.isAuditKeyAdmin();
boolean isSvcAdmin = isAdmin || svcStore.isServiceAdminUser(policy.getService(), userName) || (!StringUtils.isEmpty(policy.getZoneName()) && (serviceMgr.isZoneAdmin(policy.getZoneName()) || serviceMgr.isZoneAuditor(policy.getZoneName())));
if (!isAdmin && !isKeyAdmin && !isSvcAdmin && !isAuditAdmin && !isAuditKeyAdmin) {
boolean isAllowed = false;
Set<String> userGroups = userMgr.getGroupsForUser(userName);
isAllowed = hasAdminAccess(policy, userName, userGroups);
if (!isAllowed) {
throw restErrorUtil.createRESTException(HttpServletResponse.SC_UNAUTHORIZED, "User '"
+ userName + "' does not have delegated-admin privilege on given resources", true);
}
} else {
XXService xService = daoManager.getXXService().findByName(policy.getService());
XXServiceDef xServiceDef = daoManager.getXXServiceDef().getById(xService.getType());
if (isAdmin || isAuditAdmin) {
if (EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME.equals(xServiceDef.getImplclassname())) {
throw restErrorUtil.createRESTException(
"KMS Policies/Services/Service-Defs are not accessible for user '"
+ userName + "'.", MessageEnums.OPER_NO_PERMISSION);
}
} else if (isKeyAdmin || isAuditKeyAdmin) {
if (!EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME.equals(xServiceDef.getImplclassname())) {
throw restErrorUtil.createRESTException("Only KMS Policies/Services/Service-Defs are accessible for user '"
+ userName + "'.", MessageEnums.OPER_NO_PERMISSION);
}
}
}
}
private void patchAssociatedTagServiceInSecurityZoneInfos(ServicePolicies servicePolicies) {
if (servicePolicies != null && MapUtils.isNotEmpty(servicePolicies.getSecurityZones())) {
// Get list of zones that associated tag-service (if any) is associated with
List<String> zonesInAssociatedTagService = new ArrayList<>();
String tagServiceName = servicePolicies.getTagPolicies() != null ? servicePolicies.getTagPolicies().getServiceName() : null;
if (StringUtils.isNotEmpty(tagServiceName)) {
try {
RangerService tagService = svcStore.getServiceByName(tagServiceName);
if (tagService != null && tagService.getIsEnabled()) {
zonesInAssociatedTagService = daoManager.getXXSecurityZoneDao().findZonesByTagServiceName(tagServiceName);
}
} catch (Exception exception) {
LOG.warn("Could not get service associated with [" + tagServiceName + "]", exception);
}
}
if (CollectionUtils.isNotEmpty(zonesInAssociatedTagService)) {
for (Map.Entry<String, ServicePolicies.SecurityZoneInfo> entry : servicePolicies.getSecurityZones().entrySet()) {
String zoneName = entry.getKey();
ServicePolicies.SecurityZoneInfo securityZoneInfo = entry.getValue();
securityZoneInfo.setContainsAssociatedTagService(zonesInAssociatedTagService.contains(zoneName));
}
}
}
}
private void scheduleCreateOrGetTagService(RangerService resourceService) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> scheduleCreateOrGetTagService(resourceService=" + resourceService.getName() + ")");
}
final boolean isAutoCreateTagService = config.getBoolean("ranger.tagservice.auto.create", true);
if (isAutoCreateTagService) {
String tagServiceName = config.get("ranger.tagservice.auto.name");
if (StringUtils.isBlank(tagServiceName)) {
tagServiceName = getGeneratedTagServiceName(resourceService.getName());
}
if (StringUtils.isNotBlank(tagServiceName)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Attempting to get/create and possibly link to tag-service:[" + tagServiceName + "]");
}
final boolean isAutoLinkTagService = config.getBoolean("ranger.tagservice.auto.link", true);
RangerService tagService = null;
try {
tagService = svcStore.getServiceByName(tagServiceName);
} catch (Exception e) {
LOG.info("failed to retrieve tag-service [" + tagServiceName + "]. Will attempt to create.", e);
}
if (tagService == null) {
final TagServiceOperationContext context = new TagServiceOperationContext(tagServiceName, resourceService.getName(), isAutoLinkTagService);
Runnable createAndLinkTagServiceTask = new Runnable() {
@Override
public void run() {
Runnable realTask = new Runnable() {
@Override
public void run() {
doCreateAndLinkTagService(context);
}
};
transactionService.scheduleToExecuteInOwnTransaction(realTask, 0L);
}
};
rangerTransactionSynchronizationAdapter.executeOnTransactionCommit(createAndLinkTagServiceTask);
} else if (isAutoLinkTagService) {
resourceService.setTagService(tagServiceName);
}
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== scheduleCreateOrGetTagService(resourceService=" + resourceService.getName() + ")");
}
}
private String getGeneratedTagServiceName(String resourceServiceName) {
int lastIndexOfMarker = StringUtils.lastIndexOf(resourceServiceName, '_');
if (lastIndexOfMarker != -1) {
return resourceServiceName.substring(0, lastIndexOfMarker) + "_tag";
} else {
return null;
}
}
private final class TagServiceOperationContext {
final String tagServiceName;
final String resourceServiceName;
final boolean isAutoLinkTagService;
TagServiceOperationContext(@Nonnull String tagserviceName, @Nonnull String resourceServiceName, boolean isAutoLinkTagService) {
this.tagServiceName = tagserviceName;
this.resourceServiceName = resourceServiceName;
this.isAutoLinkTagService = isAutoLinkTagService;
}
@Override
public String toString() {
return "{tagServiceName=" + tagServiceName + ", resourceServiceName=" + resourceServiceName + ", isAutoLinkTagService=" + isAutoLinkTagService + "}";
}
}
private void doCreateAndLinkTagService(final TagServiceOperationContext context) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> doCreateAndLinkTagService(context=" + context + ")");
}
RangerService resourceService = null;
try {
resourceService = svcStore.getServiceByName(context.resourceServiceName);
LOG.info("Successfully retrieved resource-service:[" + resourceService.getName() + "]");
} catch (Exception e) {
LOG.error("Resource-service:[" + context.resourceServiceName + "] cannot be retrieved");
}
if (resourceService != null) {
RangerService tagService = new RangerService();
tagService.setName(context.tagServiceName);
tagService.setDisplayName(context.tagServiceName);//set DEFAULT display name
tagService.setType(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_TAG_NAME);
LOG.info("creating tag-service [" + context.tagServiceName + "]");
RangerService service;
try {
service = svcStore.createService(tagService);
LOG.info("Created tag-service:[" + service.getName() + "]");
} catch (Exception e) {
LOG.info("Failed to create tag-service " + context.tagServiceName, e);
}
if (context.isAutoLinkTagService) {
Runnable linkTagServiceTask = new Runnable() {
@Override
public void run() {
Runnable realTask = new Runnable() {
@Override
public void run() {
doLinkTagService(context);
}
};
transactionService.scheduleToExecuteInOwnTransaction(realTask, 0L);
}
};
rangerTransactionSynchronizationAdapter.executeOnTransactionCompletion(linkTagServiceTask);
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== doCreateAndLinkTagService(context=" + context + ")");
}
}
private void doLinkTagService(final TagServiceOperationContext context) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> doLinkTagService(context=" + context + ")");
}
try {
RangerService resourceService = svcStore.getServiceByName(context.resourceServiceName);
LOG.info("Successfully retrieved resource-service:[" + resourceService.getName() + "]");
RangerService tagService = svcStore.getServiceByName(context.tagServiceName);
LOG.info("Successfully retrieved tag-service:[" + tagService.getName() + "]");
if (!StringUtils.equals(tagService.getName(), resourceService.getTagService())) {
resourceService.setTagService(tagService.getName());
LOG.info("Linking resource-service[" + resourceService.getName() + "] with tag-service [" + tagService.getName() + "]");
RangerService service = svcStore.updateService(resourceService, null);
LOG.info("Updated resource-service:[" + service.getName() + "]");
}
} catch (Exception e) {
LOG.error("Failed to link service[" + context.resourceServiceName + "] with tag-service [" + context.tagServiceName + "]");
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== doLinkTagService(context=" + context + ")");
}
}
private void deleteExactMatchPolicyForResource(List<RangerPolicy> policies, String user, String zoneName) throws Exception {
if (CollectionUtils.isNotEmpty(policies)) {
long totalDeletedPolicies = 0;
for (RangerPolicy rangerPolicy : policies) {
RangerPolicy existingPolicy = null ;
try {
if(zoneName!=null) {
rangerPolicy.setZoneName(zoneName);
}
existingPolicy = getExactMatchPolicyForResource(rangerPolicy, StringUtils.isNotBlank(user) ? user :"admin");
} catch (Exception e) {
existingPolicy=null;
}
if (existingPolicy != null) {
svcStore.deletePolicy(existingPolicy, null);
totalDeletedPolicies = totalDeletedPolicies + 1;
if (totalDeletedPolicies % RangerBizUtil.policyBatchSize == 0) {
bizUtil.bulkModeOnlyFlushAndClear();
}
if (LOG.isDebugEnabled()) {
LOG.debug("Policy " + rangerPolicy.getName() + " deleted successfully.");
}
}
}
bizUtil.bulkModeOnlyFlushAndClear();
}
}
private String getRangerAdminZoneName(String serviceName, GrantRevokeRequest grantRevokeRequest) {
String ret = grantRevokeRequest.getZoneName();
if (StringUtils.isEmpty(ret)) {
RangerPolicyAdmin policyAdmin = getPolicyAdmin(serviceName);
ret = policyAdmin.getUniquelyMatchedZoneName(grantRevokeRequest);
}
return ret;
}
private RangerPolicy getPolicyByName(String serviceName,String policyName) {
RangerPolicy ret = null;
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getPolicyByName(" + serviceName + "," + policyName + ")");
}
SearchFilter filter = new SearchFilter();
filter.setParam(SearchFilter.SERVICE_NAME, serviceName);
filter.setParam(SearchFilter.POLICY_NAME, policyName);
List<RangerPolicy> policies = getPolicies(filter);
if (CollectionUtils.isNotEmpty(policies)) {
ret = policies.get(0);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getPolicyByName(" + serviceName + "," + policyName + ")" + ret);
}
return ret;
}
private RangerPolicy getPolicyByNameAndZone(String serviceName, String policyName, String zoneName) {
RangerPolicy ret = null;
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getPolicyByNameAndZone(" + serviceName + "," + policyName + "," + zoneName + ")");
}
SearchFilter filter = new SearchFilter();
filter.setParam(SearchFilter.SERVICE_NAME, serviceName);
filter.setParam(SearchFilter.POLICY_NAME, policyName);
filter.setParam(SearchFilter.ZONE_NAME, zoneName);
List<RangerPolicy> policies = getPolicies(filter);
if (CollectionUtils.isNotEmpty(policies) && policies.size()==1) {
ret = policies.get(0);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getPolicyByNameAndZone(" + serviceName + "," + policyName + "," + zoneName + ")");
}
return ret;
}
private RangerPolicy createPolicyUnconditionally(RangerPolicy policy) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.createPolicyUnconditionally( "+ policy +")");
}
RangerPolicy ret = null;
if (StringUtils.isBlank(policy.getName())) {
String guid = policy.getGuid();
if (StringUtils.isBlank(guid)) {
guid = guidUtil.genGUID();
policy.setGuid(guid);
if (LOG.isDebugEnabled()) {
LOG.debug("No GUID supplied on the policy! Ok, setting GUID to [" + guid + "].");
}
}
String name = policy.getService() + "-" + guid;
policy.setName(name);
if (LOG.isDebugEnabled()) {
LOG.debug("Policy did not have its name set! Ok, setting name to [" + name + "]");
}
}
RangerPolicyValidator validator = validatorFactory.getPolicyValidator(svcStore);
validator.validate(policy, Action.CREATE, bizUtil.isAdmin());
ensureAdminAccess(policy);
bizUtil.blockAuditorRoleUser();
ret = svcStore.createPolicy(policy);
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.createPolicyUnconditionally( " + ret + ")");
}
return ret;
}
private RangerPolicy getPolicyMatchByName(RangerPolicy policy, HttpServletRequest request) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.getPolicyMatchByName( " + policy + ")");
}
RangerPolicy existingPolicy = null;
String serviceName = request.getParameter(PARAM_SERVICE_NAME);
if (serviceName == null) {
serviceName = (String) request.getAttribute(PARAM_SERVICE_NAME);
}
if (StringUtils.isNotEmpty(serviceName)) {
policy.setService(serviceName);
}
String policyName = request.getParameter(PARAM_POLICY_NAME);
if (policyName == null) {
policyName = (String) request.getAttribute(PARAM_POLICY_NAME);
}
if (StringUtils.isNotEmpty(policyName)) {
policy.setName(StringUtils.trim(policyName));
}
if (StringUtils.isNotEmpty(serviceName) && StringUtils.isNotEmpty(policyName)) {
String zoneName = request.getParameter(PARAM_ZONE_NAME);
if (StringUtils.isBlank(zoneName)) {
zoneName = (String) request.getAttribute(PARAM_ZONE_NAME);
}
if (StringUtils.isNotBlank(zoneName)) {
policy.setZoneName(StringUtils.trim(zoneName));
}
if (StringUtils.isNotBlank(zoneName)) {
existingPolicy = getPolicyByNameAndZone(policy.getService(), policy.getName(), policy.getZoneName());
} else {
existingPolicy = getPolicyByName(policy.getService(), policy.getName());
}
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.getPolicyMatchByName( " + existingPolicy + ")");
}
return existingPolicy;
}
private String deleteServiceById(Long id) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceREST.deleteServiceById( " + id + ")");
}
RangerAdminOpContext opContext = new RangerAdminOpContext();
opContext.setBulkModeContext(true);
RangerContextHolder.setOpContext(opContext);
RangerPerfTracer perf = null;
String deletedServiceName = null;
try {
if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.deleteService(serviceId=" + id + ")");
}
RangerServiceValidator validator = validatorFactory.getServiceValidator(svcStore);
validator.validate(id, Action.DELETE);
UserSessionBase session = ContextUtil.getCurrentUserSession();
if (session != null) {
XXService service = daoManager.getXXService().getById(id);
if (service != null) {
//if logged-in user is not the service creator then check admin priv.
if (!session.getUserId().equals(service.getAddedByUserId())) {
bizUtil.hasAdminPermissions("Services");
}
EmbeddedServiceDefsUtil embeddedServiceDefsUtil = EmbeddedServiceDefsUtil.instance();
if (service.getType().equals(embeddedServiceDefsUtil.getTagServiceDefId())) {
List<XXService> referringServices = daoManager.getXXService().findByTagServiceId(id);
if (!CollectionUtils.isEmpty(referringServices)) {
Set<String> referringServiceNames = new HashSet<String>();
for (XXService xXService : referringServices) {
referringServiceNames.add(xXService.getName());
if (referringServiceNames.size() >= 10) {
break;
}
}
if (referringServices.size() <= 10) {
throw restErrorUtil.createRESTException("Tag service '" + service.getName() + "' is being referenced by " + referringServices.size() + " services: " + referringServiceNames, MessageEnums.OPER_NOT_ALLOWED_FOR_STATE);
} else {
throw restErrorUtil.createRESTException("Tag service '" + service.getName() + "' is being referenced by " + referringServices.size() + " services: " + referringServiceNames + " and more..", MessageEnums.OPER_NOT_ALLOWED_FOR_STATE);
}
}
}
XXServiceDef xxServiceDef = daoManager.getXXServiceDef().getById(service.getType());
if (!session.getUserId().equals(service.getAddedByUserId())) {
bizUtil.hasKMSPermissions("Service", xxServiceDef.getImplclassname());
bizUtil.blockAuditorRoleUser();
}
tagStore.deleteAllTagObjectsForService(service.getName());
deletedServiceName = service.getName();
svcStore.deleteService(id);
} else {
LOG.error("Cannot retrieve service:[" + id + "] for deletion");
throw new Exception("deleteService(" + id + ") failed");
}
} else {
LOG.error("Cannot retrieve user session.");
throw new Exception("deleteService(" + id + ") failed");
}
} catch(WebApplicationException excp) {
throw excp;
} catch(Throwable excp) {
LOG.error("deleteService(" + id + ") failed", excp);
throw restErrorUtil.createRESTException(excp.getMessage());
} finally {
RangerPerfTracer.log(perf);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== ServiceREST.deleteServiceById() - deletedServiceName="+deletedServiceName);
}
return deletedServiceName;
}
}