Skip to content

Commit

Permalink
increased test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
stephan committed Jul 4, 2017
1 parent f1827e0 commit bf69f8d
Show file tree
Hide file tree
Showing 6 changed files with 246 additions and 22 deletions.
19 changes: 19 additions & 0 deletions src/main/java/org/zerhusen/common/utils/TimeProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.zerhusen.common.utils;

import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.Date;

/**
* Created by stephan on 04.07.17.
*/
@Component
public class TimeProvider implements Serializable {

private static final long serialVersionUID = -3301695478208950415L;

public Date now() {
return new Date();
}
}
41 changes: 26 additions & 15 deletions src/main/java/org/zerhusen/security/JwtTokenUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mobile.device.Device;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.zerhusen.common.utils.TimeProvider;

import java.io.Serializable;
import java.util.Date;
Expand All @@ -21,11 +23,15 @@ public class JwtTokenUtil implements Serializable {
static final String CLAIM_KEY_USERNAME = "sub";
static final String CLAIM_KEY_AUDIENCE = "audience";
static final String CLAIM_KEY_CREATED = "created";
static final String CLAIM_KEY_EXPIRED = "exp";

private static final String AUDIENCE_UNKNOWN = "unknown";
private static final String AUDIENCE_WEB = "web";
private static final String AUDIENCE_MOBILE = "mobile";
private static final String AUDIENCE_TABLET = "tablet";
static final String AUDIENCE_UNKNOWN = "unknown";
static final String AUDIENCE_WEB = "web";
static final String AUDIENCE_MOBILE = "mobile";
static final String AUDIENCE_TABLET = "tablet";

@Autowired
private TimeProvider timeProvider;

@Value("${jwt.secret}")
private String secret;
Expand Down Expand Up @@ -90,13 +96,9 @@ private Claims getClaimsFromToken(String token) {
return claims;
}

private Date generateExpirationDate() {
return new Date(System.currentTimeMillis() + expiration * 1000);
}

private Boolean isTokenExpired(String token) {
final Date expiration = getExpirationDateFromToken(token);
return expiration.before(new Date());
return expiration.before(timeProvider.now());
}

private Boolean isCreatedBeforeLastPasswordReset(Date created, Date lastPasswordReset) {
Expand All @@ -122,16 +124,25 @@ private Boolean ignoreTokenExpiration(String token) {

public String generateToken(UserDetails userDetails, Device device) {
Map<String, Object> claims = new HashMap<>();

claims.put(CLAIM_KEY_USERNAME, userDetails.getUsername());
claims.put(CLAIM_KEY_AUDIENCE, generateAudience(device));
claims.put(CLAIM_KEY_CREATED, new Date());
return generateToken(claims);

final Date createdDate = timeProvider.now();
claims.put(CLAIM_KEY_CREATED, createdDate);

return doGenerateToken(claims);
}

String generateToken(Map<String, Object> claims) {
private String doGenerateToken(Map<String, Object> claims) {
final Date createdDate = (Date) claims.get(CLAIM_KEY_CREATED);
final Date expirationDate = new Date(createdDate.getTime() + expiration * 1000);

System.out.println("doGenerateToken " + createdDate);

return Jwts.builder()
.setClaims(claims)
.setExpiration(generateExpirationDate())
.setExpiration(expirationDate)
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
Expand All @@ -146,8 +157,8 @@ public String refreshToken(String token) {
String refreshedToken;
try {
final Claims claims = getClaimsFromToken(token);
claims.put(CLAIM_KEY_CREATED, new Date());
refreshedToken = generateToken(claims);
claims.put(CLAIM_KEY_CREATED, timeProvider.now());
refreshedToken = doGenerateToken(claims);
} catch (Exception e) {
refreshedToken = null;
}
Expand Down
20 changes: 20 additions & 0 deletions src/test/java/org/zerhusen/common/utils/TimeProviderTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.zerhusen.common.utils;

import org.assertj.core.api.Assertions;
import org.junit.Test;

import java.util.Date;

import static org.assertj.core.api.Assertions.*;
import static org.junit.Assert.*;

/**
* Created by stephan on 04.07.17.
*/
public class TimeProviderTest {
@Test
public void now() throws Exception {
assertThat(new TimeProvider().now()).isCloseTo(new Date(), 1000);
}

}
46 changes: 46 additions & 0 deletions src/test/java/org/zerhusen/security/DeviceDummy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.zerhusen.security;

import org.springframework.mobile.device.Device;
import org.springframework.mobile.device.DevicePlatform;

/**
* Created by stephan on 04.07.17.
*/
public class DeviceDummy implements Device {

private boolean normal;
private boolean mobile;
private boolean tablet;

@Override
public boolean isNormal() {
return normal;
}

@Override
public boolean isMobile() {
return mobile;
}

@Override
public boolean isTablet() {
return tablet;
}

@Override
public DevicePlatform getDevicePlatform() {
return null;
}

public void setNormal(boolean normal) {
this.normal = normal;
}

public void setMobile(boolean mobile) {
this.mobile = mobile;
}

public void setTablet(boolean tablet) {
this.tablet = tablet;
}
}
89 changes: 82 additions & 7 deletions src/test/java/org/zerhusen/security/JwtTokenUtilTest.java
Original file line number Diff line number Diff line change
@@ -1,49 +1,124 @@
package org.zerhusen.security;

import org.assertj.core.util.DateUtil;
import org.assertj.core.util.Maps;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.util.ReflectionUtils;
import org.zerhusen.common.utils.TimeProvider;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.within;
import static org.mockito.Mockito.*;

/**
* Created by stephan on 10.09.16.
*/
public class JwtTokenUtilTest {

private static final String TEST_USER = "testUser";

@Mock
private TimeProvider timeProviderMock;

@InjectMocks
private JwtTokenUtil jwtTokenUtil;

@Before
public void init() {
jwtTokenUtil = new JwtTokenUtil();
ReflectionTestUtils.setField(jwtTokenUtil, "expiration", 3600000L);
MockitoAnnotations.initMocks(this);

ReflectionTestUtils.setField(jwtTokenUtil, "expiration", 3600L); // one hour
ReflectionTestUtils.setField(jwtTokenUtil, "secret", "mySecret");
}

@Test
public void testGenerateTokenGeneratesDifferentTokensForDifferentCreationDates() throws Exception {
final Map<String, Object> claims = createClaims("2016-09-08T03:00:00");
final String token = jwtTokenUtil.generateToken(claims);
when(timeProviderMock.now())
.thenReturn(DateUtil.yesterday())
.thenReturn(DateUtil.now());

final Map<String, Object> claimsForLaterToken = createClaims("2016-09-08T08:00:00");
final String laterToken = jwtTokenUtil.generateToken(claimsForLaterToken);
final String token = createToken();
final String laterToken = createToken();

assertThat(token).isNotEqualTo(laterToken);
}

@Test
public void getUsernameFromToken() throws Exception {
when(timeProviderMock.now()).thenReturn(DateUtil.now());

final String token = createToken();

assertThat(jwtTokenUtil.getUsernameFromToken(token)).isEqualTo(TEST_USER);
}

@Test
public void getCreatedDateFromToken() throws Exception {
final Date now = DateUtil.now();
when(timeProviderMock.now()).thenReturn(now);

final String token = createToken();

assertThat(jwtTokenUtil.getCreatedDateFromToken(token)).hasSameTimeAs(now);
}

@Test
public void getExpirationDateFromToken() throws Exception {
final Date now = DateUtil.now();
when(timeProviderMock.now()).thenReturn(now);
final String token = createToken();

final Date expirationDateFromToken = jwtTokenUtil.getExpirationDateFromToken(token);
assertThat(DateUtil.timeDifference(expirationDateFromToken, now)).isCloseTo(3600000L, within(1000L));
}

@Test
public void getAudienceFromToken() throws Exception {
when(timeProviderMock.now()).thenReturn(DateUtil.now());
final String token = createToken();

assertThat(jwtTokenUtil.getAudienceFromToken(token)).isEqualTo(JwtTokenUtil.AUDIENCE_WEB);
}

// TODO write tests
// @Test
// public void canTokenBeRefreshed() throws Exception {
// }
//
// @Test
// public void refreshToken() throws Exception {
// }
//
// @Test
// public void validateToken() throws Exception {
// }

private Map<String, Object> createClaims(String creationDate) {
Map<String, Object> claims = new HashMap();
claims.put(JwtTokenUtil.CLAIM_KEY_USERNAME, "testUser");
claims.put(JwtTokenUtil.CLAIM_KEY_USERNAME, TEST_USER);
claims.put(JwtTokenUtil.CLAIM_KEY_AUDIENCE, "testAudience");
claims.put(JwtTokenUtil.CLAIM_KEY_CREATED, DateUtil.parseDatetime(creationDate));
return claims;
}

private String createToken() {
final DeviceDummy device = new DeviceDummy();
device.setNormal(true);

return jwtTokenUtil.generateToken(new UserDetailsDummy(TEST_USER), device);
}

}
53 changes: 53 additions & 0 deletions src/test/java/org/zerhusen/security/UserDetailsDummy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package org.zerhusen.security;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;

/**
* Created by stephan on 04.07.17.
*/
public class UserDetailsDummy implements UserDetails {

private final String username;

public UserDetailsDummy(String username) {
this.username = username;
}

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}

@Override
public String getPassword() {
return null;
}

@Override
public String getUsername() {
return username;
}

@Override
public boolean isAccountNonExpired() {
return false;
}

@Override
public boolean isAccountNonLocked() {
return false;
}

@Override
public boolean isCredentialsNonExpired() {
return false;
}

@Override
public boolean isEnabled() {
return false;
}
}

0 comments on commit bf69f8d

Please sign in to comment.