Skip to content

Commit

Permalink
[fix][cli] Fix expiration of tokens created with "pulsar tokens creat…
Browse files Browse the repository at this point in the history
…e" (#22815)

Co-authored-by: David Jensen <djn@danskecommodities.com>
(cherry picked from commit 245c3e8)
  • Loading branch information
entvex authored and lhotari committed Jun 4, 2024
1 parent dc7ce73 commit f1c4547
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
import javax.crypto.SecretKey;
import lombok.Cleanup;
import org.apache.pulsar.broker.authentication.utils.AuthTokenUtils;
import org.apache.pulsar.cli.converters.TimeUnitToSecondsConverter;
import org.apache.pulsar.cli.converters.TimeUnitToMillisConverter;
import org.apache.pulsar.docs.tools.CmdGenerateDocs;

public class TokensCliUtils {
Expand Down Expand Up @@ -119,7 +119,7 @@ public static class CommandCreateToken {
"--expiry-time"},
description = "Relative expiry time for the token (eg: 1h, 3d, 10y)."
+ " (m=minutes) Default: no expiration",
converter = TimeUnitToSecondsConverter.class)
converter = TimeUnitToMillisConverter.class)
private Long expiryTime = null;

@Parameter(names = {"-sk",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,76 @@
package org.apache.pulsar.utils.auth.tokens;

import static org.testng.Assert.assertTrue;

import com.beust.jcommander.Parameter;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.io.Decoders;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.Date;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

/**
* TokensCliUtils Tests.
*/
public class TokensCliUtilsTest {

@DataProvider(name = "desiredExpireTime")
public Object[][] desiredExpireTime() {
return new Object[][] {
{"600", 600}, //10m
{"5m", 300},
{"1h", 3600},
{"1d", 86400},
{"1w", 604800},
{"1y", 31536000}
};
}

@Test(dataProvider = "desiredExpireTime")
public void commandCreateToken_WhenCreatingATokenWithExpiryTime_ShouldHaveTheDesiredExpireTime(String expireTime, int expireAsSec) throws Exception {
PrintStream oldStream = System.out;
try {
//Arrange
ByteArrayOutputStream baoStream = new ByteArrayOutputStream();
System.setOut(new PrintStream(baoStream));

String[] command = {"create", "--secret-key",
"data:;base64,u+FxaxYWpsTfxeEmMh8fQeS3g2jfXw4+sGIv+PTY+BY=",
"--subject", "test",
"--expiry-time", expireTime,
};

TokensCliUtils.main(command);
String token = baoStream.toString();

Instant start = (new Date().toInstant().plus(expireAsSec - 5, ChronoUnit.SECONDS));
Instant stop = (new Date().toInstant().plus(expireAsSec + 5, ChronoUnit.SECONDS));

//Act
Claims jwt = Jwts.parserBuilder()
.setSigningKey(Decoders.BASE64.decode("u+FxaxYWpsTfxeEmMh8fQeS3g2jfXw4+sGIv+PTY+BY="))
.build()
.parseClaimsJws(token)
.getBody();

//Assert
//Checks if the token expires within +-5 sec.
assertTrue(( ! jwt.getExpiration().toInstant().isBefore( start ) ) && ( jwt.getExpiration().toInstant().isBefore( stop ) ));

} catch (Exception e) {
throw new RuntimeException(e);
} finally {
System.setOut(oldStream);
}
}

/**
* Test tokens generate docs.
*
Expand Down

0 comments on commit f1c4547

Please sign in to comment.