feat: add protected public web lyrics workflow
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"testing/fstest"
|
||||
)
|
||||
|
||||
func newTestPublicApp(t *testing.T, downloads string) (*publicApp, http.Handler) {
|
||||
t.Helper()
|
||||
web := fstest.MapFS{
|
||||
"app.html": &fstest.MapFile{Data: []byte("public app")},
|
||||
"app.js": &fstest.MapFile{Data: []byte("js")},
|
||||
"styles.css": &fstest.MapFile{Data: []byte("css")},
|
||||
}
|
||||
app, err := newPublicApp("https://lrc.flechazo.xin", downloads, web, fakeQQ{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return app, app.routes()
|
||||
}
|
||||
|
||||
func publicRequest(method, path, body string) *http.Request {
|
||||
request := httptest.NewRequest(method, "https://lrc.flechazo.xin"+path, strings.NewReader(body))
|
||||
request.Header.Set("Origin", "https://lrc.flechazo.xin")
|
||||
request.Header.Set("Content-Type", "application/json")
|
||||
request.Header.Set("X-Real-IP", "203.0.113.7")
|
||||
return request
|
||||
}
|
||||
|
||||
func TestPublicPageNeedsNoSession(t *testing.T) {
|
||||
_, handler := newTestPublicApp(t, "")
|
||||
w := httptest.NewRecorder()
|
||||
handler.ServeHTTP(w, publicRequest(http.MethodGet, "/", ""))
|
||||
if w.Code != http.StatusOK || w.Body.String() != "public app" {
|
||||
t.Fatalf("status=%d body=%q", w.Code, w.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestPublicAPIRejectsWrongOrigin(t *testing.T) {
|
||||
_, handler := newTestPublicApp(t, "")
|
||||
request := publicRequest(http.MethodPost, "/api/search", `{"keyword":"test","limit":2}`)
|
||||
request.Header.Set("Origin", "https://attacker.example")
|
||||
w := httptest.NewRecorder()
|
||||
handler.ServeHTTP(w, request)
|
||||
if w.Code != http.StatusForbidden {
|
||||
t.Fatalf("expected 403, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPublicSearchWorksWithoutCookie(t *testing.T) {
|
||||
_, handler := newTestPublicApp(t, "")
|
||||
w := httptest.NewRecorder()
|
||||
handler.ServeHTTP(w, publicRequest(http.MethodPost, "/api/search", `{"keyword":"测试","limit":2}`))
|
||||
if w.Code != http.StatusOK || !strings.Contains(w.Body.String(), "测试") {
|
||||
t.Fatalf("status=%d body=%s", w.Code, w.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestPublicPerClientRateLimit(t *testing.T) {
|
||||
_, handler := newTestPublicApp(t, "")
|
||||
for attempt := 1; attempt <= publicClientLimit+1; attempt++ {
|
||||
w := httptest.NewRecorder()
|
||||
handler.ServeHTTP(w, publicRequest(http.MethodPost, "/api/search", `{"keyword":"test","limit":1}`))
|
||||
if attempt <= publicClientLimit && w.Code != http.StatusOK {
|
||||
t.Fatalf("attempt %d unexpectedly returned %d", attempt, w.Code)
|
||||
}
|
||||
if attempt == publicClientLimit+1 && w.Code != http.StatusTooManyRequests {
|
||||
t.Fatalf("expected final attempt to return 429, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPublicDownloadWhitelistAndRange(t *testing.T) {
|
||||
directory := t.TempDir()
|
||||
name := "lrc-local-windows-amd64.exe"
|
||||
if err := os.WriteFile(filepath.Join(directory, name), []byte("0123456789"), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, handler := newTestPublicApp(t, directory)
|
||||
request := publicRequest(http.MethodGet, "/download/"+name, "")
|
||||
request.Header.Set("Range", "bytes=2-5")
|
||||
w := httptest.NewRecorder()
|
||||
handler.ServeHTTP(w, request)
|
||||
if w.Code != http.StatusPartialContent || w.Body.String() != "2345" {
|
||||
t.Fatalf("status=%d body=%q", w.Code, w.Body.String())
|
||||
}
|
||||
if !strings.Contains(w.Header().Get("Content-Disposition"), name) {
|
||||
t.Fatal("download disposition is missing")
|
||||
}
|
||||
|
||||
w = httptest.NewRecorder()
|
||||
handler.ServeHTTP(w, publicRequest(http.MethodGet, "/download/not-allowed", ""))
|
||||
if w.Code != http.StatusNotFound {
|
||||
t.Fatalf("unexpected non-whitelist status %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPublicOriginConfigurationMustUseHTTPS(t *testing.T) {
|
||||
_, err := newPublicApp("http://lrc.flechazo.xin", "", fstest.MapFS{}, fakeQQ{})
|
||||
if err == nil {
|
||||
t.Fatal("expected insecure public origin to be rejected")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user