From 3d36dfc7c70af41ac7f36c03bcec7b7fff453b40 Mon Sep 17 00:00:00 2001 From: genofire Date: Sun, 12 Mar 2023 15:53:33 +0100 Subject: [PATCH] feat: add policy with signing for Access Control --- go.mod | 1 + go.sum | 3 +++ signed-policy/main.go | 47 +++++++++++++++++++++++++++++++++ signed-policy/main_test.go | 52 +++++++++++++++++++++++++++++++++++++ signed-policy/signed-policy | 1 + 5 files changed, 104 insertions(+) create mode 100644 signed-policy/main.go create mode 100644 signed-policy/main_test.go create mode 100644 signed-policy/signed-policy diff --git a/go.mod b/go.mod index 867d01d..0ef242f 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/prometheus/client_golang v1.14.0 github.com/prometheus/common v0.40.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect + github.com/stretchr/testify v1.8.2 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.9.0 // indirect go.uber.org/zap v1.24.0 diff --git a/go.sum b/go.sum index ac46ad4..a4756bc 100644 --- a/go.sum +++ b/go.sum @@ -468,6 +468,7 @@ github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5J github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -476,6 +477,8 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= diff --git a/signed-policy/main.go b/signed-policy/main.go new file mode 100644 index 0000000..f20d6f6 --- /dev/null +++ b/signed-policy/main.go @@ -0,0 +1,47 @@ +package signedPolicy + +import ( + "crypto/hmac" + "crypto/sha1" + "encoding/base64" + "encoding/json" + "net/url" +) + +type Policy struct { + URLExpire int `json:"url_expire"` + URLActivate int `json:"url_activate,omitempty"` + StreamExpire int `json:"stream_expire,omitempty"` + AllowIP string `json:"allow_ip,omitempty"` +} + +func (p Policy) Encode() string { + str, err := json.Marshal(p) + if err != nil { + return "" + } + return base64.RawStdEncoding.EncodeToString(str) +} +func SignEncodedPolicy(url *url.URL, secretKey string) string { + hasher := hmac.New(sha1.New, []byte(secretKey)) + hasher.Write([]byte(url.String())) + return base64.RawURLEncoding.EncodeToString(hasher.Sum(nil)) + +} +func (p Policy) Sign(url *url.URL, secretKey string) string { + query := url.Query() + query.Add("policy", p.Encode()) + url.RawQuery = query.Encode() + return SignEncodedPolicy(url, secretKey) +} + +func (p Policy) SignURL(url *url.URL, secretKey string) { + encode := p.Encode() + query := url.Query() + query.Add("policy", encode) + url.RawQuery = query.Encode() + + signature := SignEncodedPolicy(url, secretKey) + query.Add("signature", signature) + url.RawQuery = query.Encode() +} \ No newline at end of file diff --git a/signed-policy/main_test.go b/signed-policy/main_test.go new file mode 100644 index 0000000..86bf634 --- /dev/null +++ b/signed-policy/main_test.go @@ -0,0 +1,52 @@ +// https://airensoft.gitbook.io/ovenmediaengine/access-control/signedpolicy +package signedPolicy + +import ( + "net/url" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestPolicyEncode(t *testing.T) { + assert := assert.New(t) + + p := Policy{ + URLExpire: 1399721581, + } + + assert.Equal("eyJ1cmxfZXhwaXJlIjoxMzk5NzIxNTgxfQ", p.Encode()) +} + +func TestPolicySign(t *testing.T) { + assert := assert.New(t) + + p := Policy{ + URLExpire: 1399721581, + } + + secretKey := "1kU^b6" + + u, _ := url.Parse("ws://192.168.0.100:3333/app/stream") + + assert.Equal("dvVdBpoxAeCPl94Kt5RoiqLI0YE", p.Sign(u, secretKey)) +} +func TestPolicySignURL(t *testing.T) { + assert := assert.New(t) + + p := Policy{ + URLExpire: 1399721581, + } + + secretKey := "1kU^b6" + + u, _ := url.Parse("ws://192.168.0.100:3333/app/stream") + + p.SignURL(u, secretKey) + + // drop port -> is not part of example + u.Host = u.Hostname() + + expected := "ws://192.168.0.100/app/stream?policy=eyJ1cmxfZXhwaXJlIjoxMzk5NzIxNTgxfQ&signature=dvVdBpoxAeCPl94Kt5RoiqLI0YE" + assert.Equal(expected, u.String()) +} diff --git a/signed-policy/signed-policy b/signed-policy/signed-policy new file mode 100644 index 0000000..02bcf98 --- /dev/null +++ b/signed-policy/signed-policy @@ -0,0 +1 @@ +package signed-policy