simplify token issuer/verifier interface

This commit is contained in:
David Zhao committed 2020-12-27 20:53:07 -08:00
1 parent 353f35443a
commit 46dadc25c2
13 files changed
+245 -338

No files matched your search

+63
View File
@@ -0,0 +1,63 @@
package auth
import (
"time"
"gopkg.in/square/go-jose.v2"
"gopkg.in/square/go-jose.v2/jwt"
)
// Signer that produces token signed with API key and secret
type AccessToken struct {
apiKey string
secret string
identity string
grant *VideoGrant
validFor time.Duration
}
func NewAccessToken(key string, secret string) *AccessToken {
return &AccessToken{
apiKey: key,
secret: secret,
}
}
func (t *AccessToken) SetIdentity(identity string) *AccessToken {
t.identity = identity
return t
}
func (t *AccessToken) SetValidFor(duration time.Duration) *AccessToken {
t.validFor = duration
return t
}
func (t *AccessToken) AddGrant(grant *VideoGrant) *AccessToken {
t.grant = grant
return t
}
func (t *AccessToken) ToJWT() (string, error) {
if t.apiKey == "" || t.secret == "" {
return "", ErrKeysMissing
}
sig, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.HS256, Key: []byte(t.secret)},
(&jose.SignerOptions{}).WithType("JWT"))
if err != nil {
return "", err
}
cl := jwt.Claims{
Issuer: t.apiKey,
NotBefore: jwt.NewNumericDate(time.Now()),
Expiry: jwt.NewNumericDate(time.Now().Add(t.validFor)),
ID: t.identity,
}
grants := &ClaimGrants{}
if t.grant != nil {
grants.Video = t.grant
}
return jwt.Signed(sig).Claims(cl).Claims(grants).CompactSerialize()
}
@@ -14,31 +14,33 @@ import (
func TestAPIIssuer(t *testing.T) {
t.Run("keys must be set", func(t *testing.T) {
s := auth.NewAPIKeyTokenIssuer("", "")
_, err := s.CreateToken(&auth.GrantClaims{}, time.Hour)
token := auth.NewAccessToken("", "")
_, err := token.ToJWT()
assert.Equal(t, auth.ErrKeysMissing, err)
})
t.Run("generates a decodeable key", func(t *testing.T) {
apiKey, secret := apiKeypair()
//fmt.Println(apiKey, secret)
s := auth.NewAPIKeyTokenIssuer(apiKey, secret)
claims := auth.GrantClaims{RoomJoin: true, Room: "myroom"}
raw, err := s.CreateToken(&claims, time.Hour)
videoGrant := &auth.VideoGrant{RoomJoin: true, Room: "myroom"}
at := auth.NewAccessToken(apiKey, secret).
AddGrant(videoGrant).
SetValidFor(time.Minute * 5).
SetIdentity("user")
value, err := at.ToJWT()
//fmt.Println(raw)
assert.NoError(t, err)
assert.Len(t, strings.Split(raw, "."), 3)
assert.Len(t, strings.Split(value, "."), 3)
// ensure it's a valid JWT
token, err := jwt.ParseSigned(raw)
token, err := jwt.ParseSigned(value)
assert.NoError(t, err)
decodedGrant := auth.GrantClaims{}
decodedGrant := auth.ClaimGrants{}
err = token.UnsafeClaimsWithoutVerification(&decodedGrant)
assert.NoError(t, err)
assert.EqualValues(t, &claims, &decodedGrant)
assert.EqualValues(t, videoGrant, decodedGrant.Video)
})
}
+33 -33
View File
@@ -19,14 +19,14 @@ type FakeKeyProvider struct {
getSecretReturnsOnCall map[int]struct {
result1 string
}
KeyCountStub func() int
keyCountMutex sync.RWMutex
keyCountArgsForCall []struct {
NumKeysStub func() int
numKeysMutex sync.RWMutex
numKeysArgsForCall []struct {
}
keyCountReturns struct {
numKeysReturns struct {
result1 int
}
keyCountReturnsOnCall map[int]struct {
numKeysReturnsOnCall map[int]struct {
result1 int
}
invocations map[string][][]interface{}
@@ -95,14 +95,14 @@ func (fake *FakeKeyProvider) GetSecretReturnsOnCall(i int, result1 string) {
}
func (fake *FakeKeyProvider) NumKeys() int {
fake.keyCountMutex.Lock()
ret, specificReturn := fake.keyCountReturnsOnCall[len(fake.keyCountArgsForCall)]
fake.keyCountArgsForCall = append(fake.keyCountArgsForCall, struct {
fake.numKeysMutex.Lock()
ret, specificReturn := fake.numKeysReturnsOnCall[len(fake.numKeysArgsForCall)]
fake.numKeysArgsForCall = append(fake.numKeysArgsForCall, struct {
}{})
stub := fake.KeyCountStub
fakeReturns := fake.keyCountReturns
stub := fake.NumKeysStub
fakeReturns := fake.numKeysReturns
fake.recordInvocation("NumKeys", []interface{}{})
fake.keyCountMutex.Unlock()
fake.numKeysMutex.Unlock()
if stub != nil {
return stub()
}
@@ -112,37 +112,37 @@ func (fake *FakeKeyProvider) NumKeys() int {
return fakeReturns.result1
}
func (fake *FakeKeyProvider) KeyCountCallCount() int {
fake.keyCountMutex.RLock()
defer fake.keyCountMutex.RUnlock()
return len(fake.keyCountArgsForCall)
func (fake *FakeKeyProvider) NumKeysCallCount() int {
fake.numKeysMutex.RLock()
defer fake.numKeysMutex.RUnlock()
return len(fake.numKeysArgsForCall)
}
func (fake *FakeKeyProvider) KeyCountCalls(stub func() int) {
fake.keyCountMutex.Lock()
defer fake.keyCountMutex.Unlock()
fake.KeyCountStub = stub
func (fake *FakeKeyProvider) NumKeysCalls(stub func() int) {
fake.numKeysMutex.Lock()
defer fake.numKeysMutex.Unlock()
fake.NumKeysStub = stub
}
func (fake *FakeKeyProvider) KeyCountReturns(result1 int) {
fake.keyCountMutex.Lock()
defer fake.keyCountMutex.Unlock()
fake.KeyCountStub = nil
fake.keyCountReturns = struct {
func (fake *FakeKeyProvider) NumKeysReturns(result1 int) {
fake.numKeysMutex.Lock()
defer fake.numKeysMutex.Unlock()
fake.NumKeysStub = nil
fake.numKeysReturns = struct {
result1 int
}{result1}
}
func (fake *FakeKeyProvider) KeyCountReturnsOnCall(i int, result1 int) {
fake.keyCountMutex.Lock()
defer fake.keyCountMutex.Unlock()
fake.KeyCountStub = nil
if fake.keyCountReturnsOnCall == nil {
fake.keyCountReturnsOnCall = make(map[int]struct {
func (fake *FakeKeyProvider) NumKeysReturnsOnCall(i int, result1 int) {
fake.numKeysMutex.Lock()
defer fake.numKeysMutex.Unlock()
fake.NumKeysStub = nil
if fake.numKeysReturnsOnCall == nil {
fake.numKeysReturnsOnCall = make(map[int]struct {
result1 int
})
}
fake.keyCountReturnsOnCall[i] = struct {
fake.numKeysReturnsOnCall[i] = struct {
result1 int
}{result1}
}
@@ -152,8 +152,8 @@ func (fake *FakeKeyProvider) Invocations() map[string][][]interface{} {
defer fake.invocationsMutex.RUnlock()
fake.getSecretMutex.RLock()
defer fake.getSecretMutex.RUnlock()
fake.keyCountMutex.RLock()
defer fake.keyCountMutex.RUnlock()
fake.numKeysMutex.RLock()
defer fake.numKeysMutex.RUnlock()
copiedInvocations := map[string][][]interface{}{}
for key, value := range fake.invocations {
copiedInvocations[key] = value
-119
View File
@@ -1,119 +0,0 @@
// Code generated by counterfeiter. DO NOT EDIT.
package authfakes
import (
"sync"
"time"
"github.com/livekit/livekit-server/pkg/auth"
)
type FakeTokenIssuer struct {
CreateTokenStub func(*auth.GrantClaims, time.Duration) (string, error)
createTokenMutex sync.RWMutex
createTokenArgsForCall []struct {
arg1 *auth.GrantClaims
arg2 time.Duration
}
createTokenReturns struct {
result1 string
result2 error
}
createTokenReturnsOnCall map[int]struct {
result1 string
result2 error
}
invocations map[string][][]interface{}
invocationsMutex sync.RWMutex
}
func (fake *FakeTokenIssuer) CreateToken(arg1 *auth.GrantClaims, arg2 time.Duration) (string, error) {
fake.createTokenMutex.Lock()
ret, specificReturn := fake.createTokenReturnsOnCall[len(fake.createTokenArgsForCall)]
fake.createTokenArgsForCall = append(fake.createTokenArgsForCall, struct {
arg1 *auth.GrantClaims
arg2 time.Duration
}{arg1, arg2})
stub := fake.CreateTokenStub
fakeReturns := fake.createTokenReturns
fake.recordInvocation("CreateToken", []interface{}{arg1, arg2})
fake.createTokenMutex.Unlock()
if stub != nil {
return stub(arg1, arg2)
}
if specificReturn {
return ret.result1, ret.result2
}
return fakeReturns.result1, fakeReturns.result2
}
func (fake *FakeTokenIssuer) CreateTokenCallCount() int {
fake.createTokenMutex.RLock()
defer fake.createTokenMutex.RUnlock()
return len(fake.createTokenArgsForCall)
}
func (fake *FakeTokenIssuer) CreateTokenCalls(stub func(*auth.GrantClaims, time.Duration) (string, error)) {
fake.createTokenMutex.Lock()
defer fake.createTokenMutex.Unlock()
fake.CreateTokenStub = stub
}
func (fake *FakeTokenIssuer) CreateTokenArgsForCall(i int) (*auth.GrantClaims, time.Duration) {
fake.createTokenMutex.RLock()
defer fake.createTokenMutex.RUnlock()
argsForCall := fake.createTokenArgsForCall[i]
return argsForCall.arg1, argsForCall.arg2
}
func (fake *FakeTokenIssuer) CreateTokenReturns(result1 string, result2 error) {
fake.createTokenMutex.Lock()
defer fake.createTokenMutex.Unlock()
fake.CreateTokenStub = nil
fake.createTokenReturns = struct {
result1 string
result2 error
}{result1, result2}
}
func (fake *FakeTokenIssuer) CreateTokenReturnsOnCall(i int, result1 string, result2 error) {
fake.createTokenMutex.Lock()
defer fake.createTokenMutex.Unlock()
fake.CreateTokenStub = nil
if fake.createTokenReturnsOnCall == nil {
fake.createTokenReturnsOnCall = make(map[int]struct {
result1 string
result2 error
})
}
fake.createTokenReturnsOnCall[i] = struct {
result1 string
result2 error
}{result1, result2}
}
func (fake *FakeTokenIssuer) Invocations() map[string][][]interface{} {
fake.invocationsMutex.RLock()
defer fake.invocationsMutex.RUnlock()
fake.createTokenMutex.RLock()
defer fake.createTokenMutex.RUnlock()
copiedInvocations := map[string][][]interface{}{}
for key, value := range fake.invocations {
copiedInvocations[key] = value
}
return copiedInvocations
}
func (fake *FakeTokenIssuer) recordInvocation(key string, args []interface{}) {
fake.invocationsMutex.Lock()
defer fake.invocationsMutex.Unlock()
if fake.invocations == nil {
fake.invocations = map[string][][]interface{}{}
}
if fake.invocations[key] == nil {
fake.invocations[key] = [][]interface{}{}
}
fake.invocations[key] = append(fake.invocations[key], args)
}
var _ auth.TokenIssuer = new(FakeTokenIssuer)
+87 -13
View File
@@ -8,33 +8,98 @@ import (
)
type FakeTokenVerifier struct {
VerifyStub func() (*auth.GrantClaims, error)
IdentityStub func() string
identityMutex sync.RWMutex
identityArgsForCall []struct {
}
identityReturns struct {
result1 string
}
identityReturnsOnCall map[int]struct {
result1 string
}
VerifyStub func(interface{}) (*auth.VideoGrant, error)
verifyMutex sync.RWMutex
verifyArgsForCall []struct {
arg1 interface{}
}
verifyReturns struct {
result1 *auth.GrantClaims
result1 *auth.VideoGrant
result2 error
}
verifyReturnsOnCall map[int]struct {
result1 *auth.GrantClaims
result1 *auth.VideoGrant
result2 error
}
invocations map[string][][]interface{}
invocationsMutex sync.RWMutex
}
func (fake *FakeTokenVerifier) Verify() (*auth.GrantClaims, error) {
func (fake *FakeTokenVerifier) Identity() string {
fake.identityMutex.Lock()
ret, specificReturn := fake.identityReturnsOnCall[len(fake.identityArgsForCall)]
fake.identityArgsForCall = append(fake.identityArgsForCall, struct {
}{})
stub := fake.IdentityStub
fakeReturns := fake.identityReturns
fake.recordInvocation("Identity", []interface{}{})
fake.identityMutex.Unlock()
if stub != nil {
return stub()
}
if specificReturn {
return ret.result1
}
return fakeReturns.result1
}
func (fake *FakeTokenVerifier) IdentityCallCount() int {
fake.identityMutex.RLock()
defer fake.identityMutex.RUnlock()
return len(fake.identityArgsForCall)
}
func (fake *FakeTokenVerifier) IdentityCalls(stub func() string) {
fake.identityMutex.Lock()
defer fake.identityMutex.Unlock()
fake.IdentityStub = stub
}
func (fake *FakeTokenVerifier) IdentityReturns(result1 string) {
fake.identityMutex.Lock()
defer fake.identityMutex.Unlock()
fake.IdentityStub = nil
fake.identityReturns = struct {
result1 string
}{result1}
}
func (fake *FakeTokenVerifier) IdentityReturnsOnCall(i int, result1 string) {
fake.identityMutex.Lock()
defer fake.identityMutex.Unlock()
fake.IdentityStub = nil
if fake.identityReturnsOnCall == nil {
fake.identityReturnsOnCall = make(map[int]struct {
result1 string
})
}
fake.identityReturnsOnCall[i] = struct {
result1 string
}{result1}
}
func (fake *FakeTokenVerifier) Verify(arg1 interface{}) (*auth.VideoGrant, error) {
fake.verifyMutex.Lock()
ret, specificReturn := fake.verifyReturnsOnCall[len(fake.verifyArgsForCall)]
fake.verifyArgsForCall = append(fake.verifyArgsForCall, struct {
}{})
arg1 interface{}
}{arg1})
stub := fake.VerifyStub
fakeReturns := fake.verifyReturns
fake.recordInvocation("Verify", []interface{}{})
fake.recordInvocation("Verify", []interface{}{arg1})
fake.verifyMutex.Unlock()
if stub != nil {
return stub()
return stub(arg1)
}
if specificReturn {
return ret.result1, ret.result2
@@ -48,34 +113,41 @@ func (fake *FakeTokenVerifier) VerifyCallCount() int {
return len(fake.verifyArgsForCall)
}
func (fake *FakeTokenVerifier) VerifyCalls(stub func() (*auth.GrantClaims, error)) {
func (fake *FakeTokenVerifier) VerifyCalls(stub func(interface{}) (*auth.VideoGrant, error)) {
fake.verifyMutex.Lock()
defer fake.verifyMutex.Unlock()
fake.VerifyStub = stub
}
func (fake *FakeTokenVerifier) VerifyReturns(result1 *auth.GrantClaims, result2 error) {
func (fake *FakeTokenVerifier) VerifyArgsForCall(i int) interface{} {
fake.verifyMutex.RLock()
defer fake.verifyMutex.RUnlock()
argsForCall := fake.verifyArgsForCall[i]
return argsForCall.arg1
}
func (fake *FakeTokenVerifier) VerifyReturns(result1 *auth.VideoGrant, result2 error) {
fake.verifyMutex.Lock()
defer fake.verifyMutex.Unlock()
fake.VerifyStub = nil
fake.verifyReturns = struct {
result1 *auth.GrantClaims
result1 *auth.VideoGrant
result2 error
}{result1, result2}
}
func (fake *FakeTokenVerifier) VerifyReturnsOnCall(i int, result1 *auth.GrantClaims, result2 error) {
func (fake *FakeTokenVerifier) VerifyReturnsOnCall(i int, result1 *auth.VideoGrant, result2 error) {
fake.verifyMutex.Lock()
defer fake.verifyMutex.Unlock()
fake.VerifyStub = nil
if fake.verifyReturnsOnCall == nil {
fake.verifyReturnsOnCall = make(map[int]struct {
result1 *auth.GrantClaims
result1 *auth.VideoGrant
result2 error
})
}
fake.verifyReturnsOnCall[i] = struct {
result1 *auth.GrantClaims
result1 *auth.VideoGrant
result2 error
}{result1, result2}
}
@@ -83,6 +155,8 @@ func (fake *FakeTokenVerifier) VerifyReturnsOnCall(i int, result1 *auth.GrantCla
func (fake *FakeTokenVerifier) Invocations() map[string][][]interface{} {
fake.invocationsMutex.RLock()
defer fake.invocationsMutex.RUnlock()
fake.identityMutex.RLock()
defer fake.identityMutex.RUnlock()
fake.verifyMutex.RLock()
defer fake.verifyMutex.RUnlock()
copiedInvocations := map[string][][]interface{}{}
+6 -2
View File
@@ -1,7 +1,11 @@
package auth
type GrantClaims struct {
type VideoGrant struct {
RoomCreate bool `json:"room_create,omitempty"`
RoomJoin bool `json:"room_join,omitempty"`
Room string `json:"room"`
Room string `json:"room,omitempty"`
}
type ClaimGrants struct {
Video *VideoGrant `json:"video,omitempty"`
}
+9 -6
View File
@@ -2,7 +2,6 @@ package auth
import (
"errors"
"time"
)
//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate
@@ -11,14 +10,18 @@ var (
ErrKeysMissing = errors.New("missing API key or secret key")
)
//counterfeiter:generate . TokenIssuer
type TokenIssuer interface {
CreateToken(claims *GrantClaims, validFor time.Duration) (string, error)
}
////counterfeiter:generate . AccessToken
//type AccessToken interface {
// SetExpiration(time.Duration) AccessToken
// Identity(string) AccessToken
// AddGrant(*VideoGrant) AccessToken
// ToJWT() (string, error)
//}
//counterfeiter:generate . TokenVerifier
type TokenVerifier interface {
Verify() (*GrantClaims, error)
Identity() string
Verify(key interface{}) (*VideoGrant, error)
}
//counterfeiter:generate . KeyProvider
-41
View File
@@ -1,41 +0,0 @@
package auth
import (
"time"
"gopkg.in/square/go-jose.v2"
"gopkg.in/square/go-jose.v2/jwt"
)
// Signer that produces token signed with API key and secret
type APIKeyTokenIssuer struct {
APIKey string
SecretKey string
}
func NewAPIKeyTokenIssuer(key string, secret string) *APIKeyTokenIssuer {
return &APIKeyTokenIssuer{
APIKey: key,
SecretKey: secret,
}
}
func (s *APIKeyTokenIssuer) CreateToken(claims *GrantClaims, validFor time.Duration) (string, error) {
if s.APIKey == "" || s.SecretKey == "" {
return "", ErrKeysMissing
}
sig, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.HS256, Key: []byte(s.SecretKey)},
(&jose.SignerOptions{}).WithType("JWT"))
if err != nil {
return "", err
}
cl := jwt.Claims{
Issuer: s.APIKey,
Subject: s.APIKey,
NotBefore: jwt.NewNumericDate(time.Now()),
Expiry: jwt.NewNumericDate(time.Now().Add(validFor)),
}
return jwt.Signed(sig).Claims(cl).Claims(claims).CompactSerialize()
}
+16 -12
View File
@@ -7,9 +7,9 @@ import (
)
type APIKeyTokenVerifier struct {
token *jwt.JSONWebToken
apiKey string
secretKey string
token *jwt.JSONWebToken
identity string
apiKey string
}
func ParseAPIToken(raw string) (*APIKeyTokenVerifier, error) {
@@ -24,8 +24,9 @@ func ParseAPIToken(raw string) (*APIKeyTokenVerifier, error) {
}
return &APIKeyTokenVerifier{
token: tok,
apiKey: out.Issuer,
token: tok,
apiKey: out.Issuer,
identity: out.ID,
}, nil
}
@@ -34,21 +35,24 @@ func (v *APIKeyTokenVerifier) APIKey() string {
return v.apiKey
}
func (v *APIKeyTokenVerifier) SetSecretKey(secret string) {
v.secretKey = secret
func (v *APIKeyTokenVerifier) Identity() string {
return v.identity
}
func (v *APIKeyTokenVerifier) Verify() (*GrantClaims, error) {
if v.secretKey == "" {
func (v *APIKeyTokenVerifier) Verify(key interface{}) (*VideoGrant, error) {
if key == nil || key == "" {
return nil, ErrKeysMissing
}
if s, ok := key.(string); ok {
key = []byte(s)
}
out := jwt.Claims{}
claims := GrantClaims{}
if err := v.token.Claims([]byte(v.secretKey), &out, &claims); err != nil {
claims := ClaimGrants{}
if err := v.token.Claims(key, &out, &claims); err != nil {
return nil, err
}
if err := out.Validate(jwt.Expected{Issuer: v.apiKey, Time: time.Now()}); err != nil {
return nil, err
}
return &claims, nil
return claims.Video, nil
}
+11 -10
View File
@@ -18,34 +18,35 @@ func TestAPIVerifier(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, apiKey, v.APIKey())
_, err = v.Verify()
_, err = v.Verify("")
assert.Error(t, err)
v.SetSecretKey("anothersecret")
_, err = v.Verify()
_, err = v.Verify("anothersecret")
assert.Error(t, err)
})
t.Run("key has expired", func(t *testing.T) {
v, err := auth.ParseAPIToken(accessToken)
v.SetSecretKey(secret)
_, err = v.Verify()
_, err = v.Verify(secret)
assert.Error(t, err)
})
t.Run("unexpired token is verified", func(t *testing.T) {
s := auth.NewAPIKeyTokenIssuer(apiKey, secret)
claim := auth.GrantClaims{RoomCreate: true}
authToken, err := s.CreateToken(&claim, time.Minute)
claim := auth.VideoGrant{RoomCreate: true}
at := auth.NewAccessToken(apiKey, secret).
AddGrant(&claim).
SetValidFor(time.Minute).
SetIdentity("me")
authToken, err := at.ToJWT()
assert.NoError(t, err)
v, err := auth.ParseAPIToken(authToken)
assert.NoError(t, err)
assert.Equal(t, apiKey, v.APIKey())
assert.Equal(t, "me", v.Identity())
v.SetSecretKey(secret)
decoded, err := v.Verify()
decoded, err := v.Verify(secret)
assert.NoError(t, err)
assert.Equal(t, &claim, decoded)
})
-82
View File
@@ -1,82 +0,0 @@
package rtc
import (
"github.com/pion/sdp/v3"
"github.com/pion/webrtc/v3"
)
const (
mimeTypeH264 = "video/h264"
mimeTypeOpus = "audio/opus"
mimeTypeVP8 = "video/vp8"
mimeTypeVP9 = "video/vp9"
)
func createMediaEngine() (*webrtc.MediaEngine, error) {
me := &webrtc.MediaEngine{}
if err := me.RegisterCodec(webrtc.RTPCodecParameters{
RTPCodecCapability: webrtc.RTPCodecCapability{MimeType: mimeTypeOpus, ClockRate: 48000, Channels: 2, SDPFmtpLine: "minptime=10;useinbandfec=1", RTCPFeedback: nil},
PayloadType: 111,
}, webrtc.RTPCodecTypeAudio); err != nil {
return nil, err
}
videoRTCPFeedback := []webrtc.RTCPFeedback{{"goog-remb", ""}, {"ccm", "fir"}, {"nack", ""}, {"nack", "pli"}}
for _, codec := range []webrtc.RTPCodecParameters{
{
RTPCodecCapability: webrtc.RTPCodecCapability{MimeType: mimeTypeVP8, ClockRate: 90000, RTCPFeedback: videoRTCPFeedback},
PayloadType: 96,
},
{
RTPCodecCapability: webrtc.RTPCodecCapability{MimeType: mimeTypeVP9, ClockRate: 90000, SDPFmtpLine: "profile-id=0", RTCPFeedback: videoRTCPFeedback},
PayloadType: 98,
},
{
RTPCodecCapability: webrtc.RTPCodecCapability{MimeType: mimeTypeVP9, ClockRate: 90000, SDPFmtpLine: "profile-id=1", RTCPFeedback: videoRTCPFeedback},
PayloadType: 100,
},
{
RTPCodecCapability: webrtc.RTPCodecCapability{MimeType: mimeTypeH264, ClockRate: 90000, SDPFmtpLine: "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f", RTCPFeedback: videoRTCPFeedback},
PayloadType: 102,
},
{
RTPCodecCapability: webrtc.RTPCodecCapability{MimeType: mimeTypeH264, ClockRate: 90000, SDPFmtpLine: "level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f", RTCPFeedback: videoRTCPFeedback},
PayloadType: 127,
},
{
RTPCodecCapability: webrtc.RTPCodecCapability{MimeType: mimeTypeH264, ClockRate: 90000, SDPFmtpLine: "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f", RTCPFeedback: videoRTCPFeedback},
PayloadType: 125,
},
{
RTPCodecCapability: webrtc.RTPCodecCapability{MimeType: mimeTypeH264, ClockRate: 90000, SDPFmtpLine: "level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f", RTCPFeedback: videoRTCPFeedback},
PayloadType: 108,
},
{
RTPCodecCapability: webrtc.RTPCodecCapability{MimeType: mimeTypeH264, ClockRate: 90000, SDPFmtpLine: "level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f", RTCPFeedback: videoRTCPFeedback},
PayloadType: 127,
},
{
RTPCodecCapability: webrtc.RTPCodecCapability{MimeType: mimeTypeH264, ClockRate: 90000, SDPFmtpLine: "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=640032", RTCPFeedback: videoRTCPFeedback},
PayloadType: 123,
},
} {
if err := me.RegisterCodec(codec, webrtc.RTPCodecTypeVideo); err != nil {
return nil, err
}
}
for _, extension := range []string{
sdp.SDESMidURI,
sdp.SDESRTPStreamIDURI,
sdp.TransportCCURI,
} {
if err := me.RegisterHeaderExtension(webrtc.RTPHeaderExtensionCapability{URI: extension}, webrtc.RTPCodecTypeAudio); err != nil {
return nil, err
}
if err := me.RegisterHeaderExtension(webrtc.RTPHeaderExtensionCapability{URI: extension}, webrtc.RTPCodecTypeVideo); err != nil {
return nil, err
}
}
return me, nil
}
+3 -5
View File
@@ -58,9 +58,7 @@ func (m *APIKeyAuthMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request,
return
}
v.SetSecretKey(secret)
grants, err := v.Verify()
grants, err := v.Verify(secret)
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("invalid token: " + err.Error()))
@@ -75,8 +73,8 @@ func (m *APIKeyAuthMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request,
next.ServeHTTP(w, r)
}
func GetGrants(ctx context.Context) *auth.GrantClaims {
claims, ok := ctx.Value(grantsKey).(*auth.GrantClaims)
func GetGrants(ctx context.Context) *auth.VideoGrant {
claims, ok := ctx.Value(grantsKey).(*auth.VideoGrant)
if !ok {
return nil
}
+5 -5
View File
@@ -4,7 +4,6 @@ import (
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/stretchr/testify/assert"
@@ -20,16 +19,17 @@ func TestAuthMiddleware(t *testing.T) {
provider.GetSecretReturns(secret)
m := service.NewAPIKeyAuthMiddleware(provider)
var grants *auth.GrantClaims
var grants *auth.VideoGrant
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
grants = service.GetGrants(r.Context())
w.WriteHeader(http.StatusOK)
})
orig := &auth.VideoGrant{Room: "abcdefg", RoomJoin: true}
// ensure that the original claim could be retrieved
issuer := auth.NewAPIKeyTokenIssuer(api, secret)
orig := &auth.GrantClaims{Room: "abcdefg", RoomJoin: true}
token, err := issuer.CreateToken(orig, time.Minute)
at := auth.NewAccessToken(api, secret).
AddGrant(orig)
token, err := at.ToJWT()
assert.NoError(t, err)
r := &http.Request{Header: http.Header{}}