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]