Skip to content

Commit

Permalink
Merge pull request #43 from AgoraIO-Community/public-methods
Browse files Browse the repository at this point in the history
Public methods
  • Loading branch information
maxxfrazer authored Aug 21, 2023
2 parents 393eb4a + b3298cc commit a04f110
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 48 deletions.
1 change: 1 addition & 0 deletions service/endpoints_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func TestGetTokenValidAndInvalid(t *testing.T) {
{"/getToken", http.StatusBadRequest, []byte(`{"tokenType": "invalid_type", "channel": "channel789", "role": "publisher", "uid": "user123", "expire": 3600}`)},
{"/getToken", http.StatusBadRequest, []byte(`{"tokenType": "rtc", "role": "publisher", "uid": "user123", "expire": 3600}`)},
{"/getToken", http.StatusBadRequest, []byte(`{"tokenType": "rtm", "expire": 1800}`)},
{"/getToken", http.StatusBadRequest, []byte(``)},
{"/getToken", http.StatusOK, []byte(`{"tokenType": "chat"}`)},
{"/getToken", http.StatusOK, []byte(`{"tokenType": "chat", "uid": "user123"}`)},
}
Expand Down
103 changes: 66 additions & 37 deletions service/http_handlers_POST.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package service

import (
"encoding/json"
"errors"
"net/http"
"strconv"
Expand All @@ -11,15 +12,50 @@ import (
"github.com/gin-gonic/gin"
)

// TokenRequest is a struct representing the JSON payload structure for token generation requests.
// It contains fields necessary for generating different types of tokens (RTC, RTM, or chat) based on the "TokenType".
// The "Channel", "RtcRole", "Uid", and "ExpirationSeconds" fields are used for specific token types.
//
// TokenType options: "rtc" for RTC token, "rtm" for RTM token, and "chat" for chat token.
type TokenRequest struct {
TokenType string `json:"tokenType"` // The token type: "rtc", "rtm", or "chat"
Channel string `json:"channel,omitempty"` // The channel name (used for RTC and RTM tokens)
RtcRole string `json:"role,omitempty"` // The role of the user for RTC tokens (publisher or subscriber)
Uid string `json:"uid,omitempty"` // The user ID or account (used for RTC, RTM, and some chat tokens)
ExpirationSeconds int `json:"expire,omitempty"` // The token expiration time in seconds (used for all token types)
}

// getToken is a helper function that acts as a proxy to the GetToken method.
// It forwards the HTTP response writer and request from the provided *gin.Context
// to the GetToken method for token generation and response sending.
//
// Parameters:
// - c: *gin.Context - The Gin context representing the HTTP request and response.
//
// Behavior:
// - Forwards the HTTP response writer and request to the GetToken method.
//
// Notes:
// - This function acts as an intermediary to invoke the GetToken method.
// - It allows token generation and response sending through a common proxy function.
//
// Example usage:
//
// router.GET("/getToken", service.getToken)
func (s *Service) getToken(c *gin.Context) {
s.GetToken(c.Writer, c.Request)
}

// getToken handles the HTTP request to generate a token based on the provided tokenType.
// It checks the tokenType from the query parameters and calls the appropriate token generation method.
// The generated token is sent as a JSON response to the client.
//
// Parameters:
// - c: *gin.Context - The Gin context representing the HTTP request and response.
// - w: http.ResponseWriter - The HTTP response writer to send the response to the client.
// - r: *http.Request - The HTTP request received from the client.
//
// Behavior:
// 1. Retrieves the tokenType from the query parameters, defaulting to "rtc" if not provided.
// 1. Retrieves the tokenType from the query parameters. Error if invalid entry or not provided.
// 2. Uses a switch statement to handle different tokenType cases:
// - "rtm": Calls the RtmToken method to generate the RTM token and sends it as a JSON response.
// - "chat": Calls the ChatToken method to generate the chat token and sends it as a JSON response.
Expand All @@ -31,12 +67,13 @@ import (
//
// Example usage:
//
// router.GET("/getToken", service.getToken)
func (s *Service) getToken(c *gin.Context) {
// Parse the request body into a TokenRequest struct
// router.GET("/getToken", service.GetToken)
func (s *Service) GetToken(w http.ResponseWriter, r *http.Request) {
var tokenReq TokenRequest
if err := c.ShouldBindJSON(&tokenReq); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
// Parse the request body into a TokenRequest struct
err := json.NewDecoder(r.Body).Decode(&tokenReq)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

Expand All @@ -45,38 +82,30 @@ func (s *Service) getToken(c *gin.Context) {

switch tokenReq.TokenType {
case "rtc":
token, tokenErr = s.genRtcToken(tokenReq)
token, tokenErr = s.GenRtcToken(tokenReq)
case "rtm":
token, tokenErr = s.genRtmToken(tokenReq)
token, tokenErr = s.GenRtmToken(tokenReq)
case "chat":
token, tokenErr = s.genChatToken(tokenReq)
token, tokenErr = s.GenChatToken(tokenReq)
default:
c.JSON(http.StatusBadRequest, gin.H{"error": "Unsupported tokenType"})
http.Error(w, "Unsupported tokenType", http.StatusBadRequest)
return
}
if tokenErr != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": tokenErr.Error()})
http.Error(w, tokenErr.Error(), http.StatusBadRequest)
return
}
c.JSON(http.StatusOK, gin.H{
"token": token,
})
}

// TokenRequest is a struct representing the JSON payload structure for token generation requests.
// It contains fields necessary for generating different types of tokens (RTC, RTM, or chat) based on the "TokenType".
// The "Channel", "RtcRole", "Uid", and "ExpirationSeconds" fields are used for specific token types.
//
// TokenType options: "rtc" for RTC token, "rtm" for RTM token, and "chat" for chat token.
type TokenRequest struct {
TokenType string `json:"tokenType"` // The token type: "rtc", "rtm", or "chat"
Channel string `json:"channel,omitempty"` // The channel name (used for RTC and RTM tokens)
RtcRole string `json:"role,omitempty"` // The role of the user for RTC tokens (publisher or subscriber)
Uid string `json:"uid,omitempty"` // The user ID or account (used for RTC, RTM, and some chat tokens)
ExpirationSeconds int `json:"expire,omitempty"` // The token expiration time in seconds (used for all token types)
response := struct {
Token string `json:"token"`
}{Token: token}

w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(response)
}

// genRtcToken generates an RTC token based on the provided TokenRequest and returns it.
// GenRtcToken generates an RTC token based on the provided TokenRequest and returns it.
//
// Parameters:
// - tokenRequest: TokenRequest - The TokenRequest struct containing the required information for RTC token generation.
Expand Down Expand Up @@ -104,8 +133,8 @@ type TokenRequest struct {
// Role: "publisher",
// ExpirationSeconds: 3600,
// }
// token, err := service.genRtcToken(tokenReq)
func (s *Service) genRtcToken(tokenRequest TokenRequest) (string, error) {
// token, err := service.GenRtcToken(tokenReq)
func (s *Service) GenRtcToken(tokenRequest TokenRequest) (string, error) {
if tokenRequest.Channel == "" {
return "", errors.New("invalid: missing channel name")
}
Expand Down Expand Up @@ -138,7 +167,7 @@ func (s *Service) genRtcToken(tokenRequest TokenRequest) (string, error) {
)
}

// genRtmToken generates an RTM (Real-Time Messaging) token based on the provided TokenRequest and returns it.
// GenRtmToken generates an RTM (Real-Time Messaging) token based on the provided TokenRequest and returns it.
//
// Parameters:
// - tokenRequest: TokenRequest - The TokenRequest struct containing the required information for RTM token generation.
Expand All @@ -163,8 +192,8 @@ func (s *Service) genRtcToken(tokenRequest TokenRequest) (string, error) {
// Uid: "user123",
// ExpirationSeconds: 3600,
// }
// token, err := service.genRtmToken(tokenReq)
func (s *Service) genRtmToken(tokenRequest TokenRequest) (string, error) {
// token, err := service.GenRtmToken(tokenReq)
func (s *Service) GenRtmToken(tokenRequest TokenRequest) (string, error) {
if tokenRequest.Uid == "" {
return "", errors.New("invalid: missing user ID or account")
}
Expand All @@ -180,7 +209,7 @@ func (s *Service) genRtmToken(tokenRequest TokenRequest) (string, error) {
)
}

// genChatToken generates a chat token based on the provided TokenRequest and returns it.
// GenChatToken generates a chat token based on the provided TokenRequest and returns it.
//
// Parameters:
// - tokenRequest: TokenRequest - The TokenRequest struct containing the required information for chat token generation.
Expand All @@ -205,16 +234,16 @@ func (s *Service) genRtmToken(tokenRequest TokenRequest) (string, error) {
// TokenType: "chat",
// ExpirationSeconds: 3600,
// }
// token, err := service.genChatToken(tokenReq)
// token, err := service.GenChatToken(tokenReq)
//
// // Generate a chat user token
// tokenReq := TokenRequest{
// TokenType: "chat",
// Uid: "user123",
// ExpirationSeconds: 3600,
// }
// token, err := service.genChatToken(tokenReq)
func (s *Service) genChatToken(tokenRequest TokenRequest) (string, error) {
// token, err := service.GenChatToken(tokenReq)
func (s *Service) GenChatToken(tokenRequest TokenRequest) (string, error) {
if tokenRequest.ExpirationSeconds == 0 {
tokenRequest.ExpirationSeconds = 3600
}
Expand Down
22 changes: 11 additions & 11 deletions service/http_handlers_POST_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func CreateTestService(t *testing.T) *Service {
}
}

// TestGenRtcToken tests the genRtcToken function.
// TestGenRtcToken tests the GenRtcToken function.
func TestGenRtcToken(t *testing.T) {
service := CreateTestService(t)

Expand All @@ -31,7 +31,7 @@ func TestGenRtcToken(t *testing.T) {
ExpirationSeconds: 3600,
}

token, err := service.genRtcToken(tokenReq)
token, err := service.GenRtcToken(tokenReq)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
Expand All @@ -49,7 +49,7 @@ func TestGenRtcToken(t *testing.T) {
RtcRole: "subscriber",
}

_, err = service.genRtcToken(validWithoutExpiration)
_, err = service.GenRtcToken(validWithoutExpiration)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
Expand All @@ -61,7 +61,7 @@ func TestGenRtcToken(t *testing.T) {
ExpirationSeconds: 3600,
}

_, err = service.genRtcToken(invalidTokenReq)
_, err = service.GenRtcToken(invalidTokenReq)
if err == nil {
t.Error("Expected error, but got nil")
}
Expand All @@ -73,7 +73,7 @@ func TestGenRtcToken(t *testing.T) {
RtcRole: "subscriber",
}

_, err = service.genRtcToken(invalidTokenReq2)
_, err = service.GenRtcToken(invalidTokenReq2)
if err == nil {
t.Error("Expected error, but got nil")
}
Expand All @@ -90,7 +90,7 @@ func TestGenRtmToken(t *testing.T) {
ExpirationSeconds: 3600,
}

token, err := service.genRtmToken(tokenReq)
token, err := service.GenRtmToken(tokenReq)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
Expand All @@ -107,7 +107,7 @@ func TestGenRtmToken(t *testing.T) {
Channel: "test_channel",
}

token, err = service.genRtmToken(tokenChannelReq)
token, err = service.GenRtmToken(tokenChannelReq)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
Expand All @@ -123,7 +123,7 @@ func TestGenRtmToken(t *testing.T) {
ExpirationSeconds: 3600,
}

_, err = service.genRtmToken(invalidTokenReq)
_, err = service.GenRtmToken(invalidTokenReq)
if err == nil {
t.Error("Expected error, but got nil")
}
Expand All @@ -141,7 +141,7 @@ func TestGenChatToken(t *testing.T) {
ExpirationSeconds: 3600,
}

tokenApp, err := service.genChatToken(tokenReqApp)
tokenApp, err := service.GenChatToken(tokenReqApp)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
Expand All @@ -158,7 +158,7 @@ func TestGenChatToken(t *testing.T) {
ExpirationSeconds: 3600,
}

tokenUser, err := service.genChatToken(tokenReqUser)
tokenUser, err := service.GenChatToken(tokenReqUser)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
Expand All @@ -174,7 +174,7 @@ func TestGenChatToken(t *testing.T) {
Uid: "user123",
}

_, err = service.genChatToken(invalidTokenReq)
_, err = service.GenChatToken(invalidTokenReq)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
Expand Down

0 comments on commit a04f110

Please sign in to comment.