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

ivandika pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/master by this push:
     new f4c8a12edb0 HDDS-13635. Move ACL check in OMVolumeCreateRequest and 
OMBucketCreateRequest to pre execute (#9045)
f4c8a12edb0 is described below

commit f4c8a12edb0d5256cbbcc5d11fd2396c79470b15
Author: Sergey Soldatov <[email protected]>
AuthorDate: Tue Sep 30 07:09:22 2025 -0700

    HDDS-13635. Move ACL check in OMVolumeCreateRequest and 
OMBucketCreateRequest to pre execute (#9045)
---
 .../om/TestOMHALeaderSpecificACLEnforcement.java   | 318 +++++++++++++++++++++
 .../om/request/bucket/OMBucketCreateRequest.java   |  25 +-
 .../om/request/volume/OMVolumeCreateRequest.java   |  26 +-
 .../request/TestOMClientRequestWithUserInfo.java   |   7 +
 .../request/bucket/TestOMBucketCreateRequest.java  |  30 ++
 .../request/volume/TestOMVolumeCreateRequest.java  |  30 ++
 6 files changed, 421 insertions(+), 15 deletions(-)

diff --git 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOMHALeaderSpecificACLEnforcement.java
 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOMHALeaderSpecificACLEnforcement.java
new file mode 100644
index 00000000000..4e49a92a9c9
--- /dev/null
+++ 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOMHALeaderSpecificACLEnforcement.java
@@ -0,0 +1,318 @@
+/*
+ * 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.hadoop.ozone.om;
+
+import static 
org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_ACL_AUTHORIZER_CLASS;
+import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_ACL_ENABLED;
+import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_ADMINISTRATORS;
+import static 
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.PERMISSION_DENIED;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.hdds.utils.IOUtils;
+import org.apache.hadoop.ozone.MiniOzoneCluster;
+import org.apache.hadoop.ozone.MiniOzoneHAClusterImpl;
+import org.apache.hadoop.ozone.client.BucketArgs;
+import org.apache.hadoop.ozone.client.ObjectStore;
+import org.apache.hadoop.ozone.client.OzoneBucket;
+import org.apache.hadoop.ozone.client.OzoneClient;
+import org.apache.hadoop.ozone.client.OzoneClientFactory;
+import org.apache.hadoop.ozone.client.OzoneVolume;
+import org.apache.hadoop.ozone.client.VolumeArgs;
+import org.apache.hadoop.ozone.om.exceptions.OMException;
+import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer;
+import org.apache.hadoop.ozone.security.acl.OzoneNativeAuthorizer;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.ozone.test.GenericTestUtils;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+
+/**
+ * Integration test for OM HA leader-specific ACL enforcement.
+ * Demonstrates that ACL check responsibility depends entirely on the current 
leader,
+ * with no expectation that all leaders are synchronized. Each leader enforces
+ * ACLs based on its own configuration independently.
+ */
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+public class TestOMHALeaderSpecificACLEnforcement {
+
+  private static final String OM_SERVICE_ID = "om-service-test-admin";
+  private static final int NUM_OF_OMS = 3;
+  private static final String TEST_USER = "testuser-" + 
+      RandomStringUtils.secure().nextAlphabetic(5).toLowerCase(Locale.ROOT);
+  private static final String TEST_VOLUME = "testvol-" + 
+      RandomStringUtils.secure().nextAlphabetic(5).toLowerCase(Locale.ROOT);
+  private static final String ADMIN_VOLUME = "adminvol-" + 
+      RandomStringUtils.secure().nextAlphabetic(5).toLowerCase(Locale.ROOT);
+  private static final String TEST_BUCKET = "testbucket-" + 
+      RandomStringUtils.secure().nextAlphabetic(5).toLowerCase(Locale.ROOT);
+
+  private MiniOzoneHAClusterImpl cluster;
+  private OzoneClient client;
+  private UserGroupInformation testUserUgi;
+
+  @BeforeAll
+  public void init() throws Exception {
+    // Create test user
+    testUserUgi = UserGroupInformation.createUserForTesting(TEST_USER, new 
String[]{"testgroup"});
+    
+    // Set up and start the cluster
+    setupCluster();
+    
+    // Create admin volume that will be used for bucket permission testing
+    createAdminVolume();
+  }
+
+  @AfterAll
+  public void shutdown() {
+    IOUtils.closeQuietly(client);
+    if (cluster != null) {
+      cluster.shutdown();
+    }
+  }
+
+  /**
+   * Main test method that validates leader-specific ACL enforcement in OM HA.
+   * 1. Creates a mini cluster with OM HA
+   * 2. Adds test user as admin to only the current leader OM node
+   * 3. Validates user can perform admin operations when leader has the config
+   * 4. Transfers leadership to another node (with independent configuration)
+   * 5. Demonstrates that ACL enforcement depends entirely on new leader's 
config
+   */
+  @Test
+  public void testOMHAAdminPrivilegesAfterLeadershipChange() throws Exception {
+    // Step 1: Get the current leader OM
+    OzoneManager currentLeader = cluster.getOMLeader();
+    String leaderNodeId = currentLeader.getOMNodeId();
+    
+    // Step 2: Add test user as admin only to the current leader OM
+    addAdminToSpecificOM(currentLeader, TEST_USER);
+    
+    // Verify admin was added
+    assertTrue(currentLeader.getOmAdminUsernames().contains(TEST_USER),
+        "Test user should be admin on leader OM");
+    
+    // Step 3: Test volume and bucket creation as test user (should succeed)
+    testVolumeAndBucketCreationAsUser(true);
+    
+    // Step 4: Force leadership transfer to another OM node
+    OzoneManager newLeader = transferLeadershipToAnotherNode(currentLeader);
+    assertNotEquals(leaderNodeId, newLeader.getOMNodeId(), 
+        "Leadership should have transferred to a different node");
+    
+    // Step 5: Verify test user is NOT admin on new leader
+    assertTrue(!newLeader.getOmAdminUsernames().contains(TEST_USER),
+        "Test user should NOT be admin on new leader OM");
+    
+    // Step 6: Test volume and bucket creation as test user (should fail)
+    testVolumeAndBucketCreationAsUser(false);
+  }
+
+  /**
+   * Sets up the OM HA cluster with node-specific admin configurations.
+   */
+  private void setupCluster() throws Exception {
+    OzoneConfiguration conf = createBaseConfiguration();
+    conf.setClass(OZONE_ACL_AUTHORIZER_CLASS, OzoneNativeAuthorizer.class,
+        IAccessAuthorizer.class);
+    
+    // Build HA cluster
+    MiniOzoneHAClusterImpl.Builder builder = 
MiniOzoneCluster.newHABuilder(conf);
+    builder.setOMServiceId(OM_SERVICE_ID)
+        .setNumOfOzoneManagers(NUM_OF_OMS)
+        .setNumDatanodes(3);
+    
+    cluster = builder.build();
+    cluster.waitForClusterToBeReady();
+    
+    // Create client
+    client = OzoneClientFactory.getRpcClient(OM_SERVICE_ID, conf);
+  }
+
+  /**
+   * Creates base configuration for the cluster.
+   */
+  private OzoneConfiguration createBaseConfiguration() throws IOException {
+    OzoneConfiguration conf = new OzoneConfiguration();
+    
+    // Enable ACL for proper permission testing
+    conf.setBoolean(OZONE_ACL_ENABLED, true);
+    
+    // Set current user as initial admin (needed for cluster setup)
+    String currentUser = 
UserGroupInformation.getCurrentUser().getShortUserName();
+    conf.set(OZONE_ADMINISTRATORS, currentUser);
+    
+    return conf;
+  }
+
+  /**
+   * Creates an admin volume that will be used for testing bucket creation 
permissions.
+   * This volume is created by the admin user, so non-admin users should not 
be able
+   * to create buckets in it.
+   */
+  private void createAdminVolume() throws Exception {
+    ObjectStore adminObjectStore = client.getObjectStore();
+    
+    // Create volume as admin user
+    VolumeArgs volumeArgs = VolumeArgs.newBuilder()
+        .setOwner(UserGroupInformation.getCurrentUser().getShortUserName())
+        .build();
+    
+    adminObjectStore.createVolume(ADMIN_VOLUME, volumeArgs);
+  }
+
+  /**
+   * Adds a user as admin to a specific OM instance.
+   * This uses reconfiguration to add the admin user.
+   */
+  private void addAdminToSpecificOM(OzoneManager om, String username) throws 
Exception {
+    // Get current admin users
+    String currentAdmins = String.join(",", om.getOmAdminUsernames());
+    
+    // Add the new user to admin list
+    String newAdmins = currentAdmins + "," + username;
+    
+    // Reconfigure the OM to add the new admin
+    
om.getReconfigurationHandler().reconfigurePropertyImpl(OZONE_ADMINISTRATORS, 
newAdmins);
+  }
+
+  /**
+   * Tests volume and bucket creation as the test user.
+   * 
+   * @param shouldSucceed true if operations should succeed, false if they 
should fail
+   */
+  private void testVolumeAndBucketCreationAsUser(boolean shouldSucceed) throws 
Exception {
+    // Switch to test user context
+    UserGroupInformation.setLoginUser(testUserUgi);
+    
+    try (OzoneClient userClient = 
OzoneClientFactory.getRpcClient(OM_SERVICE_ID, cluster.getConf())) {
+      ObjectStore userObjectStore = userClient.getObjectStore();
+      
+      if (shouldSucceed) {
+        // Test volume creation (should succeed)
+        VolumeArgs volumeArgs = VolumeArgs.newBuilder()
+            .setOwner(TEST_USER)
+            .build();
+        
+        userObjectStore.createVolume(TEST_VOLUME, volumeArgs);
+        OzoneVolume volume = userObjectStore.getVolume(TEST_VOLUME);
+        assertNotNull(volume, "Volume should be created successfully");
+        assertEquals(TEST_VOLUME, volume.getName());
+        
+        // Test bucket creation (should succeed)
+        BucketArgs bucketArgs = BucketArgs.newBuilder()
+            .build();
+        
+        volume.createBucket(TEST_BUCKET, bucketArgs);
+        OzoneBucket bucket = volume.getBucket(TEST_BUCKET);
+        assertNotNull(bucket, "Bucket should be created successfully");
+        assertEquals(TEST_BUCKET, bucket.getName());
+        
+      } else {
+        // Test volume creation (should fail)
+        VolumeArgs volumeArgs = VolumeArgs.newBuilder()
+            .setOwner(TEST_USER)
+            .build();
+        
+        String newVolumeName = "failtest-" + 
RandomStringUtils.secure().nextAlphabetic(5).toLowerCase(Locale.ROOT);
+        OMException volumeException = assertThrows(OMException.class, () -> {
+          userObjectStore.createVolume(newVolumeName, volumeArgs);
+        }, "Volume creation should fail for non-admin user");
+        assertEquals(PERMISSION_DENIED, volumeException.getResult());
+        
+        // Test bucket creation (should fail) - use admin-created volume
+        if (volumeExists(userObjectStore, ADMIN_VOLUME)) {
+          OzoneVolume adminVolume = userObjectStore.getVolume(ADMIN_VOLUME);
+          BucketArgs bucketArgs = BucketArgs.newBuilder().build();
+          String newBucketName = "failtest-" + 
RandomStringUtils.secure().nextAlphabetic(5).toLowerCase(Locale.ROOT);
+          
+          OMException bucketException = assertThrows(OMException.class, () -> {
+            adminVolume.createBucket(newBucketName, bucketArgs);
+          }, "Bucket creation should fail for non-admin user in admin-owned 
volume");
+          assertEquals(PERMISSION_DENIED, bucketException.getResult());
+        }
+      }
+    } finally {
+      // Reset to original user
+      UserGroupInformation.setLoginUser(UserGroupInformation.getCurrentUser());
+    }
+  }
+
+  /**
+   * Helper method to check if volume exists.
+   */
+  private boolean volumeExists(ObjectStore store, String volumeName) {
+    try {
+      store.getVolume(volumeName);
+      return true;
+    } catch (IOException e) {
+      return false;
+    }
+  }
+
+  /**
+   * Transfers leadership from current leader to another OM node.
+   * 
+   * @param currentLeader the current leader OM
+   * @return the new leader OM after transfer
+   */
+  private OzoneManager transferLeadershipToAnotherNode(OzoneManager 
currentLeader) throws Exception {
+    // Get list of all OMs
+    List<OzoneManager> omList = new 
ArrayList<>(cluster.getOzoneManagersList());
+    
+    // Remove current leader from list
+    omList.remove(currentLeader);
+    
+    // Select the first alternative OM as target
+    OzoneManager targetOM = omList.get(0);
+    String targetNodeId = targetOM.getOMNodeId();
+    
+    // Transfer leadership
+    currentLeader.transferLeadership(targetNodeId);
+    
+    // Wait for leadership transfer to complete
+    GenericTestUtils.waitFor(() -> {
+      try {
+        OzoneManager currentLeaderCheck = cluster.getOMLeader();
+        return 
!currentLeaderCheck.getOMNodeId().equals(currentLeader.getOMNodeId());
+      } catch (Exception e) {
+        return false;
+      }
+    }, 1000, 30000);
+    
+    // Verify leadership change
+    cluster.waitForLeaderOM();
+    OzoneManager newLeader = cluster.getOMLeader();
+    
+    assertEquals(targetNodeId, newLeader.getOMNodeId(), 
+        "Leadership should have transferred to target OM");
+    
+    return newLeader;
+  }
+}
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/bucket/OMBucketCreateRequest.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/bucket/OMBucketCreateRequest.java
index a89cdf5eb45..838ee3be86c 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/bucket/OMBucketCreateRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/bucket/OMBucketCreateRequest.java
@@ -87,6 +87,8 @@ public OMBucketCreateRequest(OMRequest omRequest) {
   @Override
   public OMRequest preExecute(OzoneManager ozoneManager) throws IOException {
 
+    super.preExecute(ozoneManager);
+
     // Get original request.
     CreateBucketRequest createBucketRequest =
         getOmRequest().getCreateBucketRequest();
@@ -95,6 +97,22 @@ public OMRequest preExecute(OzoneManager ozoneManager) 
throws IOException {
     OmUtils.validateBucketName(bucketInfo.getBucketName(),
         ozoneManager.isStrictS3());
 
+    // ACL check during preExecute
+    if (ozoneManager.getAclsEnabled()) {
+      try {
+        checkAcls(ozoneManager, OzoneObj.ResourceType.BUCKET,
+            OzoneObj.StoreType.OZONE, IAccessAuthorizer.ACLType.CREATE,
+            bucketInfo.getVolumeName(), bucketInfo.getBucketName(), null);
+      } catch (IOException ex) {
+        // Ensure audit log captures preExecute failures
+        markForAudit(ozoneManager.getAuditLogger(),
+            buildAuditMessage(OMAction.CREATE_BUCKET,
+                buildVolumeAuditMap(bucketInfo.getVolumeName()), ex,
+                getOmRequest().getUserInfo()));
+        throw ex;
+      }
+    }
+
     validateMaxBucket(ozoneManager);
 
     // Get KMS provider.
@@ -206,13 +224,6 @@ public OMClientResponse 
validateAndUpdateCache(OzoneManager ozoneManager, Execut
     OMClientResponse omClientResponse = null;
 
     try {
-      // check Acl
-      if (ozoneManager.getAclsEnabled()) {
-        checkAcls(ozoneManager, OzoneObj.ResourceType.BUCKET,
-            OzoneObj.StoreType.OZONE, IAccessAuthorizer.ACLType.CREATE,
-            volumeName, bucketName, null);
-      }
-
       mergeOmLockDetails(
           metadataManager.getLock().acquireReadLock(VOLUME_LOCK, volumeName));
       acquiredVolumeLock = getOmLockDetails().isLockAcquired();
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/volume/OMVolumeCreateRequest.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/volume/OMVolumeCreateRequest.java
index 4f05b5d266c..1397f8a1b9f 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/volume/OMVolumeCreateRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/volume/OMVolumeCreateRequest.java
@@ -66,12 +66,30 @@ public OMVolumeCreateRequest(OMRequest omRequest) {
   @Override
   public OMRequest preExecute(OzoneManager ozoneManager) throws IOException {
 
+    super.preExecute(ozoneManager);
+
     VolumeInfo volumeInfo  =
         getOmRequest().getCreateVolumeRequest().getVolumeInfo();
     // Verify resource name
     OmUtils.validateVolumeName(volumeInfo.getVolume(),
         ozoneManager.isStrictS3());
 
+    // ACL check during preExecute
+    if (ozoneManager.getAclsEnabled()) {
+      try {
+        checkAcls(ozoneManager, OzoneObj.ResourceType.VOLUME,
+            OzoneObj.StoreType.OZONE, IAccessAuthorizer.ACLType.CREATE,
+            volumeInfo.getVolume(), null, null);
+      } catch (IOException ex) {
+        // Ensure audit log captures preExecute failures
+        markForAudit(ozoneManager.getAuditLogger(),
+            buildAuditMessage(OMAction.CREATE_VOLUME,
+                buildVolumeAuditMap(volumeInfo.getVolume()), ex,
+                getOmRequest().getUserInfo()));
+        throw ex;
+      }
+    }
+
     // Set creation time & set modification time
     long initialTime = Time.now();
     VolumeInfo updatedVolumeInfo =
@@ -124,14 +142,6 @@ public OMClientResponse 
validateAndUpdateCache(OzoneManager ozoneManager, Execut
 
 
       auditMap = omVolumeArgs.toAuditMap();
-
-      // check acl
-      if (ozoneManager.getAclsEnabled()) {
-        checkAcls(ozoneManager, OzoneObj.ResourceType.VOLUME,
-            OzoneObj.StoreType.OZONE, IAccessAuthorizer.ACLType.CREATE, volume,
-            null, null);
-      }
-
       // acquire lock.
       mergeOmLockDetails(omMetadataManager.getLock().acquireWriteLock(
           VOLUME_LOCK, volume));
diff --git 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/TestOMClientRequestWithUserInfo.java
 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/TestOMClientRequestWithUserInfo.java
index f2542251ab7..9fda60374c1 100644
--- 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/TestOMClientRequestWithUserInfo.java
+++ 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/TestOMClientRequestWithUserInfo.java
@@ -43,6 +43,7 @@
 import org.apache.hadoop.ozone.om.helpers.BucketLayout;
 import org.apache.hadoop.ozone.om.request.bucket.OMBucketCreateRequest;
 import org.apache.hadoop.ozone.om.request.key.OMKeyCommitRequest;
+import org.apache.hadoop.ozone.om.upgrade.OMLayoutVersionManager;
 import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.BucketInfo;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest;
@@ -77,6 +78,12 @@ public void setup() throws Exception {
     when(ozoneManager.getMetrics()).thenReturn(omMetrics);
     when(ozoneManager.getMetadataManager()).thenReturn(omMetadataManager);
     when(ozoneManager.getConfiguration()).thenReturn(ozoneConfiguration);
+
+    // Mock version manager to avoid NPE in preExecute
+    OMLayoutVersionManager versionManager = mock(OMLayoutVersionManager.class);
+    when(versionManager.getMetadataLayoutVersion()).thenReturn(0);
+    when(ozoneManager.getVersionManager()).thenReturn(versionManager);
+
     inetAddress = InetAddress.getByName("127.0.0.1");
   }
 
diff --git 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/bucket/TestOMBucketCreateRequest.java
 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/bucket/TestOMBucketCreateRequest.java
index f8f73c0979b..136421d2a4e 100644
--- 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/bucket/TestOMBucketCreateRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/bucket/TestOMBucketCreateRequest.java
@@ -33,6 +33,7 @@
 import org.apache.hadoop.hdds.protocol.proto.HddsProtos.StorageTypeProto;
 import org.apache.hadoop.ozone.om.OMConfigKeys;
 import org.apache.hadoop.ozone.om.OMMetadataManager;
+import org.apache.hadoop.ozone.om.OzoneManager;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
 import org.apache.hadoop.ozone.om.helpers.BucketLayout;
 import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
@@ -42,6 +43,8 @@
 import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse;
+import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer;
+import org.apache.hadoop.ozone.security.acl.OzoneObj;
 import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.util.Time;
 import org.junit.jupiter.api.Test;
@@ -147,6 +150,33 @@ public void 
testValidateAndUpdateCacheWithBucketAlreadyExists()
             .BUCKET_ALREADY_EXISTS, omResponse.getStatus());
   }
 
+  @Test
+  public void preExecutePermissionDeniedWhenAclEnabled() {
+    String volumeName = UUID.randomUUID().toString();
+    String bucketName = UUID.randomUUID().toString();
+
+    // Enable ACLs so preExecute path performs ACL checks
+    when(ozoneManager.getAclsEnabled()).thenReturn(true);
+
+    OMRequest originalRequest = newCreateBucketRequest(
+        newBucketInfoBuilder(bucketName, volumeName)).build();
+
+    OMBucketCreateRequest req = new OMBucketCreateRequest(originalRequest) {
+      @Override
+      public void checkAcls(OzoneManager ozoneManager,
+          OzoneObj.ResourceType resType,
+          OzoneObj.StoreType storeType, IAccessAuthorizer.ACLType aclType,
+          String vol, String bucket, String key) throws java.io.IOException {
+        throw new OMException("denied",
+            OMException.ResultCodes.PERMISSION_DENIED);
+      }
+    };
+
+    OMException e = assertThrows(OMException.class,
+        () -> req.preExecute(ozoneManager));
+    assertEquals(OMException.ResultCodes.PERMISSION_DENIED, e.getResult());
+  }
+
   @Test
   public void preExecuteRejectsInvalidReplication() {
     String volumeName = UUID.randomUUID().toString();
diff --git 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/volume/TestOMVolumeCreateRequest.java
 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/volume/TestOMVolumeCreateRequest.java
index 5157f403913..c352312a03a 100644
--- 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/volume/TestOMVolumeCreateRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/volume/TestOMVolumeCreateRequest.java
@@ -27,6 +27,7 @@
 import static org.mockito.Mockito.when;
 
 import java.util.UUID;
+import org.apache.hadoop.ozone.om.OzoneManager;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
 import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
 import org.apache.hadoop.ozone.om.request.OMRequestTestUtils;
@@ -35,6 +36,8 @@
 import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.VolumeInfo;
+import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer;
+import org.apache.hadoop.ozone.security.acl.OzoneObj;
 import org.apache.hadoop.ozone.storage.proto.OzoneManagerStorageProtos;
 import org.junit.jupiter.api.Test;
 
@@ -204,6 +207,33 @@ public void 
testValidateAndUpdateCacheWithVolumeAlreadyExists()
         omMetadataManager.getVolumeKey(volumeName)));
   }
 
+  @Test
+  public void preExecutePermissionDeniedWhenAclEnabled() throws Exception {
+    String volumeName = UUID.randomUUID().toString();
+    String adminName = UUID.randomUUID().toString();
+    String ownerName = UUID.randomUUID().toString();
+
+    when(ozoneManager.getAclsEnabled()).thenReturn(true);
+
+    OMRequest originalRequest = createVolumeRequest(volumeName, adminName,
+        ownerName);
+
+    OMVolumeCreateRequest req = new OMVolumeCreateRequest(originalRequest) {
+      @Override
+      public void checkAcls(OzoneManager ozoneManager,
+          OzoneObj.ResourceType resType,
+          OzoneObj.StoreType storeType, IAccessAuthorizer.ACLType aclType,
+          String vol, String bucket, String key) throws java.io.IOException {
+        throw new OMException("denied",
+            OMException.ResultCodes.PERMISSION_DENIED);
+      }
+    };
+
+    OMException e = assertThrows(OMException.class,
+        () -> req.preExecute(ozoneManager));
+    assertEquals(OMException.ResultCodes.PERMISSION_DENIED, e.getResult());
+  }
+
   @Test
   public void 
         testAcceptS3CompliantVolumeNameCreationRegardlessOfStrictS3Setting()


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to