element-call-Github/backend/auth/server.go
David Baker 8996aa772c Initial support for getting SFO config using OIDC
* Change `jwt_service_url` to `livekit_service_url`
 * Make it a POST so we can send the openID token sensibly
 * Get an OIDC token & pass it with the request
 * Read the SFU URL from there too

and convert the auth server accordingly, althugh with no actual OIDC
support yet, it just issues tokens blindly just as before and ignores
the openid token completely.

We'll need to update configs & the JWT service before merging this.
2023-06-28 16:35:56 +01:00

127 lines
2.9 KiB
Go

package main
import (
"encoding/json"
"log"
"net/http"
"os"
"time"
"github.com/livekit/protocol/auth"
)
type Handler struct {
key, secret string
}
type OpenIDTokenType struct {
}
type SFURequest struct {
Room string `json:"room"`
OpenIDToken OpenIDTokenType `json:"openid_token"`
DeviceID string `json:"device_id"`
RemoveMeUserID string `json:"remove_me_user_id"` // we'll get this from OIDC
}
type SFUResponse struct {
URL string `json:"url"`
JWT string `json:"jwt"`
}
func (h *Handler) handle(w http.ResponseWriter, r *http.Request) {
log.Printf("Request from %s", r.RemoteAddr)
// Set the CORS headers
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "POST")
w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token")
// Handle preflight request (CORS)
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
} else if r.Method == "POST" {
var body SFURequest
err := json.NewDecoder(r.Body).Decode(&body)
if err != nil {
log.Printf("Error decoding JSON: %v", err)
w.WriteHeader(http.StatusBadRequest)
return
}
if body.Room == "" {
log.Printf("Request missing room")
w.WriteHeader(http.StatusBadRequest)
return
}
token, err := getJoinToken(h.key, h.secret, body.Room, body.RemoveMeUserID+":"+body.DeviceID)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
res := SFUResponse{URL: "http://localhost:7880/", JWT: token}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(res)
} else {
w.WriteHeader(http.StatusMethodNotAllowed)
}
/*
roomName := r.URL.Query().Get("roomName")
name := r.URL.Query().Get("name")
identity := r.URL.Query().Get("identity")
log.Printf("roomName: %s, name: %s, identity: %s", roomName, name, identity)
if roomName == "" || name == "" || identity == "" {
w.WriteHeader(http.StatusBadRequest)
return
}
*/
}
func main() {
key := os.Getenv("LIVEKIT_KEY")
secret := os.Getenv("LIVEKIT_SECRET")
// Check if the key and secret are empty.
if key == "" || secret == "" {
log.Fatal("LIVEKIT_KEY and LIVEKIT_SECRET environment variables must be set")
}
log.Printf("LIVEKIT_KEY: %s and LIVEKIT_SECRET %s", key, secret)
handler := &Handler{
key: key,
secret: secret,
}
http.HandleFunc("/sfu/get", handler.handle)
log.Fatal(http.ListenAndServe(":8080", nil))
}
func getJoinToken(apiKey, apiSecret, room, identity string) (string, error) {
at := auth.NewAccessToken(apiKey, apiSecret)
canPublish := true
canSubscribe := true
grant := &auth.VideoGrant{
RoomJoin: true,
RoomCreate: true,
CanPublish: &canPublish,
CanSubscribe: &canSubscribe,
Room: room,
}
at.AddGrant(grant).
SetIdentity(identity).
SetValidFor(time.Hour)
return at.ToJWT()
}