This is an automated email from the ASF dual-hosted git repository.

roryqi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git


The following commit(s) were added to refs/heads/main by this push:
     new 0ab370555e [#7889] feat(authz): support partition operation 
authorization (#8967)
0ab370555e is described below

commit 0ab370555ed759af290a893a36f70411a02577fe
Author: yangyang zhong <[email protected]>
AuthorDate: Fri Oct 31 14:40:57 2025 +0800

    [#7889] feat(authz): support partition operation authorization (#8967)
    
    ### What changes were proposed in this pull request?
    
    support partition operation authorization
    
    ### Why are the changes needed?
    
    Fix: #7889
    
    ### Does this PR introduce _any_ user-facing change?
    
    None
    
    ### How was this patch tested?
    
    
    
org.apache.gravitino.client.integration.test.authorization.PartitionAuthorizationIT
---
 .../authorization/PartitionAuthorizationIT.java    | 253 +++++++++++++++++++++
 .../AuthorizationExpressionConstants.java          |   7 +
 .../web/filter/GravitinoInterceptionService.java   |   4 +-
 .../server/web/rest/PartitionOperations.java       |  53 +++--
 .../gravitino/server/web/rest/TableOperations.java |  12 +-
 5 files changed, 302 insertions(+), 27 deletions(-)

diff --git 
a/clients/client-java/src/test/java/org/apache/gravitino/client/integration/test/authorization/PartitionAuthorizationIT.java
 
b/clients/client-java/src/test/java/org/apache/gravitino/client/integration/test/authorization/PartitionAuthorizationIT.java
new file mode 100644
index 0000000000..b25fc1f0f4
--- /dev/null
+++ 
b/clients/client-java/src/test/java/org/apache/gravitino/client/integration/test/authorization/PartitionAuthorizationIT.java
@@ -0,0 +1,253 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.gravitino.client.integration.test.authorization;
+
+import static 
org.apache.gravitino.client.integration.test.StatisticIT.TABLE_COMMENT;
+import static org.junit.Assert.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.gravitino.Catalog;
+import org.apache.gravitino.MetadataObject;
+import org.apache.gravitino.MetadataObjects;
+import org.apache.gravitino.NameIdentifier;
+import org.apache.gravitino.authorization.Privileges;
+import org.apache.gravitino.authorization.SecurableObject;
+import org.apache.gravitino.authorization.SecurableObjects;
+import org.apache.gravitino.client.GravitinoMetalake;
+import org.apache.gravitino.exceptions.ForbiddenException;
+import org.apache.gravitino.integration.test.container.ContainerSuite;
+import org.apache.gravitino.integration.test.container.HiveContainer;
+import org.apache.gravitino.rel.Column;
+import org.apache.gravitino.rel.SupportsPartitions;
+import org.apache.gravitino.rel.Table;
+import org.apache.gravitino.rel.TableCatalog;
+import org.apache.gravitino.rel.expressions.literals.Literal;
+import org.apache.gravitino.rel.expressions.literals.Literals;
+import org.apache.gravitino.rel.expressions.transforms.Transform;
+import org.apache.gravitino.rel.expressions.transforms.Transforms;
+import org.apache.gravitino.rel.partitions.IdentityPartition;
+import org.apache.gravitino.rel.partitions.Partitions;
+import org.apache.gravitino.rel.types.Types;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+
+@Tag("gravitino-docker-test")
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
+public class PartitionAuthorizationIT extends BaseRestApiAuthorizationIT {
+
+  private static final String CATALOG = "catalog";
+  private static final String SCHEMA = "partitionSchema";
+  private static final ContainerSuite containerSuite = 
ContainerSuite.getInstance();
+  private static String hmsUri;
+  private static String role = "role";
+
+  @BeforeAll
+  public void startIntegrationTest() throws Exception {
+    containerSuite.startHiveContainer();
+    super.startIntegrationTest();
+    hmsUri =
+        String.format(
+            "thrift://%s:%d",
+            containerSuite.getHiveContainer().getContainerIpAddress(),
+            HiveContainer.HIVE_METASTORE_PORT);
+    Map<String, String> properties = Maps.newHashMap();
+    properties.put("metastore.uris", hmsUri);
+    client
+        .loadMetalake(METALAKE)
+        .createCatalog(CATALOG, Catalog.Type.RELATIONAL, "hive", "comment", 
properties)
+        .asSchemas()
+        .createSchema(SCHEMA, "test", new HashMap<>());
+    // try to load the schema as normal user, expect failure
+    assertThrows(
+        "Can not access metadata {" + CATALOG + "." + SCHEMA + "}.",
+        RuntimeException.class,
+        () -> {
+          normalUserClient
+              .loadMetalake(METALAKE)
+              .loadCatalog(CATALOG)
+              .asSchemas()
+              .loadSchema(SCHEMA);
+        });
+    // grant tester privilege
+    List<SecurableObject> securableObjects = new ArrayList<>();
+    GravitinoMetalake gravitinoMetalake = client.loadMetalake(METALAKE);
+    SecurableObject catalogObject =
+        SecurableObjects.ofCatalog(CATALOG, 
ImmutableList.of(Privileges.UseCatalog.allow()));
+    securableObjects.add(catalogObject);
+    gravitinoMetalake.createRole(role, new HashMap<>(), securableObjects);
+    gravitinoMetalake.grantRolesToUser(ImmutableList.of(role), NORMAL_USER);
+    gravitinoMetalake.grantPrivilegesToRole(
+        role,
+        catalogObject,
+        ImmutableSet.of(
+            Privileges.SelectTable.allow(),
+            Privileges.UseSchema.allow(),
+            Privileges.UseCatalog.allow()));
+    // normal user can load the catalog but not the schema
+    Catalog catalogLoadByNormalUser = 
normalUserClient.loadMetalake(METALAKE).loadCatalog(CATALOG);
+    assertEquals(CATALOG, catalogLoadByNormalUser.name());
+    TableCatalog tableCatalog = 
client.loadMetalake(METALAKE).loadCatalog(CATALOG).asTableCatalog();
+    Column[] columns = createColumns();
+
+    NameIdentifier nameIdentifier = NameIdentifier.of(SCHEMA, "table1");
+
+    tableCatalog.createTable(
+        nameIdentifier,
+        columns,
+        TABLE_COMMENT,
+        new HashMap<>(),
+        new Transform[] {Transforms.identity(columns[0].name())});
+    // normal user cannot create table
+    TableCatalog tableCatalogNormalUser =
+        
normalUserClient.loadMetalake(METALAKE).loadCatalog(CATALOG).asTableCatalog();
+    assertThrows(
+        "Can not access metadata {" + CATALOG + "." + SCHEMA + "}.",
+        ForbiddenException.class,
+        () -> {
+          tableCatalogNormalUser.createTable(
+              NameIdentifier.of(SCHEMA, "table2"), createColumns(), "test2", 
new HashMap<>());
+        });
+  }
+
+  @AfterAll
+  public void stopIntegrationTest() throws IOException, InterruptedException {
+    
client.loadMetalake(METALAKE).loadCatalog(CATALOG).asSchemas().dropSchema(SCHEMA,
 true);
+    super.stopIntegrationTest();
+  }
+
+  private Column[] createColumns() {
+    return new Column[] {Column.of("col1", Types.StringType.get())};
+  }
+
+  @Test
+  @Order(1)
+  public void testCreatePartition() {
+    TableCatalog tableCatalog = 
client.loadMetalake(METALAKE).loadCatalog(CATALOG).asTableCatalog();
+    Table table1 = tableCatalog.loadTable(NameIdentifier.of(SCHEMA, "table1"));
+
+    TableCatalog tableCatalogNormalUser =
+        
normalUserClient.loadMetalake(METALAKE).loadCatalog(CATALOG).asTableCatalog();
+    SupportsPartitions supportsPartitions = 
getTable1(tableCatalogNormalUser).supportPartitions();
+    assertThrows(
+        "Can not access metadata {" + CATALOG + "." + SCHEMA + "}.",
+        ForbiddenException.class,
+        () -> {
+          supportsPartitions.addPartition(genPartition());
+        });
+    SupportsPartitions supportsPartitionsByAdmin = table1.supportPartitions();
+    supportsPartitionsByAdmin.addPartition(genPartition());
+  }
+
+  private static Table getTable1(TableCatalog tableCatalogNormalUser) {
+    return tableCatalogNormalUser.loadTable(NameIdentifier.of(SCHEMA, 
"table1"));
+  }
+
+  private static IdentityPartition genPartition() {
+    return Partitions.identity(
+        new String[][] {{"col1"}}, new Literal[] 
{Literals.stringLiteral("1")});
+  }
+
+  @Test
+  @Order(2)
+  public void testListPartition() {
+    TableCatalog tableCatalog = 
client.loadMetalake(METALAKE).loadCatalog(CATALOG).asTableCatalog();
+    Table table1 = tableCatalog.loadTable(NameIdentifier.of(SCHEMA, "table1"));
+
+    TableCatalog tableCatalogNormalUser =
+        
normalUserClient.loadMetalake(METALAKE).loadCatalog(CATALOG).asTableCatalog();
+    SupportsPartitions supportsPartitions =
+        tableCatalogNormalUser.loadTable(NameIdentifier.of(SCHEMA, 
"table1")).supportPartitions();
+    MetadataObject metadataObject = MetadataObjects.of(null, CATALOG, 
MetadataObject.Type.CATALOG);
+    client
+        .loadMetalake(METALAKE)
+        .revokePrivilegesFromRole(
+            role, metadataObject, 
ImmutableSet.of(Privileges.SelectTable.allow()));
+    assertThrows(
+        "Can not access metadata {" + CATALOG + "." + SCHEMA + "}.",
+        ForbiddenException.class,
+        supportsPartitions::listPartitions);
+    SupportsPartitions supportsPartitionsByAdmin = table1.supportPartitions();
+    supportsPartitionsByAdmin.listPartitions();
+    client
+        .loadMetalake(METALAKE)
+        .grantPrivilegesToRole(
+            role, metadataObject, 
ImmutableSet.of(Privileges.SelectTable.allow()));
+  }
+
+  @Test
+  @Order(3)
+  public void testLoadPartition() {
+    TableCatalog tableCatalog = 
client.loadMetalake(METALAKE).loadCatalog(CATALOG).asTableCatalog();
+    Table table1 = tableCatalog.loadTable(NameIdentifier.of(SCHEMA, "table1"));
+
+    TableCatalog tableCatalogNormalUser =
+        
normalUserClient.loadMetalake(METALAKE).loadCatalog(CATALOG).asTableCatalog();
+    SupportsPartitions supportsPartitions =
+        tableCatalogNormalUser.loadTable(NameIdentifier.of(SCHEMA, 
"table1")).supportPartitions();
+    MetadataObject metadataObject = MetadataObjects.of(null, CATALOG, 
MetadataObject.Type.CATALOG);
+    client
+        .loadMetalake(METALAKE)
+        .revokePrivilegesFromRole(
+            role, metadataObject, 
ImmutableSet.of(Privileges.SelectTable.allow()));
+    assertThrows(
+        "Can not access metadata {" + CATALOG + "." + SCHEMA + "}.",
+        ForbiddenException.class,
+        () -> {
+          supportsPartitions.getPartition("col1=1");
+        });
+    SupportsPartitions supportsPartitionsByAdmin = table1.supportPartitions();
+    supportsPartitionsByAdmin.getPartition("col1=1");
+    client
+        .loadMetalake(METALAKE)
+        .grantPrivilegesToRole(
+            role, metadataObject, 
ImmutableSet.of(Privileges.SelectTable.allow()));
+  }
+
+  @Test
+  @Order(4)
+  public void testDropPartition() {
+    TableCatalog tableCatalog = 
client.loadMetalake(METALAKE).loadCatalog(CATALOG).asTableCatalog();
+    Table table1 = tableCatalog.loadTable(NameIdentifier.of(SCHEMA, "table1"));
+
+    TableCatalog tableCatalogNormalUser =
+        
normalUserClient.loadMetalake(METALAKE).loadCatalog(CATALOG).asTableCatalog();
+    SupportsPartitions supportsPartitions =
+        tableCatalogNormalUser.loadTable(NameIdentifier.of(SCHEMA, 
"table1")).supportPartitions();
+    assertThrows(
+        "Can not access metadata {" + CATALOG + "." + SCHEMA + "}.",
+        ForbiddenException.class,
+        () -> {
+          supportsPartitions.dropPartition("col1=1");
+        });
+    SupportsPartitions supportsPartitionsByAdmin = table1.supportPartitions();
+    supportsPartitionsByAdmin.dropPartition("col1=1");
+  }
+}
diff --git 
a/server-common/src/main/java/org/apache/gravitino/server/authorization/expression/AuthorizationExpressionConstants.java
 
b/server-common/src/main/java/org/apache/gravitino/server/authorization/expression/AuthorizationExpressionConstants.java
index 5d5017d7f1..47dd6cb654 100644
--- 
a/server-common/src/main/java/org/apache/gravitino/server/authorization/expression/AuthorizationExpressionConstants.java
+++ 
b/server-common/src/main/java/org/apache/gravitino/server/authorization/expression/AuthorizationExpressionConstants.java
@@ -40,6 +40,13 @@ public class AuthorizationExpressionConstants {
                   ANY_USE_CATALOG && ANY_USE_SCHEMA  && (TABLE::OWNER || 
ANY_SELECT_TABLE || ANY_MODIFY_TABLE)
                   """;
 
+  public static final String alterTableAuthorizationExpression =
+      """
+                  ANY(OWNER, METALAKE, CATALOG) ||
+                  SCHEMA_OWNER_WITH_USE_CATALOG ||
+                  ANY_USE_CATALOG && ANY_USE_SCHEMA && (TABLE::OWNER || 
ANY_MODIFY_TABLE)
+                  """;
+
   public static final String loadTopicsAuthorizationExpression =
       """
           ANY(OWNER, METALAKE, CATALOG) ||
diff --git 
a/server/src/main/java/org/apache/gravitino/server/web/filter/GravitinoInterceptionService.java
 
b/server/src/main/java/org/apache/gravitino/server/web/filter/GravitinoInterceptionService.java
index dec93f882f..a43d4d4236 100644
--- 
a/server/src/main/java/org/apache/gravitino/server/web/filter/GravitinoInterceptionService.java
+++ 
b/server/src/main/java/org/apache/gravitino/server/web/filter/GravitinoInterceptionService.java
@@ -54,6 +54,7 @@ import org.apache.gravitino.server.web.rest.GroupOperations;
 import org.apache.gravitino.server.web.rest.MetalakeOperations;
 import org.apache.gravitino.server.web.rest.ModelOperations;
 import org.apache.gravitino.server.web.rest.OwnerOperations;
+import org.apache.gravitino.server.web.rest.PartitionOperations;
 import org.apache.gravitino.server.web.rest.PermissionOperations;
 import org.apache.gravitino.server.web.rest.RoleOperations;
 import org.apache.gravitino.server.web.rest.SchemaOperations;
@@ -93,7 +94,8 @@ public class GravitinoInterceptionService implements 
InterceptionService {
             PermissionOperations.class.getName(),
             RoleOperations.class.getName(),
             OwnerOperations.class.getName(),
-            StatisticOperations.class.getName()));
+            StatisticOperations.class.getName(),
+            PartitionOperations.class.getName()));
   }
 
   @Override
diff --git 
a/server/src/main/java/org/apache/gravitino/server/web/rest/PartitionOperations.java
 
b/server/src/main/java/org/apache/gravitino/server/web/rest/PartitionOperations.java
index ec7cfc3c40..b4bf0eeed4 100644
--- 
a/server/src/main/java/org/apache/gravitino/server/web/rest/PartitionOperations.java
+++ 
b/server/src/main/java/org/apache/gravitino/server/web/rest/PartitionOperations.java
@@ -36,6 +36,8 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.Response;
+import org.apache.gravitino.Entity;
+import org.apache.gravitino.MetadataObject;
 import org.apache.gravitino.NameIdentifier;
 import org.apache.gravitino.catalog.PartitionDispatcher;
 import org.apache.gravitino.dto.rel.partitions.PartitionDTO;
@@ -47,6 +49,9 @@ import org.apache.gravitino.dto.responses.PartitionResponse;
 import org.apache.gravitino.dto.util.DTOConverters;
 import org.apache.gravitino.metrics.MetricNames;
 import org.apache.gravitino.rel.partitions.Partition;
+import 
org.apache.gravitino.server.authorization.annotations.AuthorizationExpression;
+import 
org.apache.gravitino.server.authorization.annotations.AuthorizationMetadata;
+import 
org.apache.gravitino.server.authorization.expression.AuthorizationExpressionConstants;
 import org.apache.gravitino.server.web.Utils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -67,11 +72,15 @@ public class PartitionOperations {
   @Produces("application/vnd.gravitino.v1+json")
   @Timed(name = "list-partition-name." + MetricNames.HTTP_PROCESS_DURATION, 
absolute = true)
   @ResponseMetered(name = "list-partition-name", absolute = true)
+  @AuthorizationExpression(
+      expression = 
AuthorizationExpressionConstants.loadTableAuthorizationExpression,
+      accessMetadataType = MetadataObject.Type.TABLE)
   public Response listPartitionNames(
-      @PathParam("metalake") String metalake,
-      @PathParam("catalog") String catalog,
-      @PathParam("schema") String schema,
-      @PathParam("table") String table,
+      @PathParam("metalake") @AuthorizationMetadata(type = 
Entity.EntityType.METALAKE)
+          String metalake,
+      @PathParam("catalog") @AuthorizationMetadata(type = 
Entity.EntityType.CATALOG) String catalog,
+      @PathParam("schema") @AuthorizationMetadata(type = 
Entity.EntityType.SCHEMA) String schema,
+      @PathParam("table") @AuthorizationMetadata(type = 
Entity.EntityType.TABLE) String table,
       @QueryParam("details") @DefaultValue("false") boolean verbose) {
     LOG.info(
         "Received list partition {} request for table: {}.{}.{}.{}",
@@ -119,11 +128,15 @@ public class PartitionOperations {
   @Produces("application/vnd.gravitino.v1+json")
   @Timed(name = "get-partition." + MetricNames.HTTP_PROCESS_DURATION, absolute 
= true)
   @ResponseMetered(name = "get-partition", absolute = true)
+  @AuthorizationExpression(
+      expression = 
AuthorizationExpressionConstants.loadTableAuthorizationExpression,
+      accessMetadataType = MetadataObject.Type.TABLE)
   public Response getPartition(
-      @PathParam("metalake") String metalake,
-      @PathParam("catalog") String catalog,
-      @PathParam("schema") String schema,
-      @PathParam("table") String table,
+      @PathParam("metalake") @AuthorizationMetadata(type = 
Entity.EntityType.METALAKE)
+          String metalake,
+      @PathParam("catalog") @AuthorizationMetadata(type = 
Entity.EntityType.CATALOG) String catalog,
+      @PathParam("schema") @AuthorizationMetadata(type = 
Entity.EntityType.SCHEMA) String schema,
+      @PathParam("table") @AuthorizationMetadata(type = 
Entity.EntityType.TABLE) String table,
       @PathParam("partition") String partition) {
     LOG.info(
         "Received get partition request for partition[{}] of 
table[{}.{}.{}.{}]",
@@ -157,11 +170,15 @@ public class PartitionOperations {
   @Produces("application/vnd.gravitino.v1+json")
   @Timed(name = "add-partitions." + MetricNames.HTTP_PROCESS_DURATION, 
absolute = true)
   @ResponseMetered(name = "add-partitions", absolute = true)
+  @AuthorizationExpression(
+      expression = 
AuthorizationExpressionConstants.alterTableAuthorizationExpression,
+      accessMetadataType = MetadataObject.Type.TABLE)
   public Response addPartitions(
-      @PathParam("metalake") String metalake,
-      @PathParam("catalog") String catalog,
-      @PathParam("schema") String schema,
-      @PathParam("table") String table,
+      @PathParam("metalake") @AuthorizationMetadata(type = 
Entity.EntityType.METALAKE)
+          String metalake,
+      @PathParam("catalog") @AuthorizationMetadata(type = 
Entity.EntityType.CATALOG) String catalog,
+      @PathParam("schema") @AuthorizationMetadata(type = 
Entity.EntityType.SCHEMA) String schema,
+      @PathParam("table") @AuthorizationMetadata(type = 
Entity.EntityType.TABLE) String table,
       AddPartitionsRequest request) {
     LOG.info(
         "Received add {} partition(s) request for table {}.{}.{}.{} ",
@@ -197,11 +214,15 @@ public class PartitionOperations {
   @Produces("application/vnd.gravitino.v1+json")
   @Timed(name = "drop-partition." + MetricNames.HTTP_PROCESS_DURATION, 
absolute = true)
   @ResponseMetered(name = "drop-partition", absolute = true)
+  @AuthorizationExpression(
+      expression = 
AuthorizationExpressionConstants.alterTableAuthorizationExpression,
+      accessMetadataType = MetadataObject.Type.TABLE)
   public Response dropPartition(
-      @PathParam("metalake") String metalake,
-      @PathParam("catalog") String catalog,
-      @PathParam("schema") String schema,
-      @PathParam("table") String table,
+      @PathParam("metalake") @AuthorizationMetadata(type = 
Entity.EntityType.METALAKE)
+          String metalake,
+      @PathParam("catalog") @AuthorizationMetadata(type = 
Entity.EntityType.CATALOG) String catalog,
+      @PathParam("schema") @AuthorizationMetadata(type = 
Entity.EntityType.SCHEMA) String schema,
+      @PathParam("table") @AuthorizationMetadata(type = 
Entity.EntityType.TABLE) String table,
       @PathParam("partition") String partition,
       @QueryParam("purge") @DefaultValue("false") boolean purge) {
     LOG.info(
diff --git 
a/server/src/main/java/org/apache/gravitino/server/web/rest/TableOperations.java
 
b/server/src/main/java/org/apache/gravitino/server/web/rest/TableOperations.java
index ec47cf8e64..31ef89544e 100644
--- 
a/server/src/main/java/org/apache/gravitino/server/web/rest/TableOperations.java
+++ 
b/server/src/main/java/org/apache/gravitino/server/web/rest/TableOperations.java
@@ -164,10 +164,7 @@ public class TableOperations {
   @Timed(name = "load-table." + MetricNames.HTTP_PROCESS_DURATION, absolute = 
true)
   @ResponseMetered(name = "load-table", absolute = true)
   @AuthorizationExpression(
-      expression =
-          "ANY(OWNER, METALAKE, CATALOG) || "
-              + "SCHEMA_OWNER_WITH_USE_CATALOG || "
-              + "ANY_USE_CATALOG && ANY_USE_SCHEMA  && (TABLE::OWNER || 
ANY_SELECT_TABLE|| ANY_MODIFY_TABLE)",
+      expression = 
AuthorizationExpressionConstants.loadTableAuthorizationExpression,
       accessMetadataType = MetadataObject.Type.TABLE)
   public Response loadTable(
       @PathParam("metalake") @AuthorizationMetadata(type = 
Entity.EntityType.METALAKE)
@@ -198,12 +195,7 @@ public class TableOperations {
   @Timed(name = "alter-table." + MetricNames.HTTP_PROCESS_DURATION, absolute = 
true)
   @ResponseMetered(name = "alter-table", absolute = true)
   @AuthorizationExpression(
-      expression =
-          """
-                      ANY(OWNER, METALAKE, CATALOG) ||
-                       SCHEMA_OWNER_WITH_USE_CATALOG ||
-                       ANY_USE_CATALOG && ANY_USE_SCHEMA  && (TABLE::OWNER || 
ANY_MODIFY_TABLE)
-                      """,
+      expression = 
AuthorizationExpressionConstants.alterTableAuthorizationExpression,
       accessMetadataType = MetadataObject.Type.TABLE)
   public Response alterTable(
       @PathParam("metalake") @AuthorizationMetadata(type = 
Entity.EntityType.METALAKE)

Reply via email to