66 lines
3.1 KiB
Go
66 lines
3.1 KiB
Go
package httpapi
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"testing"
|
|
|
|
"git.pcux.cn/xuans/Scert/backend/internal/domain"
|
|
"git.pcux.cn/xuans/Scert/backend/internal/repository"
|
|
)
|
|
|
|
func TestDomainInitialDNSAccountAtomicAPI(t *testing.T) {
|
|
f := newProjectMemberAPIFixture(t)
|
|
f.server.projectDomains = f.members
|
|
f.server.repository = repository.NewSQLDomainRepository(f.db)
|
|
account, err := f.members.CreateDNSAccount(t.Context(), "primary-super-admin", domain.DNSAccount{ID: "initial-account", Name: "初始账户", ProjectID: "default", Provider: "cloudflare", CredentialRef: "secret://dns/initial"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
account, err = f.members.RecordDNSAccountVerification(t.Context(), "primary-super-admin", account.ID, account.Revision, true)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, scenario := range []struct {
|
|
name, actor, provider, challenge, accountID string
|
|
revision int64
|
|
status int
|
|
}{
|
|
{"success", "primary-super-admin", "cloudflare", "dns-01", account.ID, account.Revision, http.StatusCreated},
|
|
{"old-version", "primary-super-admin", "cloudflare", "dns-01", account.ID, 1, http.StatusConflict},
|
|
{"wrong-provider", "primary-super-admin", "route53", "dns-01", account.ID, account.Revision, http.StatusUnprocessableEntity},
|
|
{"wrong-challenge", "primary-super-admin", "cloudflare", "http-01", account.ID, account.Revision, http.StatusBadRequest},
|
|
{"no-account", "primary-super-admin", "cloudflare", "dns-01", "", 2, http.StatusBadRequest},
|
|
{"no-permission", "viewer", "cloudflare", "dns-01", account.ID, account.Revision, http.StatusForbidden},
|
|
} {
|
|
t.Run(scenario.name, func(t *testing.T) {
|
|
name := scenario.name + ".example.test"
|
|
body := fmt.Sprintf(`{"name":%q,"certificate_type":"single","challenge_type":%q,"dns_provider":%q,"dns_account_id":%q,"dns_account_revision":%d}`, name, scenario.challenge, scenario.provider, scenario.accountID, scenario.revision)
|
|
response := serveUserRequest(f.server, f.cookies[scenario.actor], http.MethodPost, "/api/v1/domains", body)
|
|
if response.Code != scenario.status {
|
|
t.Fatal("创建接口状态错误", response.Code, response.Body.String())
|
|
}
|
|
if response.Code == http.StatusCreated {
|
|
var item domain.Domain
|
|
if err := json.Unmarshal(response.Body.Bytes(), &item); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
loaded, err := repository.NewSQLDomainRepository(f.db).GetByID(t.Context(), item.ID)
|
|
if err != nil || item.DNSBindingID == "" || item.DNSBindingID != loaded.DNSBindingID || loaded.DNSAccountID != account.ID {
|
|
t.Fatal("创建响应与原子绑定不符", err)
|
|
}
|
|
response = serveUserRequest(f.server, f.cookies[scenario.actor], http.MethodPut, "/api/v1/domains/"+item.ID, body)
|
|
if response.Code != http.StatusBadRequest {
|
|
t.Fatal("普通更新不能绕过绑定令牌", response.Code)
|
|
}
|
|
} else {
|
|
var count int
|
|
if err := f.db.QueryRowContext(t.Context(), `SELECT COUNT(*) FROM domains WHERE name = ?`, name).Scan(&count); err != nil || count != 0 {
|
|
t.Fatal("失败后遗留未绑定域名", err)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|