mirror of
https://github.com/DeBrosOfficial/orama.git
synced 2026-03-17 08:56:58 +00:00
- Add signaling package with message types and structures for SFU communication. - Implement client and server message serialization/deserialization tests. - Enhance systemd manager to handle SFU and TURN services, including start/stop logic. - Create TURN server configuration and main server logic with HMAC-SHA1 authentication. - Add tests for TURN server credential generation and validation. - Define systemd service files for SFU and TURN services.
226 lines
5.3 KiB
Go
226 lines
5.3 KiB
Go
package turn
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestGenerateCredentials(t *testing.T) {
|
|
secret := "test-secret-key-32bytes-long!!!!"
|
|
namespace := "test-namespace"
|
|
ttl := 10 * time.Minute
|
|
|
|
username, password := GenerateCredentials(secret, namespace, ttl)
|
|
|
|
if username == "" {
|
|
t.Fatal("username should not be empty")
|
|
}
|
|
if password == "" {
|
|
t.Fatal("password should not be empty")
|
|
}
|
|
|
|
// Username should be "{timestamp}:{namespace}"
|
|
var ts int64
|
|
var ns string
|
|
n, err := fmt.Sscanf(username, "%d:%s", &ts, &ns)
|
|
if err != nil || n != 2 {
|
|
t.Fatalf("username format should be timestamp:namespace, got %q", username)
|
|
}
|
|
|
|
if ns != namespace {
|
|
t.Fatalf("namespace in username should be %q, got %q", namespace, ns)
|
|
}
|
|
|
|
// Timestamp should be ~10 minutes in the future
|
|
now := time.Now().Unix()
|
|
expectedExpiry := now + int64(ttl.Seconds())
|
|
if ts < expectedExpiry-2 || ts > expectedExpiry+2 {
|
|
t.Fatalf("expiry timestamp should be ~%d, got %d", expectedExpiry, ts)
|
|
}
|
|
}
|
|
|
|
func TestGeneratePassword(t *testing.T) {
|
|
secret := "test-secret"
|
|
username := "1234567890:test-ns"
|
|
|
|
password1 := GeneratePassword(secret, username)
|
|
password2 := GeneratePassword(secret, username)
|
|
|
|
// Same inputs should produce same output
|
|
if password1 != password2 {
|
|
t.Fatal("GeneratePassword should be deterministic")
|
|
}
|
|
|
|
// Different secret should produce different output
|
|
password3 := GeneratePassword("different-secret", username)
|
|
if password1 == password3 {
|
|
t.Fatal("different secrets should produce different passwords")
|
|
}
|
|
|
|
// Different username should produce different output
|
|
password4 := GeneratePassword(secret, "9999999999:other-ns")
|
|
if password1 == password4 {
|
|
t.Fatal("different usernames should produce different passwords")
|
|
}
|
|
}
|
|
|
|
func TestValidateCredentials(t *testing.T) {
|
|
secret := "test-secret-key"
|
|
namespace := "my-namespace"
|
|
ttl := 10 * time.Minute
|
|
|
|
// Generate valid credentials
|
|
username, password := GenerateCredentials(secret, namespace, ttl)
|
|
|
|
tests := []struct {
|
|
name string
|
|
secret string
|
|
username string
|
|
password string
|
|
namespace string
|
|
wantValid bool
|
|
}{
|
|
{
|
|
name: "valid credentials",
|
|
secret: secret,
|
|
username: username,
|
|
password: password,
|
|
namespace: namespace,
|
|
wantValid: true,
|
|
},
|
|
{
|
|
name: "wrong secret",
|
|
secret: "wrong-secret",
|
|
username: username,
|
|
password: password,
|
|
namespace: namespace,
|
|
wantValid: false,
|
|
},
|
|
{
|
|
name: "wrong password",
|
|
secret: secret,
|
|
username: username,
|
|
password: "wrongpassword",
|
|
namespace: namespace,
|
|
wantValid: false,
|
|
},
|
|
{
|
|
name: "wrong namespace",
|
|
secret: secret,
|
|
username: username,
|
|
password: password,
|
|
namespace: "other-namespace",
|
|
wantValid: false,
|
|
},
|
|
{
|
|
name: "expired credentials",
|
|
secret: secret,
|
|
username: fmt.Sprintf("%d:%s", time.Now().Unix()-60, namespace),
|
|
password: GeneratePassword(secret, fmt.Sprintf("%d:%s", time.Now().Unix()-60, namespace)),
|
|
namespace: namespace,
|
|
wantValid: false,
|
|
},
|
|
{
|
|
name: "malformed username - no colon",
|
|
secret: secret,
|
|
username: "badusername",
|
|
password: "whatever",
|
|
namespace: namespace,
|
|
wantValid: false,
|
|
},
|
|
{
|
|
name: "malformed username - non-numeric timestamp",
|
|
secret: secret,
|
|
username: "notanumber:my-namespace",
|
|
password: "whatever",
|
|
namespace: namespace,
|
|
wantValid: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := ValidateCredentials(tt.secret, tt.username, tt.password, tt.namespace)
|
|
if got != tt.wantValid {
|
|
t.Errorf("ValidateCredentials() = %v, want %v", got, tt.wantValid)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestConfigValidation(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
config Config
|
|
wantErrs int
|
|
}{
|
|
{
|
|
name: "valid config",
|
|
config: Config{
|
|
ListenAddr: "0.0.0.0:3478",
|
|
PublicIP: "1.2.3.4",
|
|
Realm: "dbrs.space",
|
|
AuthSecret: "secret123",
|
|
RelayPortStart: 49152,
|
|
RelayPortEnd: 50000,
|
|
Namespace: "test-ns",
|
|
},
|
|
wantErrs: 0,
|
|
},
|
|
{
|
|
name: "missing all fields",
|
|
config: Config{},
|
|
wantErrs: 6, // listen_addr, public_ip, realm, auth_secret, relay_port_range, namespace
|
|
},
|
|
{
|
|
name: "invalid public IP",
|
|
config: Config{
|
|
ListenAddr: "0.0.0.0:3478",
|
|
PublicIP: "not-an-ip",
|
|
Realm: "dbrs.space",
|
|
AuthSecret: "secret",
|
|
RelayPortStart: 49152,
|
|
RelayPortEnd: 50000,
|
|
Namespace: "test-ns",
|
|
},
|
|
wantErrs: 1,
|
|
},
|
|
{
|
|
name: "relay range too small",
|
|
config: Config{
|
|
ListenAddr: "0.0.0.0:3478",
|
|
PublicIP: "1.2.3.4",
|
|
Realm: "dbrs.space",
|
|
AuthSecret: "secret",
|
|
RelayPortStart: 49152,
|
|
RelayPortEnd: 49200,
|
|
Namespace: "test-ns",
|
|
},
|
|
wantErrs: 1,
|
|
},
|
|
{
|
|
name: "relay range inverted",
|
|
config: Config{
|
|
ListenAddr: "0.0.0.0:3478",
|
|
PublicIP: "1.2.3.4",
|
|
Realm: "dbrs.space",
|
|
AuthSecret: "secret",
|
|
RelayPortStart: 50000,
|
|
RelayPortEnd: 49152,
|
|
Namespace: "test-ns",
|
|
},
|
|
wantErrs: 1,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
errs := tt.config.Validate()
|
|
if len(errs) != tt.wantErrs {
|
|
t.Errorf("Validate() returned %d errors, want %d: %v", len(errs), tt.wantErrs, errs)
|
|
}
|
|
})
|
|
}
|
|
}
|