From 6271ab875ee58786171b6eac2fbfb23d5d889740 Mon Sep 17 00:00:00 2001 From: sunshinexcode <24xinhui@163.com> Date: Thu, 19 Dec 2024 21:10:22 +0800 Subject: [PATCH] feat(): generate token by Lua --- .../lua/.devcontainer/devcontainer.json | 19 + DynamicKey/AgoraDynamicKey/lua/.gitignore | 2 + DynamicKey/AgoraDynamicKey/lua/.luarc.json | 13 + DynamicKey/AgoraDynamicKey/lua/README.md | 31 ++ .../lua/agora-token-0.1.0-1.rockspec | 30 ++ .../lua/examples/apaas_token_builder.lua | 45 +++ .../lua/examples/chat_token_builder.lua | 34 ++ .../lua/examples/education_token_builder.lua | 45 +++ .../lua/examples/fpa_token_builder.lua | 23 ++ .../lua/examples/rtc_token_builder.lua | 116 ++++++ .../lua/examples/rtm_token_builder.lua | 27 ++ .../AgoraDynamicKey/lua/src/access_token.lua | 346 ++++++++++++++++++ .../lua/src/apaas_token_builder.lua | 69 ++++ .../lua/src/chat_token_builder.lua | 42 +++ .../lua/src/education_token_builder.lua | 69 ++++ .../lua/src/fpa_token_builder.lua | 22 ++ .../lua/src/rtc_token_builder.lua | 197 ++++++++++ .../lua/src/rtm_token_builder.lua | 22 ++ DynamicKey/AgoraDynamicKey/lua/src/utils.lua | 173 +++++++++ .../lua/tests/test_access_token.lua | 52 +++ .../AgoraDynamicKey/lua/tests/test_utils.lua | 57 +++ 21 files changed, 1434 insertions(+) create mode 100644 DynamicKey/AgoraDynamicKey/lua/.devcontainer/devcontainer.json create mode 100644 DynamicKey/AgoraDynamicKey/lua/.gitignore create mode 100644 DynamicKey/AgoraDynamicKey/lua/.luarc.json create mode 100644 DynamicKey/AgoraDynamicKey/lua/README.md create mode 100644 DynamicKey/AgoraDynamicKey/lua/agora-token-0.1.0-1.rockspec create mode 100644 DynamicKey/AgoraDynamicKey/lua/examples/apaas_token_builder.lua create mode 100644 DynamicKey/AgoraDynamicKey/lua/examples/chat_token_builder.lua create mode 100644 DynamicKey/AgoraDynamicKey/lua/examples/education_token_builder.lua create mode 100644 DynamicKey/AgoraDynamicKey/lua/examples/fpa_token_builder.lua create mode 100644 DynamicKey/AgoraDynamicKey/lua/examples/rtc_token_builder.lua create mode 100644 DynamicKey/AgoraDynamicKey/lua/examples/rtm_token_builder.lua create mode 100644 DynamicKey/AgoraDynamicKey/lua/src/access_token.lua create mode 100644 DynamicKey/AgoraDynamicKey/lua/src/apaas_token_builder.lua create mode 100644 DynamicKey/AgoraDynamicKey/lua/src/chat_token_builder.lua create mode 100644 DynamicKey/AgoraDynamicKey/lua/src/education_token_builder.lua create mode 100644 DynamicKey/AgoraDynamicKey/lua/src/fpa_token_builder.lua create mode 100644 DynamicKey/AgoraDynamicKey/lua/src/rtc_token_builder.lua create mode 100644 DynamicKey/AgoraDynamicKey/lua/src/rtm_token_builder.lua create mode 100644 DynamicKey/AgoraDynamicKey/lua/src/utils.lua create mode 100644 DynamicKey/AgoraDynamicKey/lua/tests/test_access_token.lua create mode 100644 DynamicKey/AgoraDynamicKey/lua/tests/test_utils.lua diff --git a/DynamicKey/AgoraDynamicKey/lua/.devcontainer/devcontainer.json b/DynamicKey/AgoraDynamicKey/lua/.devcontainer/devcontainer.json new file mode 100644 index 00000000..7a0bdf00 --- /dev/null +++ b/DynamicKey/AgoraDynamicKey/lua/.devcontainer/devcontainer.json @@ -0,0 +1,19 @@ +{ + "name": "AgoraDynamicKey-lua", + "image": "nickblah/lua:5.4.7-luarocks-ubuntu", + "customizations": { + "vscode": { + "extensions": [ + "sumneko.lua" + ] + } + }, + "features": { + "ghcr.io/devcontainers/features/git:1": {} + }, + "workspaceMount": "source=${localWorkspaceFolder},target=/app,type=bind", + "workspaceFolder": "/app", + "postCreateCommand": { + "install dependencies": "apt-get update && apt-get install -y build-essential zlib1g-dev libssl-dev && luarocks make agora-token-0.1.0-1.rockspec" + } +} \ No newline at end of file diff --git a/DynamicKey/AgoraDynamicKey/lua/.gitignore b/DynamicKey/AgoraDynamicKey/lua/.gitignore new file mode 100644 index 00000000..706fd07f --- /dev/null +++ b/DynamicKey/AgoraDynamicKey/lua/.gitignore @@ -0,0 +1,2 @@ +.idea +.vscode diff --git a/DynamicKey/AgoraDynamicKey/lua/.luarc.json b/DynamicKey/AgoraDynamicKey/lua/.luarc.json new file mode 100644 index 00000000..fe1d0bf0 --- /dev/null +++ b/DynamicKey/AgoraDynamicKey/lua/.luarc.json @@ -0,0 +1,13 @@ +{ + "workspace": { + "library": [ + "/usr/local" + ] + }, + "diagnostics": { + "globals": [ + "error", + "os" + ] + } +} \ No newline at end of file diff --git a/DynamicKey/AgoraDynamicKey/lua/README.md b/DynamicKey/AgoraDynamicKey/lua/README.md new file mode 100644 index 00000000..674765ef --- /dev/null +++ b/DynamicKey/AgoraDynamicKey/lua/README.md @@ -0,0 +1,31 @@ +# Authenticate Users with a token + +To enhance communication security, Agora uses tokens to authenticate users before they access the Agora service, or joining an RTC channel. + +## Code structure + +Under the `lua` directory: + +* `/src/` contains the source code for generating a token, where `rtc_token_builder` is used for generating an RTC token, and `rtm_token_builder` is used for generating an RTM token. +* `/examples/` contains the sample code for generating a token, where `rtc_token_builder` is used for generating an RTC token, and `rtm_token_builder` is used for generating an RTM token. + +## Generate a token with the sample code + +This section takes `rtc_token_builder` as an example to show how to generate a token with the sample code. + +Before proceeding, ensure that you have installed the latest version of Lua. + +1. Download or clone the [Tools](https://github.com/AgoraIO/Tools) repository. + +2. Open the `DynamicKey/AgoraDynamicKey/lua/examples/rtc_token_builder.lua` file, replace the value of `app_id`, `app_certificate`, `channel_name`, and `uid` with your own, and comment out the code snippets of `build_token_with_user_account`. + +3. Open your Terminal, navigate to the same directory, and run the following command. + + ``` + luarocks make agora-token-0.1.0-1.rockspec + lua examples/rtc_token_builder.lua + ``` + +## Reference + +For a complete authentication flow between the app server and app client, see [Authenticate Your Users with Tokens](). \ No newline at end of file diff --git a/DynamicKey/AgoraDynamicKey/lua/agora-token-0.1.0-1.rockspec b/DynamicKey/AgoraDynamicKey/lua/agora-token-0.1.0-1.rockspec new file mode 100644 index 00000000..be2bbd55 --- /dev/null +++ b/DynamicKey/AgoraDynamicKey/lua/agora-token-0.1.0-1.rockspec @@ -0,0 +1,30 @@ +package = "agora-token" +version = "0.1.0-1" +source = { + url = "git+https://github.com/AgoraIO/Tools", +} +description = { + summary = "Agora Token for lua", + homepage = "https://github.com/AgoraIO/Tools/tree/master/DynamicKey/AgoraDynamicKey/lua", + license = "MIT", +} +dependencies = { + "base64", + "luaossl", + "luaunit", + "lua-zlib", + "md5" +} +build = { + type = "builtin", + modules = { + ["agora_token.access_token"] = "src/access_token.lua", + ["agora_token.apaas_token_builder"] = "src/apaas_token_builder.lua", + ["agora_token.chat_token_builder"] = "src/chat_token_builder.lua", + ["agora_token.education_token_builder"] = "src/education_token_builder.lua", + ["agora_token.fpa_token_builder"] = "src/fpa_token_builder.lua", + ["agora_token.rtc_token_builder"] = "src/rtc_token_builder.lua", + ["agora_token.rtm_token_builder"] = "src/rtm_token_builder.lua", + ["agora_token.utils"] = "src/utils.lua" + } +} diff --git a/DynamicKey/AgoraDynamicKey/lua/examples/apaas_token_builder.lua b/DynamicKey/AgoraDynamicKey/lua/examples/apaas_token_builder.lua new file mode 100644 index 00000000..b3dc230a --- /dev/null +++ b/DynamicKey/AgoraDynamicKey/lua/examples/apaas_token_builder.lua @@ -0,0 +1,45 @@ +local apaas_token_builder = require("agora_token.apaas_token_builder") + +-- Need to set environment variable AGORA_APP_ID +local app_id = os.getenv("AGORA_APP_ID") or "" +-- Need to set environment variable AGORA_APP_CERTIFICATE +local app_certificate = os.getenv("AGORA_APP_CERTIFICATE") or "" + +local room_uuid = "123" +local user_uuid = "2882341273" +local role = 1 +local expire = 600 + +print("App Id: " .. app_id) +print("App Certificate: " .. app_certificate) +if app_id == "" or app_certificate == "" then + print("Need to set environment variable AGORA_APP_ID and AGORA_APP_CERTIFICATE") + return +end + +local status, token = pcall(function() + return apaas_token_builder.build_room_user_token(app_id, app_certificate, room_uuid, user_uuid, role, expire) +end) +if status then + print("Apaas room user token: " .. token) +else + print("Error: " .. token) +end + +status, token = pcall(function() + return apaas_token_builder.build_user_token(app_id, app_certificate, user_uuid, expire) +end) +if status then + print("Apaas user token: " .. token) +else + print("Error: " .. token) +end + +status, token = pcall(function() + return apaas_token_builder.build_app_token(app_id, app_certificate, expire) +end) +if status then + print("Apaas app token: " .. token) +else + print("Error: " .. token) +end diff --git a/DynamicKey/AgoraDynamicKey/lua/examples/chat_token_builder.lua b/DynamicKey/AgoraDynamicKey/lua/examples/chat_token_builder.lua new file mode 100644 index 00000000..9762cbdd --- /dev/null +++ b/DynamicKey/AgoraDynamicKey/lua/examples/chat_token_builder.lua @@ -0,0 +1,34 @@ +local chat_token_builder = require("agora_token.chat_token_builder") + +-- Need to set environment variable AGORA_APP_ID +local app_id = os.getenv("AGORA_APP_ID") or "" +-- Need to set environment variable AGORA_APP_CERTIFICATE +local app_certificate = os.getenv("AGORA_APP_CERTIFICATE") or "" + +local user_uuid = "a7180cb0-1d4a-11ed-9210-89ff47c9da5e" +local expire = 600 + +print("App Id: " .. app_id) +print("App Certificate: " .. app_certificate) +if app_id == "" or app_certificate == "" then + print("Need to set environment variable AGORA_APP_ID and AGORA_APP_CERTIFICATE") + return +end + +local status, token = pcall(function() + return chat_token_builder.build_chat_app_token(app_id, app_certificate, expire) +end) +if status then + print("ChatAppToken: " .. token) +else + print("Error: " .. token) +end + +status, token = pcall(function() + return chat_token_builder.build_chat_user_token(app_id, app_certificate, user_uuid, expire) +end) +if status then + print("ChatUserToken: " .. token) +else + print("Error: " .. token) +end diff --git a/DynamicKey/AgoraDynamicKey/lua/examples/education_token_builder.lua b/DynamicKey/AgoraDynamicKey/lua/examples/education_token_builder.lua new file mode 100644 index 00000000..fdc3b254 --- /dev/null +++ b/DynamicKey/AgoraDynamicKey/lua/examples/education_token_builder.lua @@ -0,0 +1,45 @@ +local education_token_builder = require("agora_token.education_token_builder") + +-- Need to set environment variable AGORA_APP_ID +local app_id = os.getenv("AGORA_APP_ID") or "" +-- Need to set environment variable AGORA_APP_CERTIFICATE +local app_certificate = os.getenv("AGORA_APP_CERTIFICATE") or "" + +local room_uuid = "123" +local user_uuid = "2882341273" +local role = 1 +local expire = 600 + +print("App Id: " .. app_id) +print("App Certificate: " .. app_certificate) +if app_id == "" or app_certificate == "" then + print("Need to set environment variable AGORA_APP_ID and AGORA_APP_CERTIFICATE") + return +end + +local status, token = pcall(function() + return education_token_builder.build_room_user_token(app_id, app_certificate, room_uuid, user_uuid, role, expire) +end) +if status then + print("Education room user token: " .. token) +else + print("Error: " .. token) +end + +status, token = pcall(function() + return education_token_builder.build_user_token(app_id, app_certificate, user_uuid, expire) +end) +if status then + print("Education user token: " .. token) +else + print("Error: " .. token) +end + +status, token = pcall(function() + return education_token_builder.build_app_token(app_id, app_certificate, expire) +end) +if status then + print("Education app token: " .. token) +else + print("Error: " .. token) +end diff --git a/DynamicKey/AgoraDynamicKey/lua/examples/fpa_token_builder.lua b/DynamicKey/AgoraDynamicKey/lua/examples/fpa_token_builder.lua new file mode 100644 index 00000000..b4a56b06 --- /dev/null +++ b/DynamicKey/AgoraDynamicKey/lua/examples/fpa_token_builder.lua @@ -0,0 +1,23 @@ +local fpa_token_builder = require("agora_token.fpa_token_builder") + +-- Need to set environment variable AGORA_APP_ID +local app_id = os.getenv("AGORA_APP_ID") or "" +-- Need to set environment variable AGORA_APP_CERTIFICATE +local app_certificate = os.getenv("AGORA_APP_CERTIFICATE") or "" + +print("App Id: " .. app_id) +print("App Certificate: " .. app_certificate) + +if app_id == "" or app_certificate == "" then + print("Need to set environment variable AGORA_APP_ID and AGORA_APP_CERTIFICATE") + return +end + +local status, token = pcall(function() + return fpa_token_builder.build_token(app_id, app_certificate) +end) +if status then + print("Token with FPA service: " .. token) +else + print("Error: " .. token) +end diff --git a/DynamicKey/AgoraDynamicKey/lua/examples/rtc_token_builder.lua b/DynamicKey/AgoraDynamicKey/lua/examples/rtc_token_builder.lua new file mode 100644 index 00000000..ab71cd67 --- /dev/null +++ b/DynamicKey/AgoraDynamicKey/lua/examples/rtc_token_builder.lua @@ -0,0 +1,116 @@ +local rtc_token_builder = require("agora_token.rtc_token_builder") + +-- Need to set environment variable AGORA_APP_ID +local app_id = os.getenv("AGORA_APP_ID") or "" +-- Need to set environment variable AGORA_APP_CERTIFICATE +local app_certificate = os.getenv("AGORA_APP_CERTIFICATE") or "" + +local channel_name = "7d72365eb983485397e3e3f9d460bdda" +local uid = 2882341273 +local uid_str = "2882341273" +local token_expiration_in_seconds = 3600 +local privilege_expiration_in_seconds = 3600 +local join_channel_privilege_expire_in_seconds = 3600 +local pub_audio_privilege_expire_in_seconds = 3600 +local pub_video_privilege_expire_in_seconds = 3600 +local pub_data_stream_privilege_expire_in_seconds = 3600 + +print("App Id: " .. app_id) +print("App Certificate: " .. app_certificate) +if app_id == nil or app_certificate == nil or app_id == "" or app_certificate == "" then + print("Need to set environment variable AGORA_APP_ID and AGORA_APP_CERTIFICATE") + return +end + +local status, token = pcall(function() + return rtc_token_builder.build_token_with_uid( + app_id, + app_certificate, + channel_name, + uid, + rtc_token_builder.ROLE_PUBLISHER, + token_expiration_in_seconds, + privilege_expiration_in_seconds) +end) + +if status then + print("Token with int uid: " .. token) +else + print("Error: " .. token) +end + +status, token = pcall(function() + return rtc_token_builder.build_token_with_user_account( + app_id, + app_certificate, + channel_name, + uid_str, + rtc_token_builder.ROLE_PUBLISHER, + token_expiration_in_seconds, + privilege_expiration_in_seconds + ) +end) + +if status then + print("Token with user account: " .. token) +else + print("Error: " .. token) +end + +status, token = pcall(function() + return rtc_token_builder.build_token_with_uid_and_privilege( + app_id, + app_certificate, + channel_name, + uid, + token_expiration_in_seconds, + join_channel_privilege_expire_in_seconds, + pub_audio_privilege_expire_in_seconds, + pub_video_privilege_expire_in_seconds, + pub_data_stream_privilege_expire_in_seconds + ) +end) + +if status then + print("Token with int uid and privilege: " .. token) +else + print("Error: " .. token) +end + +status, token = pcall(function() + return rtc_token_builder.build_token_with_user_account_and_privilege( + app_id, + app_certificate, + channel_name, + uid_str, + token_expiration_in_seconds, + join_channel_privilege_expire_in_seconds, + pub_audio_privilege_expire_in_seconds, + pub_video_privilege_expire_in_seconds, + pub_data_stream_privilege_expire_in_seconds + ) +end) + +if status then + print("Token with user account and privilege: " .. token) +else + print("Error: " .. token) +end + +status, token = pcall(function() + return rtc_token_builder.build_token_with_rtm( + app_id, + app_certificate, + channel_name, + uid_str, + rtc_token_builder.ROLE_PUBLISHER, + token_expiration_in_seconds, + privilege_expiration_in_seconds + ) +end) + +if status then + print("Token with RTM: " .. token) +else + print("Error: " .. token) +end diff --git a/DynamicKey/AgoraDynamicKey/lua/examples/rtm_token_builder.lua b/DynamicKey/AgoraDynamicKey/lua/examples/rtm_token_builder.lua new file mode 100644 index 00000000..f5dbe93a --- /dev/null +++ b/DynamicKey/AgoraDynamicKey/lua/examples/rtm_token_builder.lua @@ -0,0 +1,27 @@ +local rtm_token_builder = require("agora_token.rtm_token_builder") + +-- Need to set environment variable AGORA_APP_ID +local app_id = os.getenv("AGORA_APP_ID") or "" +-- Need to set environment variable AGORA_APP_CERTIFICATE +local app_certificate = os.getenv("AGORA_APP_CERTIFICATE") or "" + +local user_id = "test_user_id" +local expiration_seconds = 3600 + +print("App Id: " .. app_id) +print("App Certificate: " .. app_certificate) + +if app_id == "" or app_certificate == "" then + print("Need to set environment variable AGORA_APP_ID and AGORA_APP_CERTIFICATE") + return +end + +local status, token = pcall(function() + return rtm_token_builder.build_token(app_id, app_certificate, user_id, expiration_seconds) +end) + +if status then + print("Rtm Token: " .. token) +else + print("Error: " .. token) +end diff --git a/DynamicKey/AgoraDynamicKey/lua/src/access_token.lua b/DynamicKey/AgoraDynamicKey/lua/src/access_token.lua new file mode 100644 index 00000000..1a12920a --- /dev/null +++ b/DynamicKey/AgoraDynamicKey/lua/src/access_token.lua @@ -0,0 +1,346 @@ +local utils = require("agora_token.utils") + +local VERSION = "007" +local VERSION_LENGTH = 3 + +-- Service type +local SERVICE_TYPE_RTC = 1 +local SERVICE_TYPE_RTM = 2 +local SERVICE_TYPE_FPA = 4 +local SERVICE_TYPE_CHAT = 5 +local SERVICE_TYPE_APAAS = 7 + +-- Rtc +local PRIVILEGE_JOIN_CHANNEL = 1 +local PRIVILEGE_PUBLISH_AUDIO_STREAM = 2 +local PRIVILEGE_PUBLISH_VIDEO_STREAM = 3 +local PRIVILEGE_PUBLISH_DATA_STREAM = 4 + +-- Rtm +-- Fpa +local PRIVILEGE_LOGIN = 1 + +-- Chat +local PRIVILEGE_CHAT_USER = 1 +local PRIVILEGE_CHAT_APP = 2 + +-- Apaas +local PRIVILEGE_APAAS_ROOM_USER = 1 +local PRIVILEGE_APAAS_USER = 2 +local PRIVILEGE_APAAS_APP = 3 + +local get_version +local is_uuid + +local Service = {} +Service.__index = Service + +local function new_service(service_type) + local instance = { + privileges = {}, + service_type = service_type, + } + setmetatable(instance, Service) + return instance +end + +function Service:add_privilege(privilege, expire) + self.privileges[privilege] = expire +end + +function Service:get_service_type() + return self.service_type +end + +function Service:pack_privileges() + return utils.pack_map_uint32(self.privileges) +end + +function Service:pack_type() + return utils.pack_uint16(self.service_type) +end + +function Service:pack() + return self:pack_type() .. self:pack_privileges() +end + +function Service:unpack(data) + self.privileges, data = utils.unpack_map_uint32(data) + return data +end + +local ServiceRtc = {} +ServiceRtc.__index = ServiceRtc + +local function new_service_rtc(channel_name, uid) + local instance = { + service = new_service(SERVICE_TYPE_RTC), + channel_name = channel_name, + uid = uid, + } + setmetatable(instance, ServiceRtc) + return instance +end + +function ServiceRtc:pack() + return self.service:pack() .. utils.pack_string(self.channel_name) .. utils.pack_string(self.uid) +end + +function ServiceRtc:unpack(data) + data = self.service:unpack(data) + self.channel_name, data = utils.unpack_string(data) + self.uid, data = utils.unpack_string(data) + return data +end + +local ServiceRtm = {} +ServiceRtm.__index = ServiceRtm + +local function new_service_rtm(user_id) + local instance = { + service = new_service(SERVICE_TYPE_RTM), + user_id = user_id, + } + setmetatable(instance, ServiceRtm) + return instance +end + +function ServiceRtm:pack() + return self.service:pack() .. utils.pack_string(self.user_id) +end + +function ServiceRtm:unpack(data) + data = self.service:unpack(data) + self.user_id, data = utils.unpack_string(data) + return data +end + +local ServiceFpa = {} +ServiceFpa.__index = ServiceFpa + +local function new_service_fpa() + local instance = { + service = new_service(SERVICE_TYPE_FPA), + } + setmetatable(instance, ServiceFpa) + return instance +end + +function ServiceFpa:pack() + return self.service:pack() +end + +function ServiceFpa:unpack(data) + data = self.service:unpack(data) + return data +end + +local ServiceChat = {} +ServiceChat.__index = ServiceChat + +local function new_service_chat(user_id) + local instance = { + service = new_service(SERVICE_TYPE_CHAT), + user_id = user_id, + } + setmetatable(instance, ServiceChat) + return instance +end + +function ServiceChat:pack() + return self.service:pack() .. utils.pack_string(self.user_id) +end + +function ServiceChat:unpack(data) + data = self.service:unpack(data) + self.user_id, data = utils.unpack_string(data) + return data +end + +local ServiceApaas = {} +ServiceApaas.__index = ServiceApaas + +local function new_service_apaas(room_uuid, user_uuid, role) + local instance = { + service = new_service(SERVICE_TYPE_APAAS), + room_uuid = room_uuid, + user_uuid = user_uuid, + role = role, + } + setmetatable(instance, ServiceApaas) + return instance +end + +function ServiceApaas:pack() + return self.service:pack() .. + utils.pack_string(self.room_uuid) .. utils.pack_string(self.user_uuid) .. utils.pack_int16(self.role) +end + +function ServiceApaas:unpack(data) + data = self.service:unpack(data) + self.room_uuid, data = utils.unpack_string(data) + self.user_uuid, data = utils.unpack_string(data) + self.role, data = utils.unpack_int16(data) + return data +end + +local AccessToken = {} +AccessToken.__index = AccessToken + +local function new_access_token(app_id, app_cert, expire) + local issue_ts = os.time() + local salt = utils.get_rand(1, 99999999) + + local instance = { + app_cert = app_cert, + app_id = app_id, + expire = expire, + issue_ts = issue_ts, + salt = salt, + services = {}, + } + setmetatable(instance, AccessToken) + return instance +end + +local function create_access_token() + return new_access_token("", "", 900) +end + +function AccessToken:add_service(service) + self.services[service.service:get_service_type()] = service +end + +function AccessToken:build() + if not is_uuid(self.app_id) or not is_uuid(self.app_cert) then + error("check appId or appCertificate") + end + + local data = utils.pack_string(self.app_id) .. + utils.pack_uint32(self.issue_ts) .. + utils.pack_uint32(self.expire) .. + utils.pack_uint32(self.salt) .. utils.pack_uint16(utils.count_table_elements(self.services)) + + local sign = self:get_sign() + + local service_types = {} + for service_type in pairs(self.services) do + table.insert(service_types, service_type) + end + table.sort(service_types) + + for _, service_type in ipairs(service_types) do + local service = self.services[service_type] + if service then + data = data .. service:pack() + end + end + + local signature = utils.hmac_sha256(sign, data) + + local res = get_version() .. utils.base64_encode_str(utils.compress_zlib(utils.pack_string(signature) .. data)) + return res +end + +function AccessToken:parse(token) + local version = token:sub(1, VERSION_LENGTH) + if version ~= get_version() then + return false + end + + local decode_byte = utils.base64_decode_str(token:sub(VERSION_LENGTH + 1)) + local buffer = utils.decompress_zlib(decode_byte) + + local signature + signature, buffer = utils.unpack_string(buffer) + + self.app_id, buffer = utils.unpack_string(buffer) + self.issue_ts, buffer = utils.unpack_uint32(buffer) + self.expire, buffer = utils.unpack_uint32(buffer) + self.salt, buffer = utils.unpack_uint32(buffer) + + local service_count + local service_type + service_count, buffer = utils.unpack_uint16(buffer) + for _ = 1, service_count do + service_type, buffer = utils.unpack_uint16(buffer) + local service = self:new_service(service_type) + buffer = service:unpack(buffer) + self.services[service_type] = service + end + + return true +end + +function AccessToken:get_sign() + local h_issue_ts = utils.hmac_sha256(utils.pack_uint32(self.issue_ts), self.app_cert) + local h_salt = utils.hmac_sha256(utils.pack_uint32(self.salt), h_issue_ts) + + return h_salt +end + +function AccessToken:new_service(service_type) + if service_type == SERVICE_TYPE_RTC then + return new_service_rtc("", "") + elseif service_type == SERVICE_TYPE_RTM then + return new_service_rtm("") + elseif service_type == SERVICE_TYPE_FPA then + return new_service_fpa() + elseif service_type == SERVICE_TYPE_CHAT then + return new_service_chat("") + elseif service_type == SERVICE_TYPE_APAAS then + return new_service_apaas("", "", -1) + else + error("new service failed: unknown service type " .. service_type) + end +end + +local function get_uid_str(uid) + if uid == 0 then + return "" + end + return tostring(uid) +end + +get_version = function() + return VERSION +end + +is_uuid = function(s) + return #s == 32 and s:match("^[%x]+$") ~= nil +end + +return { + AccessToken = AccessToken, + create_access_token = create_access_token, + get_uid_str = get_uid_str, + get_version = get_version, + is_uuid = is_uuid, + new_access_token = new_access_token, + new_service = new_service, + new_service_rtc = new_service_rtc, + new_service_rtm = new_service_rtm, + new_service_fpa = new_service_fpa, + new_service_chat = new_service_chat, + new_service_apaas = new_service_apaas, + PRIVILEGE_JOIN_CHANNEL = PRIVILEGE_JOIN_CHANNEL, + PRIVILEGE_PUBLISH_AUDIO_STREAM = PRIVILEGE_PUBLISH_AUDIO_STREAM, + PRIVILEGE_PUBLISH_VIDEO_STREAM = PRIVILEGE_PUBLISH_VIDEO_STREAM, + PRIVILEGE_PUBLISH_DATA_STREAM = PRIVILEGE_PUBLISH_DATA_STREAM, + PRIVILEGE_LOGIN = PRIVILEGE_LOGIN, + PRIVILEGE_CHAT_USER = PRIVILEGE_CHAT_USER, + PRIVILEGE_CHAT_APP = PRIVILEGE_CHAT_APP, + PRIVILEGE_APAAS_ROOM_USER = PRIVILEGE_APAAS_ROOM_USER, + PRIVILEGE_APAAS_USER = PRIVILEGE_APAAS_USER, + PRIVILEGE_APAAS_APP = PRIVILEGE_APAAS_APP, + SERVICE_TYPE_RTC = SERVICE_TYPE_RTC, + SERVICE_TYPE_RTM = SERVICE_TYPE_RTM, + SERVICE_TYPE_FPA = SERVICE_TYPE_FPA, + SERVICE_TYPE_CHAT = SERVICE_TYPE_CHAT, + SERVICE_TYPE_APAAS = SERVICE_TYPE_APAAS, + ServiceRtc = ServiceRtc, + ServiceRtm = ServiceRtm, + ServiceFpa = ServiceFpa, + ServiceChat = ServiceChat, + ServiceApaas = ServiceApaas, +} diff --git a/DynamicKey/AgoraDynamicKey/lua/src/apaas_token_builder.lua b/DynamicKey/AgoraDynamicKey/lua/src/apaas_token_builder.lua new file mode 100644 index 00000000..d769796d --- /dev/null +++ b/DynamicKey/AgoraDynamicKey/lua/src/apaas_token_builder.lua @@ -0,0 +1,69 @@ +local access_token = require("agora_token.access_token") +local utils = require("agora_token.utils") + +-- Build room user token. +-- +-- app_id: The App ID issued to you by Agora. Apply for a new App ID from Agora Dashboard if it is missing from your kit. See Get an App ID. +-- app_certificate: Certificate of the application that you registered in the Agora Dashboard. See Get an App Certificate. +-- room_uuid: The room's id, must be unique. +-- user_uuid: The user's id, must be unique. +-- role: The user's role. +-- expire: represented by the number of seconds elapsed since now. If, for example, you want to access the Agora Service within 10 minutes after the token is generated, set expire as 600(seconds). +-- return The room user token. +local function build_room_user_token(app_id, app_certificate, room_uuid, user_uuid, role, expire) + local token = access_token.new_access_token(app_id, app_certificate, expire) + + local chat_user_id = utils.md5_hash(user_uuid) + local service_apaas = access_token.new_service_apaas(room_uuid, user_uuid, role) + service_apaas.service:add_privilege(access_token.PRIVILEGE_APAAS_ROOM_USER, expire) + token:add_service(service_apaas) + + local service_rtm = access_token.new_service_rtm(user_uuid) + service_rtm.service:add_privilege(access_token.PRIVILEGE_LOGIN, expire) + token:add_service(service_rtm) + + local service_chat = access_token.new_service_chat(chat_user_id) + service_chat.service:add_privilege(access_token.PRIVILEGE_CHAT_USER, expire) + token:add_service(service_chat) + + return token:build() +end + +-- Build user token. +-- +-- app_id: The App ID issued to you by Agora. Apply for a new App ID from Agora Dashboard if it is missing from your kit. See Get an App ID. +-- app_certificate: Certificate of the application that you registered in the Agora Dashboard. See Get an App Certificate. +-- user_uuid: The user's id, must be unique. +-- expire: represented by the number of seconds elapsed since now. If, for example, you want to access the Agora Service within 10 minutes after the token is generated, set expire as 600(seconds). +-- return The user token. +local function build_user_token(app_id, app_certificate, user_uuid, expire) + local token = access_token.new_access_token(app_id, app_certificate, expire) + + local service_apaas = access_token.new_service_apaas("", user_uuid, -1) + service_apaas.service:add_privilege(access_token.PRIVILEGE_APAAS_USER, expire) + token:add_service(service_apaas) + + return token:build() +end + +-- Build app token. +-- +-- app_id: The App ID issued to you by Agora. Apply for a new App ID from Agora Dashboard if it is missing from your kit. See Get an App ID. +-- app_certificate: Certificate of the application that you registered in the Agora Dashboard. See Get an App Certificate. +-- expire: represented by the number of seconds elapsed since now. If, for example, you want to access the Agora Service within 10 minutes after the token is generated, set expire as 600(seconds). +-- return The app token. +local function build_app_token(app_id, app_certificate, expire) + local token = access_token.new_access_token(app_id, app_certificate, expire) + + local service_apaas = access_token.new_service_apaas("", "", -1) + service_apaas.service:add_privilege(access_token.PRIVILEGE_APAAS_APP, expire) + token:add_service(service_apaas) + + return token:build() +end + +return { + build_room_user_token = build_room_user_token, + build_user_token = build_user_token, + build_app_token = build_app_token, +} diff --git a/DynamicKey/AgoraDynamicKey/lua/src/chat_token_builder.lua b/DynamicKey/AgoraDynamicKey/lua/src/chat_token_builder.lua new file mode 100644 index 00000000..a8dc4d04 --- /dev/null +++ b/DynamicKey/AgoraDynamicKey/lua/src/chat_token_builder.lua @@ -0,0 +1,42 @@ +local access_token = require("agora_token.access_token") + +-- Build the chat user token. +-- +-- app_id: The App ID issued to you by Agora. Apply for a new App ID from +-- Agora Dashboard if it is missing from your kit. See Get an App ID. +-- app_certificate: Certificate of the application that you registered in +-- the Agora Dashboard. See Get an App Certificate. +-- user_uuid: The user's id, must be unique. +-- expire: represented by the number of seconds elapsed since now. If, for example, you want to access the Agora Service within 10 minutes after the token is generated, set expire as 600(seconds). +-- @return The Chat User token. +local function build_chat_user_token(app_id, app_certificate, user_uuid, expire) + local token = access_token.new_access_token(app_id, app_certificate, expire) + local service_chat = access_token.new_service_chat(user_uuid) + service_chat.service:add_privilege(access_token.PRIVILEGE_CHAT_USER, expire) + token:add_service(service_chat) + + return token:build() +end + +-- Build the chat app token. +-- +-- app_id: The App ID issued to you by Agora. Apply for a new App ID from +-- Agora Dashboard if it is missing from your kit. See Get an App ID. +-- app_certificate: Certificate of the application that you registered in +-- the Agora Dashboard. See Get an App Certificate. +-- expire: represented by the number of seconds elapsed since now. If, for example, you want to access the Agora Service within 10 minutes after the token is generated, set expire as 600(seconds). +-- @return The Chat App token. +local function build_chat_app_token(app_id, app_certificate, expire) + local token = access_token.new_access_token(app_id, app_certificate, expire) + + local service_chat = access_token.new_service_chat("") + service_chat.service:add_privilege(access_token.PRIVILEGE_CHAT_APP, expire) + token:add_service(service_chat) + + return token:build() +end + +return { + build_chat_user_token = build_chat_user_token, + build_chat_app_token = build_chat_app_token, +} diff --git a/DynamicKey/AgoraDynamicKey/lua/src/education_token_builder.lua b/DynamicKey/AgoraDynamicKey/lua/src/education_token_builder.lua new file mode 100644 index 00000000..d769796d --- /dev/null +++ b/DynamicKey/AgoraDynamicKey/lua/src/education_token_builder.lua @@ -0,0 +1,69 @@ +local access_token = require("agora_token.access_token") +local utils = require("agora_token.utils") + +-- Build room user token. +-- +-- app_id: The App ID issued to you by Agora. Apply for a new App ID from Agora Dashboard if it is missing from your kit. See Get an App ID. +-- app_certificate: Certificate of the application that you registered in the Agora Dashboard. See Get an App Certificate. +-- room_uuid: The room's id, must be unique. +-- user_uuid: The user's id, must be unique. +-- role: The user's role. +-- expire: represented by the number of seconds elapsed since now. If, for example, you want to access the Agora Service within 10 minutes after the token is generated, set expire as 600(seconds). +-- return The room user token. +local function build_room_user_token(app_id, app_certificate, room_uuid, user_uuid, role, expire) + local token = access_token.new_access_token(app_id, app_certificate, expire) + + local chat_user_id = utils.md5_hash(user_uuid) + local service_apaas = access_token.new_service_apaas(room_uuid, user_uuid, role) + service_apaas.service:add_privilege(access_token.PRIVILEGE_APAAS_ROOM_USER, expire) + token:add_service(service_apaas) + + local service_rtm = access_token.new_service_rtm(user_uuid) + service_rtm.service:add_privilege(access_token.PRIVILEGE_LOGIN, expire) + token:add_service(service_rtm) + + local service_chat = access_token.new_service_chat(chat_user_id) + service_chat.service:add_privilege(access_token.PRIVILEGE_CHAT_USER, expire) + token:add_service(service_chat) + + return token:build() +end + +-- Build user token. +-- +-- app_id: The App ID issued to you by Agora. Apply for a new App ID from Agora Dashboard if it is missing from your kit. See Get an App ID. +-- app_certificate: Certificate of the application that you registered in the Agora Dashboard. See Get an App Certificate. +-- user_uuid: The user's id, must be unique. +-- expire: represented by the number of seconds elapsed since now. If, for example, you want to access the Agora Service within 10 minutes after the token is generated, set expire as 600(seconds). +-- return The user token. +local function build_user_token(app_id, app_certificate, user_uuid, expire) + local token = access_token.new_access_token(app_id, app_certificate, expire) + + local service_apaas = access_token.new_service_apaas("", user_uuid, -1) + service_apaas.service:add_privilege(access_token.PRIVILEGE_APAAS_USER, expire) + token:add_service(service_apaas) + + return token:build() +end + +-- Build app token. +-- +-- app_id: The App ID issued to you by Agora. Apply for a new App ID from Agora Dashboard if it is missing from your kit. See Get an App ID. +-- app_certificate: Certificate of the application that you registered in the Agora Dashboard. See Get an App Certificate. +-- expire: represented by the number of seconds elapsed since now. If, for example, you want to access the Agora Service within 10 minutes after the token is generated, set expire as 600(seconds). +-- return The app token. +local function build_app_token(app_id, app_certificate, expire) + local token = access_token.new_access_token(app_id, app_certificate, expire) + + local service_apaas = access_token.new_service_apaas("", "", -1) + service_apaas.service:add_privilege(access_token.PRIVILEGE_APAAS_APP, expire) + token:add_service(service_apaas) + + return token:build() +end + +return { + build_room_user_token = build_room_user_token, + build_user_token = build_user_token, + build_app_token = build_app_token, +} diff --git a/DynamicKey/AgoraDynamicKey/lua/src/fpa_token_builder.lua b/DynamicKey/AgoraDynamicKey/lua/src/fpa_token_builder.lua new file mode 100644 index 00000000..0934f343 --- /dev/null +++ b/DynamicKey/AgoraDynamicKey/lua/src/fpa_token_builder.lua @@ -0,0 +1,22 @@ +local access_token = require("agora_token.access_token") + +-- Build the FPA token. +-- +-- app_id: The App ID issued to you by Agora. Apply for a new App ID from +-- Agora Dashboard if it is missing from your kit. See Get an App ID. +-- app_certificate: Certificate of the application that you registered in +-- the Agora Dashboard. See Get an App Certificate. +-- return The FPA token. +local function build_token(app_id, app_certificate) + local token = access_token.new_access_token(app_id, app_certificate, 24 * 3600) + + local service_fpa = access_token.new_service_fpa() + service_fpa.service:add_privilege(access_token.PRIVILEGE_LOGIN, 0) + token:add_service(service_fpa) + + return token:build() +end + +return { + build_token = build_token, +} diff --git a/DynamicKey/AgoraDynamicKey/lua/src/rtc_token_builder.lua b/DynamicKey/AgoraDynamicKey/lua/src/rtc_token_builder.lua new file mode 100644 index 00000000..606f8efd --- /dev/null +++ b/DynamicKey/AgoraDynamicKey/lua/src/rtc_token_builder.lua @@ -0,0 +1,197 @@ +local access_token = require("agora_token.access_token") + +-- RECOMMENDED. Use this role for a voice/video call or a live broadcast, if +-- your scenario does not require authentication for +-- [Co-host](https://docs.agora.io/en/video-calling/get-started/authentication-workflow?#co-host-token-authentication). +local ROLE_PUBLISHER = 1 + +-- Only use this role if your scenario requires authentication for +-- [Co-host](https://docs.agora.io/en/video-calling/get-started/authentication-workflow?#co-host-token-authentication). +-- @note In order for this role to take effect, please contact our support team +-- to enable authentication for Hosting-in for you. Otherwise, Role_Subscriber +-- still has the same privileges as Role_Publisher. +local ROLE_SUBSCRIBER = 2 + +local build_token_with_user_account +local build_token_with_user_account_and_privilege + +-- Build the RTC token with uid. +-- +-- app_id: The App ID issued to you by Agora. Apply for a new App ID from +-- Agora Dashboard if it is missing from your kit. See Get an App ID. +-- app_certificate: Certificate of the application that you registered in +-- the Agora Dashboard. See Get an App Certificate. +-- channel_name: Unique channel name for the AgoraRTC session in the string format +-- uid: User ID. A 32-bit unsigned integer with a value ranging from 1 to (2^32-1). uid must be unique. +-- role: RolePublisher: A broadcaster/host in a live-broadcast profile. +-- RoleSubscriber: An audience(default) in a live-broadcast profile. +-- token_expire: represented by the number of seconds elapsed since now. If, for example, +-- you want to access the Agora Service within 10 minutes after the token is generated, +-- set token_expire as 600(seconds). +-- privilege_expire: represented by the number of seconds elapsed since now. If, for example, +-- you want to enable your privilege for 10 minutes, set privilege_expire as 600(seconds). +-- return The RTC token. +local function build_token_with_uid(app_id, app_certificate, channel_name, uid, role, token_expire, privilege_expire) + return build_token_with_user_account( + app_id, + app_certificate, + channel_name, + access_token.get_uid_str(uid), + role, + token_expire, + privilege_expire + ) +end + +-- Build the RTC token with account. +-- +-- app_id: The App ID issued to you by Agora. Apply for a new App ID from +-- Agora Dashboard if it is missing from your kit. See Get an App ID. +-- app_certificate: Certificate of the application that you registered in +-- the Agora Dashboard. See Get an App Certificate. +-- channel_name: Unique channel name for the AgoraRTC session in the string format +-- account: The user's account, max length is 255 Bytes. +-- role: RolePublisher: A broadcaster/host in a live-broadcast profile. +-- RoleSubscriber: An audience(default) in a live-broadcast profile. +-- token_expire: represented by the number of seconds elapsed since now. If, for example, +-- you want to access the Agora Service within 10 minutes after the token is generated, +-- set token_expire as 600(seconds). +-- privilege_expire: represented by the number of seconds elapsed since now. If, for example, +-- you want to enable your privilege for 10 minutes, set privilege_expire as 600(seconds). +-- return The RTC token. +build_token_with_user_account = function(app_id, app_certificate, channel_name, account, role, token_expire, + privilege_expire) + local token = access_token.new_access_token(app_id, app_certificate, token_expire) + + local service_rtc = access_token.new_service_rtc(channel_name, account) + service_rtc.service:add_privilege(access_token.PRIVILEGE_JOIN_CHANNEL, privilege_expire) + if role == ROLE_PUBLISHER then + service_rtc.service:add_privilege(access_token.PRIVILEGE_PUBLISH_AUDIO_STREAM, privilege_expire) + service_rtc.service:add_privilege(access_token.PRIVILEGE_PUBLISH_VIDEO_STREAM, privilege_expire) + service_rtc.service:add_privilege(access_token.PRIVILEGE_PUBLISH_DATA_STREAM, privilege_expire) + end + token:add_service(service_rtc) + + return token:build() +end + +-- Generates an RTC token with the specified privilege. +-- +-- This method supports generating a token with the following privileges: +-- - Joining an RTC channel. +-- - Publishing audio in an RTC channel. +-- - Publishing video in an RTC channel. +-- - Publishing data streams in an RTC channel. +-- +-- The privileges for publishing audio, video, and data streams in an RTC channel apply only if you have +-- enabled co-host authentication. +-- +-- A user can have multiple privileges. Each privilege is valid for a maximum of 24 hours. +-- The SDK triggers the onTokenPrivilegeWillExpire and onRequestToken callbacks when the token is about to expire +-- or has expired. The callbacks do not report the specific privilege affected, and you need to maintain +-- the respective timestamp for each privilege in your app logic. After receiving the callback, you need +-- to generate a new token, and then call renewToken to pass the new token to the SDK, or call joinChannel to re-join +-- the channel. +-- +-- Agora recommends setting a reasonable timestamp for each privilege according to your scenario. +-- Suppose the expiration timestamp for joining the channel is set earlier than that for publishing audio. +-- When the token for joining the channel expires, the user is immediately kicked off the RTC channel +-- and cannot publish any audio stream, even though the timestamp for publishing audio has not expired. +local function build_token_with_uid_and_privilege(app_id, app_certificate, channel_name, uid, token_expire, + join_channel_privilege_expire, pub_audio_privilege_expire, + pub_video_privilege_expire, pub_data_stream_privilege_expire) + return build_token_with_user_account_and_privilege( + app_id, + app_certificate, + channel_name, + access_token.get_uid_str(uid), + token_expire, + join_channel_privilege_expire, + pub_audio_privilege_expire, + pub_video_privilege_expire, + pub_data_stream_privilege_expire + ) +end + +-- Generates an RTC token with the specified privilege. +-- +-- This method supports generating a token with the following privileges: +-- - Joining an RTC channel. +-- - Publishing audio in an RTC channel. +-- - Publishing video in an RTC channel. +-- - Publishing data streams in an RTC channel. +-- +-- The privileges for publishing audio, video, and data streams in an RTC channel apply only if you have +-- enabled co-host authentication. +-- +-- A user can have multiple privileges. Each privilege is valid for a maximum of 24 hours. +-- The SDK triggers the onTokenPrivilegeWillExpire and onRequestToken callbacks when the token is about to expire +-- or has expired. The callbacks do not report the specific privilege affected, and you need to maintain +-- the respective timestamp for each privilege in your app logic. After receiving the callback, you need +-- to generate a new token, and then call renewToken to pass the new token to the SDK, or call joinChannel to re-join +-- the channel. +-- +-- @note +-- Agora recommends setting a reasonable timestamp for each privilege according to your scenario. +-- Suppose the expiration timestamp for joining the channel is set earlier than that for publishing audio. +-- When the token for joining the channel expires, the user is immediately kicked off the RTC channel +-- and cannot publish any audio stream, even though the timestamp for publishing audio has not expired. +build_token_with_user_account_and_privilege = function(app_id, app_certificate, channel_name, account, token_expire, + join_channel_privilege_expire, pub_audio_privilege_expire, + pub_video_privilege_expire, pub_data_stream_privilege_expire) + local token = access_token.new_access_token(app_id, app_certificate, token_expire) + + local service_rtc = access_token.new_service_rtc(channel_name, account) + service_rtc.service:add_privilege(access_token.PRIVILEGE_JOIN_CHANNEL, join_channel_privilege_expire) + service_rtc.service:add_privilege(access_token.PRIVILEGE_PUBLISH_AUDIO_STREAM, pub_audio_privilege_expire) + service_rtc.service:add_privilege(access_token.PRIVILEGE_PUBLISH_VIDEO_STREAM, pub_video_privilege_expire) + service_rtc.service:add_privilege(access_token.PRIVILEGE_PUBLISH_DATA_STREAM, pub_data_stream_privilege_expire) + token:add_service(service_rtc) + + return token:build() +end + +-- Build the RTC and RTM token with account. +-- +-- app_id: The App ID issued to you by Agora. Apply for a new App ID from +-- Agora Dashboard if it is missing from your kit. See Get an App ID. +-- app_certificate: Certificate of the application that you registered in +-- the Agora Dashboard. See Get an App Certificate. +-- channel_name: Unique channel name for the AgoraRTC session in the string format +-- account: The user's account, max length is 255 Bytes. +-- role: RolePublisher: A broadcaster/host in a live-broadcast profile. +-- RoleSubscriber: An audience(default) in a live-broadcast profile. +-- token_expire: represented by the number of seconds elapsed since now. If, for example, +-- you want to access the Agora Service within 10 minutes after the token is generated, +-- set token_expire as 600(seconds). +-- privilege_expire: represented by the number of seconds elapsed since now. If, for example, +-- you want to enable your privilege for 10 minutes, set privilege_expire as 600(seconds). +-- return The RTC and RTM token. +local function build_token_with_rtm(app_id, app_certificate, channel_name, account, role, token_expire, privilege_expire) + local token = access_token.new_access_token(app_id, app_certificate, token_expire) + + local service_rtc = access_token.new_service_rtc(channel_name, account) + service_rtc.service:add_privilege(access_token.PRIVILEGE_JOIN_CHANNEL, privilege_expire) + if role == ROLE_PUBLISHER then + service_rtc.service:add_privilege(access_token.PRIVILEGE_PUBLISH_AUDIO_STREAM, privilege_expire) + service_rtc.service:add_privilege(access_token.PRIVILEGE_PUBLISH_VIDEO_STREAM, privilege_expire) + service_rtc.service:add_privilege(access_token.PRIVILEGE_PUBLISH_DATA_STREAM, privilege_expire) + end + token:add_service(service_rtc) + + local service_rtm = access_token.new_service_rtm(account) + service_rtm.service:add_privilege(access_token.PRIVILEGE_LOGIN, token_expire) + token:add_service(service_rtm) + + return token:build() +end + +return { + build_token_with_uid = build_token_with_uid, + build_token_with_user_account = build_token_with_user_account, + build_token_with_uid_and_privilege = build_token_with_uid_and_privilege, + build_token_with_user_account_and_privilege = build_token_with_user_account_and_privilege, + build_token_with_rtm = build_token_with_rtm, + ROLE_PUBLISHER = ROLE_PUBLISHER, + ROLE_SUBSCRIBER = ROLE_SUBSCRIBER, +} diff --git a/DynamicKey/AgoraDynamicKey/lua/src/rtm_token_builder.lua b/DynamicKey/AgoraDynamicKey/lua/src/rtm_token_builder.lua new file mode 100644 index 00000000..44bf9d25 --- /dev/null +++ b/DynamicKey/AgoraDynamicKey/lua/src/rtm_token_builder.lua @@ -0,0 +1,22 @@ +local access_token = require("agora_token.access_token") + +-- Build the RTM token. +-- +-- app_id: The App ID issued to you by Agora. Apply for a new App ID from Agora Dashboard if it is missing from your kit. See Get an App ID. +-- app_certificate: Certificate of the application that you registered in the Agora Dashboard. See Get an App Certificate. +-- user_id: The user's account, max length is 64 Bytes. +-- expire: represented by the number of seconds elapsed since now. If, for example, you want to access the Agora Service within 10 minutes after the token is generated, set expire as 600(seconds). +-- return The RTM token. +local function build_token(app_id, app_certificate, user_id, expire) + local token = access_token.new_access_token(app_id, app_certificate, expire) + + local service_rtm = access_token.new_service_rtm(user_id) + service_rtm.service:add_privilege(access_token.PRIVILEGE_LOGIN, expire) + token:add_service(service_rtm) + + return token:build() +end + +return { + build_token = build_token, +} diff --git a/DynamicKey/AgoraDynamicKey/lua/src/utils.lua b/DynamicKey/AgoraDynamicKey/lua/src/utils.lua new file mode 100644 index 00000000..ea44393a --- /dev/null +++ b/DynamicKey/AgoraDynamicKey/lua/src/utils.lua @@ -0,0 +1,173 @@ +local base64 = require("base64") +local hmac = require("openssl.hmac") +local md5 = require("md5") +local zlib = require("zlib") + +local function base64_encode_str(data) + return base64.encode(data) +end + +local function base64_decode_str(data) + return base64.decode(data) +end + +local function compress_zlib(data) + local deflate = zlib.deflate() + local compressed_data, eof, bytes_in, bytes_out = deflate(data, "finish") + return compressed_data +end + +local function count_table_elements(tbl) + local count = 0 + for _ in pairs(tbl) do + count = count + 1 + end + return count +end + +local function decompress_zlib(data) + local inflate = zlib.inflate() + local decompressed_data, eof, bytes_in, bytes_out = inflate(data, "finish") + return decompressed_data +end + +local function format_map(map) + local result = {} + for k, v in pairs(map) do + table.insert(result, string.format("%s=%s", k, v)) + end + return table.concat(result, ", ") +end + +local function get_rand(min, max) + if max <= min then + return min + end + + math.randomseed(os.time()) + + return math.random(min, max) +end + +local function hmac_sha256(key, data) + local hmac_sha256 = hmac.new(key, "sha256") + local digest = hmac_sha256:final(data) + + return digest +end + +local function md5_hash(data) + return md5.sumhexa(data) +end + +local function print_table(t, indent) + indent = indent or "" + + for key, value in pairs(t) do + io.write(indent .. tostring(key) .. ": ") + + if type(value) == "table" then + print() + print_table(value, indent .. " ") + else + print(tostring(value)) + end + end +end + +local function to_hex(data) + return (data:gsub('.', function(c) + return string.format('%02x', string.byte(c)) + end)) +end + +local function pack_int16(x) + return string.pack("