Commit 407ff00c by ashutoshm Committed by Madhan Neethiraj

ATLAS-1408: added validation to prevent creating types with . (dot) in name…

ATLAS-1408: added validation to prevent creating types with . (dot) in name (ashutoshm via mneethiraj) Signed-off-by: 's avatarMadhan Neethiraj <madhan@apache.org>
parent 03857baa
......@@ -51,6 +51,7 @@ public enum AtlasErrorCode {
PATCH_NOT_APPLICABLE_FOR_TYPE(400, "ATLAS40022E", "{0} - invalid patch for type {1}"),
PATCH_FOR_UNKNOWN_TYPE(400, "ATLAS40023E", "{0} - patch references unknown type {1}"),
PATCH_INVALID_DATA(400, "ATLAS40024E", "{0} - patch data is invalid for type {1}"),
TYPE_NAME_INVALID_FORMAT(400, "ATLAS40025E", "{0}: invalid name for {1}. Only alphanumeric and '_' are allowed."),
// All Not found enums go here
TYPE_NAME_NOT_FOUND(404, "ATLAS4041E", "Given typename {0} was invalid"),
......
......@@ -19,6 +19,8 @@ package org.apache.atlas.type;
import com.google.common.collect.ImmutableSet;
import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
import org.apache.atlas.model.typedef.AtlasClassificationDef;
import org.apache.atlas.model.typedef.AtlasEntityDef;
......@@ -40,6 +42,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_ARRAY_PREFIX;
import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_ARRAY_SUFFIX;
......@@ -52,6 +56,9 @@ import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_MAP_SUF
*/
public class AtlasTypeUtil {
private static final Set<String> ATLAS_BUILTIN_TYPENAMES = new HashSet<>();
private static final String NAME_REGEX = "[a-zA-z][a-zA-Z0-9_ ]*";
private static final Pattern NAME_PATTERN = Pattern.compile(NAME_REGEX);
static {
Collections.addAll(ATLAS_BUILTIN_TYPENAMES, AtlasBaseTypeDef.ATLAS_BUILTIN_TYPES);
......@@ -80,6 +87,20 @@ public class AtlasTypeUtil {
}
public static boolean isValidTypeName(String typeName) {
Matcher m = NAME_PATTERN.matcher(typeName);
return m.matches();
}
public static void validateType(AtlasBaseTypeDef typeDef) throws AtlasBaseException {
String typeName = typeDef.getName();
if (!isValidTypeName(typeName)) {
throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_INVALID_FORMAT, typeName, typeDef.getCategory().name());
}
}
public static String getStringValue(Map map, Object key) {
Object ret = map != null ? map.get(key) : null;
......
......@@ -9,6 +9,7 @@ ATLAS-1060 Add composite indexes for exact match performance improvements for al
ATLAS-1127 Modify creation and modification timestamps to Date instead of Long(sumasai)
ALL CHANGES:
ATLAS-1408 added validation to prevent creating types with . (dot) in name (ashutoshm via mneethiraj)
ATLAS-1277 Add feather use 'order by ' in the DSL search (zhangqiang2 via sumasai)
ATLAS-1379 Avoid object query overhead when report query selects class type alias (guptaneeru via dkantor)
ATLAS-1419 update entity-update API impl to preserve value of entity attribute when no value is provided
......
......@@ -30,6 +30,7 @@ import org.apache.atlas.repository.util.FilterUtil;
import org.apache.atlas.type.AtlasClassificationType;
import org.apache.atlas.type.AtlasType;
import org.apache.atlas.type.AtlasTypeRegistry;
import org.apache.atlas.type.AtlasTypeUtil;
import org.apache.atlas.typesystem.types.DataTypes.TypeCategory;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
......@@ -56,6 +57,8 @@ public class AtlasClassificationDefStoreV1 extends AtlasAbstractDefStoreV1 imple
LOG.debug("==> AtlasClassificationDefStoreV1.preCreate({})", classificationDef);
}
AtlasTypeUtil.validateType(classificationDef);
AtlasType type = typeRegistry.getType(classificationDef.getName());
if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.CLASSIFICATION) {
......@@ -174,6 +177,8 @@ public class AtlasClassificationDefStoreV1 extends AtlasAbstractDefStoreV1 imple
LOG.debug("==> AtlasClassificationDefStoreV1.update({})", classifiDef);
}
AtlasTypeUtil.validateType(classifiDef);
AtlasClassificationDef ret = StringUtils.isNotBlank(classifiDef.getGuid())
? updateByGuid(classifiDef.getGuid(), classifiDef) : updateByName(classifiDef.getName(), classifiDef);
......@@ -191,6 +196,8 @@ public class AtlasClassificationDefStoreV1 extends AtlasAbstractDefStoreV1 imple
LOG.debug("==> AtlasClassificationDefStoreV1.updateByName({}, {})", name, classificationDef);
}
AtlasTypeUtil.validateType(classificationDef);
AtlasType type = typeRegistry.getType(classificationDef.getName());
if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.CLASSIFICATION) {
......@@ -221,6 +228,8 @@ public class AtlasClassificationDefStoreV1 extends AtlasAbstractDefStoreV1 imple
LOG.debug("==> AtlasClassificationDefStoreV1.updateByGuid({})", guid);
}
AtlasTypeUtil.validateType(classificationDef);
AtlasType type = typeRegistry.getTypeByGuid(guid);
if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.CLASSIFICATION) {
......
......@@ -29,6 +29,7 @@ import org.apache.atlas.repository.util.FilterUtil;
import org.apache.atlas.type.AtlasEntityType;
import org.apache.atlas.type.AtlasType;
import org.apache.atlas.type.AtlasTypeRegistry;
import org.apache.atlas.type.AtlasTypeUtil;
import org.apache.atlas.typesystem.types.DataTypes.TypeCategory;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
......@@ -55,6 +56,8 @@ public class AtlasEntityDefStoreV1 extends AtlasAbstractDefStoreV1 implements At
LOG.debug("==> AtlasEntityDefStoreV1.preCreate({})", entityDef);
}
AtlasTypeUtil.validateType(entityDef);
AtlasType type = typeRegistry.getType(entityDef.getName());
if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.ENTITY) {
......@@ -173,6 +176,8 @@ public class AtlasEntityDefStoreV1 extends AtlasAbstractDefStoreV1 implements At
LOG.debug("==> AtlasEntityDefStoreV1.update({})", entityDef);
}
AtlasTypeUtil.validateType(entityDef);
AtlasEntityDef ret = StringUtils.isNotBlank(entityDef.getGuid()) ? updateByGuid(entityDef.getGuid(), entityDef)
: updateByName(entityDef.getName(), entityDef);
......@@ -189,6 +194,8 @@ public class AtlasEntityDefStoreV1 extends AtlasAbstractDefStoreV1 implements At
LOG.debug("==> AtlasEntityDefStoreV1.updateByName({}, {})", name, entityDef);
}
AtlasTypeUtil.validateType(entityDef);
AtlasType type = typeRegistry.getType(entityDef.getName());
if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.ENTITY) {
......@@ -219,6 +226,8 @@ public class AtlasEntityDefStoreV1 extends AtlasAbstractDefStoreV1 implements At
LOG.debug("==> AtlasEntityDefStoreV1.updateByGuid({})", guid);
}
AtlasTypeUtil.validateType(entityDef);
AtlasType type = typeRegistry.getTypeByGuid(guid);
if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.ENTITY) {
......
......@@ -28,6 +28,7 @@ import org.apache.atlas.repository.graphdb.AtlasVertex;
import org.apache.atlas.repository.store.graph.AtlasEnumDefStore;
import org.apache.atlas.repository.util.FilterUtil;
import org.apache.atlas.type.AtlasTypeRegistry;
import org.apache.atlas.type.AtlasTypeUtil;
import org.apache.atlas.typesystem.types.DataTypes.TypeCategory;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
......@@ -54,6 +55,8 @@ public class AtlasEnumDefStoreV1 extends AtlasAbstractDefStoreV1 implements Atla
LOG.debug("==> AtlasEnumDefStoreV1.create({})", enumDef);
}
AtlasTypeUtil.validateType(enumDef);
AtlasVertex vertex = typeDefStore.findTypeVertexByName(enumDef.getName());
if (vertex != null) {
......@@ -143,6 +146,8 @@ public class AtlasEnumDefStoreV1 extends AtlasAbstractDefStoreV1 implements Atla
LOG.debug("==> AtlasEnumDefStoreV1.update({})", enumDef);
}
AtlasTypeUtil.validateType(enumDef);
AtlasEnumDef ret = StringUtils.isNotBlank(enumDef.getGuid()) ? updateByGuid(enumDef.getGuid(), enumDef)
: updateByName(enumDef.getName(), enumDef);
......@@ -159,6 +164,8 @@ public class AtlasEnumDefStoreV1 extends AtlasAbstractDefStoreV1 implements Atla
LOG.debug("==> AtlasEnumDefStoreV1.updateByName({}, {})", name, enumDef);
}
AtlasTypeUtil.validateType(enumDef);
AtlasVertex vertex = typeDefStore.findTypeVertexByNameAndCategory(name, TypeCategory.ENUM);
if (vertex == null) {
......@@ -184,6 +191,8 @@ public class AtlasEnumDefStoreV1 extends AtlasAbstractDefStoreV1 implements Atla
LOG.debug("==> AtlasEnumDefStoreV1.updateByGuid({})", guid);
}
AtlasTypeUtil.validateType(enumDef);
AtlasVertex vertex = typeDefStore.findTypeVertexByGuidAndCategory(guid, TypeCategory.ENUM);
if (vertex == null) {
......
......@@ -67,6 +67,8 @@ public class AtlasStructDefStoreV1 extends AtlasAbstractDefStoreV1 implements At
LOG.debug("==> AtlasStructDefStoreV1.preCreate({})", structDef);
}
AtlasTypeUtil.validateType(structDef);
AtlasType type = typeRegistry.getType(structDef.getName());
if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.STRUCT) {
......@@ -184,6 +186,8 @@ public class AtlasStructDefStoreV1 extends AtlasAbstractDefStoreV1 implements At
LOG.debug("==> AtlasStructDefStoreV1.update({})", structDef);
}
AtlasTypeUtil.validateType(structDef);
AtlasStructDef ret = StringUtils.isNotBlank(structDef.getGuid()) ? updateByGuid(structDef.getGuid(), structDef)
: updateByName(structDef.getName(), structDef);
......@@ -200,6 +204,8 @@ public class AtlasStructDefStoreV1 extends AtlasAbstractDefStoreV1 implements At
LOG.debug("==> AtlasStructDefStoreV1.updateByName({}, {})", name, structDef);
}
AtlasTypeUtil.validateType(structDef);
AtlasType type = typeRegistry.getType(structDef.getName());
if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.STRUCT) {
......@@ -230,6 +236,8 @@ public class AtlasStructDefStoreV1 extends AtlasAbstractDefStoreV1 implements At
LOG.debug("==> AtlasStructDefStoreV1.updateByGuid({})", guid);
}
AtlasTypeUtil.validateType(structDef);
AtlasType type = typeRegistry.getTypeByGuid(guid);
if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.STRUCT) {
......
......@@ -40,6 +40,7 @@ import org.apache.atlas.repository.RepositoryException;
import org.apache.atlas.repository.audit.EntityAuditRepository;
import org.apache.atlas.repository.graph.GraphHelper;
import org.apache.atlas.repository.typestore.ITypeStore;
import org.apache.atlas.type.AtlasTypeUtil;
import org.apache.atlas.typesystem.IStruct;
import org.apache.atlas.typesystem.ITypedReferenceableInstance;
import org.apache.atlas.typesystem.ITypedStruct;
......@@ -55,8 +56,11 @@ import org.apache.atlas.typesystem.persistence.ReferenceableInstance;
import org.apache.atlas.typesystem.types.AttributeInfo;
import org.apache.atlas.typesystem.types.ClassType;
import org.apache.atlas.typesystem.types.DataTypes;
import org.apache.atlas.typesystem.types.EnumTypeDefinition;
import org.apache.atlas.typesystem.types.HierarchicalTypeDefinition;
import org.apache.atlas.typesystem.types.IDataType;
import org.apache.atlas.typesystem.types.Multiplicity;
import org.apache.atlas.typesystem.types.StructTypeDefinition;
import org.apache.atlas.typesystem.types.TraitType;
import org.apache.atlas.typesystem.types.TypeSystem;
import org.apache.atlas.typesystem.types.cache.TypeCache;
......@@ -213,14 +217,36 @@ public class DefaultMetadataService implements MetadataService, ActiveStateChang
return createOrUpdateTypes(typeDefinition, true);
}
private TypesDef validateTypeDefinition(String typeDefinition) {
private TypesDef validateTypeDefinition(String typeDefinition) throws AtlasException {
try {
TypesDef typesDef = TypesSerialization.fromJson(typeDefinition);
if (typesDef.isEmpty()) {
throw new IllegalArgumentException("Invalid type definition");
}
for (HierarchicalTypeDefinition<ClassType> t : typesDef.classTypesAsJavaList()) {
if (!AtlasTypeUtil.isValidTypeName(t.typeName))
throw new AtlasException("Only characters, numbers and '_' are allowed in class names. " + t.toString());
}
for (StructTypeDefinition t : typesDef.structTypesAsJavaList()) {
if (!AtlasTypeUtil.isValidTypeName(t.typeName))
throw new AtlasException("Only characters, numbers and '_' are allowed in struct names. " + t.toString());
}
for (EnumTypeDefinition t : typesDef.enumTypesAsJavaList()) {
if (!AtlasTypeUtil.isValidTypeName(t.name))
throw new AtlasException("Only characters, numbers and '_' are allowed in enum names. " + t.toString());
}
for (HierarchicalTypeDefinition<TraitType> t : typesDef.traitTypesAsJavaList()) {
if (!AtlasTypeUtil.isValidTypeName(t.typeName))
throw new AtlasException("Only characters, numbers and '_' are allowed in trait names. " + t.toString());
}
return typesDef;
} catch (Exception e) {
}
catch (Exception e) {
LOG.error("Unable to deserialize json={}", typeDefinition, e);
throw new IllegalArgumentException("Unable to deserialize json " + typeDefinition, e);
}
......
......@@ -202,7 +202,7 @@ public class DefaultMetadataServiceTest {
String arrayAttrName = randomStrWithReservedChars();
String mapAttrName = randomStrWithReservedChars();
HierarchicalTypeDefinition<ClassType> typeDefinition =
createClassTypeDef(randomStrWithReservedChars(), ImmutableSet.<String>of(),
createClassTypeDef("test_type_"+ RandomStringUtils.randomAlphanumeric(10), ImmutableSet.<String>of(),
createOptionalAttrDef(strAttrName, DataTypes.STRING_TYPE),
new AttributeDefinition(arrayAttrName, DataTypes.arrayTypeName(DataTypes.STRING_TYPE.getName()),
Multiplicity.OPTIONAL, false, null),
......@@ -1145,6 +1145,22 @@ public class DefaultMetadataServiceTest {
}
@Test
public void testTypeWithDotsCreationShouldNotBeCreated() throws AtlasException, JSONException {
String typeName = "test_.v1_type_"+ RandomStringUtils.randomAlphanumeric(10);
HierarchicalTypeDefinition<ClassType> typeDef = TypesUtil.createClassTypeDef(
typeName, ImmutableSet.<String>of(),
TypesUtil.createUniqueRequiredAttrDef("test_type_attribute", DataTypes.STRING_TYPE));
TypesDef typesDef = new TypesDef(typeDef, false);
try {
metadataService.createType(TypesSerialization.toJson(typesDef));
fail("Expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
//expected
}
}
@Test
public void testAuditEventsInvalidParams() throws Exception {
//entity id can't be null
try {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment