Copilot commented on code in PR #11095:
URL: https://github.com/apache/ozone/pull/11095#discussion_r3849633653


##########
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3RevokeSTSTokenRequest.java:
##########
@@ -61,48 +69,86 @@ public S3RevokeSTSTokenRequest(OMRequest omRequest) {
   @Override
   public OMRequest preExecute(OzoneManager ozoneManager) throws IOException {
     final OMRequest omRequest = super.preExecute(ozoneManager);
-    final OzoneManagerProtocolProtos.RevokeSTSTokenRequest revokeReq =
-        omRequest.getRevokeSTSTokenRequest();
+    final RevokeSTSTokenRequest revokeReq = 
omRequest.getRevokeSTSTokenRequest();
+    validateRevokeRequestFields(revokeReq);
 
-    // Get the original (long-lived) access key id from the session token
-    // and enforce the same permission model that is used for S3 secret
+    // Use the original (long-lived) access key ID from the request and enforce
+    // the same permission model that is used for S3 secret
     // operations (get/set/revoke). Only the owner of the original access
     // key (i.e. the creator of the STS token) or an S3 / tenant admin is 
allowed
     // to revoke its temporary STS credentials.
-    final String sessionToken = revokeReq.getSessionToken();
-    final STSTokenIdentifier stsTokenIdentifier = 
STSSecurityUtil.constructValidateAndDecryptSTSToken(
-        sessionToken, ozoneManager.getSecretKeyClient(), CLOCK);
-    final String originalAccessKeyId = 
stsTokenIdentifier.getOriginalAccessKeyId();
+    final String originalAccessKeyId = revokeReq.getOriginalAccessKeyId();
 
     final UserGroupInformation ugi = 
S3SecretRequestHelper.getOrCreateUgi(originalAccessKeyId);
     S3SecretRequestHelper.checkAccessIdSecretOpPermission(ozoneManager, ugi, 
originalAccessKeyId);
 
-    return omRequest;
+    if (!ozoneManager.getS3SecretManager().hasS3Secret(originalAccessKeyId)) {
+      throw new OMException("originalAccessKeyId does not exist: " + 
originalAccessKeyId, ACCESS_ID_NOT_FOUND);
+    }
+
+    final long revocationTimeMillis = CLOCK.millis();
+    final RevokeSTSTokenRequest updatedRevokeReq = revokeReq.toBuilder()
+        .setRevocationTimeMillis(revocationTimeMillis)
+        .build();
+
+    return omRequest.toBuilder()
+        .setRevokeSTSTokenRequest(updatedRevokeReq)
+        .build();
   }
 
   @Override
   public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, 
ExecutionContext context) {
     final OMResponse.Builder omResponse = 
OmResponseUtil.getOMResponseBuilder(getOmRequest());
+    IOException exception = null;
+    OMClientResponse omClientResponse;
+    final Map<String, String> auditMap = new HashMap<>();
 
-    final OzoneManagerProtocolProtos.RevokeSTSTokenRequest revokeReq = 
getOmRequest().getRevokeSTSTokenRequest();
-    final String sessionToken = revokeReq.getSessionToken();
+    try {
+      final RevokeSTSTokenRequest revokeReq = 
validateReplicatedRevokeRequestFields(getOmRequest());
+      final String originalAccessKeyId = revokeReq.getOriginalAccessKeyId();
+      auditMap.put(OzoneConsts.S3_REVOKESTSTOKEN_USER, originalAccessKeyId);
+      final long revocationTimeMillis = revokeReq.getRevocationTimeMillis();
 
-    // All actual DB mutations are done in the response's addToDBBatch().
-    final OMClientResponse omClientResponse = new S3RevokeSTSTokenResponse(
-        sessionToken, omResponse.build());
+      // All actual DB mutations are done in the response's addToDBBatch().
+      omClientResponse = new S3RevokeSTSTokenResponse(originalAccessKeyId, 
revocationTimeMillis, omResponse.build());
 
-    // Audit log
-    final Map<String, String> auditMap = new HashMap<>();
-    final OzoneManagerProtocolProtos.UserInfo userInfo = 
getOmRequest().getUserInfo();
-    auditMap.put(OzoneConsts.S3_REVOKESTSTOKEN_USER, userInfo.getUserName());
-    markForAudit(ozoneManager.getAuditLogger(), buildAuditMessage(
-        OMAction.REVOKE_STS_TOKEN, auditMap, null, userInfo));
+      // Update the cache immediately so subsequent validation checks see the 
revocation
+      
ozoneManager.getMetadataManager().getS3RevokedStsTokenTable().addCacheEntry(
+          new CacheKey<>(originalAccessKeyId), 
CacheValue.get(context.getIndex(), revocationTimeMillis));
 
-    // Update the cache immediately so subsequent validation checks see the 
revocation
-    
ozoneManager.getMetadataManager().getS3RevokedStsTokenTable().addCacheEntry(
-        new CacheKey<>(sessionToken), CacheValue.get(context.getIndex(), 
CLOCK.millis()));
+      LOG.info(
+          "Marked STS tokens as revoked for originalAccessKeyId={} with cutoff 
time {}.",
+          originalAccessKeyId, revocationTimeMillis);
+    } catch (IOException ex) {
+      exception = ex;
+      omClientResponse = new S3RevokeSTSTokenResponse(null, 0L, 
createErrorOMResponse(omResponse, ex));
+    }
 
-    LOG.info("Marked STS session token '{}' as revoked.", sessionToken);
+    // Audit log
+    markForAudit(
+        ozoneManager.getAuditLogger(), buildAuditMessage(
+            OMAction.REVOKE_STS_TOKEN, auditMap, exception, 
getOmRequest().getUserInfo()));
     return omClientResponse;
   }
+
+  private static void validateRevokeRequestFields(RevokeSTSTokenRequest 
revokeReq) throws OMException {
+    final String originalAccessKeyId = revokeReq.getOriginalAccessKeyId();
+    if (StringUtils.isEmpty(originalAccessKeyId)) {
+      throw new OMException("originalAccessKeyId is required for STS token 
revocation", INVALID_REQUEST);
+    }
+    if (revokeReq.hasRevocationTimeMillis()) {
+      throw new OMException("revocationTimeMillis must not be set by client", 
INVALID_REQUEST);
+    }
+  }
+
+  private static RevokeSTSTokenRequest 
validateReplicatedRevokeRequestFields(OMRequest omRequest) throws OMException {
+    if (!omRequest.hasRevokeSTSTokenRequest()) {
+      throw new OMException("revokeSTSTokenRequest is required for STS token 
revocation", INTERNAL_ERROR);
+    }
+    final RevokeSTSTokenRequest revokeReq = 
omRequest.getRevokeSTSTokenRequest();
+    if (!revokeReq.hasRevocationTimeMillis()) {
+      throw new OMException("revocationTimeMillis is required for STS token 
revocation", INTERNAL_ERROR);
+    }
+    return revokeReq;

Review Comment:
   `validateReplicatedRevokeRequestFields()` validates presence of 
`revocationTimeMillis`, but does not validate that `originalAccessKeyId` is 
non-empty on the replicated path. Even though the leader should enforce this, 
rejecting malformed replicated requests defensively avoids writing an 
empty-string key into the revocation table if an unexpected request slips 
through.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to