diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/DashboardServiceRepository.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/DashboardServiceRepository.java index 83bd7ce157b..482813c6920 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/DashboardServiceRepository.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/DashboardServiceRepository.java @@ -42,6 +42,7 @@ public class DashboardServiceRepository extends EntityRepository "", UPDATE_FIELDS); fernet = Fernet.getInstance(); + this.allowEdits = true; } public void rotate() throws IOException { diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/EntityRepository.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/EntityRepository.java index 301788448ad..b0f3cf17985 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/EntityRepository.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/EntityRepository.java @@ -118,6 +118,7 @@ public abstract class EntityRepository { protected final boolean supportsTags; protected final boolean supportsOwner; protected final boolean supportsFollower; + protected boolean allowEdits = false; /** Fields that can be updated during PATCH operation */ private final Fields patchFields; @@ -370,14 +371,8 @@ public abstract class EntityRepository { return createNewEntity(entity); } - public final PutResponse createOrUpdate(UriInfo uriInfo, T updated) throws IOException, ParseException { - // By default, do not allow updates on original description or display names of entities - return createOrUpdate(uriInfo, updated, false); - } - @Transaction - public final PutResponse createOrUpdate(UriInfo uriInfo, T updated, boolean allowEdits) - throws IOException, ParseException { + public final PutResponse createOrUpdate(UriInfo uriInfo, T updated) throws IOException, ParseException { prepare(updated); EntityInterface updatedInterface = getEntityInterface(updated); @@ -397,7 +392,7 @@ public abstract class EntityRepository { // Update the attributes and relationships of an entity EntityUpdater entityUpdater = getUpdater(original, updated, Operation.PUT); - entityUpdater.update(allowEdits); + entityUpdater.update(); String change = entityUpdater.fieldsChanged() ? RestUtil.ENTITY_UPDATED : RestUtil.ENTITY_NO_CHANGE; return new PutResponse<>(Status.OK, withHref(uriInfo, updated), change); } @@ -459,10 +454,6 @@ public abstract class EntityRepository { } @Transaction - public final DeleteResponse delete(String updatedBy, String id) throws IOException, ParseException { - return delete(updatedBy, id, false, false); - } - public final DeleteResponse delete(String updatedBy, String id, boolean recursive) throws IOException, ParseException { return delete(updatedBy, id, recursive, false); @@ -572,7 +563,7 @@ public abstract class EntityRepository { } } - public final EntityReference getOriginalOwner(T entity) throws IOException, ParseException { + public EntityReference getOriginalOwner(T entity) throws IOException, ParseException { if (!supportsOwner) { return null; } @@ -884,19 +875,15 @@ public abstract class EntityRepository { this.operation = operation; } - public final void update() throws IOException, ParseException { - update(false); - } - /** Compare original and updated entities and perform updates. Update the entity version and track changes. */ - public final void update(boolean allowEdits) throws IOException, ParseException { + public final void update() throws IOException, ParseException { if (operation.isDelete()) { // DELETE Operation updateDeleted(); } else { // PUT or PATCH operations updated.setId(original.getId()); updateDeleted(); - updateDescription(allowEdits); - updateDisplayName(allowEdits); + updateDescription(); + updateDisplayName(); updateOwner(); updateTags(updated.getFullyQualifiedName(), "tags", original.getTags(), updated.getTags()); entitySpecificUpdate(); @@ -910,7 +897,7 @@ public abstract class EntityRepository { // Default implementation. Override this to add any entity specific field updates } - private void updateDescription(boolean allowEdits) throws JsonProcessingException { + private void updateDescription() throws JsonProcessingException { if (operation.isPut() && original.getDescription() != null && !original.getDescription().isEmpty() @@ -939,7 +926,7 @@ public abstract class EntityRepository { } } - private void updateDisplayName(boolean allowEdits) throws JsonProcessingException { + private void updateDisplayName() throws JsonProcessingException { if (operation.isPut() && original.getDisplayName() != null && !original.getDisplayName().isEmpty() diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/GlossaryRepository.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/GlossaryRepository.java index 988dc23add9..e5bb4323a79 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/GlossaryRepository.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/GlossaryRepository.java @@ -25,7 +25,6 @@ import java.net.URI; import java.text.ParseException; import java.util.List; import java.util.UUID; -import org.jdbi.v3.sqlobject.transaction.Transaction; import org.openmetadata.catalog.Entity; import org.openmetadata.catalog.entity.data.Glossary; import org.openmetadata.catalog.resources.glossary.GlossaryResource; @@ -54,11 +53,6 @@ public class GlossaryRepository extends EntityRepository { UPDATE_FIELDS); } - @Transaction - public EntityReference getOwnerReference(Glossary glossary) throws IOException { - return EntityUtil.populateOwner(daoCollection.userDAO(), daoCollection.teamDAO(), glossary.getOwner()); - } - @Override public Glossary setFields(Glossary glossary, Fields fields) throws IOException, ParseException { glossary.setOwner(fields.contains(FIELD_OWNER) ? getOwner(glossary) : null); diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/MessagingServiceRepository.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/MessagingServiceRepository.java index 906c6bb6804..fd21f017b38 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/MessagingServiceRepository.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/MessagingServiceRepository.java @@ -43,6 +43,7 @@ public class MessagingServiceRepository extends EntityRepository dao, "", UPDATE_FIELDS); + this.allowEdits = true; } @Override diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/StorageServiceRepository.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/StorageServiceRepository.java index 5e5166a637f..32682177e8b 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/StorageServiceRepository.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/StorageServiceRepository.java @@ -39,6 +39,7 @@ public class StorageServiceRepository extends EntityRepository { dao, "", UPDATE_FIELDS); + this.allowEdits = true; } @Override diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/UserRepository.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/UserRepository.java index ddf2d85fde3..a9780b0b897 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/UserRepository.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/UserRepository.java @@ -60,6 +60,12 @@ public class UserRepository extends EntityRepository { return new UserEntityInterface(entity); } + @Override + public EntityReference getOriginalOwner(User entity) throws IOException, ParseException { + // For User entity, the entity and the owner are the same + return getEntityInterface(entity).getEntityReference(); + } + /** Ensures that the default roles are added for POST, PUT and PATCH operations. */ @Override public void prepare(User user) throws IOException, ParseException { @@ -84,7 +90,7 @@ public class UserRepository extends EntityRepository { List defaultRoles = new ArrayList<>(); for (EntityReference teamRef : teamsRef) { Team team = Entity.getEntity(teamRef, new Fields(List.of("defaultRoles")), Include.NON_DELETED); - if (team != null && team.getDefaultRoles() != null) { + if (team.getDefaultRoles() != null) { defaultRoles.addAll(team.getDefaultRoles()); } } diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/EntityResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/EntityResource.java index e1c578b089a..f1d4db9ca03 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/EntityResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/EntityResource.java @@ -1,29 +1,41 @@ package org.openmetadata.catalog.resources; +import static org.openmetadata.catalog.Entity.FIELD_OWNER; import static org.openmetadata.common.utils.CommonUtil.listOrEmpty; import java.io.IOException; import java.security.GeneralSecurityException; import java.text.ParseException; import java.util.List; +import java.util.UUID; +import javax.json.JsonPatch; +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.jdbi3.EntityRepository; import org.openmetadata.catalog.jdbi3.ListFilter; import org.openmetadata.catalog.security.Authorizer; +import org.openmetadata.catalog.security.SecurityUtil; +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; +import org.openmetadata.catalog.util.RestUtil.PatchResponse; +import org.openmetadata.catalog.util.RestUtil.PutResponse; import org.openmetadata.catalog.util.ResultList; public abstract class EntityResource> { protected final List allowedFields; protected final K dao; protected final Authorizer authorizer; + private final boolean supportsOwner; public EntityResource(Class entityClass, K repository, Authorizer authorizer) { allowedFields = Entity.getEntityFields(entityClass); + supportsOwner = allowedFields.contains(FIELD_OWNER); this.dao = repository; this.authorizer = authorizer; } @@ -72,4 +84,41 @@ public abstract class EntityResource> { Fields fields = getFields(fieldsParam); return addHref(uriInfo, dao.getByName(uriInfo, name, fields, include)); } + + public Response create(UriInfo uriInfo, SecurityContext securityContext, T entity, int flags) + throws IOException, ParseException { + SecurityUtil.authorizeAdmin(authorizer, securityContext, flags); + entity = addHref(uriInfo, dao.create(uriInfo, entity)); + EntityInterface entityInterface = dao.getEntityInterface(entity); + return Response.created(entityInterface.getHref()).entity(entity).build(); + } + + public Response createOrUpdate(UriInfo uriInfo, SecurityContext securityContext, T entity, int checkFlags) + throws IOException, ParseException { + EntityReference owner = SecurityUtil.checkOwner(checkFlags) ? dao.getOriginalOwner(entity) : null; + SecurityUtil.authorize(authorizer, securityContext, null, owner, checkFlags); + PutResponse response = dao.createOrUpdate(uriInfo, entity); + addHref(uriInfo, response.getEntity()); + return response.toResponse(); + } + + public Response patchInternal(UriInfo uriInfo, SecurityContext securityContext, String id, JsonPatch patch) + throws IOException, ParseException { + T entity = dao.get(uriInfo, id, supportsOwner ? getFields(FIELD_OWNER) : Fields.EMPTY_FIELDS); + EntityInterface entityInterface = dao.getEntityInterface(entity); + SecurityUtil.checkAdminRoleOrPermissions( + authorizer, securityContext, entityInterface.getEntityReference(), entityInterface.getOwner(), patch); + PatchResponse response = + dao.patch(uriInfo, UUID.fromString(id), securityContext.getUserPrincipal().getName(), patch); + addHref(uriInfo, response.getEntity()); + return response.toResponse(); + } + + public Response delete(UriInfo uriInfo, SecurityContext securityContext, String id, boolean recursive, int checkFlags) + throws IOException, ParseException { + SecurityUtil.authorizeAdmin(authorizer, securityContext, checkFlags); + DeleteResponse response = dao.delete(securityContext.getUserPrincipal().getName(), id, recursive); + addHref(uriInfo, response.getEntity()); + return response.toResponse(); + } } diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/bots/BotsResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/bots/BotsResource.java index 2ffd9900e77..1486b76bd5a 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/bots/BotsResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/bots/BotsResource.java @@ -13,6 +13,8 @@ package org.openmetadata.catalog.resources.bots; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; + import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -46,7 +48,6 @@ import org.openmetadata.catalog.jdbi3.ListFilter; import org.openmetadata.catalog.resources.Collection; import org.openmetadata.catalog.resources.EntityResource; import org.openmetadata.catalog.security.Authorizer; -import org.openmetadata.catalog.security.SecurityUtil; import org.openmetadata.catalog.util.EntityUtil.Fields; import org.openmetadata.catalog.util.ResultList; @@ -130,11 +131,9 @@ public class BotsResource extends EntityResource { }) public Response create(@Context UriInfo uriInfo, @Context SecurityContext securityContext, Bots bot) throws IOException, ParseException { - SecurityUtil.checkAdminRole(authorizer, securityContext); bot.withId(UUID.randomUUID()) .withUpdatedBy(securityContext.getUserPrincipal().getName()) .withUpdatedAt(System.currentTimeMillis()); - dao.create(uriInfo, bot); - return Response.created(bot.getHref()).entity(bot).build(); + return create(uriInfo, securityContext, bot, ADMIN); } } diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/charts/ChartResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/charts/ChartResource.java index 305c5ba6fe3..acc8d0eab2a 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/charts/ChartResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/charts/ChartResource.java @@ -13,6 +13,10 @@ package org.openmetadata.catalog.resources.charts; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; +import static org.openmetadata.catalog.security.SecurityUtil.OWNER; + import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.ExternalDocumentation; import io.swagger.v3.oas.annotations.Operation; @@ -56,15 +60,9 @@ import org.openmetadata.catalog.jdbi3.ListFilter; import org.openmetadata.catalog.resources.Collection; 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.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; -import org.openmetadata.catalog.util.RestUtil.PatchResponse; -import org.openmetadata.catalog.util.RestUtil.PutResponse; import org.openmetadata.catalog.util.ResultList; @Path("/v1/charts") @@ -275,10 +273,8 @@ public class ChartResource extends EntityResource { }) public Response create(@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateChart create) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); Chart chart = getChart(securityContext, create); - chart = addHref(uriInfo, dao.create(uriInfo, chart)); - return Response.created(chart.getHref()).entity(chart).build(); + return create(uriInfo, securityContext, chart, ADMIN | BOT); } @PATCH @@ -289,7 +285,7 @@ public class ChartResource extends EntityResource { description = "Update an existing chart 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, @@ -303,16 +299,7 @@ public class ChartResource extends EntityResource { })) JsonPatch patch) throws IOException, ParseException { - Fields fields = getFields(Entity.FIELD_OWNER); - Chart chart = dao.get(uriInfo, id, fields); - EntityInterface entityInterface = dao.getEntityInterface(chart); - SecurityUtil.checkAdminRoleOrPermissions( - authorizer, securityContext, entityInterface.getEntityReference(), entityInterface.getOwner(), patch); - - PatchResponse response = - dao.patch(uriInfo, UUID.fromString(id), securityContext.getUserPrincipal().getName(), patch); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return patchInternal(uriInfo, securityContext, id, patch); } @PUT @@ -330,10 +317,7 @@ public class ChartResource extends EntityResource { @Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateChart create) throws IOException, ParseException { Chart chart = getChart(securityContext, create); - SecurityUtil.checkAdminRoleOrPermissions(authorizer, securityContext, dao.getOriginalOwner(chart)); - PutResponse response = dao.createOrUpdate(uriInfo, chart); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return createOrUpdate(uriInfo, securityContext, chart, ADMIN | BOT | OWNER); } @PUT @@ -388,9 +372,7 @@ public class ChartResource extends EntityResource { }) public Response delete(@Context UriInfo uriInfo, @Context SecurityContext securityContext, @PathParam("id") String id) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); - DeleteResponse response = dao.delete(securityContext.getUserPrincipal().getName(), id); - return response.toResponse(); + return delete(uriInfo, securityContext, id, false, ADMIN | BOT); } private Chart getChart(SecurityContext securityContext, CreateChart create) { diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/dashboards/DashboardResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/dashboards/DashboardResource.java index fa18bcf2e2f..ba6ccdd39e3 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/dashboards/DashboardResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/dashboards/DashboardResource.java @@ -13,7 +13,9 @@ package org.openmetadata.catalog.resources.dashboards; -import static org.openmetadata.catalog.Entity.FIELD_OWNER; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; +import static org.openmetadata.catalog.security.SecurityUtil.OWNER; import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.ExternalDocumentation; @@ -58,12 +60,8 @@ import org.openmetadata.catalog.jdbi3.ListFilter; import org.openmetadata.catalog.resources.Collection; 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.Include; -import org.openmetadata.catalog.util.RestUtil.DeleteResponse; -import org.openmetadata.catalog.util.RestUtil.PatchResponse; -import org.openmetadata.catalog.util.RestUtil.PutResponse; import org.openmetadata.catalog.util.ResultList; @Path("/v1/dashboards") @@ -279,10 +277,8 @@ public class DashboardResource extends EntityResource response = - dao.patch(uriInfo, UUID.fromString(id), securityContext.getUserPrincipal().getName(), patch); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return patchInternal(uriInfo, securityContext, id, patch); } @PUT @@ -338,10 +323,7 @@ public class DashboardResource extends EntityResource response = dao.createOrUpdate(uriInfo, dashboard); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return createOrUpdate(uriInfo, securityContext, dashboard, ADMIN | BOT | OWNER); } @PUT @@ -396,9 +378,7 @@ public class DashboardResource extends EntityResource response = dao.delete(securityContext.getUserPrincipal().getName(), id); - return response.toResponse(); + return delete(uriInfo, securityContext, id, false, ADMIN | BOT); } private Dashboard getDashboard(SecurityContext securityContext, CreateDashboard create) { diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/databases/DatabaseResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/databases/DatabaseResource.java index e125b36c5ff..3765ae1bf43 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/databases/DatabaseResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/databases/DatabaseResource.java @@ -13,6 +13,10 @@ package org.openmetadata.catalog.resources.databases; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; +import static org.openmetadata.catalog.security.SecurityUtil.OWNER; + import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.ExternalDocumentation; import io.swagger.v3.oas.annotations.Operation; @@ -56,14 +60,9 @@ import org.openmetadata.catalog.jdbi3.ListFilter; import org.openmetadata.catalog.resources.Collection; 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.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; -import org.openmetadata.catalog.util.RestUtil.PutResponse; import org.openmetadata.catalog.util.ResultList; @Path("/v1/databases") @@ -276,10 +275,8 @@ public class DatabaseResource extends EntityResource entityInterface = dao.getEntityInterface(database); - SecurityUtil.checkAdminRoleOrPermissions( - authorizer, securityContext, entityInterface.getEntityReference(), entityInterface.getOwner(), patch); - - PatchResponse response = - dao.patch(uriInfo, UUID.fromString(id), securityContext.getUserPrincipal().getName(), patch); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return patchInternal(uriInfo, securityContext, id, patch); } @PUT @@ -330,10 +319,7 @@ public class DatabaseResource extends EntityResource response = dao.createOrUpdate(uriInfo, database); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return createOrUpdate(uriInfo, securityContext, database, ADMIN | BOT | OWNER); } @DELETE @@ -368,9 +354,7 @@ public class DatabaseResource extends EntityResource response = dao.delete(securityContext.getUserPrincipal().getName(), id, recursive); - return response.toResponse(); + return delete(uriInfo, securityContext, id, recursive, ADMIN | BOT); } private Database getDatabase(SecurityContext securityContext, CreateDatabase create) { diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/databases/TableResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/databases/TableResource.java index e1e61f4cfb7..596d577a4a2 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/databases/TableResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/databases/TableResource.java @@ -13,7 +13,9 @@ package org.openmetadata.catalog.resources.databases; -import static org.openmetadata.catalog.Entity.FIELD_OWNER; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; +import static org.openmetadata.catalog.security.SecurityUtil.OWNER; import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.ExternalDocumentation; @@ -74,9 +76,6 @@ import org.openmetadata.catalog.type.TableData; import org.openmetadata.catalog.type.TableJoins; import org.openmetadata.catalog.type.TableProfile; 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; import org.openmetadata.catalog.util.ResultList; @Path("/v1/tables") @@ -295,9 +294,7 @@ public class TableResource extends EntityResource { public Response create(@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateTable create) throws IOException, ParseException { 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(); + return create(uriInfo, securityContext, table, ADMIN | BOT); } @PUT @@ -316,10 +313,7 @@ public class TableResource extends EntityResource { @Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateTable create) throws IOException, ParseException { Table table = getTable(securityContext, create); - SecurityUtil.checkAdminRoleOrPermissions(authorizer, securityContext, dao.getOriginalOwner(table)); - PutResponse response = dao.createOrUpdate(uriInfo, validateNewTable(table)); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return createOrUpdate(uriInfo, securityContext, table, ADMIN | BOT | OWNER); } @PATCH @@ -344,18 +338,7 @@ public class TableResource extends EntityResource { })) JsonPatch patch) throws IOException, ParseException { - Table table = dao.get(uriInfo, id, getFields(FIELD_OWNER)); - SecurityUtil.checkAdminRoleOrPermissions( - authorizer, - securityContext, - dao.getEntityInterface(table).getEntityReference(), - dao.getOriginalOwner(table), - patch); - - PatchResponse
response = - dao.patch(uriInfo, UUID.fromString(id), securityContext.getUserPrincipal().getName(), patch); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return patchInternal(uriInfo, securityContext, id, patch); } @DELETE @@ -373,9 +356,7 @@ public class TableResource extends EntityResource { @Context SecurityContext securityContext, @Parameter(description = "Id of the table", schema = @Schema(type = "string")) @PathParam("id") String id) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); - DeleteResponse
response = dao.delete(securityContext.getUserPrincipal().getName(), id); - return response.toResponse(); + return delete(uriInfo, securityContext, id, false, ADMIN | BOT); } @PUT @@ -418,7 +399,7 @@ public class TableResource extends EntityResource { @Parameter(description = "Id of the table", schema = @Schema(type = "string")) @PathParam("id") String id, TableJoins joins) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); + SecurityUtil.authorizeAdmin(authorizer, securityContext, ADMIN | BOT); Table table = dao.addJoins(UUID.fromString(id), joins); return addHref(uriInfo, table); } @@ -432,7 +413,7 @@ public class TableResource extends EntityResource { @Parameter(description = "Id of the table", schema = @Schema(type = "string")) @PathParam("id") String id, TableData tableData) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); + SecurityUtil.authorizeAdmin(authorizer, securityContext, ADMIN | BOT); Table table = dao.addSampleData(UUID.fromString(id), tableData); return addHref(uriInfo, table); } @@ -446,7 +427,7 @@ public class TableResource extends EntityResource { @Parameter(description = "Id of the table", schema = @Schema(type = "string")) @PathParam("id") String id, TableProfile tableProfile) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); + SecurityUtil.authorizeAdmin(authorizer, securityContext, ADMIN | BOT); Table table = dao.addTableProfileData(UUID.fromString(id), tableProfile); return addHref(uriInfo, table); } @@ -480,7 +461,7 @@ public class TableResource extends EntityResource { @Parameter(description = "Id of the table", schema = @Schema(type = "string")) @PathParam("id") String id, SQLQuery sqlQuery) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); + SecurityUtil.authorizeAdmin(authorizer, securityContext, ADMIN | BOT); Table table = dao.addQuery(UUID.fromString(id), sqlQuery); return addHref(uriInfo, table); } @@ -497,7 +478,7 @@ public class TableResource extends EntityResource { @Parameter(description = "Id of the table", schema = @Schema(type = "string")) @PathParam("id") String id, DataModel dataModel) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); + SecurityUtil.authorizeAdmin(authorizer, securityContext, ADMIN | BOT); Table table = dao.addDataModel(UUID.fromString(id), dataModel); return addHref(uriInfo, table); } @@ -511,7 +492,7 @@ public class TableResource extends EntityResource { @Parameter(description = "Id of the table", schema = @Schema(type = "string")) @PathParam("id") String id, CreateTableTest createTableTest) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); + SecurityUtil.authorizeAdmin(authorizer, securityContext, ADMIN | BOT); TableTest tableTest = getTableTest(securityContext, createTableTest); Table table = dao.addTableTest(UUID.fromString(id), tableTest); return addHref(uriInfo, table); @@ -527,7 +508,7 @@ public class TableResource extends EntityResource { @Parameter(description = "Table Test Type", schema = @Schema(type = "string")) @PathParam("tableTestType") String tableTestType) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); + SecurityUtil.authorizeAdmin(authorizer, securityContext, ADMIN | BOT); Table table = dao.deleteTableTest(UUID.fromString(id), tableTestType); return addHref(uriInfo, table); } @@ -541,7 +522,7 @@ public class TableResource extends EntityResource { @Parameter(description = "Id of the table", schema = @Schema(type = "string")) @PathParam("id") String id, CreateColumnTest createColumnTest) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); + SecurityUtil.authorizeAdmin(authorizer, securityContext, ADMIN | BOT); ColumnTest columnTest = getColumnTest(securityContext, createColumnTest); Table table = dao.addColumnTest(UUID.fromString(id), columnTest); return addHref(uriInfo, table); @@ -556,7 +537,7 @@ public class TableResource extends EntityResource { @Parameter(description = "Id of the table", schema = @Schema(type = "string")) @PathParam("id") String id, CreateCustomMetric createCustomMetric) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); + SecurityUtil.authorizeAdmin(authorizer, securityContext, ADMIN | BOT); CustomMetric customMetric = getCustomMetric(securityContext, createCustomMetric); Table table = dao.addCustomMetric(UUID.fromString(id), customMetric); return addHref(uriInfo, table); @@ -577,7 +558,7 @@ public class TableResource extends EntityResource { @Parameter(description = "column Test Type", schema = @Schema(type = "string")) @PathParam("columnTestType") String columnTestType) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); + SecurityUtil.authorizeAdmin(authorizer, securityContext, ADMIN | BOT); Table table = dao.deleteColumnTest(UUID.fromString(id), columnName, columnTestType); return addHref(uriInfo, table); } @@ -597,7 +578,7 @@ public class TableResource extends EntityResource { @Parameter(description = "column Test Type", schema = @Schema(type = "string")) @PathParam("customMetricName") String customMetricName) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); + SecurityUtil.authorizeAdmin(authorizer, securityContext, ADMIN | BOT); Table table = dao.deleteCustomMetric(UUID.fromString(id), columnName, customMetricName); return addHref(uriInfo, table); } @@ -645,21 +626,22 @@ public class TableResource extends EntityResource { } private Table getTable(SecurityContext securityContext, CreateTable create) { - return new Table() - .withId(UUID.randomUUID()) - .withName(create.getName()) - .withColumns(create.getColumns()) - .withDescription(create.getDescription()) - .withTableConstraints(create.getTableConstraints()) - .withTablePartition(create.getTablePartition()) - .withTableType(create.getTableType()) - .withTags(create.getTags()) - .withViewDefinition(create.getViewDefinition()) - .withProfileSample(create.getProfileSample()) - .withUpdatedBy(securityContext.getUserPrincipal().getName()) - .withOwner(create.getOwner()) - .withUpdatedAt(System.currentTimeMillis()) - .withDatabase(create.getDatabase()); + return validateNewTable( + new Table() + .withId(UUID.randomUUID()) + .withName(create.getName()) + .withColumns(create.getColumns()) + .withDescription(create.getDescription()) + .withTableConstraints(create.getTableConstraints()) + .withTablePartition(create.getTablePartition()) + .withTableType(create.getTableType()) + .withTags(create.getTags()) + .withViewDefinition(create.getViewDefinition()) + .withProfileSample(create.getProfileSample()) + .withUpdatedBy(securityContext.getUserPrincipal().getName()) + .withOwner(create.getOwner()) + .withUpdatedAt(System.currentTimeMillis()) + .withDatabase(create.getDatabase())); } private TableTest getTableTest(SecurityContext securityContext, CreateTableTest create) { diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/events/WebhookResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/events/WebhookResource.java index 78001c27474..99d6bdff6be 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/events/WebhookResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/events/WebhookResource.java @@ -13,6 +13,9 @@ package org.openmetadata.catalog.resources.events; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; + import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -49,7 +52,6 @@ import org.openmetadata.catalog.jdbi3.WebhookRepository; import org.openmetadata.catalog.resources.Collection; import org.openmetadata.catalog.resources.EntityResource; import org.openmetadata.catalog.security.Authorizer; -import org.openmetadata.catalog.security.SecurityUtil; import org.openmetadata.catalog.type.ChangeEvent; import org.openmetadata.catalog.type.EntityHistory; import org.openmetadata.catalog.type.Include; @@ -58,8 +60,6 @@ import org.openmetadata.catalog.type.Webhook.Status; import org.openmetadata.catalog.util.EntityUtil; 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.PutResponse; import org.openmetadata.catalog.util.ResultList; @Path("/v1/webhook") @@ -252,12 +252,10 @@ public class WebhookResource extends EntityResource public Response createWebhook( @Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateWebhook create) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); Webhook webhook = getWebhook(securityContext, create); - webhook.setStatus(Boolean.TRUE.equals(webhook.getEnabled()) ? Status.ACTIVE : Status.DISABLED); - webhook = dao.create(uriInfo, webhook); + Response response = create(uriInfo, securityContext, webhook, ADMIN); dao.addWebhookPublisher(webhook); - return Response.created(webhook.getHref()).entity(webhook).build(); + return response; } @PUT @@ -275,12 +273,10 @@ public class WebhookResource extends EntityResource public Response updateWebhook( @Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateWebhook create) throws IOException, ParseException, InterruptedException { - SecurityUtil.checkAdminRole(authorizer, securityContext); Webhook webhook = getWebhook(securityContext, create); - webhook.setStatus(Boolean.TRUE.equals(webhook.getEnabled()) ? Status.ACTIVE : Status.DISABLED); - PutResponse putResponse = dao.createOrUpdate(uriInfo, webhook); - dao.updateWebhookPublisher(webhook); - return putResponse.toResponse(); + Response response = createOrUpdate(uriInfo, securityContext, webhook, ADMIN | BOT); + dao.updateWebhookPublisher((Webhook) response.getEntity()); + return response; } @DELETE @@ -302,10 +298,9 @@ public class WebhookResource extends EntityResource @Context SecurityContext securityContext, @Parameter(description = "webhook Id", schema = @Schema(type = "string")) @PathParam("id") String id) throws IOException, ParseException, InterruptedException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); - DeleteResponse response = dao.delete(securityContext.getUserPrincipal().getName(), id); + Response response = delete(uriInfo, securityContext, id, false, ADMIN); dao.deleteWebhookPublisher(UUID.fromString(id)); - return response.toResponse(); + return response; } public Webhook getWebhook(SecurityContext securityContext, CreateWebhook create) { @@ -322,6 +317,7 @@ public class WebhookResource extends EntityResource .withEnabled(create.getEnabled()) .withUpdatedBy(securityContext.getUserPrincipal().getName()) .withUpdatedAt(System.currentTimeMillis()) - .withSecretKey(create.getSecretKey()); + .withSecretKey(create.getSecretKey()) + .withStatus(Boolean.TRUE.equals(create.getEnabled()) ? Status.ACTIVE : Status.DISABLED); } } diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/feeds/FeedResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/feeds/FeedResource.java index 31f8c6bf0aa..de5e4fac167 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/feeds/FeedResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/feeds/FeedResource.java @@ -13,6 +13,10 @@ package org.openmetadata.catalog.resources.feeds; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; +import static org.openmetadata.catalog.security.SecurityUtil.OWNER; + import com.fasterxml.jackson.annotation.JsonPropertyOrder; import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.ExternalDocumentation; @@ -326,7 +330,7 @@ public class FeedResource { Thread thread = dao.get(threadId); Post post = dao.getPostById(thread, postId); // delete post only if the admin/bot/author tries to delete it - SecurityUtil.checkAdminOrBotOrOwner(authorizer, securityContext, dao.getOwnerOfPost(post)); + SecurityUtil.authorize(authorizer, securityContext, null, dao.getOwnerOfPost(post), ADMIN | BOT | OWNER); return dao.deletePost(thread, post, securityContext.getUserPrincipal().getName()).toResponse(); } diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/glossary/GlossaryResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/glossary/GlossaryResource.java index 51f157a1cb7..3c581923192 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/glossary/GlossaryResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/glossary/GlossaryResource.java @@ -13,6 +13,10 @@ package org.openmetadata.catalog.resources.glossary; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; +import static org.openmetadata.catalog.security.SecurityUtil.OWNER; + import com.google.inject.Inject; import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.ExternalDocumentation; @@ -57,13 +61,9 @@ import org.openmetadata.catalog.jdbi3.ListFilter; import org.openmetadata.catalog.resources.Collection; 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.Include; import org.openmetadata.catalog.util.RestUtil; -import org.openmetadata.catalog.util.RestUtil.DeleteResponse; -import org.openmetadata.catalog.util.RestUtil.PatchResponse; -import org.openmetadata.catalog.util.RestUtil.PutResponse; import org.openmetadata.catalog.util.ResultList; @Path("/v1/glossaries") @@ -274,10 +274,8 @@ public class GlossaryResource extends EntityResource response = - dao.patch(uriInfo, UUID.fromString(id), securityContext.getUserPrincipal().getName(), patch); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return patchInternal(uriInfo, securityContext, id, patch); } @PUT @@ -331,10 +319,7 @@ public class GlossaryResource extends EntityResource response = dao.createOrUpdate(uriInfo, glossary); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return createOrUpdate(uriInfo, securityContext, glossary, ADMIN | BOT | OWNER); } @DELETE @@ -349,9 +334,7 @@ public class GlossaryResource extends EntityResource response = dao.delete(securityContext.getUserPrincipal().getName(), id); - return response.toResponse(); + return delete(uriInfo, securityContext, id, false, ADMIN | BOT); } private Glossary getGlossary(SecurityContext securityContext, CreateGlossary create) { diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/glossary/GlossaryTermResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/glossary/GlossaryTermResource.java index 69a326d8a48..e8e1131845d 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/glossary/GlossaryTermResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/glossary/GlossaryTermResource.java @@ -13,6 +13,9 @@ package org.openmetadata.catalog.resources.glossary; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; + import com.google.inject.Inject; import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.ExternalDocumentation; @@ -59,16 +62,11 @@ import org.openmetadata.catalog.jdbi3.ListFilter; import org.openmetadata.catalog.resources.Collection; 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.EntityInterface; 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; -import org.openmetadata.catalog.util.RestUtil.PutResponse; import org.openmetadata.catalog.util.ResultList; @Path("/v1/glossaryTerms") @@ -324,10 +322,8 @@ public class GlossaryTermResource extends EntityResource entityInterface = dao.getEntityInterface(term); - SecurityUtil.checkAdminRoleOrPermissions( - authorizer, securityContext, entityInterface.getEntityReference(), entityInterface.getOwner(), patch); - PatchResponse response = - dao.patch(uriInfo, UUID.fromString(id), securityContext.getUserPrincipal().getName(), patch); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return patchInternal(uriInfo, securityContext, id, patch); } @PUT @@ -378,10 +367,7 @@ public class GlossaryTermResource extends EntityResource response = dao.createOrUpdate(uriInfo, term); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return createOrUpdate(uriInfo, securityContext, term, ADMIN | BOT); } @DELETE @@ -396,9 +382,7 @@ public class GlossaryTermResource extends EntityResource response = dao.delete(securityContext.getUserPrincipal().getName(), id); - return response.toResponse(); + return delete(uriInfo, securityContext, id, false, ADMIN | BOT); } private GlossaryTerm getGlossaryTerm(SecurityContext securityContext, CreateGlossaryTerm create) { diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/locations/LocationResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/locations/LocationResource.java index 81e0c50740c..6e9695f4eee 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/locations/LocationResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/locations/LocationResource.java @@ -13,6 +13,10 @@ package org.openmetadata.catalog.resources.locations; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; +import static org.openmetadata.catalog.security.SecurityUtil.OWNER; + import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.ExternalDocumentation; import io.swagger.v3.oas.annotations.Operation; @@ -56,14 +60,10 @@ import org.openmetadata.catalog.jdbi3.LocationRepository; import org.openmetadata.catalog.resources.Collection; 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.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; -import org.openmetadata.catalog.util.RestUtil.PutResponse; import org.openmetadata.catalog.util.ResultList; @Path("/v1/locations") @@ -331,10 +331,8 @@ public class LocationResource extends EntityResource response = dao.createOrUpdate(uriInfo, validateNewLocation(location)); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return createOrUpdate(uriInfo, securityContext, location, ADMIN | BOT | OWNER); } @PATCH @@ -381,19 +376,7 @@ public class LocationResource extends EntityResource response = - dao.patch(uriInfo, UUID.fromString(id), securityContext.getUserPrincipal().getName(), patch); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return patchInternal(uriInfo, securityContext, id, patch); } @DELETE @@ -411,9 +394,7 @@ public class LocationResource extends EntityResource response = dao.delete(securityContext.getUserPrincipal().getName(), id); - return response.toResponse(); + return delete(uriInfo, securityContext, id, false, ADMIN | BOT); } @PUT diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/metrics/MetricsResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/metrics/MetricsResource.java index 343e93a5065..cb6bf4673e9 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/metrics/MetricsResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/metrics/MetricsResource.java @@ -13,6 +13,9 @@ package org.openmetadata.catalog.resources.metrics; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; + import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -49,7 +52,6 @@ import org.openmetadata.catalog.resources.Collection; import org.openmetadata.catalog.resources.EntityResource; import org.openmetadata.catalog.security.Authorizer; import org.openmetadata.catalog.type.Include; -import org.openmetadata.catalog.util.RestUtil.PutResponse; import org.openmetadata.catalog.util.ResultList; @Path("/v1/metrics") @@ -155,8 +157,7 @@ public class MetricsResource extends EntityResource public Response create(@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid Metrics metrics) throws IOException, ParseException { addToMetrics(securityContext, metrics); - dao.create(uriInfo, metrics); - return Response.created(metrics.getHref()).entity(metrics).build(); + return create(uriInfo, securityContext, metrics, ADMIN | BOT); } @PUT @@ -175,8 +176,7 @@ public class MetricsResource extends EntityResource @Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid Metrics metrics) throws IOException, ParseException { addToMetrics(securityContext, metrics); - PutResponse response = dao.createOrUpdate(uriInfo, metrics); - return response.toResponse(); + return createOrUpdate(uriInfo, securityContext, metrics); } private void addToMetrics(SecurityContext securityContext, Metrics metrics) { diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/mlmodels/MlModelResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/mlmodels/MlModelResource.java index c614ba6d277..e91b7ed1963 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/mlmodels/MlModelResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/mlmodels/MlModelResource.java @@ -13,6 +13,10 @@ package org.openmetadata.catalog.resources.mlmodels; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; +import static org.openmetadata.catalog.security.SecurityUtil.OWNER; + import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.ExternalDocumentation; import io.swagger.v3.oas.annotations.Operation; @@ -56,14 +60,9 @@ import org.openmetadata.catalog.jdbi3.MlModelRepository; import org.openmetadata.catalog.resources.Collection; 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.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; -import org.openmetadata.catalog.util.RestUtil.PutResponse; import org.openmetadata.catalog.util.ResultList; @Path("/v1/mlmodels") @@ -225,10 +224,8 @@ public class MlModelResource extends EntityResource public Response create( @Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateMlModel create) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); MlModel mlModel = getMlModel(securityContext, create); - mlModel = addHref(uriInfo, dao.create(uriInfo, mlModel)); - return Response.created(mlModel.getHref()).entity(mlModel).build(); + return create(uriInfo, securityContext, mlModel, ADMIN | BOT); } @PATCH @@ -253,19 +250,7 @@ public class MlModelResource extends EntityResource })) JsonPatch patch) throws IOException, ParseException { - Fields fields = getFields(FIELDS); - MlModel mlModel = dao.get(uriInfo, id, fields); - SecurityUtil.checkAdminRoleOrPermissions( - authorizer, - securityContext, - dao.getEntityInterface(mlModel).getEntityReference(), - dao.getOwnerReference(mlModel), - patch); - - PatchResponse response = - dao.patch(uriInfo, UUID.fromString(id), securityContext.getUserPrincipal().getName(), patch); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return patchInternal(uriInfo, securityContext, id, patch); } @PUT @@ -284,10 +269,7 @@ public class MlModelResource extends EntityResource @Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateMlModel create) throws IOException, ParseException { MlModel mlModel = getMlModel(securityContext, create); - SecurityUtil.checkAdminRoleOrPermissions(authorizer, securityContext, dao.getOriginalOwner(mlModel)); - PutResponse response = dao.createOrUpdate(uriInfo, mlModel); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return createOrUpdate(uriInfo, securityContext, mlModel, ADMIN | BOT | OWNER); } @PUT @@ -393,9 +375,7 @@ public class MlModelResource extends EntityResource @Context SecurityContext securityContext, @Parameter(description = "Id of the ML Model", schema = @Schema(type = "string")) @PathParam("id") String id) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); - DeleteResponse response = dao.delete(securityContext.getUserPrincipal().getName(), id); - return response.toResponse(); + return delete(uriInfo, securityContext, id, false, ADMIN | BOT); } private MlModel getMlModel(SecurityContext securityContext, CreateMlModel create) { diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/operations/AirflowPipelineResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/operations/AirflowPipelineResource.java index 542d91e4e66..a74b21477be 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/operations/AirflowPipelineResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/operations/AirflowPipelineResource.java @@ -14,6 +14,9 @@ package org.openmetadata.catalog.resources.operations; import static org.openmetadata.catalog.Entity.FIELD_OWNER; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; +import static org.openmetadata.catalog.security.SecurityUtil.OWNER; import static org.openmetadata.common.utils.CommonUtil.listOrEmpty; import io.swagger.annotations.Api; @@ -62,14 +65,9 @@ import org.openmetadata.catalog.operations.pipelines.AirflowPipeline; import org.openmetadata.catalog.resources.Collection; 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.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; -import org.openmetadata.catalog.util.RestUtil.PutResponse; import org.openmetadata.catalog.util.ResultList; @Slf4j @@ -311,11 +309,10 @@ public class AirflowPipelineResource extends EntityResource entityInterface = dao.getEntityInterface(airflowPipeline); - SecurityUtil.checkAdminRoleOrPermissions( - authorizer, securityContext, entityInterface.getEntityReference(), entityInterface.getOwner(), patch); - - PatchResponse response = - dao.patch(uriInfo, UUID.fromString(id), securityContext.getUserPrincipal().getName(), patch); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return patchInternal(uriInfo, securityContext, id, patch); } @PUT @@ -368,11 +357,9 @@ public class AirflowPipelineResource extends EntityResource response = dao.createOrUpdate(uriInfo, pipeline); - deploy(pipeline, SecurityUtil.isAdminOrBotRole(authorizer, securityContext)); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + Response response = createOrUpdate(uriInfo, securityContext, pipeline, ADMIN | BOT | OWNER); + deploy(pipeline, true); // TODO cleanup + return response; } @POST @@ -410,12 +397,10 @@ public class AirflowPipelineResource extends EntityResource response = dao.delete(securityContext.getUserPrincipal().getName(), id); - return response.toResponse(); + return response; } private AirflowPipeline getAirflowPipeline(SecurityContext securityContext, CreateAirflowPipeline create) { diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/pipelines/PipelineResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/pipelines/PipelineResource.java index 5b17bd761d3..96320c8217f 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/pipelines/PipelineResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/pipelines/PipelineResource.java @@ -13,6 +13,10 @@ package org.openmetadata.catalog.resources.pipelines; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; +import static org.openmetadata.catalog.security.SecurityUtil.OWNER; + import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.ExternalDocumentation; import io.swagger.v3.oas.annotations.Operation; @@ -60,11 +64,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.RestUtil; -import org.openmetadata.catalog.util.RestUtil.DeleteResponse; -import org.openmetadata.catalog.util.RestUtil.PatchResponse; -import org.openmetadata.catalog.util.RestUtil.PutResponse; import org.openmetadata.catalog.util.ResultList; @Path("/v1/pipelines") @@ -280,10 +280,8 @@ public class PipelineResource extends EntityResource response = - dao.patch(uriInfo, UUID.fromString(id), securityContext.getUserPrincipal().getName(), patch); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return patchInternal(uriInfo, securityContext, id, patch); } @PUT @@ -340,10 +326,7 @@ public class PipelineResource extends EntityResource response = dao.createOrUpdate(uriInfo, pipeline); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return createOrUpdate(uriInfo, securityContext, pipeline, ADMIN | BOT | OWNER); } @PUT @@ -365,7 +348,7 @@ public class PipelineResource extends EntityResource response = dao.delete(securityContext.getUserPrincipal().getName(), id); - return response.toResponse(); + return delete(uriInfo, securityContext, id, false, ADMIN | BOT); } private Pipeline getPipeline(SecurityContext securityContext, CreatePipeline create) { diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/policies/PolicyResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/policies/PolicyResource.java index 7bf22d5a185..191cd2bc81d 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/policies/PolicyResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/policies/PolicyResource.java @@ -13,7 +13,9 @@ package org.openmetadata.catalog.resources.policies; -import static org.openmetadata.catalog.Entity.FIELD_OWNER; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; +import static org.openmetadata.catalog.security.SecurityUtil.OWNER; import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.ExternalDocumentation; @@ -59,15 +61,10 @@ import org.openmetadata.catalog.jdbi3.PolicyRepository; import org.openmetadata.catalog.resources.Collection; import org.openmetadata.catalog.resources.EntityResource; import org.openmetadata.catalog.security.Authorizer; -import org.openmetadata.catalog.security.SecurityUtil; import org.openmetadata.catalog.security.policyevaluator.PolicyEvaluator; 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.DeleteResponse; -import org.openmetadata.catalog.util.RestUtil.PatchResponse; -import org.openmetadata.catalog.util.RestUtil.PutResponse; import org.openmetadata.catalog.util.ResultList; @Path("/v1/policies") @@ -283,10 +280,8 @@ public class PolicyResource extends EntityResource { }) public Response create(@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreatePolicy create) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); Policy policy = getPolicy(securityContext, create); - policy = addHref(uriInfo, dao.create(uriInfo, policy)); - return Response.created(policy.getHref()).entity(policy).build(); + return create(uriInfo, securityContext, policy, ADMIN | BOT); } @PATCH @@ -311,14 +306,7 @@ public class PolicyResource extends EntityResource { })) JsonPatch patch) throws IOException, ParseException { - Fields fields = getFields(FIELD_OWNER); - Policy policy = dao.get(uriInfo, id, fields); - SecurityUtil.checkAdminRoleOrPermissions(authorizer, securityContext, dao.getOwnerReference(policy)); - - PatchResponse response = - dao.patch(uriInfo, UUID.fromString(id), securityContext.getUserPrincipal().getName(), patch); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return patchInternal(uriInfo, securityContext, id, patch); } @PUT @@ -337,10 +325,7 @@ public class PolicyResource extends EntityResource { @Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreatePolicy create) throws IOException, ParseException { Policy policy = getPolicy(securityContext, create); - SecurityUtil.checkAdminRoleOrPermissions(authorizer, securityContext, dao.getOriginalOwner(policy)); - PutResponse response = dao.createOrUpdate(uriInfo, policy); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return createOrUpdate(uriInfo, securityContext, policy, ADMIN | BOT | OWNER); } @DELETE @@ -355,9 +340,7 @@ public class PolicyResource extends EntityResource { }) public Response delete(@Context UriInfo uriInfo, @Context SecurityContext securityContext, @PathParam("id") String id) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); - DeleteResponse response = dao.delete(securityContext.getUserPrincipal().getName(), id); - return response.toResponse(); + return delete(uriInfo, securityContext, id, false, ADMIN | BOT); } private Policy getPolicy(SecurityContext securityContext, CreatePolicy create) { diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/reports/ReportResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/reports/ReportResource.java index 832d2b90aa4..c23beb159b8 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/reports/ReportResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/reports/ReportResource.java @@ -13,6 +13,9 @@ package org.openmetadata.catalog.resources.reports; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; + import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -48,7 +51,6 @@ import org.openmetadata.catalog.resources.EntityResource; import org.openmetadata.catalog.security.Authorizer; import org.openmetadata.catalog.type.Include; import org.openmetadata.catalog.util.EntityUtil.Fields; -import org.openmetadata.catalog.util.RestUtil.PutResponse; import org.openmetadata.catalog.util.ResultList; @Path("/v1/reports") @@ -147,8 +149,7 @@ public class ReportResource extends EntityResource { public Response create(@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid Report report) throws IOException, ParseException { addToReport(securityContext, report); - dao.create(uriInfo, report); - return Response.created(report.getHref()).entity(report).build(); + return create(uriInfo, securityContext, report, ADMIN | BOT); } @PUT @@ -167,8 +168,7 @@ public class ReportResource extends EntityResource { @Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid Report report) throws IOException, ParseException { addToReport(securityContext, report); - PutResponse response = dao.createOrUpdate(uriInfo, report); - return response.toResponse(); + return createOrUpdate(uriInfo, securityContext, report); } private void addToReport(SecurityContext securityContext, Report report) { diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/services/dashboard/DashboardServiceResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/services/dashboard/DashboardServiceResource.java index 203a17c73f6..386f0350391 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/services/dashboard/DashboardServiceResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/services/dashboard/DashboardServiceResource.java @@ -14,6 +14,9 @@ package org.openmetadata.catalog.resources.services.dashboard; import static org.openmetadata.catalog.Entity.FIELD_OWNER; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; +import static org.openmetadata.catalog.security.SecurityUtil.OWNER; import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.Operation; @@ -53,12 +56,9 @@ import org.openmetadata.catalog.jdbi3.ListFilter; import org.openmetadata.catalog.resources.Collection; 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.Include; import org.openmetadata.catalog.util.RestUtil; -import org.openmetadata.catalog.util.RestUtil.DeleteResponse; -import org.openmetadata.catalog.util.RestUtil.PutResponse; import org.openmetadata.catalog.util.ResultList; @Path("/v1/services/dashboardServices") @@ -266,10 +266,8 @@ public class DashboardServiceResource extends EntityResource response = dao.createOrUpdate(uriInfo, service, true); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return createOrUpdate(uriInfo, securityContext, service, ADMIN | BOT | OWNER); } @DELETE @@ -318,9 +313,7 @@ public class DashboardServiceResource extends EntityResource response = dao.delete(securityContext.getUserPrincipal().getName(), id, recursive); - return response.toResponse(); + return delete(uriInfo, securityContext, id, recursive, ADMIN | BOT); } private DashboardService getService(CreateDashboardService create, SecurityContext securityContext) { diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/services/database/DatabaseServiceResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/services/database/DatabaseServiceResource.java index 558b02bf812..f0040ede3ab 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/services/database/DatabaseServiceResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/services/database/DatabaseServiceResource.java @@ -14,6 +14,10 @@ package org.openmetadata.catalog.resources.services.database; import static org.openmetadata.catalog.fernet.Fernet.isTokenized; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; +import static org.openmetadata.catalog.security.SecurityUtil.OWNER; +import static org.openmetadata.common.utils.CommonUtil.listOrEmpty; import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.Operation; @@ -24,9 +28,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import java.io.IOException; import java.security.GeneralSecurityException; import java.text.ParseException; -import java.util.Collections; import java.util.List; -import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; import javax.validation.Valid; @@ -66,8 +68,6 @@ import org.openmetadata.catalog.type.MetadataOperation; import org.openmetadata.catalog.util.EntityUtil; import org.openmetadata.catalog.util.JsonUtils; import org.openmetadata.catalog.util.RestUtil; -import org.openmetadata.catalog.util.RestUtil.DeleteResponse; -import org.openmetadata.catalog.util.RestUtil.PutResponse; import org.openmetadata.catalog.util.ResultList; @Path("/v1/services/databaseServices") @@ -300,10 +300,10 @@ public class DatabaseServiceResource extends EntityResource response = dao.createOrUpdate(uriInfo, service, true); - addHref(uriInfo, decryptOrNullify(securityContext, response.getEntity())); - return response.toResponse(); + Response response = createOrUpdate(uriInfo, securityContext, service, ADMIN | BOT | OWNER); + decryptOrNullify(securityContext, (DatabaseService) response.getEntity()); + return response; } @DELETE @@ -352,16 +351,14 @@ public class DatabaseServiceResource extends EntityResource response = dao.delete(securityContext.getUserPrincipal().getName(), id, recursive); - decryptOrNullify(securityContext, response.getEntity()); - return response.toResponse(); + Response response = delete(uriInfo, securityContext, id, recursive, ADMIN | BOT); + decryptOrNullify(securityContext, (DatabaseService) response.getEntity()); + return response; } private ResultList decryptOrNullify( SecurityContext securityContext, ResultList databaseServices) { - Optional.ofNullable(databaseServices.getData()) - .orElse(Collections.emptyList()) + listOrEmpty(databaseServices.getData()) .forEach(databaseService -> decryptOrNullify(securityContext, databaseService)); return databaseServices; } diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/services/messaging/MessagingServiceResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/services/messaging/MessagingServiceResource.java index 523c2278045..77afd96f100 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/services/messaging/MessagingServiceResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/services/messaging/MessagingServiceResource.java @@ -14,6 +14,9 @@ package org.openmetadata.catalog.resources.services.messaging; import static org.openmetadata.catalog.Entity.FIELD_OWNER; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; +import static org.openmetadata.catalog.security.SecurityUtil.OWNER; import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.Operation; @@ -53,12 +56,9 @@ import org.openmetadata.catalog.jdbi3.MessagingServiceRepository; import org.openmetadata.catalog.resources.Collection; 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.Include; import org.openmetadata.catalog.util.RestUtil; -import org.openmetadata.catalog.util.RestUtil.DeleteResponse; -import org.openmetadata.catalog.util.RestUtil.PutResponse; import org.openmetadata.catalog.util.ResultList; @Path("/v1/services/messagingServices") @@ -269,10 +269,8 @@ public class MessagingServiceResource extends EntityResource response = dao.createOrUpdate(uriInfo, service, true); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return createOrUpdate(uriInfo, securityContext, service, ADMIN | BOT | OWNER); } @DELETE @@ -324,9 +319,7 @@ public class MessagingServiceResource extends EntityResource response = dao.delete(securityContext.getUserPrincipal().getName(), id, recursive); - return response.toResponse(); + return delete(uriInfo, securityContext, id, recursive, ADMIN | BOT); } private MessagingService getService(CreateMessagingService create, SecurityContext securityContext) { diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/services/pipeline/PipelineServiceResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/services/pipeline/PipelineServiceResource.java index 84e87df29b8..295145f1c4c 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/services/pipeline/PipelineServiceResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/services/pipeline/PipelineServiceResource.java @@ -14,6 +14,9 @@ package org.openmetadata.catalog.resources.services.pipeline; import static org.openmetadata.catalog.Entity.FIELD_OWNER; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; +import static org.openmetadata.catalog.security.SecurityUtil.OWNER; import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.Operation; @@ -53,12 +56,9 @@ import org.openmetadata.catalog.jdbi3.PipelineServiceRepository; import org.openmetadata.catalog.resources.Collection; 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.Include; import org.openmetadata.catalog.util.RestUtil; -import org.openmetadata.catalog.util.RestUtil.DeleteResponse; -import org.openmetadata.catalog.util.RestUtil.PutResponse; import org.openmetadata.catalog.util.ResultList; @Path("/v1/services/pipelineServices") @@ -269,10 +269,8 @@ public class PipelineServiceResource extends EntityResource response = dao.createOrUpdate(uriInfo, service, true); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return createOrUpdate(uriInfo, securityContext, service, ADMIN | BOT | OWNER); } @DELETE @@ -321,9 +316,7 @@ public class PipelineServiceResource extends EntityResource response = dao.delete(securityContext.getUserPrincipal().getName(), id, recursive); - return response.toResponse(); + return delete(uriInfo, securityContext, id, recursive, ADMIN | BOT); } private PipelineService getService(CreatePipelineService create, SecurityContext securityContext) { diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/services/storage/StorageServiceResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/services/storage/StorageServiceResource.java index 9f715d4bfdb..63b9b1bd7ec 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/services/storage/StorageServiceResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/services/storage/StorageServiceResource.java @@ -14,6 +14,9 @@ package org.openmetadata.catalog.resources.services.storage; import static org.openmetadata.catalog.Entity.FIELD_OWNER; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; +import static org.openmetadata.catalog.security.SecurityUtil.OWNER; import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.Operation; @@ -53,12 +56,9 @@ import org.openmetadata.catalog.jdbi3.StorageServiceRepository; import org.openmetadata.catalog.resources.Collection; 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.Include; import org.openmetadata.catalog.util.RestUtil; -import org.openmetadata.catalog.util.RestUtil.DeleteResponse; -import org.openmetadata.catalog.util.RestUtil.PutResponse; import org.openmetadata.catalog.util.ResultList; @Path("/v1/services/storageServices") @@ -267,10 +267,8 @@ public class StorageServiceResource extends EntityResource response = dao.createOrUpdate(uriInfo, service, true); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return createOrUpdate(uriInfo, securityContext, service, ADMIN | BOT | OWNER); } @DELETE @@ -316,9 +311,7 @@ public class StorageServiceResource extends EntityResource response = dao.delete(securityContext.getUserPrincipal().getName(), id, recursive); - return response.toResponse(); + return delete(uriInfo, securityContext, id, recursive, ADMIN | BOT); } private StorageService getService(CreateStorageService create, SecurityContext securityContext) { diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/tags/TagResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/tags/TagResource.java index 0cf0c1694b3..633a32e6152 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/tags/TagResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/tags/TagResource.java @@ -13,6 +13,8 @@ package org.openmetadata.catalog.resources.tags; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; import static org.openmetadata.common.utils.CommonUtil.listOrEmpty; import io.swagger.annotations.Api; @@ -284,7 +286,7 @@ public class TagResource { public Response createCategory( @Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateTagCategory create) throws IOException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); + SecurityUtil.authorizeAdmin(authorizer, securityContext, ADMIN | BOT); TagCategory category = new TagCategory() .withName(create.getName()) @@ -316,7 +318,7 @@ public class TagResource { String category, @Valid CreateTag create) throws IOException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); + SecurityUtil.authorizeAdmin(authorizer, securityContext, ADMIN | BOT); Tag tag = new Tag() .withName(create.getName()) @@ -357,7 +359,7 @@ public class TagResource { String primaryTag, @Valid CreateTag create) throws IOException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); + SecurityUtil.authorizeAdmin(authorizer, securityContext, ADMIN | BOT); Tag tag = new Tag() .withName(create.getName()) @@ -384,7 +386,7 @@ public class TagResource { String categoryName, @Valid CreateTagCategory create) throws IOException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); + SecurityUtil.authorizeAdmin(authorizer, securityContext, ADMIN | BOT); TagCategory category = new TagCategory() .withName(create.getName()) @@ -416,7 +418,7 @@ public class TagResource { String primaryTag, @Valid CreateTag create) throws IOException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); + SecurityUtil.authorizeAdmin(authorizer, securityContext, ADMIN | BOT); Tag tag = new Tag() .withName(create.getName()) @@ -456,7 +458,7 @@ public class TagResource { String secondaryTag, @Valid CreateTag create) throws IOException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); + SecurityUtil.authorizeAdmin(authorizer, securityContext, ADMIN | BOT); Tag tag = new Tag() .withName(create.getName()) diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/teams/RoleResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/teams/RoleResource.java index d1445f8a14e..b75afea52f6 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/teams/RoleResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/teams/RoleResource.java @@ -13,6 +13,9 @@ package org.openmetadata.catalog.resources.teams; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; + import io.dropwizard.jersey.PATCH; import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.ExternalDocumentation; @@ -57,13 +60,10 @@ import org.openmetadata.catalog.jdbi3.RoleRepository; import org.openmetadata.catalog.resources.Collection; 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.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; import org.openmetadata.catalog.util.ResultList; @Path("/v1/roles") @@ -291,10 +291,8 @@ public class RoleResource extends EntityResource { public Response create( @Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateRole createRole) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); Role role = getRole(createRole, securityContext); - role = addHref(uriInfo, dao.create(uriInfo, role)); - return Response.created(role.getHref()).entity(role).build(); + return create(uriInfo, securityContext, role, ADMIN | BOT); } @PUT @@ -312,11 +310,8 @@ public class RoleResource extends EntityResource { public Response createOrUpdateRole( @Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateRole createRole) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); Role role = getRole(createRole, securityContext); - RestUtil.PutResponse response = dao.createOrUpdate(uriInfo, role); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return createOrUpdate(uriInfo, securityContext, role, ADMIN | BOT); } @PATCH @@ -341,11 +336,7 @@ public class RoleResource extends EntityResource { })) JsonPatch patch) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); - PatchResponse response = - dao.patch(uriInfo, UUID.fromString(id), securityContext.getUserPrincipal().getName(), patch); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return patchInternal(uriInfo, securityContext, id, patch); } @DELETE @@ -360,11 +351,9 @@ public class RoleResource extends EntityResource { }) public Response delete(@Context UriInfo uriInfo, @Context SecurityContext securityContext, @PathParam("id") String id) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); // A role has a strong relationship with a policy. Recursively delete the policy that the role contains, to avoid // leaving a dangling policy without a role. - DeleteResponse response = dao.delete(securityContext.getUserPrincipal().getName(), id, true); - return response.toResponse(); + return delete(uriInfo, securityContext, id, true, ADMIN | BOT); } private Role getRole(CreateRole cr, SecurityContext securityContext) { diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/teams/TeamResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/teams/TeamResource.java index 9c99115f0d2..8af410c4a47 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/teams/TeamResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/teams/TeamResource.java @@ -13,6 +13,10 @@ package org.openmetadata.catalog.resources.teams; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; +import static org.openmetadata.catalog.security.SecurityUtil.OWNER; + import io.dropwizard.jersey.PATCH; import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.ExternalDocumentation; @@ -56,13 +60,8 @@ import org.openmetadata.catalog.jdbi3.TeamRepository; import org.openmetadata.catalog.resources.Collection; 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.Include; -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; import org.openmetadata.catalog.util.ResultList; @Path("/v1/teams") @@ -271,10 +270,8 @@ public class TeamResource extends EntityResource { }) public Response create(@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateTeam ct) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); Team team = getTeam(ct, securityContext); - addHref(uriInfo, dao.create(uriInfo, team)); - return Response.created(team.getHref()).entity(team).build(); + return create(uriInfo, securityContext, team, ADMIN | BOT); } @PUT @@ -293,10 +290,7 @@ public class TeamResource extends EntityResource { @Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateTeam ct) throws IOException, ParseException { Team team = getTeam(ct, securityContext); - SecurityUtil.checkAdminRoleOrPermissions(authorizer, securityContext, dao.getOriginalOwner(team)); - RestUtil.PutResponse response = dao.createOrUpdate(uriInfo, team); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return createOrUpdate(uriInfo, securityContext, team, ADMIN | BOT | OWNER); } @PATCH @@ -321,14 +315,7 @@ public class TeamResource extends EntityResource { })) JsonPatch patch) throws IOException, ParseException { - Team team = dao.get(uriInfo, id, getFields(Entity.FIELD_OWNER)); - EntityInterface entityInterface = dao.getEntityInterface(team); - SecurityUtil.checkAdminRoleOrPermissions( - authorizer, securityContext, entityInterface.getEntityReference(), entityInterface.getOwner(), patch); - PatchResponse response = - dao.patch(uriInfo, UUID.fromString(id), securityContext.getUserPrincipal().getName(), patch); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return patchInternal(uriInfo, securityContext, id, patch); } @DELETE @@ -343,9 +330,7 @@ public class TeamResource extends EntityResource { }) public Response delete(@Context UriInfo uriInfo, @Context SecurityContext securityContext, @PathParam("id") String id) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); - DeleteResponse response = dao.delete(securityContext.getUserPrincipal().getName(), id); - return response.toResponse(); + return delete(uriInfo, securityContext, id, false, ADMIN | BOT); } private Team getTeam(CreateTeam ct, SecurityContext securityContext) { diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/teams/UserResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/teams/UserResource.java index 5f216686632..99ea8d5a5d2 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/teams/UserResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/teams/UserResource.java @@ -13,6 +13,10 @@ package org.openmetadata.catalog.resources.teams; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; +import static org.openmetadata.catalog.security.SecurityUtil.OWNER; + import io.dropwizard.jersey.PATCH; import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.ExternalDocumentation; @@ -65,8 +69,6 @@ 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; -import org.openmetadata.catalog.util.RestUtil.DeleteResponse; -import org.openmetadata.catalog.util.RestUtil.PatchResponse; import org.openmetadata.catalog.util.ResultList; @Slf4j @@ -309,9 +311,10 @@ public class UserResource extends EntityResource { public Response createUser( @Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateUser create) throws IOException, ParseException { - if (create.getIsAdmin() != null && create.getIsAdmin()) { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); + if (Boolean.TRUE.equals(create.getIsAdmin())) { + SecurityUtil.authorizeAdmin(authorizer, securityContext, ADMIN | BOT); } + // TODO do we need to authenticate user is creating himself? User user = getUser(securityContext, create); addHref(uriInfo, dao.create(uriInfo, user)); return Response.created(user.getHref()).entity(user).build(); @@ -332,12 +335,13 @@ public class UserResource extends EntityResource { public Response createOrUpdateUser( @Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateUser create) throws IOException, ParseException { - if ((create.getIsAdmin() != null && create.getIsAdmin()) || (create.getIsBot() != null && create.getIsBot())) { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); + if (Boolean.TRUE.equals(create.getIsAdmin()) || Boolean.TRUE.equals(create.getIsBot())) { + SecurityUtil.authorizeAdmin(authorizer, securityContext, ADMIN | BOT); } + // TODO this is different from POST method User user = getUser(securityContext, create); - SecurityUtil.checkAdminRoleOrPermissions( - authorizer, securityContext, new UserEntityInterface(user).getEntityReference()); + SecurityUtil.authorize( + authorizer, securityContext, null, new UserEntityInterface(user).getEntityReference(), ADMIN | BOT | OWNER); RestUtil.PutResponse response = dao.createOrUpdate(uriInfo, user); addHref(uriInfo, response.getEntity()); return response.toResponse(); @@ -370,17 +374,11 @@ public class UserResource extends EntityResource { if (patchOpObject.containsKey("path") && patchOpObject.containsKey("value")) { String path = patchOpObject.getString("path"); if (path.equals("/isAdmin") || path.equals("/isBot")) { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); + SecurityUtil.authorizeAdmin(authorizer, securityContext, ADMIN | BOT); } } } - User user = dao.get(uriInfo, id, Fields.EMPTY_FIELDS); - SecurityUtil.checkAdminRoleOrPermissions( - authorizer, securityContext, new UserEntityInterface(user).getEntityReference()); - PatchResponse response = - dao.patch(uriInfo, UUID.fromString(id), securityContext.getUserPrincipal().getName(), patch); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return patchInternal(uriInfo, securityContext, id, patch); } @DELETE @@ -395,9 +393,7 @@ public class UserResource extends EntityResource { }) public Response delete(@Context UriInfo uriInfo, @Context SecurityContext securityContext, @PathParam("id") String id) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); - DeleteResponse response = dao.delete(securityContext.getUserPrincipal().getName(), id); - return response.toResponse(); + return delete(uriInfo, securityContext, id, false, ADMIN | BOT); } private User getUser(SecurityContext securityContext, CreateUser create) throws IOException { diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/topics/TopicResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/topics/TopicResource.java index dc98aecda69..45b1aaab485 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/topics/TopicResource.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/topics/TopicResource.java @@ -13,7 +13,9 @@ package org.openmetadata.catalog.resources.topics; -import static org.openmetadata.catalog.Entity.FIELD_OWNER; +import static org.openmetadata.catalog.security.SecurityUtil.ADMIN; +import static org.openmetadata.catalog.security.SecurityUtil.BOT; +import static org.openmetadata.catalog.security.SecurityUtil.OWNER; import com.google.inject.Inject; import io.swagger.annotations.Api; @@ -59,13 +61,8 @@ import org.openmetadata.catalog.jdbi3.TopicRepository; import org.openmetadata.catalog.resources.Collection; 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.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; import org.openmetadata.catalog.util.ResultList; @Path("/v1/topics") @@ -278,11 +275,8 @@ public class TopicResource extends EntityResource { }) public Response create(@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateTopic create) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); Topic topic = getTopic(securityContext, create); - - topic = addHref(uriInfo, dao.create(uriInfo, topic)); - return Response.created(topic.getHref()).entity(topic).build(); + return create(uriInfo, securityContext, topic, ADMIN | BOT); } @PATCH @@ -307,19 +301,7 @@ public class TopicResource extends EntityResource { })) JsonPatch patch) throws IOException, ParseException { - Fields fields = getFields(FIELD_OWNER); - Topic topic = dao.get(uriInfo, id, fields); - SecurityUtil.checkAdminRoleOrPermissions( - authorizer, - securityContext, - dao.getEntityInterface(topic).getEntityReference(), - dao.getOwnerReference(topic), - patch); - - PatchResponse response = - dao.patch(uriInfo, UUID.fromString(id), securityContext.getUserPrincipal().getName(), patch); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return patchInternal(uriInfo, securityContext, id, patch); } @PUT @@ -337,10 +319,7 @@ public class TopicResource extends EntityResource { @Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateTopic create) throws IOException, ParseException { Topic topic = getTopic(securityContext, create); - SecurityUtil.checkAdminRoleOrPermissions(authorizer, securityContext, dao.getOriginalOwner(topic)); - PutResponse response = dao.createOrUpdate(uriInfo, topic); - addHref(uriInfo, response.getEntity()); - return response.toResponse(); + return createOrUpdate(uriInfo, securityContext, topic, ADMIN | BOT | OWNER); } @PUT @@ -395,9 +374,7 @@ public class TopicResource extends EntityResource { }) public Response delete(@Context UriInfo uriInfo, @Context SecurityContext securityContext, @PathParam("id") String id) throws IOException, ParseException { - SecurityUtil.checkAdminOrBotRole(authorizer, securityContext); - DeleteResponse response = dao.delete(securityContext.getUserPrincipal().getName(), id); - return response.toResponse(); + return delete(uriInfo, securityContext, id, false, ADMIN | BOT); } private Topic getTopic(SecurityContext securityContext, CreateTopic create) { diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/AuthenticationContext.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/AuthenticationContext.java index fbc1ffaf25b..f59ad17eac8 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/AuthenticationContext.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/AuthenticationContext.java @@ -17,16 +17,16 @@ import java.security.Principal; /** Holds context information of authenticated user, which will be used for authorization. */ public final class AuthenticationContext { - private Principal principal; + private final Principal principal; + + public AuthenticationContext(Principal principal) { + this.principal = principal; + } public Principal getPrincipal() { return principal; } - public void setPrincipal(Principal principal) { - this.principal = principal; - } - @Override public String toString() { return "AuthenticationContext{" + ", principal=" + principal + '}'; diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/SecurityUtil.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/SecurityUtil.java index 029f0d7f13f..d3a2e04a0f5 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/SecurityUtil.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/SecurityUtil.java @@ -30,53 +30,50 @@ import org.openmetadata.catalog.type.MetadataOperation; import org.openmetadata.catalog.util.JsonPatchUtils; public final class SecurityUtil { + public static final int ADMIN = 1; + public static final int BOT = 2; + public static final int OWNER = 4; + public static final int PERMISSIONS = 8; + private SecurityUtil() {} - public static void checkAdminRole(Authorizer authorizer, SecurityContext securityContext) { - Principal principal = securityContext.getUserPrincipal(); - AuthenticationContext authenticationCtx = SecurityUtil.getAuthenticationContext(principal); - if (!authorizer.isAdmin(authenticationCtx)) { - throw new AuthorizationException(notAdmin(principal)); + public static void authorizeAdmin(Authorizer authorizer, SecurityContext securityContext, int checkFlags) { + if (checkOwner(checkFlags) || checkPermissions(checkFlags)) { + throw new IllegalArgumentException("Only ADMIN or BOT authorization is allowed"); } + AuthenticationContext authenticationCtx = SecurityUtil.getAuthenticationContext(securityContext); + if (authorizer.isAdmin(authenticationCtx)) { + return; + } + if (checkBot(checkFlags) && authorizer.isBot(authenticationCtx)) { + return; + } + throw new AuthorizationException(notAdmin(authenticationCtx.getPrincipal())); } - public static Boolean isAdminOrBotRole(Authorizer authorizer, SecurityContext securityContext) { - try { - checkAdminOrBotRole(authorizer, securityContext); - return true; - } catch (AuthorizationException e) { - return false; + public static void authorize( + Authorizer authorizer, + SecurityContext securityContext, + EntityReference entity, + EntityReference owner, + int checkFlags) { + AuthenticationContext authenticationCtx = SecurityUtil.getAuthenticationContext(securityContext); + if (authorizer.isAdmin(authenticationCtx)) { + return; } - } - - public static void checkAdminOrBotRole(Authorizer authorizer, SecurityContext securityContext) { - Principal principal = securityContext.getUserPrincipal(); - AuthenticationContext authenticationCtx = SecurityUtil.getAuthenticationContext(principal); - if (!authorizer.isAdmin(authenticationCtx) && !authorizer.isBot(authenticationCtx)) { - throw new AuthorizationException(notAdmin(principal)); + if (checkFlags == 0) { + throw new AuthorizationException(notAdmin(authenticationCtx.getPrincipal())); } - } - - public static void checkAdminOrBotOrOwner( - Authorizer authorizer, SecurityContext securityContext, EntityReference ownerReference) { - Principal principal = securityContext.getUserPrincipal(); - AuthenticationContext authenticationCtx = SecurityUtil.getAuthenticationContext(principal); - if (!authorizer.isAdmin(authenticationCtx) - && !authorizer.isBot(authenticationCtx) - && !authorizer.isOwner(authenticationCtx, ownerReference)) { - throw new AuthorizationException(noPermission(principal)); + if ((checkFlags | BOT) > 0 && authorizer.isBot(authenticationCtx)) { + return; } - } - - public static void checkAdminRoleOrPermissions( - Authorizer authorizer, SecurityContext securityContext, EntityReference entityReference) { - Principal principal = securityContext.getUserPrincipal(); - AuthenticationContext authenticationCtx = SecurityUtil.getAuthenticationContext(principal); - if (!authorizer.isAdmin(authenticationCtx) - && !authorizer.isBot(authenticationCtx) - && !authorizer.hasPermissions(authenticationCtx, entityReference)) { - throw new AuthorizationException(noPermission(principal)); + if ((checkFlags | OWNER) > 0 && authorizer.isOwner(authenticationCtx, owner)) { + return; } + if ((checkFlags | PERMISSIONS) > 0 && authorizer.hasPermissions(authenticationCtx, entity)) { + return; + } + throw new AuthorizationException(noPermission(authenticationCtx.getPrincipal())); } /** This helper function checks if user has permission to perform the given metadata operation. */ @@ -85,15 +82,14 @@ public final class SecurityUtil { SecurityContext securityContext, EntityReference entityReference, MetadataOperation metadataOperation) { - Principal principal = securityContext.getUserPrincipal(); - AuthenticationContext authenticationCtx = SecurityUtil.getAuthenticationContext(principal); + AuthenticationContext authenticationCtx = SecurityUtil.getAuthenticationContext(securityContext); if (authorizer.isAdmin(authenticationCtx) || authorizer.isBot(authenticationCtx)) { return; } if (!authorizer.hasPermissions(authenticationCtx, entityReference, metadataOperation)) { - throw new AuthorizationException(noPermission(principal, metadataOperation.value())); + throw new AuthorizationException(noPermission(authenticationCtx.getPrincipal(), metadataOperation.value())); } } @@ -108,8 +104,7 @@ public final class SecurityUtil { EntityReference entityReference, EntityReference ownerReference, JsonPatch patch) { - Principal principal = securityContext.getUserPrincipal(); - AuthenticationContext authenticationCtx = SecurityUtil.getAuthenticationContext(principal); + AuthenticationContext authenticationCtx = SecurityUtil.getAuthenticationContext(securityContext); if (authorizer.isAdmin(authenticationCtx) || authorizer.isBot(authenticationCtx) @@ -121,11 +116,11 @@ public final class SecurityUtil { // If there are no specific metadata operations that can be determined from the JSON Patch, deny the changes. if (metadataOperations.isEmpty()) { - throw new AuthorizationException(noPermission(principal)); + throw new AuthorizationException(noPermission(authenticationCtx.getPrincipal())); } for (MetadataOperation metadataOperation : metadataOperations) { if (!authorizer.hasPermissions(authenticationCtx, entityReference, metadataOperation)) { - throw new AuthorizationException(noPermission(principal, metadataOperation.value())); + throw new AuthorizationException(noPermission(authenticationCtx.getPrincipal(), metadataOperation.value())); } } } @@ -136,13 +131,7 @@ public final class SecurityUtil { public static AuthenticationContext getAuthenticationContext(SecurityContext securityContext) { Principal principal = securityContext.getUserPrincipal(); - return SecurityUtil.getAuthenticationContext(principal); - } - - private static AuthenticationContext getAuthenticationContext(Principal principal) { - AuthenticationContext context = new AuthenticationContext(); - context.setPrincipal(principal); - return context; + return new AuthenticationContext(principal); } public static Map authHeaders(String username) { @@ -172,4 +161,16 @@ public final class SecurityUtil { } return target.request(); } + + public static boolean checkBot(int checkFlags) { + return (checkFlags & BOT) > 0; + } + + public static boolean checkOwner(int checkFlags) { + return (checkFlags & OWNER) > 0; + } + + public static boolean checkPermissions(int checkFlags) { + return (checkFlags & PERMISSIONS) > 0; + } } diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/util/RestUtil.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/util/RestUtil.java index d6fcaa87440..35d75eebdc6 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/util/RestUtil.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/util/RestUtil.java @@ -210,10 +210,6 @@ public final class RestUtil { private final T entity; private final String changeType; - /** - * Response.Status.CREATED when PUT operation creates a new entity or Response.Status.OK when PUT operation updates - * a new entity - */ public DeleteResponse(T entity, String changeType) { this.entity = entity; this.changeType = changeType; diff --git a/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/teams/RoleResourceTest.java b/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/teams/RoleResourceTest.java index ad55ee0fd23..ab953bd5704 100644 --- a/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/teams/RoleResourceTest.java +++ b/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/teams/RoleResourceTest.java @@ -17,7 +17,7 @@ import static javax.ws.rs.core.Response.Status.FORBIDDEN; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.fail; -import static org.openmetadata.catalog.exception.CatalogExceptionMessage.notAdmin; +import static org.openmetadata.catalog.exception.CatalogExceptionMessage.noPermission; import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS; import static org.openmetadata.catalog.util.TestUtils.TEST_AUTH_HEADERS; import static org.openmetadata.catalog.util.TestUtils.TEST_USER_NAME; @@ -166,7 +166,9 @@ public class RoleResourceTest extends EntityResourceTest { String originalJson = JsonUtils.pojoToJson(role); role.setDisplayName("newDisplayName"); assertResponse( - () -> patchEntity(role.getId(), originalJson, role, TEST_AUTH_HEADERS), FORBIDDEN, notAdmin(TEST_USER_NAME)); + () -> patchEntity(role.getId(), originalJson, role, TEST_AUTH_HEADERS), + FORBIDDEN, + noPermission(TEST_USER_NAME)); } private static void validateRole( diff --git a/catalog-rest-service/src/test/java/org/openmetadata/catalog/util/TestUtils.java b/catalog-rest-service/src/test/java/org/openmetadata/catalog/util/TestUtils.java index 049e89ebd60..73fe9aca0e1 100644 --- a/catalog-rest-service/src/test/java/org/openmetadata/catalog/util/TestUtils.java +++ b/catalog-rest-service/src/test/java/org/openmetadata/catalog/util/TestUtils.java @@ -156,13 +156,12 @@ public final class TestUtils { } public static void post(WebTarget target, Map headers) throws HttpResponseException { - Response response = SecurityUtil.addHeaders(target, headers).post(null); - readResponse(response, Status.CREATED.getStatusCode()); + post(target, null, headers); } public static void post(WebTarget target, K request, Map headers) throws HttpResponseException { - Response response = - SecurityUtil.addHeaders(target, headers).post(Entity.entity(request, MediaType.APPLICATION_JSON)); + Entity entity = (request == null) ? null : Entity.entity(request, MediaType.APPLICATION_JSON); + Response response = SecurityUtil.addHeaders(target, headers).post(entity); readResponse(response, Status.CREATED.getStatusCode()); } @@ -215,7 +214,7 @@ public final class TestUtils { } public static void assertDeleted(List list, Boolean expected) { - listOrEmpty(list).forEach(e -> expected.equals(e.getDeleted())); + listOrEmpty(list).forEach(e -> assertEquals(expected, e.getDeleted())); } public static void validateEntityReference(EntityReference ref) {