001/* 002 * Copyright 2024 Vonage 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package com.vonage.client.video; 017 018import com.vonage.jwt.Jwt; 019import java.time.Duration; 020import java.time.ZonedDateTime; 021import java.util.List; 022import java.util.Objects; 023 024/** 025 * Defines values for the {@code options} parameter of the 026 * {@link VideoClient#generateToken(String sessionId, TokenOptions tokenOptions)} method. 027 */ 028public class TokenOptions { 029 private final Role role; 030 private final Duration ttl; 031 private final String data; 032 private final List<String> initialLayoutClassList; 033 034 private TokenOptions(Builder builder) { 035 role = Objects.requireNonNull(builder.role, "Role cannot be null."); 036 037 ttl = Objects.requireNonNull(builder.ttl, "Time-to-Live cannot be null."); 038 if (ttl.toMillis() > Duration.ofDays(30).toMillis()) { 039 throw new IllegalArgumentException("Time-to-Live cannot exceed 30 days."); 040 } 041 042 // default value of null means to omit the key "connection_data" from the token 043 if ((data = builder.data) != null && data.length() > 1000) { 044 throw new IllegalArgumentException("Connection data cannot exceed 1000 characters."); 045 } 046 047 // default value of null means to omit the key "initialLayoutClassList" from the token 048 initialLayoutClassList = builder.initialLayoutClassList; 049 } 050 051 protected void addClaims(Jwt.Builder jwt) { 052 jwt.expiresAt(ZonedDateTime.now().plus(ttl)); 053 jwt.addClaim("role", role.toString()); 054 if (data != null) { 055 jwt.addClaim("connection_data", data); 056 } 057 if (initialLayoutClassList != null) { 058 jwt.addClaim("initial_layout_class_list", String.join(" ", initialLayoutClassList)); 059 } 060 } 061 062 /** 063 * Returns the role assigned to the token. 064 * 065 * @return The role, as an enum. 066 * @see Builder#role(Role) 067 */ 068 public Role getRole() { 069 return role; 070 } 071 072 /** 073 * Returns the time-to-live for the JWT. 074 * 075 * @return The TTL duration. 076 * @see Builder#expiryLength(Duration) 077 */ 078 public Duration getExpiryLength() { 079 return ttl; 080 } 081 082 /** 083 * Returns the connection metadata assigned to the token. 084 * 085 * @return The connection data, as a string. 086 * @see Builder#data(String) 087 */ 088 public String getData() { 089 return data; 090 } 091 092 /** 093 * Returns the initial layout class list for streams published by the client using this token. 094 * 095 * @return The initial layout classes, as a List of strings. 096 * @see Builder#initialLayoutClassList(List) 097 */ 098 public List<String> getInitialLayoutClassList() { 099 return initialLayoutClassList; 100 } 101 102 /** 103 * Entry point for constructing an instance of TokenOptions. 104 * 105 * @return A new Builder. 106 */ 107 public static Builder builder() { 108 return new Builder(); 109 } 110 111 /** 112 * Use this class to create a TokenOptions object. 113 */ 114 public static class Builder { 115 private Role role = Role.PUBLISHER; 116 private Duration ttl = Duration.ofHours(24); 117 private String data; 118 private List<String> initialLayoutClassList; 119 120 Builder() {} 121 122 /** 123 * Sets the role for the token. Each role defines a set of permissions granted to the token. 124 * 125 * @param role The role for the token. Valid values are defined in the Role class: 126 * <ul> 127 * <li> {@code SUBSCRIBER} — A subscriber can only subscribe to streams.</li> 128 * 129 * <li> {@code PUBLISHER} — A publisher can publish streams, subscribe to 130 * streams, and signal. (This is the default value if you do not specify a role.)</li> 131 * 132 * <li> {@code MODERATOR} — In addition to the privileges granted to a 133 * publisher, a moderator can perform moderation functions, such as forcing clients to 134 * disconnect, to stop publishing streams, or to mute audio in published streams. See the 135 * <a href="https://tokbox.com/developer/guides/moderation/">Moderation developer guide</a>. 136 * </li> 137 * </ul> 138 * 139 * @return This builder. 140 */ 141 public Builder role(Role role) { 142 this.role = role; 143 return this; 144 } 145 146 /** 147 * Sets the expiration time for the token. 148 * 149 * @param ttl The expiration length (time-to-live) The maximum duration is 30 days. Default is 24 hours. 150 * 151 * @return This builder. 152 */ 153 public Builder expiryLength(Duration ttl) { 154 this.ttl = ttl; 155 return this; 156 } 157 158 /** 159 * A string containing connection metadata describing the end-user. For example, you 160 * can pass the user ID, name, or other data describing the end-user. The length of the 161 * string is limited to 1000 characters. This data cannot be updated once it is set. 162 * 163 * @param data The connection metadata. 164 * 165 * @return This builder. 166 */ 167 public Builder data(String data) throws IllegalArgumentException { 168 this.data = data; 169 return this; 170 } 171 172 /** 173 * A List of class names (strings) to be used as the initial layout classes 174 * for streams published by the client. Layout classes are used in customizing the layout 175 * of videos in 176 * <a href="https://tokbox.com/developer/guides/broadcast/live-streaming/">live streaming 177 * broadcasts</a> and 178 * <a href="https://tokbox.com/developer/guides/archiving/layout-control.html">composed 179 * archives</a>. 180 * 181 * @param initialLayoutClassList The initial layout class list. 182 * 183 * @return This builder. 184 */ 185 public Builder initialLayoutClassList (List<String> initialLayoutClassList) { 186 this.initialLayoutClassList = initialLayoutClassList; 187 return this; 188 } 189 190 /** 191 * Builds the TokenOptions object. 192 * 193 * @return A new TokenOptions instance with this builder's properties. 194 */ 195 public TokenOptions build() { 196 return new TokenOptions(this); 197 } 198 } 199}