103 lines
4.0 KiB
Go
103 lines
4.0 KiB
Go
package main
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"cmautobuy/admin/model"
|
|
"cmautobuy/admin/repository"
|
|
"cmautobuy/admin/service"
|
|
)
|
|
|
|
func Test客户端归属页面与管理员写权限(t *testing.T) {
|
|
db, err := repository.Open(t.TempDir())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer db.Close()
|
|
if err := repository.Migrate(db); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
now := time.Now()
|
|
if err := service.SetupInitialAdmin(db, "admin", "admin-password", "admin-password", now); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
admin, _ := repository.FindUserByUsername(db, "admin")
|
|
for _, name := range []string{"buyer-a", "buyer-b"} {
|
|
if err := service.CreatePurchaser(db, admin, name, "buyer-password", "buyer-password", now); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
buyerA, _ := repository.FindUserByUsername(db, "buyer-a")
|
|
for _, client := range []model.Client{
|
|
{ClientID: "client-a", Name: "采购一号机"},
|
|
{ClientID: "client-free", Name: "未绑定机器"},
|
|
} {
|
|
if err := service.RegisterClient(db, client, true); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
router, err := newRouter(db)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
adminToken, _, _, _ := service.Login(db, "admin", "admin-password", now)
|
|
adminPageRequest := httptest.NewRequest(http.MethodGet, "/clients", nil)
|
|
adminPageRequest.AddCookie(&http.Cookie{Name: "cmautobuy_session", Value: adminToken})
|
|
adminPage := httptest.NewRecorder()
|
|
router.ServeHTTP(adminPage, adminPageRequest)
|
|
if adminPage.Code != http.StatusOK {
|
|
t.Fatalf("管理员客户端页 = %d: %s", adminPage.Code, adminPage.Body.String())
|
|
}
|
|
for _, want := range []string{"当前负责人", "绑定", "buyer-a", "buyer-b", "/clients/delete"} {
|
|
if !strings.Contains(adminPage.Body.String(), want) {
|
|
t.Errorf("管理员客户端页缺少 %q", want)
|
|
}
|
|
}
|
|
csrf := findResponseCookie(t, adminPage, "cmautobuy_csrf")
|
|
assign := postFormRequest("/clients/assign", url.Values{
|
|
"csrf_token": {csrf.Value}, "client_id": {"client-a"}, "user_id": {buyerA.UserID},
|
|
}, csrf)
|
|
assign.AddCookie(&http.Cookie{Name: "cmautobuy_session", Value: adminToken})
|
|
assignResponse := httptest.NewRecorder()
|
|
router.ServeHTTP(assignResponse, assign)
|
|
if assignResponse.Code != http.StatusSeeOther || !strings.HasPrefix(assignResponse.Header().Get("Location"), "/clients?") {
|
|
t.Fatalf("管理员绑定响应 = %d %s", assignResponse.Code, assignResponse.Header().Get("Location"))
|
|
}
|
|
|
|
buyerToken, _, _, _ := service.Login(db, "buyer-a", "buyer-password", now)
|
|
buyerPageRequest := httptest.NewRequest(http.MethodGet, "/clients", nil)
|
|
buyerPageRequest.AddCookie(&http.Cookie{Name: "cmautobuy_session", Value: buyerToken})
|
|
buyerPage := httptest.NewRecorder()
|
|
router.ServeHTTP(buyerPage, buyerPageRequest)
|
|
body := buyerPage.Body.String()
|
|
if buyerPage.Code != http.StatusOK || !strings.Contains(body, "采购一号机") ||
|
|
strings.Contains(body, "未绑定机器") {
|
|
t.Fatalf("采购员客户端可见范围不正确: %d %s", buyerPage.Code, body)
|
|
}
|
|
for _, forbidden := range []string{"/clients/assign", "/clients/unassign", "/clients/delete", "转交"} {
|
|
if strings.Contains(body, forbidden) {
|
|
t.Errorf("采购员只读页面不应包含 %q", forbidden)
|
|
}
|
|
}
|
|
|
|
buyerCSRF := findResponseCookie(t, buyerPage, "cmautobuy_csrf")
|
|
forbiddenAssign := postFormRequest("/clients/assign", url.Values{
|
|
"csrf_token": {buyerCSRF.Value}, "client_id": {"client-free"}, "user_id": {buyerA.UserID},
|
|
}, buyerCSRF)
|
|
forbiddenAssign.AddCookie(&http.Cookie{Name: "cmautobuy_session", Value: buyerToken})
|
|
forbiddenResponse := httptest.NewRecorder()
|
|
router.ServeHTTP(forbiddenResponse, forbiddenAssign)
|
|
if forbiddenResponse.Code != http.StatusForbidden || !strings.Contains(forbiddenResponse.Body.String(), "只有管理员") {
|
|
t.Fatalf("采购员绑定应返回 403,实际 %d %s", forbiddenResponse.Code, forbiddenResponse.Body.String())
|
|
}
|
|
rows, err := service.ListClientViewsForUser(db, buyerA, "", time.Minute)
|
|
if err != nil || len(rows) != 1 || rows[0].ClientID != "client-a" {
|
|
t.Fatalf("越权请求后归属不应变化,rows=%+v err=%v", rows, err)
|
|
}
|
|
}
|