初始化蓝鸟文件快递柜源码与部署文档
This commit is contained in:
commit
5643d22242
70 files changed
+18669
No files matched your search
@@ -0,0 +1,175 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func adminResult(t *testing.T, c *testClient, path string) adminListResult {
|
||||
t.Helper()
|
||||
w := c.request(t, "GET", path, nil)
|
||||
expect(t, w, 200)
|
||||
var p adminListResult
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if p.Items == nil {
|
||||
t.Fatal("items must be an array, including when empty")
|
||||
}
|
||||
return p
|
||||
}
|
||||
func TestAdminParcelPaginationAndSearch(t *testing.T) {
|
||||
c := fixture(t, false)
|
||||
expect(t, c.request(t, "GET", "/admin/parcels?page_size=10", nil), 401)
|
||||
loginTestAdmin(t, c)
|
||||
tx, err := c.a.db.Begin()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer tx.Rollback()
|
||||
for i := 1; i <= 25; i++ {
|
||||
id := fmt.Sprintf("%032x", i)
|
||||
state := "ready"
|
||||
if i%2 == 0 {
|
||||
state = "revoked"
|
||||
}
|
||||
_, err = tx.Exec("INSERT INTO parcels(id,visitor,ip,state,created,password_hash,manage_hash,days,downloads,renewal_days,renewal_mode,lifetime_days,upload_expires,usage_day) VALUES(?,?,'203.0.113.1',?,1000,'','',1,1,0,'add',30,2000,'2026-10-05')", id, "visitor", state)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
name := fmt.Sprintf("document-%d.txt", i)
|
||||
if i == 5 {
|
||||
name = "说明_%_Report.txt"
|
||||
}
|
||||
_, err = tx.Exec("INSERT INTO files(id,parcel,name,size,status,reserved,remaining) VALUES(?,?,?,12,'deleted',0,0)", id, id, name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
if err = tx.Commit(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
first := adminResult(t, c, "/admin/parcels")
|
||||
if first.Total != 25 || first.PageSize != 10 || first.Pages != 3 || len(first.Items) != 10 || first.Items[0]["id"] != fmt.Sprintf("%032x", 25) {
|
||||
t.Fatalf("bad first page: %+v", first)
|
||||
}
|
||||
second := adminResult(t, c, "/admin/parcels?page=2")
|
||||
if second.Page != 2 || second.Items[0]["id"] != fmt.Sprintf("%032x", 15) {
|
||||
t.Fatalf("bad second page: %+v", second)
|
||||
}
|
||||
last := adminResult(t, c, "/admin/parcels?page=999999999")
|
||||
if last.Page != 3 || len(last.Items) != 5 {
|
||||
t.Fatalf("out-of-range page was not clamped: %+v", last)
|
||||
}
|
||||
for _, q := range []string{"REPORT", "说明", "%", fmt.Sprintf("%032x", 5)} {
|
||||
p := adminResult(t, c, "/admin/parcels?q="+url.QueryEscape(q))
|
||||
if p.Total != 1 || p.Items[0]["id"] != fmt.Sprintf("%032x", 5) {
|
||||
t.Fatalf("literal filename/ID query %q: %+v", q, p)
|
||||
}
|
||||
}
|
||||
p := adminResult(t, c, "/admin/parcels?state=revoked&page_size=20")
|
||||
if p.Total != 12 || p.PageSize != 20 || len(p.Items) != 12 {
|
||||
t.Fatalf("state filter: %+v", p)
|
||||
}
|
||||
p = adminResult(t, c, "/admin/parcels?q="+url.QueryEscape("' OR 1=1 --"))
|
||||
if p.Total != 0 || len(p.Items) != 0 || p.Page != 1 || p.Pages != 1 {
|
||||
t.Fatalf("empty/literal injection query: %+v", p)
|
||||
}
|
||||
for _, q := range []string{"page=0", "page=-1", "page=oops", "page_size=0", "page_size=101", "page_size=oops", "state=unknown", "q=" + strings.Repeat("a", 257)} {
|
||||
expect(t, c.request(t, "GET", "/admin/parcels?"+q, nil), 400)
|
||||
}
|
||||
}
|
||||
func TestAdminAuditPaginationAndCombinedFilters(t *testing.T) {
|
||||
c := fixture(t, false)
|
||||
expect(t, c.request(t, "GET", "/admin/audit", nil), 401)
|
||||
loginTestAdmin(t, c)
|
||||
if _, err := c.a.db.Exec("DELETE FROM audit"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
base := c.a.now().Unix()
|
||||
tx, err := c.a.db.Begin()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer tx.Rollback()
|
||||
for i := 1; i <= 54; i++ {
|
||||
action := "upload.create"
|
||||
if i%2 == 0 {
|
||||
action = "admin.delete"
|
||||
}
|
||||
source := "2001:db8::1"
|
||||
if i%3 == 0 {
|
||||
source = "203.0.113.1"
|
||||
}
|
||||
target := fmt.Sprintf("job-%d", i)
|
||||
if i == 18 {
|
||||
target = "job_%_18"
|
||||
}
|
||||
if _, err = tx.Exec("INSERT INTO audit(created,action,target,source) VALUES(?,?,?,?)", base+int64(i)*60, action, target, source); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
if err = tx.Commit(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
p := adminResult(t, c, "/admin/audit")
|
||||
if p.Total != 54 || p.PageSize != 20 || p.Pages != 3 || len(p.Items) != 20 || p.Items[0]["target"] != "job-54" {
|
||||
t.Fatalf("bad audit page: %+v", p)
|
||||
}
|
||||
p2 := adminResult(t, c, "/admin/audit?page=2")
|
||||
if p2.Items[0]["target"] != "job-34" {
|
||||
t.Fatalf("audit page did not change: %+v", p2)
|
||||
}
|
||||
last := adminResult(t, c, "/admin/audit?page=99999")
|
||||
if last.Page != 3 || len(last.Items) != 14 {
|
||||
t.Fatalf("bad audit last page: %+v", last)
|
||||
}
|
||||
query := fmt.Sprintf("/admin/audit?action=admin.delete&source=203.0.113.1&target=JOB&from=%d&to=%d", base+10*60, base+30*60)
|
||||
filtered := adminResult(t, c, query)
|
||||
if filtered.Total != 4 || len(filtered.Items) != 4 {
|
||||
t.Fatalf("combined/inclusive date filters: %+v", filtered)
|
||||
}
|
||||
for _, item := range filtered.Items {
|
||||
if item["action"] != "admin.delete" || item["source"] != "203.0.113.1" {
|
||||
t.Fatalf("wrong filter result: %+v", item)
|
||||
}
|
||||
}
|
||||
literal := adminResult(t, c, "/admin/audit?target=%25")
|
||||
if literal.Total != 1 || literal.Items[0]["target"] != "job_%_18" {
|
||||
t.Fatalf("wildcard interpreted as pattern: %+v", literal)
|
||||
}
|
||||
ipv6 := adminResult(t, c, "/admin/audit?source=2001%3ADB8")
|
||||
if ipv6.Total != 36 {
|
||||
t.Fatalf("IPv6 fragment filter: %+v", ipv6)
|
||||
}
|
||||
empty := adminResult(t, c, "/admin/audit?action=unknown")
|
||||
if empty.Total != 0 || empty.Pages != 1 || len(empty.Items) != 0 {
|
||||
t.Fatal("empty audit search malformed")
|
||||
}
|
||||
for _, q := range []string{"page=0", "page_size=101", "from=-1", "from=nope", "to=1.5", "from=20&to=10", "action=" + strings.Repeat("a", 65), "source=" + strings.Repeat("a", 129), "target=" + strings.Repeat("a", 257)} {
|
||||
expect(t, c.request(t, "GET", "/admin/audit?"+q, nil), 400)
|
||||
}
|
||||
}
|
||||
func TestAdminAuditOneHundredThousandRecordsRemainPaged(t *testing.T) {
|
||||
c := fixture(t, false)
|
||||
loginTestAdmin(t, c)
|
||||
_, err := c.a.db.Exec("DELETE FROM audit; WITH RECURSIVE n(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM n WHERE i<100000) INSERT INTO audit(created,action,target,source) SELECT 1000,'upload.create',printf('target-%d',i),'203.0.113.1' FROM n")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
first := adminResult(t, c, "/admin/audit")
|
||||
if first.Total != 100000 || first.Pages != 5000 || len(first.Items) != 20 || first.Items[0]["target"] != "target-100000" {
|
||||
t.Fatalf("large audit query unbounded: %+v", first)
|
||||
}
|
||||
last := adminResult(t, c, "/admin/audit?page=5000")
|
||||
if last.Page != 5000 || len(last.Items) != 20 || last.Items[19]["target"] != "target-1" {
|
||||
t.Fatalf("large audit final page incorrect: %+v", last)
|
||||
}
|
||||
filtered := adminResult(t, c, "/admin/audit?target=target-12345")
|
||||
if filtered.Total != 1 || len(filtered.Items) != 1 || filtered.Items[0]["target"] != "target-12345" {
|
||||
t.Fatal("search did not include older/all retained audit events")
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user