diff --git a/agents-audit/src/main/java/org/apache/ranger/audit/provider/MiscUtil.java b/agents-audit/src/main/java/org/apache/ranger/audit/provider/MiscUtil.java index 1e5d1d8d8e..b69e27693c 100644 --- a/agents-audit/src/main/java/org/apache/ranger/audit/provider/MiscUtil.java +++ b/agents-audit/src/main/java/org/apache/ranger/audit/provider/MiscUtil.java @@ -786,45 +786,6 @@ public static void authWithKerberos(String keytab, String principal, } - public static void loginWithKeyTab(String keytab, String principal, String nameRules) { - if (logger.isDebugEnabled()) { - logger.debug("==> MiscUtil.loginWithKeyTab() keytab= " + keytab + "principal= " + principal + "nameRules= " + nameRules); - } - - if (keytab == null || principal == null) { - logger.error("Failed to login as keytab or principal is null!"); - return; - } - - String[] spnegoPrincipals; - UserGroupInformation ugi; - - try { - if (principal.equals("*")) { - spnegoPrincipals = KerberosUtil.getPrincipalNames(keytab, Pattern.compile("HTTP/.*")); - if (spnegoPrincipals.length == 0) { - logger.error("No principals found in keytab= " + keytab); - } - } else { - spnegoPrincipals = new String[] { principal }; - } - - if (nameRules != null) { - KerberosName.setRules(nameRules); - } - - logger.info("Creating UGI from keytab directly. keytab= " + keytab + ", principal= " + spnegoPrincipals[0]); - ugi = UserGroupInformation.loginUserFromKeytabAndReturnUGI(spnegoPrincipals[0], keytab); - MiscUtil.setUGILoginUser(ugi, null); - } catch (Exception e) { - logger.error("Failed to login with given keytab= " + keytab + "principal= " + principal + "nameRules= " + nameRules, e); - } - - if (logger.isDebugEnabled()) { - logger.debug("<== MiscUtil.loginWithKeyTab()"); - } - } - static class LogHistory { long lastLogTime = 0; int counter = 0; diff --git a/agents-common/src/main/java/org/apache/ranger/admin/client/AbstractRangerAdminClient.java b/agents-common/src/main/java/org/apache/ranger/admin/client/AbstractRangerAdminClient.java index a65c187088..1ad5ec01e9 100644 --- a/agents-common/src/main/java/org/apache/ranger/admin/client/AbstractRangerAdminClient.java +++ b/agents-common/src/main/java/org/apache/ranger/admin/client/AbstractRangerAdminClient.java @@ -22,7 +22,6 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.security.UserGroupInformation; import org.apache.ranger.plugin.model.RangerRole; import org.apache.ranger.plugin.util.*; import org.slf4j.Logger; @@ -35,8 +34,6 @@ public abstract class AbstractRangerAdminClient implements RangerAdminClient { protected Gson gson; - private boolean forceNonKerberos = false; - @Override public void init(String serviceName, String appId, String configPropertyPrefix, Configuration config) { Gson gson = null; @@ -48,7 +45,6 @@ public void init(String serviceName, String appId, String configPropertyPrefix, } this.gson = gson; - this.forceNonKerberos = config.getBoolean(configPropertyPrefix + ".forceNonKerberos", false); } @Override @@ -120,16 +116,4 @@ public List getTagTypes(String tagTypePattern) throws Exception { public RangerUserStore getUserStoreIfUpdated(long lastKnownUserStoreVersion, long lastActivationTimeInMillis) throws Exception { return null; } - - public boolean isKerberosEnabled(UserGroupInformation user) { - final boolean ret; - - if (forceNonKerberos) { - ret = false; - } else { - ret = user != null && UserGroupInformation.isSecurityEnabled() && user.hasKerberosCredentials(); - } - - return ret; - } } diff --git a/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java b/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java index 9cd0fd263d..8edb3cbe8d 100644 --- a/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java +++ b/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java @@ -184,7 +184,7 @@ public RangerRole createRole(final RangerRole request) throws Exception { ClientResponse response = null; UserGroupInformation user = MiscUtil.getUGILoginUser(); - boolean isSecureMode = isKerberosEnabled(user); + boolean isSecureMode = user != null && UserGroupInformation.isSecurityEnabled(); String relativeURL = RangerRESTUtils.REST_URL_SERVICE_CREATE_ROLE; Map queryParams = new HashMap (); @@ -239,7 +239,7 @@ public void dropRole(final String execUser, final String roleName) throws Except ClientResponse response = null; UserGroupInformation user = MiscUtil.getUGILoginUser(); - boolean isSecureMode = isKerberosEnabled(user); + boolean isSecureMode = user != null && UserGroupInformation.isSecurityEnabled(); Map queryParams = new HashMap(); queryParams.put(RangerRESTUtils.SERVICE_NAME_PARAM, serviceNameUrlParam); @@ -294,7 +294,7 @@ public List getUserRoles(final String execUser) throws Exception { String emptyString = ""; ClientResponse response = null; UserGroupInformation user = MiscUtil.getUGILoginUser(); - boolean isSecureMode = isKerberosEnabled(user); + boolean isSecureMode = user != null && UserGroupInformation.isSecurityEnabled(); String relativeURL = RangerRESTUtils.REST_URL_SERVICE_GET_USER_ROLES + execUser; if (isSecureMode) { @@ -349,7 +349,7 @@ public List getAllRoles(final String execUser) throws Exception { String emptyString = ""; ClientResponse response = null; UserGroupInformation user = MiscUtil.getUGILoginUser(); - boolean isSecureMode = isKerberosEnabled(user); + boolean isSecureMode = user != null && UserGroupInformation.isSecurityEnabled(); String relativeURL = RangerRESTUtils.REST_URL_SERVICE_GET_ALL_ROLES; Map queryParams = new HashMap(); @@ -407,7 +407,7 @@ public RangerRole getRole(final String execUser, final String roleName) throws E RangerRole ret = null; ClientResponse response = null; UserGroupInformation user = MiscUtil.getUGILoginUser(); - boolean isSecureMode = isKerberosEnabled(user); + boolean isSecureMode = user != null && UserGroupInformation.isSecurityEnabled(); String relativeURL = RangerRESTUtils.REST_URL_SERVICE_GET_ROLE_INFO + roleName; Map queryParams = new HashMap(); @@ -465,7 +465,7 @@ public void grantRole(final GrantRevokeRoleRequest request) throws Exception { ClientResponse response = null; UserGroupInformation user = MiscUtil.getUGILoginUser(); - boolean isSecureMode = isKerberosEnabled(user); + boolean isSecureMode = user != null && UserGroupInformation.isSecurityEnabled(); String relativeURL = RangerRESTUtils.REST_URL_SERVICE_GRANT_ROLE + serviceNameUrlParam; if (isSecureMode) { @@ -513,7 +513,7 @@ public void revokeRole(final GrantRevokeRoleRequest request) throws Exception { ClientResponse response = null; UserGroupInformation user = MiscUtil.getUGILoginUser(); - boolean isSecureMode = isKerberosEnabled(user); + boolean isSecureMode = user != null && UserGroupInformation.isSecurityEnabled(); String relativeURL = RangerRESTUtils.REST_URL_SERVICE_REVOKE_ROLE + serviceNameUrlParam; if (isSecureMode) { @@ -561,7 +561,7 @@ public void grantAccess(final GrantRevokeRequest request) throws Exception { ClientResponse response = null; UserGroupInformation user = MiscUtil.getUGILoginUser(); - boolean isSecureMode = isKerberosEnabled(user); + boolean isSecureMode = user != null && UserGroupInformation.isSecurityEnabled(); Map queryParams = new HashMap(); queryParams.put(RangerRESTUtils.REST_PARAM_PLUGIN_ID, pluginId); @@ -613,7 +613,7 @@ public void revokeAccess(final GrantRevokeRequest request) throws Exception { ClientResponse response = null; UserGroupInformation user = MiscUtil.getUGILoginUser(); - boolean isSecureMode = isKerberosEnabled(user); + boolean isSecureMode = user != null && UserGroupInformation.isSecurityEnabled(); Map queryParams = new HashMap(); queryParams.put(RangerRESTUtils.REST_PARAM_PLUGIN_ID, pluginId); @@ -704,7 +704,7 @@ public List getTagTypes(String pattern) throws Exception { List ret = null; String emptyString = ""; UserGroupInformation user = MiscUtil.getUGILoginUser(); - boolean isSecureMode = isKerberosEnabled(user); + boolean isSecureMode = user != null && UserGroupInformation.isSecurityEnabled(); Map queryParams = new HashMap(); queryParams.put(RangerRESTUtils.SERVICE_NAME_PARAM, serviceNameUrlParam); @@ -755,7 +755,7 @@ public RangerUserStore getUserStoreIfUpdated(long lastKnownUserStoreVersion, lon final RangerUserStore ret; final UserGroupInformation user = MiscUtil.getUGILoginUser(); - final boolean isSecureMode = isKerberosEnabled(user); + final boolean isSecureMode = user != null && UserGroupInformation.isSecurityEnabled(); final ClientResponse response; Map queryParams = new HashMap(); @@ -838,7 +838,7 @@ private ServicePolicies getServicePoliciesIfUpdatedWithCred(final long lastKnown final ServicePolicies ret; final UserGroupInformation user = MiscUtil.getUGILoginUser(); - final boolean isSecureMode = isKerberosEnabled(user); + final boolean isSecureMode = user != null && UserGroupInformation.isSecurityEnabled(); final ClientResponse response = getRangerAdminPolicyDownloadResponse(lastKnownVersion, lastActivationTimeInMillis, user, isSecureMode); if (response == null || response.getStatus() == HttpServletResponse.SC_NOT_MODIFIED || response.getStatus() == HttpServletResponse.SC_NO_CONTENT) { @@ -888,7 +888,7 @@ private ServicePolicies getServicePoliciesIfUpdatedWithCookie(final long lastKno final ServicePolicies ret; final UserGroupInformation user = MiscUtil.getUGILoginUser(); - final boolean isSecureMode = isKerberosEnabled(user); + final boolean isSecureMode = user != null && UserGroupInformation.isSecurityEnabled(); final ClientResponse response = getRangerAdminPolicyDownloadResponse(lastKnownVersion, lastActivationTimeInMillis, user, isSecureMode); if (response == null || response.getStatus() == HttpServletResponse.SC_NOT_MODIFIED || response.getStatus() == HttpServletResponse.SC_NO_CONTENT) { @@ -1016,7 +1016,7 @@ private ServiceTags getServiceTagsIfUpdatedWithCred(final long lastKnownVersion, final ServiceTags ret; final UserGroupInformation user = MiscUtil.getUGILoginUser(); - final boolean isSecureMode = isKerberosEnabled(user); + final boolean isSecureMode = user != null && UserGroupInformation.isSecurityEnabled(); final ClientResponse response = getRangerAdminTagDownloadResponse(lastKnownVersion, lastActivationTimeInMillis, user, isSecureMode); if (response == null || response.getStatus() == HttpServletResponse.SC_NOT_MODIFIED) { @@ -1070,7 +1070,7 @@ private ServiceTags getServiceTagsIfUpdatedWithCookie(final long lastKnownVersio final ServiceTags ret; final UserGroupInformation user = MiscUtil.getUGILoginUser(); - final boolean isSecureMode = isKerberosEnabled(user); + final boolean isSecureMode = user != null && UserGroupInformation.isSecurityEnabled(); final ClientResponse response = getRangerAdminTagDownloadResponse(lastKnownVersion, lastActivationTimeInMillis, user, isSecureMode); if (response == null || response.getStatus() == HttpServletResponse.SC_NOT_MODIFIED) { @@ -1198,7 +1198,7 @@ private RangerRoles getRolesIfUpdatedWithCred(final long lastKnownRoleVersion, f final RangerRoles ret; final UserGroupInformation user = MiscUtil.getUGILoginUser(); - final boolean isSecureMode = isKerberosEnabled(user); + final boolean isSecureMode = user != null && UserGroupInformation.isSecurityEnabled(); final ClientResponse response = getRangerRolesDownloadResponse(lastKnownRoleVersion, lastActivationTimeInMillis, user, isSecureMode); if (response == null || response.getStatus() == HttpServletResponse.SC_NOT_MODIFIED || response.getStatus() == HttpServletResponse.SC_NO_CONTENT) { @@ -1253,7 +1253,7 @@ private RangerRoles getRolesIfUpdatedWithCookie(final long lastKnownRoleVersion, final RangerRoles ret; final UserGroupInformation user = MiscUtil.getUGILoginUser(); - final boolean isSecureMode = isKerberosEnabled(user); + final boolean isSecureMode = user != null && UserGroupInformation.isSecurityEnabled(); final ClientResponse response = getRangerRolesDownloadResponse(lastKnownRoleVersion, lastActivationTimeInMillis, user, isSecureMode); if (response == null || response.getStatus() == HttpServletResponse.SC_NOT_MODIFIED || response.getStatus() == HttpServletResponse.SC_NO_CONTENT) { diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java index 23db18f3a2..3ae0add51a 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java @@ -36,7 +36,6 @@ import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator; import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator.RangerPolicyResourceEvaluator; import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator.PolicyACLSummary; -import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher; import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher.MatchType; import org.apache.ranger.plugin.service.RangerDefaultRequestProcessor; import org.apache.ranger.plugin.util.GrantRevokeRequest; @@ -312,43 +311,39 @@ public RangerResourceACLs getResourceACLs(RangerAccessRequest request, Integer r MatchType matchType = tagMatchTypeMap.get(evaluator.getPolicyId()); boolean isMatched = false; - boolean isConditionalMatch = false; if (matchType == null) { for (RangerPolicyResourceEvaluator resourceEvaluator : evaluator.getResourceEvaluators()) { - RangerPolicyResourceMatcher matcher = resourceEvaluator.getPolicyResourceMatcher(); + matchType = resourceEvaluator.getPolicyResourceMatcher().getMatchType(request.getResource(), request.getContext()); - matchType = matcher.getMatchType(request.getResource(), request.getContext()); - isMatched = isMatch(matchType, request.getResourceMatchingScope()); + if (request.getResourceMatchingScope() == RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS) { + isMatched = matchType != MatchType.NONE; + } else { + isMatched = matchType == MatchType.SELF || matchType == MatchType.SELF_AND_ALL_DESCENDANTS; + } if (isMatched) { - isConditionalMatch = false; - break; - } else if (matcher.getNeedsDynamicEval() && !isConditionalMatch) { - MatchType dynWildCardMatch = resourceEvaluator.getMacrosReplaceWithWildcardMatcher(policyEngine).getMatchType(request.getResource(), request.getContext()); - - isConditionalMatch = isMatch(dynWildCardMatch, request.getResourceMatchingScope()); } } } else { - isMatched = isMatch(matchType, request.getResourceMatchingScope()); + if (request.getResourceMatchingScope() == RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS) { + isMatched = matchType != MatchType.NONE; + } else { + isMatched = matchType == MatchType.SELF || matchType == MatchType.SELF_AND_ALL_DESCENDANTS; + } } - if (!isMatched && !isConditionalMatch) { + if (!isMatched) { continue; } - if (!isConditionalMatch) { - isConditionalMatch = policyIdForTemporalTags.contains(evaluator.getPolicyId()) || evaluator.getValidityScheduleEvaluatorsCount() != 0; - } - if (policyType == RangerPolicy.POLICY_TYPE_ACCESS) { - updateFromPolicyACLs(evaluator, isConditionalMatch, ret); + updateFromPolicyACLs(evaluator, policyIdForTemporalTags, ret); } else if (policyType == RangerPolicy.POLICY_TYPE_ROWFILTER) { - updateRowFiltersFromPolicy(evaluator, isConditionalMatch, ret); + updateRowFiltersFromPolicy(evaluator, policyIdForTemporalTags, ret); } else if (policyType == RangerPolicy.POLICY_TYPE_DATAMASK) { - updateDataMasksFromPolicy(evaluator, isConditionalMatch, ret); + updateDataMasksFromPolicy(evaluator, policyIdForTemporalTags, ret); } } @@ -1177,13 +1172,15 @@ private boolean getIsFallbackSupported() { return policyEngine.getPluginContext().getConfig().getIsFallbackSupported(); } - private void updateFromPolicyACLs(RangerPolicyEvaluator evaluator, boolean isConditional, RangerResourceACLs resourceACLs) { + private void updateFromPolicyACLs(RangerPolicyEvaluator evaluator, Set policyIdForTemporalTags, RangerResourceACLs resourceACLs) { PolicyACLSummary aclSummary = evaluator.getPolicyACLSummary(); if (aclSummary == null) { return; } + boolean isConditional = policyIdForTemporalTags.contains(evaluator.getPolicyId()) || evaluator.getValidityScheduleEvaluatorsCount() != 0; + for (Map.Entry> userAccessInfo : aclSummary.getUsersAccessInfo().entrySet()) { final String userName = userAccessInfo.getKey(); @@ -1251,10 +1248,12 @@ private void updateFromPolicyACLs(RangerPolicyEvaluator evaluator, boolean isCon } } - private void updateRowFiltersFromPolicy(RangerPolicyEvaluator evaluator, boolean isConditional, RangerResourceACLs resourceACLs) { + private void updateRowFiltersFromPolicy(RangerPolicyEvaluator evaluator, Set policyIdForTemporalTags, RangerResourceACLs resourceACLs) { PolicyACLSummary aclSummary = evaluator.getPolicyACLSummary(); if (aclSummary != null) { + boolean isConditional = policyIdForTemporalTags.contains(evaluator.getPolicyId()) || evaluator.getValidityScheduleEvaluatorsCount() != 0; + for (RowFilterResult rowFilterResult : aclSummary.getRowFilters()) { rowFilterResult = copyRowFilter(rowFilterResult); @@ -1267,10 +1266,12 @@ private void updateRowFiltersFromPolicy(RangerPolicyEvaluator evaluator, boolean } } - private void updateDataMasksFromPolicy(RangerPolicyEvaluator evaluator, boolean isConditional, RangerResourceACLs resourceACLs) { + private void updateDataMasksFromPolicy(RangerPolicyEvaluator evaluator, Set policyIdForTemporalTags, RangerResourceACLs resourceACLs) { PolicyACLSummary aclSummary = evaluator.getPolicyACLSummary(); if (aclSummary != null) { + boolean isConditional = policyIdForTemporalTags.contains(evaluator.getPolicyId()) || evaluator.getValidityScheduleEvaluatorsCount() != 0; + for (DataMaskResult dataMaskResult : aclSummary.getDataMasks()) { dataMaskResult = copyDataMask(dataMaskResult); @@ -1311,18 +1312,6 @@ private Set copyStrings(Set values) { return values != null ? new HashSet<>(values) : null; } - private boolean isMatch(MatchType matchType, RangerAccessRequest.ResourceMatchingScope matchingScope) { - final boolean ret; - - if (matchingScope == RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS) { - ret = matchType != MatchType.NONE; - } else { - ret = matchType == MatchType.SELF || matchType == MatchType.SELF_AND_ALL_DESCENDANTS; - } - - return ret; - } - private static class ServiceConfig { private final Set auditExcludedUsers; private final Set auditExcludedGroups; diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceACLs.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceACLs.java index e0c0f94a99..aa49507b8c 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceACLs.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceACLs.java @@ -40,7 +40,6 @@ import java.util.Set; import static org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator.ACCESS_ALLOWED; -import static org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator.ACCESS_CONDITIONAL; import static org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator.ACCESS_DENIED; public class RangerResourceACLs { @@ -117,7 +116,7 @@ public void setUserAccessInfo(String userName, String accessType, Integer access accessResult = new AccessResult(access, policy); userAccessInfo.put(accessType, accessResult); - } else if (access != ACCESS_CONDITIONAL) { + } else { accessResult.setResult(access); accessResult.setPolicy(policy); } @@ -138,7 +137,7 @@ public void setGroupAccessInfo(String groupName, String accessType, Integer acce accessResult = new AccessResult(access, policy); groupAccessInfo.put(accessType, accessResult); - } else if (access != ACCESS_CONDITIONAL) { + } else { accessResult.setResult(access); accessResult.setPolicy(policy); } @@ -159,7 +158,7 @@ public void setRoleAccessInfo(String roleName, String accessType, Integer access accessResult = new AccessResult(access, policy); roleAccessInfo.put(accessType, accessResult); - } else if (access != ACCESS_CONDITIONAL) { + } else { accessResult.setResult(access); accessResult.setPolicy(policy); } diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java index 159617b392..c16d2acb0e 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java @@ -25,24 +25,18 @@ import org.apache.ranger.plugin.model.RangerServiceDef; import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef; import org.apache.ranger.plugin.model.validation.RangerServiceDefHelper; -import org.apache.ranger.plugin.policyengine.PolicyEngine; import org.apache.ranger.plugin.policyengine.RangerAccessRequest; import org.apache.ranger.plugin.policyengine.RangerPluginContext; import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions; import org.apache.ranger.plugin.policyresourcematcher.RangerDefaultPolicyResourceMatcher; import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher; -import org.apache.ranger.plugin.resourcematcher.RangerAbstractResourceMatcher; import org.apache.ranger.plugin.resourcematcher.RangerResourceMatcher; -import org.apache.ranger.plugin.util.RangerRequestExprResolver; import org.apache.ranger.plugin.util.ServiceDefUtil; -import org.apache.ranger.plugin.util.StringTokenReplacer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; @@ -53,18 +47,6 @@ public abstract class RangerAbstractPolicyEvaluator implements RangerPolicyEvalu private static final AtomicLong NEXT_RESOURCE_EVALUATOR_ID = new AtomicLong(1); - private final static Map WILDCARD_EVAL_CONTEXT = new HashMap() { - @Override - public boolean containsKey(Object key) { return true; } - - @Override - public Object get(Object key) { return RangerAbstractResourceMatcher.WILDCARD_ASTERISK; } - }; - - static { - WILDCARD_EVAL_CONTEXT.put(RangerAbstractResourceMatcher.WILDCARD_ASTERISK, RangerAbstractResourceMatcher.WILDCARD_ASTERISK); - } - private RangerPolicy policy; private RangerServiceDef serviceDef; private boolean needsDynamicEval = false; @@ -253,61 +235,11 @@ public StringBuilder toString(StringBuilder sb) { return sb; } - private Map getPolicyResourcesWithMacrosReplaced(Map resources, PolicyEngine policyEngine) { - if (LOG.isDebugEnabled()) { - LOG.debug("==> RangerAbstractPolicyEvaluator.getPolicyResourcesWithMacrosReplaced(" + resources + ")"); - } - - final Map ret; - final Collection resourceKeys = resources == null ? null : resources.keySet(); - - if (CollectionUtils.isNotEmpty(resourceKeys)) { - ret = new HashMap<>(); - - for (String resourceName : resourceKeys) { - RangerPolicyResource resourceValues = resources.get(resourceName); - List values = resourceValues == null ? null : resourceValues.getValues(); - - if (CollectionUtils.isNotEmpty(values)) { - StringTokenReplacer tokenReplacer = policyEngine.getStringTokenReplacer(resourceName); - - List modifiedValues = new ArrayList<>(); - - for (String value : values) { - RangerRequestExprResolver exprResolver = new RangerRequestExprResolver(value, serviceDef.getName()); - String modifiedValue = exprResolver.resolveExpressions(WILDCARD_EVAL_CONTEXT); - - if (tokenReplacer != null) { - modifiedValue = tokenReplacer.replaceTokens(modifiedValue, WILDCARD_EVAL_CONTEXT); - } - - modifiedValues.add(modifiedValue); - } - - RangerPolicyResource modifiedPolicyResource = new RangerPolicyResource(modifiedValues, resourceValues.getIsExcludes(), resourceValues.getIsRecursive()); - - ret.put(resourceName, modifiedPolicyResource); - } else { - ret.put(resourceName, resourceValues); - } - } - } else { - ret = resources; - } - - if (LOG.isDebugEnabled()) { - LOG.debug("<== RangerAbstractPolicyEvaluator.getPolicyResourcesWithMacrosReplaced(" + resources + "): " + ret); - } - - return ret; - } - public class RangerDefaultPolicyResourceEvaluator implements RangerPolicyResourceEvaluator { - private final long id; - private final Map resource; - private final RangerDefaultPolicyResourceMatcher resourceMatcher; - private final RangerResourceDef leafResourceDef; - private volatile RangerDefaultPolicyResourceMatcher macrosReplacedWithWildcardMatcher; + private final long id; + private final Map resource; + private final RangerDefaultPolicyResourceMatcher resourceMatcher; + private final RangerResourceDef leafResourceDef; public RangerDefaultPolicyResourceEvaluator(long id, Map resource, int policyType, RangerServiceDef serviceDef, RangerServiceDefHelper serviceDefHelper) { this.id = id; @@ -336,36 +268,6 @@ public RangerPolicyResourceMatcher getPolicyResourceMatcher() { return resourceMatcher; } - @Override - public RangerPolicyResourceMatcher getMacrosReplaceWithWildcardMatcher(PolicyEngine policyEngine) { - RangerDefaultPolicyResourceMatcher ret = this.macrosReplacedWithWildcardMatcher; - - if (ret == null) { - synchronized (this) { - ret = this.macrosReplacedWithWildcardMatcher; - - if (ret == null) { - if (resourceMatcher.getNeedsDynamicEval()) { - Map updatedResource = getPolicyResourcesWithMacrosReplaced(resource, policyEngine); - - ret = new RangerDefaultPolicyResourceMatcher(); - - ret.setPolicyResources(updatedResource, resourceMatcher.getPolicyType()); - ret.setServiceDef(serviceDef); - ret.setServiceDefHelper(resourceMatcher.getServiceDefHelper()); - ret.init(); - } else { - ret = resourceMatcher; - } - - this.macrosReplacedWithWildcardMatcher = ret; - } - } - } - - return ret; - } - @Override public Map getPolicyResource() { return resource; diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultDataMaskPolicyItemEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultDataMaskPolicyItemEvaluator.java index d979e97e14..8d9969a3f4 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultDataMaskPolicyItemEvaluator.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultDataMaskPolicyItemEvaluator.java @@ -18,7 +18,6 @@ */ package org.apache.ranger.plugin.policyevaluator; -import org.apache.commons.lang.StringUtils; import org.apache.ranger.plugin.model.RangerPolicy; import org.apache.ranger.plugin.model.RangerServiceDef; import org.apache.ranger.plugin.model.RangerPolicy.RangerDataMaskPolicyItem; @@ -26,34 +25,15 @@ import org.apache.ranger.plugin.policyengine.RangerAccessResult; import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions; import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher; -import org.apache.ranger.plugin.util.RangerRequestExprResolver; public class RangerDefaultDataMaskPolicyItemEvaluator extends RangerDefaultPolicyItemEvaluator implements RangerDataMaskPolicyItemEvaluator { - final private RangerDataMaskPolicyItem dataMaskPolicyItem; - final private RangerRequestExprResolver maskedValueExprResolver; - final private RangerRequestExprResolver maskConditionExprResolver; + final private RangerDataMaskPolicyItem dataMaskPolicyItem; public RangerDefaultDataMaskPolicyItemEvaluator(RangerServiceDef serviceDef, RangerPolicy policy, RangerDataMaskPolicyItem policyItem, int policyItemIndex, RangerPolicyEngineOptions options) { super(serviceDef, policy, policyItem, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DATAMASK, policyItemIndex, options); dataMaskPolicyItem = policyItem; - - RangerPolicyItemDataMaskInfo dataMaskInfo = dataMaskPolicyItem != null ? dataMaskPolicyItem.getDataMaskInfo() : null; - String maskedValue = dataMaskInfo != null ? dataMaskInfo.getValueExpr() : null; - String maskCondition = dataMaskInfo != null ? dataMaskInfo.getConditionExpr() : null; - - if (StringUtils.isNotBlank(maskedValue) && RangerRequestExprResolver.hasExpressions(maskedValue)) { - maskedValueExprResolver = new RangerRequestExprResolver(maskedValue, getServiceType()); - } else { - maskedValueExprResolver = null; - } - - if (StringUtils.isNotBlank(maskCondition) && RangerRequestExprResolver.hasExpressions(maskCondition)) { - maskConditionExprResolver = new RangerRequestExprResolver(maskCondition, getServiceType()); - } else { - maskConditionExprResolver = null; - } } @Override @@ -67,19 +47,8 @@ public void updateAccessResult(RangerPolicyEvaluator policyEvaluator, RangerAcce if (dataMaskInfo != null) { result.setMaskType(dataMaskInfo.getDataMaskType()); - - if (maskedValueExprResolver != null) { - result.setMaskedValue(maskedValueExprResolver.resolveExpressions(result.getAccessRequest())); - } else { - result.setMaskedValue(dataMaskInfo.getValueExpr()); - } - - if (maskConditionExprResolver != null) { - result.setMaskCondition(maskConditionExprResolver.resolveExpressions(result.getAccessRequest())); - } else { - result.setMaskCondition(dataMaskInfo.getConditionExpr()); - } - + result.setMaskCondition(dataMaskInfo.getConditionExpr()); + result.setMaskedValue(dataMaskInfo.getValueExpr()); result.setIsAccessDetermined(true); result.setPolicyPriority(policyEvaluator.getPolicyPriority()); result.setPolicyId(policyEvaluator.getPolicyId()); diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java index f130e2491d..d1c2f7cde0 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java @@ -39,8 +39,6 @@ import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; import org.apache.ranger.plugin.model.RangerPolicy.RangerRowFilterPolicyItem; import org.apache.ranger.plugin.model.RangerServiceDef; -import org.apache.ranger.plugin.policyengine.PolicyEngine; -import org.apache.ranger.plugin.policyengine.RangerResourceAccessInfo; import org.apache.ranger.plugin.policyengine.RangerAccessRequest; import org.apache.ranger.plugin.policyengine.RangerAccessResult; import org.apache.ranger.plugin.policyengine.RangerAccessResource; @@ -48,6 +46,7 @@ import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions; import org.apache.ranger.plugin.policyengine.RangerResourceACLs.DataMaskResult; import org.apache.ranger.plugin.policyengine.RangerResourceACLs.RowFilterResult; +import org.apache.ranger.plugin.policyengine.RangerResourceAccessInfo; import org.apache.ranger.plugin.policyresourcematcher.RangerResourceEvaluator; import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher; @@ -642,7 +641,5 @@ default long getPolicyId() { } RangerPolicyEvaluator getPolicyEvaluator(); - - RangerPolicyResourceMatcher getMacrosReplaceWithWildcardMatcher(PolicyEngine policyEngine); } } diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java index 78e2f18846..15f2522db9 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java @@ -101,10 +101,6 @@ public void setServiceDefHelper(RangerServiceDefHelper serviceDefHelper) { public int getPolicyType() { return policyType; } - public RangerServiceDefHelper getServiceDefHelper() { - return serviceDefHelper; - } - @Override public RangerServiceDef getServiceDef() { return serviceDef; diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/store/EmbeddedServiceDefsUtil.java b/agents-common/src/main/java/org/apache/ranger/plugin/store/EmbeddedServiceDefsUtil.java index 79e09a1a24..db629c85d3 100755 --- a/agents-common/src/main/java/org/apache/ranger/plugin/store/EmbeddedServiceDefsUtil.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/EmbeddedServiceDefsUtil.java @@ -49,7 +49,7 @@ public class EmbeddedServiceDefsUtil { // following servicedef list should be reviewed/updated whenever a new embedded service-def is added - public static final String DEFAULT_BOOTSTRAP_SERVICEDEF_LIST = "tag,hdfs,hbase,hive,kms,knox,storm,yarn,kafka,solr,atlas,nifi,nifi-registry,sqoop,kylin,elasticsearch,presto,trino,ozone,kudu,schema-registry,nestedstructure"; + public static final String DEFAULT_BOOTSTRAP_SERVICEDEF_LIST = "tag,hdfs,hbase,hive,kms,knox,storm,yarn,kafka,solr,atlas,nifi,nifi-registry,sqoop,kylin,elasticsearch,presto,trino,ozone,kudu,schema-registry"; private static final String PROPERTY_SUPPORTED_SERVICE_DEFS = "ranger.supportedcomponents"; private Set supportedServiceDefs; public static final String EMBEDDED_SERVICEDEF_TAG_NAME = "tag"; @@ -75,7 +75,6 @@ public class EmbeddedServiceDefsUtil { public static final String EMBEDDED_SERVICEDEF_TRINO_NAME = "trino"; public static final String EMBEDDED_SERVICEDEF_OZONE_NAME = "ozone"; public static final String EMBEDDED_SERVICEDEF_KUDU_NAME = "kudu"; - public static final String EMBEDDED_SERVICEDEF_NESTEDSTRUCTURE_NAME = "nestedstructure"; public static final String PROPERTY_CREATE_EMBEDDED_SERVICE_DEFS = "ranger.service.store.create.embedded.service-defs"; @@ -121,7 +120,6 @@ public class EmbeddedServiceDefsUtil { private RangerServiceDef trinoServiceDef; private RangerServiceDef ozoneServiceDef; private RangerServiceDef kuduServiceDef; - private RangerServiceDef nestedStructureServiveDef; private RangerServiceDef tagServiceDef; @@ -173,7 +171,6 @@ public void init(ServiceStore store) { prestoServiceDef = getOrCreateServiceDef(store, EMBEDDED_SERVICEDEF_PRESTO_NAME); ozoneServiceDef = getOrCreateServiceDef(store, EMBEDDED_SERVICEDEF_OZONE_NAME); kuduServiceDef = getOrCreateServiceDef(store, EMBEDDED_SERVICEDEF_KUDU_NAME); - nestedStructureServiveDef = getOrCreateServiceDef(store, EMBEDDED_SERVICEDEF_NESTEDSTRUCTURE_NAME); // Ensure that tag service def is updated with access types of all service defs store.updateTagServiceDefForAccessTypes(); @@ -261,8 +258,6 @@ public long getElasticsearchServiceDefId() { public long getKuduServiceDefId() { return getId(kuduServiceDef); } - public long getNestedStructureServiceDefId() { return getId(nestedStructureServiveDef); } - public RangerServiceDef getEmbeddedServiceDef(String defType) throws Exception { RangerServiceDef serviceDef=null; if(StringUtils.isNotEmpty(defType)){ diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/store/ServiceStore.java b/agents-common/src/main/java/org/apache/ranger/plugin/store/ServiceStore.java index aecde05fb4..6283e02f2a 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/store/ServiceStore.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/ServiceStore.java @@ -71,8 +71,6 @@ public interface ServiceStore { RangerPolicy createPolicy(RangerPolicy policy) throws Exception; - RangerPolicy createDefaultPolicy(RangerPolicy policy) throws Exception; - RangerPolicy updatePolicy(RangerPolicy policy) throws Exception; void deletePolicy(RangerPolicy policy, RangerService service) throws Exception; diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/store/TagValidator.java b/agents-common/src/main/java/org/apache/ranger/plugin/store/TagValidator.java index 699e49e17b..08b1e45fda 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/store/TagValidator.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/TagValidator.java @@ -150,7 +150,6 @@ public RangerServiceResource preCreateServiceResource(RangerServiceResource reso if (ret == null) { RangerServiceResourceSignature serializer = new RangerServiceResourceSignature(resource); resource.setResourceSignature(serializer.getSignature()); - ret = tagStore.getServiceResourceByServiceAndResourceSignature(resource.getServiceName(), resource.getResourceSignature()); } return ret; diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRequestExprResolver.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRequestExprResolver.java index 3a183cff6a..4e5d949de3 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRequestExprResolver.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRequestExprResolver.java @@ -26,7 +26,6 @@ import javax.script.ScriptEngine; import java.util.Collection; -import java.util.Map; import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -55,46 +54,6 @@ public RangerRequestExprResolver(String str, String serviceType) { } } - /* - * replaces expressions in this.str with corresponding values in exprValues map (argument). - * For example, given the following: - * 1. this.str has value: "dept = '${{USER.dept}}'" - * 2. exprValues has value: { "dept": "marketing" } - * This method returns: "dept = 'marketing'" - */ - public String resolveExpressions(Map exprValues) { - String ret = str; - - if (hasTokens) { - StringBuffer sb = new StringBuffer(); - Matcher matcher = PATTERN.matcher(str); - - while (matcher.find()) { - String expr = matcher.group(REGEX_GROUP_EXPR); - String val = Objects.toString(exprValues.get(expr)); - - matcher.appendReplacement(sb, val); - } - - matcher.appendTail(sb); - - ret = sb.toString(); - - if (LOG.isDebugEnabled()) { - LOG.debug("RangerRequestExprResolver.resolveExpressions(" + str + "): ret=" + ret); - } - } - - return ret; - } - - /* - * replaces expressions in this.str with corresponding values in request (argument). - * For example, given the following: - * 1. this.str has value: "dept = '${{USER.dept}}'" - * 2. request.user has attribute dept with value: "marketing" - * This method returns: "dept = 'marketing'" - */ public String resolveExpressions(RangerAccessRequest request) { String ret = str; diff --git a/agents-common/src/main/resources/service-defs/ranger-servicedef-nestedstructure.json b/agents-common/src/main/resources/service-defs/ranger-servicedef-nestedstructure.json deleted file mode 100644 index dc6b1d32df..0000000000 --- a/agents-common/src/main/resources/service-defs/ranger-servicedef-nestedstructure.json +++ /dev/null @@ -1,186 +0,0 @@ -{ - "name": "nestedstructure", - "displayName": "nestedstructure", - "implClass": "", - "label": "NestedStructure", - "description": "Plugin to enforce READ and WRITE access control on nested structures such as JSON response objects from microservice API resource calls", - "options": { - "enableDenyAndExceptionsInPolicies": "true" - }, - "configs": [ - { "itemId": 1, "name": "commonNameForCertificate", "type": "string", "mandatory": false }, - { "itemId": 2, "name": "policy.download.auth.users", "type": "string", "mandatory": false } - ], - "resources": [ - { - "itemId": 1, - "name": "schema", - "type": "string", - "level": 10, - "mandatory": true, - "lookupSupported": false, - "recursiveSupported": false, - "excludesSupported": true, - "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", - "matcherOptions": { "wildCard": "true", "ignoreCase": "true" }, - "label": "NestedStructure Schema", - "description": "Schema of the nested structure returned from Microservice GET, etc", - "accessTypeRestrictions": [], - "isValidLeaf": true - }, - { - "itemId": 2, - "name": "field", - "type": "string", - "level": 20, - "parent": "schema", - "mandatory": true, - "lookupSupported": false, - "recursiveSupported": false, - "excludesSupported": true, - "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", - "matcherOptions": { "wildCard": "true", "ignoreCase": "true" }, - "label": "NestedStructure Schema Field", - "description": "NestedStructure Schema Field", - "accessTypeRestrictions": [], - "isValidLeaf": true - } - ], - "accessTypes": [ - { "itemId": 1, "name": "read", "label": "Read" }, - { "itemId": 2, "name": "write", "label": "Write" } - ], - "policyConditions": [], - "contextEnrichers": [], - "enums": [], - "dataMaskDef": { - "maskTypes": [ - { - "itemId": 1, - "name": "MASK", - "label": "Redact", - "description": "Replace lowercase with 'x', uppercase with 'X', digits with '0'", - "transformer": "mask({field})", - "dataMaskOptions": {} - }, - { - "itemId": 2, - "name": "MASK_SHOW_LAST_4", - "label": "Partial mask: show last 4", - "description": "Show last 4 characters; replace rest with 'x'", - "transformer": "mask_show_last_n({field}, 4, 'x', 'x', 'x', -1, '1')", - "dataMaskOptions": {} - }, - { - "itemId": 3, - "name": "MASK_SHOW_FIRST_4", - "label": "Partial mask: show first 4", - "description": "Show first 4 characters; replace rest with 'x'", - "transformer": "mask_show_first_n({field}, 4, 'x', 'x', 'x', -1, '1')", - "dataMaskOptions": {} - }, - { - "itemId": 4, - "name": "MASK_HASH", - "label": "Hash", - "description": "Hash the value", - "transformer": "mask_hash({field})", - "dataMaskOptions": {} - }, - { - "itemId": 5, - "name": "MASK_NULL", - "label": "Nullify", - "description": "Replace with NULL", - "dataMaskOptions": {} - }, - { - "itemId": 6, - "name": "MASK_NONE", - "label": "Unmasked (retain original value)", - "description": "No masking", - "dataMaskOptions": {} - }, - { - "itemId": 12, - "name": "MASK_DATE_SHOW_YEAR", - "label": "Date: show only year", - "description": "Date: show only year", - "transformer": "mask({field}, 'x', 'x', 'x', -1, '1', 1, 0, -1)", - "dataMaskOptions": {} - }, - { - "itemId": 13, - "name": "CUSTOM", - "label": "Custom", - "description": "Custom", - "dataMaskOptions": {} - } - ], - "accessTypes": [ - { "itemId": 1, "name": "read", "label": "Read" } - ], - "resources": [ - { - "itemId": 1, - "name": "schema", - "type": "string", - "level": 10, - "mandatory": true, - "lookupSupported": false, - "recursiveSupported": false, - "excludesSupported": false, - "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", - "matcherOptions": { "wildCard": "false", "ignoreCase": "true" }, - "uiHint": "{ \"singleValue\":true }", - "label": "NestedStructure Schema", - "description": "NestedStructure Schema returned from Microservice GET, etc", - "accessTypeRestrictions": [], - "isValidLeaf": false - }, - { - "itemId": 2, - "name": "field", - "type": "string", - "level": 20, - "parent": "schema", - "mandatory": true, - "lookupSupported": false, - "recursiveSupported": false, - "excludesSupported": false, - "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", - "matcherOptions": { "wildCard": "false", "ignoreCase": "true" }, - "uiHint": "{ \"singleValue\":true }", - "label": "NestedStructure Schema Field", - "description": "NestedStructure Schema Field", - "accessTypeRestrictions": [], - "isValidLeaf": true - } - ] - }, - "rowFilterDef": { - "accessTypes": [ - { "itemId": 1, "name": "read", "label": "Read" }, - { "itemId": 2, "name": "write", "label": "Write" } - ], - "resources": [ - { - "itemId": 1, - "name": "schema", - "type": "string", - "level": 10, - "mandatory": true, - "lookupSupported": false, - "recursiveSupported": false, - "excludesSupported": false, - "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", - "matcherOptions": { "wildCard": "false", "ignoreCase": "true" }, - "uiHint": "{ \"singleValue\":true }", - "label": "NestedStructure Schema", - "description": "NestedStructure Schema returned from Microservice GET, etc", - "accessTypeRestrictions": [], - "isValidLeaf": true - } - ] - } -} \ No newline at end of file diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyACLs.java b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyACLs.java index a7f48bb331..b6135b096d 100644 --- a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyACLs.java +++ b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyACLs.java @@ -267,11 +267,7 @@ private void runTests(InputStreamReader reader, String testName) throws Exceptio } else if (!(MapUtils.isEmpty(acls.getRoleACLs()) && MapUtils.isEmpty(oneTest.rolePermissions))) { roleACLsMatched = false; } - assertTrue("getResourceACLs() failed! " + testCase.name + ":" + oneTest.name + " - userACLsMatched", userACLsMatched); - assertTrue("getResourceACLs() failed! " + testCase.name + ":" + oneTest.name + " - groupACLsMatched", groupACLsMatched); - assertTrue("getResourceACLs() failed! " + testCase.name + ":" + oneTest.name + " - roleACLsMatched", roleACLsMatched); - assertTrue("getResourceACLs() failed! " + testCase.name + ":" + oneTest.name + " - rowFiltersMatched", rowFiltersMatched); - assertTrue("getResourceACLs() failed! " + testCase.name + ":" + oneTest.name + " - dataMaskingMatched", dataMaskingMatched); + assertTrue("getResourceACLs() failed! " + testCase.name + ":" + oneTest.name, userACLsMatched && groupACLsMatched && roleACLsMatched && rowFiltersMatched && dataMaskingMatched); } } } diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java index 59c50e4ca6..e6bd2f4f88 100644 --- a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java +++ b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java @@ -349,13 +349,6 @@ public void testPolicyEngine_hiveMasking() { runTestsFromResourceFiles(resourceFiles); } - @Test - public void testPolicyEngine_hiveMaskingWithReqExpressions() { - String[] resourceFiles = {"/policyengine/test_policyengine_hive_mask_filter_with_req_expressions.json"}; - - runTestsFromResourceFiles(resourceFiles); - } - @Test public void testPolicyEngine_hiveTagMasking() { String[] resourceFiles = {"/policyengine/test_policyengine_tag_hive_mask.json"}; @@ -687,19 +680,19 @@ private void runTestCaseTests(RangerPolicyEngine policyEngine, RangerPolicyEngin RangerAccessResultProcessor auditHandler = new RangerDefaultAuditHandler(); - if (MapUtils.isNotEmpty(test.userAttributes) || MapUtils.isNotEmpty(test.groupAttributes)) { - RangerUserStore userStore = new RangerUserStore(); - - userStore.setUserAttrMapping(test.userAttributes); - userStore.setGroupAttrMapping(test.groupAttributes); - - RangerAccessRequestUtil.setRequestUserStoreInContext(request.getContext(), userStore); - } - if(test.result != null) { RangerAccessResult expected = test.result; RangerAccessResult result; + if (MapUtils.isNotEmpty(test.userAttributes) || MapUtils.isNotEmpty(test.groupAttributes)) { + RangerUserStore userStore = new RangerUserStore(); + + userStore.setUserAttrMapping(test.userAttributes); + userStore.setGroupAttrMapping(test.groupAttributes); + + RangerAccessRequestUtil.setRequestUserStoreInContext(request.getContext(), userStore); + } + result = policyEngine.evaluatePolicies(request, RangerPolicy.POLICY_TYPE_ACCESS, auditHandler); policyEngine.evaluateAuditPolicies(result); diff --git a/agents-common/src/test/resources/policyengine/test_aclprovider_default.json b/agents-common/src/test/resources/policyengine/test_aclprovider_default.json index 8b799acff5..37f4f3c2d5 100644 --- a/agents-common/src/test/resources/policyengine/test_aclprovider_default.json +++ b/agents-common/src/test/resources/policyengine/test_aclprovider_default.json @@ -394,30 +394,6 @@ "users": ["user1", "user2"] } ] - }, - { "id": 21, "name": "db=user_{USER}, table=*, column=*", "isEnabled": true, "isAuditEnabled": true, "isDenyAllElse": false, - "resources": { "database": { "values": [ "user_{USER}*" ] }, "table": { "values": [ "*" ] }, "column": { "values": [ "*" ] } }, - "policyItems": [ - { "accesses": [ { "type": "select" }, { "type": "update" } ], - "groups": [ "public" ] - } - ] - }, - { "id": 22, "name": "db=dept_${{USER.dept}}, table=*, column=*", "isEnabled": true, "isAuditEnabled": true, "isDenyAllElse": false, - "resources": { "database": { "values": [ "dept_${{USER.dept}}" ] }, "table": { "values": [ "*" ] }, "column": { "values": [ "*" ] } }, - "policyItems": [ - { "accesses": [ { "type": "select" } ], - "groups": [ "public", "engg" ] - } - ] - }, - { "id": 23, "name": "db=dept_engg, table=*, column=*", "isEnabled": true, "isAuditEnabled": true, "isDenyAllElse": false, - "resources": { "database": { "values": [ "dept_engg" ] }, "table": { "values": [ "*" ] }, "column": { "values": [ "*" ] } }, - "policyItems": [ - { "accesses": [ { "type": "select" } ], - "groups": [ "engg" ] - } - ] } ], "tagPolicies": { @@ -581,14 +557,6 @@ }, "tests": [ - { "name": "{USER} macro in database name", - "resource": { "elements": { "database": "user_madhan", "table": "test_tbl1" } }, - "groupPermissions": { "public": { "select": { "result": 2, "isFinal": true }, "update": { "result": 2, "isFinal": true } } } - }, - { "name": "${{USER.dept}} macro in database name", - "resource": { "elements": { "database": "dept_engg", "table": "test_tbl1" } }, - "groupPermissions": { "public": { "select": { "result": 2, "isFinal": true } }, "engg": { "select": { "result": 1, "isFinal": true } } } - }, { "name": "denyAllElse-test", "resource": {"elements":{"database":"denyAllElse", "table":"table-1", "column": "column-1" }}, diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_hive_mask_filter_with_req_expressions.json b/agents-common/src/test/resources/policyengine/test_policyengine_hive_mask_filter_with_req_expressions.json deleted file mode 100644 index 5a4637008d..0000000000 --- a/agents-common/src/test/resources/policyengine/test_policyengine_hive_mask_filter_with_req_expressions.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "serviceName": "hivedev", - - "serviceDef": { - "name": "hive", "id": 3, - "resources": [ - { "name": "database", "level": 1, "mandatory": true, "lookupSupported": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": true, "ignoreCase": true }, "label": "Hive Database", "description": "Hive Database" }, - { "name": "table", "level": 2, "parent": "database", "mandatory": true, "lookupSupported": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": true, "ignoreCase": true }, "label": "Hive Table", "description": "Hive Table" }, - { "name": "udf", "level": 2, "parent": "database", "mandatory": true, "lookupSupported": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": true, "ignoreCase": true }, "label": "Hive UDF", "description": "Hive UDF" }, - { "name": "column", "level": 3, "parent": "table", "mandatory": true, "lookupSupported": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": true, "ignoreCase": true }, "label": "Hive Column", "description": "Hive Column" } - ], - "accessTypes": [ - { "name": "select", "label": "Select" }, - { "name": "update", "label": "Update" }, - { "name": "create", "label": "Create" }, - { "name": "drop", "label": "Drop" }, - { "name": "alter", "label": "Alter" }, - { "name": "index", "label": "Index" }, - { "name": "lock", "label": "Lock" }, - { "name": "all", "label": "All", "impliedGrants": [ "select", "update", "create", "drop", "alter", "index", "lock" ] } - ], - "dataMaskDef": { - "maskTypes": [ - { "itemId": 1, "name": "MASK", "label": "Mask", "description": "Replace lowercase with 'x', uppercase with 'X', digits with '0'" }, - { "itemId": 2, "name": "SHUFFLE", "label": "Shuffle", "description": "Randomly shuffle the contents" }, - { "itemId": 10, "name": "NULL", "label": "NULL", "description": "Replace with NULL" }, - { "itemId": 11, "name": "CUSTOM", "label": "CUSTOM", "description": "Custom expression" } - ], - "accessTypes": [ - { "name": "select", "label": "Select" } - ], - "resources": [ - { "name": "database", "matcherOptions": { "wildCard":false } }, - { "name": "table", "matcherOptions": { "wildCard":false } }, - { "name": "column", "matcherOptions": { "wildCard":false } } - ] - }, - "rowFilterDef": { - "accessTypes": [ - { "name": "select", "label": "Select" } - ], - "resources": [ - { "name": "database", "matcherOptions": { "wildCard":false } }, - { "name": "table", "matcherOptions": { "wildCard":false } } - ] - } - }, - - "policies": [ - { "id": 1, "name": "db=*: audit-all-access", "isEnabled": true, "isAuditEnabled": true, - "resources": { "database": { "values": [ "*" ] }, "table": { "values": [ "*" ] }, "column": { "values": [ "*" ] } }, - "policyItems": [ - { "accesses": [ { "type": "all", "isAllowed": true } ], "users": [ "hive", "user1", "user2" ], "groups": [ "public" ], "delegateAdmin":false } - ] - }, - { "id": 101, "name": "db=employee, table=personal, column=ssn: mask ssn column", "isEnabled": true, "isAuditEnabled": true, "policyType": 1, - "resources": { "database": { "values": [ "employee" ] }, "table": { "values": [ "personal" ] }, "column": { "values": [ "ssn" ] } }, - "dataMaskPolicyItems": [ - { "accesses": [ { "type": "select", "isAllowed": true } ], "groups": [ "public" ], "delegateAdmin":false, - "dataMaskInfo": { "dataMaskType": "CUSTOM", "valueExpr": "CASE WHEN dept = '${{USER.dept}}' THEN {col} ELSE mask_show_last_n({col}, 4, 'x', 'x', 'x', -1, '1') END" } - } - ] - }, - { "id": 201, "name": "db=employee, table=personal", "isEnabled": true, "isAuditEnabled": true, "policyType": 2, - "resources": { "database": { "values": [ "employee" ] }, "table": { "values": [ "personal" ] } }, - "rowFilterPolicyItems": [ - { "accesses": [ { "type": "select", "isAllowed": true } ], "groups": [ "public" ], "delegateAdmin":false, - "rowFilterInfo": { "filterExpr": "dept='${{USER.dept}}'" } - } - ] - } - ], - - "tests": [ - { "name": "'select ssn from employee.personal;' for user1 - maskType=CUSTOM", - "request": { - "resource": { "elements": { "database": "employee", "table": "personal", "column": "ssn" } }, - "accessType": "select", "user": "user1", "userGroups": [], "requestData": "select ssn from employee.personal;' for user1" - }, - "userAttributes": { "user1": { "dept": "engg" }, "user2": { "dept": "r&d" } }, - "dataMaskResult": { "additionalInfo": { "maskType": "CUSTOM", "maskCondition":null, "maskedValue": "CASE WHEN dept = 'engg' THEN {col} ELSE mask_show_last_n({col}, 4, 'x', 'x', 'x', -1, '1') END"}, "policyId": 101} - }, - { "name": "'select ssn from employee.personal;' for user2 - maskType=CUSTOM", - "request": { - "resource": { "elements": { "database": "employee", "table": "personal", "column": "ssn" } }, - "accessType": "select", "user": "user2", "userGroups": [], "requestData": "select ssn from employee.personal;' for user2" - }, - "userAttributes": { "user1": { "dept": "engg" }, "user2": { "dept": "r&d" } }, - "dataMaskResult": { "additionalInfo": { "maskType": "CUSTOM", "maskCondition":null, "maskedValue": "CASE WHEN dept = 'r&d' THEN {col} ELSE mask_show_last_n({col}, 4, 'x', 'x', 'x', -1, '1') END"}, "policyId": 101} - }, - { "name": "'select ssn from employee.personal;' for user1 - filterExpr=dept='engg'", - "request": { - "resource": { "elements": { "database": "employee", "table": "personal" } }, - "accessType": "select", "user": "user1", "userGroups": [], "requestData": "select ssn from employee.personal;' for user1" - }, - "userAttributes": { "user1": { "dept": "engg" }, "user2": { "dept": "r&d" } }, - "rowFilterResult": { "additionalInfo": { "filterExpr": "dept='engg'" }, "policyId": 201} - }, - { "name": "'select ssn from employee.personal;' for user2 - filterExpr=dept='r&d'", - "request": { - "resource": { "elements": { "database": "employee", "table": "personal" } }, - "accessType": "select", "user": "user2", "userGroups": [], "requestData": "select ssn from employee.personal;' for user2" - }, - "userAttributes": { "user1": { "dept": "engg" }, "user2": { "dept": "r&d" } }, - "rowFilterResult": { "additionalInfo": { "filterExpr": "dept='r&d'" }, "policyId": 201} - } - ] -} - diff --git a/dev-support/ranger-docker/scripts/create-ranger-services.py b/dev-support/ranger-docker/scripts/create-ranger-services.py index f329d1f290..7ce541d669 100644 --- a/dev-support/ranger-docker/scripts/create-ranger-services.py +++ b/dev-support/ranger-docker/scripts/create-ranger-services.py @@ -7,9 +7,7 @@ def service_not_exists(service): try: - res = ranger_client.get_service(service.name) - if res is None: - return 1 + ranger_client.get_service(service.name) except JSONDecodeError: return 1 return 0 diff --git a/dev-support/ranger-docker/scripts/ranger-kafka-setup.sh b/dev-support/ranger-docker/scripts/ranger-kafka-setup.sh index 51c91195f6..c6edce6b9b 100755 --- a/dev-support/ranger-docker/scripts/ranger-kafka-setup.sh +++ b/dev-support/ranger-docker/scripts/ranger-kafka-setup.sh @@ -29,5 +29,4 @@ cd ${RANGER_HOME}/ranger-kafka-plugin sed -i 's/localhost:2181/ranger-zk.example.com:2181/' ${KAFKA_HOME}/config/server.properties -echo >> ${KAFKA_HOME}/config/server.properties echo "authorizer.class.name=org.apache.ranger.authorization.kafka.authorizer.RangerKafkaAuthorizer" >> ${KAFKA_HOME}/config/server.properties diff --git a/dev-support/ranger-pmd-ruleset.xml b/dev-support/ranger-pmd-ruleset.xml index 2899f7ca9e..88d77f2362 100644 --- a/dev-support/ranger-pmd-ruleset.xml +++ b/dev-support/ranger-pmd-ruleset.xml @@ -94,7 +94,6 @@ - diff --git a/intg/src/main/java/org/apache/ranger/RangerClient.java b/intg/src/main/java/org/apache/ranger/RangerClient.java index e4e3a57ad7..f92116d363 100644 --- a/intg/src/main/java/org/apache/ranger/RangerClient.java +++ b/intg/src/main/java/org/apache/ranger/RangerClient.java @@ -19,8 +19,6 @@ package org.apache.ranger; import com.sun.jersey.api.client.GenericType; -import org.apache.hadoop.security.UserGroupInformation; -import org.apache.ranger.audit.provider.MiscUtil; import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,11 +28,14 @@ import org.apache.ranger.admin.client.datatype.RESTResponse; import org.apache.ranger.plugin.util.GrantRevokeRoleRequest; import org.apache.ranger.plugin.util.RangerRESTClient; +import org.apache.hadoop.security.SecureClientLogin; +import javax.security.auth.Subject; import java.security.PrivilegedAction; import javax.ws.rs.HttpMethod; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import java.io.IOException; import java.net.URI; import java.util.*; @@ -142,15 +143,19 @@ public class RangerClient { private final RangerRESTClient restClient; - private boolean isSecureMode = false; - private UserGroupInformation ugi = null; + private boolean isSecureMode = false; + private Subject sub = null; private void authInit(String authType, String username, String password) { if (AUTH_KERBEROS.equalsIgnoreCase(authType)) { - isSecureMode = true; - MiscUtil.loginWithKeyTab(password, username, null); - ugi = MiscUtil.getUGILoginUser(); - LOG.info("RangerClient.authInit() UGI user: " + ugi.getUserName() + " principal: " + username); + if (SecureClientLogin.isKerberosCredentialExists(username, password)) { + isSecureMode = true; + try { + sub = SecureClientLogin.loginUserFromKeytab(username, password); + } catch (IOException e) { + LOG.error(e.getMessage()); + } + } else LOG.error("Authentication credentials missing/invalid"); } else { restClient.setBasicAuthInfo(username, password); } @@ -459,8 +464,7 @@ private ClientResponse responseHandler(API api, Map params, Obje } if (isSecureMode) { - ugi = MiscUtil.getUGILoginUser(); - clientResponse = ugi.doAs((PrivilegedAction) () -> { + clientResponse = Subject.doAs(sub, (PrivilegedAction) () -> { try { return invokeREST(api,params,request); } catch (RangerServiceException e) { diff --git a/knox-agent/src/main/java/org/apache/ranger/admin/client/RangerAdminJersey2RESTClient.java b/knox-agent/src/main/java/org/apache/ranger/admin/client/RangerAdminJersey2RESTClient.java index e257f34d8f..09f46eb154 100644 --- a/knox-agent/src/main/java/org/apache/ranger/admin/client/RangerAdminJersey2RESTClient.java +++ b/knox-agent/src/main/java/org/apache/ranger/admin/client/RangerAdminJersey2RESTClient.java @@ -289,7 +289,7 @@ public RangerUserStore getUserStoreIfUpdated(long lastKnownUserStoreVersion, lon final RangerUserStore ret; final UserGroupInformation user = MiscUtil.getUGILoginUser(); - final boolean isSecureMode = isKerberosEnabled(user); + final boolean isSecureMode = user != null && UserGroupInformation.isSecurityEnabled(); final Response response; Map queryParams = new HashMap(); @@ -538,7 +538,7 @@ private ServicePolicies getServicePoliciesIfUpdatedWithCred(final long lastKnown final ServicePolicies ret; final UserGroupInformation user = MiscUtil.getUGILoginUser(); - final boolean isSecureMode = isKerberosEnabled(user); + final boolean isSecureMode = user != null && UserGroupInformation.isSecurityEnabled(); final Response response = getRangerAdminPolicyDownloadResponse(lastKnownVersion, lastActivationTimeInMillis, user, isSecureMode); int httpResponseCode = response == null ? -1 : response.getStatus(); @@ -604,7 +604,7 @@ private ServicePolicies getServicePoliciesIfUpdatedWithCookie(final long lastKno final ServicePolicies ret; final UserGroupInformation user = MiscUtil.getUGILoginUser(); - final boolean isSecureMode = isKerberosEnabled(user); + final boolean isSecureMode = user != null && UserGroupInformation.isSecurityEnabled(); final Response response = getRangerAdminPolicyDownloadResponse(lastKnownVersion, lastActivationTimeInMillis, user, isSecureMode); int httpResponseCode = response == null ? -1 : response.getStatus(); @@ -754,7 +754,7 @@ private ServiceTags getServiceTagsIfUpdatedWithCred(final long lastKnownVersion, final ServiceTags ret; final UserGroupInformation user = MiscUtil.getUGILoginUser(); - final boolean isSecureMode = isKerberosEnabled(user); + final boolean isSecureMode = user != null && UserGroupInformation.isSecurityEnabled(); final Response response = getTagsDownloadResponse(lastKnownVersion, lastActivationTimeInMillis, user, isSecureMode); int httpResponseCode = response == null ? -1 : response.getStatus(); @@ -820,7 +820,7 @@ private ServiceTags getServiceTagsIfUpdatedWithCookie(final long lastKnownVersio final ServiceTags ret; final UserGroupInformation user = MiscUtil.getUGILoginUser(); - final boolean isSecureMode = isKerberosEnabled(user); + final boolean isSecureMode = user != null && UserGroupInformation.isSecurityEnabled(); final Response response = getTagsDownloadResponse(lastKnownVersion, lastActivationTimeInMillis, user, isSecureMode); int httpResponseCode = response == null ? -1 : response.getStatus(); @@ -968,7 +968,7 @@ private RangerRoles getRangerRolesIfUpdatedWithCred(final long lastKnownRoleVers final RangerRoles ret; final UserGroupInformation user = MiscUtil.getUGILoginUser(); - final boolean isSecureMode = isKerberosEnabled(user); + final boolean isSecureMode = user != null && UserGroupInformation.isSecurityEnabled(); final Response response = getRoleDownloadResponse(lastKnownRoleVersion, lastActivationTimeInMillis, user, isSecureMode); int httpResponseCode = response == null ? -1 : response.getStatus(); @@ -1034,7 +1034,7 @@ private RangerRoles getRangerRolesIfUpdatedWithCookie(final long lastKnownRoleVe final RangerRoles ret; final UserGroupInformation user = MiscUtil.getUGILoginUser(); - final boolean isSecureMode = isKerberosEnabled(user); + final boolean isSecureMode = user != null && UserGroupInformation.isSecurityEnabled(); final Response response = getRoleDownloadResponse(lastKnownRoleVersion, lastActivationTimeInMillis, user, isSecureMode); int httpResponseCode = response == null ? -1 : response.getStatus(); diff --git a/plugin-nestedstructure/.gitignore b/plugin-nestedstructure/.gitignore deleted file mode 100644 index b83d22266a..0000000000 --- a/plugin-nestedstructure/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target/ diff --git a/plugin-nestedstructure/LICENSE b/plugin-nestedstructure/LICENSE deleted file mode 100644 index d645695673..0000000000 --- a/plugin-nestedstructure/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed 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. diff --git a/plugin-nestedstructure/NOTICE b/plugin-nestedstructure/NOTICE deleted file mode 100644 index 8772a4fba1..0000000000 --- a/plugin-nestedstructure/NOTICE +++ /dev/null @@ -1,18 +0,0 @@ -Apache Ranger Nestedstructure Plugin - -Copyright 2022 Comcast Cable Communications Management, LLC - -Licensed 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. -S -PDX-License-Identifier: Apache-2.0 - -This product includes software developed at Comcast (http://www.comcast.com/). diff --git a/plugin-nestedstructure/README.md b/plugin-nestedstructure/README.md deleted file mode 100644 index ea878f6a27..0000000000 --- a/plugin-nestedstructure/README.md +++ /dev/null @@ -1,168 +0,0 @@ - - -# ranger-api-plugin - -## License -Licensed under the Apache License, Version 2.0. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - -## Usage - -Simply call `NestedStructureAuthorizer.authorize()` to determine if the user has access to the JSON record and fields. -The result will indicate if the user is authorized. The result also contains the JSON string the user is authorized view, for example by masking fields as specified in Apache Ranger policies. -```java -String schema = "json_object.cxt.cmt.product.vnull3"; -String userName = "beckma200"; -Set userGroups = new HashSet<>(); -String jsonString = ...; - -AccessResult result = NestedStructureAuthorizer.getInstance().authorize(schema, userName, userGroups, jsonString, NestedStructureAccessType.READ); - -String authorizedJsonString = result.hasAccess() ? result.getJson() : null; -``` - -An example client is included at `org.apache.ranger.authorization.nestedstructure.authorizer.ExampleClient` - -## Configuration Items -The classpath needs to contain 3 files, `ranger-nestedstructure-audit.xml`, -`ranger-nestedstructure-policymgr-ssl.xml`, and `ranger-nestedstructure-security.xml`. -Each of these files need to edited in each deployment. -Other required files do not need edits and are included in the jar file. - -**ranger-nestedstructure-security.xml** -- `ranger.plugin.nestedstructure.policy.rest.url` should be set to the correct audit location (prod vs integration). - - -**ranger-nestedstructure-audit.xml** -- `xasecure.audit.destination.solr.urls` should be set to the correct audit location (prod vs integration). - -**ranger-nestedstructure-policymgr-ssl.xml** -- `xasecure.policymgr.clientssl.keystore` should be set to location of the `ranger-plugin-keystore.p12` file. -- `xasecure.policymgr.clientssl.keystore.credential.file` should be set to the location of `ranger.jceks` file. -- `xasecure.policymgr.clientssl.truststore` should be set to location of the `global-truststore.p12` file. -- `xasecure.policymgr.clientssl.truststore.credential.file` should be set to the location of the `ranger.jceks` file. - - -## Example of Permissions of Masking Different Fields - -```json -{ - "store": { - "book": [ - { - "category": "reference", - "author": "Nigel Rees", - "title": "Sayings of the Century", - "price": 8.95 - }, - { - "category": "fiction", - "author": "Evelyn Waugh", - "title": "Sword of Honour", - "price": 12.99 - }, - { - "category": "fiction", - "author": "Herman Melville", - "title": "Moby Dick", - "isbn": "0-553-21311-3", - "price": 8.99 - }, - { - "category": "fiction", - "author": "J. R. R. Tolkien", - "title": "The Lord of the Rings", - "isbn": "0-395-19395-8", - "price": 22.99 - } - ], - "bicycle": { - "color": "red", - "price": 19.95 - } - }, - "expensive": 10 -} -``` - -##### Arrays -Arrays require the user to specify that all elements of the array should be considered. The addition of an asterisk `*` is required. -To restrict by book price, specify one of the following values in Apache Ranger Policy for resource `field`: - -- `store.book[*]price < 100` -- `store.book.*.price < 100` - -##### Maps -Simple dot `.` syntax is all that is required. -To restrict the color of the bicycle use in Ranger -`store.bicycle.color` - -### Masking -Only primitive types (numbers, booleans, and strings) can be masked. -Elements inside arrays and maps will be masked at a field level. - -Note that at this time, masking a container is NOT possible. Each element has to be individually masked. - -If the mask type is not applicable to the datatype, a default mask of `NULL` will be used. - -#### Mask Types -* MASK - * Replaces entire String with `*`. - * Replaces Number with `-11111` - * Ensures resulting String has length of 5 of more - * Replaces Booleans with false - * Supported types: String, Boolean, Number -* MASK_SHOW_LAST_4 - * Replaces all but the last four characters of a string with `x` - * Supported types: String -* MASK_SHOW_FIRST_4 - * Replaces all except the first four characters of a string with `x` - * Supported types: String -* MASK_HASH - * Replaces string with a SHA256 hash of the string - * Supported types: String -* CUSTOM - * Replaces value with a custom specified value of the same type - * Supported types: String, Boolean, Number -* MASK_NULL - * Replaces value with `null` - * Supported types: String, Boolean, Number -* MASK_NONE - * Returns the value without changing it - * Supported types: String, Boolean, Number -* MASK_DATE_SHOW_YEAR - * Replaces a parsable date with only the year parsed from the date. - * The table below lists the supported date formats. - * For more information on date formats see [DateFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html) documentation. - * - - - - - - - - - - - - - -
FormatDescriptionExample
BASIC_ISO_DATEBasic ISO date'20111203'
ISO_LOCAL_DATE ISOLocal Date'2011-12-03'
ISO_OFFSET_DATEISO Date with offset''2011-12-03+01:00'
ISO_DATEISO Date with or without offset'2011-12-03+01:00'; '2011-12-03'
ISO_LOCAL_DATE_TIMEISO Local Date and Time'2011-12-03T10:15:30'
ISO_OFFSET_DATE_TIMEDate Time with Offset'2011-12-03T10:15:30+01:00'
ISO_ZONED_DATE_TIMEZoned Date Time'2011-12-03T10:15:30+01:00[Europe/Paris]'
ISO_DATE_TIMEDate and time with ZoneId'2011-12-03T10:15:30+01:00[Europe/Paris]'
ISO_ORDINAL_DATEYear and day of year/td>'2012-337'
ISO_WEEK_DATEYear and Week'2012-W48-6'
ISO_INSTANTDate and Time of an Instant'2011-12-03T10:15:30Z'
RFC_1123_DATE_TIMERFC 1123 / RFC 822'Tue, 3 Jun 2008 11:05:30 GMT'
- diff --git a/plugin-nestedstructure/conf/log4j.properties b/plugin-nestedstructure/conf/log4j.properties deleted file mode 100644 index f01052b343..0000000000 --- a/plugin-nestedstructure/conf/log4j.properties +++ /dev/null @@ -1,37 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -log4j.rootLogger=WARN,CONSOLE,ROLLING - -#log4j.logger.org.apache=WARN -#log4j.logger.org.omg=WARN -#log4j.logger.com.amazonaws.services.kinesis=DEBUG - -log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender -log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout - -# Pattern to output the caller's file name and line number. -log4j.appender.CONSOLE.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n - -log4j.appender.ROLLING=org.apache.log4j.RollingFileAppender -log4j.appender.ROLLING.File=kvs-gateway.log - -log4j.appender.ROLLING.MaxFileSize=100MB -# Keep one backup file -log4j.appender.ROLLING.MaxBackupIndex=1 - -log4j.appender.ROLLING.layout=org.apache.log4j.PatternLayout -log4j.appender.ROLLING.layout.ConversionPattern=%p %t %c - %m%n - diff --git a/plugin-nestedstructure/conf/ranger-nestedstructure-audit.xml b/plugin-nestedstructure/conf/ranger-nestedstructure-audit.xml deleted file mode 100644 index 9eb0b22f6b..0000000000 --- a/plugin-nestedstructure/conf/ranger-nestedstructure-audit.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - xasecure.audit.destination.solr - true - - - xasecure.audit.destination.solr.async.max.queue.size - 100 - - - xasecure.audit.destination.solr.async.max.flush.interval.ms - 1000 - - - xasecure.audit.destination.solr.ssl.checkPeerName - false - - - xasecure.audit.destination.solr.urls - - - \ No newline at end of file diff --git a/plugin-nestedstructure/conf/ranger-nestedstructure-policymgr-ssl.xml b/plugin-nestedstructure/conf/ranger-nestedstructure-policymgr-ssl.xml deleted file mode 100644 index 092546f537..0000000000 --- a/plugin-nestedstructure/conf/ranger-nestedstructure-policymgr-ssl.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - xasecure.policymgr.clientssl.keystore - /var/ranger/security/ranger-plugin-keystore.p12 - - - xasecure.policymgr.clientssl.keystore.credential.file - jceks://file/var/ranger/security/ranger.jceks - - - xasecure.policymgr.clientssl.keystore.password - none - - - xasecure.policymgr.clientssl.keystore.type - pkcs12 - - - xasecure.policymgr.clientssl.truststore - /var/ranger/security/global-truststore.p12 - - - xasecure.policymgr.clientssl.truststore.credential.file - jceks://file/var/ranger/security/ranger.jceks - - - xasecure.policymgr.clientssl.truststore.password - none - - - xasecure.policymgr.clientssl.truststore.type - pkcs12 - - \ No newline at end of file diff --git a/plugin-nestedstructure/conf/ranger-nestedstructure-security.xml b/plugin-nestedstructure/conf/ranger-nestedstructure-security.xml deleted file mode 100644 index 9be584186b..0000000000 --- a/plugin-nestedstructure/conf/ranger-nestedstructure-security.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - ranger.plugin.nestedstructure.policy.rest.url - - - URL to Ranger Admin - - - - ranger.plugin.nestedstructure.service.name - privacera_nestedstructure - - Name of the Ranger service containing policies for this SampleApp instance - - - - ranger.plugin.nestedstructure.policy.source.impl - org.apache.ranger.admin.client.RangerAdminRESTClient - - Class to retrieve policies from the source - - - - ranger.plugin.nestedstructure.policy.cache.dir - /tmp - - Directory where Ranger policies are cached after successful retrieval from the source - - - - ranger.plugin.nestedstructure.policy.rest.client.connection.timeoutMs - 120000 - - RangerRestClient Connection Timeout in Milli Seconds - - - - ranger.plugin.nestedstructure.policy.rest.client.read.timeoutMs - 30000 - - RangerRestClient read Timeout in Milli Seconds - - - \ No newline at end of file diff --git a/plugin-nestedstructure/pom.xml b/plugin-nestedstructure/pom.xml deleted file mode 100644 index 63f57ea061..0000000000 --- a/plugin-nestedstructure/pom.xml +++ /dev/null @@ -1,111 +0,0 @@ - - - - - ranger - org.apache.ranger - 3.0.0-SNAPSHOT - - 4.0.0 - - ranger-nestedstructure-plugin - NestedStructure Security Plugin - NestedStructure Security Plugin - jar - - - 8 - 8 - - - - - org.apache.ranger - ranger-plugins-common - ${project.version} - - - commons-codec - commons-codec - 1.11 - - - commons-lang - commons-lang - 2.6 - - - commons-logging - commons-logging - 1.1.1 - - - org.apache.logging.log4j - log4j-core - ${log4j2.version} - - - com.google.code.gson - gson - ${gson.version} - compile - - - com.jayway.jsonpath - json-path - 2.4.0 - - - org.openjdk.nashorn - nashorn-core - 15.4 - - - org.testng - testng - ${testng.version} - test - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven.surefire.plugin.version} - - - org.apache.maven.plugins - maven-compiler-plugin - 3.3 - true - - false - ${javac.source.version} - ${javac.target.version} - UTF-8 - 1024m - true - - - - - diff --git a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/AccessResult.java b/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/AccessResult.java deleted file mode 100644 index bf4a32501a..0000000000 --- a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/AccessResult.java +++ /dev/null @@ -1,54 +0,0 @@ -/** -* Copyright 2022 Comcast Cable Communications Management, LLC -* -* Licensed 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. -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -package org.apache.ranger.authorization.nestedstructure.authorizer; - -import java.util.ArrayList; -import java.util.List; - -/** - * The response of the API when checking for authorizing and masking fields that are not authorized. - **/ -public class AccessResult { - private final boolean hasAccess; - private final String json; - private final List errors = new ArrayList<>(); - - public AccessResult(boolean hasAccess, String json) { - this.hasAccess = hasAccess; - this.json = json; - } - - public boolean hasAccess() { - return hasAccess; - } - - public String getJson() { - return json; - } - - public boolean hasErrors() { return errors.size() > 0; } - - public AccessResult addError(Exception e){ - errors.add(e); - - return this; - } - - public List getErrors() { return errors; } -} diff --git a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/DataMasker.java b/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/DataMasker.java deleted file mode 100644 index f630799b0d..0000000000 --- a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/DataMasker.java +++ /dev/null @@ -1,283 +0,0 @@ -/** -* Copyright 2022 Comcast Cable Communications Management, LLC -* -* Licensed 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. -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -package org.apache.ranger.authorization.nestedstructure.authorizer; - -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.commons.lang.StringUtils; - -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; -import java.time.temporal.TemporalAccessor; -import java.util.Arrays; -import java.util.List; - -/** - * Masks the 3 primitive types of json: strings, numbers, and booleans - * Not all mask types are supported on each type. For example hashing a boolean doesn't make sense. - * When masking dates, a subset of the date formats defined in {@link DateTimeFormatter} are allowed. - * See DataMasker.SUPPORTED_DATE_FORMATS for the list of supported formats. - */ -public class DataMasker { - /** - * The default numberic value when masking and no other value is defined. - */ - static final Number DEFAULT_NUMBER_MASK = new Long(-11111); - - /** - * The default boolean value when masking and no other value is defined. - */ - static final Boolean DEFAULT_BOOLEAN_MASK = false; - - /** - * A list of the supported date formats that can be masked. - */ - static final List SUPPORTED_DATE_FORMATS; - - static { - SUPPORTED_DATE_FORMATS = Arrays.asList( - DateTimeFormatter.BASIC_ISO_DATE, - DateTimeFormatter.ISO_LOCAL_DATE, - DateTimeFormatter.ISO_OFFSET_DATE, - DateTimeFormatter.ISO_DATE, - DateTimeFormatter.ISO_LOCAL_DATE_TIME, - DateTimeFormatter.ISO_OFFSET_DATE_TIME, - DateTimeFormatter.ISO_ZONED_DATE_TIME, - DateTimeFormatter.ISO_DATE_TIME, - DateTimeFormatter.ISO_ORDINAL_DATE, - DateTimeFormatter.ISO_WEEK_DATE, - DateTimeFormatter.ISO_INSTANT, - DateTimeFormatter.RFC_1123_DATE_TIME - ); - } - - /** - * Masks a boolean value if applicable - * @param value input value - * @param maskType type of masking - * @param customMaskValueStr string representation of a boolean if applicable - * @return the masked value - */ - public static Boolean maskBoolean(Boolean value, String maskType, String customMaskValueStr) { - if (maskType == null){ - throw new MaskingException("boolean doesn't support mask type: " + maskType); - } - - final Boolean ret; - - switch (maskType) { - case MaskTypes.MASK: - ret = DEFAULT_BOOLEAN_MASK; - break; - - case MaskTypes.MASK_NULL: - // replace with NULL - ret = null; - break; - - case MaskTypes.MASK_NONE: - // noop, same as no mask - ret = value; - break; - - case MaskTypes.CUSTOM: { - Boolean customMaskValue = DEFAULT_BOOLEAN_MASK; - - try { - customMaskValue = Boolean.parseBoolean(customMaskValueStr); - } catch (Exception e) { - // ignore - } - - // already done by the policy - ret = customMaskValue; - } - break; - - default: - // raise error, error message "unknown mask type" - throw new MaskingException("boolean doesn't support mask type: " + maskType); - } - - return ret; - } - - /** - * Masks a number value if applicable - * @param value input value of the number - * @param maskType type of masking - * @param customMaskValueStr string representation of a number if application - * @return the masked value - */ - public static Number maskNumber(Number value, String maskType, String customMaskValueStr) { - if (maskType == null){ - throw new MaskingException("number doesn't support mask type: " + maskType); - } - - final Number ret; - - switch (maskType) { - case MaskTypes.MASK: - ret= DEFAULT_NUMBER_MASK; - break; - - case MaskTypes.MASK_NULL: - // replace with NULL - ret = null; - break; - - case MaskTypes.MASK_NONE: - // noop, same as no mask - ret = value; - break; - - case MaskTypes.CUSTOM: { - try { - ret = Long.parseLong(customMaskValueStr); - } catch (Exception e) { - throw new MaskingException("unable to extract number from custom mask value: " + customMaskValueStr, e); - } - } - break; - - default: - // raise error, error message "unknown mask type" - throw new MaskingException("number doesn't support mask type: " + maskType); - } - - return ret; - } - - /** - * Masks a string value if applicable - * @param value the input value of the string - * @param maskType type of masking - * @param customMaskValue string value if using custom masking - * @return the masked value - */ - public static String maskString(String value, String maskType, String customMaskValue) { - if (maskType == null){ - throw new MaskingException("string doesn't support mask type: " + maskType); - } - - final String ret; - - switch (maskType) { - case MaskTypes.MASK: - ret = generateMask(value); - break; - - case MaskTypes.MASK_SHOW_LAST_4: - // "Show last 4 characters; replace rest with 'x'" - ret = showLastFour(value); - break; - - case MaskTypes.MASK_SHOW_FIRST_4: - // "Show first 4 characters; replace rest with 'x'", - ret = showFirstFour(value); - break; - - case MaskTypes.MASK_HASH: - // "Hash the value" - //can't hash null, so give it a consistent null string to hash - ret = DigestUtils.sha256Hex(value == null ? "null" : value); - break; - - case MaskTypes.MASK_NULL: - // replace with NULL - ret = null; - break; - - case MaskTypes.MASK_NONE: - // noop, same as no mask - ret = value; - break; - - case MaskTypes.MASK_DATE_SHOW_YEAR: - //"Date: show only year", - ret = maskYear(value); - break; - - case MaskTypes.CUSTOM: - // already done by the policy - ret = customMaskValue; - break; - - default: - // raise error, error message "unknown mask type" - throw new MaskingException("string doesn't support mask type: " + maskType); - } - - return ret; - } - - private static String generateMask(String value) { - // to do : take an object as param, identify whether it's an array, string or number; - // number return -1111111111; array : mask each element - //number of **** will be between MIN and MAX MASK LENGTH - int maskedValueLen = StringUtils.length(value); - - if (maskedValueLen < MaskTypes.MIN_MASK_LENGTH) { - maskedValueLen = MaskTypes.MIN_MASK_LENGTH; - } else if (maskedValueLen > MaskTypes.MAX_MASK_LENGTH) { - maskedValueLen = MaskTypes.MAX_MASK_LENGTH; - } - - return StringUtils.repeat("*", maskedValueLen); - } - - private static String showLastFour(String value){ - int length = StringUtils.length(value); - - return length <= 4 ? value : StringUtils.repeat("x", length - 4) + value.substring(length - 4); - } - - private static String showFirstFour(String value){ - int length = StringUtils.length(value); - - return length <= 4 ? value : value.substring(0, 4) + StringUtils.repeat("x", length - 4); - } - - private static String maskYear(String value){ - String ret = null; - - if (StringUtils.isEmpty(value)) { - ret = value; - } else { - for (DateTimeFormatter dateFormat : SUPPORTED_DATE_FORMATS) { - try { - TemporalAccessor temporalAccessor = dateFormat.parse(value); - LocalDate localDateTime = LocalDate.from(temporalAccessor); - - ret = localDateTime.format(DateTimeFormatter.ofPattern("yyyy")); - - break; - } catch (Exception e) { - // ignore - } - } - - if (ret == null) { - throw new MaskingException("Unable to mask year, unsupported date format: " + value + - ". See documentation for supported date formats."); - } - } - - return ret; - } -} diff --git a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/FieldLevelAccess.java b/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/FieldLevelAccess.java deleted file mode 100644 index 0d27d36ec1..0000000000 --- a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/FieldLevelAccess.java +++ /dev/null @@ -1,62 +0,0 @@ -/** -* Copyright 2022 Comcast Cable Communications Management, LLC -* -* Licensed 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. -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -package org.apache.ranger.authorization.nestedstructure.authorizer; - -/** - * An internal structure. It notes if a specific field is authorized, is masked and what type of masking it is. - * If written in scala, this would have been a case class. - **/ -class FieldLevelAccess { - final String field; - final boolean hasAccess; - final Long maskPolicyId; - final boolean isMasked; - final String customMaskedValue; - final String maskType; - - public FieldLevelAccess(String field, boolean hasAccess, Long maskPolicyId, boolean isMasked, - String maskType, String customMaskedValue) { - this.field = field; - this.hasAccess = hasAccess; - this.maskPolicyId = maskPolicyId; - this.isMasked = isMasked; - this.maskType = maskType; - this.customMaskedValue = customMaskedValue; - } - - public String getCustomMaskedValue() { - return customMaskedValue; - } - - public String getField() { - return field; - } - - public boolean isHasAccess() { - return hasAccess; - } - - public Long getMaskPolicyId() { - return maskPolicyId; - } - - public boolean isMasked() { - return isMasked; - } -} diff --git a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/JsonManipulator.java b/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/JsonManipulator.java deleted file mode 100644 index 57030f277f..0000000000 --- a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/JsonManipulator.java +++ /dev/null @@ -1,168 +0,0 @@ -/** -* Copyright 2022 Comcast Cable Communications Management, LLC -* -* Licensed 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. -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -package org.apache.ranger.authorization.nestedstructure.authorizer; - -import com.google.gson.JsonParser; -import com.google.gson.JsonSyntaxException; -import com.jayway.jsonpath.Configuration; -import com.jayway.jsonpath.DocumentContext; -import com.jayway.jsonpath.JsonPath; -import com.jayway.jsonpath.Option; - - -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -/** -* Accepts a json string, parses it into a {@link DocumentContext}. - * Individual fields can be updated in the {@link DocumentContext}. - * And a new json string can be obtained. -**/ -public class JsonManipulator { - /** - the overall document - **/ - private final DocumentContext documentContext; - - /** - a {@link DocumentContext} that specializes in returning field names (not values) - **/ - private final DocumentContext fieldContextDocument; - - private final Set fields; - - - /** - * - * @param jsonString json to be parsed and masked - */ - public JsonManipulator(String jsonString) { - checkIsValidJson(jsonString); - - documentContext = JsonPath.parse(jsonString); - - //"$..*" - give me everything - Configuration conf = Configuration.builder().options(Option.AS_PATH_LIST).build(); - - fieldContextDocument = JsonPath.using(conf).parse(jsonString); - - List leafPathList = fieldContextDocument.read("$..*"); - - //remove non-leaf nodes from the list - //if element n starts with element n-1, then n-1 is a leaf node and should be removed - Collections.sort(leafPathList); - - List filteredList = new ArrayList<>(); - - for (int i = 0; i < leafPathList.size(); i++) { - String current = leafPathList.get(i); - - if ((i + 1) < leafPathList.size()) { - String next = leafPathList.get(i + 1); - - if (!next.startsWith(current)) { - filteredList.add(current); - } - } else { - filteredList.add(current); - } - } - - leafPathList = filteredList; - - Stream newList = leafPathList.stream().map(path -> { - return path.replaceAll("\\[[0-9]+\\]", ".*") //removes "[0]" replaces with .* - .replaceAll("\\$\\['", "") //removes "$['" - .replaceAll("'\\]\\['", ".") //removes "']['" - .replaceAll("\\*\\['", "*.") //removes *[' - .replaceAll("'\\]", ""); //removes trailing "']" - }); - - fields = newList.collect(Collectors.toSet()); - } - - /** - * - * @return The names of all the edge fields in the {@link DocumentContext}. - * Note that is a value is nested (ie it is of type map) that it is not returned. - * For example if the full field set was Set(address, address.city, address.street, address.state), - * only Set(address.city, address.street, address.state) would be returned - */ - public Set getFields() { return fields; } - - /** - * Does the actual masking of values. - * @param fieldAccess - */ - public void maskFields(List fieldAccess){ - Stream maskedFields = fieldAccess.stream().filter(fa -> fa.hasAccess && fa.isMasked); - - maskedFields.forEach(fa -> { - //System.out.println( " attribute " + fa.field + " masked ? " + (fa.isMasked? "yes":"no")); - - getMatchingFields(fa.field).forEach(fullFieldPath -> { - final Object realValue = documentContext.read(fullFieldPath); - final Object maskedValue; - - //I know I could use polymorphism to not have different methods - //but I prefer the readability and the clarity of different method names - if (realValue instanceof String) { - maskedValue = DataMasker.maskString((String)realValue, fa.maskType, fa.customMaskedValue); - } else if (realValue instanceof Number) { - maskedValue = DataMasker.maskNumber((Number)realValue, fa.maskType, fa.customMaskedValue); - } else if (realValue instanceof Boolean) { - maskedValue = DataMasker.maskBoolean((Boolean)realValue, fa.maskType, fa.customMaskedValue); - } else { - throw new MaskingException("unable to determine field type: " + realValue); - } - - documentContext.set(fullFieldPath, maskedValue); - }); - }); - } - - /** - * @return the current/updated json string of the {@link DocumentContext} that is being worked on - */ - public String getJsonString(){return documentContext.jsonString();} - - - /** - * Used for testing - * @param fullPath - * @return the value at a specific path - */ - String readString(String fullPath){ - return documentContext.read(fullPath).toString(); - } - - private void checkIsValidJson(String jsonString) { - try { - JsonParser.parseString(jsonString); // throws JsonSyntaxException - } catch (JsonSyntaxException e) { - throw new MaskingException("invalid input json; unable to mask", e); - } - } - - private List getMatchingFields(String fieldPath){ - return fieldContextDocument.read("$."+fieldPath); - } -} - diff --git a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/MaskTypes.java b/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/MaskTypes.java deleted file mode 100644 index 6464cfc06e..0000000000 --- a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/MaskTypes.java +++ /dev/null @@ -1,54 +0,0 @@ -/** -* Copyright 2022 Comcast Cable Communications Management, LLC -* -* Licensed 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. -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -package org.apache.ranger.authorization.nestedstructure.authorizer; - -/** - * Defines the types of masks that are supported. - */ -public interface MaskTypes { - String MASK = "MASK"; - String MASK_SHOW_LAST_4 = "MASK_SHOW_LAST_4"; - String MASK_SHOW_FIRST_4 = "MASK_SHOW_FIRST_4"; - String MASK_HASH = "MASK_HASH"; - String MASK_NULL = "MASK_NULL"; - String MASK_NONE = "MASK_NONE"; - String MASK_DATE_SHOW_YEAR = "MASK_DATE_SHOW_YEAR"; - String CUSTOM = "CUSTOM"; - int MIN_MASK_LENGTH = 5; - int MAX_MASK_LENGTH = 30; - - /** - * These formats can be masked into yyyy, '2012' - - - - - - - - - - - - - - -
FormatDescriptionExample
BASIC_ISO_DATEBasic ISO date'20111203'
ISO_LOCAL_DATE ISOLocal Date'2011-12-03'
ISO_OFFSET_DATEISO Date with offset''2011-12-03+01:00'
ISO_DATEISO Date with or without offset'2011-12-03+01:00'; '2011-12-03'
ISO_LOCAL_DATE_TIMEISO Local Date and Time'2011-12-03T10:15:30'
ISO_OFFSET_DATE_TIMEDate Time with Offset'2011-12-03T10:15:30+01:00'
ISO_ZONED_DATE_TIMEZoned Date Time'2011-12-03T10:15:30+01:00[Europe/Paris]'
ISO_DATE_TIMEDate and time with ZoneId'2011-12-03T10:15:30+01:00[Europe/Paris]'
ISO_ORDINAL_DATEYear and day of year/td>'2012-337'
ISO_WEEK_DATEYear and Week'2012-W48-6'
ISO_INSTANTDate and Time of an Instant'2011-12-03T10:15:30Z'
RFC_1123_DATE_TIMERFC 1123 / RFC 822'Tue, 3 Jun 2008 11:05:30 GMT'
- */ -} diff --git a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/MaskingException.java b/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/MaskingException.java deleted file mode 100644 index 316973db7f..0000000000 --- a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/MaskingException.java +++ /dev/null @@ -1,32 +0,0 @@ -/** -* Copyright 2022 Comcast Cable Communications Management, LLC -* -* Licensed 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. -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -package org.apache.ranger.authorization.nestedstructure.authorizer; - -/** - * The most common {@link Exception} this project throws. - **/ -public class MaskingException extends RuntimeException { - public MaskingException(String message){ - super(message); - } - - public MaskingException(String message, Exception e) { - super(message, e); - } -} diff --git a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/NestedStructureAccessType.java b/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/NestedStructureAccessType.java deleted file mode 100644 index 92f0990514..0000000000 --- a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/NestedStructureAccessType.java +++ /dev/null @@ -1,45 +0,0 @@ -/** -* Copyright 2022 Comcast Cable Communications Management, LLC -* -* Licensed 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. -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -package org.apache.ranger.authorization.nestedstructure.authorizer; - -import org.apache.commons.lang3.StringUtils; - -public enum NestedStructureAccessType { - READ("read"), - WRITE("write"); - - private final String value; - - public static NestedStructureAccessType getAccessType(String name) { - for (NestedStructureAccessType accessType : NestedStructureAccessType.values()) { - if (StringUtils.equalsIgnoreCase(accessType.value, name) || - StringUtils.equalsIgnoreCase(accessType.name(), name)) { - return accessType; - } - } - - return null; - } - - NestedStructureAccessType(String value) { - this.value = value; - } - - public String getValue() { return value; } -} diff --git a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/NestedStructureAuditHandler.java b/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/NestedStructureAuditHandler.java deleted file mode 100644 index 1203ee2c15..0000000000 --- a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/NestedStructureAuditHandler.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.ranger.authorization.nestedstructure.authorizer; - -import org.apache.hadoop.conf.Configuration; -import org.apache.ranger.audit.model.AuthzAuditEvent; -import org.apache.ranger.plugin.audit.RangerDefaultAuditHandler; -import org.apache.ranger.plugin.model.RangerPolicy; -import org.apache.ranger.plugin.policyengine.RangerAccessResult; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -public class NestedStructureAuditHandler extends RangerDefaultAuditHandler { - public static final String ACCESS_TYPE_ROWFILTER = "ROW_FILTER"; - - List auditEvents = null; - boolean deniedExists = false; - - public NestedStructureAuditHandler(Configuration config) { - super(config); - } - - @Override - public void processResult(RangerAccessResult result) { - if (result.getIsAudited()) { - AuthzAuditEvent auditEvent = createAuditEvent(result); - - if (auditEvent != null) { - if (auditEvents == null) { - auditEvents = new ArrayList<>(); - } - - auditEvents.add(auditEvent); - - if (auditEvent.getAccessResult() == 0) { - deniedExists = true; - } - } - } - } - - @Override - public void processResults(Collection results) { - for (RangerAccessResult result : results) { - processResult(result); - } - } - - public void flushAudit() { - if (auditEvents != null) { - for (AuthzAuditEvent auditEvent : auditEvents) { - if (deniedExists && auditEvent.getAccessResult() != 0) { // if deny exists, skip logging for allowed results - continue; - } - - super.logAuthzAudit(auditEvent); - } - } - } - - private AuthzAuditEvent createAuditEvent(RangerAccessResult result) { - AuthzAuditEvent ret = super.getAuthzEvents(result); - - if (ret != null) { - int policyType = result.getPolicyType(); - - if (policyType == RangerPolicy.POLICY_TYPE_DATAMASK && result.isMaskEnabled()) { - ret.setAccessType(result.getMaskType()); - } else if (policyType == RangerPolicy.POLICY_TYPE_ROWFILTER) { - ret.setAccessType(ACCESS_TYPE_ROWFILTER); - } - } - - return ret; - } -} diff --git a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/NestedStructureAuthorizer.java b/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/NestedStructureAuthorizer.java deleted file mode 100644 index bd2f509e78..0000000000 --- a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/NestedStructureAuthorizer.java +++ /dev/null @@ -1,285 +0,0 @@ -/** -* Copyright 2022 Comcast Cable Communications Management, LLC -* -* Licensed 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. -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -package org.apache.ranger.authorization.nestedstructure.authorizer; - -import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig; -import org.apache.ranger.plugin.policyengine.RangerAccessRequest; -import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl; -import org.apache.ranger.plugin.policyengine.RangerAccessResult; -import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions; -import org.apache.ranger.plugin.service.RangerBasePlugin; -import org.apache.ranger.plugin.util.RangerRoles; -import org.apache.ranger.plugin.util.ServicePolicies; -import org.apache.ranger.plugin.util.ServiceTags; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.Set; - -public class NestedStructureAuthorizer { - static private final Logger logger = LoggerFactory.getLogger(NestedStructureAuthorizer.class); - - private static final String RANGER_CMT_SERVICETYPE = "nestedstructure"; - private static final String RANGER_CMT_APPID = "nestedstructure"; - - private static volatile NestedStructureAuthorizer instance; - - private final RangerBasePlugin plugin; - - private NestedStructureAuthorizer() { - plugin = new RangerBasePlugin(RANGER_CMT_SERVICETYPE, RANGER_CMT_APPID); - - plugin.init(); - } - - // for testing purpose only - public NestedStructureAuthorizer(ServicePolicies policies, ServiceTags tags, RangerRoles roles) { - RangerPolicyEngineOptions options = new RangerPolicyEngineOptions(); - - options.disablePolicyRefresher = true; - options.disableUserStoreRetriever = true; - options.disableTagRetriever = true; - - RangerPluginConfig pluginConfig = new RangerPluginConfig(RANGER_CMT_SERVICETYPE, policies.getServiceName(), RANGER_CMT_APPID, null, null, options); - - plugin = new RangerBasePlugin(pluginConfig, policies, tags, roles); - } - - public static NestedStructureAuthorizer getInstance() { - NestedStructureAuthorizer ret = NestedStructureAuthorizer.instance; - - if (ret == null) { - synchronized (NestedStructureAuthorizer.class) { - ret = NestedStructureAuthorizer.instance; - - if (ret == null) { - NestedStructureAuthorizer.instance = ret = new NestedStructureAuthorizer(); - } - } - } - - return ret; - } - - /** - * - * @param schema atlas schema name - * @param user atlas user name - * @param userGroups atlas user groups - * @param json the json of the record to be evaluated - * @param accessType access type requested; must be included in NestedStructureAccessType. - * @return if the user is authorized to access this data. If there is no authorization, null is returned. - * If there is partial authorization, a modified/masked json blob is returned - */ - public AccessResult authorize(String schema, String user, Set userGroups, String json, NestedStructureAccessType accessType) { - AccessResult ret; - - NestedStructureAuditHandler auditHandler = new NestedStructureAuditHandler(plugin.getConfig()); - - try { - ret = privateAuthorize(schema, user, userGroups, json, accessType, auditHandler); - } catch (Exception e) { - logger.warn("exception during processing, user: " + user + "\n json: " + json, e); - - ret = new AccessResult(false, null).addError(e); - } finally { - auditHandler.flushAudit(); - } - - return ret; - } - - private AccessResult privateAuthorize(String schema, String user, Set userGroups, String json, NestedStructureAccessType accessType, NestedStructureAuditHandler auditHandler) { - final AccessResult ret; - - if (!hasAccessToSchemaOrAnyField(schema, user, userGroups, accessType, auditHandler)) { - ret = new AccessResult(false, null); - } else if (!hasAccessToRecord(schema, user, userGroups, json, accessType, auditHandler)) { - ret = new AccessResult(false, null); - } else { - boolean accessDenied = false; - JsonManipulator jsonManipulator = new JsonManipulator(json); - List fieldResults = new ArrayList<>(); - - //check each field individually - both if the user has access and if so, what masking is required - for (String field : jsonManipulator.getFields()) { - FieldLevelAccess fieldAccess = hasFieldAccess(schema, user, userGroups, field, accessType, auditHandler); - - fieldResults.add(fieldAccess); - - if (!fieldAccess.hasAccess) { - accessDenied = true; - - break; - } - } - - //the user must have access to all fields. - // if the user doesn't have access to one of the fields return an empty/false AccessResult - if (accessDenied) { - ret = new AccessResult(false, null); - } else { - jsonManipulator.maskFields(fieldResults); - - ret = new AccessResult(true, jsonManipulator.getJsonString()); - } - } - - return ret; - } - - /** - * Checks to see that the user has access to the specific field in this schema - * @param schema atlas schema name - * @param user atlas user name - * @param userGroups atlas user groups - * @param fld field name - * @param accessType access type requested; must be included in NestedStructureAccessType. - * @return a pojo describing access level and masking - */ - private FieldLevelAccess hasFieldAccess(String schema, String user, Set userGroups, String fld, NestedStructureAccessType accessType, NestedStructureAuditHandler auditHandler) { - String atlasString = fld.replaceAll("\\.\\[\\*\\]\\.'", ".") //removes ".[*]." - .replaceAll("\\.\\*\\.", "."); //removes ".*." - - // RangerAccessResource fldResource = new NestedStructure_Resource(Optional.of("json_object.cxt.cmt.product.vnull3"), Optional.of("partner")); - NestedStructureResource resource = new NestedStructureResource(Optional.of(schema), Optional.of(atlasString)); - RangerAccessRequest request = new RangerAccessRequestImpl(resource, accessType.getValue(), user, userGroups, null); - RangerAccessResult result = plugin.isAccessAllowed(request, auditHandler); - - if (result == null){ - throw new MaskingException("unable to determine access"); - } - - boolean hasAccess = result.getIsAccessDetermined() && result.getIsAllowed(); - FieldLevelAccess ret; - - if (logger.isDebugEnabled()) { - logger.debug("checking at line 123 " + accessType + " access to " + schema + "." + fld + " as " + atlasString + " for user: " + user + - " has access ? " + (hasAccess ? "yes" : "no") + " policyId: " + result.getPolicyId()); - } - - if (!hasAccess) { - ret = new FieldLevelAccess(fld, hasAccess, -1L, true, null, null); - } else { - RangerAccessResult maskResult = plugin.evalDataMaskPolicies(request, null); - - if (maskResult == null) { - throw new MaskingException("unable to determine access"); - } - - boolean isMasked = maskResult.isMaskEnabled(); - Long maskPolicyId = maskResult.getPolicyId(); - - // generate audit log for masking only when masking is enabled for the field - if (isMasked) { - auditHandler.processResult(maskResult); - } - - if (logger.isDebugEnabled()) { - String maskPolicy = isMasked ? (" policyId: " + maskPolicyId) : ""; - - logger.debug("attribute " + fld + " as " + atlasString + " masked ? " + (isMasked ? "yes" : "no") + maskPolicy); - } - - ret = new FieldLevelAccess(fld, hasAccess, maskPolicyId, isMasked, maskResult.getMaskType(), maskResult.getMaskedValue()); - } - - return ret; - } - - /** - * record-level filtering of schema - * note that while determining the filter to apply for a table, Apache Ranger policy engine evaluates - * the policy-items in the order listed in the policy. The filter specified in the first policy-item - * that matches the access-request (i.e. user/groups) will be used in the query. - * @param schema atlas schema name - * @param user atlas user name - * @param userGroups atlas user groups - * @param jsonString the json payload that needs to be evaluated - * @param accessType access type requested; must be included in NestedStructureAccessType. - * @return if the user is authorized to view this particular record - */ - - private boolean hasAccessToRecord(String schema, String user, Set userGroups, String jsonString, NestedStructureAccessType accessType, NestedStructureAuditHandler auditHandler) { - boolean ret = true; - NestedStructureResource resource = new NestedStructureResource(Optional.of(schema)); - RangerAccessRequest request = new RangerAccessRequestImpl(resource, accessType.getValue(), user, userGroups, null); - RangerAccessResult result = plugin.evalRowFilterPolicies(request, null); - - if (result == null) { - throw new MaskingException("unable to determine access"); - } - - if (result.isRowFilterEnabled()) { - String filterExpr = result.getFilterExpr(); - - if (logger.isDebugEnabled()) { - logger.debug("row level filter enabled with expression: " + filterExpr); - } - - ret = RecordFilterJavaScript.filterRow(user, filterExpr, jsonString); - - // generate audit log only when row-filter denies access to the record - if (!ret) { - result.setIsAllowed(false); - - auditHandler.processResult(result); - } - } - - return ret; - } - - /** - * Checks to see if this user has any access at all to this schema - * @param schema atlas schema name - * @param user atlas user name - * @param accessType access type requested; must be included in NestedStructureAccessType. - * @return if the user has access to this schema - */ - private boolean hasAccessToSchemaOrAnyField(String schema, String user, Set userGroups, NestedStructureAccessType accessType, NestedStructureAuditHandler auditHandler) { - NestedStructureResource resource = new NestedStructureResource(Optional.of(schema)); - RangerAccessRequestImpl request = new RangerAccessRequestImpl(resource, accessType.getValue(), user, userGroups, null); - - request.setResourceMatchingScope(RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS); - - RangerAccessResult result = plugin.isAccessAllowed(request, null); - - if (result == null){ - throw new MaskingException("unable to determine access"); - } - - boolean ret = result.getIsAccessDetermined() && result.getIsAllowed(); - - // generate audit log when the user doesn't have access to any field within the schema - if (!ret) { - auditHandler.processResult(result); - } - - if (logger.isDebugEnabled()) { - logger.debug("checking LINE 202 " + accessType + " access to " + schema + " for user: " + user + " has access ? " - + (ret ? "yes" : "no") + " policyId: " + result.getPolicyId()); - } - - return ret; - } -} diff --git a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/NestedStructureResource.java b/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/NestedStructureResource.java deleted file mode 100644 index ff47065192..0000000000 --- a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/NestedStructureResource.java +++ /dev/null @@ -1,46 +0,0 @@ -/** -* Copyright 2022 Comcast Cable Communications Management, LLC -* -* Licensed 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. -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -package org.apache.ranger.authorization.nestedstructure.authorizer; - -import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl; - -import java.util.Optional; - -public class NestedStructureResource extends RangerAccessResourceImpl { - public static final String KEY_SCHEMA = "schema"; - public static final String KEY_FIELD = "field"; - - public NestedStructureResource(Optional schema, Optional field) { - if (schema.isPresent()) { - setValue(KEY_SCHEMA, schema.get()); - } - - if (field.isPresent()) { - setValue(KEY_FIELD, field.get()); - } - } - - public NestedStructureResource(Optional schema) { - if (schema.isPresent()) { - setValue(KEY_SCHEMA, schema.get()); - } - } -} - - diff --git a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/NestedStructureService.java b/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/NestedStructureService.java deleted file mode 100644 index 15b6f21c93..0000000000 --- a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/NestedStructureService.java +++ /dev/null @@ -1,37 +0,0 @@ -/** -* Copyright 2022 Comcast Cable Communications Management, LLC -* -* Licensed 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. -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -package org.apache.ranger.authorization.nestedstructure.authorizer; - -import org.apache.ranger.plugin.service.RangerBaseService; -import org.apache.ranger.plugin.service.ResourceLookupContext; - -import java.util.List; -import java.util.Map; - -public class NestedStructureService extends RangerBaseService { - @Override - public Map validateConfig() { - return null; - } - - @Override - public List lookupResource(ResourceLookupContext resourceLookupContext) { - return null; - } -} \ No newline at end of file diff --git a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/RecordFilterJavaScript.java b/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/RecordFilterJavaScript.java deleted file mode 100644 index 77767767c7..0000000000 --- a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/RecordFilterJavaScript.java +++ /dev/null @@ -1,110 +0,0 @@ -/** - * - * -* Copyright 2022 Comcast Cable Communications Management, LLC -* -* Licensed 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. -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -package org.apache.ranger.authorization.nestedstructure.authorizer; - -import jdk.nashorn.api.scripting.ClassFilter; -import jdk.nashorn.api.scripting.NashornScriptEngineFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.script.Bindings; -import javax.script.ScriptEngine; - -/** - * Executes an injected javascript command to determine if the user has access to the selected record - */ -public class RecordFilterJavaScript { - private static final Logger logger = LoggerFactory.getLogger(RecordFilterJavaScript.class); - - /** - * javascript primitive imports that the nashorn engine needs to function properly, e.g., with "includes" - */ - private static final String NASHORN_POLYFILL_ARRAY_PROTOTYPE_INCLUDES = "if (!Array.prototype.includes) " + - "{ Object.defineProperty(Array.prototype, 'includes', { value: function(valueToFind, fromIndex) " + - "{ if (this == null) { throw new TypeError('\"this\" is null or not defined'); } var o = Object(this); " + - "var len = o.length >>> 0; if (len === 0) { return false; } var n = fromIndex | 0; " + - "var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); " + - "function sameValueZero(x, y) { return x === y || (typeof x === 'number' && typeof y === 'number' " + - "&& isNaN(x) && isNaN(y)); } while (k < len) { if (sameValueZero(o[k], valueToFind)) { return true; } k++; }" + - " return false; } }); }"; - - - /** - * This class filter prevents javascript from importing, using or reflecting any java classes - * Helps keep javascript clean of injections. It also contains other checks to ensure that injected - * javascript is reasonably safe. - */ - static class SecurityFilter implements ClassFilter { - @Override - public boolean exposeToScripts(String s) { - return false; - } - - /** - * - * @param filterExpr the javascript to check if it contains potentially harmful commands - * @return if this script is likely bad - */ - boolean containsMalware(String filterExpr){ - //this.engine is the javascript notation for getting access to runtime that is executing the script - //more checks can be added here - return filterExpr.contains("this.engine"); - } - } - - - public static boolean filterRow(String user, String filterExpr, String jsonString) { - SecurityFilter securityFilter = new SecurityFilter(); - - if (securityFilter.containsMalware(filterExpr)) { - throw new MaskingException("cannot process filter expression due to security concern \"this.engine\": " + filterExpr); - } - - NashornScriptEngineFactory factory = new NashornScriptEngineFactory(); - ScriptEngine engine = factory.getScriptEngine(securityFilter); - - if (logger.isDebugEnabled()) { - logger.debug("filterExpr: " + filterExpr); - } - - // convert the given JSON string to JavaScript object, which the filterExpr expects, and then exec the filterExpr - String script = " jsonAttr = JSON.parse(jsonString); " + NASHORN_POLYFILL_ARRAY_PROTOTYPE_INCLUDES + " " + filterExpr; - - try { - Bindings bindings = engine.createBindings(); - - bindings.put("jsonString", jsonString); - bindings.put("user", user); - - boolean hasAccess = (boolean) engine.eval(script, bindings); - - if (logger.isDebugEnabled()) { - logger.debug("row filter access=" + hasAccess); - } - - return hasAccess; - } catch (Exception e) { - throw new MaskingException("unable to properly evaluate filter expression: " + filterExpr, e); - } - } -} - - \ No newline at end of file diff --git a/plugin-nestedstructure/src/test/java/org/apache/ranger/authorization/nestedstructure/authorizer/ExampleClient.java b/plugin-nestedstructure/src/test/java/org/apache/ranger/authorization/nestedstructure/authorizer/ExampleClient.java deleted file mode 100644 index af32aff996..0000000000 --- a/plugin-nestedstructure/src/test/java/org/apache/ranger/authorization/nestedstructure/authorizer/ExampleClient.java +++ /dev/null @@ -1,47 +0,0 @@ -/** -* Copyright 2022 Comcast Cable Communications Management, LLC -* -* Licensed 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. -* -* SPDX-License-Identifier: Apache-2.0 -*/ - -package org.apache.ranger.authorization.nestedstructure.authorizer; - - -import java.util.Set; - -public class ExampleClient { - public static void main( String[] args) { - String schema = "json_object.foo.v1"; - String userName = "someuser"; - Set userGroups = null; - String jsonString = "{\n" + - " \"foo\": \"12345678\",\n" + - " \"address\": {\n" + - " \"city\": \"philadelphia\" \n" + - " },\n" + - " \"bar\": \"snafu\" \n" + - "}\n"; - - AccessResult result = NestedStructureAuthorizer.getInstance().authorize(schema, userName, userGroups, jsonString, NestedStructureAccessType.READ); - - System.out.println("has errors: "+ result.hasErrors()); - System.out.println("hasAccess: "+ result.hasAccess()); - System.out.println("authorizedJson: "+ result.getJson()); - - result.getErrors().stream().forEach(e-> e.printStackTrace()); - - System.out.println("done"); - } -} diff --git a/plugin-nestedstructure/src/test/java/org/apache/ranger/authorization/nestedstructure/authorizer/TestDataMasker.java b/plugin-nestedstructure/src/test/java/org/apache/ranger/authorization/nestedstructure/authorizer/TestDataMasker.java deleted file mode 100644 index e070fa24f0..0000000000 --- a/plugin-nestedstructure/src/test/java/org/apache/ranger/authorization/nestedstructure/authorizer/TestDataMasker.java +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.ranger.authorization.nestedstructure.authorizer; - -import org.testng.Assert; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static org.apache.ranger.authorization.nestedstructure.authorizer.MaskTypes.*; - -public class TestDataMasker { - - @DataProvider(name = "testMaskProvider") - public Object[][] dpMethod(){ - return new Object[][] { - {"1234567890", MASK, null, "**********"}, - {"1", MASK, null, "*****"}, - {"", MASK, null, "*****"}, - {null, MASK, null, "*****"}, - {"1234567890", MASK_SHOW_LAST_4, null, "xxxxxx7890"}, - - {null, MASK_SHOW_LAST_4, null, null}, - {"1", MASK_SHOW_LAST_4, null, "1"}, - {"12", MASK_SHOW_LAST_4, null, "12"}, - {"abc", MASK_SHOW_LAST_4, null, "abc"}, - {"abcd", MASK_SHOW_LAST_4, null, "abcd"}, - {"abcde", MASK_SHOW_LAST_4, null, "xbcde"}, - {"abcde1234567890a", MASK_SHOW_LAST_4, null, "xxxxxxxxxxxx890a"}, - - {null, MASK_SHOW_FIRST_4, null, null}, - {"1", MASK_SHOW_FIRST_4, null, "1"}, - {"12", MASK_SHOW_FIRST_4, null, "12"}, - {"abc", MASK_SHOW_FIRST_4, null, "abc"}, - {"abcd", MASK_SHOW_FIRST_4, null, "abcd"}, - {"abcde", MASK_SHOW_FIRST_4, null, "abcdx"}, - {"abcde1234567890a", MASK_SHOW_FIRST_4, null, "abcdxxxxxxxxxxxx"}, - - {null, MASK_NULL, null, null}, - {"1", MASK_NULL, null, null}, - {"12", MASK_NULL, null, null}, - {"abc", MASK_NULL, null, null}, - {"abcd", MASK_NULL, null, null}, - {"abcde", MASK_NULL, null, null}, - {"abcde1234567890a", MASK_NULL, null, null}, - - {null, CUSTOM, null, null}, - {"1", CUSTOM, null, null}, - {"12", CUSTOM, "woot", "woot"}, - {"abc", CUSTOM, "woot", "woot"}, - {"abcd", CUSTOM, "woot", "woot"}, - {"abcde", CUSTOM, "woot", "woot"}, - {"abcde1234567890a", CUSTOM, "woot", "woot"}, - - {"1234567890", MASK, null, "**********"}, - {"1234567890", MASK, null, "**********"}, - {"1234567890", MASK, null, "**********"}, - {"1", MASK, null, "*****"}, - {"1B", MASK, null, "*****"}, - {"akdkajkjkdfsjkdfsjklfjkfjkljkjklfjkldfsdfjkldfjkldfsjkdfjkljkljklf", MASK, null, "******************************"}, - }; - } - @Test(dataProvider = "testMaskProvider") - void testMask(String value, String maskType, String customValue, String result){ - Assert.assertEquals(DataMasker.maskString(value, maskType, customValue), result); - } - - @DataProvider(name = "shaProvider") - public Object[][] shaProvider() { - return new Object[][]{ - {"1234567890"}, - {null}, - {""}, - {"djfklasfjkjkdsjadsjkladfsjkl;adfsjewi9etwigodsfojkkmcv " + - "]e3djfjkadsjkfls;jkfjdsfkj;kldsjfdsl;jfas" + - "dsfjadsl;fjdsklfjewfl fjdsjw fkl;jfkldsj9049023902390234902349023490" + - "]389439023490234890234890234890234890fjfsjdfsjkldsjkldfsjkdfsjklef" + - "ershjewjrjkl;erwjkl;erwijo23490234890234890fjkdfsjkdfsjkadsf" + - "23490234890890dfiudfsjkdfsjkldfsjkl90890234890234890fdjklfj!@#%^))(*&^%$(" + - ")(*&^%$#!@#$%^&*()(*&^%$@#$%^&*((*&^%$!@#$%^&*((*&^%$@#$%^&*()(*&^%$@#$%^"}, - {"fdjkls"}, - {" "} - }; - } - - @Test(dataProvider = "shaProvider") - void testShaMask(String value){ - String masked = DataMasker.maskString(value, MASK_HASH, null); - Assert.assertEquals(masked.length(), 64); - Assert.assertTrue(isHexadecimal(masked)); - } - - private static final Pattern HEXADECIMAL_PATTERN = Pattern.compile("\\p{XDigit}+"); - - private boolean isHexadecimal(String input) { - final Matcher matcher = HEXADECIMAL_PATTERN.matcher(input); - return matcher.matches(); - } - - @DataProvider(name = "badMasks") - public Object[][] badMasks(){ - return new Object[][] { - {"1234567890", null, null, "**********"}, - {"1", null, null, "*****"}, - - {null, "", null, null}, - {"1", "", null, "1"}, - {"12", "", null, "12"}, - - {"abcd", "mask", null, "abcd"}, - {"abcde", "mask", null, "abcdx"}, - {"abcde1234567890a", "mask", null, "abcdxxxxxxxxxxxx"}, - - }; - } - @Test(expectedExceptions = { MaskingException.class }, dataProvider = "badMasks") - void testInvalidMask(String value, String maskType, String customValue, String result){ - DataMasker.maskString(value, maskType, customValue); - } - - @DataProvider(name = "dateformats") - public Object[][] dateformats(){ - return new Object[][] { - {"", MASK_DATE_SHOW_YEAR, null, ""}, - {null, MASK_DATE_SHOW_YEAR, null, null}, - {"20111203", MASK_DATE_SHOW_YEAR, null, "2011"}, - {"2011-12-03", MASK_DATE_SHOW_YEAR, null, "2011"}, - {"2011-12-03+01:00", MASK_DATE_SHOW_YEAR, null, "2011"}, - {"2012-12-03+01:00", MASK_DATE_SHOW_YEAR, null, "2012"}, - {"2011-12-03T10:15:30", MASK_DATE_SHOW_YEAR, null, "2011"}, - {"2011-12-03T10:15:30+01:00", MASK_DATE_SHOW_YEAR, null, "2011"}, - {"2015-12-03T10:15:30+01:00[Europe/Paris]", MASK_DATE_SHOW_YEAR, null, "2015"}, - {"2012-12-03T10:15:30+01:00[Europe/Paris]", MASK_DATE_SHOW_YEAR, null, "2012"}, - {"2012-337", MASK_DATE_SHOW_YEAR, null, "2012"}, - {"2012-W48-6", MASK_DATE_SHOW_YEAR, null, "2012"}, - {"Tue, 3 Jun 2008 11:05:30 GMT", MASK_DATE_SHOW_YEAR, null, "2008"}, - {"3 Jun 2008 11:05:30 GMT", MASK_DATE_SHOW_YEAR, null, "2008"} - }; - } - @Test(dataProvider = "dateformats") - void testMaskYear(String value, String maskType, String customValue, String result){ - Assert.assertEquals(DataMasker.maskString(value, maskType, customValue), result); - } - - @DataProvider(name = "dateformatsBad") - public Object[][] dateformatsBad(){ - return new Object[][] { - {" ", MASK_DATE_SHOW_YEAR, null, ""}, - {"null", MASK_DATE_SHOW_YEAR, null, null}, - {"2011120354", MASK_DATE_SHOW_YEAR, null, "2011"}, - {"2011--12-03", MASK_DATE_SHOW_YEAR, null, "2011"}, - {"2011-12 01:00", MASK_DATE_SHOW_YEAR, null, "2011"}, - {"2012-12-03T+01:00", MASK_DATE_SHOW_YEAR, null, "2012"}, - {"2011-12-0310:15:30", MASK_DATE_SHOW_YEAR, null, "2011"}, - }; - } - @Test(expectedExceptions = { MaskingException.class }, dataProvider = "dateformatsBad") - void testMaskYearBad(String value, String maskType, String customValue, String result){ - DataMasker.maskString(value, maskType, customValue); - } - - @DataProvider(name = "booleans2") - public Object[][] booleans(){ - return new Object[][] { - {true, MASK, null, false}, - {false, MASK, null, false}, - - {true, CUSTOM, "true", true}, - {false, CUSTOM, "true", true}, - {true, CUSTOM, "false", false}, - {false, CUSTOM, "false", false}, - - {true, MASK_NULL, "true", null}, - {false, MASK_NULL, "false", null}, - - {true, MASK_NONE, null, true}, - {false, MASK_NONE, null, false}, - }; - } - @Test(dataProvider = "booleans2") - void testMaskBooleans(Boolean value, String maskType, String customValue, Boolean result){ - Assert.assertEquals(DataMasker.maskBoolean(value, maskType, customValue), result); - } - - @DataProvider(name = "booleansBad") - public Object[][] booleansBad(){ - return new Object[][] { - {false, MASK_DATE_SHOW_YEAR, null, null}, - {false, MASK_HASH, null, null}, - {true, MASK_HASH, null, null}, - {false, null, null, null}, - }; - } - @Test(expectedExceptions = { MaskingException.class }, dataProvider = "booleansBad") - void testMaskBooleansBad(Boolean value, String maskType, String customValue, Boolean result){ - DataMasker.maskBoolean(value, maskType, customValue); - } - - - @DataProvider(name = "numbers") - public Object[][] numbers(){ - return new Object[][] { - {0, MASK, null, DataMasker.DEFAULT_NUMBER_MASK}, - {-101, MASK, null, DataMasker.DEFAULT_NUMBER_MASK}, - {1.215, MASK, null, DataMasker.DEFAULT_NUMBER_MASK}, - {12345648976453L, MASK, null, DataMasker.DEFAULT_NUMBER_MASK}, - - {0, MASK_NULL, null, null}, - {-101, MASK_NULL, null, null}, - {1.215, MASK_NULL, null, null}, - {12345648976453L, MASK_NULL, null, null}, - - {0, MASK_NONE, null, 0}, - {-101, MASK_NONE, null, -101}, - {1.215, MASK_NONE, null, 1.215}, - {12345648976453L, MASK_NONE, null, 12345648976453L}, - - {0, CUSTOM, "100", 100}, - {-101, CUSTOM, "202", 202}, - {1.215, CUSTOM, "303", 303}, - {12345648976453L, CUSTOM, "-404", -404}, - }; - } - @Test(dataProvider = "numbers") - void testNumbers(Number value, String maskType, String customValue, Number result){ - DataMasker.maskNumber(value, maskType, customValue); - } - - @DataProvider(name = "numbersBad") - public Object[][] numbersBad(){ - return new Object[][] { - {1, MASK_DATE_SHOW_YEAR, null, null}, - {null, MASK_HASH, null, null}, - {1000, MASK_HASH, null, null}, - {1001.012345, null, null, null}, - - {1, CUSTOM, "", null}, - {null, CUSTOM, "null", null}, - {1000, CUSTOM, "102456fdafdasfda45fghnhjjuio", null}, - {1001.012345, CUSTOM, "a big brown bear came lolloping over the mountain", null}, - }; - } - @Test(expectedExceptions = { MaskingException.class }, dataProvider = "numbersBad") - void testNumbersBad(Number value, String maskType, String customValue, Boolean result){ - DataMasker.maskNumber(value, maskType, customValue); - } -} diff --git a/plugin-nestedstructure/src/test/java/org/apache/ranger/authorization/nestedstructure/authorizer/TestJsonManipulator.java b/plugin-nestedstructure/src/test/java/org/apache/ranger/authorization/nestedstructure/authorizer/TestJsonManipulator.java deleted file mode 100644 index 79af9f6501..0000000000 --- a/plugin-nestedstructure/src/test/java/org/apache/ranger/authorization/nestedstructure/authorizer/TestJsonManipulator.java +++ /dev/null @@ -1,363 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.ranger.authorization.nestedstructure.authorizer; - -import com.google.gson.JsonParser; -import org.testng.Assert; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - -import java.util.Arrays; -import java.util.List; -import java.util.Set; - -import static org.apache.ranger.authorization.nestedstructure.authorizer.MaskTypes.*; - -public class TestJsonManipulator { - static final String testString1 = "{\n" + - " \"customerRelationshipId\": \"42207ad4\",\n" + - " \"accountnumber\": \"12345678\",\n" + - " \"partner\": \"dance\",\n" + - " \"acquisitionDate\": \"2018-02-01\",\n" + - " \"customerSubtype\": [\n" + - " \"type1\",\n" + - " \"type2\"\n" + - " ],\n" + - " \"address\": {\n" + - " \"addressLine1\": \"123 Main St\",\n" + - " \"addressLine2\": \"Apt1\",\n" + - " \"city\": \"philadelphia\",\n" + - " \"state\": \"PA\",\n" + - " \"zipCode\": \"19019\",\n" + - " \"zipCodePlus4\": \"1111\",\n" + - " \"country\": \"USA\"\n" + - " }\n" + - "}\n"; - - - static final String bigTester = "{" + - " \"someString\": \"42207ad4-590e-4d5d-a65f-6a4ccddca9e3002\"," + - " \"someNumber\": 12345678," + - " \"someBoolean\": true," + - " \"stringArray\": [\"thing1\", \"thing2\"]," + - " \"numberArray\": [1, 2, 3]," + - " \"booleanArray\": [true, false, true]," + - " \"aMap\": {" + - " \"mapString\": \"123 Main St\"," + - " \"mapBoolean\": false," + - " \"mapNumber\": 987," + - " \"mapStrinArray\": [\"one\", \"two\"]," + - " \"mapMap\": {\"mapMapString\": \"19019\"}" + - " }\n" + - "}\n"; - - - @Test - public void testFieldNames1() { - JsonManipulator js = new JsonManipulator("{foo: 1}"); - - Assert.assertEquals(js.getFields().size(), 1); - } - - @Test - public void testFieldNames2() { - JsonManipulator js = new JsonManipulator("{foo: 1, bar: 2}"); - - Assert.assertEquals(js.getFields().size(), 2); - } - - @Test - public void testFieldNamesBigger() { - JsonManipulator js = new JsonManipulator(testString1); - - System.out.println(js.getFields()); - - Set fields = js.getFields(); - - Assert.assertTrue(fields.contains("customerRelationshipId")); - Assert.assertTrue(fields.contains("partner")); - Assert.assertTrue(fields.contains("acquisitionDate")); - Assert.assertTrue(fields.contains("customerSubtype.*")); - Assert.assertTrue(fields.contains("accountnumber")); - Assert.assertTrue(fields.contains("address.addressLine1")); - Assert.assertTrue(fields.contains("address.addressLine2")); - Assert.assertTrue(fields.contains("address.city")); - Assert.assertTrue(fields.contains("address.zipCode")); - Assert.assertTrue(fields.contains("address.zipCodePlus4")); - Assert.assertTrue(fields.contains("address.state")); - Assert.assertTrue(fields.contains("address.country")); - Assert.assertEquals(js.getFields().size(), 12); - } - - @Test(expectedExceptions = {MaskingException.class}) - public void invalidJson() { - JsonManipulator js = new JsonManipulator("{foo:\"bar\""); - - Assert.assertEquals(js.getFields().size(), 1); - } - - @Test - public void testToString() { - String condensedString = JsonParser.parseString(testString1).toString(); - JsonManipulator man = new JsonManipulator(condensedString); - - Assert.assertEquals(man.getJsonString(), condensedString); - } - - @Test - public void testBigTesterFieldNames() { - JsonManipulator man = new JsonManipulator(bigTester); - - Assert.assertEquals(man.getFields().size(), 11); - } - - @DataProvider(name = "simpleMasks") - public Object[][] simpleMasks(){ - return new Object[][] { - //basic string masking - {"{\"string1\":\"value1\"}", - Arrays.asList( - new FieldLevelAccess("string1", true, 1L, true, MASK_NULL, "customValue")), - "{\"string1\":null}"}, - {"{\"string1\":\"value1\"}", - Arrays.asList( - new FieldLevelAccess("string1", true, 1L, true, CUSTOM, "customValue")), - "{\"string1\":\"customValue\"}"}, - {"{\"string1\":\"value1\"}", - Arrays.asList( - new FieldLevelAccess("string1", true, 1L, true, MASK_NONE, "customValue")), - "{\"string1\":\"value1\"}"}, - {"{\"string1\":\"value1\"}", - Arrays.asList( - new FieldLevelAccess("string1", true, 1L, true, MASK_SHOW_FIRST_4, "customValue")), - "{\"string1\":\"valuxx\"}"}, - {"{\"string1\":\"value1\"}", - Arrays.asList( - new FieldLevelAccess("string1", true, 1L, true, MASK_SHOW_LAST_4, "customValue")), - "{\"string1\":\"xxlue1\"}"}, - {"{\"string1\":\"value1\"}", - Arrays.asList( - new FieldLevelAccess("string1", true, 1L, true, MASK_HASH, "customValue")), - "{\"string1\":\"3c9683017f9e4bf33d0fbedd26bf143fd72de9b9dd145441b75f0604047ea28e\"}"}, - {"{\"string1\":\"2021-12-25\"}", - Arrays.asList( - new FieldLevelAccess("string1", true, 1L, true, MASK_DATE_SHOW_YEAR, "customValue")), - "{\"string1\":\"2021\"}"}, - - //basic number masking - {"{\"string1\":123456}", - Arrays.asList( - new FieldLevelAccess("string1", true, 1L, true, MASK_NULL, "100")), - "{\"string1\":null}"}, - {"{\"string1\":123456}", - Arrays.asList( - new FieldLevelAccess("string1", true, 1L, true, CUSTOM, "100")), - "{\"string1\":100}"}, - {"{\"string1\":123456}", - Arrays.asList( - new FieldLevelAccess("string1", true, 1L, true, MASK_NONE, "100")), - "{\"string1\":123456}"}, - {"{\"string1\":123456}", - Arrays.asList( - new FieldLevelAccess("string1", true, 1L, true, MASK, "100")), - "{\"string1\":-11111}"}, - - //basic boolean masking - {"{\"string1\":true}", - Arrays.asList( - new FieldLevelAccess("string1", true, 1L, true, MASK_NULL, "true")), - "{\"string1\":null}"}, - {"{\"string1\":true}", - Arrays.asList( - new FieldLevelAccess("string1", true, 1L, true, CUSTOM, "false")), - "{\"string1\":false}"}, - {"{\"string1\":true}", - Arrays.asList( - new FieldLevelAccess("string1", true, 1L, true, MASK_NONE, "true")), - "{\"string1\":true}"}, - {"{\"string1\":true}", - Arrays.asList( - new FieldLevelAccess("string1", true, 1L, true, MASK, "true")), - "{\"string1\":false}"}, - - //array string masking - {"{\"string1\":[\"aaaaaaa\",\"bbbbbbb\"]}", - Arrays.asList( - new FieldLevelAccess("string1.*", true, 1L, true, MASK_NULL, "true")), - "{\"string1\":[null,null]}"}, - {"{\"string1\":[\"aaaaaaa\",\"bbbbbbb\"]}", - Arrays.asList( - new FieldLevelAccess("string1.*", true, 1L, true, CUSTOM, "false")), - "{\"string1\":[\"false\",\"false\"]}"}, - {"{\"string1\":[\"aaaaaaa\",\"bbbbbbb\"]}", - Arrays.asList( - new FieldLevelAccess("string1.*", true, 1L, true, MASK_NONE, "true")), - "{\"string1\":[\"aaaaaaa\",\"bbbbbbb\"]}"}, - {"{\"string1\":[\"aaaaaaa\",\"bbbbbbbbbb\"]}", - Arrays.asList( - new FieldLevelAccess("string1.*", true, 1L, true, MASK, "true")), - "{\"string1\":[\"*******\",\"**********\"]}"}, - - - }; - } - - @Test(dataProvider = "simpleMasks") - void testSimpleMasks(String json, List fieldAccess, String outputJson){ - JsonManipulator man = new JsonManipulator(json); - - man.maskFields(fieldAccess); - - Assert.assertEquals(man.getJsonString(), outputJson); - } - - @DataProvider(name = "complexMasks") - public Object[][] complexMasks(){ - return new Object[][] { - //test masking two fields - {bigTester, - Arrays.asList( - new FieldLevelAccess("someNumber", true, 1L, true, CUSTOM, "555"), - new FieldLevelAccess("someBoolean", true, 1L, true, CUSTOM, "false")), - "someNumber", "555"}, - {bigTester, - Arrays.asList( - new FieldLevelAccess("someNumber", true, 1L, true, CUSTOM, "555"), - new FieldLevelAccess("someBoolean", true, 1L, true, CUSTOM, "false")), - "someBoolean", "false"}, - - - {bigTester, - Arrays.asList( - new FieldLevelAccess("someString", true, 1L, true, CUSTOM, "555")), - "someString", "555"}, - {bigTester, - Arrays.asList( - new FieldLevelAccess("someNumber", true, 1L, true, CUSTOM, "555")), - "someNumber", "555"}, - {bigTester, - Arrays.asList( - new FieldLevelAccess("stringArray.*", true, 1L, true, CUSTOM, "555")), - "stringArray.*", "[\"555\",\"555\"]"}, - {bigTester, - Arrays.asList( - new FieldLevelAccess("booleanArray.*", true, 1L, true, CUSTOM, "false")), - "booleanArray.*", "[false,false,false]"}, - - {bigTester, - Arrays.asList( - new FieldLevelAccess("aMap.mapString", true, 1L, true, CUSTOM, "foo")), - "aMap.mapString", "foo"}, - {bigTester, - Arrays.asList( - new FieldLevelAccess("aMap.mapBoolean", true, 1L, true, CUSTOM, "true")), - "aMap.mapBoolean", "true"}, - {bigTester, - Arrays.asList( - new FieldLevelAccess("aMap.mapNumber", true, 1L, true, CUSTOM, "444")), - "aMap.mapNumber", "444"}, - {bigTester, - Arrays.asList( - new FieldLevelAccess("aMap.mapStrinArray.*", true, 1L, true, CUSTOM, "baa")), - "aMap.mapStrinArray.*", "[\"baa\",\"baa\"]"}, - {bigTester, - Arrays.asList( - new FieldLevelAccess("aMap.mapMap.mapMapString", true, 1L, true, CUSTOM, "444qqq")), - "aMap.mapMap.mapMapString", "444qqq"}, - - {bigTester, - Arrays.asList( - new FieldLevelAccess("aMap.mapMap.mapMapString", false, 1L, true, CUSTOM, "444qqq")), - "aMap.mapMap.mapMapString", "19019"}, - {bigTester, - Arrays.asList( - new FieldLevelAccess("aMap.mapMap.mapMapString", true, 1L, false, CUSTOM, "444qqq")), - "aMap.mapMap.mapMapString", "19019"}, - }; - } - - @Test(dataProvider = "complexMasks") - void testComplexMasks(String json, List fieldAccess, String fieldName, String value){ - JsonManipulator man = new JsonManipulator(json); - man.maskFields(fieldAccess); - Assert.assertEquals(man.readString(fieldName), value); - } - - @Test - void testRecordsInArray(){ - String json = "{\n" + - " \"modifiedTimestamp\": \"2000-01-23T04:56:07.000Z\",\n" + - " \"source\": [\n" + - " {\n" + - " \"sourceId\": \"123456\",\n" + - " \"sourceType\": \"a type\",\n" + - " \"sourceType2\": \"type two\",\n" + - " \"sourceSystem\": \"Source System\"\n" + - " }\n" + - " ],\n" + - " \"channel\": \"channel 4\",\n" + - " \"transactionStatus\": \"SUCCESS\",\n" + - " \"customAttributes\": [\n" + - " {\n" + - " \"key\": \"new\",\n" + - " \"value\": \"value1\"\n" + - " }\n" + - " ],\n" + - " \"modifiedBy\": \"batchJob\"\n" + - "}"; - JsonManipulator man = new JsonManipulator(json); - Assert.assertEquals(man.getFields().size(), 10); - } - - @Test - void testRecordsInArray2(){ - String json = "{\n" + - " \"modifiedTimestamp\": \"2000-01-23T04:56:07.000Z\",\n" + - " \"source\": [\n" + - " {\n" + - " \"sourceId\": \"123456\",\n" + - " \"sourceType\": \"a type\",\n" + - " \"sourceType2\": \"type two\",\n" + - " \"sourceSystem\": \"Source System\"\n" + - " }\n" + - " ],\n" + - " \"channel\": \"channel 4\",\n" + - " \"transactionStatus\": \"SUCCESS\",\n" + - " \"customAttributes\": [\n" + - " {\n" + - " \"key\": \"new\",\n" + - " \"value\": \"value1\"\n" + - " },\n" + - " {\n" + - " \"key\": \"new22\",\n" + - " \"value\": \"value22\"\n" + - " }\n" + - " ],\n" + - " \"modifiedBy\": \"batchJob\"\n" + - "}"; - JsonManipulator man = new JsonManipulator(json); - Assert.assertEquals(man.getFields().size(), 10); - - FieldLevelAccess fieldAccess = new FieldLevelAccess("customAttributes.*.key", - true, 1L, true, CUSTOM, "THEMASK"); - man.maskFields(Arrays.asList(fieldAccess)); - Assert.assertEquals(man.readString("customAttributes.[0].key"), "THEMASK"); - } -} diff --git a/plugin-nestedstructure/src/test/java/org/apache/ranger/authorization/nestedstructure/authorizer/TestNestedStructureAuthorizer.java b/plugin-nestedstructure/src/test/java/org/apache/ranger/authorization/nestedstructure/authorizer/TestNestedStructureAuthorizer.java deleted file mode 100644 index 461e9e9725..0000000000 --- a/plugin-nestedstructure/src/test/java/org/apache/ranger/authorization/nestedstructure/authorizer/TestNestedStructureAuthorizer.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.ranger.authorization.nestedstructure.authorizer; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import org.apache.commons.lang3.StringUtils; -import org.apache.ranger.plugin.model.RangerServiceDef; -import org.apache.ranger.plugin.util.RangerRoles; -import org.apache.ranger.plugin.util.ServicePolicies; -import org.apache.ranger.plugin.util.ServiceTags; - -import java.io.*; -import java.util.List; -import java.util.Set; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -import static org.testng.AssertJUnit.assertEquals; -import static org.testng.AssertJUnit.assertTrue; - -public class TestNestedStructureAuthorizer { - static Gson gsonBuilder; - - @BeforeClass - public static void setUpBeforeClass() throws Exception { - gsonBuilder = new GsonBuilder().setDateFormat("yyyyMMdd-HH:mm:ss.SSSZ") - .setPrettyPrinting() - .create(); - } - - @Test - public void test_customer_records() { - runTestsFromResourceFile("/test_customer_records.json"); - } - - private void runTestsFromResourceFile(String resourceName) { - try(InputStream inStream = this.getClass().getResourceAsStream(resourceName); - InputStreamReader reader = new InputStreamReader(inStream)) { - runTests(reader, resourceName); - } catch (IOException excp) { - // ignore - } - } - - private void runTests(InputStreamReader reader, String testName) { - NestedStructureTestCase testCase = gsonBuilder.fromJson(reader, NestedStructureTestCase.class); - - assertTrue("invalid input: " + testName, testCase != null && testCase.policies != null && testCase.tests != null); - - if (testCase.policies.getServiceDef() == null && StringUtils.isNotBlank(testCase.serviceDefFilename)) { - try (InputStream inStream = this.getClass().getResourceAsStream(testCase.serviceDefFilename); - InputStreamReader sdefReader = new InputStreamReader(inStream)) { - testCase.policies.setServiceDef(gsonBuilder.fromJson(sdefReader, RangerServiceDef.class)); - } catch (IOException excp) { - // ignore - } - } - - NestedStructureAuthorizer authorizer = new NestedStructureAuthorizer(testCase.policies, testCase.tags, testCase.roles); - - for (NestedStructureTestCase.TestData test : testCase.tests) { - AccessResult expected = test.result; - AccessResult result = authorizer.authorize(test.schema, test.user, test.userGroups, test.json, NestedStructureAccessType.getAccessType(test.accessType)); - - assertEquals(test.name + ": hasAccess doesn't match: expected=" + expected.hasAccess() + ", actual=" + result.hasAccess(), expected.hasAccess(), result.hasAccess()); - assertEquals(test.name + ": json doesn't match: expected=" + expected.getJson() + ", actual=" + result.getJson(), expected.getJson(), result.getJson()); - } - } - - static class NestedStructureTestCase { - public ServicePolicies policies; - public ServiceTags tags; - public RangerRoles roles; - public List tests; - public String serviceDefFilename; - - class TestData { - public String name; - public String schema; - public String json; - public String user; - public Set userGroups; - public String accessType; - public AccessResult result; - } - } -} diff --git a/plugin-nestedstructure/src/test/java/org/apache/ranger/authorization/nestedstructure/authorizer/TestRecordFilterJavaScript.java b/plugin-nestedstructure/src/test/java/org/apache/ranger/authorization/nestedstructure/authorizer/TestRecordFilterJavaScript.java deleted file mode 100644 index 9cb161b8dd..0000000000 --- a/plugin-nestedstructure/src/test/java/org/apache/ranger/authorization/nestedstructure/authorizer/TestRecordFilterJavaScript.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.apache.ranger.authorization.nestedstructure.authorizer; - -import org.testng.Assert; -import org.testng.annotations.AfterTest; -import org.testng.annotations.Test; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; - - -public class TestRecordFilterJavaScript { - - @Test(expectedExceptions = {MaskingException.class}) - public void testArbitraryCommand(){ - RecordFilterJavaScript.filterRow("user","this.engine.factory.scriptEngine.eval('java.lang.Runtime.getRuntime().exec(\"/Applications/Spotify.app/Contents/MacOS/Spotify\")')", - TestJsonManipulator.bigTester); - } - - @Test - public void testAccessJava() { - try { - RecordFilterJavaScript.filterRow("user", "bufferedWriter = new java.io.BufferedWriter(new java.io.FileWriter('omg.txt'));\n" + - " bufferedWriter.write(\"Writing line one to file\"); bufferedWriter.close;", TestJsonManipulator.bigTester); - - } catch (MaskingException e) { - Assert.assertTrue(e.getCause() instanceof RuntimeException); - Assert.assertTrue(e.getCause().getCause() instanceof ClassNotFoundException); - } - Assert.assertFalse(Files.exists(Paths.get("omg.txt"))); - } - - @AfterTest - public void deleteTestFile() throws IOException { - Files.deleteIfExists(Paths.get("omg.txt")); - } - - @Test - public void testBasicFilters(){ - Assert.assertEquals(RecordFilterJavaScript.filterRow("user", "jsonAttr.partner.equals('dance')", TestJsonManipulator.testString1), true); - Assert.assertEquals(RecordFilterJavaScript.filterRow("user", "jsonAttr.address.zipCode.equals('19019')", TestJsonManipulator.testString1), true); - Assert.assertEquals(RecordFilterJavaScript.filterRow("user", "jsonAttr.aMap.mapNumber > 5", TestJsonManipulator.bigTester), true); - - Assert.assertEquals(RecordFilterJavaScript.filterRow("user", "jsonAttr.partner.equals('cox')", TestJsonManipulator.testString1), false); - } -} - diff --git a/plugin-nestedstructure/src/test/resources/servicedef-nestedstructure.json b/plugin-nestedstructure/src/test/resources/servicedef-nestedstructure.json deleted file mode 100644 index 9cf6ba85bb..0000000000 --- a/plugin-nestedstructure/src/test/resources/servicedef-nestedstructure.json +++ /dev/null @@ -1,186 +0,0 @@ -{ - "name": "nestedstructure", - "displayName": "nestedstructure", - "implClass": "", - "label": "NestedStructure", - "description": "Plugin to enforce read AND WRITE access control on nested structures such as JSON response objects from microservice API resource calls", - "options": { - "enableDenyAndExceptionsInPolicies": "true" - }, - "configs": [ - { "itemId": 1, "name": "commonNameForCertificate", "type": "string", "mandatory": false }, - { "itemId": 2, "name": "policy.download.auth.users", "type": "string", "mandatory": false } - ], - "resources": [ - { - "itemId": 1, - "name": "schema", - "type": "string", - "level": 10, - "mandatory": true, - "lookupSupported": false, - "recursiveSupported": false, - "excludesSupported": true, - "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", - "matcherOptions": { "wildCard": "true", "ignoreCase": "true" }, - "label": "NestedStructure Schema", - "description": "Schema of the nested structure returned from Microservice GET, etc", - "accessTypeRestrictions": [], - "isValidLeaf": true - }, - { - "itemId": 2, - "name": "field", - "type": "string", - "level": 20, - "parent": "schema", - "mandatory": true, - "lookupSupported": false, - "recursiveSupported": false, - "excludesSupported": true, - "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", - "matcherOptions": { "wildCard": "true", "ignoreCase": "true" }, - "label": "NestedStructure Schema Field", - "description": "NestedStructure Schema Field", - "accessTypeRestrictions": [], - "isValidLeaf": true - } - ], - "accessTypes": [ - { "itemId": 1, "name": "read", "label": "Read" }, - { "itemId": 2, "name": "write", "label": "Write" } - ], - "policyConditions": [], - "contextEnrichers": [], - "enums": [], - "dataMaskDef": { - "maskTypes": [ - { - "itemId": 1, - "name": "MASK", - "label": "Redact", - "description": "Replace lowercase with 'x', uppercase with 'X', digits with '0'", - "transformer": "mask({field})", - "dataMaskOptions": {} - }, - { - "itemId": 2, - "name": "MASK_SHOW_LAST_4", - "label": "Partial mask: show last 4", - "description": "Show last 4 characters; replace rest with 'x'", - "transformer": "mask_show_last_n({field}, 4, 'x', 'x', 'x', -1, '1')", - "dataMaskOptions": {} - }, - { - "itemId": 3, - "name": "MASK_SHOW_FIRST_4", - "label": "Partial mask: show first 4", - "description": "Show first 4 characters; replace rest with 'x'", - "transformer": "mask_show_first_n({field}, 4, 'x', 'x', 'x', -1, '1')", - "dataMaskOptions": {} - }, - { - "itemId": 4, - "name": "MASK_HASH", - "label": "Hash", - "description": "Hash the value", - "transformer": "mask_hash({field})", - "dataMaskOptions": {} - }, - { - "itemId": 5, - "name": "MASK_NULL", - "label": "Nullify", - "description": "Replace with NULL", - "dataMaskOptions": {} - }, - { - "itemId": 6, - "name": "MASK_NONE", - "label": "Unmasked (retain original value)", - "description": "No masking", - "dataMaskOptions": {} - }, - { - "itemId": 12, - "name": "MASK_DATE_SHOW_YEAR", - "label": "Date: show only year", - "description": "Date: show only year", - "transformer": "mask({field}, 'x', 'x', 'x', -1, '1', 1, 0, -1)", - "dataMaskOptions": {} - }, - { - "itemId": 13, - "name": "CUSTOM", - "label": "Custom", - "description": "Custom", - "dataMaskOptions": {} - } - ], - "accessTypes": [ - { "itemId": 1, "name": "read", "label": "Read" } - ], - "resources": [ - { - "itemId": 1, - "name": "schema", - "type": "string", - "level": 10, - "mandatory": true, - "lookupSupported": false, - "recursiveSupported": false, - "excludesSupported": false, - "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", - "matcherOptions": { "wildCard": "false", "ignoreCase": "true" }, - "uiHint": "{ \"singleValue\":true }", - "label": "NestedStructure Schema", - "description": "NestedStructure Schema returned from Microservice GET, etc", - "accessTypeRestrictions": [], - "isValidLeaf": false - }, - { - "itemId": 2, - "name": "field", - "type": "string", - "level": 20, - "parent": "schema", - "mandatory": true, - "lookupSupported": false, - "recursiveSupported": false, - "excludesSupported": false, - "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", - "matcherOptions": { "wildCard": "false", "ignoreCase": "true" }, - "uiHint": "{ \"singleValue\":true }", - "label": "NestedStructure Schema Field", - "description": "NestedStructure Schema Field", - "accessTypeRestrictions": [], - "isValidLeaf": true - } - ] - }, - "rowFilterDef": { - "accessTypes": [ - { "itemId": 1, "name": "read", "label": "Read" }, - { "itemId": 2, "name": "write", "label": "Write" } - ], - "resources": [ - { - "itemId": 1, - "name": "schema", - "type": "string", - "level": 10, - "mandatory": true, - "lookupSupported": false, - "recursiveSupported": false, - "excludesSupported": false, - "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", - "matcherOptions": { "wildCard": "false", "ignoreCase": "true" }, - "uiHint": "{ \"singleValue\":true }", - "label": "NestedStructure Schema", - "description": "NestedStructure Schema returned from Microservice GET, etc", - "accessTypeRestrictions": [], - "isValidLeaf": true - } - ] - } -} \ No newline at end of file diff --git a/plugin-nestedstructure/src/test/resources/test_customer_records.json b/plugin-nestedstructure/src/test/resources/test_customer_records.json deleted file mode 100644 index 343fe7737f..0000000000 --- a/plugin-nestedstructure/src/test/resources/test_customer_records.json +++ /dev/null @@ -1,164 +0,0 @@ -{ - "name": "test access control policies for nestedstructure", - "comments": [ - "tests on authorizing access to customer Json records, along with fields masking and record filtering", - "record structure:", - " { ", - " id: 1,", - " name: customerName,", - " phone: phoneNumber,", - " email: emailAddress,", - " address: { line1: streetName, line2: landmark, city: myCity, state: myState, zipCode: myZipCode }", - " lastOrderDate: 2022/07/16,", - " recentOrders: [", - " {", - " orderId: 1,", - " orderDate: 2022/06/14,", - " orderAmount: 504.76", - " }", - " {", - " orderId: 2,", - " orderDate: 2022/06/06,", - " orderAmount: 321.98", - " }", - " ]", - " }" - ], - "policies": { - "serviceName": "dev_nestedstructure", - "serviceId": 1, - "policyVersion": 1, - "auditMode": "audit-none", - "policies": [ - { - "id": 1, "name":"ACCESS: schema=customer, field=*", - "resources": { "schema": { "values": [ "customer" ] }, "field": { "values": [ "*" ] } }, - "policyItems":[ - { "accesses": [ { "type": "read" } ], "users": [ "user1" ], "groups": [ "analysts" ] } - ] - }, - { - "id": 2, "name":"ACCESS: schema=customer, field=id,name,lastOrderDate,recentOrders", - "resources": { "schema": { "values": [ "customer" ] }, "field": { "values": [ "id", "name", "lastOrderDate", "recentOrders.*" ] } }, - "policyItems":[ - { "accesses": [ { "type": "read" } ], "groups": [ "csr" ] } - ] - }, - { - "id": 101, "name":"MASKING: schema=customer, field=lastOrderDate", "policyType": 1, - "resources": { "schema": { "values": [ "customer" ] }, "field": { "values": [ "lastOrderDate"] } }, - "dataMaskPolicyItems":[ - { "accesses": [ { "type": "read" } ], "groups": [ "analysts" ], "dataMaskInfo": { "dataMaskType": "MASK_NULL" } }, - { "accesses": [ { "type": "read" } ], "groups": [ "csr" ], "dataMaskInfo": { "dataMaskType": "MASK_DATE_SHOW_YEAR" } } - ] - }, - { - "id": 102, "name":"MASKING: schema=customer, field=recentOrders.orderDate", "policyType": 1, - "resources": { "schema": { "values": [ "customer" ] }, "field": { "values": [ "recentOrders.orderDate"] } }, - "dataMaskPolicyItems":[ - { "accesses": [ { "type": "read" } ], "groups": [ "analysts" ], "dataMaskInfo": { "dataMaskType": "MASK_NULL" } }, - { "accesses": [ { "type": "read" } ], "groups": [ "csr" ], "dataMaskInfo": { "dataMaskType": "MASK_DATE_SHOW_YEAR" } } - ] - }, - { - "id": 201, "name":"FILTER: schema=customer", "policyType": 2, - "resources": { "schema": { "values": [ "customer" ] } }, - "rowFilterPolicyItems":[ - { "accesses": [ { "type": "read" } ], "groups": [ "region-ca" ], "rowFilterInfo": { "filterExpr": "jsonAttr.address.state == 'CA'" } }, - { "accesses": [ { "type": "read" } ], "groups": [ "region-wa" ], "rowFilterInfo": { "filterExpr": "jsonAttr.address.state == 'WA'" } } - ] - } - ] - }, - "tags": { }, - "roles": { - "roleVersion": 1 - }, - "serviceDefFilename": "/servicedef-nestedstructure.json", - "tests": [ - { - "name": "ALLOW user1 to read schema=customer, fields=[id,email,address,lastOrderDate]", - "user": "user1", "accessType": "read", - "schema": "customer", - "json": "{\"id\":\"1\",\"name\":\"CA-Customer\",\"email\":\"name@domain.com\",\"address\":{\"state\":\"CA\"},\"lastOrderDate\":\"2022-07-16\"}", - "result": { - "hasAccess": true, - "json": "{\"id\":\"1\",\"name\":\"CA-Customer\",\"email\":\"name@domain.com\",\"address\":{\"state\":\"CA\"},\"lastOrderDate\":\"2022-07-16\"}", - "errors": [ ] - } - }, - { - "name": "ALLOW user in groups=[csr] to read schema=customer, with masked-year for lastOrderDate and recentOrders.orderDate", - "user": "some-user", "userGroups": [ "csr" ], "accessType": "read", - "schema": "customer", - "json": "{\"id\":\"1\",\"name\":\"CA-Customer\",\"lastOrderDate\":\"2022-07-16\",\"recentOrders\":[{\"orderId\":1,\"orderDate\":\"2022-06-14\",\"orderAmount\":504.76},{\"orderId\":2,\"orderDate\":\"2022-06-06\",\"orderAmount\":321.98}]}", - "result": { - "hasAccess": true, - "json": "{\"id\":\"1\",\"name\":\"CA-Customer\",\"lastOrderDate\":\"2022\",\"recentOrders\":[{\"orderId\":1,\"orderDate\":\"2022\",\"orderAmount\":504.76},{\"orderId\":2,\"orderDate\":\"2022\",\"orderAmount\":321.98}]}", - "errors": [ ] - } - }, - { - "name": "DENY user in groups=[csr] to read schema=customer, fields=[email,address]", - "user": "some-user", "userGroups": [ "csr" ], "accessType": "read", - "schema": "customer", - "json": "{\"id\":\"1\",\"name\":\"CA-Customer\",\"email\":\"name@domain.com\",\"address\":{\"state\":\"CA\"},\"lastOrderDate\":\"2022-07-16\"}", - "result": { - "hasAccess": false, - "json": null, - "errors": [ ] - } - }, - { - "name": "ALLOW user in groups=[analysts, region-ca] to read schema=customer, having address.state=CA, with masked-null for lastOrderDate", - "user": "some-user", "userGroups": [ "analysts", "region-ca" ], "accessType": "read", - "schema": "customer", - "json": "{\"id\":\"1\",\"name\":\"CA-Customer\",\"email\":\"name@domain.com\",\"address\":{\"state\":\"CA\"},\"lastOrderDate\":\"2022-07-16\",\"recentOrders\":[{\"orderId\":1,\"orderDate\":\"2022-06-14\",\"orderAmount\":504.76},{\"orderId\":2,\"orderDate\":\"2022-06-06\",\"orderAmount\":321.98}]}", - "result": { - "hasAccess": true, - "json": "{\"id\":\"1\",\"name\":\"CA-Customer\",\"email\":\"name@domain.com\",\"address\":{\"state\":\"CA\"},\"lastOrderDate\":null,\"recentOrders\":[{\"orderId\":1,\"orderDate\":null,\"orderAmount\":504.76},{\"orderId\":2,\"orderDate\":null,\"orderAmount\":321.98}]}", - "errors": [ ] - } - }, - { - "name": "DENY user in groups=[analysts, region-ca] to read schema=customer, having address.state=WA", - "user": "some-user", "userGroups": [ "analysts", "region-ca" ], "accessType": "read", - "schema": "customer", - "json": "{\"id\":\"2\",\"name\":\"WA-Customer\",\"email\":\"name@domain.com\",\"address\":{\"state\":\"WA\"},\"lastOrderDate\":\"2022-07-16\"}", - "result": { - "hasAccess": false, - "json": null, - "errors": [ ] - } - }, - { - "name": "ALLOW user in groups=[analysts, region-wa] to read schema=customer, having address.state=WA, with masked-null for lastOrderDate", - "user": "some-user", "userGroups": [ "analysts", "region-wa" ], "accessType": "read", - "schema": "customer", - "json": "{\"id\":\"2\",\"name\":\"WA-Customer\",\"email\":\"name@domain.com\",\"address\":{\"state\":\"WA\"},\"lastOrderDate\":\"2022-07-16\",\"recentOrders\":[{\"orderId\":1,\"orderDate\":\"2022-06-14\",\"orderAmount\":504.76},{\"orderId\":2,\"orderDate\":\"2022-06-06\",\"orderAmount\":321.98}]}", - "result": { - "hasAccess": true, - "json": "{\"id\":\"2\",\"name\":\"WA-Customer\",\"email\":\"name@domain.com\",\"address\":{\"state\":\"WA\"},\"lastOrderDate\":null,\"recentOrders\":[{\"orderId\":1,\"orderDate\":null,\"orderAmount\":504.76},{\"orderId\":2,\"orderDate\":null,\"orderAmount\":321.98}]}", - "errors": [ ] - } - }, - { - "name": "DENY user in groups=[analysts, region-wa] to read schema=customer, having address.state=CA", - "user": "some-user", "userGroups": [ "analysts", "region-wa" ], "accessType": "read", - "schema": "customer", - "json": "{\"id\":\"1\",\"name\":\"CA-Customer\",\"email\":\"name@domain.com\",\"address\":{\"state\":\"CA\"},\"lastOrderDate\":\"2022-07-16\"}", - "result": { - "hasAccess": false, - "json": null, - "errors": [ ] - } - }, - { - "name": "DENY user1 to read schema=employee, field=id", - "user": "user1", "accessType": "read", - "schema": "employee", - "json": "{\"id\":\"1\"}", - "result": { "hasAccess": false, "json": null, "errors": [ ] } - } - ] -} diff --git a/pom.xml b/pom.xml index 8698e67e5d..0945f4b1de 100644 --- a/pom.xml +++ b/pom.xml @@ -283,7 +283,6 @@ security-admin plugin-kafka plugin-solr - plugin-nestedstructure plugin-nifi plugin-nifi-registry plugin-presto @@ -352,7 +351,6 @@ security-admin plugin-kafka plugin-solr - plugin-nestedstructure plugin-nifi plugin-nifi-registry plugin-presto @@ -640,18 +638,6 @@ ranger-trino-plugin-shim - - ranger-nestedstructure-plugin - - agents-audit - agents-common - agents-cred - agents-installer - credentialbuilder - ranger-util - plugin-nestedstructure - - linux diff --git a/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java b/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java index 6cc3509d86..6c99df4e96 100644 --- a/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java +++ b/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java @@ -97,7 +97,7 @@ public enum PRINCIPAL_TYPE { USER, GROUP, ROLE } @Autowired RESTErrorUtil restErrorUtil; - public void createNewPolMappingForRefTable(RangerPolicy policy, XXPolicy xPolicy, XXServiceDef xServiceDef, boolean isDefaultPolicy) throws Exception { + public void createNewPolMappingForRefTable(RangerPolicy policy, XXPolicy xPolicy, XXServiceDef xServiceDef) throws Exception { if(policy == null) { return; } @@ -168,7 +168,7 @@ public void createNewPolMappingForRefTable(RangerPolicy policy, XXPolicy xPolicy } daoMgr.getXXPolicyRefResource().batchCreate(xPolResources); - final boolean isAdmin = rangerBizUtil.checkAdminAccess() || isDefaultPolicy; + final boolean isAdmin = rangerBizUtil.checkAdminAccess(); List xPolRoles = new ArrayList<>(); for (String role : roleNames) { @@ -397,7 +397,7 @@ private Long createPrincipal(String user) { ret = xUser.getId(); } } else { - LOG.warn("serviceConfigUser:[" + name + "] creation failed. This may be a transient/spurious condition that may correct itself when transaction is committed"); + LOG.error("serviceConfigUser:[" + name + "] creation failed"); } } break; diff --git a/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyRetriever.java b/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyRetriever.java index e94c37f7b9..238fecd483 100644 --- a/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyRetriever.java +++ b/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyRetriever.java @@ -343,7 +343,7 @@ String getUserScreenName(Long userId) { ret = userScreenNames.get(userId); if(ret == null) { - XXPortalUser user = daoMgr.getXXPortalUser().findById(userId); + XXPortalUser user = daoMgr.getXXPortalUser().getById(userId); if(user != null) { ret = user.getPublicScreenName(); diff --git a/security-admin/src/main/java/org/apache/ranger/biz/RoleDBStore.java b/security-admin/src/main/java/org/apache/ranger/biz/RoleDBStore.java index c19e3e1a1f..f501f28963 100644 --- a/security-admin/src/main/java/org/apache/ranger/biz/RoleDBStore.java +++ b/security-admin/src/main/java/org/apache/ranger/biz/RoleDBStore.java @@ -391,13 +391,13 @@ public Long getRoleVersion(String serviceName) { public Set getRoleNames(String userName, Set userGroups) throws Exception{ Set ret = new HashSet<>(); if (StringUtils.isNotEmpty(userName)) { - List xxRoleRefUsers = roleRefUpdater.getRangerDaoManager().getXXRoleRefUser().findByUserName(userName); + List xxRoleRefUsers = roleRefUpdater.daoMgr.getXXRoleRefUser().findByUserName(userName); for (XXRoleRefUser xxRoleRefUser : xxRoleRefUsers) { ret.add(getRole(xxRoleRefUser.getRoleId())); } } for(String userGroup : userGroups) { - List xxRoleRefGroups = roleRefUpdater.getRangerDaoManager().getXXRoleRefGroup().findByGroupName(userGroup); + List xxRoleRefGroups = roleRefUpdater.daoMgr.getXXRoleRefGroup().findByGroupName(userGroup); for (XXRoleRefGroup xxRoleRefGroup : xxRoleRefGroups) { ret.add(getRole(xxRoleRefGroup.getRoleId())); } diff --git a/security-admin/src/main/java/org/apache/ranger/biz/RoleRefUpdater.java b/security-admin/src/main/java/org/apache/ranger/biz/RoleRefUpdater.java index 56f7ec4c87..012d4c02f6 100644 --- a/security-admin/src/main/java/org/apache/ranger/biz/RoleRefUpdater.java +++ b/security-admin/src/main/java/org/apache/ranger/biz/RoleRefUpdater.java @@ -74,9 +74,7 @@ public class RoleRefUpdater { @Autowired RangerBizUtil xaBizUtil; - public RangerDaoManager getRangerDaoManager() { - return daoMgr; - } + public void createNewRoleMappingForRefTable(RangerRole rangerRole, Boolean createNonExistUserGroup) { if (rangerRole == null) { return; @@ -296,7 +294,7 @@ private Long createPrincipal(String user) { ret = xUser.getId(); } } else { - LOG.warn("serviceConfigUser:[" + name + "] creation failed. This may be a transient/spurious condition that may correct itself when transaction is committed"); + LOG.error("serviceConfigUser:[" + name + "] creation failed"); } } break; diff --git a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java index 9136336004..41fb3bb962 100644 --- a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java +++ b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java @@ -266,19 +266,19 @@ public class ServiceDBStore extends AbstractServiceStore { @Autowired RESTErrorUtil restErrorUtil; - + @Autowired RangerServiceService svcService; - + @Autowired StringUtil stringUtil; - + @Autowired RangerAuditFields rangerAuditFields; - + @Autowired RangerPolicyService policyService; - + @Autowired RangerPolicyLabelsService policyLabelsService; @@ -1510,6 +1510,7 @@ public RangerService createService(RangerService service) throws Exception { service = svcService.create(service); } XXService xCreatedService = daoMgr.getXXService().getById(service.getId()); + VXUser vXUser = null; XXServiceConfigMapDao xConfMapDao = daoMgr.getXXServiceConfigMap(); for (Entry configMap : validConfigs.entrySet()) { @@ -1520,14 +1521,14 @@ public RangerService createService(RangerService service) throws Exception { String userName = stringUtil.getValidUserName(configValue); XXUser xxUser = daoMgr.getXXUser().findByUserName(userName); if (xxUser != null) { - VXUser vXUser = xUserService.populateViewBean(xxUser); + vXUser = xUserService.populateViewBean(xxUser); } else { UserSessionBase usb = ContextUtil.getCurrentUserSession(); if (usb != null && !usb.isUserAdmin() && !usb.isSpnegoEnabled()) { throw restErrorUtil.createRESTException("User does not exist with given username: [" + userName + "] please use existing user", MessageEnums.OPER_NO_PERMISSION); } - xUserMgr.createServiceConfigUser(userName); + vXUser = xUserMgr.createServiceConfigUser(userName); } } @@ -1556,7 +1557,9 @@ public RangerService createService(RangerService service) throws Exception { xConfMap = xConfMapDao.create(xConfMap); } updateTabPermissions(service.getType(), validConfigs); - + if (LOG.isDebugEnabled()) { + LOG.debug("vXUser:[" + vXUser + "]"); + } RangerService createdService = svcService.getPopulatedViewObject(xCreatedService); if (createdService == null) { @@ -1681,7 +1684,7 @@ public RangerService updateService(RangerService service, Map op service = svcService.update(service); if (hasTagServiceValueChanged || hasIsEnabledChanged || hasServiceConfigForPluginChanged) { - updatePolicyVersion(service, RangerPolicyDelta.CHANGE_TYPE_SERVICE_CHANGE, null,false); + updatePolicyVersion(service, RangerPolicyDelta.CHANGE_TYPE_SERVICE_CHANGE, null, false); } } @@ -1696,6 +1699,7 @@ public RangerService updateService(RangerService service, Map op daoMgr.getXXServiceConfigMap().remove(dbConfigMap); } + VXUser vXUser = null; XXServiceConfigMapDao xConfMapDao = daoMgr.getXXServiceConfigMap(); for (Entry configMap : validConfigs.entrySet()) { String configKey = configMap.getKey(); @@ -1705,14 +1709,14 @@ public RangerService updateService(RangerService service, Map op String userName = stringUtil.getValidUserName(configValue); XXUser xxUser = daoMgr.getXXUser().findByUserName(userName); if (xxUser != null) { - VXUser vXUser = xUserService.populateViewBean(xxUser); + vXUser = xUserService.populateViewBean(xxUser); } else { UserSessionBase usb = ContextUtil.getCurrentUserSession(); if (usb != null && !usb.isUserAdmin()) { throw restErrorUtil.createRESTException("User does not exist with given username: [" + userName + "] please use existing user", MessageEnums.OPER_NO_PERMISSION); } - xUserMgr.createServiceConfigUser(userName); + vXUser = xUserMgr.createServiceConfigUser(userName); } } @@ -1754,7 +1758,9 @@ public RangerService updateService(RangerService service, Map op xConfMapDao.create(xConfMap); } updateTabPermissions(service.getType(), validConfigs); - + if (LOG.isDebugEnabled()) { + LOG.debug("vXUser:[" + vXUser + "]"); + } RangerService updService = svcService.getPopulatedViewObject(xUpdService); dataHistService.createObjectDataHistory(updService, RangerDataHistService.ACTION_UPDATE); bizUtil.createTrxLog(trxLogList); @@ -1988,15 +1994,6 @@ public PList getPaginatedServices(SearchFilter filter) throws Exc @Override public RangerPolicy createPolicy(RangerPolicy policy) throws Exception { - return createPolicy(policy, false); - } - - @Override - public RangerPolicy createDefaultPolicy(RangerPolicy policy) throws Exception { - return createPolicy(policy, true); - } - - public RangerPolicy createPolicy(RangerPolicy policy, boolean isDefaultPolicy) throws Exception { RangerService service = getServiceByName(policy.getService()); @@ -2045,7 +2042,7 @@ public RangerPolicy createPolicy(RangerPolicy policy, boolean isDefaultPolicy) t } XXPolicy xCreatedPolicy = daoMgr.getXXPolicy().getById(policy.getId()); - policyRefUpdater.createNewPolMappingForRefTable(policy, xCreatedPolicy, xServiceDef, isDefaultPolicy); + policyRefUpdater.createNewPolMappingForRefTable(policy, xCreatedPolicy, xServiceDef); createOrMapLabels(xCreatedPolicy, uniquePolicyLabels); RangerPolicy createdPolicy = policyService.getPopulatedViewObject(xCreatedPolicy); @@ -2218,7 +2215,7 @@ public RangerPolicy updatePolicy(RangerPolicy policy) throws Exception { policyRefUpdater.cleanupRefTables(policy); deleteExistingPolicyLabel(policy); - policyRefUpdater.createNewPolMappingForRefTable(policy, newUpdPolicy, xServiceDef, false); + policyRefUpdater.createNewPolMappingForRefTable(policy, newUpdPolicy, xServiceDef); createOrMapLabels(newUpdPolicy, uniquePolicyLabels); RangerPolicy updPolicy = policyService.getPopulatedViewObject(newUpdPolicy); @@ -3280,7 +3277,7 @@ void createDefaultPolicies(RangerService createdService) throws Exception { if (CollectionUtils.isNotEmpty(defaultPolicies)) { for (RangerPolicy defaultPolicy : defaultPolicies) { - createDefaultPolicy(defaultPolicy); + createPolicy(defaultPolicy); } } @@ -3305,7 +3302,7 @@ public void createZoneDefaultPolicies(Collection serviceNames, RangerSec defaultPolicy.setZoneName(zoneName); - createDefaultPolicy(defaultPolicy); + createPolicy(defaultPolicy); } } } @@ -3353,14 +3350,17 @@ List populateDefaultPolicies(RangerService service) throws Excepti if(serviceCheckUsers != null){ for (String userName : serviceCheckUsers) { if(!StringUtils.isEmpty(userName)){ + VXUser vXUser = null; XXUser xxUser = daoMgr.getXXUser().findByUserName(userName); if (xxUser != null) { - VXUser vXUser = xUserService.populateViewBean(xxUser); + vXUser = xUserService.populateViewBean(xxUser); } else { - xUserMgr.createServiceConfigUser(userName); - LOG.info("Creating Ambari Service Check User : "+ userName); + vXUser = xUserMgr.createServiceConfigUser(userName); + LOG.info("Creating Ambari Service Check User : "+vXUser.getName()); + } + if(vXUser != null){ + users.add(vXUser.getName()); } - users.add(userName); } } } @@ -3454,7 +3454,7 @@ void createDefaultPolicyUsersAndGroups(List defaultPolicies) { throw restErrorUtil.createRESTException("User does not exist with given username: [" + policyUser + "] please use existing user", MessageEnums.OPER_NO_PERMISSION); } - xUserMgr.createServiceConfigUser(userName); + xUserMgr.createServiceConfigUser(userName); } } } diff --git a/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java b/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java index 04968ecc53..9af354d09d 100755 --- a/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java +++ b/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java @@ -2492,6 +2492,7 @@ public void restrictSelfAccountDeletion(String loginID) { } } + @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) public VXUser createServiceConfigUser(String userName){ if (userName == null || "null".equalsIgnoreCase(userName) || userName.trim().isEmpty()) { logger.error("User Name: "+userName); @@ -2511,27 +2512,6 @@ public VXUser createServiceConfigUser(String userName){ return vXUser; } - public VXUser createServiceConfigUserSynchronously(String userName){ - if (userName == null || "null".equalsIgnoreCase(userName) || userName.trim().isEmpty()) { - logger.error("User Name: "+userName); - throw restErrorUtil.createRESTException("Please provide a valid username.",MessageEnums.INVALID_INPUT_DATA); - } - - VXUser vXUser = null; - - XXUser xxUser = daoManager.getXXUser().findByUserName(userName); - if (xxUser == null) { - ExternalUserCreator externalUserCreator = new ExternalUserCreator(userName); - externalUserCreator.run(); - xxUser = daoManager.getXXUser().findByUserName(userName); - } - - if (xxUser != null) { - vXUser = xUserService.populateViewBean(xxUser); - } - return vXUser; - } - protected void validatePassword(VXUser vXUser) { if (vXUser.getPassword() != null && !vXUser.getPassword().isEmpty()) { boolean checkPassword = false; diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXPolicyDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXPolicyDao.java index dc58be3df0..4677c37f32 100644 --- a/security-admin/src/main/java/org/apache/ranger/db/XXPolicyDao.java +++ b/security-admin/src/main/java/org/apache/ranger/db/XXPolicyDao.java @@ -18,9 +18,7 @@ package org.apache.ranger.db; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import javax.persistence.NoResultException; @@ -358,34 +356,4 @@ public List findPolicyByGUIDAndServiceIdAndZoneId(String guid, Long se } return ret; } - - public Map findDuplicatePoliciesByServiceAndResourceSignature() { - Map policies = new HashMap(); - try { - List rows = (List) getEntityManager().createNamedQuery("XXPolicy.findDuplicatePoliciesByServiceAndResourceSignature").getResultList(); - if (rows != null) { - for (Object[] row : rows) { - policies.put((String) row[0], (Long) row[1]); - } - } - } catch (NoResultException e) { - return null; - } catch (Exception ex) { - } - return policies; - } - - public List findByServiceIdAndResourceSignature(Long serviceId, String policySignature) { - if (policySignature == null || serviceId == null) { - return new ArrayList(); - } - try { - return getEntityManager().createNamedQuery("XXPolicy.findByServiceIdAndResourceSignature", tClass) - .setParameter("serviceId", serviceId) - .setParameter("resSignature", policySignature) - .getResultList(); - } catch (NoResultException e) { - return new ArrayList(); - } - } } \ No newline at end of file diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXPortalUserDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXPortalUserDao.java index 1787eeae60..8d15a324e7 100644 --- a/security-admin/src/main/java/org/apache/ranger/db/XXPortalUserDao.java +++ b/security-admin/src/main/java/org/apache/ranger/db/XXPortalUserDao.java @@ -128,25 +128,4 @@ public List findByUserSourceAndStatus(final int source, final int return null; } } - - public XXPortalUser findById(Long id) { - XXPortalUser xXPortalUser = null; - if (id == null) { - return xXPortalUser; - } - try { - xXPortalUser = new XXPortalUser(); - Object[] row = (Object[]) getEntityManager().createNamedQuery("XXPortalUser.findById").setParameter("id", id).getSingleResult(); - if (row != null) { - xXPortalUser.setFirstName((String) row[0]); - xXPortalUser.setLastName((String) row[1]); - xXPortalUser.setPublicScreenName((String) row[2]); - xXPortalUser.setLoginId((String) row[3]); - return xXPortalUser; - } - } catch (NoResultException e) { - return null; - } - return xXPortalUser; - } } diff --git a/security-admin/src/main/java/org/apache/ranger/patch/PatchForExternalUserStatusUpdate_J10056.java b/security-admin/src/main/java/org/apache/ranger/patch/PatchForExternalUserStatusUpdate_J10056.java index f4a122b38e..f1ed0978cc 100644 --- a/security-admin/src/main/java/org/apache/ranger/patch/PatchForExternalUserStatusUpdate_J10056.java +++ b/security-admin/src/main/java/org/apache/ranger/patch/PatchForExternalUserStatusUpdate_J10056.java @@ -28,13 +28,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionStatus; -import org.springframework.transaction.support.TransactionCallback; -import org.springframework.transaction.support.TransactionTemplate; @Component public class PatchForExternalUserStatusUpdate_J10056 extends BaseLoader { @@ -42,11 +36,7 @@ public class PatchForExternalUserStatusUpdate_J10056 extends BaseLoader { private static final Logger logger = LoggerFactory.getLogger(PatchForExternalUserStatusUpdate_J10056.class); @Autowired - private RangerDaoManager daoManager; - - @Autowired - @Qualifier(value = "transactionManager") - PlatformTransactionManager txManager; + private RangerDaoManager rngrDaoMgr; public static void main(String[] args) { try { @@ -80,27 +70,14 @@ public void execLoad() { } private void updateExternalUserStatus() { - XXPortalUserDao dao = this.daoManager.getXXPortalUser(); + XXPortalUserDao dao = this.rngrDaoMgr.getXXPortalUser(); List xXPortalUsers = dao.findByUserSourceAndStatus(RangerCommonEnums.USER_EXTERNAL,RangerCommonEnums.ACT_STATUS_DISABLED); if(CollectionUtils.isNotEmpty(xXPortalUsers)) { for (XXPortalUser xxPortalUser : xXPortalUsers) { if (xxPortalUser != null) { xxPortalUser.setStatus(RangerCommonEnums.ACT_STATUS_ACTIVE); - TransactionTemplate txTemplate = new TransactionTemplate(txManager); - txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - try { - txTemplate.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - dao.update(xxPortalUser, true); - return null; - } - }); - } catch (Throwable ex) { - logger.error("updateExternalUserStatus(): Failed to update DB for user: " + xxPortalUser.getLoginId() + " ", ex); - throw new RuntimeException(ex); - } + dao.update(xxPortalUser, true); } } } diff --git a/security-admin/src/main/java/org/apache/ranger/patch/PatchForKafkaServiceDefUpdate_J10025.java b/security-admin/src/main/java/org/apache/ranger/patch/PatchForKafkaServiceDefUpdate_J10025.java index 62847d725c..8367d3f6b2 100644 --- a/security-admin/src/main/java/org/apache/ranger/patch/PatchForKafkaServiceDefUpdate_J10025.java +++ b/security-admin/src/main/java/org/apache/ranger/patch/PatchForKafkaServiceDefUpdate_J10025.java @@ -21,7 +21,6 @@ import org.apache.ranger.authorization.utils.JsonUtils; import org.apache.ranger.biz.RangerBizUtil; import org.apache.ranger.biz.ServiceDBStore; -import org.apache.ranger.biz.XUserMgr; import org.apache.ranger.common.GUIDUtil; import org.apache.ranger.common.JSONUtil; import org.apache.ranger.common.RangerValidatorFactory; @@ -52,13 +51,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionStatus; -import org.springframework.transaction.support.TransactionCallback; -import org.springframework.transaction.support.TransactionTemplate; import java.util.ArrayList; import java.util.Arrays; @@ -115,13 +108,6 @@ public class PatchForKafkaServiceDefUpdate_J10025 extends BaseLoader { @Autowired ServiceDBStore svcStore; - @Autowired - XUserMgr xUserMgr; - - @Autowired - @Qualifier(value = "transactionManager") - PlatformTransactionManager txManager; - public static void main(String[] args) { logger.info("main()"); try { @@ -349,23 +335,7 @@ private void createDefaultPolicyForNewResources() { continue; } XXUser xxUser = daoMgr.getXXUser().findByUserName(user); - if (null == xxUser) { - TransactionTemplate txTemplate = new TransactionTemplate(txManager); - txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - try { - txTemplate.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - xUserMgr.createServiceConfigUserSynchronously(user); - return null; - } - }); - } catch (Exception exception) { - logger.error("Cannot create ServiceConfigUser(" + user + ")", exception); - } - } - xxUser = daoMgr.getXXUser().findByUserName(user); - if (null == xxUser) { + if (xxUser == null) { throw new RuntimeException(user + ": user does not exist. policy='" + xxPolicy.getName() + "' service='" + xxPolicy.getService() + "' user='" + user + "'"); } diff --git a/security-admin/src/main/java/org/apache/ranger/patch/PatchForKafkaServiceDefUpdate_J10033.java b/security-admin/src/main/java/org/apache/ranger/patch/PatchForKafkaServiceDefUpdate_J10033.java index e78c666db0..9f0717a402 100644 --- a/security-admin/src/main/java/org/apache/ranger/patch/PatchForKafkaServiceDefUpdate_J10033.java +++ b/security-admin/src/main/java/org/apache/ranger/patch/PatchForKafkaServiceDefUpdate_J10033.java @@ -42,13 +42,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionStatus; -import org.springframework.transaction.support.TransactionCallback; -import org.springframework.transaction.support.TransactionTemplate; import java.util.ArrayList; import java.util.Arrays; @@ -106,10 +100,6 @@ public class PatchForKafkaServiceDefUpdate_J10033 extends BaseLoader { @Autowired XUserMgr xUserMgr; - @Autowired - @Qualifier(value = "transactionManager") - PlatformTransactionManager txManager; - public static void main(String[] args) { logger.info("main()"); try { @@ -362,35 +352,17 @@ private void createDefaultPolicyForNewResources() { continue; } XXUser xxUser = daoMgr.getXXUser().findByUserName(user); - Long userId = null; if (xxUser == null) { - if (null == xxUser) { - logger.info(user +" user is not found, adding user: "+user); - TransactionTemplate txTemplate = new TransactionTemplate(txManager); - txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - try { - txTemplate.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - xUserMgr.createServiceConfigUserSynchronously(user); - return null; - } - }); - } catch(Exception exception) { - logger.error("Cannot create ServiceConfigUser(" + user + ")", exception); - } - } - + logger.info(user +" user is not found, adding user: "+user); + xUserMgr.createServiceConfigUser(user); xxUser = daoMgr.getXXUser().findByUserName(user); if (xxUser == null) { throw new RuntimeException(user + ": user does not exist. policy='" + xxPolicy.getName() + "' service='" + xxPolicy.getService() + "' user='" + user + "'"); } } - userId = xxUser.getId(); - XXPolicyItemUserPerm xUserPerm = new XXPolicyItemUserPerm(); - xUserPerm.setUserId(userId); + xUserPerm.setUserId(xxUser.getId()); xUserPerm.setPolicyItemId(createdXXPolicyItem.getId()); xUserPerm.setOrder(i); xUserPerm.setAddedByUserId(currentUserId); diff --git a/security-admin/src/main/java/org/apache/ranger/patch/PatchForMigratingOldRegimePolicyJson_J10046.java b/security-admin/src/main/java/org/apache/ranger/patch/PatchForMigratingOldRegimePolicyJson_J10046.java index dbffc56634..c40280629f 100644 --- a/security-admin/src/main/java/org/apache/ranger/patch/PatchForMigratingOldRegimePolicyJson_J10046.java +++ b/security-admin/src/main/java/org/apache/ranger/patch/PatchForMigratingOldRegimePolicyJson_J10046.java @@ -68,7 +68,6 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionTemplate; @@ -339,19 +338,7 @@ private void addUserNameRef(Long policyId, Set users) throws Exception { if (userObject == null) { logger.info(user +" user is not found, adding user: "+user); - TransactionTemplate txTemplate = new TransactionTemplate(txManager); - txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - try { - txTemplate.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - xUserMgr.createServiceConfigUserSynchronously(user); - return null; - } - }); - } catch(Exception exception) { - logger.error("Cannot create ServiceConfigUser(" + user + ")", exception); - } + xUserMgr.createServiceConfigUser(user); userObject = userDao.findByUserName(user); if (userObject == null) { throw new Exception(user + ": unknown user in policy [id=" + policyId + "]"); @@ -359,7 +346,6 @@ public Object doInTransaction(TransactionStatus status) { } userId = userObject.getId(); - logger.info("userId:"+userId); userIdMap.put(user, userId); } diff --git a/security-admin/src/main/java/org/apache/ranger/patch/PatchForSolrSvcDefAndPoliciesUpdate_J10055.java b/security-admin/src/main/java/org/apache/ranger/patch/PatchForSolrSvcDefAndPoliciesUpdate_J10055.java index f5f9f8956b..4684923cad 100644 --- a/security-admin/src/main/java/org/apache/ranger/patch/PatchForSolrSvcDefAndPoliciesUpdate_J10055.java +++ b/security-admin/src/main/java/org/apache/ranger/patch/PatchForSolrSvcDefAndPoliciesUpdate_J10055.java @@ -56,13 +56,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionStatus; -import org.springframework.transaction.support.TransactionCallback; -import org.springframework.transaction.support.TransactionTemplate; @Component public class PatchForSolrSvcDefAndPoliciesUpdate_J10055 extends BaseLoader { @@ -96,10 +90,6 @@ private enum NEW_RESOURCE { admin, config, schema } @Autowired private RangerValidatorFactory validatorFactory; - @Autowired - @Qualifier(value = "transactionManager") - PlatformTransactionManager txManager; - public static void main(String[] args) { logger.info("main()"); try { @@ -136,32 +126,20 @@ public void execLoad() { System.exit(1); } - TransactionTemplate txTemplate = new TransactionTemplate(txManager); - txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - try { - txTemplate.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - if (updateSolrSvcDef() == null) { - throw new RuntimeException("Error while updating " + SOLR_SVC_DEF_NAME + " service-def"); - } - return null; - } - }); - } catch (Throwable ex) { - logger.error("Error while updating " + SOLR_SVC_DEF_NAME + " service-def"); - throw new RuntimeException("Error while updating " + SOLR_SVC_DEF_NAME + " service-def"); - } - - final Long resTypeSvcDefId = embeddedSolrServiceDef.getId(); - final Long tagSvcDefId = EmbeddedServiceDefsUtil.instance().getTagServiceDefId(); - updateExistingRangerResPolicy(resTypeSvcDefId); - updateExistingRangerTagPolicies(tagSvcDefId); - - deleteOldAccessTypeRefs(resTypeSvcDefId); - deleteOldAccessTypeRefs(tagSvcDefId); + if (updateSolrSvcDef() != null) { + final Long resTypeSvcDefId = embeddedSolrServiceDef.getId(); + final Long tagSvcDefId = EmbeddedServiceDefsUtil.instance().getTagServiceDefId(); + updateExistingRangerResPolicy(resTypeSvcDefId); + updateExistingRangerTagPolicies(tagSvcDefId); + + deleteOldAccessTypeRefs(resTypeSvcDefId); + deleteOldAccessTypeRefs(tagSvcDefId); + } else { + logger.error("Error while updating " + SOLR_SVC_DEF_NAME + " service-def"); + throw new RuntimeException("Error while updating " + SOLR_SVC_DEF_NAME + " service-def"); + } } catch (Exception e) { - logger.error("Error whille executing PatchForSolrSvcDefAndPoliciesUpdate_J10055, Error - ", e); + logger.error("Error whille executing PatchForSolrSvcDefAndPoliciesUpdate_J10055 - ", e); System.exit(1); } @@ -192,211 +170,160 @@ private void updateExistingRangerResPolicy(Long svcDefId) throws Exception { logger.info("<== PatchForSolrSvcDefAndPoliciesUpdate_J10055.updateExistingRangerResPolicy(...)"); } - private void updateZoneResourceMapping(final XXService solrDBSvc) throws Exception { - logger.info("==> PatchForSolrSvcDefAndPoliciesUpdate_J10055.updateZoneResourceMapping(...)"); - // Update Zone Resource Mapping For Solr Services - final String svcName = solrDBSvc.getName(); - SearchFilter filter = new SearchFilter(); - filter.setParam(SearchFilter.SERVICE_NAME, svcName); - List secZoneList = this.secZoneDBStore.getSecurityZones(filter); - long index = 1; - for (RangerSecurityZone secZone : secZoneList) { - logger.info("updateZoneResourceMapping() processing: [" + index + "/" + secZoneList.size() + "]"); - TransactionTemplate txTemplate = new TransactionTemplate(txManager); - txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - try { - txTemplate.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - try { - updateZone(secZone, svcName); - } catch (Exception e) { - throw new RuntimeException(e); - } - return null; - } - }); - } catch (Throwable ex) { - logger.error("updateZoneResourceMapping(): Failed to update zone: " + secZone.getName() + " ", ex); - throw new RuntimeException(ex); - } - index++; - } - logger.info("<== PatchForSolrSvcDefAndPoliciesUpdate_J10055.updateZoneResourceMapping(...)"); - } - - private void updateZone(RangerSecurityZone secZone, String svcName) throws Exception { - RangerSecurityZoneService secZoneSvc = secZone.getServices().get(svcName);// get secZoneSvc only for this svcName - List>> solrZoneSvcResourcesMapList = secZoneSvc.getResources(); - - final Set>> updatedResMapSet = new HashSet>>(); - for (HashMap> existingResMap : solrZoneSvcResourcesMapList) { - boolean isAllResource = false; // * - for (Map.Entry> resNameValueListMap : existingResMap.entrySet()) { - - updatedResMapSet.add(existingResMap); - final List resourceValueList = resNameValueListMap.getValue(); - - if (CollectionUtils.isNotEmpty(resourceValueList) && resourceValueList.indexOf("*") >= 0) { - updatedResMapSet.clear(); - updatedResMapSet.add(existingResMap); - isAllResource = true; - break; - } else { - HashMap> updatedResMap = new HashMap>(); - updatedResMap.put(NEW_RESOURCE.schema.name(), resourceValueList); - updatedResMapSet.add(updatedResMap); - } - } - - if (isAllResource) { - final List allResVal = Arrays.asList("*"); - for (NEW_RESOURCE newRes : NEW_RESOURCE.values()) { - HashMap> updatedResMap = new HashMap>(); - updatedResMap.put(newRes.name(), allResVal); - updatedResMapSet.add(updatedResMap); - } - secZoneSvc.setResources(new ArrayList>>(updatedResMapSet)); - break; - } - secZoneSvc.setResources(new ArrayList>>(updatedResMapSet)); - } - this.secZoneDBStore.updateSecurityZoneById(secZone); - } - - private void updateExistingRangerTagPolicies(Long svcDefId) throws Exception { - List dbServices = daoMgr.getXXService().findByServiceDefId(svcDefId); - if (CollectionUtils.isNotEmpty(dbServices)) { - for (XXService dbService : dbServices) { - SearchFilter filter = new SearchFilter(); - filter.setParam(SearchFilter.SERVICE_NAME, dbService.getName()); - updateTagPolicies(svcDBStore.getServicePolicies(dbService.getId(), filter)); - } - } - } + private void updateZoneResourceMapping(final XXService solrDBSvc) throws Exception { + logger.info("==> PatchForSolrSvcDefAndPoliciesUpdate_J10055.updateZoneResourceMapping(...)"); + // Update Zone Resource Mapping For Solr Services + final String svcName = solrDBSvc.getName(); + SearchFilter filter = new SearchFilter(); + filter.setParam(SearchFilter.SERVICE_NAME, svcName); + List secZoneList = this.secZoneDBStore.getSecurityZones(filter); + for (RangerSecurityZone secZone : secZoneList) { + RangerSecurityZoneService secZoneSvc = secZone.getServices().get(svcName);// get secZoneSvc only for this svcName + List>> solrZoneSvcResourcesMapList = secZoneSvc.getResources(); + + final Set>> updatedResMapSet = new HashSet>>(); + for (HashMap> existingResMap : solrZoneSvcResourcesMapList) { + boolean isAllResource = false; // * + for (Map.Entry> resNameValueListMap : existingResMap.entrySet()) { + + updatedResMapSet.add(existingResMap); + final List resourceValueList = resNameValueListMap.getValue(); + + if (CollectionUtils.isNotEmpty(resourceValueList) && resourceValueList.indexOf("*") >= 0) { + updatedResMapSet.clear(); + updatedResMapSet.add(existingResMap); + isAllResource = true; + break; + } else { + HashMap> updatedResMap = new HashMap>(); + updatedResMap.put(NEW_RESOURCE.schema.name(), resourceValueList); + updatedResMapSet.add(updatedResMap); + } + } - private void updateTagPolicies(List tagServicePolicies) { - if (CollectionUtils.isNotEmpty(tagServicePolicies)) { - long index = 1; - for (RangerPolicy exPolicy : tagServicePolicies) { - logger.info("updateTagPolicies() processing: [" + index + "/" + tagServicePolicies.size() + "]"); - TransactionTemplate txTemplate = new TransactionTemplate(txManager); - txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - try { - txTemplate.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - updateTagPolicyItemAccess(exPolicy.getPolicyItems()); - updateTagPolicyItemAccess(exPolicy.getAllowExceptions()); - updateTagPolicyItemAccess(exPolicy.getDenyPolicyItems()); - updateTagPolicyItemAccess(exPolicy.getDenyExceptions()); - try { - svcDBStore.updatePolicy(exPolicy); - } catch (Exception e) { - throw new RuntimeException(e); - } - return null; - } - }); - } catch (Throwable ex) { - logger.error("updateTagPolicies(): Failed to update policy: " + exPolicy.getName() + " ", ex); - throw new RuntimeException(ex); - } - index++; - } - } - } + if (isAllResource) { + final List allResVal = Arrays.asList("*"); + for (NEW_RESOURCE newRes : NEW_RESOURCE.values()) { + HashMap> updatedResMap = new HashMap>(); + updatedResMap.put(newRes.name(), allResVal); + updatedResMapSet.add(updatedResMap); + } + secZoneSvc.setResources(new ArrayList>>(updatedResMapSet)); + break; + } + secZoneSvc.setResources(new ArrayList>>(updatedResMapSet)); + } + this.secZoneDBStore.updateSecurityZoneById(secZone); + logger.info("<== PatchForSolrSvcDefAndPoliciesUpdate_J10055.updateZoneResourceMapping(...)"); + } + } - private void updateResPolicies(List policies) { - if (CollectionUtils.isNotEmpty(policies)) { - long index = 1; - for (RangerPolicy exPolicy : policies) { - logger.info("updateResPolicies() processing: [" + index + "/" + policies.size() + "]"); - TransactionTemplate txTemplate = new TransactionTemplate(txManager); - txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - try { - txTemplate.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - createOrUpdatePolicy(exPolicy); - return null; - } - }); - } catch (Throwable ex) { - logger.error("updateResPolicies(): Failed to create/update policy: " + exPolicy.getName() + " ", ex); - throw new RuntimeException(ex); - } - index++; - } - } - } + private void updateExistingRangerTagPolicies(Long svcDefId) throws Exception { + logger.info("==> PatchForSolrSvcDefAndPoliciesUpdate_J10055.updateExistingRangerTagPolicies(" + svcDefId + ")"); + List dbServices = daoMgr.getXXService().findByServiceDefId(svcDefId); + if (CollectionUtils.isNotEmpty(dbServices)) { + for (XXService dbService : dbServices) { + SearchFilter filter = new SearchFilter(); + filter.setParam(SearchFilter.SERVICE_NAME, dbService.getName()); + updateTagPolicies(svcDBStore.getServicePolicies(dbService.getId(), filter)); + } + } + logger.info("<== PatchForSolrSvcDefAndPoliciesUpdate_J10055.updateExistingRangerTagPolicies(" + svcDefId + ")"); +} + + private void updateTagPolicies(List tagServicePolicies) { + logger.info("==> PatchForSolrSvcDefAndPoliciesUpdate_J10055.updateTagPolicies(...)"); + if (CollectionUtils.isNotEmpty(tagServicePolicies)) { + for (RangerPolicy exPolicy : tagServicePolicies) { + try { + updateTagPolicyItemAccess(exPolicy.getPolicyItems()); + updateTagPolicyItemAccess(exPolicy.getAllowExceptions()); + updateTagPolicyItemAccess(exPolicy.getDenyPolicyItems()); + updateTagPolicyItemAccess(exPolicy.getDenyExceptions()); + this.svcDBStore.updatePolicy(exPolicy); + } catch (Exception e) { + logger.error("Failed to apply the patch - ", e); + System.exit(1); + } + } + } + logger.info("<== PatchForSolrSvcDefAndPoliciesUpdate_J10055.updateTagPolicies(...)"); + } - private void createOrUpdatePolicy(RangerPolicy exPolicy) { - // Filter policy items which are eligible for admin,config and schema resources - final List filteredAllowPolciyItems = filterPolicyItemsForAdminPermission(exPolicy.getPolicyItems()); - final List filteredAllowExcpPolItems = filterPolicyItemsForAdminPermission(exPolicy.getAllowExceptions()); - final List filteredDenyPolItems = filterPolicyItemsForAdminPermission(exPolicy.getDenyPolicyItems()); - final List filteredDenyExcpPolItems = filterPolicyItemsForAdminPermission(exPolicy.getDenyExceptions()); - - // check if there is a need to create additional policies with - // admin/config/schema resource(s) - final boolean splitPolicy = (filteredAllowPolciyItems.size() > 0 || filteredAllowExcpPolItems.size() > 0 || filteredDenyPolItems.size() > 0 || filteredDenyExcpPolItems.size() > 0); - if (splitPolicy) { - RangerPolicy newPolicyForNewResource = new RangerPolicy(); - newPolicyForNewResource.setService(exPolicy.getService()); - newPolicyForNewResource.setServiceType(exPolicy.getServiceType()); - newPolicyForNewResource.setPolicyPriority(exPolicy.getPolicyPriority()); - - RangerPolicyResource newRes = new RangerPolicyResource(); - boolean isAllResources = false; - // Only one entry expected - for (Map.Entry entry : exPolicy.getResources().entrySet()) { - RangerPolicyResource exPolRes = entry.getValue(); - newRes.setIsExcludes(exPolRes.getIsExcludes()); - newRes.setIsRecursive(exPolRes.getIsRecursive()); - newRes.setValues(exPolRes.getValues()); - if (CollectionUtils.isNotEmpty(exPolRes.getValues()) && exPolRes.getValues().indexOf("*") >= 0) { - isAllResources = true; - } - } + private void updateResPolicies(List policies) { + logger.info("==> PatchForSolrSvcDefAndPoliciesUpdate_J10055.updateResPolicies(...)"); + if (CollectionUtils.isNotEmpty(policies)) { + for (RangerPolicy exPolicy : policies) { + // Filter policy items which are eligible for admin,config and schema resources + final List filteredAllowPolciyItems = filterPolicyItemsForAdminPermission(exPolicy.getPolicyItems()); + final List filteredAllowExcpPolItems = filterPolicyItemsForAdminPermission(exPolicy.getAllowExceptions()); + final List filteredDenyPolItems = filterPolicyItemsForAdminPermission(exPolicy.getDenyPolicyItems()); + final List filteredDenyExcpPolItems = filterPolicyItemsForAdminPermission(exPolicy.getDenyExceptions()); + + // check if there is a need to create additional policies with admin/config/schema resource(s) + final boolean splitPolicy = (filteredAllowPolciyItems.size() > 0 || filteredAllowExcpPolItems.size() > 0 || filteredDenyPolItems.size() > 0 || filteredDenyExcpPolItems.size() > 0); + if (splitPolicy) { + RangerPolicy newPolicyForNewResource = new RangerPolicy(); + newPolicyForNewResource.setService(exPolicy.getService()); + newPolicyForNewResource.setServiceType(exPolicy.getServiceType()); + newPolicyForNewResource.setPolicyPriority(exPolicy.getPolicyPriority()); + + RangerPolicyResource newRes = new RangerPolicyResource(); + boolean isAllResources = false; + // Only one entry expected + for (Map.Entry entry : exPolicy.getResources().entrySet()) { + RangerPolicyResource exPolRes = entry.getValue(); + newRes.setIsExcludes(exPolRes.getIsExcludes()); + newRes.setIsRecursive(exPolRes.getIsRecursive()); + newRes.setValues(exPolRes.getValues()); + if (CollectionUtils.isNotEmpty(exPolRes.getValues()) && exPolRes.getValues().indexOf("*") >= 0) { + isAllResources = true; + } + } - newPolicyForNewResource.setPolicyItems(filteredAllowPolciyItems); - newPolicyForNewResource.setAllowExceptions(filteredAllowExcpPolItems); - newPolicyForNewResource.setDenyPolicyItems(filteredDenyPolItems); - newPolicyForNewResource.setDenyExceptions(filteredDenyExcpPolItems); - newPolicyForNewResource.setOptions(exPolicy.getOptions()); - newPolicyForNewResource.setValiditySchedules(exPolicy.getValiditySchedules()); - newPolicyForNewResource.setPolicyLabels(exPolicy.getPolicyLabels()); - newPolicyForNewResource.setConditions(exPolicy.getConditions()); - newPolicyForNewResource.setIsDenyAllElse(exPolicy.getIsDenyAllElse()); - newPolicyForNewResource.setZoneName(exPolicy.getZoneName()); - - try { - if (isAllResources) { - for (NEW_RESOURCE resType : NEW_RESOURCE.values()) { - createNewPolicy(resType.name(), newPolicyForNewResource, newRes, exPolicy.getName()); - } - } else { - createNewPolicy(NEW_RESOURCE.schema.name(), newPolicyForNewResource, newRes, exPolicy.getName()); - } + newPolicyForNewResource.setPolicyItems(filteredAllowPolciyItems); + newPolicyForNewResource.setAllowExceptions(filteredAllowExcpPolItems); + newPolicyForNewResource.setDenyPolicyItems(filteredDenyPolItems); + newPolicyForNewResource.setDenyExceptions(filteredDenyExcpPolItems); + newPolicyForNewResource.setOptions(exPolicy.getOptions()); + newPolicyForNewResource.setValiditySchedules(exPolicy.getValiditySchedules()); + newPolicyForNewResource.setPolicyLabels(exPolicy.getPolicyLabels()); + newPolicyForNewResource.setConditions(exPolicy.getConditions()); + newPolicyForNewResource.setIsDenyAllElse(exPolicy.getIsDenyAllElse()); + newPolicyForNewResource.setZoneName(exPolicy.getZoneName()); + + try { + if (isAllResources) { + for (NEW_RESOURCE resType : NEW_RESOURCE.values()) { + createNewPolicy(resType.name(), newPolicyForNewResource, newRes, exPolicy.getName()); + } + } else { + createNewPolicy(NEW_RESOURCE.schema.name(), newPolicyForNewResource, newRes, exPolicy.getName()); + } - } catch (Exception e) { - throw new RuntimeException(e); - } - } - try { - // update policy items - updateResPolicyItemAccess(exPolicy.getPolicyItems()); - updateResPolicyItemAccess(exPolicy.getAllowExceptions()); - updateResPolicyItemAccess(exPolicy.getDenyPolicyItems()); - updateResPolicyItemAccess(exPolicy.getDenyExceptions()); - this.svcDBStore.updatePolicy(exPolicy); - } catch (Exception e) { - throw new RuntimeException(e); - } - } + } catch (Exception e) { + logger.error("Failed to apply the patch - ", e); + System.exit(1); + } + } + try { + // update policy items + updateResPolicyItemAccess(exPolicy.getPolicyItems()); + updateResPolicyItemAccess(exPolicy.getAllowExceptions()); + updateResPolicyItemAccess(exPolicy.getDenyPolicyItems()); + updateResPolicyItemAccess(exPolicy.getDenyExceptions()); + this.svcDBStore.updatePolicy(exPolicy); + } catch (Exception e) { + logger.error("Failed to apply the patch - ", e); + System.exit(1); + } + } + } + logger.info("<== PatchForSolrSvcDefAndPoliciesUpdate_J10055.updateResPolicies(...)"); + } private void createNewPolicy(final String resType, final RangerPolicy newPolicy, final RangerPolicyResource newRes, final String exPolicyName) throws Exception { + logger.info("==> PatchForSolrSvcDefAndPoliciesUpdate_J10055.createNewPolicy(...)"); final String newPolicyName = resType + " - '" + exPolicyName + "'"; newPolicy.setName(newPolicyName); newPolicy.setDescription(newPolicyName); @@ -407,9 +334,11 @@ private void createNewPolicy(final String resType, final RangerPolicy newPolicy, newPolicy.setResourceSignature(null); newPolicy.setGuid(null); this.svcDBStore.createPolicy(newPolicy); + logger.info("<== PatchForSolrSvcDefAndPoliciesUpdate_J10055.createNewPolicy(...)"); } private void updateResPolicyItemAccess(List policyItems) { + logger.info("==> PatchForSolrSvcDefAndPoliciesUpdate_J10055.updateResPolicyItemAccess(...)"); Set newRangerPolicyItemAccess = new HashSet(); if (CollectionUtils.isNotEmpty(policyItems)) { for (RangerPolicyItem exPolicyItem : policyItems) { @@ -439,9 +368,11 @@ private void updateResPolicyItemAccess(List policyItems) { } } } + logger.info("<== PatchForSolrSvcDefAndPoliciesUpdate_J10055.updateResPolicyItemAccess(...)"); } private void updateTagPolicyItemAccess(List policyItems) { + logger.info("==> PatchForSolrSvcDefAndPoliciesUpdate_J10055.updateTagPolicyItemAccess(...)"); List newPolicyItems = new ArrayList(); Set newRangerPolicyItemAccess = new HashSet(); if (CollectionUtils.isNotEmpty(policyItems)) { @@ -474,9 +405,11 @@ private void updateTagPolicyItemAccess(List policyItems) { } } } + logger.info("<== PatchForSolrSvcDefAndPoliciesUpdate_J10055.updateTagPolicyItemAccess(...)"); } private List filterPolicyItemsForAdminPermission(List policyItems) { + logger.info("==> PatchForSolrSvcDefAndPoliciesUpdate_J10055.filterPolicyItemsForAdminPermission(...)"); // Add only those policy items who's access permission list contains 'solr_admin' permission List filteredPolicyItems = new ArrayList(); Set newRangerPolicyItemAccess = new HashSet(); @@ -489,6 +422,7 @@ private List filterPolicyItemsForAdminPermission( filteredPolicyItems.add(newPolicyItem); } })); + logger.info("<== PatchForSolrSvcDefAndPoliciesUpdate_J10055.filterPolicyItemsForAdminPermission(...)"); return filteredPolicyItems; } @@ -505,7 +439,7 @@ private RangerServiceDef updateSolrSvcDef() { xXServiceDefObj = daoMgr.getXXServiceDef().findByName(SOLR_SVC_DEF_NAME); if (xXServiceDefObj == null) { logger.info(xXServiceDefObj + ": service-def not found. No patching is needed"); - System.exit(0); + System.out.println(0); } embeddedSolrResourceDefs = embeddedSolrServiceDef.getResources(); // ResourcesType @@ -518,7 +452,6 @@ private RangerServiceDef updateSolrSvcDef() { } } catch (Exception e) { logger.error("Error while updating " + SOLR_SVC_DEF_NAME + " service-def", e); - throw new RuntimeException(e); } logger.info("<== PatchForSolrSvcDefAndPoliciesUpdate_J10055.updateSolrSvcDef()"); return ret; @@ -550,7 +483,7 @@ private void deleteOldAccessTypeRefs(Long svcDefId) { } private void updateServiceConfig(final XXService dbService) throws Exception { - logger.info("==> PatchForSolrSvcDefAndPoliciesUpdate_J10055.updateServiceConfig()"); + final RangerService rangerSvc = this.svcDBStore.getService(dbService.getId()); final Map configMap = rangerSvc != null ? rangerSvc.getConfigs() : null; Set accessTypeSet = new HashSet(); @@ -580,7 +513,6 @@ private void updateServiceConfig(final XXService dbService) throws Exception { rangerSvc.setConfigs(configMap); this.svcDBStore.updateService(rangerSvc, null); } - logger.info("<== PatchForSolrSvcDefAndPoliciesUpdate_J10055.updateServiceConfig()"); } private void updateDefaultAuditFilter(final String svcDefName) throws Exception { @@ -615,4 +547,4 @@ private void updateDefaultAuditFilter(final String svcDefName) throws Exception } logger.info("<== PatchForSolrSvcDefAndPoliciesUpdate_J10055.updateAtlasDefaultAuditFilter()"); } -} \ No newline at end of file +} diff --git a/security-admin/src/main/java/org/apache/ranger/patch/PatchForSyncSourceUpdate_J10054.java b/security-admin/src/main/java/org/apache/ranger/patch/PatchForSyncSourceUpdate_J10054.java index 99de47310a..bbde1a4df0 100644 --- a/security-admin/src/main/java/org/apache/ranger/patch/PatchForSyncSourceUpdate_J10054.java +++ b/security-admin/src/main/java/org/apache/ranger/patch/PatchForSyncSourceUpdate_J10054.java @@ -28,13 +28,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionStatus; -import org.springframework.transaction.support.TransactionCallback; -import org.springframework.transaction.support.TransactionTemplate; import java.util.List; import java.util.Map; @@ -45,10 +39,6 @@ public class PatchForSyncSourceUpdate_J10054 extends BaseLoader{ @Autowired RangerDaoManager daoManager; - @Autowired - @Qualifier(value = "transactionManager") - PlatformTransactionManager txManager; - private static final Logger logger = LoggerFactory.getLogger(PatchForSyncSourceUpdate_J10054.class); @Override @@ -97,39 +87,23 @@ public boolean updateSyncSourceForUsers(){ if (StringUtils.isNotEmpty(otherAttributes) && StringUtils.isEmpty(syncSource)){ syncSource = (String) gson.fromJson(otherAttributes, Map.class).get(UgsyncCommonConstants.SYNC_SOURCE); xUser.setSyncSource(syncSource); - - TransactionTemplate txTemplate = new TransactionTemplate(txManager); - txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - - String finalSyncSource = syncSource; - try { - txTemplate.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - if (StringUtils.isNotEmpty(finalSyncSource)) { - XXPortalUser xXPortalUser = daoManager.getXXPortalUser().findByLoginId(xUser.getName()); - if (xXPortalUser != null && xXPortalUser.getUserSource() == 0){ - /* updating the user source to external for users which had some sync source prior to upgrade - but the user source was marked internal to due bugs which were fixed later. - See RANGER-3297 for more info - */ - xXPortalUser.setUserSource(1); - daoManager.getXXPortalUser().update(xXPortalUser); - if (logger.isDebugEnabled()) { - logger.debug("USER: Name: " + xUser.getName() + " userSource changed to External"); - } - } - } - daoManager.getXXUser().update(xUser); - if (logger.isDebugEnabled()) { - logger.debug("USER: Name: " + xUser.getName() + " syncSource updated to " + finalSyncSource); - } - return null; + if (StringUtils.isNotEmpty(syncSource)) { + XXPortalUser xXPortalUser = daoManager.getXXPortalUser().findByLoginId(xUser.getName()); + if (xXPortalUser != null && xXPortalUser.getUserSource() == 0){ + /* updating the user source to external for users which had some sync source prior to upgrade + but the user source was marked internal to due bugs which were fixed later. + See RANGER-3297 for more info + */ + xXPortalUser.setUserSource(1); + daoManager.getXXPortalUser().update(xXPortalUser); + if (logger.isDebugEnabled()) { + logger.debug("USER: Name: " + xUser.getName() + " userSource changed to External"); } - }); - } catch (Throwable ex) { - logger.error("updateSyncSourceForUsers(): Failed to update DB for user: " + xUser.getName() + " ", ex); - throw new RuntimeException(ex); + } + } + daoManager.getXXUser().update(xUser); + if (logger.isDebugEnabled()) { + logger.debug("USER: Name: " + xUser.getName() + " syncSource updated to " + syncSource); } } else if (logger.isDebugEnabled()) { logger.debug("Skipping syncSource update for user: " + xUser.getName() ); @@ -156,21 +130,7 @@ public boolean updateSyncSourceForGroups(){ if (logger.isDebugEnabled()) { logger.debug("GROUP: Name: " + xGroup.getName() + " syncSource updated to " + syncSource); } - - TransactionTemplate txTemplate = new TransactionTemplate(txManager); - txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - try { - txTemplate.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - daoManager.getXXGroup().update(xGroup); - return null; - } - }); - } catch (Throwable ex) { - logger.error("updateSyncSourceForGroups(): Failed to update DB for group: " + xGroup.getName() + " ", ex); - throw new RuntimeException(ex); - } + daoManager.getXXGroup().update(xGroup); } else if (logger.isDebugEnabled()) { logger.debug("Skipping syncSource update for group: " + xGroup.getName() ); } diff --git a/security-admin/src/main/java/org/apache/ranger/patch/PatchForUpdatingPolicyJson_J10019.java b/security-admin/src/main/java/org/apache/ranger/patch/PatchForUpdatingPolicyJson_J10019.java index 6eb3315e75..ae6158ab02 100644 --- a/security-admin/src/main/java/org/apache/ranger/patch/PatchForUpdatingPolicyJson_J10019.java +++ b/security-admin/src/main/java/org/apache/ranger/patch/PatchForUpdatingPolicyJson_J10019.java @@ -92,7 +92,6 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionTemplate; @@ -357,19 +356,7 @@ private void addUserNameRef(Long policyId, Set users) throws Exception { if (userObject == null) { logger.info(user +" user is not found, adding user: "+user); - TransactionTemplate txTemplate = new TransactionTemplate(txManager); - txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); - try { - txTemplate.execute(new TransactionCallback() { - @Override - public Object doInTransaction(TransactionStatus status) { - xUserMgr.createServiceConfigUserSynchronously(user); - return null; - } - }); - } catch(Exception exception) { - logger.error("Cannot create ServiceConfigUser(" + user + ")", exception); - } + xUserMgr.createServiceConfigUser(user); userObject = userDao.findByUserName(user); if (userObject == null) { throw new Exception(user + ": unknown user in policy [id=" + policyId + "]"); @@ -377,7 +364,6 @@ public Object doInTransaction(TransactionStatus status) { } userId = userObject.getId(); - logger.info("userId:"+userId); userIdMap.put(user, userId); } diff --git a/security-admin/src/main/java/org/apache/ranger/patch/PatchPreSql_058_ForUpdateToUniqueResoureceSignature_J10053.java b/security-admin/src/main/java/org/apache/ranger/patch/PatchPreSql_058_ForUpdateToUniqueResoureceSignature_J10053.java index fb7e5fd409..0227298aaf 100644 --- a/security-admin/src/main/java/org/apache/ranger/patch/PatchPreSql_058_ForUpdateToUniqueResoureceSignature_J10053.java +++ b/security-admin/src/main/java/org/apache/ranger/patch/PatchPreSql_058_ForUpdateToUniqueResoureceSignature_J10053.java @@ -17,18 +17,14 @@ package org.apache.ranger.patch; -import java.util.Iterator; import java.util.List; -import java.util.Map; import org.apache.commons.collections.CollectionUtils; import org.apache.ranger.authorization.utils.JsonUtils; import org.apache.ranger.biz.ServiceDBStore; import org.apache.ranger.common.RangerFactory; import org.apache.ranger.db.RangerDaoManager; -import org.apache.ranger.db.XXPolicyLabelMapDao; import org.apache.ranger.entity.XXPolicy; -import org.apache.ranger.entity.XXPolicyLabelMap; import org.apache.ranger.plugin.model.RangerPolicy; import org.apache.ranger.plugin.model.RangerPolicyResourceSignature; import org.apache.ranger.util.CLIUtil; @@ -93,7 +89,6 @@ public void execLoad() { try { updateDisabledPolicyResourceSignature(); - removeDuplicateResourceSignaturesPolicies(); } catch (Exception e) { logger.error("Error while PatchPreSql_058_ForUpdateToUniqueResoureceSignature_J10053()", e); System.exit(1); @@ -133,49 +128,4 @@ private void updateDisabledPolicyResourceSignature() throws Exception { } } - private void removeDuplicateResourceSignaturesPolicies() throws Exception { - logger.info("==> removeDuplicateResourceSignaturesPolicies() "); - Map duplicateEntries = daoMgr.getXXPolicy().findDuplicatePoliciesByServiceAndResourceSignature(); - if (duplicateEntries != null && duplicateEntries.size() > 0) { - logger.info("Total number of possible duplicate policies:" + duplicateEntries.size()); - for (Map.Entry entry : duplicateEntries.entrySet()) { - logger.info("Duplicate policy Entry - {ResourceSignature:" + entry.getKey() + ", ServiceId:" + entry.getValue() + "}"); - List xxPolicyList = daoMgr.getXXPolicy().findByServiceIdAndResourceSignature(entry.getValue(), entry.getKey()); - if (CollectionUtils.isNotEmpty(xxPolicyList) && xxPolicyList.size() > 1) { - Iterator duplicatePolicies = xxPolicyList.iterator(); - duplicatePolicies.next(); - while (duplicatePolicies.hasNext()) { - XXPolicy xxPolicy = duplicatePolicies.next(); - if (xxPolicy != null) { - logger.info("Attempting to Remove duplicate policy:{" + xxPolicy.getId() + ":" + xxPolicy.getName() + "}"); - if (cleanupRefTables(xxPolicy.getId())) { - daoMgr.getXXPolicy().remove(xxPolicy.getId()); - } - } - } - } - } - } else { - logger.info("no duplicate Policy found"); - } - } - - private Boolean cleanupRefTables(Long policyId) { - if (policyId == null) { - return false; - } - daoMgr.getXXPolicyRefResource().deleteByPolicyId(policyId); - daoMgr.getXXPolicyRefRole().deleteByPolicyId(policyId); - daoMgr.getXXPolicyRefGroup().deleteByPolicyId(policyId); - daoMgr.getXXPolicyRefUser().deleteByPolicyId(policyId); - daoMgr.getXXPolicyRefAccessType().deleteByPolicyId(policyId); - daoMgr.getXXPolicyRefCondition().deleteByPolicyId(policyId); - daoMgr.getXXPolicyRefDataMaskType().deleteByPolicyId(policyId); - XXPolicyLabelMapDao policyLabelMapDao = daoMgr.getXXPolicyLabelMap(); - List xxPolicyLabelMaps = policyLabelMapDao.findByPolicyId(policyId); - for (XXPolicyLabelMap xxPolicyLabelMap : xxPolicyLabelMaps) { - policyLabelMapDao.remove(xxPolicyLabelMap); - } - return true; - } } diff --git a/security-admin/src/main/java/org/apache/ranger/rest/RoleREST.java b/security-admin/src/main/java/org/apache/ranger/rest/RoleREST.java index a2ab49a88f..1e74a5ffd0 100644 --- a/security-admin/src/main/java/org/apache/ranger/rest/RoleREST.java +++ b/security-admin/src/main/java/org/apache/ranger/rest/RoleREST.java @@ -909,7 +909,7 @@ private void ensureAdminAccess(String serviceName, String userName) throws Excep effectiveUser = loggedInUser; } - if (!bizUtil.isUserRangerAdmin(effectiveUser) && !svcStore.isServiceAdminUser(serviceName, effectiveUser)) { + if (!bizUtil.isUserRangerAdmin(effectiveUser)) { throw new Exception("User " + effectiveUser + " does not have permission for this operation"); } } @@ -937,7 +937,7 @@ private RangerRole getRoleIfAccessible(String roleName, String serviceName, Stri effectiveUser = loggedInUser; } try { - if (!bizUtil.isUserRangerAdmin(effectiveUser) && !svcStore.isServiceAdminUser(serviceName, effectiveUser)) { + if (!bizUtil.isUserRangerAdmin(effectiveUser)) { existingRole = roleStore.getRole(roleName); ensureRoleAccess(effectiveUser, userGroups, existingRole); diff --git a/security-admin/src/main/java/org/apache/ranger/rest/ServiceTagsProcessor.java b/security-admin/src/main/java/org/apache/ranger/rest/ServiceTagsProcessor.java index 1d6c48a4ee..b256e2838f 100644 --- a/security-admin/src/main/java/org/apache/ranger/rest/ServiceTagsProcessor.java +++ b/security-admin/src/main/java/org/apache/ranger/rest/ServiceTagsProcessor.java @@ -396,11 +396,6 @@ private void addOrUpdate(ServiceTags serviceTags) throws Exception { } tagStore.refreshServiceResource(resourceInStore.getId()); RangerPerfTracer.logAlways(perf); - } else { - if (CollectionUtils.isEmpty(tagIds)) { - // No tags associated with the resource - delete the resource too - tagStore.deleteServiceResource(resourceInStore.getId()); - } } } } diff --git a/security-admin/src/main/resources/META-INF/jpa_named_queries.xml b/security-admin/src/main/resources/META-INF/jpa_named_queries.xml index e4a2354b06..7e69cc4a36 100755 --- a/security-admin/src/main/resources/META-INF/jpa_named_queries.xml +++ b/security-admin/src/main/resources/META-INF/jpa_named_queries.xml @@ -418,14 +418,6 @@ select obj from XXPolicy obj, XXService svc, XXSecurityZone zone where obj.guid = :guid and obj.service = svc.id and svc.name = :serviceName and obj.zoneId = zone.id and zone.name = :zoneName - - select obj.resourceSignature, obj.service from XXPolicy obj GROUP BY obj.resourceSignature, obj.service HAVING COUNT(obj.resourceSignature) > 1 - - - - select obj from XXPolicy obj where obj.service = :serviceId and obj.resourceSignature = :resSignature - - select obj from XXServiceDef obj where obj.name = :name @@ -1200,10 +1192,6 @@ SELECT obj FROM XXPortalUser obj WHERE obj.userSource=:userSource and obj.status=:status - - SELECT obj.firstName, obj.lastName, obj.publicScreenName, obj.loginId FROM XXPortalUser obj WHERE obj.id=:id - - SELECT obj FROM XXModuleDef obj diff --git a/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java b/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java index a80f12efb1..dfb5814f3d 100644 --- a/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java +++ b/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java @@ -1706,7 +1706,7 @@ public void test26createPolicy() throws Exception { Mockito.when(daoManager.getXXPolicy()).thenReturn(xPolicyDao); Mockito.when(xPolicyDao.getById(Id)).thenReturn(xPolicy); - Mockito.doNothing().when(policyRefUpdater).createNewPolMappingForRefTable(rangerPolicy, xPolicy, xServiceDef, false); + Mockito.doNothing().when(policyRefUpdater).createNewPolMappingForRefTable(rangerPolicy, xPolicy, xServiceDef); Mockito.when(policyService.getPopulatedViewObject(xPolicy)).thenReturn(rangerPolicy); Mockito.when(daoManager.getXXService()).thenReturn(xServiceDao); diff --git a/security-admin/src/test/java/org/apache/ranger/rest/TestRoleREST.java b/security-admin/src/test/java/org/apache/ranger/rest/TestRoleREST.java deleted file mode 100644 index 217c1bba37..0000000000 --- a/security-admin/src/test/java/org/apache/ranger/rest/TestRoleREST.java +++ /dev/null @@ -1,933 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.ranger.rest; - -import org.apache.ranger.admin.client.datatype.RESTResponse; -import org.apache.ranger.biz.*; -import org.apache.ranger.common.*; -import org.apache.ranger.db.*; -import org.apache.ranger.entity.*; -import org.apache.ranger.plugin.model.RangerRole; -import org.apache.ranger.plugin.model.validation.RangerRoleValidator; -import org.apache.ranger.plugin.util.GrantRevokeRoleRequest; -import org.apache.ranger.plugin.util.RangerRoles; -import org.apache.ranger.plugin.util.SearchFilter; -import org.apache.ranger.security.context.RangerContextHolder; -import org.apache.ranger.security.context.RangerSecurityContext; -import org.apache.ranger.service.RangerRoleService; -import org.apache.ranger.service.XUserService; -import org.apache.ranger.view.RangerRoleList; -import org.apache.ranger.view.VXUser; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.*; -import org.mockito.junit.MockitoJUnitRunner; - -import javax.servlet.http.HttpServletRequest; -import java.util.*; - -import static org.mockito.ArgumentMatchers.eq; - - -@RunWith(MockitoJUnitRunner.class) -public class TestRoleREST { - private static final Long userId = 8L; - private static final Long roleId = 9L; - private static final String adminLoginID = "admin"; - - @Mock - RangerRole role; - - @Mock - RESTErrorUtil restErrorUtil; - @Mock - AssetMgr assetMgr; - - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - RangerDaoManager daoMgr; - @Mock - RoleDBStore roleStore; - @Mock - RangerRoleService roleService; - - @Mock - XUserService xUserService; - - @Mock - ServiceDBStore svcStore; - - @Mock - RangerSearchUtil searchUtil; - - @Mock - ServiceUtil serviceUtil; - - @Mock - RangerValidatorFactory validatorFactory; - - @Mock - RangerBizUtil bizUtil; - - @Mock - XUserMgr userMgr; - - @Mock - XXRoleRefUserDao xRoleUserDao; - - @Mock - XXRoleRefGroupDao xRoleGroupDao; - - @Mock - XXRoleRefRoleDao xRoleRoleDao; - - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - RoleRefUpdater roleRefUpdater; - - @InjectMocks private RoleREST roleRest = new RoleREST(); - - @Before - public void setup() { - RangerSecurityContext context = new RangerSecurityContext(); - context.setUserSession(new UserSessionBase()); - RangerContextHolder.setSecurityContext(context); - UserSessionBase currentUserSession = ContextUtil.getCurrentUserSession(); - currentUserSession.setUserAdmin(true); - XXPortalUser xXPortalUser = new XXPortalUser(); - xXPortalUser.setLoginId(adminLoginID); - xXPortalUser.setId(userId); - currentUserSession.setXXPortalUser(xXPortalUser); - } - - @After - public void destroySession() { - RangerSecurityContext context = new RangerSecurityContext(); - context.setUserSession(null); - RangerContextHolder.setSecurityContext(context); - } - - @Test - public void test1CreateRole(){ - boolean createNonExistUserGroup = true; - Mockito.when(validatorFactory.getRangerRoleValidator(roleStore)).thenReturn(Mockito.mock(RangerRoleValidator.class)); - Mockito.when(bizUtil.isUserRangerAdmin(Mockito.anyString())).thenReturn(true); - RangerRole rangerRole = createRole(); - try { - Mockito.when(roleStore.createRole(Mockito.any(RangerRole.class), eq(createNonExistUserGroup))). - thenReturn(rangerRole); - } catch (Exception e) { - throw new RuntimeException(e); - } - RangerRole createdRole = roleRest.createRole("admin", rangerRole ,createNonExistUserGroup); - Assert.assertNotNull(createdRole); - Assert.assertEquals(createdRole.getName(), rangerRole.getName()); - Assert.assertEquals(createdRole.getDescription(), rangerRole.getDescription()); - Assert.assertEquals(createdRole.getCreatedByUser(), rangerRole.getCreatedByUser()); - } - - @Test - public void test2UpdateRole(){ - Boolean createNonExistUserGroup = Boolean.TRUE; - RangerRole rangerRole = createRole(); - RangerRole rangerRoleOld = createRoleOld(); - Mockito.when(validatorFactory.getRangerRoleValidator(roleStore)).thenReturn(Mockito.mock(RangerRoleValidator.class)); - XXRoleDao xxRoleDao = Mockito.mock(XXRoleDao.class); - Mockito.when(daoMgr.getXXRole()).thenReturn(xxRoleDao); - Mockito.when(daoMgr.getXXPolicyRefRole().findRoleRefPolicyCount(Mockito.anyString())).thenReturn(0l); - try { - Mockito.when(roleStore.getRole(Mockito.anyLong())).thenReturn(rangerRoleOld); - } catch (Exception e) { - throw new RuntimeException(e); - } - try { - Mockito.when(roleStore.updateRole(Mockito.any(RangerRole.class),Mockito.anyBoolean())).thenReturn(rangerRole); - } catch (Exception e) { - throw new RuntimeException(e); - } - RangerRole updatedRole = roleRest.updateRole(roleId, rangerRole, eq(createNonExistUserGroup)); - Assert.assertNotNull(updatedRole); - Assert.assertEquals(updatedRole.getName(), rangerRole.getName()); - Assert.assertEquals(updatedRole.getUsers(), rangerRole.getUsers()); - } - - @Test - public void test3DeleteRoleByName(){ - RangerRole rangerRole = createRole(); - Mockito.doReturn(true).when(bizUtil).isUserRangerAdmin(Mockito.anyString()); - Mockito.when(validatorFactory.getRangerRoleValidator(roleStore)).thenReturn(Mockito.mock(RangerRoleValidator.class)); - roleRest.deleteRole("admin", adminLoginID ,rangerRole.getName()); - try { - Mockito.verify(roleStore, Mockito.times(1)).deleteRole(Mockito.anyString()); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - @Test - public void test4DeleteRoleById(){ - RangerRole rangerRole = createRole(); - Mockito.doReturn(true).when(bizUtil).isUserRangerAdmin(Mockito.anyString()); - Mockito.when(validatorFactory.getRangerRoleValidator(roleStore)).thenReturn(Mockito.mock(RangerRoleValidator.class)); - roleRest.deleteRole(rangerRole.getId()); - try { - Mockito.verify(roleStore, Mockito.times(1)).deleteRole(Mockito.anyLong()); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - @Test - public void test5GetRoleByName(){ - RangerRole rangerRole = createRole(); - Mockito.doReturn(true).when(bizUtil).isUserRangerAdmin(Mockito.anyString()); - try { - Mockito.when(roleStore.getRole(Mockito.anyString())).thenReturn(rangerRole); - } catch (Exception e) { - throw new RuntimeException(e); - } - RangerRole returnedRole = roleRest.getRole("admin", adminLoginID ,rangerRole.getName()); - Assert.assertNotNull(returnedRole); - Assert.assertEquals(returnedRole.getName(), rangerRole.getName()); - } - - @Test - public void test6GetRoleById(){ - RangerRole rangerRole = createRole(); - try { - Mockito.when(roleStore.getRole(Mockito.anyLong())).thenReturn(rangerRole); - } catch (Exception e) { - throw new RuntimeException(e); - } - RangerRole returnedRole = roleRest.getRole(eq(rangerRole.getId())); - Assert.assertNotNull(returnedRole); - Assert.assertEquals(returnedRole.getName(), rangerRole.getName()); - Assert.assertEquals(returnedRole.getId(), rangerRole.getId()); - } - - @Test - public void test7GetAllRoles(){ - RangerRoleList rangerRoleList = new RangerRoleList(); - Mockito.when(searchUtil.getSearchFilter(Mockito.any(HttpServletRequest.class), eq(roleService.sortFields))). - thenReturn(Mockito.mock(SearchFilter.class)); - RangerRoleList returnedRangerRoleList = roleRest.getAllRoles(Mockito.mock(HttpServletRequest.class)); - Assert.assertNotNull(returnedRangerRoleList); - Assert.assertEquals(returnedRangerRoleList.getListSize(), rangerRoleList.getListSize()); - } - - @Test - public void test8GetAllRolesForUser(){ - RangerRoleList rangerRoleList = new RangerRoleList(); - SearchFilter searchFilter = new SearchFilter(); - Mockito.when(searchUtil.getSearchFilter(Mockito.any(HttpServletRequest.class), eq(roleService.sortFields))). - thenReturn(searchFilter); - RangerRoleList returnedRangerRoleList = roleRest.getAllRolesForUser(Mockito.mock(HttpServletRequest.class)); - Assert.assertNotNull(returnedRangerRoleList); - Assert.assertEquals(returnedRangerRoleList.getListSize(), rangerRoleList.getListSize()); - } - @Test - public void test9GetAllRoleNames(){ - List roleList = createRoleList(); - Mockito.when(searchUtil.getSearchFilter(Mockito.any(HttpServletRequest.class), eq(roleService.sortFields))). - thenReturn(Mockito.mock(SearchFilter.class)); - Mockito.when(bizUtil.isUserRangerAdmin(Mockito.anyString())).thenReturn(true); - try { - Mockito.when(roleStore.getRoleNames(Mockito.any(SearchFilter.class))).thenReturn(roleList); - } catch (Exception e) { - throw new RuntimeException(e); - } - List returnedRoleList = roleRest.getAllRoleNames(adminLoginID, adminLoginID, Mockito.mock(HttpServletRequest.class)); - Assert.assertNotNull(returnedRoleList); - Assert.assertEquals(returnedRoleList.size(), roleList.size()); - } - @Test - public void test10AddUsersAndGroups(){ - RangerRole rangerRole = createRole(); - List users = new ArrayList<>(Arrays.asList("test-role","admin")); - List groups = new ArrayList<>(Arrays.asList("group1","group2")); - Boolean isAdmin = true; - Mockito.when(bizUtil.isUserRangerAdmin(Mockito.anyString())).thenReturn(true); - try { - Mockito.when(roleStore.getRole(Mockito.anyLong())).thenReturn(rangerRole); - } catch (Exception e) { - throw new RuntimeException(e); - } - try { - Mockito.when(roleStore.updateRole(Mockito.any(RangerRole.class),Mockito.anyBoolean())). - then(AdditionalAnswers.returnsFirstArg()); - } catch (Exception e) { - throw new RuntimeException(e); - } - RangerRole returnedRole = roleRest.addUsersAndGroups(roleId, users, groups, isAdmin); - Assert.assertNotNull(returnedRole); - Assert.assertEquals(returnedRole.getUsers().size(), users.size()); - Assert.assertEquals(returnedRole.getGroups().size(), groups.size()); - } - @Test - public void test11RemoveUsersAndGroups(){ - RangerRole rangerRole = createRoleWithUsersAndGroups(); - List users = new ArrayList<>(Arrays.asList("test-role","admin")); - List groups = new ArrayList<>(Arrays.asList("test-group","admin")); - List createdRoleUsers = new ArrayList<>(); - for(RangerRole.RoleMember roleMember : rangerRole.getUsers()){ - createdRoleUsers.add(roleMember.getName()); - } - List createdRoleGroups = new ArrayList<>(); - for(RangerRole.RoleMember groupMember : rangerRole.getGroups()){ - createdRoleGroups.add(groupMember.getName()); - } - Mockito.when(bizUtil.isUserRangerAdmin(Mockito.anyString())).thenReturn(true); - try { - Mockito.when(roleStore.getRole(Mockito.anyLong())).thenReturn(rangerRole); - } catch (Exception e) { - throw new RuntimeException(e); - } - try { - Mockito.when(roleStore.updateRole(Mockito.any(RangerRole.class),Mockito.anyBoolean())). - then(AdditionalAnswers.returnsFirstArg()); - } catch (Exception e) { - throw new RuntimeException(e); - } - RangerRole returnedRole = roleRest.removeUsersAndGroups(roleId, users, groups); - Assert.assertNotNull(returnedRole); - Assert.assertEquals(createdRoleUsers,users); - Assert.assertEquals(createdRoleGroups,groups); - Assert.assertEquals(returnedRole.getUsers().size(), 0); - Assert.assertEquals(returnedRole.getGroups().size(), 0); - } - - @Test - public void test12RemoveAdminFromUsersAndGroups(){ - RangerRole rangerRole = createRoleWithUsersAndGroups(); - for (RangerRole.RoleMember role: rangerRole.getUsers()){ - Assert.assertTrue(role.getIsAdmin()); - } - for (RangerRole.RoleMember group: rangerRole.getGroups()){ - Assert.assertTrue(group.getIsAdmin()); - } - List users = new ArrayList<>(Arrays.asList("test-role","admin")); - List groups = new ArrayList<>(Arrays.asList("test-group","admin")); - List createdRoleUsers = new ArrayList<>(); - for(RangerRole.RoleMember roleMember : rangerRole.getUsers()){ - createdRoleUsers.add(roleMember.getName()); - } - List createdRoleGroups = new ArrayList<>(); - for(RangerRole.RoleMember groupMember : rangerRole.getGroups()){ - createdRoleGroups.add(groupMember.getName()); - } - Mockito.when(bizUtil.isUserRangerAdmin(Mockito.anyString())).thenReturn(true); - try { - Mockito.when(roleStore.getRole(Mockito.anyLong())).thenReturn(rangerRole); - } catch (Exception e) { - throw new RuntimeException(e); - } - try { - Mockito.when(roleStore.updateRole(Mockito.any(RangerRole.class),Mockito.anyBoolean())). - then(AdditionalAnswers.returnsFirstArg()); - } catch (Exception e) { - throw new RuntimeException(e); - } - RangerRole returnedRole = roleRest.removeAdminFromUsersAndGroups(roleId, users, groups); - Assert.assertNotNull(returnedRole); - Assert.assertEquals(createdRoleUsers,users); - Assert.assertEquals(createdRoleGroups,groups); - for (RangerRole.RoleMember role: returnedRole.getUsers()){ - Assert.assertFalse(role.getIsAdmin()); - } - for (RangerRole.RoleMember group: returnedRole.getGroups()){ - Assert.assertFalse(group.getIsAdmin()); - } - } - @Test - public void test13GrantRole(){ - RangerRole rangerRole = createRole(); - String serviceName = "serviceName"; - GrantRevokeRoleRequest grantRevokeRoleRequest = createGrantRevokeRoleRequest(); - Mockito.when(bizUtil.isUserRangerAdmin(Mockito.anyString())).thenReturn(true,true,true); - try { - Mockito.when(roleStore.updateRole(Mockito.any(RangerRole.class),Mockito.anyBoolean())). - then(AdditionalAnswers.returnsFirstArg()); - } catch (Exception e) { - throw new RuntimeException(e); - } - try { - Mockito.when(roleStore.getRole(Mockito.anyString())).thenReturn(rangerRole,rangerRole,rangerRole,rangerRole); - } catch (Exception e) { - throw new RuntimeException(e); - } - RESTResponse resp = roleRest.grantRole(serviceName, grantRevokeRoleRequest, - Mockito.mock(HttpServletRequest.class)); - Assert.assertNotNull(resp); - Assert.assertEquals(resp.getStatusCode(), RESTResponse.STATUS_SUCCESS); - } - - @Test - public void test14RevokeRole(){ - RangerRole rangerRole = createRole(); - String serviceName = "serviceName"; - GrantRevokeRoleRequest grantRevokeRoleRequest = createGrantRevokeRoleRequest(); - Mockito.when(bizUtil.isUserRangerAdmin(Mockito.anyString())).thenReturn(true,true,true); - try { - Mockito.when(roleStore.getRole(Mockito.anyString())).thenReturn(rangerRole,rangerRole,rangerRole,rangerRole); - } catch (Exception e) { - throw new RuntimeException(e); - } - try { - Mockito.when(roleStore.updateRole(Mockito.any(RangerRole.class),Mockito.anyBoolean())). - then(AdditionalAnswers.returnsFirstArg()); - } catch (Exception e) { - throw new RuntimeException(e); - } - RESTResponse resp = roleRest.revokeRole(serviceName, grantRevokeRoleRequest, - Mockito.mock(HttpServletRequest.class)); - Assert.assertNotNull(resp); - Assert.assertEquals(resp.getStatusCode(), RESTResponse.STATUS_SUCCESS); - } - - @Test - public void test15GetUserRoles(){ - Set rangerRoles = new HashSet<>(); - RangerRole rangerRole = createRole(); - rangerRoles.add(rangerRole); - List xxRoleRefGroupList = createXXRoleRefGroupList(); - List xxRoleRefRoleList = createXXRoleRefUserList(); - Set groups = new HashSet<>(Arrays.asList("group1", "group2")); - Mockito.when(xUserService.getXUserByUserName(Mockito.anyString())).thenReturn(createVXUser()); - Mockito.when(userMgr.getGroupsForUser(Mockito.anyString())).thenReturn(groups); - Mockito.when(roleRefUpdater.getRangerDaoManager().getXXRoleRefUser().findByUserName(adminLoginID)). - thenReturn(xxRoleRefRoleList); - Mockito.when(roleRefUpdater.getRangerDaoManager().getXXRoleRefGroup().findByGroupName(adminLoginID)). - thenReturn(xxRoleRefGroupList); - try { - Mockito.when(roleStore.getRoleNames(Mockito.anyString(),eq(groups))).thenReturn(rangerRoles); - } catch (Exception e) { - throw new RuntimeException(e); - } - List returnedRoles = roleRest.getUserRoles(adminLoginID,Mockito.mock(HttpServletRequest.class)); - Assert.assertNotNull(returnedRoles); - Assert.assertEquals(returnedRoles.size(), rangerRoles.size()); - } - - @Test - public void test16GetRangerRolesIfUpdated() { - RangerRoles rangerRoles = createRangerRoles(); - String serviceName = "serviceName"; - String pluginId = "pluginId"; - String clusterName = ""; - String pluginCapabilities = ""; - RangerRoles returnedRangeRoles; - Mockito.when(serviceUtil.isValidService(Mockito.anyString(),Mockito.any(HttpServletRequest.class))). - thenReturn(true); - try { - Mockito.when(roleStore.getRoles(Mockito.anyString(), Mockito.anyLong())).thenReturn(rangerRoles); - } catch (Exception e) { - throw new RuntimeException(e); - } - try { - returnedRangeRoles = roleRest.getRangerRolesIfUpdated(serviceName, - -1l, 0l, pluginId, clusterName, pluginCapabilities, - Mockito.mock(HttpServletRequest.class)); - } catch (Exception e) { - throw new RuntimeException(e); - } - Assert.assertNotNull(returnedRangeRoles); - Assert.assertEquals(returnedRangeRoles.getRangerRoles().size(), rangerRoles.getRangerRoles().size()); - } - - @Test - public void test17GetSecureRangerRolesIfUpdated(){ - RangerRoles rangerRoles = createRangerRoles(); - String serviceName = "serviceName"; - String pluginId = "pluginId"; - String clusterName = ""; - String pluginCapabilities = ""; - RangerRoles returnedRangeRoles; - Mockito.when(serviceUtil.isValidService(Mockito.anyString(),Mockito.any(HttpServletRequest.class))). - thenReturn(true); - try { - Mockito.when(roleStore.getRoles(Mockito.anyString(), Mockito.anyLong())).thenReturn(rangerRoles); - } catch (Exception e) { - throw new RuntimeException(e); - } - Mockito.when(daoMgr.getXXService().findByName(Mockito.anyString())).thenReturn(createXXService()); - Mockito.when(bizUtil.isAdmin()).thenReturn(true); - try { - returnedRangeRoles = roleRest.getSecureRangerRolesIfUpdated(serviceName, - -1l, 0l, pluginId, clusterName, pluginCapabilities, - Mockito.mock(HttpServletRequest.class)); - } catch (Exception e) { - throw new RuntimeException(e); - } - Assert.assertNotNull(returnedRangeRoles); - Assert.assertEquals(returnedRangeRoles.getRangerRoles().size(), rangerRoles.getRangerRoles().size()); - } - - @Test(expected = Throwable.class) - public void test1bCreateRole(){ - boolean createNonExistUserGroup = true; - Mockito.when(validatorFactory.getRangerRoleValidator(roleStore)).thenReturn(Mockito.mock(RangerRoleValidator.class)); - Mockito.when(bizUtil.isUserRangerAdmin(Mockito.anyString())).thenReturn(true); - RangerRole rangerRole = createRoleInvalidMember(); - roleRest.createRole("admin", rangerRole ,createNonExistUserGroup); - } - @Test(expected = Throwable.class) - public void test2bUpdateRole(){ - Boolean createNonExistUserGroup = Boolean.TRUE; - RangerRole rangerRole = createRoleInvalidMember(); - RangerRole rangerRoleOld = createRoleOld(); - Mockito.when(validatorFactory.getRangerRoleValidator(roleStore)).thenReturn(Mockito.mock(RangerRoleValidator.class)); - XXRoleDao xxRoleDao = Mockito.mock(XXRoleDao.class); - Mockito.when(daoMgr.getXXRole()).thenReturn(xxRoleDao); - Mockito.when(daoMgr.getXXPolicyRefRole().findRoleRefPolicyCount(Mockito.anyString())).thenReturn(0l); - try { - Mockito.when(roleStore.getRole(Mockito.anyLong())).thenReturn(rangerRoleOld); - } catch (Exception e) { - throw new RuntimeException(e); - } - roleRest.updateRole(roleId, rangerRole, eq(createNonExistUserGroup)); - } - @Test(expected = Throwable.class) - public void test3bDeleteRoleByName(){ - RangerRole rangerRole = createRole(); - Mockito.doReturn(false).when(bizUtil).isUserRangerAdmin(Mockito.anyString()); - Mockito.when(validatorFactory.getRangerRoleValidator(roleStore)).thenReturn(Mockito.mock(RangerRoleValidator.class)); - roleRest.deleteRole("admin", adminLoginID ,rangerRole.getName()); - try { - Mockito.verify(roleStore, Mockito.times(1)).deleteRole(Mockito.anyString()); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - @Test(expected = Throwable.class) - public void test4bDeleteRoleById(){ - RangerRole rangerRole = createRole(); - Mockito.when(validatorFactory.getRangerRoleValidator(roleStore)).thenReturn(Mockito.mock(RangerRoleValidator.class)); - roleRest.deleteRole(rangerRole.getId()); - try { - Mockito.verify(roleStore, Mockito.times(1)).deleteRole(Mockito.anyLong()); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - @Test(expected = Throwable.class) - public void test5bGetRoleByName(){ - RangerRole rangerRole = createRole(); - roleRest.getRole("admin", adminLoginID ,rangerRole.getName()); - } - - @Test(expected = Throwable.class) - public void test6bGetRoleById(){ - RangerRole rangerRole = createRole(); - try { - Mockito.when(roleStore.getRole(Mockito.anyLong())).thenThrow(new Exception("test")); - } catch (Exception e) { - throw new RuntimeException(e); - } - roleRest.getRole(eq(rangerRole.getId())); - } - - @Test(expected = Throwable.class) - public void test7bGetAllRoles(){ - SearchFilter searchFilter = new SearchFilter(); - try { - Mockito.when(roleStore.getRoles(searchFilter, Mockito.any(RangerRoleList.class))).thenThrow(new Exception("test")); - } catch (Exception e) { - throw new RuntimeException(e); - } - Mockito.when(searchUtil.getSearchFilter(Mockito.any(HttpServletRequest.class), eq(roleService.sortFields))). - thenReturn(Mockito.mock(SearchFilter.class)); - roleRest.getAllRoles(Mockito.mock(HttpServletRequest.class)); - } - - @Test - public void test8bGetAllRolesForUser(){ - RangerRoleList rangerRoleList = new RangerRoleList(); - SearchFilter searchFilter = new SearchFilter(); - Mockito.when(searchUtil.getSearchFilter(Mockito.any(HttpServletRequest.class), eq(roleService.sortFields))). - thenReturn(searchFilter); - RangerRoleList returnedRangerRoleList = roleRest.getAllRolesForUser(Mockito.mock(HttpServletRequest.class)); - Assert.assertNotNull(returnedRangerRoleList); - Assert.assertEquals(returnedRangerRoleList.getListSize(), rangerRoleList.getListSize()); - } - - @Test(expected = Throwable.class) - public void test9bGetAllRoleNames(){ - List roleList = createRoleList(); - Mockito.when(searchUtil.getSearchFilter(Mockito.any(HttpServletRequest.class), eq(roleService.sortFields))). - thenReturn(Mockito.mock(SearchFilter.class)); - List returnedRoleList = roleRest.getAllRoleNames(adminLoginID, adminLoginID, Mockito.mock(HttpServletRequest.class)); - Assert.assertNotNull(returnedRoleList); - Assert.assertEquals(returnedRoleList.size(), roleList.size()); - } - @Test - public void test10bAddUsersAndGroups(){ - RangerRole rangerRole = createRoleWithUsersAndGroups(); - int currentUsersCount = rangerRole.getUsers().size(); - int currentGroupsCount = rangerRole.getGroups().size(); - List users = new ArrayList<>(Arrays.asList("test-role2","test-role3")); - List groups = new ArrayList<>(Arrays.asList("test-group2","test-group3")); - Boolean isAdmin = Boolean.TRUE; - Mockito.when(bizUtil.isUserRangerAdmin(Mockito.anyString())).thenReturn(true); - try { - Mockito.when(roleStore.getRole(Mockito.anyLong())).thenReturn(rangerRole); - } catch (Exception e) { - throw new RuntimeException(e); - } - try { - Mockito.when(roleStore.updateRole(Mockito.any(RangerRole.class),Mockito.anyBoolean())). - then(AdditionalAnswers.returnsFirstArg()); - } catch (Exception e) { - throw new RuntimeException(e); - } - RangerRole returnedRole = roleRest.addUsersAndGroups(roleId, users, groups, isAdmin); - Assert.assertNotNull(returnedRole); - Assert.assertEquals(returnedRole.getGroups().size(), groups.size() + currentGroupsCount); - } - - @Test(expected = Throwable.class) - public void test10cAddUsersAndGroups(){ - RangerRole rangerRole = createRole(); - List users = new ArrayList<>(Arrays.asList("{OWNER}","test-role3")); - List groups = new ArrayList<>(Arrays.asList("test-group2","test-group3")); - Boolean isAdmin = Boolean.TRUE; - roleRest.addUsersAndGroups(roleId, users, groups, isAdmin); - } - - @Test(expected = Throwable.class) - public void test11bRemoveUsersAndGroups(){ - RangerRole rangerRole = createRole(); - List users = new ArrayList<>(Arrays.asList("test-role","admin")); - List groups = new ArrayList<>(); - List createdRoleUsers = new ArrayList<>(); - for(RangerRole.RoleMember roleMember : rangerRole.getUsers()){ - createdRoleUsers.add(roleMember.getName()); - } - roleRest.removeUsersAndGroups(roleId, users, groups); - } - - @Test(expected = Throwable.class) - public void test12bRemoveAdminFromUsersAndGroups(){ - RangerRole rangerRole = createRole(); - for (RangerRole.RoleMember role: rangerRole.getUsers()){ - Assert.assertTrue(role.getIsAdmin()); - } - List users = new ArrayList<>(Arrays.asList("test-role","admin")); - List groups = new ArrayList<>(); - List createdRoleUsers = new ArrayList<>(); - for(RangerRole.RoleMember roleMember : rangerRole.getUsers()){ - createdRoleUsers.add(roleMember.getName()); - } - roleRest.removeAdminFromUsersAndGroups(roleId, users, groups); - } - - @Test(expected = Throwable.class) - public void test13bGrantRole(){ - RangerRole rangerRole = createRole(); - String serviceName = "serviceName"; - GrantRevokeRoleRequest grantRevokeRoleRequest = createGrantRevokeRoleRequest(); - roleRest.grantRole(serviceName, grantRevokeRoleRequest, - Mockito.mock(HttpServletRequest.class)); - } - - @Test - public void test14bRevokeRole(){ - RangerRole rangerRole = createRole(); - String serviceName = "serviceName"; - GrantRevokeRoleRequest grantRevokeRoleRequest = createGrantRevokeRoleRequest(); - grantRevokeRoleRequest.setGrantOption(Boolean.TRUE); - Mockito.when(bizUtil.isUserRangerAdmin(Mockito.anyString())).thenReturn(true,true,true); - try { - Mockito.when(roleStore.getRole(Mockito.anyString())).thenReturn(rangerRole,rangerRole,rangerRole,rangerRole); - } catch (Exception e) { - throw new RuntimeException(e); - } - try { - Mockito.when(roleStore.updateRole(Mockito.any(RangerRole.class),Mockito.anyBoolean())). - then(AdditionalAnswers.returnsFirstArg()); - } catch (Exception e) { - throw new RuntimeException(e); - } - RESTResponse resp = roleRest.revokeRole(serviceName, grantRevokeRoleRequest, - Mockito.mock(HttpServletRequest.class)); - Assert.assertNotNull(resp); - Assert.assertEquals(resp.getStatusCode(), RESTResponse.STATUS_SUCCESS); - } - - @Test(expected = Throwable.class) - public void test14cRevokeRole(){ - RangerRole rangerRole = createRole(); - String serviceName = "serviceName"; - GrantRevokeRoleRequest grantRevokeRoleRequest = createGrantRevokeRoleRequest(); - grantRevokeRoleRequest.setGrantOption(Boolean.TRUE); - grantRevokeRoleRequest.setGrantorGroups(new HashSet<>(Arrays.asList("group1","group2"))); - roleRest.revokeRole(serviceName, grantRevokeRoleRequest, - Mockito.mock(HttpServletRequest.class)); - } - - @Test(expected = Throwable.class) - public void test15bGetUserRoles(){ - Set rangerRoles = new HashSet<>(); - RangerRole rangerRole = createRole(); - rangerRoles.add(rangerRole); - List xxRoleRefGroupList = createXXRoleRefGroupList(); - List xxRoleRefRoleList = createXXRoleRefUserList(); - Set groups = new HashSet<>(Arrays.asList("group1", "group2")); - Mockito.when(xUserService.getXUserByUserName(Mockito.anyString())).thenReturn(null); - Mockito.when(roleRefUpdater.getRangerDaoManager().getXXRoleRefUser().findByUserName(adminLoginID)). - thenReturn(xxRoleRefRoleList); - Mockito.when(roleRefUpdater.getRangerDaoManager().getXXRoleRefGroup().findByGroupName(adminLoginID)). - thenReturn(xxRoleRefGroupList); - roleRest.getUserRoles(adminLoginID,Mockito.mock(HttpServletRequest.class)); - } - - @Test(expected = Throwable.class) - public void test16bGetRangerRolesIfUpdated() { - RangerRoles rangerRoles = createRangerRoles(); - String serviceName = "serviceName"; - String pluginId = "pluginId"; - String clusterName = ""; - String pluginCapabilities = ""; - try { - Mockito.doThrow(new Exception()).when(bizUtil).failUnauthenticatedDownloadIfNotAllowed(); - } catch (Exception e) { - throw new RuntimeException(e); - } - try { - roleRest.getRangerRolesIfUpdated(serviceName, -1l, 0l, pluginId, clusterName, - pluginCapabilities, Mockito.mock(HttpServletRequest.class)); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - @Test(expected = Throwable.class) - public void test16cGetRangerRolesIfUpdated() { - String serviceName = "serviceName"; - String pluginId = "pluginId"; - String clusterName = ""; - String pluginCapabilities = ""; - Mockito.when(serviceUtil.isValidService(Mockito.anyString(),Mockito.any(HttpServletRequest.class))). - thenReturn(true); - try { - Mockito.when(roleStore.getRoles(Mockito.anyString(), Mockito.anyLong())).thenReturn(null); - } catch (Exception e) { - throw new RuntimeException(e); - } - try { - roleRest.getRangerRolesIfUpdated(serviceName, -1l, 0l, pluginId, clusterName, - pluginCapabilities, Mockito.mock(HttpServletRequest.class)); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - @Test(expected = Throwable.class) - public void test17bGetSecureRangerRolesIfUpdated(){ - RangerRoles rangerRoles = createRangerRoles(); - String serviceName = "serviceName"; - String pluginId = "pluginId"; - String clusterName = ""; - String pluginCapabilities = ""; - Mockito.when(serviceUtil.isValidService(eq(null),Mockito.any(HttpServletRequest.class))). - thenThrow(new Exception()); - try { - Mockito.when(roleStore.getRoles(Mockito.anyString(), Mockito.anyLong())).thenReturn(rangerRoles); - } catch (Exception e) { - throw new RuntimeException(e); - } - Mockito.when(daoMgr.getXXService().findByName(Mockito.anyString())).thenReturn(createXXService()); - Mockito.when(bizUtil.isAdmin()).thenReturn(true); - try { - roleRest.getSecureRangerRolesIfUpdated(serviceName, -1l, 0l, pluginId, - clusterName, pluginCapabilities, Mockito.mock(HttpServletRequest.class)); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - @Test(expected = Throwable.class) - public void test17cGetSecureRangerRolesIfUpdated(){ - String serviceName = "serviceName"; - String pluginId = "pluginId"; - String clusterName = ""; - String pluginCapabilities = ""; - Mockito.when(serviceUtil.isValidService(Mockito.anyString(), Mockito.any(HttpServletRequest.class))). - thenReturn(true); - Mockito.when(daoMgr.getXXService().findByName(Mockito.anyString())).thenReturn(null); - Mockito.when(bizUtil.isAdmin()).thenReturn(true); - try { - roleRest.getSecureRangerRolesIfUpdated(serviceName, -1l, 0l, pluginId, - clusterName, pluginCapabilities, Mockito.mock(HttpServletRequest.class)); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - @Test(expected = Throwable.class) - public void test17dGetSecureRangerRolesIfUpdated(){ - - String serviceName = "serviceName"; - String pluginId = "pluginId"; - String clusterName = ""; - String pluginCapabilities = ""; - Mockito.when(serviceUtil.isValidService(Mockito.anyString(), Mockito.any(HttpServletRequest.class))). - thenReturn(true); - try { - Mockito.when(roleStore.getRoles(Mockito.anyString(), Mockito.anyLong())).thenReturn(null); - } catch (Exception e) { - throw new RuntimeException(e); - } - Mockito.when(daoMgr.getXXService().findByName(Mockito.anyString())).thenReturn(createXXService()); - Mockito.when(bizUtil.isAdmin()).thenReturn(true); - try { - roleRest.getSecureRangerRolesIfUpdated(serviceName, -1l, 0l, pluginId, - clusterName, pluginCapabilities, Mockito.mock(HttpServletRequest.class)); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - private RangerRole createRole(){ - String name = "test-role"; - String name2 = "admin"; - RangerRole.RoleMember rm1 = new RangerRole.RoleMember(name,true); - RangerRole.RoleMember rm2 = new RangerRole.RoleMember(name2, true); - List usersList = new ArrayList<>(Arrays.asList(rm1,rm2)); - RangerRole rangerRole = new RangerRole(name, name, null, usersList, null); - rangerRole.setCreatedByUser(name); - rangerRole.setId(roleId); - return rangerRole; - } - - private RangerRole createRoleWithUsersAndGroups(){ - String userName1 = "test-role"; - String userName2 = "admin"; - String groupName1 = "test-group"; - String groupName2 = "admin"; - RangerRole.RoleMember rm1 = new RangerRole.RoleMember(userName1,true); - RangerRole.RoleMember rm2 = new RangerRole.RoleMember(userName2, true); - List usersList = new ArrayList<>(Arrays.asList(rm1,rm2)); - RangerRole.RoleMember rm3 = new RangerRole.RoleMember(groupName1,true); - RangerRole.RoleMember rm4 = new RangerRole.RoleMember(groupName2, true); - List groupList = new ArrayList<>(Arrays.asList(rm3,rm4)); - - RangerRole rangerRole = new RangerRole(userName1, userName1, null, usersList, groupList); - rangerRole.setCreatedByUser(userName1); - rangerRole.setId(roleId); - return rangerRole; - } - - private RangerRole createRoleInvalidMember(){ - String name = "{OWNER}"; - String name2 = "admin"; - RangerRole.RoleMember rm1 = new RangerRole.RoleMember(name,true); - RangerRole.RoleMember rm2 = new RangerRole.RoleMember(name2, true); - List usersList = new ArrayList<>(Arrays.asList(rm1,rm2)); - RangerRole rangerRole = new RangerRole(name, name, null, usersList, null); - rangerRole.setCreatedByUser(name); - rangerRole.setId(roleId); - return rangerRole; - } - - private RangerRole createRoleOld(){ - String name = "test-role2"; - String name2 = "admin"; - RangerRole.RoleMember rm1 = new RangerRole.RoleMember(name,true); - RangerRole.RoleMember rm2 = new RangerRole.RoleMember(name2, true); - List usersList = Arrays.asList(rm1,rm2); - RangerRole rangerRole = new RangerRole(name, name, null, usersList, null); - rangerRole.setCreatedByUser(name); - rangerRole.setId(roleId); - return rangerRole; - } - private VXUser createVXUser() { - VXUser testVXUser= new VXUser(); - Collection c = new ArrayList(); - testVXUser.setId(userId); - testVXUser.setCreateDate(new Date()); - testVXUser.setUpdateDate(new Date()); - testVXUser.setOwner("admin"); - testVXUser.setUpdatedBy("admin"); - testVXUser.setName("User1"); - testVXUser.setFirstName("FnameUser1"); - testVXUser.setLastName("LnameUser1"); - testVXUser.setPassword("User1"); - testVXUser.setGroupIdList(null); - testVXUser.setGroupNameList(null); - testVXUser.setStatus(1); - testVXUser.setIsVisible(1); - testVXUser.setUserSource(0); - c.add("ROLE_SYS_ADMIN"); - testVXUser.setUserRoleList(c); - return testVXUser; - } - - private List createXXRoleRefGroupList(){ - List xxRoleRefGroupList = new ArrayList(); - XXRoleRefGroup xxRoleRefGroup1 = new XXRoleRefGroup(); - xxRoleRefGroup1.setRoleId(roleId); - xxRoleRefGroupList.add(xxRoleRefGroup1); - return xxRoleRefGroupList; - } - - private List createXXRoleRefUserList(){ - List xxRoleRefUserList = new ArrayList(); - XXRoleRefUser xxRoleRefUser1 = new XXRoleRefUser(); - xxRoleRefUser1.setRoleId(roleId); - xxRoleRefUserList.add(xxRoleRefUser1); - return xxRoleRefUserList; - } - - private List createRoleList(){ - List roleList = new ArrayList(); - roleList.add("admin"); - roleList.add("user"); - return roleList; - } - - private RangerRoles createRangerRoles(){ - Set rangerRolesSet = new HashSet<>(Arrays.asList(createRole())); - RangerRoles rangerRoles = new RangerRoles(); - rangerRoles.setRangerRoles(rangerRolesSet); - return rangerRoles; - } - - private XXService createXXService(){ - XXService xxService = new XXService(); - xxService.setId(1L); - xxService.setName("test-service"); - xxService.setDescription("test-service"); - xxService.setIsEnabled(true); - xxService.setCreateTime(new Date()); - xxService.setUpdateTime(new Date()); - return xxService; - } - - private GrantRevokeRoleRequest createGrantRevokeRoleRequest(){ - Set users = new HashSet<>(Arrays.asList("test-role","admin")); - Set groups = new HashSet<>(Arrays.asList("test-group","admin")); - GrantRevokeRoleRequest roleRequest = new GrantRevokeRoleRequest(); - roleRequest.setUsers(users); - roleRequest.setGroups(groups); - roleRequest.setGrantor("admin"); - roleRequest.setTargetRoles(new HashSet<>(Arrays.asList("role1","role2"))); - return roleRequest; - } -} diff --git a/security-admin/src/test/java/org/apache/ranger/rest/TestServiceREST.java b/security-admin/src/test/java/org/apache/ranger/rest/TestServiceREST.java index 375135a5af..09d55e89d9 100644 --- a/security-admin/src/test/java/org/apache/ranger/rest/TestServiceREST.java +++ b/security-admin/src/test/java/org/apache/ranger/rest/TestServiceREST.java @@ -60,12 +60,20 @@ import org.apache.ranger.db.XXSecurityZoneRefTagServiceDao; import org.apache.ranger.db.XXServiceDao; import org.apache.ranger.db.XXServiceDefDao; -import org.apache.ranger.entity.*; -import org.apache.ranger.plugin.model.*; +import org.apache.ranger.entity.XXPortalUser; +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.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.RangerPolicyItemCondition; import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; +import org.apache.ranger.plugin.model.RangerService; +import org.apache.ranger.plugin.model.RangerServiceDef; import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef; import org.apache.ranger.plugin.model.RangerServiceDef.RangerContextEnricherDef; import org.apache.ranger.plugin.model.RangerServiceDef.RangerEnumDef; @@ -94,7 +102,14 @@ import org.apache.ranger.service.RangerServiceService; import org.apache.ranger.service.RangerTransactionService; import org.apache.ranger.service.XUserService; -import org.apache.ranger.view.*; +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.VXResponse; +import org.apache.ranger.view.VXString; +import org.apache.ranger.view.VXUser; import org.junit.Assert; import org.junit.FixMethodOrder; import org.junit.Rule; @@ -102,17 +117,12 @@ import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.junit.runners.MethodSorters; -import org.mockito.Answers; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; import com.sun.jersey.core.header.FormDataContentDisposition; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; - -import static org.mockito.ArgumentMatchers.eq; @RunWith(MockitoJUnitRunner.class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) @@ -128,7 +138,7 @@ public class TestServiceREST { @Mock RangerValidatorFactory validatorFactory; - @Mock(answer = Answers.RETURNS_DEEP_STUBS) + @Mock RangerDaoManager daoManager; @Mock @@ -232,19 +242,12 @@ public class TestServiceREST { private String capabilityVector; - private final String grantor = "test-grantor-1"; - - private final String owner_user = "test-owner-user-1"; - - private final String zone_name = "test-zone-1"; - public void setup() { RangerSecurityContext context = new RangerSecurityContext(); context.setUserSession(new UserSessionBase()); RangerContextHolder.setSecurityContext(context); UserSessionBase currentUserSession = ContextUtil .getCurrentUserSession(); - currentUserSession.setXXPortalUser(new XXPortalUser()); currentUserSession.setUserAdmin(true); capabilityVector = Long.toHexString(new RangerPluginCapability().getPluginCapabilities()); } @@ -393,59 +396,6 @@ public ServicePolicies servicePolicies() { sp.setServiceId(1l); return sp; } - private List createLongList(){ - List list = new ArrayList(); - list.add(1L); - list.add(2L); - list.add(3L); - return list; - } - private ArrayList createUserList() { - ArrayList userList = new ArrayList(); - userList.add("test-user-1"); - return userList; - } - private ArrayList createGroupList() { - ArrayList groupList = new ArrayList(); - groupList.add("test-group-1"); - return groupList; - } - private ArrayList createRoleList() { - ArrayList roleList = new ArrayList(); - roleList.add("test-role-1"); - return roleList; - } - private ArrayList createGrantorGroupList() { - ArrayList grantorGroupList = new ArrayList(); - grantorGroupList.add("test-grantor-group-1"); - return grantorGroupList; - } - - private HashMap createResourceMap() { - HashMap resourceMap = new HashMap(); - resourceMap.put("test-resource-1", "test-resource-value-1"); - return resourceMap; - } - - private ArrayList createAccessTypeList() { - ArrayList accessTypeList = new ArrayList(); - accessTypeList.add("test-access-type-1"); - return accessTypeList; - } - private GrantRevokeRequest createValidGrantRevokeRequest() { - GrantRevokeRequest grantRevokeRequest = new GrantRevokeRequest(); - grantRevokeRequest.setUsers(new HashSet<>(createUserList())); - grantRevokeRequest.setGroups(new HashSet<>(createGroupList())); - grantRevokeRequest.setRoles(new HashSet<>(createRoleList())); - grantRevokeRequest.setGrantor(grantor); - grantRevokeRequest.setGrantorGroups(new HashSet<>(createGrantorGroupList())); - grantRevokeRequest.setOwnerUser(owner_user); - grantRevokeRequest.setResource(createResourceMap()); - grantRevokeRequest.setAccessTypes(new HashSet<>(createAccessTypeList())); - grantRevokeRequest.setZoneName(zone_name); - grantRevokeRequest.setIsRecursive(true); - return grantRevokeRequest; - } @Test public void test1createServiceDef() throws Exception { @@ -712,6 +662,7 @@ public void test8updateServiceDef() throws Exception { @Test public void test9deleteService() throws Exception { + RangerService rangerService = rangerService(); XXServiceDef xServiceDef = serviceDef(); XXService xService = xService(); @@ -2202,180 +2153,6 @@ public void test63getServices() throws Exception{ } - public void mockValidateGrantRevokeRequest(){ - Mockito.when(userMgr.getXUserByUserName(Mockito.anyString())).thenReturn(Mockito.mock(VXUser.class)); - Mockito.when(userMgr.getGroupByGroupName(Mockito.anyString())).thenReturn(Mockito.mock(VXGroup.class)); - Mockito.when(daoManager.getXXRole().findByRoleName(Mockito.anyString())).thenReturn(Mockito.mock(XXRole.class)); - } - @Test - public void test14bGrantAccess() throws Exception { - HttpServletRequest request = Mockito.mock(HttpServletRequest.class); - String serviceName = "HDFS_1"; - GrantRevokeRequest grantRequestObj = createValidGrantRevokeRequest(); - Mockito.when(serviceUtil.isValidateHttpsAuthentication(serviceName, request)) - .thenReturn(true); - Mockito.doNothing().when(bizUtil).failUnauthenticatedIfNotAllowed(); - mockValidateGrantRevokeRequest(); - Mockito.when(xUserService.getXUserByUserName(Mockito.anyString())).thenReturn(Mockito.mock(VXUser.class)); - Mockito.when(svcStore.getServiceByName(Mockito.anyString())).thenReturn(Mockito.mock(RangerService.class)); - Mockito.when(bizUtil.isUserRangerAdmin(Mockito.anyString())).thenReturn(true); - RESTResponse restResponse = serviceREST.grantAccess(serviceName, - grantRequestObj, request); - Mockito.verify(svcStore, Mockito.times(1)).createPolicy(Mockito.any(RangerPolicy.class)); - assert restResponse != null; - assert restResponse.getStatusCode() == RESTResponse.STATUS_SUCCESS; - } - @Test - public void test64SecureGrantAccess(){ - HttpServletRequest request = Mockito.mock(HttpServletRequest.class); - String serviceName = "HDFS_1"; - GrantRevokeRequest grantRequestObj = createValidGrantRevokeRequest(); - Mockito.when(serviceUtil.isValidService(serviceName, request)).thenReturn(true); - Mockito.when(daoManager.getXXService().findByName(Mockito.anyString())).thenReturn(Mockito.mock(XXService.class)); - Mockito.when(daoManager.getXXServiceDef().getById(Mockito.anyLong())).thenReturn(Mockito.mock(XXServiceDef.class)); - try { - Mockito.when(svcStore.getServiceByName(Mockito.anyString())).thenReturn(Mockito.mock(RangerService.class)); - } catch (Exception e) { - throw new RuntimeException(e); - } - mockValidateGrantRevokeRequest(); - Mockito.when(bizUtil.isAdmin()).thenReturn(true); - Mockito.when(bizUtil.isUserServiceAdmin(Mockito.any(RangerService.class), Mockito.anyString())).thenReturn(true); - RESTResponse restResponse; - try { - restResponse = serviceREST.secureGrantAccess(serviceName, grantRequestObj, request); - } catch (Exception e) { - throw new RuntimeException(e); - } - try { - Mockito.verify(svcStore, Mockito.times(1)).createPolicy(Mockito.any(RangerPolicy.class)); - } catch (Exception e) { - throw new RuntimeException(e); - } - assert restResponse != null; - assert restResponse.getStatusCode() == RESTResponse.STATUS_SUCCESS; - } - @Test - public void test15bRevokeAccess() throws Exception { - HttpServletRequest request = Mockito.mock(HttpServletRequest.class); - String serviceName = "HDFS_1"; - GrantRevokeRequest revokeRequest = createValidGrantRevokeRequest(); - Mockito.when(serviceUtil.isValidateHttpsAuthentication(serviceName, request)) - .thenReturn(true); - Mockito.doNothing().when(bizUtil).failUnauthenticatedIfNotAllowed(); - mockValidateGrantRevokeRequest(); - Mockito.when(xUserService.getXUserByUserName(Mockito.anyString())).thenReturn(Mockito.mock(VXUser.class)); - Mockito.when(bizUtil.isUserRangerAdmin(Mockito.anyString())).thenReturn(true); - RESTResponse restResponse = serviceREST.revokeAccess(serviceName, - revokeRequest, request); - assert restResponse != null; - assert restResponse.getStatusCode() == RESTResponse.STATUS_SUCCESS; - } - @Test - public void test65SecureRevokeAccess(){ - HttpServletRequest request = Mockito.mock(HttpServletRequest.class); - String serviceName = "HDFS_1"; - GrantRevokeRequest revokeRequest = createValidGrantRevokeRequest(); - Mockito.when(serviceUtil.isValidService(serviceName, request)).thenReturn(true); - Mockito.when(daoManager.getXXService().findByName(Mockito.anyString())).thenReturn(Mockito.mock(XXService.class)); - Mockito.when(daoManager.getXXServiceDef().getById(Mockito.anyLong())).thenReturn(Mockito.mock(XXServiceDef.class)); - try { - Mockito.when(svcStore.getServiceByName(Mockito.anyString())).thenReturn(Mockito.mock(RangerService.class)); - } catch (Exception e) { - throw new RuntimeException(e); - } - mockValidateGrantRevokeRequest(); - Mockito.when(bizUtil.isAdmin()).thenReturn(true); - Mockito.when(bizUtil.isUserRangerAdmin(Mockito.anyString())).thenReturn(true); - RESTResponse restResponse = null; - try { - restResponse = serviceREST.secureRevokeAccess(serviceName, - revokeRequest, request); - } catch (Exception e) { - throw new RuntimeException(e); - } - assert restResponse != null; - assert restResponse.getStatusCode() == RESTResponse.STATUS_SUCCESS; - } - @Test - public void test66ApplyPolicy(){ - ServiceREST serviceRESTSpy = Mockito.spy(serviceREST); - HttpServletRequest request = Mockito.mock(HttpServletRequest.class); - RangerPolicy policy = rangerPolicy(); - Mockito.doReturn(policy).when(serviceRESTSpy).createPolicy(Mockito.any(RangerPolicy.class), eq(null)); - RangerPolicy returnedPolicy = serviceRESTSpy.applyPolicy(policy, request); - assert returnedPolicy != null; - assert returnedPolicy.getId().equals(policy.getId()); - assert returnedPolicy.getName().equals(policy.getName()); - } - - @Test - public void test67ResetPolicyCache(){ - boolean res = true; - String serviceName = "HDFS_1"; - Mockito.when(bizUtil.isAdmin()).thenReturn(true); - Mockito.when(svcStore.resetPolicyCache(serviceName)).thenReturn(res); - boolean isReset = serviceREST.resetPolicyCache(serviceName); - assert isReset == res; - } - - @Test - public void test68ResetPolicyCacheAll(){ - boolean res = true; - Mockito.when(bizUtil.isAdmin()).thenReturn(true); - Mockito.when(svcStore.resetPolicyCache(null)).thenReturn(res); - boolean isReset = serviceREST.resetPolicyCacheAll(); - assert isReset == res; - } - - @Test - public void test69DeletePolicyDeltas() { - int val = 1; - HttpServletRequest request = Mockito.mock(HttpServletRequest.class); - serviceREST.deletePolicyDeltas(val, request); - Mockito.verify(svcStore).resetPolicyUpdateLog(Mockito.anyInt(), Mockito.anyInt()); - } - @Test - public void test70PurgeEmptyPolicies() { - ServiceREST serviceRESTSpy = Mockito.spy(serviceREST); - HttpServletRequest request = Mockito.mock(HttpServletRequest.class); - String serviceName = "HDFS_1"; - try { - Mockito.when(svcStore.getServiceByName(Mockito.anyString())).thenReturn(Mockito.mock(RangerService.class)); - } catch (Exception e) { - throw new RuntimeException(e); - } - try { - Mockito.when(svcStore.getServicePolicies(Mockito.anyString(), Mockito.anyLong())).thenReturn(servicePolicies()); - } catch (Exception e) { - throw new RuntimeException(e); - } - serviceRESTSpy.purgeEmptyPolicies(serviceName, request); - Mockito.verify(serviceRESTSpy, Mockito.never()).deletePolicy(Mockito.anyLong()); - } - - @Test - public void test71DeleteClusterServices(){ - String clusterName = "cluster1"; - List idsToDelete = createLongList(); - Mockito.when(daoManager.getXXServiceConfigMap().findServiceIdsByClusterName(Mockito.anyString())). - thenReturn(idsToDelete); - XXServiceDef xServiceDef = serviceDef(); - XXService xService = xService(); - XXServiceDefDao xServiceDefDao = Mockito.mock(XXServiceDefDao.class); - Mockito.when(validatorFactory.getServiceValidator(svcStore)) - .thenReturn(serviceValidator); - Mockito.when(daoManager.getXXService().getById(Mockito.anyLong())).thenReturn(xService); - Mockito.when(daoManager.getXXServiceDef()).thenReturn(xServiceDefDao); - Mockito.when(xServiceDefDao.getById(xService.getType())).thenReturn( - xServiceDef); - ResponseEntity> deletedResponse = serviceREST.deleteClusterServices(clusterName); - assert deletedResponse.getStatusCode() == HttpStatus.OK; - assert deletedResponse.getBody() != null; - for (ServiceDeleteResponse response : deletedResponse.getBody()) { - assert response.getIsDeleted(); - } - } } diff --git a/tagsync/src/main/java/org/apache/ranger/tagsync/nestedstructureplugin/AtlasNestedStructureResourceMapper.java b/tagsync/src/main/java/org/apache/ranger/tagsync/nestedstructureplugin/AtlasNestedStructureResourceMapper.java deleted file mode 100644 index 71dd70b7fd..0000000000 --- a/tagsync/src/main/java/org/apache/ranger/tagsync/nestedstructureplugin/AtlasNestedStructureResourceMapper.java +++ /dev/null @@ -1,95 +0,0 @@ -/** -* Copyright 2022 Comcast Cable Communications Management, LLC -* -* Licensed 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. -* -* SPDX-License-Identifier: Apache-2.0 -*/ -package org.apache.ranger.tagsync.nestedstructureplugin; - -import org.apache.commons.lang.StringUtils; -import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; -import org.apache.ranger.plugin.model.RangerServiceResource; -import org.apache.ranger.tagsync.source.atlas.AtlasResourceMapper; -import org.apache.ranger.tagsync.source.atlasrest.RangerAtlasEntity; - -import java.util.HashMap; -import java.util.Map; - -/** Syncing tag-metadata (resource) relationships from Apache Atlas to Ranger - **/ - -public class AtlasNestedStructureResourceMapper extends AtlasResourceMapper { - public static final String RANGER_SERVICETYPE = "nestedstructure"; - public static final String ENTITY_TYPE_NESTEDSTRUCTURE_SCHEMA = "json_object"; - public static final String ENTITY_TYPE_NESTEDSTRUCTURE_FIELD = "json_field"; - public static final String RANGER_TYPE_NESTEDSTRUCTURE_SCHEMA = "schema"; - public static final String RANGER_TYPE_NESTEDSTRUCTURE_FIELD = "field"; - public static final String QUALIFIED_NAME_DELIMITER = "#"; - - public static final String[] SUPPORTED_ENTITY_TYPES = { ENTITY_TYPE_NESTEDSTRUCTURE_SCHEMA, ENTITY_TYPE_NESTEDSTRUCTURE_FIELD }; - - public AtlasNestedStructureResourceMapper() { - super(RANGER_SERVICETYPE, SUPPORTED_ENTITY_TYPES); - } - - @Override - public RangerServiceResource buildResource(final RangerAtlasEntity entity) throws Exception { - String qualifiedName = (String)entity.getAttributes().get(AtlasResourceMapper.ENTITY_ATTRIBUTE_QUALIFIED_NAME); - - if (StringUtils.isEmpty(qualifiedName)) { - throw new Exception("attribute '" + ENTITY_ATTRIBUTE_QUALIFIED_NAME + "' not found in entity"); - } - - String resourceStr = getResourceNameFromQualifiedName(qualifiedName); - - if (StringUtils.isEmpty(resourceStr)) { - throwExceptionWithMessage("resource not found in attribute '" + ENTITY_ATTRIBUTE_QUALIFIED_NAME + "': " + qualifiedName); - } - - String clusterName = getClusterNameFromQualifiedName(qualifiedName); - if (StringUtils.isEmpty(clusterName)) { - clusterName = defaultClusterName; - } - - String entityType = entity.getTypeName(); - String entityGuid = entity.getGuid(); - String serviceName = getRangerServiceName(clusterName); - String[] resources = resourceStr.split(QUALIFIED_NAME_DELIMITER); - String schemaName = resources.length > 0 ? resources[0] : null; - String fieldName = resources.length > 1 ? resources[1] : null; - - Map elements = new HashMap<>(); - - if (StringUtils.equals(entityType, ENTITY_TYPE_NESTEDSTRUCTURE_SCHEMA)) { - if (StringUtils.isNotEmpty(schemaName)) { - elements.put(RANGER_TYPE_NESTEDSTRUCTURE_SCHEMA , new RangerPolicyResource(schemaName)); - } - } else if (StringUtils.equals(entityType, ENTITY_TYPE_NESTEDSTRUCTURE_FIELD)) { - if (StringUtils.isNotEmpty(schemaName) && StringUtils.isNotEmpty(fieldName)) { - elements.put(RANGER_TYPE_NESTEDSTRUCTURE_SCHEMA, new RangerPolicyResource(schemaName)); - elements.put(RANGER_TYPE_NESTEDSTRUCTURE_FIELD, new RangerPolicyResource(fieldName)); - } - } else { - throwExceptionWithMessage("unrecognized entity-type: " + entityType); - } - - if (elements.isEmpty()) { - throwExceptionWithMessage("invalid qualifiedName for entity-type '" + entityType + "': " + qualifiedName); - } - - RangerServiceResource ret = new RangerServiceResource(entityGuid, serviceName, elements); - - return ret; - } -} diff --git a/tagsync/src/main/java/org/apache/ranger/tagsync/source/atlas/AtlasNotificationMapper.java b/tagsync/src/main/java/org/apache/ranger/tagsync/source/atlas/AtlasNotificationMapper.java index dadc76a547..1b81bafae2 100644 --- a/tagsync/src/main/java/org/apache/ranger/tagsync/source/atlas/AtlasNotificationMapper.java +++ b/tagsync/src/main/java/org/apache/ranger/tagsync/source/atlas/AtlasNotificationMapper.java @@ -44,7 +44,7 @@ public class AtlasNotificationMapper { private static final Logger LOG = LoggerFactory.getLogger(AtlasNotificationMapper.class); private static Map unhandledEventTypes = new HashMap<>(); - public static void logUnhandledEntityNotification(EntityNotificationWrapper entityNotification) { + private static void logUnhandledEntityNotification(EntityNotificationWrapper entityNotification) { boolean skipLogging = entityNotification.getIsEntityCreateOp() && entityNotification.getIsEmptyClassifications(); @@ -110,7 +110,7 @@ public static Map processAtlasEntities(List 0 ? resources[0] : null; - String fieldName = resources.length > 1 ? resources[1] : null; - - - assertEquals("schemaName does not match expected value", "json_object.foo.v1", schemaName); - assertEquals("fieldName does not match expected value", "partner", fieldName); - System.out.println(schemaName); - System.out.println(fieldName); - } - - @Test - public void test_ResourceParseSchemaName() { - String resourceStr = "json_object.foo.v1"; - String[] resources = resourceStr.split(QUALIFIED_NAME_DELIMITER); - String schemaName = resources.length > 0 ? resources[0] : null; - String fieldName = resources.length > 1 ? resources[1] : null; - - assertEquals("schemaName does not match expected value", resourceStr, schemaName); - assertNull("fieldName does not match expected value", fieldName); - System.out.println(schemaName); - System.out.println(fieldName); - } - - @Test - public void test_RangerEntityJsonField() { - String typeName = "json_field"; - String guid = "0265354542434ff-aewra7297dc"; - - try { - Map attributes = Collections.singletonMap("qualifiedName", "json_object.foo.v1#channel"); - RangerAtlasEntity entity = new RangerAtlasEntity(typeName, guid, attributes); - RangerServiceResource resource = mapper.buildResource(entity); - - assertTrue("Resource elements list is empty", resource.getResourceElements().size() > 0); - assertEquals("Resource elements list size does not match expected", 2, resource.getResourceElements().size()); - assertNotNull("Resource element missing value for schema", resource.getResourceElements().get("schema")); - assertEquals("Resource element schema value does not match", Collections.singletonList("json_object.foo.v1"), resource.getResourceElements().get("schema").getValues()); - assertNotNull("Resource element missing value for field", resource.getResourceElements().get("field")); - assertEquals("Resource element field value does not match", Collections.singletonList("channel"), resource.getResourceElements().get("field").getValues()); - assertEquals("serviceName does not match expected value", "null_nestedstructure", resource.getServiceName()); - } catch(Exception e) { - e.printStackTrace(); - fail("An error occurred while processing resource"); - } - - // qualifiedName containing clusterName - try { - Map attributes = Collections.singletonMap("qualifiedName", "json_object.foo.v1#channel@dev"); - RangerAtlasEntity entity = new RangerAtlasEntity(typeName, guid, attributes); - RangerServiceResource resource = mapper.buildResource(entity); - - assertTrue("Resource elements list is empty", resource.getResourceElements().size() > 0); - assertEquals("Resource elements list size does not match expected", 2, resource.getResourceElements().size()); - assertNotNull("Resource element missing value for schema", resource.getResourceElements().get("schema")); - assertEquals("Resource element schema value does not match", Collections.singletonList("json_object.foo.v1"), resource.getResourceElements().get("schema").getValues()); - assertNotNull("Resource element missing value for field", resource.getResourceElements().get("field")); - assertEquals("Resource element field value does not match", Collections.singletonList("channel"), resource.getResourceElements().get("field").getValues()); - assertEquals("serviceName does not match expected value", "dev_nestedstructure", resource.getServiceName()); - } catch(Exception e) { - e.printStackTrace(); - fail("An error occurred while processing resource"); - } - } - - @Test - public void test_RangerEntityJsonObject() { - String typeName = "json_object"; - String guid = "9fsdd-sfsrsag-dasd-3fa97"; - - try { - Map attributes = Collections.singletonMap("qualifiedName", "json_object.foo.v1"); - RangerAtlasEntity entity = new RangerAtlasEntity(typeName, guid, attributes); - RangerServiceResource resource = mapper.buildResource(entity); - - assertTrue("Resource elements list is empty", resource.getResourceElements().size() > 0); - assertEquals("Resource elements list size does not match expected", 1, resource.getResourceElements().size()); - assertNotNull("Resource element missing value for schema", resource.getResourceElements().get("schema")); - assertEquals("Resource element schema value does not match", Collections.singletonList("json_object.foo.v1"), resource.getResourceElements().get("schema").getValues()); - assertEquals("serviceName does not match expected value", "null_nestedstructure", resource.getServiceName()); - } catch (Exception e) { - e.printStackTrace(); - fail("An error occurred while processing resource"); - } - - // qualifiedName containing clusterName - try { - Map attributes = Collections.singletonMap("qualifiedName", "json_object.foo.v1@dev"); - RangerAtlasEntity entity = new RangerAtlasEntity(typeName, guid, attributes); - RangerServiceResource resource = mapper.buildResource(entity); - - assertTrue("Resource elements list is empty", resource.getResourceElements().size() > 0); - assertEquals("Resource elements list size does not match expected", 1, resource.getResourceElements().size()); - assertNotNull("Resource element missing value for schema", resource.getResourceElements().get("schema")); - assertEquals("Resource element schema value does not match", Collections.singletonList("json_object.foo.v1"), resource.getResourceElements().get("schema").getValues()); - assertEquals("serviceName does not match expected value", "dev_nestedstructure", resource.getServiceName()); - } catch (Exception e) { - e.printStackTrace(); - fail("An error occurred while processing resource"); - } - } -}