Skip to content

Commit

Permalink
[fix] Fixes Create is mishandling time units (specifically, treating …
Browse files Browse the repository at this point in the history
…seconds as milliseconds).
  • Loading branch information
entvex committed Jun 2, 2024
1 parent c39f9f8 commit e69a8ae
Show file tree
Hide file tree
Showing 2 changed files with 239 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,11 @@
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import javax.crypto.SecretKey;
import lombok.Cleanup;
import org.apache.pulsar.broker.authentication.utils.AuthTokenUtils;
import org.apache.pulsar.cli.converters.picocli.TimeUnitToSecondsConverter;
import org.apache.pulsar.cli.converters.picocli.TimeUnitToMillisConverter;
import org.apache.pulsar.docs.tools.CmdGenerateDocs;
import picocli.CommandLine;
import picocli.CommandLine.Command;
Expand Down Expand Up @@ -128,7 +129,7 @@ public static class CommandCreateToken implements Callable<Integer> {
"--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;

@Option(names = {"-sk",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,22 @@

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwsHeader;
import io.jsonwebtoken.Jwt;
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 java.util.concurrent.TimeUnit;

import io.swagger.annotations.ExampleProperty;
import org.testng.annotations.Test;
import picocli.CommandLine.Option;

Expand Down Expand Up @@ -75,6 +83,234 @@ public void testCreateToken() {
}
}

@Test
public void commandCreateToken_WhenCreatingATokenWith10MinuteExpiryTime_ShouldHaveTheDesiredExpireTime() 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", "600", //10m
};

new TokensCliUtils().execute(command);
String token = baoStream.toString();

Instant start = (new Date().toInstant().plus(10, ChronoUnit.MINUTES)).minus(5, ChronoUnit.SECONDS);
Instant stop = (new Date().toInstant().plus(10, ChronoUnit.MINUTES).plus(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
public void commandCreateToken_WhenCreatingATokenWith5MinuteExpiryTime_ShouldHaveTheDesiredExpireTime() 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", "5m",
};

new TokensCliUtils().execute(command);
String token = baoStream.toString();

Instant start = (new Date().toInstant().plus(5, ChronoUnit.MINUTES)).minus(5, ChronoUnit.SECONDS);
Instant stop = (new Date().toInstant().plus(5, ChronoUnit.MINUTES).plus(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
public void commandCreateToken_WhenCreatingATokenWith1HourExpiryTime_ShouldHaveTheDesiredExpireTime() 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", "1h",
};

new TokensCliUtils().execute(command);
String token = baoStream.toString();

Instant start = (new Date().toInstant().plus(1, ChronoUnit.HOURS)).minus(5, ChronoUnit.SECONDS);
Instant stop = (new Date().toInstant().plus(1, ChronoUnit.HOURS).plus(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
public void commandCreateToken_WhenCreatingATokenWith1DayExpiryTime_ShouldHaveTheDesiredExpireTime() 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", "1d",
};

new TokensCliUtils().execute(command);
String token = baoStream.toString();

Instant start = (new Date().toInstant().plus(1, ChronoUnit.DAYS)).minus(5, ChronoUnit.SECONDS);
Instant stop = (new Date().toInstant().plus(1, ChronoUnit.DAYS).plus(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
public void commandCreateToken_WhenCreatingATokenWith1WeekExpiryTime_ShouldHaveTheDesiredExpireTime() 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", "1w",
};

new TokensCliUtils().execute(command);
String token = baoStream.toString();

Instant start = (new Date().toInstant().plus(7, ChronoUnit.DAYS)).minus(5, ChronoUnit.SECONDS);
Instant stop = (new Date().toInstant().plus(7, ChronoUnit.DAYS).plus(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
public void commandCreateToken_WhenCreatingATokenWith1YearExpiryTime_ShouldHaveTheDesiredExpireTime() 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", "1y",
};

new TokensCliUtils().execute(command);
String token = baoStream.toString();

Instant start = (new Date().toInstant().plus(365, ChronoUnit.DAYS)).minus(5, ChronoUnit.SECONDS);
Instant stop = (new Date().toInstant().plus(365, ChronoUnit.DAYS).plus(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 e69a8ae

Please sign in to comment.