Skip to content

Commit

Permalink
#943: use helper classes in JwtHelper
Browse files Browse the repository at this point in the history
  • Loading branch information
clean-coder committed Jun 14, 2024
1 parent 3a783d5 commit b90bcdf
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 11 deletions.
53 changes: 42 additions & 11 deletions backend/src/main/java/ch/puzzle/okr/security/JwtHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import ch.puzzle.okr.exception.OkrResponseStatusException;
import ch.puzzle.okr.models.User;
import ch.puzzle.okr.multitenancy.TenantConfigProvider;
import ch.puzzle.okr.security.helper.ClaimHelper;
import ch.puzzle.okr.security.helper.TokenHelper;
import com.nimbusds.jwt.JWTClaimsSet;
import jakarta.persistence.EntityNotFoundException;
import org.slf4j.Logger;
Expand All @@ -13,15 +15,16 @@
import org.springframework.stereotype.Component;

import java.text.MessageFormat;
import java.text.ParseException;
import java.util.Map;
import java.util.Optional;

import static ch.puzzle.okr.Constants.USER;
import static org.springframework.http.HttpStatus.BAD_REQUEST;

@Component
public class JwtHelper {
private static final String CLAIM_TENANT = "tenant";
public static final String CLAIM_TENANT = "tenant";
public static final String CLAIM_ISS = "iss";

private static final Logger logger = LoggerFactory.getLogger(JwtHelper.class);

Expand Down Expand Up @@ -57,22 +60,50 @@ public User getUserFromJwt(Jwt token) {
}

public String getTenantFromToken(Jwt token) {
return getTenantOrThrow(token.getClaimAsString(CLAIM_TENANT));
TokenHelper helper = new TokenHelper();

Optional<String> tenantUsingClaimIss = helper.getTenantFromTokenUsingClaimIss(token);
if (tenantUsingClaimIss.isPresent()) {
return getMatchingTenantFromConfigOrThrow(tenantUsingClaimIss.get());
}

Optional<String> tenantUsingClaimTenant = helper.getTenantFromTokenUsingClaimTenant(token);
if (tenantUsingClaimTenant.isPresent()) {
return getMatchingTenantFromConfigOrThrow(tenantUsingClaimTenant.get());
}

logErrorAndThrowException(CLAIM_TENANT, CLAIM_ISS);
return null; // only to make the compiler happy
}

public String getTenantFromJWTClaimsSet(JWTClaimsSet claimSet) {
ClaimHelper helper = new ClaimHelper();

Optional<String> tenantUsingClaimIss = helper.getTenantFromClaimsSetUsingClaimIss(claimSet);
if (tenantUsingClaimIss.isPresent()) {
return getMatchingTenantFromConfigOrThrow(tenantUsingClaimIss.get());
}

Optional<String> tenantUsingClaimTenant = helper.getTenantFromClaimsSetUsingClaimTenant(claimSet);
if (tenantUsingClaimTenant.isPresent()) {
return getMatchingTenantFromConfigOrThrow(tenantUsingClaimTenant.get());
}

logErrorAndThrowException(CLAIM_TENANT, CLAIM_ISS);
return null; // only to make the compiler happy
}

private String getTenantOrThrow(String tenant) {
private String getMatchingTenantFromConfigOrThrow(String tenant) {
// Ensure we return only tenants for realms which really exist
return this.tenantConfigProvider.getTenantConfigById(tenant)
.orElseThrow(() -> new EntityNotFoundException(MessageFormat.format("Cannot find tenant {0}", tenant)))
.tenantId();
}

public String getTenantFromJWTClaimsSet(JWTClaimsSet claimSet) {
try {
return this.getTenantOrThrow(claimSet.getStringClaim(CLAIM_TENANT));
} catch (ParseException e) {
throw new RuntimeException("Missing `tenant` claim in JWT token!", e);
}

private void logErrorAndThrowException(String tenant, String iss) throws RuntimeException {
String errorInfo = "* Missing `" + tenant + "` and '" + iss + "' claims in JWT token!";
logger.error(errorInfo);
throw new RuntimeException(errorInfo);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class JwtHelperTest {
private static final String TOKEN_CLAIMS_KEY_TENANT = "tenant";
private static final String PITC = "pitc";

// ok
@DisplayName("getUserFromJwt() extracts User data from Token")
@Test
void getUserFromJwtExtractsUserDataFromToken() {
Expand All @@ -54,6 +55,7 @@ void getUserFromJwtExtractsUserDataFromToken() {
assertEquals(EMAIL, userFromToken.getEmail());
}

// ok
@DisplayName("getUserFromJwt() throws Exception if Token not contains User data")
@Test
void getUserFromJwtThrowsExceptionIfTokenNotContainsUserData() {
Expand Down

0 comments on commit b90bcdf

Please sign in to comment.