60b0b18ca2590dc98642e193aec75e3fdef2178a.svn-base 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. package io.agora.media;
  2. import javax.crypto.Mac;
  3. import javax.crypto.spec.SecretKeySpec;
  4. import java.util.Map;
  5. import java.util.TreeMap;
  6. public class AccessToken2 {
  7. public enum PrivilegeRtc {
  8. PRIVILEGE_JOIN_CHANNEL(1),
  9. PRIVILEGE_PUBLISH_AUDIO_STREAM(2),
  10. PRIVILEGE_PUBLISH_VIDEO_STREAM(3),
  11. PRIVILEGE_PUBLISH_DATA_STREAM(4),
  12. ;
  13. public short intValue;
  14. PrivilegeRtc(int value) {
  15. intValue = (short) value;
  16. }
  17. }
  18. public enum PrivilegeRtm {
  19. PRIVILEGE_JOIN_LOGIN(1),
  20. ;
  21. public short intValue;
  22. PrivilegeRtm(int value) {
  23. intValue = (short) value;
  24. }
  25. }
  26. public enum PrivilegeStreaming {
  27. PRIVILEGE_PUBLISH_MIX_STREAM(1),
  28. PRIVILEGE_PUBLISH_RAW_STREAM(2),
  29. ;
  30. public short intValue;
  31. PrivilegeStreaming(int value) {
  32. intValue = (short) value;
  33. }
  34. }
  35. public enum PrivilegeChat {
  36. PRIVILEGE_CHAT_USER(1),
  37. PRIVILEGE_CHAT_APP(2),
  38. ;
  39. public short intValue;
  40. PrivilegeChat(int value) {
  41. intValue = (short) value;
  42. }
  43. }
  44. private static final String VERSION = "007";
  45. public static final short SERVICE_TYPE_RTC = 1;
  46. public static final short SERVICE_TYPE_RTM = 2;
  47. public static final short SERVICE_TYPE_STREAMING = 3;
  48. public static final short SERVICE_TYPE_CHAT = 5;
  49. public String appCert = "";
  50. public String appId = "";
  51. public int expire;
  52. public int issueTs;
  53. public int salt;
  54. public Map<Short, Service> services = new TreeMap<>();
  55. public AccessToken2() {
  56. }
  57. public AccessToken2(String appId, String appCert, int expire) {
  58. this.appCert = appCert;
  59. this.appId = appId;
  60. this.expire = expire;
  61. this.issueTs = Utils.getTimestamp();
  62. this.salt = Utils.randomInt();
  63. }
  64. public void addService(Service service) {
  65. this.services.put(service.getServiceType(), service);
  66. }
  67. public String build() throws Exception {
  68. if (!Utils.isUUID(this.appId) || !Utils.isUUID(this.appCert)) {
  69. return "";
  70. }
  71. ByteBuf buf = new ByteBuf().put(this.appId).put(this.issueTs).put(this.expire).put(this.salt).put((short) this.services.size());
  72. byte[] signing = getSign();
  73. this.services.forEach((k, v) -> {
  74. v.pack(buf);
  75. });
  76. Mac mac = Mac.getInstance("HmacSHA256");
  77. mac.init(new SecretKeySpec(signing, "HmacSHA256"));
  78. byte[] signature = mac.doFinal(buf.asBytes());
  79. ByteBuf bufferContent = new ByteBuf();
  80. bufferContent.put(signature);
  81. bufferContent.buffer.put(buf.asBytes());
  82. return getVersion() + Utils.base64Encode(Utils.compress(bufferContent.asBytes()));
  83. }
  84. public Service getService(short serviceType) {
  85. if (serviceType == SERVICE_TYPE_RTC) {
  86. return new ServiceRtc();
  87. }
  88. if (serviceType == SERVICE_TYPE_RTM) {
  89. return new ServiceRtm();
  90. }
  91. if (serviceType == SERVICE_TYPE_STREAMING) {
  92. return new ServiceStreaming();
  93. }
  94. if (serviceType == SERVICE_TYPE_CHAT) {
  95. return new ServiceChat();
  96. }
  97. throw new IllegalArgumentException(String.format("unknown service type: `%d`", serviceType));
  98. }
  99. public byte[] getSign() throws Exception {
  100. Mac mac = Mac.getInstance("HmacSHA256");
  101. mac.init(new SecretKeySpec(new ByteBuf().put(this.issueTs).asBytes(), "HmacSHA256"));
  102. byte[] signing = mac.doFinal(this.appCert.getBytes());
  103. mac.init(new SecretKeySpec(new ByteBuf().put(this.salt).asBytes(), "HmacSHA256"));
  104. return mac.doFinal(signing);
  105. }
  106. public static String getUidStr(int uid) {
  107. if (uid == 0) {
  108. return "";
  109. }
  110. return String.valueOf(uid);
  111. }
  112. public static String getVersion() {
  113. return VERSION;
  114. }
  115. public boolean parse(String token) {
  116. if (!getVersion().equals(token.substring(0, Utils.VERSION_LENGTH))) {
  117. return false;
  118. }
  119. byte[] data = Utils.decompress(Utils.base64Decode(token.substring(Utils.VERSION_LENGTH)));
  120. ByteBuf buff = new ByteBuf(data);
  121. String signature = buff.readString();
  122. this.appId = buff.readString();
  123. this.issueTs = buff.readInt();
  124. this.expire = buff.readInt();
  125. this.salt = buff.readInt();
  126. short servicesNum = buff.readShort();
  127. for (int i = 0; i < servicesNum; i++) {
  128. short serviceType = buff.readShort();
  129. Service service = getService(serviceType);
  130. service.unpack(buff);
  131. this.services.put(serviceType, service);
  132. }
  133. return true;
  134. }
  135. public static class Service {
  136. public short type;
  137. public TreeMap<Short, Integer> privileges = new TreeMap<Short, Integer>() {
  138. };
  139. public Service() {
  140. }
  141. public Service(short serviceType) {
  142. this.type = serviceType;
  143. }
  144. public void addPrivilegeRtc(PrivilegeRtc privilege, int expire) {
  145. this.privileges.put(privilege.intValue, expire);
  146. }
  147. public void addPrivilegeRtm(PrivilegeRtm privilege, int expire) {
  148. this.privileges.put(privilege.intValue, expire);
  149. }
  150. public void addPrivilegeChat(PrivilegeChat privilege, int expire) {
  151. this.privileges.put(privilege.intValue, expire);
  152. }
  153. public TreeMap<Short, Integer> getPrivileges() {
  154. return this.privileges;
  155. }
  156. public short getServiceType() {
  157. return this.type;
  158. }
  159. public ByteBuf pack(ByteBuf buf) {
  160. return buf.put(this.type).putIntMap(this.privileges);
  161. }
  162. public void unpack(ByteBuf byteBuf) {
  163. this.privileges = byteBuf.readIntMap();
  164. }
  165. }
  166. public static class ServiceRtc extends Service {
  167. public String channelName;
  168. public String uid;
  169. public ServiceRtc() {
  170. this.type = SERVICE_TYPE_RTC;
  171. }
  172. public ServiceRtc(String channelName, String uid) {
  173. this.type = SERVICE_TYPE_RTC;
  174. this.channelName = channelName;
  175. this.uid = uid;
  176. }
  177. public String getChannelName() {
  178. return this.channelName;
  179. }
  180. public String getUid() {
  181. return this.uid;
  182. }
  183. public ByteBuf pack(ByteBuf buf) {
  184. return super.pack(buf).put(this.channelName).put(this.uid);
  185. }
  186. public void unpack(ByteBuf byteBuf) {
  187. super.unpack(byteBuf);
  188. this.channelName = byteBuf.readString();
  189. this.uid = byteBuf.readString();
  190. }
  191. }
  192. public static class ServiceRtm extends Service {
  193. public String userId;
  194. public ServiceRtm() {
  195. this.type = SERVICE_TYPE_RTM;
  196. }
  197. public ServiceRtm(String userId) {
  198. this.type = SERVICE_TYPE_RTM;
  199. this.userId = userId;
  200. }
  201. public String getUserId() {
  202. return this.userId;
  203. }
  204. public ByteBuf pack(ByteBuf buf) {
  205. return super.pack(buf).put(this.userId);
  206. }
  207. public void unpack(ByteBuf byteBuf) {
  208. super.unpack(byteBuf);
  209. this.userId = byteBuf.readString();
  210. }
  211. }
  212. public static class ServiceStreaming extends Service {
  213. public String channelName;
  214. public String uid;
  215. public ServiceStreaming() {
  216. this.type = SERVICE_TYPE_STREAMING;
  217. }
  218. public ServiceStreaming(String channelName, String uid) {
  219. this.type = SERVICE_TYPE_STREAMING;
  220. this.channelName = channelName;
  221. this.uid = uid;
  222. }
  223. public ByteBuf pack(ByteBuf buf) {
  224. return super.pack(buf).put(this.channelName).put(this.uid);
  225. }
  226. public void unpack(ByteBuf byteBuf) {
  227. super.unpack(byteBuf);
  228. this.channelName = byteBuf.readString();
  229. this.uid = byteBuf.readString();
  230. }
  231. }
  232. public static class ServiceChat extends Service {
  233. public String userId;
  234. public ServiceChat() {
  235. this.type = SERVICE_TYPE_CHAT;
  236. this.userId = "";
  237. }
  238. public ServiceChat(String userId) {
  239. this.type = SERVICE_TYPE_CHAT;
  240. this.userId = userId;
  241. }
  242. public String getUserId() {
  243. return this.userId;
  244. }
  245. public ByteBuf pack(ByteBuf buf) {
  246. return super.pack(buf).put(this.userId);
  247. }
  248. public void unpack(ByteBuf byteBuf) {
  249. super.unpack(byteBuf);
  250. this.userId = byteBuf.readString();
  251. }
  252. }
  253. }