package de.itvsh.goofy; import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*; import java.lang.reflect.Field; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.UUID; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.Spy; import com.auth0.jwt.exceptions.JWTVerificationException; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; class JwtTokenUtilTest { @Spy private JwtTokenUtil jwtTokenUtil; private static final String TOKEN_SECRET = "t0pS3cr3t"; @BeforeEach public void initTest() throws Exception { Field tokenSecretField = JwtTokenUtil.class.getDeclaredField("secret"); tokenSecretField.setAccessible(true); tokenSecretField.set(jwtTokenUtil, TOKEN_SECRET); } @Nested @DisplayName("Verify token generation") class TestGenerateToken { private String generatedToken; @BeforeEach void initTest() { generatedToken = jwtTokenUtil.generateToken(SecurityTestFactory.SUBJECT.toString(), SecurityTestFactory.USER_FIRSTNAME, SecurityTestFactory.USER_LASTNAME, SecurityTestFactory.AUTHORITIES); } @Test void userId() { var userId = getParsedBody().getSubject(); assertThat(userId).isEqualTo(SecurityTestFactory.SUBJECT.toString()); } @Test void expirationDate() { var before = new Date(); var expirationDate = getParsedBody().getExpiration(); var after = new Date(System.currentTimeMillis() + 900000); assertThat(expirationDate).isAfter(before).isBefore(after); } private Claims getParsedBody() { return Jwts.parser().setSigningKey(TOKEN_SECRET.getBytes()).parseClaimsJws(generatedToken).getBody(); } } @Nested class TestVerifyToken { @Test void shouldDoNotThrowExcepionOnValidToken() { var token = buildToken(UUID.randomUUID().toString(), TOKEN_SECRET, 60000); jwtTokenUtil.verifyToken(token); } @Test void shouldThrowExceptionOnInvalidToken() { var token = buildToken(UUID.randomUUID().toString(), "invalid_token", 60000); assertThrows(JWTVerificationException.class, () -> jwtTokenUtil.verifyToken(token)); } @Test void shouldThrowExceptionOnTimeExpired() { var token = buildToken(UUID.randomUUID().toString(), TOKEN_SECRET, -1000); assertThrows(JWTVerificationException.class, () -> jwtTokenUtil.verifyToken(token)); } private String buildToken(String subject, String token, int expiredTime) { Map<String, Object> claims = new HashMap<>(); claims.put(JwtTokenUtil.FIRSTNAME_CLAIM, SecurityTestFactory.USER_FIRSTNAME); claims.put(JwtTokenUtil.LASTNAME_CLAIM, SecurityTestFactory.USER_LASTNAME); claims.put(JwtTokenUtil.ROLE_CLAIM, SecurityTestFactory.AUTHORITIES); return Jwts.builder()// .setClaims(claims)// .setSubject(subject)// .setHeaderParam("typ", JwtTokenUtil.TOKEN_TYPE)// .setIssuer(JwtTokenUtil.TOKEN_ISSUER).setIssuedAt(new Date(System.currentTimeMillis()))// .setExpiration(new Date(System.currentTimeMillis() + expiredTime))// .setAudience(JwtTokenUtil.TOKEN_AUDIENCE)// .signWith(SignatureAlgorithm.HS512, token.getBytes())// .compact(); } } }