navidrome/server/subsonic/middlewares_test.go

127 lines
3.3 KiB
Go
Raw Normal View History

package subsonic
2020-01-09 21:56:44 +01:00
import (
"context"
2020-01-09 21:56:44 +01:00
"net/http"
"net/http/httptest"
2020-01-10 03:58:03 +01:00
"strings"
2020-01-09 21:56:44 +01:00
2020-01-24 01:44:08 +01:00
"github.com/deluan/navidrome/engine"
"github.com/deluan/navidrome/log"
"github.com/deluan/navidrome/model"
2020-01-09 21:56:44 +01:00
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
2020-01-10 03:58:03 +01:00
func newTestRequest(queryParams ...string) *http.Request {
r := httptest.NewRequest("get", "/ping?"+strings.Join(queryParams, "&"), nil)
2020-01-09 21:56:44 +01:00
ctx := r.Context()
return r.WithContext(log.NewContext(ctx))
}
var _ = Describe("Middlewares", func() {
var next *mockHandler
var w *httptest.ResponseRecorder
BeforeEach(func() {
next = &mockHandler{}
w = httptest.NewRecorder()
})
Describe("CheckParams", func() {
It("passes when all required params are available", func() {
2020-01-10 03:58:03 +01:00
r := newTestRequest("u=user", "v=1.15", "c=test")
2020-01-09 21:56:44 +01:00
cp := checkRequiredParameters(next)
cp.ServeHTTP(w, r)
2020-01-21 00:12:17 +01:00
Expect(next.req.Context().Value("username")).To(Equal("user"))
2020-01-09 21:56:44 +01:00
Expect(next.req.Context().Value("version")).To(Equal("1.15"))
Expect(next.req.Context().Value("client")).To(Equal("test"))
Expect(next.called).To(BeTrue())
})
It("fails when user is missing", func() {
2020-01-10 03:58:03 +01:00
r := newTestRequest("v=1.15", "c=test")
2020-01-09 21:56:44 +01:00
cp := checkRequiredParameters(next)
cp.ServeHTTP(w, r)
Expect(w.Body.String()).To(ContainSubstring(`code="10"`))
Expect(next.called).To(BeFalse())
})
It("fails when version is missing", func() {
2020-01-10 03:58:03 +01:00
r := newTestRequest("u=user", "c=test")
2020-01-09 21:56:44 +01:00
cp := checkRequiredParameters(next)
cp.ServeHTTP(w, r)
Expect(w.Body.String()).To(ContainSubstring(`code="10"`))
Expect(next.called).To(BeFalse())
})
It("fails when client is missing", func() {
2020-01-10 03:58:03 +01:00
r := newTestRequest("u=user", "v=1.15")
2020-01-09 21:56:44 +01:00
cp := checkRequiredParameters(next)
cp.ServeHTTP(w, r)
Expect(w.Body.String()).To(ContainSubstring(`code="10"`))
Expect(next.called).To(BeFalse())
})
})
Describe("Authenticate", func() {
var mockedUser *mockUsers
2020-01-09 21:56:44 +01:00
BeforeEach(func() {
mockedUser = &mockUsers{}
2020-01-09 21:56:44 +01:00
})
It("passes all parameters to users.Authenticate ", func() {
r := newTestRequest("u=valid", "p=password", "t=token", "s=salt")
cp := authenticate(mockedUser)(next)
cp.ServeHTTP(w, r)
2020-01-09 21:56:44 +01:00
Expect(mockedUser.username).To(Equal("valid"))
Expect(mockedUser.password).To(Equal("password"))
Expect(mockedUser.token).To(Equal("token"))
Expect(mockedUser.salt).To(Equal("salt"))
Expect(next.called).To(BeTrue())
2020-01-21 00:12:17 +01:00
user := next.req.Context().Value("user").(*model.User)
Expect(user.UserName).To(Equal("valid"))
2020-01-09 21:56:44 +01:00
})
It("fails authentication with wrong password", func() {
r := newTestRequest("u=invalid", "", "", "")
cp := authenticate(mockedUser)(next)
cp.ServeHTTP(w, r)
2020-01-09 21:56:44 +01:00
Expect(w.Body.String()).To(ContainSubstring(`code="40"`))
Expect(next.called).To(BeFalse())
2020-01-09 21:56:44 +01:00
})
})
})
type mockHandler struct {
req *http.Request
called bool
}
func (mh *mockHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
mh.req = r
mh.called = true
}
type mockUsers struct {
engine.Users
username, password, token, salt string
}
func (m *mockUsers) Authenticate(ctx context.Context, username, password, token, salt string) (*model.User, error) {
m.username = username
m.password = password
m.token = token
m.salt = salt
if username == "valid" {
return &model.User{UserName: username, Password: password}, nil
}
return nil, model.ErrInvalidAuth
}