You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by rm...@apache.org on 2019/10/17 01:27:02 UTC
[ranger] branch master updated: RANGER-2623:Add Validations to
RoleREST apis
This is an automated email from the ASF dual-hosted git repository.
rmani pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/master by this push:
new 722a660 RANGER-2623:Add Validations to RoleREST apis
722a660 is described below
commit 722a660b214aa9301c18b7f123f2ad689cdccf94
Author: rmani <rm...@hortonworks.com>
AuthorDate: Wed Oct 16 15:47:32 2019 -0700
RANGER-2623:Add Validations to RoleREST apis
Signed-off-by: rmani <rm...@hortonworks.com>
---
.../ranger/plugin/errors/ValidationErrorCode.java | 11 +
.../model/validation/RangerRoleValidator.java | 237 +++++++++++++++++++++
.../plugin/model/validation/RangerValidator.java | 45 ++++
.../org/apache/ranger/plugin/store/RoleStore.java | 4 +
.../java/org/apache/ranger/biz/RoleDBStore.java | 12 ++
.../ranger/common/RangerValidatorFactory.java | 6 +
.../main/java/org/apache/ranger/rest/RoleREST.java | 14 ++
7 files changed, 329 insertions(+)
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/errors/ValidationErrorCode.java b/agents-common/src/main/java/org/apache/ranger/plugin/errors/ValidationErrorCode.java
index 34f41f1..2927362 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/errors/ValidationErrorCode.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/errors/ValidationErrorCode.java
@@ -117,6 +117,17 @@ public enum ValidationErrorCode {
SECURITY_ZONE_VALIDATION_ERR_ZONE_RESOURCE_CONFLICT(3046, "Multiple zones:[{0}] match resource:[{1}]"),
SECURITY_ZONE_VALIDATION_ERR_UNEXPECTED_RESOURCES(3047, "Tag service [{0}], with non-empty resources, is associated with security zone"),
+ //RANGER ROLE Validations
+ ROLE_VALIDATION_ERR_NULL_RANGER_ROLE_OBJECT(4001, "Internal error: RangerRole object passed in was null"),
+ ROLE_VALIDATION_ERR_MISSING_FIELD(4002, "Internal error: missing field[{0}]"),
+ ROLE_VALIDATION_ERR_NULL_RANGER_ROLE_NAME(4003, "Internal error: RangerRole name passed in was null/empty"),
+ ROLE_VALIDATION_ERR_MISSING_USER_OR_GROUPS_OR_ROLES(4004, "RangerRole should contain atleast one user or group or role"),
+ ROLE_VALIDATION_ERR_ROLE_NAME_CONFLICT(4005, "Another RangerRole already exists for this name: Role =[{0}]]"),
+ ROLE_VALIDATION_ERR_INVALID_ROLE_ID(4006, "No RangerRole found for id[{0}]"),
+ ROLE_VALIDATION_ERR_INVALID_ROLE_NAME(4007, "No RangerRole found for name[{0}]"),
+ ROLE_VALIDATION_ERR_UNSUPPORTED_ACTION(4008, "Internal error: method signature isValid(Long) is only supported for DELETE"),
+
+
;
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerRoleValidator.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerRoleValidator.java
new file mode 100644
index 0000000..beeb888
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerRoleValidator.java
@@ -0,0 +1,237 @@
+/*
+ * 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.plugin.model.validation;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.errors.ValidationErrorCode;
+import org.apache.ranger.plugin.model.RangerRole;
+import org.apache.ranger.plugin.store.RoleStore;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class RangerRoleValidator extends RangerValidator {
+ private static final Log LOG = LogFactory.getLog(RangerRoleValidator.class);
+
+ public RangerRoleValidator(RoleStore store) {
+ super(store);
+ }
+
+ public void validate(RangerRole rangeRole, Action action) throws Exception {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(String.format("==> RangerRoleValidator.validate(%s, %s)", rangeRole, action));
+ }
+
+ List<ValidationFailureDetails> failures = new ArrayList<>();
+ boolean valid = isValid(rangeRole, action, failures);
+ String message = "";
+ try {
+ if (!valid) {
+ message = serializeFailures(failures);
+ throw new Exception(message);
+ }
+ } finally {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(String.format("<== RangerRoleValidator.validate(%s, %s): %s, reason[%s]", rangeRole, action, valid, message));
+ }
+ }
+ }
+
+ @Override
+ boolean isValid(Long id, Action action, List<ValidationFailureDetails> failures) {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug(String.format("==> RangerRoleValidator.isValid(%s, %s, %s)", id, action, failures));
+ }
+
+ boolean valid = true;
+ if (action != Action.DELETE) {
+ ValidationErrorCode error = ValidationErrorCode.ROLE_VALIDATION_ERR_UNSUPPORTED_ACTION;
+ failures.add(new ValidationFailureDetailsBuilder()
+ .isAnInternalError()
+ .becauseOf(error.getMessage())
+ .errorCode(error.getErrorCode())
+ .build());
+ valid = false;
+ } else if (id == null) {
+ ValidationErrorCode error = ValidationErrorCode.ROLE_VALIDATION_ERR_MISSING_FIELD;
+ failures.add(new ValidationFailureDetailsBuilder()
+ .becauseOf("Role id was null/missing")
+ .field("id")
+ .isMissing()
+ .errorCode(error.getErrorCode())
+ .becauseOf(error.getMessage(id))
+ .build());
+ valid = false;
+ } else if (!roleExists(id)) {
+ ValidationErrorCode error = ValidationErrorCode.ROLE_VALIDATION_ERR_INVALID_ROLE_ID;
+ failures.add(new ValidationFailureDetailsBuilder()
+ .becauseOf("Role with id[{0}] does not exist")
+ .field("id")
+ .isMissing()
+ .errorCode(error.getErrorCode())
+ .becauseOf(error.getMessage(id))
+ .build());
+ valid = false;
+ }
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug(String.format("<== RangerRoleValidator.isValid(%s, %s, %s): %s", id, action, failures, valid));
+ }
+ return valid;
+ }
+
+
+ @Override
+ boolean isValid(String name, Action action, List<ValidationFailureDetails> failures) {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug(String.format("==> RangerRoleValidator.isValid(%s, %s, %s)", name, action, failures));
+ }
+
+ boolean valid = true;
+ if (action != Action.DELETE) {
+ ValidationErrorCode error = ValidationErrorCode.ROLE_VALIDATION_ERR_UNSUPPORTED_ACTION;
+ failures.add(new ValidationFailureDetailsBuilder()
+ .isAnInternalError()
+ .becauseOf(error.getMessage())
+ .errorCode(error.getErrorCode())
+ .build());
+ valid = false;
+ } else if (name == null) {
+ ValidationErrorCode error = ValidationErrorCode.ROLE_VALIDATION_ERR_MISSING_FIELD;
+ failures.add(new ValidationFailureDetailsBuilder()
+ .becauseOf("Role name was null/missing")
+ .field("id")
+ .isMissing()
+ .errorCode(error.getErrorCode())
+ .becauseOf(error.getMessage(name))
+ .build());
+ valid = false;
+ } else if (!roleExists(name)) {
+ ValidationErrorCode error = ValidationErrorCode.ROLE_VALIDATION_ERR_INVALID_ROLE_NAME;
+ failures.add(new ValidationFailureDetailsBuilder()
+ .becauseOf("Role with name[{0}] does not exist")
+ .field("name")
+ .isMissing()
+ .errorCode(error.getErrorCode())
+ .becauseOf(error.getMessage(name))
+ .build());
+ valid = false;
+ }
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug(String.format("<== RangerRoleValidator.isValid(%s, %s, %s): %s", name, action, failures, valid));
+ }
+ return valid;
+ }
+
+ boolean isValid(RangerRole rangerRole, Action action, List<ValidationFailureDetails> failures) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(String.format("==> RangerRoleValidator.isValid(%s, %s, %s)", rangerRole, action, failures));
+ }
+
+ boolean valid = true;
+ if (rangerRole == null) {
+ ValidationErrorCode error = ValidationErrorCode.ROLE_VALIDATION_ERR_NULL_RANGER_ROLE_OBJECT;
+ failures.add(new ValidationFailureDetailsBuilder()
+ .isAnInternalError()
+ .isMissing()
+ .becauseOf(error.getMessage())
+ .errorCode(error.getErrorCode())
+ .build());
+ valid = false;
+ } else {
+ String roleName = rangerRole.getName();
+ if (StringUtils.isEmpty(roleName)) {
+ ValidationErrorCode error = ValidationErrorCode.ROLE_VALIDATION_ERR_NULL_RANGER_ROLE_NAME;
+ failures.add(new ValidationFailureDetailsBuilder()
+ .field("name")
+ .isMissing()
+ .becauseOf(error.getMessage())
+ .errorCode(error.getErrorCode())
+ .build());
+ valid = false;
+ }
+
+ List<RangerRole.RoleMember> users = rangerRole.getUsers();
+ List<RangerRole.RoleMember> groups = rangerRole.getGroups();
+ List<RangerRole.RoleMember> roles = rangerRole.getRoles();
+
+ if (CollectionUtils.isEmpty(users) && CollectionUtils.isEmpty(groups) && CollectionUtils.isEmpty(roles)) {
+ ValidationErrorCode error = ValidationErrorCode.ROLE_VALIDATION_ERR_MISSING_USER_OR_GROUPS_OR_ROLES;
+ failures.add(new ValidationFailureDetailsBuilder()
+ .field("users and groups and roles")
+ .isMissing()
+ .becauseOf(error.getMessage())
+ .errorCode(error.getErrorCode())
+ .build());
+ valid = false;
+ }
+
+ Long id = rangerRole.getId();
+ RangerRole existingRangerRole = getRangerRole(id);
+
+ if (action == Action.CREATE) {
+ if (existingRangerRole != null) {
+ String existingRoleName = existingRangerRole.getName();
+ if (roleName.equals(existingRoleName)) {
+ ValidationErrorCode error = ValidationErrorCode.ROLE_VALIDATION_ERR_ROLE_NAME_CONFLICT;
+ failures.add(new ValidationFailureDetailsBuilder()
+ .field("name")
+ .isSemanticallyIncorrect()
+ .becauseOf(error.getMessage(existingRoleName))
+ .errorCode(error.getErrorCode())
+ .build());
+ valid = false;
+ }
+ }
+ } else if (action == Action.UPDATE) { // id is ignored for CREATE
+ if (id == null) {
+ ValidationErrorCode error = ValidationErrorCode.ROLE_VALIDATION_ERR_MISSING_FIELD;
+ failures.add(new ValidationFailureDetailsBuilder()
+ .field("id")
+ .isMissing()
+ .becauseOf(error.getMessage(id))
+ .errorCode(error.getErrorCode())
+ .build());
+ valid = false;
+ }
+ if (existingRangerRole == null) {
+ ValidationErrorCode error = ValidationErrorCode.ROLE_VALIDATION_ERR_INVALID_ROLE_ID;
+ failures.add(new ValidationFailureDetailsBuilder()
+ .field("id")
+ .isSemanticallyIncorrect()
+ .becauseOf(error.getMessage(id))
+ .errorCode(error.getErrorCode())
+ .build());
+ valid = false;
+ }
+ }
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(String.format("<== RangerRoleValidator.isValid(%s, %s, %s): %s", rangerRole, action, failures, valid));
+ }
+
+ return valid;
+ }
+}
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerValidator.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerValidator.java
index f31483e..74653b2 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerValidator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerValidator.java
@@ -36,6 +36,7 @@ import org.apache.commons.logging.LogFactory;
import org.apache.ranger.plugin.errors.ValidationErrorCode;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+import org.apache.ranger.plugin.model.RangerRole;
import org.apache.ranger.plugin.model.RangerSecurityZone;
import org.apache.ranger.plugin.model.RangerService;
import org.apache.ranger.plugin.model.RangerServiceDef;
@@ -44,6 +45,7 @@ import org.apache.ranger.plugin.model.RangerServiceDef.RangerEnumDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerEnumElementDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerServiceConfigDef;
+import org.apache.ranger.plugin.store.RoleStore;
import org.apache.ranger.plugin.store.ServiceStore;
import org.apache.ranger.plugin.util.RangerObjectFactory;
@@ -51,6 +53,7 @@ public abstract class RangerValidator {
private static final Log LOG = LogFactory.getLog(RangerValidator.class);
+ RoleStore _roleStore;
ServiceStore _store;
RangerObjectFactory _factory = new RangerObjectFactory();
@@ -65,6 +68,13 @@ public abstract class RangerValidator {
_store = store;
}
+ protected RangerValidator(RoleStore roleStore) {
+ if (roleStore == null) {
+ throw new IllegalArgumentException("ServiceValidator(): store is null!");
+ }
+ _roleStore = roleStore;
+ }
+
public void validate(Long id, Action action) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerValidator.validate(" + id + ")");
@@ -770,4 +780,39 @@ public abstract class RangerValidator {
}
return result;
}
+
+ RangerRole getRangerRole(Long id) {
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerValidator.getRangerRole(" + id + ")");
+ }
+ RangerRole result = null;
+ try {
+ result = _roleStore.getRole(id);
+ } catch (Exception e) {
+ LOG.debug("Encountred exception while retrieving RangerRole from RoleStore store!", e);
+ }
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerValidator.getRangerRole(" + id + "): " + result);
+ }
+ return result;
+ }
+
+ boolean roleExists(Long id) {
+ try {
+ return _roleStore.roleExists(id);
+ } catch (Exception e) {
+ LOG.debug("Encountred exception while retrieving RangerRole from role store!", e);
+ return false;
+ }
+ }
+
+ boolean roleExists(String name) {
+ try {
+ return _roleStore.roleExists(name);
+ } catch (Exception e) {
+ LOG.debug("Encountred exception while retrieving RangerRole from role store!", e);
+ return false;
+ }
+ }
}
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/store/RoleStore.java b/agents-common/src/main/java/org/apache/ranger/plugin/store/RoleStore.java
index 8bf4603..0cb8f02 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/store/RoleStore.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/RoleStore.java
@@ -48,5 +48,9 @@ public interface RoleStore {
RangerRoles getRangerRoles(String serviceName, Long lastKnownRoleVersion) throws Exception;
Long getRoleVersion(String serviceName);
+
+ boolean roleExists(Long id) throws Exception;
+
+ boolean roleExists(String name) throws Exception;
}
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 dfc5be8..5d432f8 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
@@ -312,5 +312,17 @@ public class RoleDBStore implements RoleStore {
public List<RangerRole> getRoles(XXService service) {
return service == null ? ListUtils.EMPTY_LIST : getRoles(service.getId());
}
+
+ @Override
+ public boolean roleExists(Long id) throws Exception {
+ XXRole role = daoMgr.getXXRole().findByRoleId(id);
+ return role != null;
+ }
+
+ @Override
+ public boolean roleExists(String name) throws Exception {
+ XXRole role = daoMgr.getXXRole().findByRoleName(name);
+ return role != null;
+ }
}
diff --git a/security-admin/src/main/java/org/apache/ranger/common/RangerValidatorFactory.java b/security-admin/src/main/java/org/apache/ranger/common/RangerValidatorFactory.java
index 04c941e..50640f0 100644
--- a/security-admin/src/main/java/org/apache/ranger/common/RangerValidatorFactory.java
+++ b/security-admin/src/main/java/org/apache/ranger/common/RangerValidatorFactory.java
@@ -23,6 +23,8 @@ import org.apache.ranger.plugin.model.validation.RangerPolicyValidator;
import org.apache.ranger.plugin.model.validation.RangerSecurityZoneValidator;
import org.apache.ranger.plugin.model.validation.RangerServiceDefValidator;
import org.apache.ranger.plugin.model.validation.RangerServiceValidator;
+import org.apache.ranger.plugin.model.validation.RangerRoleValidator;
+import org.apache.ranger.plugin.store.RoleStore;
import org.apache.ranger.plugin.store.SecurityZoneStore;
import org.apache.ranger.plugin.store.ServiceStore;
import org.springframework.context.annotation.Scope;
@@ -46,4 +48,8 @@ public class RangerValidatorFactory {
public RangerSecurityZoneValidator getSecurityZoneValidator(ServiceStore store, SecurityZoneStore securityZoneStore) {
return new RangerSecurityZoneValidator(store, securityZoneStore);
}
+
+ public RangerRoleValidator getRangerRoleValidator(RoleStore roleStore) {
+ return new RangerRoleValidator(roleStore);
+ }
}
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 268c8c4..3156e48 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
@@ -56,6 +56,8 @@ import org.apache.ranger.entity.XXServiceDef;
import org.apache.ranger.plugin.model.RangerPluginInfo;
import org.apache.ranger.plugin.model.RangerRole;
import org.apache.ranger.plugin.model.RangerService;
+import org.apache.ranger.plugin.model.validation.RangerRoleValidator;
+import org.apache.ranger.plugin.model.validation.RangerValidator;
import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
import org.apache.ranger.plugin.util.GrantRevokeRoleRequest;
@@ -138,6 +140,9 @@ public class RoleREST {
RangerRole ret;
try {
+ RangerRoleValidator validator = validatorFactory.getRangerRoleValidator(roleStore);
+ validator.validate(role, RangerValidator.Action.CREATE);
+
String userName = role.getCreatedByUser();
ensureAdminAccess(serviceName, userName);
if (containsInvalidMember(role.getUsers())) {
@@ -176,6 +181,9 @@ public class RoleREST {
}
RangerRole ret;
try {
+ RangerRoleValidator validator = validatorFactory.getRangerRoleValidator(roleStore);
+ validator.validate(role, RangerValidator.Action.UPDATE);
+
ensureAdminAccess(null, null);
if (containsInvalidMember(role.getUsers())) {
throw new Exception("Invalid role user(s)");
@@ -207,6 +215,9 @@ public class RoleREST {
LOG.debug("==> deleteRole(user=" + execUser + " name=" + roleName + ")");
}
try {
+ RangerRoleValidator validator = validatorFactory.getRangerRoleValidator(roleStore);
+ validator.validate(roleName, RangerRoleValidator.Action.DELETE);
+
ensureAdminAccess(serviceName, execUser);
roleStore.deleteRole(roleName);
} catch(WebApplicationException excp) {
@@ -232,6 +243,9 @@ public class RoleREST {
LOG.debug("==> deleteRole(id=" + roleId + ")");
}
try {
+ RangerRoleValidator validator = validatorFactory.getRangerRoleValidator(roleStore);
+ validator.validate(roleId, RangerRoleValidator.Action.DELETE);
+
ensureAdminAccess(null, null);
roleStore.deleteRole(roleId);
} catch(WebApplicationException excp) {