Skip to content

Commit

Permalink
implemented basic resource protection using jwt
Browse files Browse the repository at this point in the history
  • Loading branch information
Kirari04 committed Jan 1, 2024
1 parent f0ee49e commit 88c086c
Show file tree
Hide file tree
Showing 5 changed files with 963 additions and 863 deletions.
57 changes: 57 additions & 0 deletions auth/jwt_stream.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package auth

import (
"ch/kirari04/videocms/config"
"fmt"
"time"

"github.com/golang-jwt/jwt/v5"
)

type ClaimsStream struct {
UUID string `json:"uuid"`
jwt.RegisteredClaims
}

var jwtKeyStream []byte

func GenerateJWTStream(linkUuid string) (string, time.Time, error) {
jwtKeyStream = []byte(fmt.Sprint(config.ENV.JwtSecretKey, "-stream"))
// Declare the expiration time of the token
// here, we have kept it as 5 minutes
expirationTime := time.Now().Add(24 * time.Hour)
// Create the JWT claims, which includes the username and expiry time
claims := &ClaimsStream{
UUID: linkUuid,
RegisteredClaims: jwt.RegisteredClaims{
// In JWT, the expiry time is expressed as unix milliseconds
ExpiresAt: jwt.NewNumericDate(expirationTime),
},
}

// Declare the token with the algorithm used for signing, and the claims
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
// Create the JWT string
tokenString, err := token.SignedString(jwtKey)
if err != nil {
return "", time.Now(), err
}
return tokenString, expirationTime, nil
}

func VerifyJWTStream(tknStr string) (*jwt.Token, *ClaimsStream, error) {
jwtKeyStream = []byte(fmt.Sprint(config.ENV.JwtSecretKey, "-stream"))
claims := &ClaimsStream{}

// Parse the JWT string and store the result in `claims`.
// Note that we are passing the key in this method as well. This method will return an error
// if the token is invalid (if it has expired according to the expiry time we set on sign in),
// or if the signature does not matchas expire
tkn, err := jwt.ParseWithClaims(tknStr, claims, func(token *jwt.Token) (interface{}, error) {
return jwtKey, nil
})
if err != nil {
return nil, nil, err
}
return tkn, claims, nil
}
9 changes: 9 additions & 0 deletions controllers/PlayerController.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package controllers

import (
"ch/kirari04/videocms/auth"
"ch/kirari04/videocms/config"
"ch/kirari04/videocms/helpers"
"ch/kirari04/videocms/inits"
Expand Down Expand Up @@ -114,6 +115,13 @@ func PlayerController(c *fiber.Ctx) error {
}
rawWebhooks, _ := json.Marshal(jsonWebhooks)

// generate jwt token that allows the user to access the stream
tkn, _, err := auth.GenerateJWTStream(dbLink.UUID)
if err != nil {
log.Printf("Failed to generate jwt stream token: %v", err)
return c.SendStatus(fiber.StatusInternalServerError)
}

return c.Render("player", fiber.Map{
"Title": fmt.Sprintf("%s - %s", config.ENV.AppName, dbLink.Name),
"Description": fmt.Sprintf("Watch %s on %s", dbLink.Name, config.ENV.AppName),
Expand All @@ -128,5 +136,6 @@ func PlayerController(c *fiber.Ctx) error {
"UUID": requestValidation.UUID,
"PROJECTURL": config.ENV.Project,
"Folder": config.ENV.FolderVideoQualitysPub,
"JWT": tkn,
})
}
29 changes: 29 additions & 0 deletions middlewares/JwtStream.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package middlewares

import (
"ch/kirari04/videocms/auth"

"github.com/gofiber/fiber/v2"
)

func JwtStream(c *fiber.Ctx) error {
uuid := c.Params("UUID", "")
if uuid == "" {
return c.Status(fiber.StatusBadRequest).SendString("Missing UUID parameter")
}
tknStr := c.Cookies(uuid, "")
if uuid == "" {
return c.Status(fiber.StatusBadRequest).SendString("UUID parameter match issue")
}
token, claims, err := auth.VerifyJWTStream(tknStr)
if err != nil {
return c.Status(fiber.StatusForbidden).SendString("Broken JWT")
}
if !token.Valid {
return c.Status(fiber.StatusForbidden).SendString("Invalid JWT")
}
if claims.UUID != uuid {
return c.Status(fiber.StatusForbidden).SendString("Mismacht UUID")
}
return c.Next()
}
13 changes: 7 additions & 6 deletions routes/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"ch/kirari04/videocms/config"
"ch/kirari04/videocms/controllers"
"ch/kirari04/videocms/inits"
"ch/kirari04/videocms/middlewares"
)

func Web() {
Expand All @@ -12,10 +13,10 @@ func Web() {
inits.App.Get("/:UUID", controllers.PlayerController)

videoData := inits.App.Group(config.ENV.FolderVideoQualitysPub)
videoData.Get("/:UUID/stream/muted/master.m3u8", controllers.GetM3u8Data)
videoData.Get("/:UUID/image/thumb/:FILE", controllers.GetThumbnailData)
videoData.Get("/:UUID/:QUALITY/:FILE", controllers.GetVideoData)
videoData.Get("/:UUID/:SUBUUID/subtitle/:FILE", controllers.GetSubtitleData)
videoData.Get("/:UUID/:AUDIOUUID/audio/:FILE", controllers.GetAudioData)
videoData.Get("/:UUID/:AUDIOUUID/stream/master.m3u8", controllers.GetM3u8Data)
videoData.Get("/:UUID/stream/muted/master.m3u8", middlewares.JwtStream, controllers.GetM3u8Data)
videoData.Get("/:UUID/image/thumb/:FILE", middlewares.JwtStream, controllers.GetThumbnailData)
videoData.Get("/:UUID/:QUALITY/:FILE", middlewares.JwtStream, controllers.GetVideoData)
videoData.Get("/:UUID/:SUBUUID/subtitle/:FILE", middlewares.JwtStream, controllers.GetSubtitleData)
videoData.Get("/:UUID/:AUDIOUUID/audio/:FILE", middlewares.JwtStream, controllers.GetAudioData)
videoData.Get("/:UUID/:AUDIOUUID/stream/master.m3u8", middlewares.JwtStream, controllers.GetM3u8Data)
}
Loading

0 comments on commit 88c086c

Please sign in to comment.