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 5469debd27a..b7281809122 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 @@ -313,7 +313,7 @@ public class DashboardServiceResource { @Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateDashboardService update) throws IOException, ParseException { DashboardService service = getService(update, securityContext); - SecurityUtil.checkAdminRoleOrPermissions(authorizer, securityContext, dao.getOriginalOwner(service)); + SecurityUtil.checkAdminOrBotOrOwner(authorizer, securityContext, dao.getOriginalOwner(service)); PutResponse response = dao.createOrUpdate(uriInfo, service, true); addHref(uriInfo, response.getEntity()); return response.toResponse(); 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 577c53b56b1..2f18248924f 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 @@ -334,7 +334,7 @@ public class DatabaseServiceResource { @Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateDatabaseService update) throws IOException, ParseException { DatabaseService service = getService(update, securityContext); - SecurityUtil.checkAdminRoleOrPermissions(authorizer, securityContext, dao.getOriginalOwner(service)); + SecurityUtil.checkAdminOrBotOrOwner(authorizer, securityContext, dao.getOriginalOwner(service)); PutResponse response = dao.createOrUpdate(uriInfo, service, true); addHref(uriInfo, decryptOrNullify(securityContext, response.getEntity())); return response.toResponse(); 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 6117cc12632..c0859a97b98 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 @@ -320,7 +320,7 @@ public class MessagingServiceResource { @Valid CreateMessagingService update) throws IOException, ParseException { MessagingService service = getService(update, securityContext); - SecurityUtil.checkAdminRoleOrPermissions(authorizer, securityContext, dao.getOriginalOwner(service)); + SecurityUtil.checkAdminOrBotOrOwner(authorizer, securityContext, dao.getOriginalOwner(service)); PutResponse response = dao.createOrUpdate(uriInfo, service, true); addHref(uriInfo, response.getEntity()); return response.toResponse(); 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 5b03de823f3..19a0f76115b 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 @@ -316,7 +316,7 @@ public class PipelineServiceResource { @Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreatePipelineService update) throws IOException, ParseException { PipelineService service = getService(update, securityContext); - SecurityUtil.checkAdminRoleOrPermissions(authorizer, securityContext, dao.getOriginalOwner(service)); + SecurityUtil.checkAdminOrBotOrOwner(authorizer, securityContext, dao.getOriginalOwner(service)); PutResponse response = dao.createOrUpdate(uriInfo, service, true); addHref(uriInfo, response.getEntity()); return response.toResponse(); diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/Authorizer.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/Authorizer.java index cd7ed71c26d..62bf280b587 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/Authorizer.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/Authorizer.java @@ -42,4 +42,6 @@ public interface Authorizer { boolean isAdmin(AuthenticationContext ctx); boolean isBot(AuthenticationContext ctx); + + boolean isOwner(AuthenticationContext ctx, EntityReference entityReference); } diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/DefaultAuthorizer.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/DefaultAuthorizer.java index c5785a7575e..0dcc4e7afdf 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/DefaultAuthorizer.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/DefaultAuthorizer.java @@ -240,6 +240,22 @@ public class DefaultAuthorizer implements Authorizer { } } + @Override + public boolean isOwner(AuthenticationContext ctx, EntityReference owner) { + validateAuthenticationContext(ctx); + String userName = SecurityUtil.getUserName(ctx); + EntityUtil.Fields fields = new EntityUtil.Fields(UserResource.ALLOWED_FIELDS, FIELDS_PARAM); + try { + User user = userRepository.getByName(null, userName, fields); + if (owner == null) { + return false; + } + return isOwnedByUser(user, owner); + } catch (IOException | EntityNotFoundException | ParseException ex) { + return false; + } + } + private void validateAuthenticationContext(AuthenticationContext ctx) { if (ctx == null || ctx.getPrincipal() == null) { throw new AuthenticationException("No principal in AuthenticationContext"); diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/NoopAuthorizer.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/NoopAuthorizer.java index dc0b111f541..e064495da1a 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/NoopAuthorizer.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/security/NoopAuthorizer.java @@ -71,6 +71,11 @@ public class NoopAuthorizer implements Authorizer { return true; } + @Override + public boolean isOwner(AuthenticationContext ctx, EntityReference entityReference) { + return true; + } + private void addAnonymousUser() { EntityUtil.Fields fields = new EntityUtil.Fields(UserResource.ALLOWED_FIELDS, FIELDS_PARAM); String username = "anonymous"; 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 e0f1633f0a0..5ce98822cba 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 @@ -57,6 +57,17 @@ public final class SecurityUtil { } } + 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)); + } + } + public static void checkAdminRoleOrPermissions( Authorizer authorizer, SecurityContext securityContext, EntityReference entityReference) { Principal principal = securityContext.getUserPrincipal();