navidrome/api/middlewares_test.go

136 lines
3.4 KiB
Go

package api
import (
"net/http"
"net/http/httptest"
"strings"
"github.com/cloudsonic/sonic-server/conf"
"github.com/cloudsonic/sonic-server/log"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
func newTestRequest(queryParams ...string) *http.Request {
r := httptest.NewRequest("get", "/ping?"+strings.Join(queryParams, "&"), nil)
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() {
r := newTestRequest("u=user", "v=1.15", "c=test")
cp := checkRequiredParameters(next)
cp.ServeHTTP(w, r)
Expect(next.req.Context().Value("user")).To(Equal("user"))
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() {
r := newTestRequest("v=1.15", "c=test")
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() {
r := newTestRequest("u=user", "c=test")
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() {
r := newTestRequest("u=user", "v=1.15")
cp := checkRequiredParameters(next)
cp.ServeHTTP(w, r)
Expect(w.Body.String()).To(ContainSubstring(`code="10"`))
Expect(next.called).To(BeFalse())
})
})
Describe("Authenticate", func() {
BeforeEach(func() {
conf.Sonic.User = "admin"
conf.Sonic.Password = "wordpass"
conf.Sonic.DevDisableAuthentication = false
})
Context("Plaintext password", func() {
It("authenticates with plaintext password ", func() {
r := newTestRequest("u=admin", "p=wordpass")
cp := authenticate(next)
cp.ServeHTTP(w, r)
Expect(next.called).To(BeTrue())
})
It("fails authentication with wrong password", func() {
r := newTestRequest("u=admin", "p=INVALID")
cp := authenticate(next)
cp.ServeHTTP(w, r)
Expect(w.Body.String()).To(ContainSubstring(`code="40"`))
Expect(next.called).To(BeFalse())
})
})
Context("Encoded password", func() {
It("authenticates with simple encoded password ", func() {
r := newTestRequest("u=admin", "p=enc:776f726470617373")
cp := authenticate(next)
cp.ServeHTTP(w, r)
Expect(next.called).To(BeTrue())
})
})
Context("Token based authentication", func() {
It("authenticates with token based authentication", func() {
r := newTestRequest("u=admin", "t=23b342970e25c7928831c3317edd0b67", "s=retnlmjetrymazgkt")
cp := authenticate(next)
cp.ServeHTTP(w, r)
Expect(next.called).To(BeTrue())
})
It("fails if salt is missing", func() {
r := newTestRequest("u=admin", "t=23b342970e25c7928831c3317edd0b67")
cp := authenticate(next)
cp.ServeHTTP(w, r)
Expect(w.Body.String()).To(ContainSubstring(`code="40"`))
Expect(next.called).To(BeFalse())
})
})
})
})
type mockHandler struct {
req *http.Request
called bool
}
func (mh *mockHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
mh.req = r
mh.called = true
}