mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-09-25 08:50:18 +00:00
Integrate DefaultAuthorizer with PolicyEvaluator (#2017)
This commit is contained in:
parent
ed797dc335
commit
321a0e811b
@ -27,7 +27,9 @@ import io.dropwizard.setup.Bootstrap;
|
||||
import io.dropwizard.setup.Environment;
|
||||
import io.federecio.dropwizard.swagger.SwaggerBundle;
|
||||
import io.federecio.dropwizard.swagger.SwaggerBundleConfiguration;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import javax.ws.rs.container.ContainerRequestFilter;
|
||||
import javax.ws.rs.container.ContainerResponseFilter;
|
||||
import javax.ws.rs.core.Response;
|
||||
@ -37,6 +39,8 @@ import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
|
||||
import org.glassfish.jersey.media.multipart.MultiPartFeature;
|
||||
import org.glassfish.jersey.server.ServerProperties;
|
||||
import org.jdbi.v3.core.Jdbi;
|
||||
import org.jdbi.v3.core.statement.SqlLogger;
|
||||
import org.jdbi.v3.core.statement.StatementContext;
|
||||
import org.openmetadata.catalog.events.EventFilter;
|
||||
import org.openmetadata.catalog.events.EventPubSub;
|
||||
import org.openmetadata.catalog.exception.CatalogGenericExceptionMapper;
|
||||
@ -62,19 +66,25 @@ public class CatalogApplication extends Application<CatalogApplicationConfig> {
|
||||
@Override
|
||||
public void run(CatalogApplicationConfig catalogConfig, Environment environment)
|
||||
throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException,
|
||||
InvocationTargetException {
|
||||
InvocationTargetException, IOException {
|
||||
|
||||
final JdbiFactory factory = new JdbiFactory();
|
||||
final Jdbi jdbi = factory.build(environment, catalogConfig.getDataSourceFactory(), "mysql3");
|
||||
|
||||
// SqlLogger sqlLogger = new SqlLogger() {
|
||||
// @Override
|
||||
// public void logAfterExecution(StatementContext context) {
|
||||
// LOG.info("sql {}, parameters {}, timeTaken {} ms", context.getRenderedSql(),
|
||||
// context.getBinding().toString(), context.getElapsedTime(ChronoUnit.MILLIS));
|
||||
// }
|
||||
// };
|
||||
// jdbi.setSqlLogger(sqlLogger);
|
||||
SqlLogger sqlLogger =
|
||||
new SqlLogger() {
|
||||
@Override
|
||||
public void logAfterExecution(StatementContext context) {
|
||||
LOG.debug(
|
||||
"sql {}, parameters {}, timeTaken {} ms",
|
||||
context.getRenderedSql(),
|
||||
context.getBinding(),
|
||||
context.getElapsedTime(ChronoUnit.MILLIS));
|
||||
}
|
||||
};
|
||||
if (LOG.isDebugEnabled()) {
|
||||
jdbi.setSqlLogger(sqlLogger);
|
||||
}
|
||||
|
||||
// Register Authorizer
|
||||
registerAuthorizer(catalogConfig, environment, jdbi);
|
||||
@ -128,7 +138,7 @@ public class CatalogApplication extends Application<CatalogApplicationConfig> {
|
||||
|
||||
private void registerAuthorizer(CatalogApplicationConfig catalogConfig, Environment environment, Jdbi jdbi)
|
||||
throws NoSuchMethodException, ClassNotFoundException, IllegalAccessException, InvocationTargetException,
|
||||
InstantiationException {
|
||||
InstantiationException, IOException {
|
||||
AuthorizerConfiguration authorizerConf = catalogConfig.getAuthorizerConfiguration();
|
||||
AuthenticationConfiguration authenticationConfiguration = catalogConfig.getAuthenticationConfiguration();
|
||||
if (authorizerConf != null) {
|
||||
|
@ -15,6 +15,7 @@ package org.openmetadata.catalog;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.text.ParseException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@ -24,13 +25,17 @@ import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import lombok.NonNull;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.openmetadata.catalog.exception.CatalogExceptionMessage;
|
||||
import org.openmetadata.catalog.exception.EntityNotFoundException;
|
||||
import org.openmetadata.catalog.jdbi3.EntityDAO;
|
||||
import org.openmetadata.catalog.jdbi3.EntityRepository;
|
||||
import org.openmetadata.catalog.type.EntityReference;
|
||||
import org.openmetadata.catalog.util.EntityInterface;
|
||||
import org.openmetadata.catalog.util.EntityUtil;
|
||||
|
||||
@Slf4j
|
||||
public final class Entity {
|
||||
private static final Map<String, EntityDAO<?>> DAO_MAP = new HashMap<>();
|
||||
private static final Map<String, EntityRepository<?>> ENTITY_REPOSITORY_MAP = new HashMap<>();
|
||||
@ -86,7 +91,7 @@ public final class Entity {
|
||||
DAO_MAP.put(entity, dao);
|
||||
ENTITY_REPOSITORY_MAP.put(entity, entityRepository);
|
||||
CANONICAL_ENTITY_NAME_MAP.put(entity.toLowerCase(Locale.ROOT), entity);
|
||||
System.out.println("Registering entity " + entity);
|
||||
log.info("Registering entity {}", entity);
|
||||
}
|
||||
|
||||
public static EntityReference getEntityReference(String entity, UUID id) throws IOException {
|
||||
@ -138,12 +143,45 @@ public final class Entity {
|
||||
return null;
|
||||
}
|
||||
String entityName = getEntityNameFromObject(entity);
|
||||
EntityRepository<T> entityRepository = getEntityRepository(entityName);
|
||||
return entityRepository.getEntityInterface(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the entity using id from given entity reference and fields
|
||||
*
|
||||
* @return entity object eg: {@link org.openmetadata.catalog.entity.data.Table}, {@link
|
||||
* org.openmetadata.catalog.entity.data.Topic}, etc
|
||||
*/
|
||||
public static <T> T getEntity(EntityReference entityReference, EntityUtil.Fields fields)
|
||||
throws IOException, ParseException {
|
||||
if (entityReference == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
EntityRepository<?> entityRepository = Entity.getEntityRepository(entityReference.getType());
|
||||
@SuppressWarnings("unchecked")
|
||||
T entity = (T) entityRepository.get(null, entityReference.getId().toString(), fields);
|
||||
if (entity == null) {
|
||||
throw EntityNotFoundException.byMessage(
|
||||
CatalogExceptionMessage.entityNotFound(entityReference.getType(), entityReference.getId()));
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the corresponding entity repository for a given entity name.
|
||||
*
|
||||
* @param entityName type of entity, eg: {@link Entity#TABLE}, {@link Entity#TOPIC}, etc
|
||||
* @return entity repository corresponding to the entity name
|
||||
*/
|
||||
public static <T> EntityRepository<T> getEntityRepository(@NonNull String entityName) {
|
||||
@SuppressWarnings("unchecked")
|
||||
EntityRepository<T> entityRepository = (EntityRepository<T>) ENTITY_REPOSITORY_MAP.get(entityName);
|
||||
if (entityRepository == null) {
|
||||
throw EntityNotFoundException.byMessage(CatalogExceptionMessage.entityTypeNotFound(entityName));
|
||||
}
|
||||
return entityRepository.getEntityInterface(entity);
|
||||
return entityRepository;
|
||||
}
|
||||
|
||||
public static void deleteEntity(String entity, UUID entityId, boolean recursive) throws IOException {
|
||||
|
@ -15,6 +15,7 @@ package org.openmetadata.catalog.jdbi3;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
@ -24,6 +25,7 @@ import org.openmetadata.catalog.Entity;
|
||||
import org.openmetadata.catalog.entity.data.Location;
|
||||
import org.openmetadata.catalog.entity.policies.Policy;
|
||||
import org.openmetadata.catalog.entity.policies.accessControl.Rule;
|
||||
import org.openmetadata.catalog.exception.CatalogExceptionMessage;
|
||||
import org.openmetadata.catalog.resources.policies.PolicyResource;
|
||||
import org.openmetadata.catalog.type.ChangeDescription;
|
||||
import org.openmetadata.catalog.type.EntityReference;
|
||||
@ -184,6 +186,33 @@ public class PolicyRepository extends EntityRepository<Policy> {
|
||||
// No validation errors, if execution reaches here.
|
||||
}
|
||||
|
||||
private List<Policy> getAccessControlPolicies() throws IOException {
|
||||
EntityUtil.Fields fields = new EntityUtil.Fields(List.of("policyType", "rules"));
|
||||
List<String> jsons = daoCollection.policyDAO().listAfter(null, Integer.MAX_VALUE, "");
|
||||
List<Policy> policies = new ArrayList<>(jsons.size());
|
||||
for (String json : jsons) {
|
||||
Policy policy = setFields(JsonUtils.readValue(json, Policy.class), fields);
|
||||
if (policy.getPolicyType() != PolicyType.AccessControl) {
|
||||
continue;
|
||||
}
|
||||
policies.add(policy);
|
||||
}
|
||||
return policies;
|
||||
}
|
||||
|
||||
public List<Rule> getAccessControlPolicyRules() throws IOException {
|
||||
List<Policy> policies = getAccessControlPolicies();
|
||||
List<Rule> rules = new ArrayList<>();
|
||||
for (Policy policy : policies) {
|
||||
List<Object> ruleObjects = policy.getRules();
|
||||
for (Object ruleObject : ruleObjects) {
|
||||
Rule rule = JsonUtils.readValue(JsonUtils.getJsonStructure(ruleObject).toString(), Rule.class);
|
||||
rules.add(rule);
|
||||
}
|
||||
}
|
||||
return rules;
|
||||
}
|
||||
|
||||
private void setLocation(Policy policy, EntityReference location) {
|
||||
if (location == null || location.getId() == null) {
|
||||
return;
|
||||
@ -334,6 +363,10 @@ public class PolicyRepository extends EntityRepository<Policy> {
|
||||
|
||||
@Override
|
||||
public void entitySpecificUpdate() throws IOException {
|
||||
// Disallow changing policyType.
|
||||
if (original.getEntity().getPolicyType() != updated.getEntity().getPolicyType()) {
|
||||
throw new IllegalArgumentException(CatalogExceptionMessage.readOnlyAttribute(Entity.POLICY, "policyType"));
|
||||
}
|
||||
recordChange("policyUrl", original.getEntity().getPolicyUrl(), updated.getEntity().getPolicyUrl());
|
||||
recordChange("enabled", original.getEntity().getEnabled(), updated.getEntity().getEnabled());
|
||||
recordChange("rules", original.getEntity().getRules(), updated.getEntity().getRules());
|
||||
|
@ -13,13 +13,15 @@
|
||||
|
||||
package org.openmetadata.catalog.security;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.jdbi.v3.core.Jdbi;
|
||||
import org.openmetadata.catalog.type.EntityReference;
|
||||
import org.openmetadata.catalog.type.MetadataOperation;
|
||||
|
||||
public interface Authorizer {
|
||||
|
||||
/** Initialize the authorizer */
|
||||
void init(AuthorizerConfiguration config, Jdbi jdbi);
|
||||
void init(AuthorizerConfiguration config, Jdbi jdbi) throws IOException;
|
||||
|
||||
/**
|
||||
* Check if the authenticated user has given permission on the target entity identified by the given resourceType and
|
||||
@ -27,6 +29,12 @@ public interface Authorizer {
|
||||
*/
|
||||
boolean hasPermissions(AuthenticationContext ctx, EntityReference entityReference);
|
||||
|
||||
/**
|
||||
* Check if the authenticated user (subject) has permission to perform the {@link MetadataOperation} on the target
|
||||
* entity (object).
|
||||
*/
|
||||
boolean hasPermissions(AuthenticationContext ctx, EntityReference entityReference, MetadataOperation operation);
|
||||
|
||||
boolean isAdmin(AuthenticationContext ctx);
|
||||
|
||||
boolean isBot(AuthenticationContext ctx);
|
||||
|
@ -19,6 +19,7 @@ import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
@ -28,8 +29,11 @@ import org.openmetadata.catalog.entity.teams.User;
|
||||
import org.openmetadata.catalog.exception.DuplicateEntityException;
|
||||
import org.openmetadata.catalog.exception.EntityNotFoundException;
|
||||
import org.openmetadata.catalog.jdbi3.CollectionDAO;
|
||||
import org.openmetadata.catalog.jdbi3.PolicyRepository;
|
||||
import org.openmetadata.catalog.jdbi3.UserRepository;
|
||||
import org.openmetadata.catalog.security.policyevaluator.PolicyEvaluator;
|
||||
import org.openmetadata.catalog.type.EntityReference;
|
||||
import org.openmetadata.catalog.type.MetadataOperation;
|
||||
import org.openmetadata.catalog.util.EntityUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -42,19 +46,22 @@ public class DefaultAuthorizer implements Authorizer {
|
||||
|
||||
private String principalDomain;
|
||||
private UserRepository userRepository;
|
||||
private static final String fieldsParam = "teams";
|
||||
private PolicyEvaluator policyEvaluator;
|
||||
private static final String fieldsParam = "roles,teams";
|
||||
|
||||
@Override
|
||||
public void init(AuthorizerConfiguration config, Jdbi dbi) {
|
||||
public void init(AuthorizerConfiguration config, Jdbi dbi) throws IOException {
|
||||
LOG.debug("Initializing DefaultAuthorizer with config {}", config);
|
||||
this.adminUsers = new HashSet<>(config.getAdminPrincipals());
|
||||
this.botUsers = new HashSet<>(config.getBotPrincipals());
|
||||
this.principalDomain = config.getPrincipalDomain();
|
||||
LOG.debug("Admin users: {}", adminUsers);
|
||||
CollectionDAO repo = dbi.onDemand(CollectionDAO.class);
|
||||
this.userRepository = new UserRepository(repo);
|
||||
CollectionDAO collectionDAO = dbi.onDemand(CollectionDAO.class);
|
||||
this.userRepository = new UserRepository(collectionDAO);
|
||||
mayBeAddAdminUsers();
|
||||
mayBeAddBotUsers();
|
||||
// Load all rules from access control policies at once during init.
|
||||
this.policyEvaluator = new PolicyEvaluator(new PolicyRepository(collectionDAO).getAccessControlPolicyRules());
|
||||
}
|
||||
|
||||
private void mayBeAddAdminUsers() {
|
||||
@ -104,10 +111,8 @@ public class DefaultAuthorizer implements Authorizer {
|
||||
if (owner == null) {
|
||||
return true;
|
||||
}
|
||||
String userName = SecurityUtil.getUserName(ctx);
|
||||
EntityUtil.Fields fields = new EntityUtil.Fields(FIELD_LIST, fieldsParam);
|
||||
try {
|
||||
User user = userRepository.getByName(null, userName, fields);
|
||||
User user = getUserFromAuthenticationContext(ctx);
|
||||
if (owner.getType().equals(Entity.TEAM)) {
|
||||
for (EntityReference team : user.getTeams()) {
|
||||
if (team.getName().equals(owner.getName())) {
|
||||
@ -123,6 +128,20 @@ public class DefaultAuthorizer implements Authorizer {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermissions(
|
||||
AuthenticationContext ctx, EntityReference entityReference, MetadataOperation operation) {
|
||||
validateAuthenticationContext(ctx);
|
||||
try {
|
||||
return policyEvaluator.hasPermission(
|
||||
getUserFromAuthenticationContext(ctx),
|
||||
Entity.getEntity(entityReference, new EntityUtil.Fields(List.of("tags"))),
|
||||
operation);
|
||||
} catch (IOException | EntityNotFoundException | ParseException ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdmin(AuthenticationContext ctx) {
|
||||
validateAuthenticationContext(ctx);
|
||||
@ -161,6 +180,12 @@ public class DefaultAuthorizer implements Authorizer {
|
||||
}
|
||||
}
|
||||
|
||||
private User getUserFromAuthenticationContext(AuthenticationContext ctx) throws IOException, ParseException {
|
||||
String userName = SecurityUtil.getUserName(ctx);
|
||||
EntityUtil.Fields fields = new EntityUtil.Fields(FIELD_LIST, fieldsParam);
|
||||
return userRepository.getByName(null, userName, fields);
|
||||
}
|
||||
|
||||
private void addAdmin(String name) {
|
||||
User user =
|
||||
new User()
|
||||
|
@ -15,6 +15,7 @@ package org.openmetadata.catalog.security;
|
||||
|
||||
import org.jdbi.v3.core.Jdbi;
|
||||
import org.openmetadata.catalog.type.EntityReference;
|
||||
import org.openmetadata.catalog.type.MetadataOperation;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -31,6 +32,12 @@ public class NoopAuthorizer implements Authorizer {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermissions(
|
||||
AuthenticationContext ctx, EntityReference entityReference, MetadataOperation operation) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdmin(AuthenticationContext ctx) {
|
||||
return true;
|
||||
|
@ -20,6 +20,7 @@ import javax.ws.rs.client.Invocation;
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import javax.ws.rs.core.SecurityContext;
|
||||
import org.openmetadata.catalog.type.EntityReference;
|
||||
import org.openmetadata.catalog.type.MetadataOperation;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -55,6 +56,20 @@ public final class SecurityUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkAdminRoleOrPermissions(
|
||||
Authorizer authorizer,
|
||||
SecurityContext securityContext,
|
||||
EntityReference entityReference,
|
||||
MetadataOperation metadataOperation) {
|
||||
Principal principal = securityContext.getUserPrincipal();
|
||||
AuthenticationContext authenticationCtx = SecurityUtil.getAuthenticationContext(principal);
|
||||
if (!authorizer.isAdmin(authenticationCtx)
|
||||
&& !authorizer.isBot(authenticationCtx)
|
||||
&& !authorizer.hasPermissions(authenticationCtx, entityReference, metadataOperation)) {
|
||||
throw new AuthorizationException("Principal: " + principal + " does not have permissions");
|
||||
}
|
||||
}
|
||||
|
||||
public static String getUserName(String principalName) {
|
||||
return principalName == null ? null : principalName.split("[/@]")[0];
|
||||
}
|
||||
|
@ -1,25 +1,27 @@
|
||||
package org.openmetadata.catalog.security.policyevaluator;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.Builder;
|
||||
import lombok.NonNull;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeasy.rules.api.Facts;
|
||||
import org.openmetadata.catalog.Entity;
|
||||
import org.openmetadata.catalog.entity.teams.User;
|
||||
import org.openmetadata.catalog.exception.EntityNotFoundException;
|
||||
import org.openmetadata.catalog.type.EntityReference;
|
||||
import org.openmetadata.catalog.type.MetadataOperation;
|
||||
import org.openmetadata.catalog.type.TagLabel;
|
||||
import org.openmetadata.catalog.util.EntityInterface;
|
||||
|
||||
@Slf4j
|
||||
@Builder(setterPrefix = "with")
|
||||
class AttributeBasedFacts {
|
||||
|
||||
private User user;
|
||||
private Object entity;
|
||||
private MetadataOperation operation;
|
||||
@NonNull private User user;
|
||||
@NonNull private Object entity;
|
||||
@NonNull private MetadataOperation operation;
|
||||
|
||||
// Do not allow anything external or the builder itself change the value of facts.
|
||||
// Individual Fact(s) within facts may be changed by the RulesEngine.
|
||||
@ -29,10 +31,7 @@ class AttributeBasedFacts {
|
||||
* Creates {@link Facts} with the operation, user (subject) and entity (object) attributes so that it is recognizable
|
||||
* by {@link org.jeasy.rules.api.RulesEngine}
|
||||
*/
|
||||
public Facts getFacts() throws RuntimeException {
|
||||
if (!validate()) {
|
||||
throw new RuntimeException("Validation failed while building facts");
|
||||
}
|
||||
public Facts getFacts() {
|
||||
facts.put(CommonFields.USER_ROLES, getUserRoles(user));
|
||||
facts.put(CommonFields.ENTITY_TAGS, getEntityTags(entity));
|
||||
facts.put(CommonFields.ENTITY_TYPE, getEntityType(entity));
|
||||
@ -46,35 +45,29 @@ class AttributeBasedFacts {
|
||||
return facts.get(CommonFields.ALLOW);
|
||||
}
|
||||
|
||||
private List<String> getUserRoles(User user) {
|
||||
// TODO: Fix this to fetch user's roles when roles is added as entity reference list from user schema.
|
||||
return user.getTeams().stream().map(EntityReference::getName).collect(Collectors.toList());
|
||||
private List<String> getUserRoles(@NonNull User user) {
|
||||
return user.getRoles().stream().map(EntityReference::getName).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<String> getEntityTags(Object entity) {
|
||||
// TODO: Fix the entityType fetch such that it is fetched from Repository or using a Util.
|
||||
// This is done here now to facilitate prototyping and unit testing.
|
||||
List<TagLabel> entityTags = Collections.emptyList();
|
||||
private List<String> getEntityTags(@NonNull Object entity) {
|
||||
List<TagLabel> entityTags = null;
|
||||
try {
|
||||
entityTags = (List<TagLabel>) entity.getClass().getMethod("getTags").invoke(entity);
|
||||
} catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
|
||||
log.warn("Could not obtain tags for entity with class {}", entity.getClass());
|
||||
EntityInterface<?> entityInterface = Entity.getEntityInterface(entity);
|
||||
entityTags = entityInterface.getTags();
|
||||
} catch (EntityNotFoundException e) {
|
||||
log.warn("could not obtain tags for the given entity {} - exception: {}", entity, e.toString());
|
||||
}
|
||||
if (entityTags == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return entityTags.stream().map(TagLabel::getTagFQN).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static String getEntityType(Object object) {
|
||||
// TODO: Fix the entityType fetch such that it is fetched from Repository or using a Util.
|
||||
// This is done here now to facilitate prototyping and unit testing.
|
||||
return object.getClass().getSimpleName().toLowerCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
private boolean validate() {
|
||||
log.debug(
|
||||
"Validating attribute based facts - user: {}, entity: {}, operation: {}",
|
||||
this.user,
|
||||
this.entity,
|
||||
this.operation);
|
||||
return this.user != null && this.entity != null && this.operation != null;
|
||||
private static String getEntityType(@NonNull Object entity) {
|
||||
String entityType = Entity.getEntityNameFromObject(entity);
|
||||
if (entityType == null) {
|
||||
log.warn("could not find entity type for the given entity {}", entity);
|
||||
}
|
||||
return entityType;
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import java.util.function.BiPredicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.joda.time.Period;
|
||||
import org.joda.time.format.ISOPeriodFormat;
|
||||
import org.openmetadata.catalog.Entity;
|
||||
@ -391,6 +392,7 @@ public final class EntityUtil {
|
||||
return followers;
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public static class Fields {
|
||||
public static final Fields EMPTY_FIELDS = new Fields(null, null);
|
||||
private final List<String> fieldList;
|
||||
|
Loading…
x
Reference in New Issue
Block a user