Skip to content

Commit 010af8b

Browse files
michaelowensSean-Der
authored andcommitted
Fix streamKey not getting passed to webhook
Move webhook validation after stream profile policy and use resolved streamkey
1 parent 54fa5bc commit 010af8b

File tree

2 files changed

+72
-15
lines changed

2 files changed

+72
-15
lines changed

internal/server/handlers/whip/whip.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -64,21 +64,6 @@ func WHIPHandler(responseWriter http.ResponseWriter, request *http.Request) {
6464

6565
var userProfile authorization.PublicProfile
6666

67-
// Stream requires webhook validation
68-
if webhookURL := os.Getenv(environment.WebhookURL); webhookURL != "" {
69-
streamKey, err := webhook.CallWebhook(webhookURL, webhook.WHIPConnect, token, request)
70-
if err != nil {
71-
responseWriter.WriteHeader(http.StatusUnauthorized)
72-
return
73-
}
74-
75-
userProfile = authorization.PublicProfile{
76-
StreamKey: streamKey,
77-
IsPublic: true,
78-
MOTD: "Welcome to " + streamKey + "'s stream!",
79-
}
80-
}
81-
8267
// Stream profile policy
8368
switch os.Getenv(environment.StreamProfilePolicy) {
8469
// Only approved profiles are allowed to stream
@@ -118,6 +103,21 @@ func WHIPHandler(responseWriter http.ResponseWriter, request *http.Request) {
118103
}
119104
}
120105

106+
// Stream requires webhook validation
107+
if webhookURL := os.Getenv(environment.WebhookURL); webhookURL != "" {
108+
streamKey, err := webhook.CallWebhook(webhookURL, webhook.WHIPConnect, userProfile.StreamKey, request)
109+
if err != nil {
110+
responseWriter.WriteHeader(http.StatusUnauthorized)
111+
return
112+
}
113+
114+
userProfile = authorization.PublicProfile{
115+
StreamKey: streamKey,
116+
IsPublic: true,
117+
MOTD: "Welcome to " + streamKey + "'s stream!",
118+
}
119+
}
120+
121121
if request.Method == http.MethodPatch {
122122

123123
if contentType := request.Header.Get("Content-Type"); contentType != "application/trickle-ice-sdpfrag" {
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package whip
2+
3+
import (
4+
"encoding/json"
5+
"net/http"
6+
"net/http/httptest"
7+
"strings"
8+
"testing"
9+
10+
"github.com/glimesh/broadcast-box/internal/environment"
11+
"github.com/glimesh/broadcast-box/internal/server/authorization"
12+
"github.com/stretchr/testify/require"
13+
)
14+
15+
type whipWebhookPayload struct {
16+
Action string `json:"action"`
17+
BearerToken string `json:"bearerToken"`
18+
}
19+
20+
func TestWHIPHandlerWebhookUsesResolvedStreamKey(t *testing.T) {
21+
t.Setenv(environment.StreamProfilePath, t.TempDir())
22+
t.Setenv(environment.StreamProfilePolicy, authorization.StreamPolicyReservedOnly)
23+
24+
const streamKey = "test_stream"
25+
bearerToken, err := authorization.CreateProfile(streamKey)
26+
require.NoError(t, err)
27+
28+
payloads := make(chan whipWebhookPayload, 1)
29+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
30+
defer func() { _ = r.Body.Close() }()
31+
32+
var payload whipWebhookPayload
33+
require.NoError(t, json.NewDecoder(r.Body).Decode(&payload))
34+
35+
payloads <- payload
36+
w.WriteHeader(http.StatusUnauthorized)
37+
}))
38+
defer server.Close()
39+
40+
t.Setenv(environment.WebhookURL, server.URL)
41+
42+
req := httptest.NewRequest(http.MethodPost, "/api/whip", strings.NewReader("v=0"))
43+
req.Header.Set("Authorization", "Bearer "+bearerToken)
44+
45+
resp := httptest.NewRecorder()
46+
WHIPHandler(resp, req)
47+
48+
require.Equal(t, http.StatusUnauthorized, resp.Code)
49+
50+
select {
51+
case payload := <-payloads:
52+
require.Equal(t, "whip-connect", payload.Action)
53+
require.Equal(t, streamKey, payload.BearerToken)
54+
default:
55+
require.Fail(t, "expected webhook to be called")
56+
}
57+
}

0 commit comments

Comments
 (0)