fix support for JWT authentication in API, metrics, playback, pprof (#3253)

Co-authored-by: Rafael Scheidt <rafaelscheidt@Rafaels-MacBook-Air.local>
Co-authored-by: aler9 <46489434+aler9@users.noreply.github.com>
This commit is contained in:
Rafael Scheidt 2024-04-18 18:55:48 -03:00 committed by GitHub
parent b84f0b90d0
commit 2bd8ac7e19
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 201 additions and 134 deletions

View file

@ -151,6 +151,10 @@ type WebRTCServer interface {
APISessionsKick(uuid.UUID) error
}
type apiAuthManager interface {
Authenticate(req *auth.Request) error
}
type apiParent interface {
logger.Writer
APIConfigSet(conf *conf.Conf)
@ -161,7 +165,7 @@ type API struct {
Address string
ReadTimeout conf.StringDuration
Conf *conf.Conf
AuthManager *auth.Manager
AuthManager apiAuthManager
PathManager PathManager
RTSPServer RTSPServer
RTSPSServer RTSPServer
@ -296,6 +300,7 @@ func (a *API) mwAuth(ctx *gin.Context) {
err := a.AuthManager.Authenticate(&auth.Request{
User: user,
Pass: pass,
Query: ctx.Request.URL.RawQuery,
IP: net.ParseIP(ctx.ClientIP()),
Action: conf.AuthActionAPI,
})

View file

@ -106,20 +106,38 @@ func TestPaginate(t *testing.T) {
require.Equal(t, []int{4, 5}, items)
}
var authManager = &auth.Manager{
Method: conf.AuthMethodInternal,
InternalUsers: []conf.AuthInternalUser{
{
User: "myuser",
Pass: "mypass",
Permissions: []conf.AuthInternalUserPermission{
{
Action: conf.AuthActionAPI,
},
func TestConfigAuth(t *testing.T) {
cnf := tempConf(t, "api: yes\n")
api := API{
Address: "localhost:9997",
ReadTimeout: conf.StringDuration(10 * time.Second),
Conf: cnf,
AuthManager: &test.AuthManager{
Func: func(req *auth.Request) error {
require.Equal(t, &auth.Request{
User: "myuser",
Pass: "mypass",
IP: req.IP,
Action: "api",
Query: "key=val",
}, req)
return nil
},
},
},
RTSPAuthMethods: nil,
Parent: &testParent{},
}
err := api.Initialize()
require.NoError(t, err)
defer api.Close()
tr := &http.Transport{}
defer tr.CloseIdleConnections()
hc := &http.Client{Transport: tr}
var out map[string]interface{}
httpRequest(t, hc, http.MethodGet, "http://myuser:mypass@localhost:9997/v3/config/global/get?key=val", nil, &out)
require.Equal(t, true, out["api"])
}
func TestConfigGlobalGet(t *testing.T) {
@ -129,7 +147,7 @@ func TestConfigGlobalGet(t *testing.T) {
Address: "localhost:9997",
ReadTimeout: conf.StringDuration(10 * time.Second),
Conf: cnf,
AuthManager: authManager,
AuthManager: test.NilAuthManager,
Parent: &testParent{},
}
err := api.Initialize()
@ -141,7 +159,7 @@ func TestConfigGlobalGet(t *testing.T) {
hc := &http.Client{Transport: tr}
var out map[string]interface{}
httpRequest(t, hc, http.MethodGet, "http://myuser:mypass@localhost:9997/v3/config/global/get", nil, &out)
httpRequest(t, hc, http.MethodGet, "http://localhost:9997/v3/config/global/get", nil, &out)
require.Equal(t, true, out["api"])
}
@ -152,7 +170,7 @@ func TestConfigGlobalPatch(t *testing.T) {
Address: "localhost:9997",
ReadTimeout: conf.StringDuration(10 * time.Second),
Conf: cnf,
AuthManager: authManager,
AuthManager: test.NilAuthManager,
Parent: &testParent{},
}
err := api.Initialize()
@ -163,7 +181,7 @@ func TestConfigGlobalPatch(t *testing.T) {
defer tr.CloseIdleConnections()
hc := &http.Client{Transport: tr}
httpRequest(t, hc, http.MethodPatch, "http://myuser:mypass@localhost:9997/v3/config/global/patch",
httpRequest(t, hc, http.MethodPatch, "http://localhost:9997/v3/config/global/patch",
map[string]interface{}{
"rtmp": false,
"readTimeout": "7s",
@ -174,7 +192,7 @@ func TestConfigGlobalPatch(t *testing.T) {
time.Sleep(500 * time.Millisecond)
var out map[string]interface{}
httpRequest(t, hc, http.MethodGet, "http://myuser:mypass@localhost:9997/v3/config/global/get", nil, &out)
httpRequest(t, hc, http.MethodGet, "http://localhost:9997/v3/config/global/get", nil, &out)
require.Equal(t, false, out["rtmp"])
require.Equal(t, "7s", out["readTimeout"])
require.Equal(t, []interface{}{"tcp"}, out["protocols"])
@ -188,7 +206,7 @@ func TestConfigGlobalPatchUnknownField(t *testing.T) { //nolint:dupl
Address: "localhost:9997",
ReadTimeout: conf.StringDuration(10 * time.Second),
Conf: cnf,
AuthManager: authManager,
AuthManager: test.NilAuthManager,
Parent: &testParent{},
}
err := api.Initialize()
@ -206,7 +224,7 @@ func TestConfigGlobalPatchUnknownField(t *testing.T) { //nolint:dupl
defer tr.CloseIdleConnections()
hc := &http.Client{Transport: tr}
req, err := http.NewRequest(http.MethodPatch, "http://myuser:mypass@localhost:9997/v3/config/global/patch",
req, err := http.NewRequest(http.MethodPatch, "http://localhost:9997/v3/config/global/patch",
bytes.NewReader(byts))
require.NoError(t, err)
@ -225,7 +243,7 @@ func TestConfigPathDefaultsGet(t *testing.T) {
Address: "localhost:9997",
ReadTimeout: conf.StringDuration(10 * time.Second),
Conf: cnf,
AuthManager: authManager,
AuthManager: test.NilAuthManager,
Parent: &testParent{},
}
err := api.Initialize()
@ -237,7 +255,7 @@ func TestConfigPathDefaultsGet(t *testing.T) {
hc := &http.Client{Transport: tr}
var out map[string]interface{}
httpRequest(t, hc, http.MethodGet, "http://myuser:mypass@localhost:9997/v3/config/pathdefaults/get", nil, &out)
httpRequest(t, hc, http.MethodGet, "http://localhost:9997/v3/config/pathdefaults/get", nil, &out)
require.Equal(t, "publisher", out["source"])
}
@ -248,7 +266,7 @@ func TestConfigPathDefaultsPatch(t *testing.T) {
Address: "localhost:9997",
ReadTimeout: conf.StringDuration(10 * time.Second),
Conf: cnf,
AuthManager: authManager,
AuthManager: test.NilAuthManager,
Parent: &testParent{},
}
err := api.Initialize()
@ -259,7 +277,7 @@ func TestConfigPathDefaultsPatch(t *testing.T) {
defer tr.CloseIdleConnections()
hc := &http.Client{Transport: tr}
httpRequest(t, hc, http.MethodPatch, "http://myuser:mypass@localhost:9997/v3/config/pathdefaults/patch",
httpRequest(t, hc, http.MethodPatch, "http://localhost:9997/v3/config/pathdefaults/patch",
map[string]interface{}{
"readUser": "myuser",
"readPass": "mypass",
@ -268,7 +286,7 @@ func TestConfigPathDefaultsPatch(t *testing.T) {
time.Sleep(500 * time.Millisecond)
var out map[string]interface{}
httpRequest(t, hc, http.MethodGet, "http://myuser:mypass@localhost:9997/v3/config/pathdefaults/get", nil, &out)
httpRequest(t, hc, http.MethodGet, "http://localhost:9997/v3/config/pathdefaults/get", nil, &out)
require.Equal(t, "myuser", out["readUser"])
require.Equal(t, "mypass", out["readPass"])
}
@ -287,7 +305,7 @@ func TestConfigPathsList(t *testing.T) {
Address: "localhost:9997",
ReadTimeout: conf.StringDuration(10 * time.Second),
Conf: cnf,
AuthManager: authManager,
AuthManager: test.NilAuthManager,
Parent: &testParent{},
}
err := api.Initialize()
@ -307,7 +325,7 @@ func TestConfigPathsList(t *testing.T) {
hc := &http.Client{Transport: tr}
var out listRes
httpRequest(t, hc, http.MethodGet, "http://myuser:mypass@localhost:9997/v3/config/paths/list", nil, &out)
httpRequest(t, hc, http.MethodGet, "http://localhost:9997/v3/config/paths/list", nil, &out)
require.Equal(t, 2, out.ItemCount)
require.Equal(t, 1, out.PageCount)
require.Equal(t, "path1", out.Items[0]["name"])
@ -329,7 +347,7 @@ func TestConfigPathsGet(t *testing.T) {
Address: "localhost:9997",
ReadTimeout: conf.StringDuration(10 * time.Second),
Conf: cnf,
AuthManager: authManager,
AuthManager: test.NilAuthManager,
Parent: &testParent{},
}
err := api.Initialize()
@ -341,7 +359,7 @@ func TestConfigPathsGet(t *testing.T) {
hc := &http.Client{Transport: tr}
var out map[string]interface{}
httpRequest(t, hc, http.MethodGet, "http://myuser:mypass@localhost:9997/v3/config/paths/get/my/path", nil, &out)
httpRequest(t, hc, http.MethodGet, "http://localhost:9997/v3/config/paths/get/my/path", nil, &out)
require.Equal(t, "my/path", out["name"])
require.Equal(t, "myuser", out["readUser"])
}
@ -353,7 +371,7 @@ func TestConfigPathsAdd(t *testing.T) {
Address: "localhost:9997",
ReadTimeout: conf.StringDuration(10 * time.Second),
Conf: cnf,
AuthManager: authManager,
AuthManager: test.NilAuthManager,
Parent: &testParent{},
}
err := api.Initialize()
@ -364,7 +382,7 @@ func TestConfigPathsAdd(t *testing.T) {
defer tr.CloseIdleConnections()
hc := &http.Client{Transport: tr}
httpRequest(t, hc, http.MethodPost, "http://myuser:mypass@localhost:9997/v3/config/paths/add/my/path",
httpRequest(t, hc, http.MethodPost, "http://localhost:9997/v3/config/paths/add/my/path",
map[string]interface{}{
"source": "rtsp://127.0.0.1:9999/mypath",
"sourceOnDemand": true,
@ -373,7 +391,7 @@ func TestConfigPathsAdd(t *testing.T) {
}, nil)
var out map[string]interface{}
httpRequest(t, hc, http.MethodGet, "http://myuser:mypass@localhost:9997/v3/config/paths/get/my/path", nil, &out)
httpRequest(t, hc, http.MethodGet, "http://localhost:9997/v3/config/paths/get/my/path", nil, &out)
require.Equal(t, "rtsp://127.0.0.1:9999/mypath", out["source"])
require.Equal(t, true, out["sourceOnDemand"])
require.Equal(t, true, out["disablePublisherOverride"])
@ -387,7 +405,7 @@ func TestConfigPathsAddUnknownField(t *testing.T) { //nolint:dupl
Address: "localhost:9997",
ReadTimeout: conf.StringDuration(10 * time.Second),
Conf: cnf,
AuthManager: authManager,
AuthManager: test.NilAuthManager,
Parent: &testParent{},
}
err := api.Initialize()
@ -406,7 +424,7 @@ func TestConfigPathsAddUnknownField(t *testing.T) { //nolint:dupl
hc := &http.Client{Transport: tr}
req, err := http.NewRequest(http.MethodPost,
"http://myuser:mypass@localhost:9997/v3/config/paths/add/my/path", bytes.NewReader(byts))
"http://localhost:9997/v3/config/paths/add/my/path", bytes.NewReader(byts))
require.NoError(t, err)
res, err := hc.Do(req)
@ -424,7 +442,7 @@ func TestConfigPathsPatch(t *testing.T) { //nolint:dupl
Address: "localhost:9997",
ReadTimeout: conf.StringDuration(10 * time.Second),
Conf: cnf,
AuthManager: authManager,
AuthManager: test.NilAuthManager,
Parent: &testParent{},
}
err := api.Initialize()
@ -435,7 +453,7 @@ func TestConfigPathsPatch(t *testing.T) { //nolint:dupl
defer tr.CloseIdleConnections()
hc := &http.Client{Transport: tr}
httpRequest(t, hc, http.MethodPost, "http://myuser:mypass@localhost:9997/v3/config/paths/add/my/path",
httpRequest(t, hc, http.MethodPost, "http://localhost:9997/v3/config/paths/add/my/path",
map[string]interface{}{
"source": "rtsp://127.0.0.1:9999/mypath",
"sourceOnDemand": true,
@ -443,14 +461,14 @@ func TestConfigPathsPatch(t *testing.T) { //nolint:dupl
"rpiCameraVFlip": true,
}, nil)
httpRequest(t, hc, http.MethodPatch, "http://myuser:mypass@localhost:9997/v3/config/paths/patch/my/path",
httpRequest(t, hc, http.MethodPatch, "http://localhost:9997/v3/config/paths/patch/my/path",
map[string]interface{}{
"source": "rtsp://127.0.0.1:9998/mypath",
"sourceOnDemand": true,
}, nil)
var out map[string]interface{}
httpRequest(t, hc, http.MethodGet, "http://myuser:mypass@localhost:9997/v3/config/paths/get/my/path", nil, &out)
httpRequest(t, hc, http.MethodGet, "http://localhost:9997/v3/config/paths/get/my/path", nil, &out)
require.Equal(t, "rtsp://127.0.0.1:9998/mypath", out["source"])
require.Equal(t, true, out["sourceOnDemand"])
require.Equal(t, true, out["disablePublisherOverride"])
@ -464,7 +482,7 @@ func TestConfigPathsReplace(t *testing.T) { //nolint:dupl
Address: "localhost:9997",
ReadTimeout: conf.StringDuration(10 * time.Second),
Conf: cnf,
AuthManager: authManager,
AuthManager: test.NilAuthManager,
Parent: &testParent{},
}
err := api.Initialize()
@ -475,7 +493,7 @@ func TestConfigPathsReplace(t *testing.T) { //nolint:dupl
defer tr.CloseIdleConnections()
hc := &http.Client{Transport: tr}
httpRequest(t, hc, http.MethodPost, "http://myuser:mypass@localhost:9997/v3/config/paths/add/my/path",
httpRequest(t, hc, http.MethodPost, "http://localhost:9997/v3/config/paths/add/my/path",
map[string]interface{}{
"source": "rtsp://127.0.0.1:9999/mypath",
"sourceOnDemand": true,
@ -483,14 +501,14 @@ func TestConfigPathsReplace(t *testing.T) { //nolint:dupl
"rpiCameraVFlip": true,
}, nil)
httpRequest(t, hc, http.MethodPost, "http://myuser:mypass@localhost:9997/v3/config/paths/replace/my/path",
httpRequest(t, hc, http.MethodPost, "http://localhost:9997/v3/config/paths/replace/my/path",
map[string]interface{}{
"source": "rtsp://127.0.0.1:9998/mypath",
"sourceOnDemand": true,
}, nil)
var out map[string]interface{}
httpRequest(t, hc, http.MethodGet, "http://myuser:mypass@localhost:9997/v3/config/paths/get/my/path", nil, &out)
httpRequest(t, hc, http.MethodGet, "http://localhost:9997/v3/config/paths/get/my/path", nil, &out)
require.Equal(t, "rtsp://127.0.0.1:9998/mypath", out["source"])
require.Equal(t, true, out["sourceOnDemand"])
require.Equal(t, nil, out["disablePublisherOverride"])
@ -504,7 +522,7 @@ func TestConfigPathsDelete(t *testing.T) {
Address: "localhost:9997",
ReadTimeout: conf.StringDuration(10 * time.Second),
Conf: cnf,
AuthManager: authManager,
AuthManager: test.NilAuthManager,
Parent: &testParent{},
}
err := api.Initialize()
@ -515,15 +533,15 @@ func TestConfigPathsDelete(t *testing.T) {
defer tr.CloseIdleConnections()
hc := &http.Client{Transport: tr}
httpRequest(t, hc, http.MethodPost, "http://myuser:mypass@localhost:9997/v3/config/paths/add/my/path",
httpRequest(t, hc, http.MethodPost, "http://localhost:9997/v3/config/paths/add/my/path",
map[string]interface{}{
"source": "rtsp://127.0.0.1:9999/mypath",
"sourceOnDemand": true,
}, nil)
httpRequest(t, hc, http.MethodDelete, "http://myuser:mypass@localhost:9997/v3/config/paths/delete/my/path", nil, nil)
httpRequest(t, hc, http.MethodDelete, "http://localhost:9997/v3/config/paths/delete/my/path", nil, nil)
req, err := http.NewRequest(http.MethodGet, "http://myuser:mypass@localhost:9997/v3/config/paths/get/my/path", nil)
req, err := http.NewRequest(http.MethodGet, "http://localhost:9997/v3/config/paths/get/my/path", nil)
require.NoError(t, err)
res, err := hc.Do(req)
@ -548,7 +566,7 @@ func TestRecordingsList(t *testing.T) {
Address: "localhost:9997",
ReadTimeout: conf.StringDuration(10 * time.Second),
Conf: cnf,
AuthManager: authManager,
AuthManager: test.NilAuthManager,
Parent: &testParent{},
}
err = api.Initialize()
@ -575,7 +593,7 @@ func TestRecordingsList(t *testing.T) {
hc := &http.Client{Transport: tr}
var out interface{}
httpRequest(t, hc, http.MethodGet, "http://myuser:mypass@localhost:9997/v3/recordings/list", nil, &out)
httpRequest(t, hc, http.MethodGet, "http://localhost:9997/v3/recordings/list", nil, &out)
require.Equal(t, map[string]interface{}{
"itemCount": float64(2),
"pageCount": float64(1),
@ -617,7 +635,7 @@ func TestRecordingsGet(t *testing.T) {
Address: "localhost:9997",
ReadTimeout: conf.StringDuration(10 * time.Second),
Conf: cnf,
AuthManager: authManager,
AuthManager: test.NilAuthManager,
Parent: &testParent{},
}
err = api.Initialize()
@ -638,7 +656,7 @@ func TestRecordingsGet(t *testing.T) {
hc := &http.Client{Transport: tr}
var out interface{}
httpRequest(t, hc, http.MethodGet, "http://myuser:mypass@localhost:9997/v3/recordings/get/mypath1", nil, &out)
httpRequest(t, hc, http.MethodGet, "http://localhost:9997/v3/recordings/get/mypath1", nil, &out)
require.Equal(t, map[string]interface{}{
"name": "mypath1",
"segments": []interface{}{
@ -666,7 +684,7 @@ func TestRecordingsDeleteSegment(t *testing.T) {
Address: "localhost:9997",
ReadTimeout: conf.StringDuration(10 * time.Second),
Conf: cnf,
AuthManager: authManager,
AuthManager: test.NilAuthManager,
Parent: &testParent{},
}
err = api.Initialize()
@ -683,7 +701,7 @@ func TestRecordingsDeleteSegment(t *testing.T) {
defer tr.CloseIdleConnections()
hc := &http.Client{Transport: tr}
u, err := url.Parse("http://myuser:mypass@localhost:9997/v3/recordings/deletesegment")
u, err := url.Parse("http://localhost:9997/v3/recordings/deletesegment")
require.NoError(t, err)
v := url.Values{}

View file

@ -523,7 +523,7 @@ func TestAPIProtocolListGet(t *testing.T) {
c := &webrtc.WHIPClient{
HTTPClient: hc,
URL: u,
Log: test.NilLogger{},
Log: test.NilLogger,
}
_, err = c.Read(context.Background())
@ -996,7 +996,7 @@ func TestAPIProtocolKick(t *testing.T) {
c := &webrtc.WHIPClient{
HTTPClient: hc,
URL: u,
Log: test.NilLogger{},
Log: test.NilLogger,
}
_, err = c.Publish(context.Background(), medi.Formats[0], nil)

View file

@ -174,7 +174,7 @@ webrtc_sessions_bytes_sent 0
s := &webrtc.WHIPClient{
HTTPClient: hc,
URL: su,
Log: test.NilLogger{},
Log: test.NilLogger,
}
tracks, err := s.Publish(context.Background(), test.MediaH264.Formats[0], nil)

View file

@ -407,7 +407,7 @@ func TestPathRunOnRead(t *testing.T) {
c := &webrtc.WHIPClient{
HTTPClient: hc,
URL: u,
Log: test.NilLogger{},
Log: test.NilLogger,
}
writerDone := make(chan struct{})

View file

@ -32,6 +32,10 @@ func metricFloat(key string, tags string, value float64) string {
return key + tags + " " + strconv.FormatFloat(value, 'f', -1, 64) + "\n"
}
type metricsAuthManager interface {
Authenticate(req *auth.Request) error
}
type metricsParent interface {
logger.Writer
}
@ -40,7 +44,7 @@ type metricsParent interface {
type Metrics struct {
Address string
ReadTimeout conf.StringDuration
AuthManager *auth.Manager
AuthManager metricsAuthManager
Parent metricsParent
httpServer *httpp.WrappedServer
@ -100,6 +104,7 @@ func (m *Metrics) mwAuth(ctx *gin.Context) {
err := m.AuthManager.Authenticate(&auth.Request{
User: user,
Pass: pass,
Query: ctx.Request.URL.RawQuery,
IP: net.ParseIP(ctx.ClientIP()),
Action: conf.AuthActionMetrics,
})

View file

@ -216,23 +216,6 @@ func writeSegment3(t *testing.T, fpath string) {
require.NoError(t, err)
}
var authManager = &auth.Manager{
Method: conf.AuthMethodInternal,
InternalUsers: []conf.AuthInternalUser{
{
User: "myuser",
Pass: "mypass",
Permissions: []conf.AuthInternalUserPermission{
{
Action: conf.AuthActionPlayback,
Path: "mypath",
},
},
},
},
RTSPAuthMethods: nil,
}
func TestOnGet(t *testing.T) {
for _, format := range []string{"fmp4", "mp4"} {
t.Run(format, func(t *testing.T) {
@ -255,8 +238,20 @@ func TestOnGet(t *testing.T) {
RecordPath: filepath.Join(dir, "%path/%Y-%m-%d_%H-%M-%S-%f"),
},
},
AuthManager: authManager,
Parent: &test.NilLogger{},
AuthManager: &test.AuthManager{
Func: func(req *auth.Request) error {
require.Equal(t, &auth.Request{
User: "myuser",
Pass: "mypass",
IP: req.IP,
Action: "playback",
Path: "mypath",
Query: req.Query,
}, req)
return nil
},
},
Parent: test.NilLogger,
}
err = s.Initialize()
require.NoError(t, err)
@ -528,8 +523,8 @@ func TestOnGetDifferentInit(t *testing.T) {
RecordPath: filepath.Join(dir, "%path/%Y-%m-%d_%H-%M-%S-%f"),
},
},
AuthManager: authManager,
Parent: &test.NilLogger{},
AuthManager: test.NilAuthManager,
Parent: test.NilLogger,
}
err = s.Initialize()
require.NoError(t, err)
@ -603,8 +598,8 @@ func TestOnGetNTPCompensation(t *testing.T) {
RecordPath: filepath.Join(dir, "%path/%Y-%m-%d_%H-%M-%S-%f"),
},
},
AuthManager: authManager,
Parent: &test.NilLogger{},
AuthManager: test.NilAuthManager,
Parent: test.NilLogger,
}
err = s.Initialize()
require.NoError(t, err)

View file

@ -9,6 +9,7 @@ import (
"testing"
"time"
"github.com/bluenviron/mediamtx/internal/auth"
"github.com/bluenviron/mediamtx/internal/conf"
"github.com/bluenviron/mediamtx/internal/test"
"github.com/stretchr/testify/require"
@ -34,8 +35,20 @@ func TestOnList(t *testing.T) {
RecordPath: filepath.Join(dir, "%path/%Y-%m-%d_%H-%M-%S-%f"),
},
},
AuthManager: authManager,
Parent: &test.NilLogger{},
AuthManager: &test.AuthManager{
Func: func(req *auth.Request) error {
require.Equal(t, &auth.Request{
User: "myuser",
Pass: "mypass",
IP: req.IP,
Action: "playback",
Query: "path=mypath",
Path: "mypath",
}, req)
return nil
},
},
Parent: test.NilLogger,
}
err = s.Initialize()
require.NoError(t, err)
@ -92,8 +105,8 @@ func TestOnListDifferentInit(t *testing.T) {
RecordPath: filepath.Join(dir, "%path/%Y-%m-%d_%H-%M-%S-%f"),
},
},
AuthManager: authManager,
Parent: &test.NilLogger{},
AuthManager: test.NilAuthManager,
Parent: test.NilLogger,
}
err = s.Initialize()
require.NoError(t, err)

View file

@ -18,12 +18,16 @@ import (
var errNoSegmentsFound = errors.New("no recording segments found for the given timestamp")
type serverAuthManager interface {
Authenticate(req *auth.Request) error
}
// Server is the playback server.
type Server struct {
Address string
ReadTimeout conf.StringDuration
PathConfs map[string]*conf.Path
AuthManager *auth.Manager
AuthManager serverAuthManager
Parent logger.Writer
httpServer *httpp.WrappedServer
@ -101,6 +105,7 @@ func (p *Server) doAuth(ctx *gin.Context, pathName string) bool {
err := p.AuthManager.Authenticate(&auth.Request{
User: user,
Pass: pass,
Query: ctx.Request.URL.RawQuery,
IP: net.ParseIP(ctx.ClientIP()),
Action: conf.AuthActionPlayback,
Path: pathName,

View file

@ -17,6 +17,10 @@ import (
"github.com/bluenviron/mediamtx/internal/restrictnetwork"
)
type pprofAuthManager interface {
Authenticate(req *auth.Request) error
}
type pprofParent interface {
logger.Writer
}
@ -25,7 +29,7 @@ type pprofParent interface {
type PPROF struct {
Address string
ReadTimeout conf.StringDuration
AuthManager *auth.Manager
AuthManager pprofAuthManager
Parent pprofParent
httpServer *httpp.WrappedServer
@ -73,6 +77,7 @@ func (pp *PPROF) ServeHTTP(w http.ResponseWriter, r *http.Request) {
err := pp.AuthManager.Authenticate(&auth.Request{
User: user,
Pass: pass,
Query: r.URL.RawQuery,
IP: net.ParseIP(ip),
Action: conf.AuthActionMetrics,
})

View file

@ -18,7 +18,7 @@ func TestPeerConnectionCloseAfterError(t *testing.T) {
pc := &PeerConnection{
API: api,
Publish: false,
Log: test.NilLogger{},
Log: test.NilLogger,
}
err = pc.Start()
require.NoError(t, err)

View file

@ -123,7 +123,7 @@ func TestAgent(t *testing.T) {
1460,
desc,
true,
&test.NilLogger{},
test.NilLogger,
)
require.NoError(t, err)
defer stream.Close()
@ -158,7 +158,7 @@ func TestAgent(t *testing.T) {
OnSegmentComplete: func(_ string) {
segDone <- struct{}{}
},
Parent: &test.NilLogger{},
Parent: test.NilLogger,
restartPause: 1 * time.Millisecond,
}
w.Initialize()
@ -305,7 +305,7 @@ func TestAgentFMP4NegativeDTS(t *testing.T) {
1460,
desc,
true,
&test.NilLogger{},
test.NilLogger,
)
require.NoError(t, err)
defer stream.Close()
@ -324,7 +324,7 @@ func TestAgentFMP4NegativeDTS(t *testing.T) {
SegmentDuration: 1 * time.Second,
PathName: "mypath",
Stream: stream,
Parent: &test.NilLogger{},
Parent: test.NilLogger,
}
w.Initialize()

View file

@ -37,7 +37,7 @@ func TestCleaner(t *testing.T) {
Format: conf.RecordFormatFMP4,
DeleteAfter: 10 * time.Second,
}},
Parent: test.NilLogger{},
Parent: test.NilLogger,
}
c.Initialize()
defer c.Close()

View file

@ -90,7 +90,7 @@ func TestServerNotFound(t *testing.T) {
ReadTimeout: conf.StringDuration(10 * time.Second),
WriteQueueSize: 512,
PathManager: &dummyPathManager{},
Parent: &test.NilLogger{},
Parent: test.NilLogger,
}
err := s.Initialize()
require.NoError(t, err)
@ -131,7 +131,7 @@ func TestServerRead(t *testing.T) {
1460,
desc,
true,
test.NilLogger{},
test.NilLogger,
)
require.NoError(t, err)
@ -154,7 +154,7 @@ func TestServerRead(t *testing.T) {
ReadTimeout: conf.StringDuration(10 * time.Second),
WriteQueueSize: 512,
PathManager: pathManager,
Parent: &test.NilLogger{},
Parent: test.NilLogger,
}
err = s.Initialize()
require.NoError(t, err)
@ -216,7 +216,7 @@ func TestServerRead(t *testing.T) {
1460,
desc,
true,
test.NilLogger{},
test.NilLogger,
)
require.NoError(t, err)
@ -239,7 +239,7 @@ func TestServerRead(t *testing.T) {
ReadTimeout: conf.StringDuration(10 * time.Second),
WriteQueueSize: 512,
PathManager: pathManager,
Parent: &test.NilLogger{},
Parent: test.NilLogger,
}
err = s.Initialize()
require.NoError(t, err)
@ -307,7 +307,7 @@ func TestDirectory(t *testing.T) {
1460,
desc,
true,
test.NilLogger{},
test.NilLogger,
)
require.NoError(t, err)
@ -330,7 +330,7 @@ func TestDirectory(t *testing.T) {
ReadTimeout: conf.StringDuration(10 * time.Second),
WriteQueueSize: 512,
PathManager: pathManager,
Parent: &test.NilLogger{},
Parent: test.NilLogger,
}
err = s.Initialize()
require.NoError(t, err)

View file

@ -44,7 +44,7 @@ func (p *dummyPath) StartPublisher(req defs.PathStartPublisherReq) (*stream.Stre
1460,
req.Desc,
true,
test.NilLogger{},
test.NilLogger,
)
if err != nil {
return nil, err
@ -120,7 +120,7 @@ func TestServerPublish(t *testing.T) {
RunOnDisconnect: "",
ExternalCmdPool: nil,
PathManager: pathManager,
Parent: &test.NilLogger{},
Parent: test.NilLogger,
}
err := s.Initialize()
require.NoError(t, err)
@ -146,7 +146,7 @@ func TestServerPublish(t *testing.T) {
<-path.streamCreated
aw := asyncwriter.New(512, &test.NilLogger{})
aw := asyncwriter.New(512, test.NilLogger)
recv := make(chan struct{})
@ -200,7 +200,7 @@ func TestServerRead(t *testing.T) {
1460,
desc,
true,
test.NilLogger{},
test.NilLogger,
)
require.NoError(t, err)
@ -222,7 +222,7 @@ func TestServerRead(t *testing.T) {
RunOnDisconnect: "",
ExternalCmdPool: nil,
PathManager: pathManager,
Parent: &test.NilLogger{},
Parent: test.NilLogger,
}
err = s.Initialize()
require.NoError(t, err)

View file

@ -43,7 +43,7 @@ func (p *dummyPath) StartPublisher(req defs.PathStartPublisherReq) (*stream.Stre
1460,
req.Desc,
true,
test.NilLogger{},
test.NilLogger,
)
if err != nil {
return nil, err
@ -114,7 +114,7 @@ func TestServerPublish(t *testing.T) {
RunOnDisconnect: "",
ExternalCmdPool: nil,
PathManager: pathManager,
Parent: &test.NilLogger{},
Parent: test.NilLogger,
}
err := s.Initialize()
require.NoError(t, err)
@ -132,7 +132,7 @@ func TestServerPublish(t *testing.T) {
<-path.streamCreated
aw := asyncwriter.New(512, &test.NilLogger{})
aw := asyncwriter.New(512, test.NilLogger)
recv := make(chan struct{})
@ -174,7 +174,7 @@ func TestServerRead(t *testing.T) {
1460,
desc,
true,
test.NilLogger{},
test.NilLogger,
)
require.NoError(t, err)
@ -205,7 +205,7 @@ func TestServerRead(t *testing.T) {
RunOnDisconnect: "",
ExternalCmdPool: nil,
PathManager: pathManager,
Parent: &test.NilLogger{},
Parent: test.NilLogger,
}
err = s.Initialize()
require.NoError(t, err)

View file

@ -42,7 +42,7 @@ func (p *dummyPath) StartPublisher(req defs.PathStartPublisherReq) (*stream.Stre
1460,
req.Desc,
true,
test.NilLogger{},
test.NilLogger,
)
if err != nil {
return nil, err
@ -100,7 +100,7 @@ func TestServerPublish(t *testing.T) {
RunOnDisconnect: "string",
ExternalCmdPool: externalCmdPool,
PathManager: pathManager,
Parent: &test.NilLogger{},
Parent: test.NilLogger,
}
err := s.Initialize()
require.NoError(t, err)
@ -139,7 +139,7 @@ func TestServerPublish(t *testing.T) {
<-path.streamCreated
aw := asyncwriter.New(512, &test.NilLogger{})
aw := asyncwriter.New(512, test.NilLogger)
recv := make(chan struct{})
@ -179,7 +179,7 @@ func TestServerRead(t *testing.T) {
1460,
desc,
true,
test.NilLogger{},
test.NilLogger,
)
require.NoError(t, err)
@ -199,7 +199,7 @@ func TestServerRead(t *testing.T) {
RunOnDisconnect: "string",
ExternalCmdPool: externalCmdPool,
PathManager: pathManager,
Parent: &test.NilLogger{},
Parent: test.NilLogger,
}
err = s.Initialize()
require.NoError(t, err)

View file

@ -55,7 +55,7 @@ func (p *dummyPath) StartPublisher(req defs.PathStartPublisherReq) (*stream.Stre
1460,
req.Desc,
true,
test.NilLogger{},
test.NilLogger,
)
if err != nil {
return nil, err
@ -119,7 +119,7 @@ func initializeTestServer(t *testing.T) *Server {
ICEServers: []conf.WebRTCICEServer{},
ExternalCmdPool: nil,
PathManager: pathManager,
Parent: test.NilLogger{},
Parent: test.NilLogger,
}
err := s.Initialize()
require.NoError(t, err)
@ -197,7 +197,7 @@ func TestServerOptionsICEServer(t *testing.T) {
}},
ExternalCmdPool: nil,
PathManager: pathManager,
Parent: test.NilLogger{},
Parent: test.NilLogger,
}
err := s.Initialize()
require.NoError(t, err)
@ -251,7 +251,7 @@ func TestServerPublish(t *testing.T) {
ICEServers: []conf.WebRTCICEServer{},
ExternalCmdPool: nil,
PathManager: pathManager,
Parent: test.NilLogger{},
Parent: test.NilLogger,
}
err := s.Initialize()
require.NoError(t, err)
@ -267,7 +267,7 @@ func TestServerPublish(t *testing.T) {
wc := &webrtc.WHIPClient{
HTTPClient: hc,
URL: su,
Log: test.NilLogger{},
Log: test.NilLogger,
}
tracks, err := wc.Publish(context.Background(), test.FormatH264, nil)
@ -289,7 +289,7 @@ func TestServerPublish(t *testing.T) {
<-path.streamCreated
aw := asyncwriter.New(512, &test.NilLogger{})
aw := asyncwriter.New(512, test.NilLogger)
recv := make(chan struct{})
@ -336,7 +336,7 @@ func TestServerRead(t *testing.T) {
1460,
desc,
true,
test.NilLogger{},
test.NilLogger,
)
require.NoError(t, err)
@ -361,7 +361,7 @@ func TestServerRead(t *testing.T) {
ICEServers: []conf.WebRTCICEServer{},
ExternalCmdPool: nil,
PathManager: pathManager,
Parent: test.NilLogger{},
Parent: test.NilLogger,
}
err = s.Initialize()
require.NoError(t, err)
@ -377,7 +377,7 @@ func TestServerRead(t *testing.T) {
wc := &webrtc.WHIPClient{
HTTPClient: hc,
URL: u,
Log: test.NilLogger{},
Log: test.NilLogger,
}
writerDone := make(chan struct{})

View file

@ -36,7 +36,7 @@ func TestSource(t *testing.T) {
pc := &webrtc.PeerConnection{
API: api,
Publish: true,
Log: test.NilLogger{},
Log: test.NilLogger,
}
err = pc.Start()
require.NoError(t, err)

View file

@ -0,0 +1,20 @@
package test
import "github.com/bluenviron/mediamtx/internal/auth"
// AuthManager is a test auth manager.
type AuthManager struct {
Func func(req *auth.Request) error
}
// Authenticate replicates auth.Manager.Replicate
func (m *AuthManager) Authenticate(req *auth.Request) error {
return m.Func(req)
}
// NilAuthManager is an auth manager that accepts everything.
var NilAuthManager = &AuthManager{
Func: func(_ *auth.Request) error {
return nil
},
}

11
internal/test/logger.go Normal file
View file

@ -0,0 +1,11 @@
package test
import "github.com/bluenviron/mediamtx/internal/logger"
type nilLogger struct{}
func (nilLogger) Log(_ logger.Level, _ string, _ ...interface{}) {
}
// NilLogger is a logger to /dev/null
var NilLogger logger.Writer = &nilLogger{}

View file

@ -1,10 +0,0 @@
package test
import "github.com/bluenviron/mediamtx/internal/logger"
// NilLogger is a logger to /dev/null
type NilLogger struct{}
// Log implements logger.Writer.
func (NilLogger) Log(_ logger.Level, _ string, _ ...interface{}) {
}