Fixes #3691 - Move common functionality to EntityResource (#3692)

* Simplify ListAfter code for reducing code verbosity

* Move allowed fields functionality to EntityResource and reduce number of fields requested for authorization
This commit is contained in:
Suresh Srinivas 2022-03-26 17:18:21 -07:00 committed by GitHub
parent 6dbb1e578d
commit 3fe7b0cd76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
58 changed files with 201 additions and 321 deletions

View File

@ -13,8 +13,6 @@
package org.openmetadata.catalog;
import static org.openmetadata.catalog.resources.teams.UserResource.ALLOWED_FIELDS;
import com.codahale.metrics.health.HealthCheck;
import java.io.IOException;
import lombok.extern.slf4j.Slf4j;
@ -22,12 +20,11 @@ import org.jdbi.v3.core.Jdbi;
import org.openmetadata.catalog.jdbi3.CollectionDAO;
import org.openmetadata.catalog.jdbi3.ListFilter;
import org.openmetadata.catalog.jdbi3.UserRepository;
import org.openmetadata.catalog.util.EntityUtil;
import org.openmetadata.catalog.util.EntityUtil.Fields;
@Slf4j
public class CatalogHealthCheck extends HealthCheck {
private final UserRepository userRepository;
private final EntityUtil.Fields fields = new EntityUtil.Fields(ALLOWED_FIELDS, "profile");
public CatalogHealthCheck(Jdbi jdbi) {
super();
@ -39,7 +36,7 @@ public class CatalogHealthCheck extends HealthCheck {
protected Result check() throws Exception {
try {
ListFilter filter = new ListFilter();
userRepository.listAfter(null, fields, filter, 1, null);
userRepository.listAfter(null, Fields.EMPTY_FIELDS, filter, 1, null);
return Result.healthy();
} catch (IOException e) {
LOG.error("Health check error {}", e.getMessage());

View File

@ -216,21 +216,11 @@ public final class Entity {
return entityRepository.getEntityInterface(entity);
}
public static <T> T getEntity(EntityReference ref, EntityUtil.Fields fields) throws IOException, ParseException {
return getEntity(ref, fields, Include.NON_DELETED);
}
public static <T> T getEntity(EntityReference ref, EntityUtil.Fields fields, Include include)
throws IOException, ParseException {
return getEntity(ref.getType(), ref.getId(), fields, include);
}
/** Retrieve the entity using id from given entity reference and fields */
public static <T> T getEntity(String entityType, UUID id, EntityUtil.Fields fields)
throws IOException, ParseException {
return getEntity(entityType, id, fields, Include.NON_DELETED);
}
/** Retrieve the entity using id from given entity reference and fields */
public static <T> T getEntity(String entityType, UUID id, EntityUtil.Fields fields, Include include)
throws IOException, ParseException {

View File

@ -31,10 +31,8 @@ import org.openmetadata.catalog.util.EntityUtil;
import org.openmetadata.catalog.util.EntityUtil.Fields;
public class AirflowPipelineRepository extends EntityRepository<AirflowPipeline> {
private static final Fields AIRFLOW_PIPELINE_UPDATE_FIELDS =
new Fields(AirflowPipelineResource.ALLOWED_FIELDS, FIELD_OWNER);
private static final Fields AIRFLOW_PIPELINE_PATCH_FIELDS =
new Fields(AirflowPipelineResource.ALLOWED_FIELDS, FIELD_OWNER);
private static final String AIRFLOW_PIPELINE_UPDATE_FIELDS = FIELD_OWNER;
private static final String AIRFLOW_PIPELINE_PATCH_FIELDS = FIELD_OWNER;
public AirflowPipelineRepository(CollectionDAO dao) {
super(

View File

@ -26,14 +26,7 @@ import org.openmetadata.catalog.util.EntityUtil.Fields;
public class BotsRepository extends EntityRepository<Bots> {
public BotsRepository(CollectionDAO dao) {
super(
BotsResource.COLLECTION_PATH,
Entity.BOTS,
Bots.class,
dao.botsDAO(),
dao,
Fields.EMPTY_FIELDS,
Fields.EMPTY_FIELDS);
super(BotsResource.COLLECTION_PATH, Entity.BOTS, Bots.class, dao.botsDAO(), dao, "", "");
}
@Override

View File

@ -38,8 +38,8 @@ import org.openmetadata.catalog.util.EntityUtil.Fields;
@Slf4j
public class ChartRepository extends EntityRepository<Chart> {
private static final Fields CHART_UPDATE_FIELDS = new Fields(ChartResource.ALLOWED_FIELDS, "owner");
private static final Fields CHART_PATCH_FIELDS = new Fields(ChartResource.ALLOWED_FIELDS, "owner,tags");
private static final String CHART_UPDATE_FIELDS = "owner";
private static final String CHART_PATCH_FIELDS = "owner,tags";
public ChartRepository(CollectionDAO dao) {
super(

View File

@ -39,10 +39,8 @@ import org.openmetadata.catalog.util.EntityUtil;
import org.openmetadata.catalog.util.EntityUtil.Fields;
public class DashboardRepository extends EntityRepository<Dashboard> {
private static final Fields DASHBOARD_UPDATE_FIELDS =
new Fields(DashboardResource.ALLOWED_FIELDS, "owner,tags,charts");
private static final Fields DASHBOARD_PATCH_FIELDS =
new Fields(DashboardResource.ALLOWED_FIELDS, "owner,tags,charts");
private static final String DASHBOARD_UPDATE_FIELDS = "owner,tags,charts";
private static final String DASHBOARD_PATCH_FIELDS = "owner,tags,charts";
public DashboardRepository(CollectionDAO dao) {
super(

View File

@ -31,7 +31,7 @@ import org.openmetadata.catalog.util.EntityUtil;
import org.openmetadata.catalog.util.EntityUtil.Fields;
public class DashboardServiceRepository extends EntityRepository<DashboardService> {
private static final Fields UPDATE_FIELDS = new Fields(DashboardServiceResource.ALLOWED_FIELDS, "owner");
private static final String UPDATE_FIELDS = "owner";
public DashboardServiceRepository(CollectionDAO dao) {
super(
@ -40,7 +40,7 @@ public class DashboardServiceRepository extends EntityRepository<DashboardServic
DashboardService.class,
dao.dashboardServiceDAO(),
dao,
Fields.EMPTY_FIELDS,
"",
UPDATE_FIELDS);
}

View File

@ -39,8 +39,8 @@ import org.openmetadata.catalog.util.EntityUtil.Fields;
import org.openmetadata.catalog.util.JsonUtils;
public class DatabaseRepository extends EntityRepository<Database> {
private static final Fields DATABASE_UPDATE_FIELDS = new Fields(DatabaseResource.ALLOWED_FIELDS, "owner");
private static final Fields DATABASE_PATCH_FIELDS = DATABASE_UPDATE_FIELDS;
private static final String DATABASE_UPDATE_FIELDS = "owner";
private static final String DATABASE_PATCH_FIELDS = DATABASE_UPDATE_FIELDS;
public DatabaseRepository(CollectionDAO dao) {
super(

View File

@ -40,7 +40,7 @@ import org.openmetadata.catalog.util.EntityUtil.Fields;
import org.openmetadata.catalog.util.JsonUtils;
public class DatabaseServiceRepository extends EntityRepository<DatabaseService> {
private static final Fields UPDATE_FIELDS = new Fields(DatabaseServiceResource.ALLOWED_FIELDS, "owner");
private static final String UPDATE_FIELDS = "owner";
private final Fernet fernet;
public DatabaseServiceRepository(CollectionDAO dao) {
@ -50,7 +50,7 @@ public class DatabaseServiceRepository extends EntityRepository<DatabaseService>
DatabaseService.class,
dao.dbServiceDAO(),
dao,
Fields.EMPTY_FIELDS,
"",
UPDATE_FIELDS);
fernet = Fernet.getInstance();
}
@ -59,7 +59,7 @@ public class DatabaseServiceRepository extends EntityRepository<DatabaseService>
if (!fernet.isKeyDefined()) {
throw new IllegalArgumentException(CatalogExceptionMessage.FERNET_KEY_NULL);
}
ListFilter filter = new ListFilter().addQueryParam("include", Include.ALL.value());
ListFilter filter = new ListFilter(Include.NON_DELETED);
List<String> jsons = dao.listAfter(filter, Integer.MAX_VALUE, "");
for (String json : jsons) {
DatabaseService databaseService = JsonUtils.readValue(json, DatabaseService.class);

View File

@ -113,6 +113,7 @@ public abstract class EntityRepository<T> {
private final String entityType;
protected final EntityDAO<T> dao;
protected final CollectionDAO daoCollection;
protected final List<String> allowedFields;
protected boolean supportsSoftDelete = true;
protected final boolean supportsTags;
protected final boolean supportsOwner;
@ -130,17 +131,17 @@ public abstract class EntityRepository<T> {
Class<T> entityClass,
EntityDAO<T> entityDAO,
CollectionDAO collectionDAO,
Fields patchFields,
Fields putFields) {
String patchFields,
String putFields) {
this.collectionPath = collectionPath;
this.entityClass = entityClass;
allowedFields = getEntityFields(entityClass);
this.dao = entityDAO;
this.daoCollection = collectionDAO;
this.patchFields = patchFields;
this.putFields = putFields;
this.patchFields = getFields(patchFields);
this.putFields = getFields(putFields);
this.entityType = entityType;
List<String> allowedFields = getEntityFields(entityClass);
this.supportsTags = allowedFields.contains("tags");
this.supportsOwner = allowedFields.contains("owner");
this.supportsFollower = allowedFields.contains("followers");
@ -571,14 +572,14 @@ public abstract class EntityRepository<T> {
}
}
public static final Fields FIELDS_OWNER = new Fields(List.of(FIELD_OWNER), FIELD_OWNER);
// TODO fix this
public final EntityReference getOriginalOwner(T entity) throws IOException, ParseException {
if (!supportsOwner) {
return null;
}
// Try to find the owner if entity exists
try {
String fqn = getFullyQualifiedName(entity);
entity = getByName(null, fqn, FIELDS_OWNER);
entity = getByName(null, fqn, getFields(FIELD_OWNER));
return getEntityInterface(entity).getOwner();
} catch (EntityNotFoundException e) {
// If entity is not found, we can return null for owner and ignore this exception
@ -794,6 +795,9 @@ public abstract class EntityRepository<T> {
}
public EntityReference getOwner(UUID id, String entityType) throws IOException, ParseException {
if (!supportsOwner) {
return null;
}
List<EntityReference> refs = findFrom(id, entityType, Relationship.OWNS);
ensureSingleRelationship(entityType, id, refs, "owners", false);
return refs.isEmpty() ? null : Entity.getEntityReferenceById(refs.get(0).getType(), refs.get(0).getId(), ALL);
@ -834,6 +838,10 @@ public abstract class EntityRepository<T> {
}
}
public final Fields getFields(String fields) {
return new Fields(allowedFields, fields);
}
enum Operation {
PUT,
PATCH,

View File

@ -40,8 +40,8 @@ import org.openmetadata.catalog.util.EntityUtil.Fields;
import org.openmetadata.catalog.util.JsonUtils;
public class GlossaryRepository extends EntityRepository<Glossary> {
private static final Fields UPDATE_FIELDS = new Fields(GlossaryResource.ALLOWED_FIELDS, "owner,tags,reviewers");
private static final Fields PATCH_FIELDS = new Fields(GlossaryResource.ALLOWED_FIELDS, "owner,tags,reviewers");
private static final String UPDATE_FIELDS = "owner,tags,reviewers";
private static final String PATCH_FIELDS = "owner,tags,reviewers";
public GlossaryRepository(CollectionDAO dao) {
super(

View File

@ -46,10 +46,8 @@ import org.openmetadata.catalog.util.JsonUtils;
@Slf4j
public class GlossaryTermRepository extends EntityRepository<GlossaryTerm> {
private static final Fields UPDATE_FIELDS =
new Fields(GlossaryTermResource.ALLOWED_FIELDS, "tags,references,relatedTerms,reviewers,synonyms");
private static final Fields PATCH_FIELDS =
new Fields(GlossaryTermResource.ALLOWED_FIELDS, "tags,references,relatedTerms,reviewers,synonyms");
private static final String UPDATE_FIELDS = "tags,references,relatedTerms,reviewers,synonyms";
private static final String PATCH_FIELDS = "tags,references,relatedTerms,reviewers,synonyms";
public GlossaryTermRepository(CollectionDAO dao) {
super(

View File

@ -3,16 +3,29 @@ package org.openmetadata.catalog.jdbi3;
import java.util.HashMap;
import java.util.Map;
import org.openmetadata.catalog.Entity;
import org.openmetadata.catalog.type.Include;
public class ListFilter {
private final Include include;
Map<String, String> queryParams = new HashMap<>();
public ListFilter() {
this(Include.NON_DELETED);
}
public ListFilter(Include include) {
this.include = include;
}
public ListFilter addQueryParam(String name, String value) {
queryParams.put(name, value);
return this;
}
public String getQueryParam(String name) {
if (name.equals("include")) {
return include.value();
}
return queryParams.get(name);
}
@ -29,12 +42,11 @@ public class ListFilter {
}
public String getIncludeCondition(String tableName) {
String include = queryParams.get("include");
String columnName = tableName == null ? "deleted" : tableName + ".deleted";
if (include == null || include.equals("non-deleted")) {
if (include == Include.NON_DELETED) {
return columnName + " = false";
}
if (include.equals("deleted")) {
if (include == Include.DELETED) {
return columnName + " = true";
}
return "";

View File

@ -41,9 +41,9 @@ import org.openmetadata.catalog.util.ResultList;
public class LocationRepository extends EntityRepository<Location> {
// Location fields that can be patched in a PATCH request
private static final Fields LOCATION_PATCH_FIELDS = new Fields(LocationResource.ALLOWED_FIELDS, "owner,tags");
private static final String LOCATION_PATCH_FIELDS = "owner,tags";
// Location fields that can be updated in a PUT request
private static final Fields LOCATION_UPDATE_FIELDS = new Fields(LocationResource.ALLOWED_FIELDS, "owner,tags");
private static final String LOCATION_UPDATE_FIELDS = "owner,tags";
public LocationRepository(CollectionDAO dao) {
super(

View File

@ -32,7 +32,7 @@ import org.openmetadata.catalog.util.EntityUtil;
import org.openmetadata.catalog.util.EntityUtil.Fields;
public class MessagingServiceRepository extends EntityRepository<MessagingService> {
private static final Fields UPDATE_FIELDS = new Fields(MessagingServiceResource.ALLOWED_FIELDS, "owner");
private static final String UPDATE_FIELDS = "owner";
public MessagingServiceRepository(CollectionDAO dao) {
super(
@ -41,7 +41,7 @@ public class MessagingServiceRepository extends EntityRepository<MessagingServic
MessagingService.class,
dao.messagingServiceDAO(),
dao,
Fields.EMPTY_FIELDS,
"",
UPDATE_FIELDS);
}

View File

@ -34,7 +34,7 @@ import org.openmetadata.catalog.util.EntityUtil;
import org.openmetadata.catalog.util.EntityUtil.Fields;
public class MetricsRepository extends EntityRepository<Metrics> {
private static final Fields METRICS_UPDATE_FIELDS = new Fields(MetricsResource.ALLOWED_FIELDS, "owner");
private static final String METRICS_UPDATE_FIELDS = "owner";
public MetricsRepository(CollectionDAO dao) {
super(
@ -43,7 +43,7 @@ public class MetricsRepository extends EntityRepository<Metrics> {
Metrics.class,
dao.metricsDAO(),
dao,
Fields.EMPTY_FIELDS,
"",
METRICS_UPDATE_FIELDS);
}

View File

@ -45,8 +45,8 @@ import org.openmetadata.catalog.util.EntityUtil.Fields;
@Slf4j
public class MlModelRepository extends EntityRepository<MlModel> {
private static final Fields MODEL_UPDATE_FIELDS = new Fields(MlModelResource.ALLOWED_FIELDS, "owner,dashboard,tags");
private static final Fields MODEL_PATCH_FIELDS = new Fields(MlModelResource.ALLOWED_FIELDS, "owner,dashboard,tags");
private static final String MODEL_UPDATE_FIELDS = "owner,dashboard,tags";
private static final String MODEL_PATCH_FIELDS = "owner,dashboard,tags";
public MlModelRepository(CollectionDAO dao) {
super(

View File

@ -48,8 +48,8 @@ import org.openmetadata.catalog.util.EntityUtil.Fields;
import org.openmetadata.catalog.util.JsonUtils;
public class PipelineRepository extends EntityRepository<Pipeline> {
private static final Fields PIPELINE_UPDATE_FIELDS = new Fields(PipelineResource.ALLOWED_FIELDS, "owner,tags,tasks");
private static final Fields PIPELINE_PATCH_FIELDS = new Fields(PipelineResource.ALLOWED_FIELDS, "owner,tags,tasks");
private static final String PIPELINE_UPDATE_FIELDS = "owner,tags,tasks";
private static final String PIPELINE_PATCH_FIELDS = "owner,tags,tasks";
public PipelineRepository(CollectionDAO dao) {
super(

View File

@ -29,7 +29,7 @@ import org.openmetadata.catalog.util.EntityUtil;
import org.openmetadata.catalog.util.EntityUtil.Fields;
public class PipelineServiceRepository extends EntityRepository<PipelineService> {
private static final Fields UPDATE_FIELDS = new Fields(PipelineServiceResource.ALLOWED_FIELDS, "owner");
private static final String UPDATE_FIELDS = "owner";
public PipelineServiceRepository(CollectionDAO dao) {
super(
@ -38,7 +38,7 @@ public class PipelineServiceRepository extends EntityRepository<PipelineService>
PipelineService.class,
dao.pipelineServiceDAO(),
dao,
Fields.EMPTY_FIELDS,
"",
UPDATE_FIELDS);
}

View File

@ -36,7 +36,6 @@ import org.openmetadata.catalog.resources.policies.PolicyResource;
import org.openmetadata.catalog.security.policyevaluator.PolicyEvaluator;
import org.openmetadata.catalog.type.ChangeDescription;
import org.openmetadata.catalog.type.EntityReference;
import org.openmetadata.catalog.type.Include;
import org.openmetadata.catalog.type.MetadataOperation;
import org.openmetadata.catalog.type.PolicyType;
import org.openmetadata.catalog.type.Relationship;
@ -47,8 +46,8 @@ import org.openmetadata.catalog.util.JsonUtils;
@Slf4j
public class PolicyRepository extends EntityRepository<Policy> {
private static final Fields POLICY_UPDATE_FIELDS = new Fields(PolicyResource.ALLOWED_FIELDS, "owner,location");
private static final Fields POLICY_PATCH_FIELDS = new Fields(PolicyResource.ALLOWED_FIELDS, "owner,location");
private static final String POLICY_UPDATE_FIELDS = "owner,location";
private static final String POLICY_PATCH_FIELDS = "owner,location";
public static final String ENABLED = "enabled";
private final PolicyEvaluator policyEvaluator;
@ -206,7 +205,7 @@ public class PolicyRepository extends EntityRepository<Policy> {
private List<Policy> getAccessControlPolicies() throws IOException, ParseException {
EntityUtil.Fields fields = new EntityUtil.Fields(List.of("policyType", "rules", ENABLED));
ListFilter filter = new ListFilter().addQueryParam("include", Include.NON_DELETED.value());
ListFilter filter = new ListFilter();
List<String> jsons = daoCollection.policyDAO().listAfter(filter, Integer.MAX_VALUE, "");
List<Policy> policies = new ArrayList<>(jsons.size());
for (String json : jsons) {

View File

@ -34,17 +34,10 @@ import org.openmetadata.catalog.util.EntityUtil.Fields;
@Slf4j
public class ReportRepository extends EntityRepository<Report> {
private static final Fields REPORT_UPDATE_FIELDS = new Fields(ReportResource.ALLOWED_FIELDS, "owner");
private static final String REPORT_UPDATE_FIELDS = "owner";
public ReportRepository(CollectionDAO dao) {
super(
ReportResource.COLLECTION_PATH,
Entity.REPORT,
Report.class,
dao.reportDAO(),
dao,
Fields.EMPTY_FIELDS,
REPORT_UPDATE_FIELDS);
super(ReportResource.COLLECTION_PATH, Entity.REPORT, Report.class, dao.reportDAO(), dao, "", REPORT_UPDATE_FIELDS);
}
@Override

View File

@ -37,7 +37,6 @@ import org.openmetadata.catalog.exception.EntityNotFoundException;
import org.openmetadata.catalog.resources.teams.RoleResource;
import org.openmetadata.catalog.type.ChangeDescription;
import org.openmetadata.catalog.type.EntityReference;
import org.openmetadata.catalog.type.Include;
import org.openmetadata.catalog.type.PolicyType;
import org.openmetadata.catalog.type.Relationship;
import org.openmetadata.catalog.util.EntityInterface;
@ -48,18 +47,8 @@ import org.openmetadata.catalog.util.ResultList;
@Slf4j
public class RoleRepository extends EntityRepository<Role> {
static final Fields ROLE_UPDATE_FIELDS = new Fields(RoleResource.ALLOWED_FIELDS, null);
static final Fields ROLE_PATCH_FIELDS = new Fields(RoleResource.ALLOWED_FIELDS, null);
public RoleRepository(CollectionDAO dao) {
super(
RoleResource.COLLECTION_PATH,
Entity.ROLE,
Role.class,
dao.roleDAO(),
dao,
ROLE_PATCH_FIELDS,
ROLE_UPDATE_FIELDS);
super(RoleResource.COLLECTION_PATH, Entity.ROLE, Role.class, dao.roleDAO(), dao, "", "");
}
@Override
@ -328,7 +317,7 @@ public class RoleRepository extends EntityRepository<Role> {
}
private void setDefaultToTrue(Role role) throws IOException, ParseException {
List<Role> defaultRoles = getDefaultRoles(null, ROLE_PATCH_FIELDS);
List<Role> defaultRoles = getDefaultRoles(null, Fields.EMPTY_FIELDS);
EntityRepository<Role> roleRepository = Entity.getEntityRepository(Entity.ROLE);
// Set default=FALSE for all existing default roles.
for (Role defaultRole : defaultRoles) {
@ -336,8 +325,8 @@ public class RoleRepository extends EntityRepository<Role> {
// Skip the current role which is being set with default=TRUE.
continue;
}
Role origDefaultRole = roleRepository.get(null, defaultRole.getId().toString(), ROLE_PATCH_FIELDS);
Role updatedDefaultRole = roleRepository.get(null, defaultRole.getId().toString(), ROLE_PATCH_FIELDS);
Role origDefaultRole = roleRepository.get(null, defaultRole.getId().toString(), Fields.EMPTY_FIELDS);
Role updatedDefaultRole = roleRepository.get(null, defaultRole.getId().toString(), Fields.EMPTY_FIELDS);
updatedDefaultRole = updatedDefaultRole.withDefaultRole(false);
new RoleUpdater(origDefaultRole, updatedDefaultRole, Operation.PATCH).update();
}
@ -366,10 +355,8 @@ public class RoleRepository extends EntityRepository<Role> {
// Assumptions:
// - we will not have more than Integer.MAX_VALUE users in the system.
// - we do not need to update deleted user's roles.
ListFilter filter = new ListFilter().addQueryParam("include", Include.NON_DELETED.value());
return userRepository
.listAfter(null, UserRepository.USER_UPDATE_FIELDS, filter, Integer.MAX_VALUE - 1, null)
.getData();
ListFilter filter = new ListFilter();
return userRepository.listAfter(null, Fields.EMPTY_FIELDS, filter, Integer.MAX_VALUE - 1, null).getData();
} catch (GeneralSecurityException | IOException | ParseException e) {
throw EntityNotFoundException.byMessage(CatalogExceptionMessage.entitiesNotFound(Entity.USER));
}

View File

@ -28,7 +28,7 @@ import org.openmetadata.catalog.type.EntityReference;
import org.openmetadata.catalog.util.EntityInterface;
public class StorageServiceRepository extends EntityRepository<StorageService> {
private static final Fields UPDATE_FIELDS = new Fields(StorageServiceResource.ALLOWED_FIELDS, "owner");
private static final String UPDATE_FIELDS = "owner";
public StorageServiceRepository(CollectionDAO dao) {
super(
@ -37,7 +37,7 @@ public class StorageServiceRepository extends EntityRepository<StorageService> {
StorageService.class,
dao.storageServiceDAO(),
dao,
Fields.EMPTY_FIELDS,
"",
UPDATE_FIELDS);
}

View File

@ -81,11 +81,9 @@ import org.openmetadata.common.utils.CommonUtil;
@Slf4j
public class TableRepository extends EntityRepository<Table> {
// Table fields that can be patched in a PATCH request
static final Fields TABLE_PATCH_FIELDS =
new Fields(TableResource.ALLOWED_FIELDS, "owner,tags,tableConstraints,tablePartition");
static final String TABLE_PATCH_FIELDS = "owner,tags,tableConstraints,tablePartition";
// Table fields that can be updated in a PUT request
static final Fields TABLE_UPDATE_FIELDS =
new Fields(TableResource.ALLOWED_FIELDS, "owner,tags,tableConstraints,tablePartition,dataModel,profileSample");
static final String TABLE_UPDATE_FIELDS = "owner,tags,tableConstraints,tablePartition,dataModel,profileSample";
public TableRepository(CollectionDAO dao) {
super(

View File

@ -35,8 +35,8 @@ import org.openmetadata.catalog.util.EntityUtil;
import org.openmetadata.catalog.util.EntityUtil.Fields;
public class TeamRepository extends EntityRepository<Team> {
static final Fields TEAM_UPDATE_FIELDS = new Fields(TeamResource.ALLOWED_FIELDS, "owner,profile,users,defaultRoles");
static final Fields TEAM_PATCH_FIELDS = new Fields(TeamResource.ALLOWED_FIELDS, "owner,profile,users,defaultRoles");
static final String TEAM_UPDATE_FIELDS = "owner,profile,users,defaultRoles";
static final String TEAM_PATCH_FIELDS = "owner,profile,users,defaultRoles";
public TeamRepository(CollectionDAO dao) {
super(TeamResource.COLLECTION_PATH, TEAM, Team.class, dao.teamDAO(), dao, TEAM_PATCH_FIELDS, TEAM_UPDATE_FIELDS);

View File

@ -39,8 +39,8 @@ import org.openmetadata.catalog.util.EntityUtil;
import org.openmetadata.catalog.util.EntityUtil.Fields;
public class TopicRepository extends EntityRepository<Topic> {
private static final Fields TOPIC_UPDATE_FIELDS = new Fields(TopicResource.ALLOWED_FIELDS, "owner,tags");
private static final Fields TOPIC_PATCH_FIELDS = new Fields(TopicResource.ALLOWED_FIELDS, "owner,tags");
private static final String TOPIC_UPDATE_FIELDS = "owner,tags";
private static final String TOPIC_PATCH_FIELDS = "owner,tags";
public static String getFQN(Topic topic) {
return (topic != null && topic.getService() != null)

View File

@ -33,6 +33,7 @@ import org.openmetadata.catalog.entity.teams.User;
import org.openmetadata.catalog.resources.teams.UserResource;
import org.openmetadata.catalog.type.ChangeDescription;
import org.openmetadata.catalog.type.EntityReference;
import org.openmetadata.catalog.type.Include;
import org.openmetadata.catalog.type.Relationship;
import org.openmetadata.catalog.util.EntityInterface;
import org.openmetadata.catalog.util.EntityUtil;
@ -40,8 +41,8 @@ import org.openmetadata.catalog.util.EntityUtil.Fields;
@Slf4j
public class UserRepository extends EntityRepository<User> {
static final Fields USER_PATCH_FIELDS = new Fields(UserResource.ALLOWED_FIELDS, "profile,roles,teams");
static final Fields USER_UPDATE_FIELDS = new Fields(UserResource.ALLOWED_FIELDS, "profile,roles,teams");
static final String USER_PATCH_FIELDS = "profile,roles,teams";
static final String USER_UPDATE_FIELDS = "profile,roles,teams";
public UserRepository(CollectionDAO dao) {
super(
@ -82,7 +83,7 @@ public class UserRepository extends EntityRepository<User> {
List<EntityReference> teamsRef = listOrEmpty(user.getTeams());
List<EntityReference> defaultRoles = new ArrayList<>();
for (EntityReference teamRef : teamsRef) {
Team team = Entity.getEntity(teamRef, new Fields(List.of("defaultRoles")));
Team team = Entity.getEntity(teamRef, new Fields(List.of("defaultRoles")), Include.NON_DELETED);
if (team != null && team.getDefaultRoles() != null) {
defaultRoles.addAll(team.getDefaultRoles());
}

View File

@ -62,14 +62,7 @@ public class WebhookRepository extends EntityRepository<Webhook> {
private static final ConcurrentHashMap<UUID, WebhookPublisher> webhookPublisherMap = new ConcurrentHashMap<>();
public WebhookRepository(CollectionDAO dao) {
super(
WebhookResource.COLLECTION_PATH,
Entity.WEBHOOK,
Webhook.class,
dao.webhookDAO(),
dao,
Fields.EMPTY_FIELDS,
Fields.EMPTY_FIELDS);
super(WebhookResource.COLLECTION_PATH, Entity.WEBHOOK, Webhook.class, dao.webhookDAO(), dao, "", "");
}
@Override

View File

@ -28,6 +28,10 @@ public abstract class EntityResource<T, K extends EntityRepository<T>> {
this.authorizer = authorizer;
}
public final Fields getFields(String fields) {
return new Fields(allowedFields, fields);
}
public abstract T addHref(UriInfo uriInfo, T entity);
public final ResultList<T> addHref(UriInfo uriInfo, ResultList<T> list) {
@ -45,7 +49,7 @@ public abstract class EntityResource<T, K extends EntityRepository<T>> {
String after)
throws GeneralSecurityException, IOException, ParseException {
RestUtil.validateCursors(before, after);
Fields fields = new Fields(allowedFields, fieldsParam);
Fields fields = getFields(fieldsParam);
ResultList<T> resultList;
if (before != null) { // Reverse paging
@ -58,14 +62,14 @@ public abstract class EntityResource<T, K extends EntityRepository<T>> {
public T getInternal(UriInfo uriInfo, SecurityContext securityContext, String id, String fieldsParam, Include include)
throws IOException, ParseException {
Fields fields = new Fields(allowedFields, fieldsParam);
Fields fields = getFields(fieldsParam);
return addHref(uriInfo, dao.get(uriInfo, id, fields, include));
}
public T getByNameInternal(
UriInfo uriInfo, SecurityContext securityContext, String name, String fieldsParam, Include include)
throws IOException, ParseException {
Fields fields = new Fields(allowedFields, fieldsParam);
Fields fields = getFields(fieldsParam);
return addHref(uriInfo, dao.getByName(uriInfo, name, fields, include));
}
}

View File

@ -59,6 +59,7 @@ import org.openmetadata.catalog.security.Authorizer;
import org.openmetadata.catalog.security.SecurityUtil;
import org.openmetadata.catalog.type.EntityHistory;
import org.openmetadata.catalog.type.Include;
import org.openmetadata.catalog.util.EntityInterface;
import org.openmetadata.catalog.util.EntityUtil.Fields;
import org.openmetadata.catalog.util.RestUtil;
import org.openmetadata.catalog.util.RestUtil.DeleteResponse;
@ -99,7 +100,6 @@ public class ChartResource extends EntityResource<Chart, ChartRepository> {
}
static final String FIELDS = "owner,followers,tags";
public static final List<String> ALLOWED_FIELDS = Entity.getEntityFields(Chart.class);
@GET
@Operation(
@ -145,8 +145,7 @@ public class ChartResource extends EntityResource<Chart, ChartRepository> {
@DefaultValue("non-deleted")
Include include)
throws IOException, GeneralSecurityException, ParseException {
ListFilter filter = new ListFilter();
filter.addQueryParam("include", include.value()).addQueryParam("service", serviceParam);
ListFilter filter = new ListFilter(include).addQueryParam("service", serviceParam);
return super.listInternal(uriInfo, securityContext, fieldsParam, filter, limitParam, before, after);
}
@ -304,14 +303,11 @@ public class ChartResource extends EntityResource<Chart, ChartRepository> {
}))
JsonPatch patch)
throws IOException, ParseException {
Fields fields = new Fields(ALLOWED_FIELDS, FIELDS);
Fields fields = getFields(Entity.FIELD_OWNER);
Chart chart = dao.get(uriInfo, id, fields);
EntityInterface<Chart> entityInterface = dao.getEntityInterface(chart);
SecurityUtil.checkAdminRoleOrPermissions(
authorizer,
securityContext,
dao.getEntityInterface(chart).getEntityReference(),
dao.getOriginalOwner(chart),
patch);
authorizer, securityContext, entityInterface.getEntityReference(), entityInterface.getOwner(), patch);
PatchResponse<Chart> response =
dao.patch(uriInfo, UUID.fromString(id), securityContext.getUserPrincipal().getName(), patch);

View File

@ -13,6 +13,8 @@
package org.openmetadata.catalog.resources.dashboards;
import static org.openmetadata.catalog.Entity.FIELD_OWNER;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.ExternalDocumentation;
import io.swagger.v3.oas.annotations.Operation;
@ -59,7 +61,6 @@ import org.openmetadata.catalog.security.Authorizer;
import org.openmetadata.catalog.security.SecurityUtil;
import org.openmetadata.catalog.type.EntityHistory;
import org.openmetadata.catalog.type.Include;
import org.openmetadata.catalog.util.EntityUtil.Fields;
import org.openmetadata.catalog.util.RestUtil.DeleteResponse;
import org.openmetadata.catalog.util.RestUtil.PatchResponse;
import org.openmetadata.catalog.util.RestUtil.PutResponse;
@ -98,7 +99,6 @@ public class DashboardResource extends EntityResource<Dashboard, DashboardReposi
}
static final String FIELDS = "owner,charts,followers,tags,usageSummary";
public static final List<String> ALLOWED_FIELDS = Entity.getEntityFields(Dashboard.class);
@GET
@Valid
@ -147,8 +147,7 @@ public class DashboardResource extends EntityResource<Dashboard, DashboardReposi
@DefaultValue("non-deleted")
Include include)
throws IOException, GeneralSecurityException, ParseException {
ListFilter filter = new ListFilter();
filter.addQueryParam("include", include.value()).addQueryParam("service", serviceParam);
ListFilter filter = new ListFilter(include).addQueryParam("service", serviceParam);
return super.listInternal(uriInfo, securityContext, fieldsParam, filter, limitParam, before, after);
}
@ -308,8 +307,7 @@ public class DashboardResource extends EntityResource<Dashboard, DashboardReposi
}))
JsonPatch patch)
throws IOException, ParseException {
Fields fields = new Fields(ALLOWED_FIELDS, FIELDS);
Dashboard dashboard = dao.get(uriInfo, id, fields);
Dashboard dashboard = dao.get(uriInfo, id, getFields(FIELD_OWNER));
SecurityUtil.checkAdminRoleOrPermissions(
authorizer,
securityContext,

View File

@ -59,6 +59,7 @@ import org.openmetadata.catalog.security.Authorizer;
import org.openmetadata.catalog.security.SecurityUtil;
import org.openmetadata.catalog.type.EntityHistory;
import org.openmetadata.catalog.type.Include;
import org.openmetadata.catalog.util.EntityInterface;
import org.openmetadata.catalog.util.EntityUtil.Fields;
import org.openmetadata.catalog.util.RestUtil.DeleteResponse;
import org.openmetadata.catalog.util.RestUtil.PatchResponse;
@ -96,7 +97,6 @@ public class DatabaseResource extends EntityResource<Database, DatabaseRepositor
}
static final String FIELDS = "owner,tables,usageSummary,location";
public static final List<String> ALLOWED_FIELDS = Entity.getEntityFields(Database.class);
@GET
@Operation(
@ -144,8 +144,7 @@ public class DatabaseResource extends EntityResource<Database, DatabaseRepositor
@DefaultValue("non-deleted")
Include include)
throws IOException, GeneralSecurityException, ParseException {
ListFilter filter = new ListFilter();
filter.addQueryParam("include", include.value()).addQueryParam("service", serviceParam);
ListFilter filter = new ListFilter(include).addQueryParam("service", serviceParam);
return super.listInternal(uriInfo, securityContext, fieldsParam, filter, limitParam, before, after);
}
@ -291,7 +290,7 @@ public class DatabaseResource extends EntityResource<Database, DatabaseRepositor
description = "Update an existing database using JsonPatch.",
externalDocs = @ExternalDocumentation(description = "JsonPatch RFC", url = "https://tools.ietf.org/html/rfc6902"))
@Consumes(MediaType.APPLICATION_JSON_PATCH_JSON)
public Response updateDescription(
public Response patch(
@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@PathParam("id") String id,
@ -305,14 +304,10 @@ public class DatabaseResource extends EntityResource<Database, DatabaseRepositor
}))
JsonPatch patch)
throws IOException, ParseException {
Fields fields = new Fields(ALLOWED_FIELDS, FIELDS);
Database database = dao.get(uriInfo, id, fields);
Database database = dao.get(uriInfo, id, getFields(Entity.FIELD_OWNER));
EntityInterface<Database> entityInterface = dao.getEntityInterface(database);
SecurityUtil.checkAdminRoleOrPermissions(
authorizer,
securityContext,
dao.getEntityInterface(database).getEntityReference(),
dao.getOriginalOwner(database),
patch);
authorizer, securityContext, entityInterface.getEntityReference(), entityInterface.getOwner(), patch);
PatchResponse<Database> response =
dao.patch(uriInfo, UUID.fromString(id), securityContext.getUserPrincipal().getName(), patch);
@ -349,9 +344,8 @@ public class DatabaseResource extends EntityResource<Database, DatabaseRepositor
@Context SecurityContext securityContext,
@Parameter(description = "Id of the database", schema = @Schema(type = "string")) @PathParam("id") String id)
throws IOException, ParseException {
Fields fields = new Fields(ALLOWED_FIELDS, "location");
dao.deleteLocation(id);
Database database = dao.get(uriInfo, id, fields);
Database database = dao.get(uriInfo, id, Fields.EMPTY_FIELDS);
return addHref(uriInfo, database);
}

View File

@ -13,6 +13,8 @@
package org.openmetadata.catalog.resources.databases;
import static org.openmetadata.catalog.Entity.FIELD_OWNER;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.ExternalDocumentation;
import io.swagger.v3.oas.annotations.Operation;
@ -26,7 +28,6 @@ import java.io.IOException;
import java.security.GeneralSecurityException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import javax.json.JsonPatch;
@ -115,14 +116,6 @@ public class TableResource extends EntityResource<Table, TableRepository> {
static final String FIELDS =
"tableConstraints,tablePartition,usageSummary,owner,profileSample,customMetrics,"
+ "tags,followers,joins,sampleData,viewDefinition,tableProfile,location,tableQueries,dataModel,tests";
public static final List<String> ALLOWED_FIELDS;
static {
List<String> list = new ArrayList<>(Entity.getEntityFields(Table.class));
list.add("tests"); // Add a field parameter called tests that represent the fields - tableTests and columnTests
list.add("customMetrics"); // Add a field parameter to add customMetrics information to the columns
ALLOWED_FIELDS = Collections.unmodifiableList(list);
}
@GET
@Operation(
@ -170,8 +163,7 @@ public class TableResource extends EntityResource<Table, TableRepository> {
@DefaultValue("non-deleted")
Include include)
throws IOException, ParseException, GeneralSecurityException {
ListFilter filter = new ListFilter();
filter.addQueryParam("include", include.value()).addQueryParam("database", databaseParam);
ListFilter filter = new ListFilter(include).addQueryParam("database", databaseParam);
return super.listInternal(uriInfo, securityContext, fieldsParam, filter, limitParam, before, after);
}
@ -302,8 +294,8 @@ public class TableResource extends EntityResource<Table, TableRepository> {
})
public Response create(@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateTable create)
throws IOException, ParseException {
SecurityUtil.checkAdminOrBotRole(authorizer, securityContext);
Table table = getTable(securityContext, create);
SecurityUtil.checkAdminOrBotRole(authorizer, securityContext);
table = addHref(uriInfo, dao.create(uriInfo, validateNewTable(table)));
return Response.created(table.getHref()).entity(table).build();
}
@ -352,8 +344,7 @@ public class TableResource extends EntityResource<Table, TableRepository> {
}))
JsonPatch patch)
throws IOException, ParseException {
Fields fields = new Fields(ALLOWED_FIELDS, FIELDS);
Table table = dao.get(uriInfo, id, fields);
Table table = dao.get(uriInfo, id, getFields(FIELD_OWNER));
SecurityUtil.checkAdminRoleOrPermissions(
authorizer,
securityContext,
@ -638,7 +629,7 @@ public class TableResource extends EntityResource<Table, TableRepository> {
@Context SecurityContext securityContext,
@Parameter(description = "Id of the table", schema = @Schema(type = "string")) @PathParam("id") String id)
throws IOException, ParseException {
Fields fields = new Fields(ALLOWED_FIELDS, "location");
Fields fields = getFields("location");
dao.deleteLocation(id);
Table table = dao.get(uriInfo, id, fields);
return addHref(uriInfo, table);

View File

@ -123,9 +123,7 @@ public class WebhookResource extends EntityResource<Webhook, WebhookRepository>
Include include)
throws IOException, ParseException, GeneralSecurityException {
RestUtil.validateCursors(before, after);
ListFilter filter = new ListFilter();
filter.addQueryParam("include", include.value());
ListFilter filter = new ListFilter(include);
ResultList<Webhook> webhooks;
if (before != null) { // Reverse paging
webhooks = dao.listBefore(uriInfo, Fields.EMPTY_FIELDS, filter, limitParam, before);
@ -277,9 +275,7 @@ public class WebhookResource extends EntityResource<Webhook, WebhookRepository>
public Response updateWebhook(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateWebhook create)
throws IOException, ParseException, InterruptedException {
// TODO
// SecurityUtil.checkAdminOrBotRole(authorizer, securityContext);
// Table table = getTable(securityContext, create);
SecurityUtil.checkAdminRole(authorizer, securityContext);
Webhook webhook = getWebhook(securityContext, create);
webhook.setStatus(Boolean.TRUE.equals(webhook.getEnabled()) ? Status.ACTIVE : Status.DISABLED);
PutResponse<Webhook> putResponse = dao.createOrUpdate(uriInfo, webhook);

View File

@ -72,7 +72,6 @@ import org.openmetadata.catalog.util.ResultList;
@Collection(name = "feeds")
public class FeedResource {
public static final String COLLECTION_PATH = "/v1/feed/";
public static final List<String> ALLOWED_FIELDS = getAllowedFields();
private final FeedRepository dao;
private final Authorizer authorizer;

View File

@ -59,9 +59,7 @@ import org.openmetadata.catalog.resources.EntityResource;
import org.openmetadata.catalog.security.Authorizer;
import org.openmetadata.catalog.security.SecurityUtil;
import org.openmetadata.catalog.type.EntityHistory;
import org.openmetadata.catalog.type.EntityReference;
import org.openmetadata.catalog.type.Include;
import org.openmetadata.catalog.util.EntityUtil.Fields;
import org.openmetadata.catalog.util.RestUtil;
import org.openmetadata.catalog.util.RestUtil.DeleteResponse;
import org.openmetadata.catalog.util.RestUtil.PatchResponse;
@ -101,7 +99,6 @@ public class GlossaryResource extends EntityResource<Glossary, GlossaryRepositor
}
static final String FIELDS = "owner,tags,reviewers,usageCount";
public static final List<String> ALLOWED_FIELDS = Entity.getEntityFields(Glossary.class);
@GET
@Valid
@ -145,8 +142,7 @@ public class GlossaryResource extends EntityResource<Glossary, GlossaryRepositor
@DefaultValue("non-deleted")
Include include)
throws IOException, GeneralSecurityException, ParseException {
ListFilter filter = new ListFilter();
filter.addQueryParam("include", include.value());
ListFilter filter = new ListFilter(include);
return super.listInternal(uriInfo, securityContext, fieldsParam, filter, limitParam, before, after);
}
@ -306,8 +302,7 @@ public class GlossaryResource extends EntityResource<Glossary, GlossaryRepositor
}))
JsonPatch patch)
throws IOException, ParseException {
Fields fields = new Fields(ALLOWED_FIELDS, FIELDS);
Glossary glossary = dao.get(uriInfo, id, fields);
Glossary glossary = dao.get(uriInfo, id, getFields(Entity.FIELD_OWNER));
SecurityUtil.checkAdminRoleOrPermissions(
authorizer,
securityContext,
@ -336,8 +331,7 @@ public class GlossaryResource extends EntityResource<Glossary, GlossaryRepositor
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateGlossary create)
throws IOException, ParseException {
Glossary glossary = getGlossary(securityContext, create);
EntityReference owner = dao.getOriginalOwner(glossary);
SecurityUtil.checkAdminRoleOrPermissions(authorizer, securityContext, owner);
SecurityUtil.checkAdminRoleOrPermissions(authorizer, securityContext, dao.getOriginalOwner(glossary));
PutResponse<Glossary> response = dao.createOrUpdate(uriInfo, glossary);
addHref(uriInfo, response.getEntity());
return response.toResponse();

View File

@ -63,6 +63,7 @@ import org.openmetadata.catalog.security.SecurityUtil;
import org.openmetadata.catalog.type.EntityHistory;
import org.openmetadata.catalog.type.EntityReference;
import org.openmetadata.catalog.type.Include;
import org.openmetadata.catalog.util.EntityInterface;
import org.openmetadata.catalog.util.EntityUtil.Fields;
import org.openmetadata.catalog.util.RestUtil;
import org.openmetadata.catalog.util.RestUtil.DeleteResponse;
@ -106,7 +107,6 @@ public class GlossaryTermResource extends EntityResource<GlossaryTerm, GlossaryT
}
static final String FIELDS = "children,relatedTerms,reviewers,tags,usageCount";
public static final List<String> ALLOWED_FIELDS = Entity.getEntityFields(GlossaryTerm.class);
@GET
@Valid
@ -165,7 +165,7 @@ public class GlossaryTermResource extends EntityResource<GlossaryTerm, GlossaryT
throws IOException, GeneralSecurityException, ParseException {
// TODO make this common implementation
RestUtil.validateCursors(before, after);
Fields fields = new Fields(ALLOWED_FIELDS, fieldsParam);
Fields fields = getFields(fieldsParam);
// Filter by glossary
String fqn = null;
@ -186,8 +186,7 @@ public class GlossaryTermResource extends EntityResource<GlossaryTerm, GlossaryT
CatalogExceptionMessage.glossaryTermMismatch(parentTermParam, glossaryIdParam));
}
}
ListFilter filter = new ListFilter();
filter.addQueryParam("include", include.value()).addQueryParam("parent", fqn);
ListFilter filter = new ListFilter(include).addQueryParam("parent", fqn);
ResultList<GlossaryTerm> terms;
if (before != null) { // Reverse paging
@ -339,7 +338,7 @@ public class GlossaryTermResource extends EntityResource<GlossaryTerm, GlossaryT
description = "Update an existing glossary using JsonPatch.",
externalDocs = @ExternalDocumentation(description = "JsonPatch RFC", url = "https://tools.ietf.org/html/rfc6902"))
@Consumes(MediaType.APPLICATION_JSON_PATCH_JSON)
public Response updateDescription(
public Response patch(
@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@PathParam("id") String id,
@ -353,14 +352,10 @@ public class GlossaryTermResource extends EntityResource<GlossaryTerm, GlossaryT
}))
JsonPatch patch)
throws IOException, ParseException {
Fields fields = new Fields(ALLOWED_FIELDS, FIELDS);
GlossaryTerm term = dao.get(uriInfo, id, fields);
GlossaryTerm term = dao.get(uriInfo, id, Fields.EMPTY_FIELDS);
EntityInterface<GlossaryTerm> entityInterface = dao.getEntityInterface(term);
SecurityUtil.checkAdminRoleOrPermissions(
authorizer,
securityContext,
dao.getEntityInterface(term).getEntityReference(),
dao.getOriginalOwner(term),
patch);
authorizer, securityContext, entityInterface.getEntityReference(), entityInterface.getOwner(), patch);
PatchResponse<GlossaryTerm> response =
dao.patch(uriInfo, UUID.fromString(id), securityContext.getUserPrincipal().getName(), patch);
addHref(uriInfo, response.getEntity());
@ -383,8 +378,7 @@ public class GlossaryTermResource extends EntityResource<GlossaryTerm, GlossaryT
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateGlossaryTerm create)
throws IOException, ParseException {
GlossaryTerm term = getGlossaryTerm(securityContext, create);
EntityReference owner = dao.getOriginalOwner(term);
SecurityUtil.checkAdminRoleOrPermissions(authorizer, securityContext, owner);
SecurityUtil.checkAdminRoleOrPermissions(authorizer, securityContext, dao.getOriginalOwner(term));
PutResponse<GlossaryTerm> response = dao.createOrUpdate(uriInfo, term);
addHref(uriInfo, response.getEntity());
return response.toResponse();

View File

@ -96,7 +96,6 @@ public class LocationResource extends EntityResource<Location, LocationRepositor
}
static final String FIELDS = "owner,followers,tags";
public static final List<String> ALLOWED_FIELDS = Entity.getEntityFields(Location.class);
@GET
@Operation(
@ -144,8 +143,7 @@ public class LocationResource extends EntityResource<Location, LocationRepositor
@DefaultValue("non-deleted")
Include include)
throws IOException, GeneralSecurityException, ParseException {
ListFilter filter = new ListFilter();
filter.addQueryParam("include", include.value()).addQueryParam("service", serviceParam);
ListFilter filter = new ListFilter(include).addQueryParam("service", serviceParam);
return super.listInternal(uriInfo, securityContext, fieldsParam, filter, limitParam, before, after);
}
@ -243,7 +241,7 @@ public class LocationResource extends EntityResource<Location, LocationRepositor
String after)
throws IOException, GeneralSecurityException, ParseException {
RestUtil.validateCursors(before, after);
Fields fields = new Fields(ALLOWED_FIELDS, fieldsParam);
Fields fields = getFields(fieldsParam);
ResultList<Location> locations;
if (before != null) { // Reverse paging
@ -383,7 +381,7 @@ public class LocationResource extends EntityResource<Location, LocationRepositor
}))
JsonPatch patch)
throws IOException, ParseException {
Fields fields = new Fields(ALLOWED_FIELDS, FIELDS);
Fields fields = getFields(FIELDS);
Location location = dao.get(uriInfo, id, fields);
SecurityUtil.checkAdminRoleOrPermissions(
authorizer,

View File

@ -41,7 +41,6 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;
import org.openmetadata.catalog.Entity;
import org.openmetadata.catalog.entity.data.Metrics;
import org.openmetadata.catalog.jdbi3.CollectionDAO;
import org.openmetadata.catalog.jdbi3.ListFilter;
@ -77,7 +76,6 @@ public class MetricsResource extends EntityResource<Metrics, MetricsRepository>
}
static final String FIELDS = "owner,usageSummary";
public static final List<String> ALLOWED_FIELDS = Entity.getEntityFields(Metrics.class);
@GET
@Operation(

View File

@ -99,7 +99,6 @@ public class MlModelResource extends EntityResource<MlModel, MlModelRepository>
}
static final String FIELDS = "owner,dashboard,followers,tags,usageSummary";
public static final List<String> ALLOWED_FIELDS = Entity.getEntityFields(MlModel.class);
@GET
@Valid
@ -143,8 +142,7 @@ public class MlModelResource extends EntityResource<MlModel, MlModelRepository>
@DefaultValue("non-deleted")
Include include)
throws IOException, GeneralSecurityException, ParseException {
ListFilter filter = new ListFilter();
filter.addQueryParam("include", include.value());
ListFilter filter = new ListFilter(include);
return super.listInternal(uriInfo, securityContext, fieldsParam, filter, limitParam, before, after);
}
@ -255,7 +253,7 @@ public class MlModelResource extends EntityResource<MlModel, MlModelRepository>
}))
JsonPatch patch)
throws IOException, ParseException {
Fields fields = new Fields(ALLOWED_FIELDS, FIELDS);
Fields fields = getFields(FIELDS);
MlModel mlModel = dao.get(uriInfo, id, fields);
SecurityUtil.checkAdminRoleOrPermissions(
authorizer,

View File

@ -28,8 +28,6 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import javax.json.JsonPatch;
@ -67,6 +65,7 @@ import org.openmetadata.catalog.security.Authorizer;
import org.openmetadata.catalog.security.SecurityUtil;
import org.openmetadata.catalog.type.EntityHistory;
import org.openmetadata.catalog.type.Include;
import org.openmetadata.catalog.util.EntityInterface;
import org.openmetadata.catalog.util.EntityUtil.Fields;
import org.openmetadata.catalog.util.RestUtil.DeleteResponse;
import org.openmetadata.catalog.util.RestUtil.PatchResponse;
@ -112,15 +111,8 @@ public class AirflowPipelineResource extends EntityResource<AirflowPipeline, Air
}
static final String FIELDS = FIELD_OWNER;
public static final List<String> ALLOWED_FIELDS;
static final String PIPELINE_STATUSES = "pipelineStatuses";
static {
List<String> list = new ArrayList<>();
list.addAll(Entity.getEntityFields(AirflowPipeline.class));
ALLOWED_FIELDS = Collections.unmodifiableList(list);
}
@GET
@Valid
@Operation(
@ -169,8 +161,7 @@ public class AirflowPipelineResource extends EntityResource<AirflowPipeline, Air
@DefaultValue("non-deleted")
Include include)
throws IOException, GeneralSecurityException, ParseException {
ListFilter filter = new ListFilter();
filter.addQueryParam("include", include.value()).addQueryParam("service", serviceParam);
ListFilter filter = new ListFilter(include).addQueryParam("service", serviceParam);
ResultList<AirflowPipeline> airflowPipelines =
super.listInternal(uriInfo, securityContext, fieldsParam, filter, limitParam, before, after);
if (fieldsParam != null && fieldsParam.contains(PIPELINE_STATUSES)) {
@ -268,7 +259,7 @@ public class AirflowPipelineResource extends EntityResource<AirflowPipeline, Air
@GET
@Path("/name/{fqn}")
@Operation(
summary = "Get a AirlfowPipeline by name",
summary = "Get a AirflowPipeline by name",
tags = "airflowPipelines",
description = "Get a ingestion by fully qualified name.",
responses = {
@ -349,14 +340,10 @@ public class AirflowPipelineResource extends EntityResource<AirflowPipeline, Air
}))
JsonPatch patch)
throws IOException, ParseException {
Fields fields = new Fields(ALLOWED_FIELDS, FIELDS);
AirflowPipeline airflowPipeline = dao.get(uriInfo, id, fields);
AirflowPipeline airflowPipeline = dao.get(uriInfo, id, getFields(FIELD_OWNER));
EntityInterface<AirflowPipeline> entityInterface = dao.getEntityInterface(airflowPipeline);
SecurityUtil.checkAdminRoleOrPermissions(
authorizer,
securityContext,
dao.getEntityInterface(airflowPipeline).getEntityReference(),
dao.getOriginalOwner(airflowPipeline),
patch);
authorizer, securityContext, entityInterface.getEntityReference(), entityInterface.getOwner(), patch);
PatchResponse<AirflowPipeline> response =
dao.patch(uriInfo, UUID.fromString(id), securityContext.getUserPrincipal().getName(), patch);
@ -405,7 +392,7 @@ public class AirflowPipelineResource extends EntityResource<AirflowPipeline, Air
public AirflowPipeline triggerIngestion(
@Context UriInfo uriInfo, @PathParam("id") String id, @Context SecurityContext securityContext)
throws IOException, ParseException {
Fields fields = new Fields(ALLOWED_FIELDS, FIELD_OWNER);
Fields fields = getFields(FIELD_OWNER);
AirflowPipeline pipeline = dao.get(uriInfo, id, fields);
airflowRESTClient.runPipeline(pipeline.getName());
return addHref(uriInfo, dao.get(uriInfo, id, fields));
@ -424,7 +411,7 @@ public class AirflowPipelineResource extends EntityResource<AirflowPipeline, Air
public Response delete(@Context UriInfo uriInfo, @Context SecurityContext securityContext, @PathParam("id") String id)
throws IOException, ParseException {
SecurityUtil.checkAdminOrBotRole(authorizer, securityContext);
Fields fields = new Fields(ALLOWED_FIELDS, FIELD_OWNER);
Fields fields = getFields(FIELD_OWNER);
AirflowPipeline pipeline = dao.get(uriInfo, id, fields);
airflowRESTClient.deletePipeline(pipeline.getName());
DeleteResponse<AirflowPipeline> response = dao.delete(securityContext.getUserPrincipal().getName(), id);

View File

@ -100,7 +100,6 @@ public class PipelineResource extends EntityResource<Pipeline, PipelineRepositor
}
static final String FIELDS = "owner,tasks,pipelineStatus,followers,tags";
public static final List<String> ALLOWED_FIELDS = Entity.getEntityFields(Pipeline.class);
@GET
@Valid
@ -149,8 +148,7 @@ public class PipelineResource extends EntityResource<Pipeline, PipelineRepositor
@DefaultValue("non-deleted")
Include include)
throws IOException, GeneralSecurityException, ParseException {
ListFilter filter = new ListFilter();
filter.addQueryParam("include", include.value()).addQueryParam("service", serviceParam);
ListFilter filter = new ListFilter(include).addQueryParam("service", serviceParam);
return super.listInternal(uriInfo, securityContext, fieldsParam, filter, limitParam, before, after);
}
@ -310,7 +308,7 @@ public class PipelineResource extends EntityResource<Pipeline, PipelineRepositor
}))
JsonPatch patch)
throws IOException, ParseException {
Fields fields = new Fields(ALLOWED_FIELDS, FIELDS);
Fields fields = getFields(FIELDS);
Pipeline pipeline = dao.get(uriInfo, id, fields);
SecurityUtil.checkAdminRoleOrPermissions(
authorizer,

View File

@ -110,7 +110,6 @@ public class PolicyResource extends EntityResource<Policy, PolicyRepository> {
}
public static final String FIELDS = "owner,location";
public static final List<String> ALLOWED_FIELDS = Entity.getEntityFields(Policy.class);
@GET
@Valid
@ -154,8 +153,7 @@ public class PolicyResource extends EntityResource<Policy, PolicyRepository> {
@DefaultValue("non-deleted")
Include include)
throws IOException, GeneralSecurityException, ParseException {
ListFilter filter = new ListFilter();
filter.addQueryParam("include", include.value());
ListFilter filter = new ListFilter(include);
return super.listInternal(uriInfo, securityContext, fieldsParam, filter, limitParam, before, after);
}
@ -313,7 +311,7 @@ public class PolicyResource extends EntityResource<Policy, PolicyRepository> {
}))
JsonPatch patch)
throws IOException, ParseException {
Fields fields = new Fields(ALLOWED_FIELDS, FIELD_OWNER);
Fields fields = getFields(FIELD_OWNER);
Policy policy = dao.get(uriInfo, id, fields);
SecurityUtil.checkAdminRoleOrPermissions(authorizer, securityContext, dao.getOwnerReference(policy));

View File

@ -39,7 +39,6 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;
import org.openmetadata.catalog.Entity;
import org.openmetadata.catalog.entity.data.Report;
import org.openmetadata.catalog.jdbi3.CollectionDAO;
import org.openmetadata.catalog.jdbi3.ListFilter;
@ -76,7 +75,6 @@ public class ReportResource extends EntityResource<Report, ReportRepository> {
}
static final String FIELDS = "owner,usageSummary";
public static final List<String> ALLOWED_FIELDS = Entity.getEntityFields(Report.class);
@GET
@Operation(
@ -97,7 +95,7 @@ public class ReportResource extends EntityResource<Report, ReportRepository> {
@QueryParam("fields")
String fieldsParam)
throws IOException, GeneralSecurityException, ParseException {
Fields fields = new Fields(ALLOWED_FIELDS, fieldsParam);
Fields fields = getFields(fieldsParam);
ListFilter filter = new ListFilter();
return dao.listAfter(uriInfo, fields, filter, 10000, null);
}

View File

@ -70,7 +70,6 @@ public class DashboardServiceResource extends EntityResource<DashboardService, D
public static final String COLLECTION_PATH = "v1/services/dashboardServices";
static final String FIELDS = FIELD_OWNER;
public static final List<String> ALLOWED_FIELDS = Entity.getEntityFields(DashboardService.class);
@Override
public DashboardService addHref(UriInfo uriInfo, DashboardService service) {
@ -130,8 +129,7 @@ public class DashboardServiceResource extends EntityResource<DashboardService, D
@DefaultValue("non-deleted")
Include include)
throws IOException, GeneralSecurityException, ParseException {
ListFilter filter = new ListFilter();
filter.addQueryParam("include", include.value());
ListFilter filter = new ListFilter(include);
return super.listInternal(uriInfo, null, fieldsParam, filter, limitParam, before, after);
}
@ -289,7 +287,7 @@ public class DashboardServiceResource extends EntityResource<DashboardService, D
schema = @Schema(implementation = CreateDashboardService.class))),
@ApiResponse(responseCode = "400", description = "Bad request")
})
public Response update(
public Response createOrUpdate(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateDashboardService update)
throws IOException, ParseException {
DashboardService service = getService(update, securityContext);

View File

@ -79,7 +79,6 @@ public class DatabaseServiceResource extends EntityResource<DatabaseService, Dat
public static final String COLLECTION_PATH = "v1/services/databaseServices/";
static final String FIELDS = "airflowPipeline,owner";
public static final List<String> ALLOWED_FIELDS = Entity.getEntityFields(DatabaseService.class);
private final Fernet fernet;
@Override
@ -140,12 +139,10 @@ public class DatabaseServiceResource extends EntityResource<DatabaseService, Dat
Include include)
throws IOException, GeneralSecurityException, ParseException {
RestUtil.validateCursors(before, after);
EntityUtil.Fields fields = new EntityUtil.Fields(ALLOWED_FIELDS, fieldsParam);
EntityUtil.Fields fields = getFields(fieldsParam);
ResultList<DatabaseService> dbServices;
ListFilter filter = new ListFilter();
filter.addQueryParam("include", include.value());
ListFilter filter = new ListFilter(include);
if (before != null) {
dbServices = dao.listBefore(uriInfo, fields, filter, limitParam, before);
} else {
@ -311,9 +308,9 @@ public class DatabaseServiceResource extends EntityResource<DatabaseService, Dat
@PUT
@Operation(
summary = "Update a database service",
summary = "Update database service",
tags = "services",
description = "Update an existing database service identified by `id`.",
description = "Update an existing or create a new database service.",
responses = {
@ApiResponse(
responseCode = "200",
@ -324,7 +321,7 @@ public class DatabaseServiceResource extends EntityResource<DatabaseService, Dat
schema = @Schema(implementation = CreateDatabaseService.class))),
@ApiResponse(responseCode = "400", description = "Bad request")
})
public Response update(
public Response createOrUpdate(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateDatabaseService update)
throws IOException, ParseException {
DatabaseService service = getService(update, securityContext);

View File

@ -70,7 +70,6 @@ public class MessagingServiceResource extends EntityResource<MessagingService, M
public static final String COLLECTION_PATH = "v1/services/messagingServices/";
public static final String FIELDS = FIELD_OWNER;
public static final List<String> ALLOWED_FIELDS = Entity.getEntityFields(MessagingService.class);
@Override
public MessagingService addHref(UriInfo uriInfo, MessagingService service) {
@ -133,8 +132,7 @@ public class MessagingServiceResource extends EntityResource<MessagingService, M
@DefaultValue("non-deleted")
Include include)
throws IOException, ParseException, GeneralSecurityException {
ListFilter filter = new ListFilter();
filter.addQueryParam("include", include.value());
ListFilter filter = new ListFilter(include);
return super.listInternal(uriInfo, null, fieldsParam, filter, limitParam, before, after);
}
@ -279,7 +277,7 @@ public class MessagingServiceResource extends EntityResource<MessagingService, M
@PUT
@Operation(
summary = "Update a messaging service",
summary = "Update messaging service",
tags = "services",
description = "Create a new messaging service or Update an existing messaging service identified by `id`.",
responses = {
@ -292,7 +290,7 @@ public class MessagingServiceResource extends EntityResource<MessagingService, M
schema = @Schema(implementation = CreateMessagingService.class))),
@ApiResponse(responseCode = "400", description = "Bad request")
})
public Response update(
public Response createOrUpdate(
@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@Parameter(description = "Id of the messaging service", schema = @Schema(type = "string")) @PathParam("id")

View File

@ -70,7 +70,6 @@ public class PipelineServiceResource extends EntityResource<PipelineService, Pip
public static final String COLLECTION_PATH = "v1/services/pipelineServices/";
static final String FIELDS = FIELD_OWNER;
public static final List<String> ALLOWED_FIELDS = Entity.getEntityFields(PipelineService.class);
@Override
public PipelineService addHref(UriInfo uriInfo, PipelineService service) {
@ -133,8 +132,7 @@ public class PipelineServiceResource extends EntityResource<PipelineService, Pip
@DefaultValue("non-deleted")
Include include)
throws IOException, GeneralSecurityException, ParseException {
ListFilter filter = new ListFilter();
filter.addQueryParam("include", include.value());
ListFilter filter = new ListFilter(include);
return super.listInternal(uriInfo, securityContext, fieldsParam, filter, limitParam, before, after);
}
@ -279,7 +277,7 @@ public class PipelineServiceResource extends EntityResource<PipelineService, Pip
@PUT
@Operation(
summary = "Update a pipeline service",
summary = "Update pipeline service",
tags = "services",
description = "Create a new pipeline service or update an existing pipeline service identified by `id`.",
responses = {
@ -292,7 +290,7 @@ public class PipelineServiceResource extends EntityResource<PipelineService, Pip
schema = @Schema(implementation = CreatePipelineService.class))),
@ApiResponse(responseCode = "400", description = "Bad request")
})
public Response update(
public Response createOrUpdate(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreatePipelineService update)
throws IOException, ParseException {
PipelineService service = getService(update, securityContext);

View File

@ -70,7 +70,6 @@ public class StorageServiceResource extends EntityResource<StorageService, Stora
public static final String COLLECTION_PATH = "v1/services/storageServices/";
static final String FIELDS = FIELD_OWNER;
public static final List<String> ALLOWED_FIELDS = Entity.getEntityFields(StorageService.class);
@Override
public StorageService addHref(UriInfo uriInfo, StorageService service) {
@ -133,8 +132,7 @@ public class StorageServiceResource extends EntityResource<StorageService, Stora
@DefaultValue("non-deleted")
Include include)
throws IOException, GeneralSecurityException, ParseException {
ListFilter filter = new ListFilter();
filter.addQueryParam("include", include.value());
ListFilter filter = new ListFilter(include);
return super.listInternal(uriInfo, securityContext, fieldsParam, filter, limitParam, before, after);
}
@ -277,7 +275,7 @@ public class StorageServiceResource extends EntityResource<StorageService, Stora
@PUT
@Operation(
summary = "Update a storage service",
summary = "Update storage service",
tags = "services",
description = "Update an existing storage service identified by `id`.",
responses = {
@ -288,7 +286,7 @@ public class StorageServiceResource extends EntityResource<StorageService, Stora
@Content(mediaType = "application/json", schema = @Schema(implementation = StorageService.class))),
@ApiResponse(responseCode = "400", description = "Bad request")
})
public Response update(
public Response createOrUpdate(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateStorageService update)
throws IOException, ParseException {
StorageService service = getService(update, securityContext);

View File

@ -101,7 +101,6 @@ public class RoleResource extends EntityResource<Role, RoleRepository> {
}
public static final String FIELDS = "policy,teams,users";
public static final List<String> ALLOWED_FIELDS = Entity.getEntityFields(Role.class);
@GET
@Valid
@ -148,8 +147,8 @@ public class RoleResource extends EntityResource<Role, RoleRepository> {
Include include)
throws IOException, GeneralSecurityException, ParseException {
RestUtil.validateCursors(before, after);
Fields fields = new Fields(ALLOWED_FIELDS, fieldsParam);
ListFilter filter = new ListFilter().addQueryParam("include", include.value());
Fields fields = getFields(fieldsParam);
ListFilter filter = new ListFilter(include);
ResultList<Role> roles;
if (defaultParam) {
@ -213,8 +212,7 @@ public class RoleResource extends EntityResource<Role, RoleRepository> {
@DefaultValue("non-deleted")
Include include)
throws IOException, ParseException {
Fields fields = new Fields(ALLOWED_FIELDS, fieldsParam);
return addHref(uriInfo, dao.get(uriInfo, id, fields, include));
return getInternal(uriInfo, securityContext, id, fieldsParam, include);
}
@GET
@ -301,7 +299,7 @@ public class RoleResource extends EntityResource<Role, RoleRepository> {
@PUT
@Operation(
summary = "Create or Update a role",
summary = "Update role",
tags = "roles",
description = "Create or Update a role.",
responses = {

View File

@ -59,7 +59,7 @@ import org.openmetadata.catalog.security.Authorizer;
import org.openmetadata.catalog.security.SecurityUtil;
import org.openmetadata.catalog.type.EntityHistory;
import org.openmetadata.catalog.type.Include;
import org.openmetadata.catalog.util.EntityUtil.Fields;
import org.openmetadata.catalog.util.EntityInterface;
import org.openmetadata.catalog.util.RestUtil;
import org.openmetadata.catalog.util.RestUtil.DeleteResponse;
import org.openmetadata.catalog.util.RestUtil.PatchResponse;
@ -96,7 +96,6 @@ public class TeamResource extends EntityResource<Team, TeamRepository> {
}
static final String FIELDS = "owner,profile,users,owns,defaultRoles";
public static final List<String> ALLOWED_FIELDS = Entity.getEntityFields(Team.class);
@GET
@Valid
@ -140,8 +139,7 @@ public class TeamResource extends EntityResource<Team, TeamRepository> {
@DefaultValue("non-deleted")
Include include)
throws IOException, GeneralSecurityException, ParseException {
ListFilter filter = new ListFilter();
filter.addQueryParam("include", include.value());
ListFilter filter = new ListFilter(include);
return super.listInternal(uriInfo, securityContext, fieldsParam, filter, limitParam, before, after);
}
@ -281,7 +279,7 @@ public class TeamResource extends EntityResource<Team, TeamRepository> {
@PUT
@Operation(
summary = "Create or Update a team",
summary = "Update team",
tags = "teams",
description = "Create or Update a team.",
responses = {
@ -291,7 +289,7 @@ public class TeamResource extends EntityResource<Team, TeamRepository> {
content = @Content(mediaType = "application/json", schema = @Schema(implementation = CreateTeam.class))),
@ApiResponse(responseCode = "400", description = "Bad request")
})
public Response createOrUpdateTeam(
public Response createOrUpdate(
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateTeam ct)
throws IOException, ParseException {
Team team = getTeam(ct, securityContext);
@ -323,14 +321,10 @@ public class TeamResource extends EntityResource<Team, TeamRepository> {
}))
JsonPatch patch)
throws IOException, ParseException {
Fields fields = new Fields(ALLOWED_FIELDS, FIELDS);
Team team = dao.get(uriInfo, id, fields);
Team team = dao.get(uriInfo, id, getFields(Entity.FIELD_OWNER));
EntityInterface<Team> entityInterface = dao.getEntityInterface(team);
SecurityUtil.checkAdminRoleOrPermissions(
authorizer,
securityContext,
dao.getEntityInterface(team).getEntityReference(),
dao.getOriginalOwner(team),
patch);
authorizer, securityContext, entityInterface.getEntityReference(), entityInterface.getOwner(), patch);
PatchResponse<Team> response =
dao.patch(uriInfo, UUID.fromString(id), securityContext.getUserPrincipal().getName(), patch);
addHref(uriInfo, response.getEntity());

View File

@ -101,7 +101,6 @@ public class UserResource extends EntityResource<User, UserRepository> {
}
static final String FIELDS = "profile,roles,teams,follows,owns";
public static final List<String> ALLOWED_FIELDS = Entity.getEntityFields(User.class);
@GET
@Valid
@ -148,8 +147,7 @@ public class UserResource extends EntityResource<User, UserRepository> {
@DefaultValue("non-deleted")
Include include)
throws IOException, GeneralSecurityException, ParseException {
ListFilter filter = new ListFilter();
filter.addQueryParam("include", include.value()).addQueryParam("team", teamParam);
ListFilter filter = new ListFilter(include).addQueryParam("team", teamParam);
return super.listInternal(uriInfo, securityContext, fieldsParam, filter, limitParam, before, after);
}
@ -262,7 +260,7 @@ public class UserResource extends EntityResource<User, UserRepository> {
@QueryParam("fields")
String fieldsParam)
throws IOException, ParseException {
Fields fields = new Fields(ALLOWED_FIELDS, fieldsParam);
Fields fields = getFields(fieldsParam);
String currentUserName = securityContext.getUserPrincipal().getName();
User user = dao.getByName(uriInfo, currentUserName, fields);
return addHref(uriInfo, user);
@ -321,7 +319,7 @@ public class UserResource extends EntityResource<User, UserRepository> {
@PUT
@Operation(
summary = "Create or Update a user",
summary = "Update user",
tags = "users",
description = "Create or Update a user.",
responses = {
@ -376,7 +374,7 @@ public class UserResource extends EntityResource<User, UserRepository> {
}
}
}
User user = dao.get(uriInfo, id, new Fields(ALLOWED_FIELDS, null));
User user = dao.get(uriInfo, id, Fields.EMPTY_FIELDS);
SecurityUtil.checkAdminRoleOrPermissions(
authorizer, securityContext, new UserEntityInterface(user).getEntityReference());
PatchResponse<User> response =

View File

@ -101,7 +101,6 @@ public class TopicResource extends EntityResource<Topic, TopicRepository> {
}
static final String FIELDS = "owner,followers,tags";
public static final List<String> ALLOWED_FIELDS = Entity.getEntityFields(Topic.class);
@GET
@Operation(
@ -149,8 +148,7 @@ public class TopicResource extends EntityResource<Topic, TopicRepository> {
@DefaultValue("non-deleted")
Include include)
throws IOException, GeneralSecurityException, ParseException {
ListFilter filter = new ListFilter();
filter.addQueryParam("include", include.value()).addQueryParam("service", serviceParam);
ListFilter filter = new ListFilter(include).addQueryParam("service", serviceParam);
return super.listInternal(uriInfo, null, fieldsParam, filter, limitParam, before, after);
}
@ -309,7 +307,7 @@ public class TopicResource extends EntityResource<Topic, TopicRepository> {
}))
JsonPatch patch)
throws IOException, ParseException {
Fields fields = new Fields(ALLOWED_FIELDS, FIELD_OWNER);
Fields fields = getFields(FIELD_OWNER);
Topic topic = dao.get(uriInfo, id, fields);
SecurityUtil.checkAdminRoleOrPermissions(
authorizer,
@ -326,7 +324,7 @@ public class TopicResource extends EntityResource<Topic, TopicRepository> {
@PUT
@Operation(
summary = "Create or update topic",
summary = "Update topic",
tags = "topics",
description = "Create a topic, it it does not exist or update an existing topic.",
responses = {

View File

@ -34,11 +34,12 @@ import org.openmetadata.catalog.jdbi3.CollectionDAO;
import org.openmetadata.catalog.jdbi3.RoleRepository;
import org.openmetadata.catalog.jdbi3.TeamRepository;
import org.openmetadata.catalog.jdbi3.UserRepository;
import org.openmetadata.catalog.resources.teams.UserResource;
import org.openmetadata.catalog.security.policyevaluator.PolicyEvaluator;
import org.openmetadata.catalog.type.EntityReference;
import org.openmetadata.catalog.type.Include;
import org.openmetadata.catalog.type.MetadataOperation;
import org.openmetadata.catalog.util.EntityUtil;
import org.openmetadata.catalog.util.EntityUtil.Fields;
import org.openmetadata.catalog.util.RestUtil;
@Slf4j
@ -74,10 +75,9 @@ public class DefaultAuthorizer implements Authorizer {
private void mayBeAddAdminUsers() {
LOG.debug("Checking user entries for admin users");
EntityUtil.Fields fields = new EntityUtil.Fields(UserResource.ALLOWED_FIELDS, FIELDS_PARAM);
for (String adminUser : adminUsers) {
try {
User user = userRepository.getByName(null, adminUser, fields);
User user = userRepository.getByName(null, adminUser, Fields.EMPTY_FIELDS);
if (user != null && (user.getIsAdmin() == null || !user.getIsAdmin())) {
user.setIsAdmin(true);
}
@ -100,10 +100,9 @@ public class DefaultAuthorizer implements Authorizer {
private void mayBeAddBotUsers() {
LOG.debug("Checking user entries for bot users");
EntityUtil.Fields fields = new EntityUtil.Fields(UserResource.ALLOWED_FIELDS, FIELDS_PARAM);
for (String botUser : botUsers) {
try {
User user = userRepository.getByName(null, botUser, fields);
User user = userRepository.getByName(null, botUser, Fields.EMPTY_FIELDS);
if (user != null && (user.getIsBot() == null || !user.getIsBot())) {
user.setIsBot(true);
}
@ -153,7 +152,8 @@ public class DefaultAuthorizer implements Authorizer {
return policyEvaluator.hasPermission(user, null, operation);
}
Object entity = Entity.getEntity(entityReference, new EntityUtil.Fields(List.of("tags", FIELD_OWNER)));
Object entity =
Entity.getEntity(entityReference, new EntityUtil.Fields(List.of("tags", FIELD_OWNER)), Include.NON_DELETED);
EntityReference owner = Entity.getEntityInterface(entity).getOwner();
if (Entity.shouldHaveOwner(entityReference.getType()) && owner != null && isOwnedByUser(user, owner)) {
@ -180,7 +180,8 @@ public class DefaultAuthorizer implements Authorizer {
if (entityReference == null) {
return policyEvaluator.getAllowedOperations(user, null);
}
Object entity = Entity.getEntity(entityReference, new EntityUtil.Fields(List.of("tags", FIELD_OWNER)));
Object entity =
Entity.getEntity(entityReference, new EntityUtil.Fields(List.of("tags", FIELD_OWNER)), Include.NON_DELETED);
EntityReference owner = Entity.getEntityInterface(entity).getOwner();
if (owner == null || isOwnedByUser(user, owner)) {
// Entity does not have an owner or is owned by the user - allow all operations.
@ -213,9 +214,8 @@ public class DefaultAuthorizer implements Authorizer {
public boolean isAdmin(AuthenticationContext ctx) {
validateAuthenticationContext(ctx);
String userName = SecurityUtil.getUserName(ctx);
EntityUtil.Fields fields = new EntityUtil.Fields(UserResource.ALLOWED_FIELDS, FIELDS_PARAM);
try {
User user = userRepository.getByName(null, userName, fields);
User user = userRepository.getByName(null, userName, Fields.EMPTY_FIELDS);
if (user.getIsAdmin() == null) {
return false;
}
@ -229,9 +229,8 @@ public class DefaultAuthorizer implements Authorizer {
public boolean isBot(AuthenticationContext ctx) {
validateAuthenticationContext(ctx);
String userName = SecurityUtil.getUserName(ctx);
EntityUtil.Fields fields = new EntityUtil.Fields(UserResource.ALLOWED_FIELDS, FIELDS_PARAM);
try {
User user = userRepository.getByName(null, userName, fields);
User user = userRepository.getByName(null, userName, Fields.EMPTY_FIELDS);
if (user.getIsBot() == null) {
return false;
}
@ -245,9 +244,8 @@ public class DefaultAuthorizer implements Authorizer {
public boolean isOwner(AuthenticationContext ctx, EntityReference owner) {
validateAuthenticationContext(ctx);
String userName = SecurityUtil.getUserName(ctx);
EntityUtil.Fields fields = new EntityUtil.Fields(UserResource.ALLOWED_FIELDS, FIELDS_PARAM);
try {
User user = userRepository.getByName(null, userName, fields);
User user = userRepository.getByName(null, userName, Fields.EMPTY_FIELDS);
if (owner == null) {
return false;
}
@ -265,7 +263,7 @@ public class DefaultAuthorizer implements Authorizer {
private User getUserFromAuthenticationContext(AuthenticationContext ctx) throws IOException, ParseException {
String userName = SecurityUtil.getUserName(ctx);
EntityUtil.Fields fields = new EntityUtil.Fields(UserResource.ALLOWED_FIELDS, FIELDS_PARAM);
EntityUtil.Fields fields = userRepository.getFields(FIELDS_PARAM);
return userRepository.getByName(null, userName, fields);
}

View File

@ -28,21 +28,20 @@ import org.openmetadata.catalog.jdbi3.CollectionDAO;
import org.openmetadata.catalog.jdbi3.RoleRepository;
import org.openmetadata.catalog.jdbi3.TeamRepository;
import org.openmetadata.catalog.jdbi3.UserRepository;
import org.openmetadata.catalog.resources.teams.UserResource;
import org.openmetadata.catalog.type.EntityReference;
import org.openmetadata.catalog.type.MetadataOperation;
import org.openmetadata.catalog.util.EntityUtil;
import org.openmetadata.catalog.util.EntityUtil.Fields;
import org.openmetadata.catalog.util.RestUtil;
@Slf4j
public class NoopAuthorizer implements Authorizer {
private static final String FIELDS_PARAM = "roles,teams";
private UserRepository userRepository;
@Override
public void init(AuthorizerConfiguration config, Jdbi jdbi) {
CollectionDAO collectionDAO = jdbi.onDemand(CollectionDAO.class);
this.userRepository = new UserRepository(collectionDAO);
// TODO: fixme
// RoleRepository and TeamRepository needs to be instantiated for Entity.DAO_MAP to populated.
// As we create default admin/bots we need to have RoleRepository and TeamRepository available in DAO_MAP.
// This needs to be handled better in future releases.
@ -84,10 +83,9 @@ public class NoopAuthorizer implements Authorizer {
}
private void addAnonymousUser() {
EntityUtil.Fields fields = new EntityUtil.Fields(UserResource.ALLOWED_FIELDS, FIELDS_PARAM);
String username = "anonymous";
try {
userRepository.getByName(null, username, fields);
userRepository.getByName(null, username, Fields.EMPTY_FIELDS);
} catch (EntityNotFoundException ex) {
User user =
new User()

View File

@ -885,7 +885,7 @@ public abstract class EntityResourceTest<T, K> extends CatalogApplicationTest {
final K request = createRequest(name, null, null, null);
T entity = createEntity(request, ADMIN_AUTH_HEADERS);
EntityInterface<T> entityInterface = getEntityInterface(entity);
String[] split = entityInterface.getFullyQualifiedName().split("\\/");
String[] split = entityInterface.getFullyQualifiedName().split("/");
String actualName = split[split.length - 1];
assertTrue(actualName.contains("foo.bar"));
}

View File

@ -1603,7 +1603,8 @@ public class TableResourceTest extends EntityResourceTest<Table, CreateTable> {
}
void assertFields(Table table, String fieldsParam) {
Fields fields = new Fields(TableResource.ALLOWED_FIELDS, fieldsParam);
// TODO cleanup
Fields fields = new Fields(Entity.getEntityFields(Table.class), fieldsParam);
if (fields.contains("usageSummary")) {
assertNotNull(table.getUsageSummary());

View File

@ -69,7 +69,7 @@ class PermissionsResourceTest extends CatalogApplicationTest {
@ParameterizedTest
@MethodSource("getPermissionsTestParams")
void get_permissiofns(String username, Map<MetadataOperation, Boolean> expectedOperations)
void get_permissions(String username, Map<MetadataOperation, Boolean> expectedOperations)
throws HttpResponseException {
WebTarget target = getResource("permissions");
Map<String, String> authHeaders = SecurityUtil.authHeaders(username + "@open-metadata.org");