001package com.plivo.api;
002
003import com.auth0.jwt.JWT;
004import com.auth0.jwt.algorithms.Algorithm;
005import com.plivo.api.exceptions.PlivoValidationException;
006import java.time.*;
007import java.util.Date;
008import java.util.HashMap;
009import java.util.Map;
010
011public class AccessToken {
012
013  private String authId;
014  private String authToken;
015  public String username;
016  public Date validFrom;
017  public Duration lifetime = Duration.ofHours(24);
018  public Date validTill;
019  public HashMap<String, HashMap<String, Object>> grants = new HashMap();
020  public String uid;
021
022  public AccessToken(String authId, String authToken, String username) {
023    this.authId = authId;
024    this.authToken = authToken;
025    this.username = username;
026    this.AllowIncoming(false);
027    this.AllowOutgoing(false);
028  }
029
030  public AccessToken ValidFrom(Date validFrom) {
031    this.validFrom = validFrom;
032    return this;
033  }
034
035  public AccessToken Lifetime(Duration lifetime) throws PlivoValidationException {
036    if (lifetime.toMillis() < 180000 || lifetime.toMillis() > 86400000) {
037      throw new PlivoValidationException("lifetime out of [180, 86400]");
038    }
039    this.lifetime = lifetime;
040    return this;
041  }
042
043  public AccessToken ValidTill(Date validTill) throws PlivoValidationException {
044    if (this.validFrom == null && this.lifetime == null) {
045      throw new PlivoValidationException("define either one of validFrom or lifetime as well");
046    }
047    if (this.validFrom != null && this.lifetime != null) {
048      throw new PlivoValidationException("define either one of validFrom or lifetime only");
049    }
050    if (this.lifetime != null) {
051      validTill.setTime(validTill.getTime() - this.lifetime.toMillis());
052      this.validFrom = validTill;
053    } else {
054      this.lifetime = Duration.ofMillis(validTill.getTime() - this.validFrom.getTime());
055    }
056    return this;
057  }
058
059  public AccessToken Uid(String uid) {
060    this.uid = uid;
061    return this;
062  }
063
064  public AccessToken AllowIncoming(Boolean allow) {
065    if (this.grants.get("voice") == null) this.grants.put("voice", new HashMap());
066    this.grants.get("voice").put("incoming_allow", allow);
067    return this;
068  }
069
070  public AccessToken AllowOutgoing(Boolean allow) {
071    if (this.grants.get("voice") == null) this.grants.put("voice", new HashMap());
072    this.grants.get("voice").put("outgoing_allow", allow);
073    return this;
074  }
075
076  public String toJwt() {
077    if (this.validFrom == null) this.validFrom = Date.from(Instant.now());
078    if (this.lifetime == null) this.lifetime = Duration.ofHours(24);
079    if (this.uid == null) this.uid = this.username + "-" + Long.toString(this.validFrom.getTime());
080    Algorithm algorithm = Algorithm.HMAC256(this.authToken);
081    Map<String, Object> headerClaims = new HashMap();
082    headerClaims.put("cty", "plivo;v=1");
083    return JWT.create()
084        .withHeader(headerClaims)
085        .withIssuer(this.authId)
086        .withSubject(this.username)
087        .withNotBefore(this.validFrom)
088        .withExpiresAt(new Date((this.validFrom.getTime() + this.lifetime.toMillis())))
089        .withJWTId(this.uid)
090        .withClaim("grants", this.grants)
091        .sign(algorithm);
092  }
093}