8442091eb12e169d5d8d0f0661456f39c0da9980.svn-base 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. package io.agora.media;
  2. import java.io.ByteArrayOutputStream;
  3. import java.io.IOException;
  4. import java.util.TreeMap;
  5. import static io.agora.media.Utils.crc32;
  6. public class AccessToken {
  7. public enum Privileges {
  8. kJoinChannel(1),
  9. kPublishAudioStream(2),
  10. kPublishVideoStream(3),
  11. kPublishDataStream(4),
  12. // For RTM only
  13. kRtmLogin(1000);
  14. // The following privileges have not
  15. // been implemented yet.
  16. //kPublishAudiocdn(5),
  17. //kPublishVideoCdn(6),
  18. //kRequestPublishAudioStream(7),
  19. //kRequestPublishVideoStream(8),
  20. //kRequestPublishDataStream(9),
  21. //kInvitePublishAudioStream(10),
  22. //kInvitePublishVideoStream(11),
  23. //kInvitePublishDataStream(12),
  24. //kAdministrateChannel(101),
  25. public short intValue;
  26. Privileges(int value) {
  27. intValue = (short) value;
  28. }
  29. }
  30. private static final String VER = "006";
  31. public String appId;
  32. public String appCertificate;
  33. public String channelName;
  34. public String uid;
  35. public byte[] signature;
  36. public byte[] messageRawContent;
  37. public int crcChannelName;
  38. public int crcUid;
  39. public PrivilegeMessage message;
  40. public int expireTimestamp;
  41. public AccessToken(String appId, String appCertificate, String channelName, String uid) {
  42. this.appId = appId;
  43. this.appCertificate = appCertificate;
  44. this.channelName = channelName;
  45. this.uid = uid;
  46. this.crcChannelName = 0;
  47. this.crcUid = 0;
  48. this.message = new PrivilegeMessage();
  49. }
  50. public String build() throws Exception {
  51. if (! Utils.isUUID(appId)) {
  52. return "";
  53. }
  54. if (!Utils.isUUID(appCertificate)) {
  55. return "";
  56. }
  57. messageRawContent = Utils.pack(message);
  58. signature = generateSignature(appCertificate,
  59. appId, channelName, uid, messageRawContent);
  60. crcChannelName = crc32(channelName);
  61. crcUid = crc32(uid);
  62. PackContent packContent = new PackContent(signature, crcChannelName, crcUid, messageRawContent);
  63. byte[] content = Utils.pack(packContent);
  64. return getVersion() + this.appId + Utils.base64Encode(content);
  65. }
  66. public void addPrivilege(Privileges privilege, int expireTimestamp) {
  67. message.messages.put(privilege.intValue, expireTimestamp);
  68. }
  69. public static String getVersion() {
  70. return VER;
  71. }
  72. public static byte[] generateSignature(String appCertificate,
  73. String appID, String channelName, String uid, byte[] message) throws Exception {
  74. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  75. try {
  76. baos.write(appID.getBytes());
  77. baos.write(channelName.getBytes());
  78. baos.write(uid.getBytes());
  79. baos.write(message);
  80. } catch (IOException e) {
  81. e.printStackTrace();
  82. }
  83. return Utils.hmacSign(appCertificate, baos.toByteArray());
  84. }
  85. public boolean fromString(String token) {
  86. if (!getVersion().equals(token.substring(0, Utils.VERSION_LENGTH))) {
  87. return false;
  88. }
  89. try {
  90. appId = token.substring(Utils.VERSION_LENGTH, Utils.VERSION_LENGTH + Utils.APP_ID_LENGTH);
  91. PackContent packContent = new PackContent();
  92. Utils.unpack(Utils.base64Decode(token.substring(Utils.VERSION_LENGTH + Utils.APP_ID_LENGTH, token.length())), packContent);
  93. signature = packContent.signature;
  94. crcChannelName = packContent.crcChannelName;
  95. crcUid = packContent.crcUid;
  96. messageRawContent = packContent.rawMessage;
  97. Utils.unpack(messageRawContent, message);
  98. } catch (Exception e) {
  99. e.printStackTrace();
  100. return false;
  101. }
  102. return true;
  103. }
  104. public class PrivilegeMessage implements PackableEx {
  105. public int salt;
  106. public int ts;
  107. public TreeMap<Short, Integer> messages;
  108. public PrivilegeMessage() {
  109. salt = Utils.randomInt();
  110. ts = Utils.getTimestamp() + 24 * 3600;
  111. messages = new TreeMap<>();
  112. }
  113. @Override
  114. public ByteBuf marshal(ByteBuf out) {
  115. return out.put(salt).put(ts).putIntMap(messages);
  116. }
  117. @Override
  118. public void unmarshal(ByteBuf in) {
  119. salt = in.readInt();
  120. ts = in.readInt();
  121. messages = in.readIntMap();
  122. }
  123. }
  124. public class PackContent implements PackableEx {
  125. public byte[] signature;
  126. public int crcChannelName;
  127. public int crcUid;
  128. public byte[] rawMessage;
  129. public PackContent() {
  130. // Nothing done
  131. }
  132. public PackContent(byte[] signature, int crcChannelName, int crcUid, byte[] rawMessage) {
  133. this.signature = signature;
  134. this.crcChannelName = crcChannelName;
  135. this.crcUid = crcUid;
  136. this.rawMessage = rawMessage;
  137. }
  138. @Override
  139. public ByteBuf marshal(ByteBuf out) {
  140. return out.put(signature).put(crcChannelName).put(crcUid).put(rawMessage);
  141. }
  142. @Override
  143. public void unmarshal(ByteBuf in) {
  144. signature = in.readBytes();
  145. crcChannelName = in.readInt();
  146. crcUid = in.readInt();
  147. rawMessage = in.readBytes();
  148. }
  149. }
  150. }