package org.gcube.common.keycloak.model; import java.io.Serializable; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import org.gcube.com.fasterxml.jackson.annotation.JsonAnyGetter; import org.gcube.com.fasterxml.jackson.annotation.JsonAnySetter; import org.gcube.com.fasterxml.jackson.annotation.JsonIgnore; import org.gcube.com.fasterxml.jackson.annotation.JsonProperty; import org.gcube.com.fasterxml.jackson.databind.annotation.JsonDeserialize; import org.gcube.com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.gcube.common.keycloak.model.util.StringOrArrayDeserializer; import org.gcube.common.keycloak.model.util.StringOrArraySerializer; import org.gcube.common.keycloak.model.util.Time; public class JsonWebToken implements Serializable { private static final long serialVersionUID = -8136409077130940942L; @JsonProperty("jti") protected String id; protected Long exp; protected Long nbf; protected Long iat; @JsonProperty("iss") protected String issuer; @JsonProperty("aud") @JsonSerialize(using = StringOrArraySerializer.class) @JsonDeserialize(using = StringOrArrayDeserializer.class) protected String[] audience; @JsonProperty("sub") protected String subject; @JsonProperty("typ") protected String type; @JsonProperty("azp") public String issuedFor; protected Map otherClaims = new HashMap<>(); public String getId() { return id; } public JsonWebToken id(String id) { this.id = id; return this; } public Long getExp() { return exp; } public JsonWebToken exp(Long exp) { this.exp = exp; return this; } @JsonIgnore public boolean isExpired() { return exp != null && exp != 0 ? Time.currentTime() > exp : false; } public Long getNbf() { return nbf; } public JsonWebToken nbf(Long nbf) { this.nbf = nbf; return this; } @JsonIgnore public boolean isNotBefore(int allowedTimeSkew) { return nbf != null ? Time.currentTime() + allowedTimeSkew >= nbf : true; } /** * Tests that the token is not expired and is not-before. * * @return */ @JsonIgnore public boolean isActive() { return isActive(0); } @JsonIgnore public boolean isActive(int allowedTimeSkew) { return !isExpired() && isNotBefore(allowedTimeSkew); } public Long getIat() { return iat; } /** * Set issuedAt to the current time */ @JsonIgnore public JsonWebToken issuedNow() { iat = Long.valueOf(Time.currentTime()); return this; } public JsonWebToken iat(Long iat) { this.iat = iat; return this; } public String getIssuer() { return issuer; } public JsonWebToken issuer(String issuer) { this.issuer = issuer; return this; } @JsonIgnore public String[] getAudience() { return audience; } public boolean hasAudience(String audience) { if (this.audience == null) return false; for (String a : this.audience) { if (a.equals(audience)) { return true; } } return false; } public JsonWebToken audience(String... audience) { this.audience = audience; return this; } public JsonWebToken addAudience(String audience) { if (this.audience == null) { this.audience = new String[] { audience }; } else { // Check if audience is already there for (String aud : this.audience) { if (audience.equals(aud)) { return this; } } String[] newAudience = Arrays.copyOf(this.audience, this.audience.length + 1); newAudience[this.audience.length] = audience; this.audience = newAudience; } return this; } public String getSubject() { return subject; } public JsonWebToken subject(String subject) { this.subject = subject; return this; } public void setSubject(String subject) { this.subject = subject; } public String getType() { return type; } public JsonWebToken type(String type) { this.type = type; return this; } /** * OAuth client the token was issued for. * * @return */ public String getIssuedFor() { return issuedFor; } public JsonWebToken issuedFor(String issuedFor) { this.issuedFor = issuedFor; return this; } /** * This is a map of any other claims and data that might be in the IDToken. Could be custom claims set up by the auth server * * @return */ @JsonAnyGetter public Map getOtherClaims() { return otherClaims; } @JsonAnySetter public void setOtherClaims(String name, Object value) { otherClaims.put(name, value); } }