Skip to content

Commit 0b2db9c

Browse files
authored
HDDS-14373. [STS] Revoked STS token logic tweaks (#9604)
1 parent a47b0b4 commit 0b2db9c

File tree

4 files changed

+70
-1
lines changed

4 files changed

+70
-1
lines changed

hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3RevokeSTSTokenRequest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import java.time.ZoneOffset;
2323
import java.util.HashMap;
2424
import java.util.Map;
25+
import org.apache.hadoop.hdds.utils.db.cache.CacheKey;
26+
import org.apache.hadoop.hdds.utils.db.cache.CacheValue;
2527
import org.apache.hadoop.ozone.OzoneConsts;
2628
import org.apache.hadoop.ozone.audit.OMAction;
2729
import org.apache.hadoop.ozone.om.OzoneManager;
@@ -106,6 +108,10 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, Execut
106108
markForAudit(ozoneManager.getAuditLogger(), buildAuditMessage(
107109
OMAction.REVOKE_STS_TOKEN, auditMap, null, userInfo));
108110

111+
// Update the cache immediately so subsequent validation checks see the revocation
112+
ozoneManager.getMetadataManager().getS3RevokedStsTokenTable().addCacheEntry(
113+
new CacheKey<>(sessionToken), CacheValue.get(context.getIndex(), CLOCK.millis()));
114+
109115
LOG.info("Marked STS session token '{}' as revoked.", sessionToken);
110116
return omClientResponse;
111117
}

hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3RevokeSTSTokenRequest.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,28 @@
2121
import static org.junit.jupiter.api.Assertions.assertEquals;
2222
import static org.junit.jupiter.api.Assertions.assertThrows;
2323
import static org.mockito.ArgumentMatchers.any;
24+
import static org.mockito.Mockito.eq;
2425
import static org.mockito.Mockito.mock;
26+
import static org.mockito.Mockito.verify;
2527
import static org.mockito.Mockito.when;
2628

2729
import java.io.IOException;
2830
import java.util.Optional;
2931
import java.util.UUID;
3032
import org.apache.hadoop.hdds.security.symmetric.SecretKeyClient;
33+
import org.apache.hadoop.hdds.utils.db.Table;
34+
import org.apache.hadoop.hdds.utils.db.cache.CacheKey;
35+
import org.apache.hadoop.hdds.utils.db.cache.CacheValue;
3136
import org.apache.hadoop.ipc.ExternalCall;
3237
import org.apache.hadoop.ipc.Server;
38+
import org.apache.hadoop.ozone.audit.AuditLogger;
39+
import org.apache.hadoop.ozone.om.OMMetadataManager;
3340
import org.apache.hadoop.ozone.om.OMMultiTenantManager;
3441
import org.apache.hadoop.ozone.om.OzoneManager;
3542
import org.apache.hadoop.ozone.om.exceptions.OMException;
43+
import org.apache.hadoop.ozone.om.execution.flowcontrol.ExecutionContext;
3644
import org.apache.hadoop.ozone.om.request.OMClientRequest;
45+
import org.apache.hadoop.ozone.om.response.OMClientResponse;
3746
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
3847
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest;
3948
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Type;
@@ -283,6 +292,41 @@ public void testPreExecuteFailsForNonOwnerNonAdminInTenant() throws Exception {
283292
assertEquals(OMException.ResultCodes.USER_MISMATCH, ex.getResult());
284293
}
285294

295+
@Test
296+
public void testValidateAndUpdateCacheUpdatesCacheImmediately() throws Exception {
297+
final String tempAccessKeyId = "ASIA4567891230";
298+
final String originalAccessKeyId = "original-access-key-id";
299+
final String sessionToken = createSessionToken(tempAccessKeyId, originalAccessKeyId);
300+
301+
final OzoneManager ozoneManager = mock(OzoneManager.class);
302+
final OMMetadataManager omMetadataManager = mock(OMMetadataManager.class);
303+
@SuppressWarnings("unchecked")
304+
final Table<String, Long> s3RevokedStsTokenTable = mock(Table.class);
305+
final ExecutionContext context = mock(ExecutionContext.class);
306+
final AuditLogger auditLogger = mock(AuditLogger.class);
307+
308+
when(ozoneManager.getMetadataManager()).thenReturn(omMetadataManager);
309+
when(omMetadataManager.getS3RevokedStsTokenTable()).thenReturn(s3RevokedStsTokenTable);
310+
when(ozoneManager.getAuditLogger()).thenReturn(auditLogger);
311+
312+
final OzoneManagerProtocolProtos.RevokeSTSTokenRequest revokeRequest =
313+
OzoneManagerProtocolProtos.RevokeSTSTokenRequest.newBuilder()
314+
.setSessionToken(sessionToken)
315+
.build();
316+
317+
final OMRequest omRequest = OMRequest.newBuilder()
318+
.setClientId(UUID.randomUUID().toString())
319+
.setCmdType(Type.RevokeSTSToken)
320+
.setRevokeSTSTokenRequest(revokeRequest)
321+
.build();
322+
323+
final S3RevokeSTSTokenRequest s3RevokeSTSTokenRequest = new S3RevokeSTSTokenRequest(omRequest);
324+
final OMClientResponse omClientResponse = s3RevokeSTSTokenRequest.validateAndUpdateCache(ozoneManager, context);
325+
326+
assertEquals(OzoneManagerProtocolProtos.Status.OK, omClientResponse.getOMResponse().getStatus());
327+
verify(s3RevokedStsTokenTable).addCacheEntry(eq(new CacheKey<>(sessionToken)), any(CacheValue.class));
328+
}
329+
286330
/**
287331
* Stub used to inject a remote user into the ProtobufRpcEngine.Server.getRemoteUser() thread-local.
288332
*/

hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/EndpointBase.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,8 @@ protected void auditReadFailure(AuditAction action, Exception ex) {
537537
protected boolean isAccessDenied(OMException ex) {
538538
ResultCodes result = ex.getResult();
539539
return result == ResultCodes.PERMISSION_DENIED
540-
|| result == ResultCodes.INVALID_TOKEN;
540+
|| result == ResultCodes.INVALID_TOKEN
541+
|| result == ResultCodes.REVOKED_TOKEN;
541542
}
542543

543544
}

hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestEndpointBase.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,21 @@
1717

1818
package org.apache.hadoop.ozone.s3.endpoint;
1919

20+
import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes;
2021
import static org.apache.hadoop.ozone.s3.util.S3Consts.CUSTOM_METADATA_HEADER_PREFIX;
2122
import static org.assertj.core.api.Assertions.assertThat;
2223
import static org.junit.jupiter.api.Assertions.assertEquals;
24+
import static org.junit.jupiter.api.Assertions.assertFalse;
2325
import static org.junit.jupiter.api.Assertions.assertThrows;
26+
import static org.junit.jupiter.api.Assertions.assertTrue;
2427

2528
import java.nio.charset.StandardCharsets;
2629
import java.util.Locale;
2730
import java.util.Map;
2831
import javax.ws.rs.core.MultivaluedHashMap;
2932
import javax.ws.rs.core.MultivaluedMap;
3033
import org.apache.hadoop.ozone.OzoneConsts;
34+
import org.apache.hadoop.ozone.om.exceptions.OMException;
3135
import org.apache.hadoop.ozone.s3.exception.OS3Exception;
3236
import org.junit.jupiter.api.Test;
3337

@@ -114,4 +118,18 @@ public void init() { }
114118
assertEquals(value, customMetadata.get(key));
115119
}
116120

121+
@Test
122+
public void testAccessDeniedResultCodes() {
123+
final EndpointBase endpointBase = new EndpointBase() {
124+
@Override
125+
public void init() { }
126+
};
127+
128+
assertTrue(endpointBase.isAccessDenied(new OMException(ResultCodes.PERMISSION_DENIED)));
129+
assertTrue(endpointBase.isAccessDenied(new OMException(ResultCodes.INVALID_TOKEN)));
130+
assertTrue(endpointBase.isAccessDenied(new OMException(ResultCodes.REVOKED_TOKEN)));
131+
assertFalse(endpointBase.isAccessDenied(new OMException(ResultCodes.INTERNAL_ERROR)));
132+
assertFalse(endpointBase.isAccessDenied(new OMException(ResultCodes.BUCKET_NOT_FOUND)));
133+
}
134+
117135
}

0 commit comments

Comments
 (0)