123 lines
3.2 KiB
Go
123 lines
3.2 KiB
Go
package accept
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.asio.asia/nixevol/NixMsg/test/harness"
|
|
"github.com/mochi-mqtt/server/v2/packets"
|
|
)
|
|
|
|
// AdminLogin 管理登录并返回带 Cookie/CSRF 的客户端。
|
|
func AdminLogin(t *testing.T, srv *harness.Server) *harness.AdminClient {
|
|
t.Helper()
|
|
ac, err := srv.AdminClient()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
loginBody, _ := json.Marshal(map[string]string{
|
|
"username": "admin",
|
|
"password": srv.AdminPassword,
|
|
})
|
|
lr, err := ac.PostJSON("/api/admin/login", loginBody)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
raw, _ := io.ReadAll(lr.Body)
|
|
_ = lr.Body.Close()
|
|
if lr.StatusCode != http.StatusOK {
|
|
t.Fatalf("admin login: %d %s", lr.StatusCode, raw)
|
|
}
|
|
return ac
|
|
}
|
|
|
|
// CreateEndpoint 用管理接口开通一端。
|
|
func CreateEndpoint(t *testing.T, ac *harness.AdminClient, id, password string) {
|
|
t.Helper()
|
|
body, _ := json.Marshal(map[string]string{
|
|
"id": id,
|
|
"login_password": password,
|
|
})
|
|
resp, err := ac.PostJSON("/api/admin/endpoints", body)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
raw, _ := io.ReadAll(resp.Body)
|
|
_ = resp.Body.Close()
|
|
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
|
|
t.Fatalf("create endpoint %s: %d %s", id, resp.StatusCode, raw)
|
|
}
|
|
}
|
|
|
|
// EnableRegistration 管理接口开启注册并设置安全码。
|
|
func EnableRegistration(t *testing.T, ac *harness.AdminClient, code string) {
|
|
t.Helper()
|
|
body := fmt.Sprintf(`{"enabled":true,"code":%q}`, code)
|
|
resp, err := ac.Do(http.MethodPut, "/api/admin/registration", []byte(body), "application/json")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
raw, _ := io.ReadAll(resp.Body)
|
|
_ = resp.Body.Close()
|
|
if resp.StatusCode != http.StatusOK {
|
|
t.Fatalf("enable registration: %d %s", resp.StatusCode, raw)
|
|
}
|
|
}
|
|
|
|
// RegisterClient 调用端注册接口。
|
|
func RegisterClient(t *testing.T, httpBase, regCode, id, password string) (status int, body string) {
|
|
t.Helper()
|
|
payload := fmt.Sprintf(`{"registration_code":%q,"id":%q,"login_password":%q}`, regCode, id, password)
|
|
code, text, err := ProbeMethod(httpBase, http.MethodPost, "/api/client/register", []byte(payload))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return code, text
|
|
}
|
|
|
|
// TryMQTTPasswordLogin 尝试密码登录;CONNACK 成功返回 true。
|
|
func TryMQTTPasswordLogin(t *testing.T, httpBase, endpointID, password string) bool {
|
|
t.Helper()
|
|
mc, err := harness.DialMQTTWebSocket(httpBase, 5*time.Second)
|
|
if err != nil {
|
|
t.Logf("dial: %v", err)
|
|
return false
|
|
}
|
|
defer func() { _ = mc.Close() }()
|
|
|
|
pk := packets.Packet{
|
|
FixedHeader: packets.FixedHeader{Type: packets.Connect},
|
|
ProtocolVersion: 5,
|
|
Connect: packets.ConnectParams{
|
|
ProtocolName: []byte("MQTT"),
|
|
Clean: true,
|
|
ClientIdentifier: endpointID,
|
|
Keepalive: 30,
|
|
UsernameFlag: true,
|
|
Username: []byte(endpointID),
|
|
PasswordFlag: true,
|
|
Password: []byte(password),
|
|
},
|
|
}
|
|
var buf bytes.Buffer
|
|
if encErr := pk.ConnectEncode(&buf); encErr != nil {
|
|
t.Fatal(encErr)
|
|
}
|
|
if sendErr := mc.Send(buf.Bytes()); sendErr != nil {
|
|
return false
|
|
}
|
|
ack, recvErr := mc.Recv()
|
|
if recvErr != nil {
|
|
return false
|
|
}
|
|
if len(ack) < 4 || ack[0]>>4 != packets.Connack {
|
|
return false
|
|
}
|
|
return ack[3] == 0
|
|
}
|