mirror of
https://github.com/Buriburizaem0n/nezha_domains.git
synced 2026-09-19 09:40:12 +00:00
test: cover multi-user permission boundaries
Co-authored-by: naiba/CloudCode <hi+cloudcode@nai.ba>
This commit is contained in:
@@ -1,11 +1,49 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"slices"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func TestCommonHasPermission(t *testing.T) {
|
||||
resource := &Common{ID: 10, UserID: 100}
|
||||
|
||||
t.Run("unauthenticated denied", func(t *testing.T) {
|
||||
ctx, _ := gin.CreateTestContext(httptest.NewRecorder())
|
||||
if resource.HasPermission(ctx) {
|
||||
t.Fatal("expected unauthenticated request to be denied")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("owner allowed", func(t *testing.T) {
|
||||
ctx, _ := gin.CreateTestContext(httptest.NewRecorder())
|
||||
ctx.Set(CtxKeyAuthorizedUser, &User{Common: Common{ID: 100}, Role: RoleMember})
|
||||
if !resource.HasPermission(ctx) {
|
||||
t.Fatal("expected owner to be allowed")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("foreign member denied", func(t *testing.T) {
|
||||
ctx, _ := gin.CreateTestContext(httptest.NewRecorder())
|
||||
ctx.Set(CtxKeyAuthorizedUser, &User{Common: Common{ID: 200}, Role: RoleMember})
|
||||
if resource.HasPermission(ctx) {
|
||||
t.Fatal("expected non-owner member to be denied")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("admin allowed", func(t *testing.T) {
|
||||
ctx, _ := gin.CreateTestContext(httptest.NewRecorder())
|
||||
ctx.Set(CtxKeyAuthorizedUser, &User{Common: Common{ID: 1}, Role: RoleAdmin})
|
||||
if !resource.HasPermission(ctx) {
|
||||
t.Fatal("expected admin to be allowed")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestSearchByID(t *testing.T) {
|
||||
t.Run("WithoutPriorityList", func(t *testing.T) {
|
||||
list, exp := []*DDNSProfile{
|
||||
|
||||
+72
-12
@@ -273,24 +273,69 @@ func TestNotificationSendRejectsLoopbackTarget(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotificationTargetRejectsSpecialUseAddresses(t *testing.T) {
|
||||
func TestNotificationTargetRejectsBlockedRanges(t *testing.T) {
|
||||
cases := []string{
|
||||
"http://100.64.0.1/", // CGNAT
|
||||
"http://192.0.2.1/", // documentation range
|
||||
"http://[fc00::1]/", // IPv6 unique local
|
||||
"http://[2001:db8::1]/", // IPv6 documentation range
|
||||
"http://[::ffff:127.0.0.1]/", // IPv4-mapped loopback
|
||||
"http://0.0.0.0/",
|
||||
"http://10.1.2.3/",
|
||||
"http://100.64.0.1/",
|
||||
"http://127.0.0.1/",
|
||||
"http://127.255.255.254/",
|
||||
"http://169.254.169.254/",
|
||||
"http://172.16.0.1/",
|
||||
"http://192.0.0.1/",
|
||||
"http://192.0.2.1/",
|
||||
"http://192.168.1.1/",
|
||||
"http://198.18.0.1/",
|
||||
"http://198.51.100.1/",
|
||||
"http://203.0.113.1/",
|
||||
"http://224.0.0.1/",
|
||||
"http://240.0.0.1/",
|
||||
"http://[::]/",
|
||||
"http://[::1]/",
|
||||
"http://[::ffff:127.0.0.1]/",
|
||||
"http://[64:ff9b::1]/",
|
||||
"http://[100::1]/",
|
||||
"http://[2001:0:0:0:0:0:0:1]/",
|
||||
"http://[2001:db8::1]/",
|
||||
"http://[fc00::1]/",
|
||||
"http://[fe80::1]/",
|
||||
"http://[ff00::1]/",
|
||||
"ftp://example.com/",
|
||||
"file:///etc/passwd",
|
||||
"http:///path",
|
||||
}
|
||||
|
||||
for _, rawURL := range cases {
|
||||
if _, _, err := resolveNotificationTarget(rawURL); err == nil {
|
||||
t.Fatalf("expected %s to be rejected", rawURL)
|
||||
}
|
||||
t.Run(rawURL, func(t *testing.T) {
|
||||
if _, _, err := resolveNotificationTarget(rawURL); err == nil {
|
||||
t.Fatalf("expected %s to be rejected", rawURL)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotificationTargetAllowsPublicAddresses(t *testing.T) {
|
||||
cases := []string{
|
||||
"http://1.1.1.1/path",
|
||||
"https://8.8.8.8/",
|
||||
"https://[2606:4700:4700::1111]/",
|
||||
}
|
||||
|
||||
for _, rawURL := range cases {
|
||||
t.Run(rawURL, func(t *testing.T) {
|
||||
parsedURL, _, err := resolveNotificationTarget(rawURL)
|
||||
if err != nil {
|
||||
t.Fatalf("expected %s to be allowed, got %v", rawURL, err)
|
||||
}
|
||||
if parsedURL == nil {
|
||||
t.Fatalf("expected parsed url for %s", rawURL)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotificationHTTPClientPreservesTLSServerName(t *testing.T) {
|
||||
client, err := newNotificationHTTPClient("https://example.com/webhook", true)
|
||||
client, err := newNotificationHTTPClient("https://1.1.1.1/webhook", true)
|
||||
if err != nil {
|
||||
t.Fatalf("expected public HTTPS URL to create client: %v", err)
|
||||
}
|
||||
@@ -298,7 +343,22 @@ func TestNotificationHTTPClientPreservesTLSServerName(t *testing.T) {
|
||||
if !ok {
|
||||
t.Fatalf("expected http.Transport, got %T", client.Transport)
|
||||
}
|
||||
if transport.TLSClientConfig == nil || transport.TLSClientConfig.ServerName != "example.com" {
|
||||
t.Fatalf("expected TLS ServerName example.com, got %#v", transport.TLSClientConfig)
|
||||
if transport.TLSClientConfig == nil || transport.TLSClientConfig.ServerName != "1.1.1.1" {
|
||||
t.Fatalf("expected TLS ServerName 1.1.1.1, got %#v", transport.TLSClientConfig)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotificationHTTPClientRejectsRedirects(t *testing.T) {
|
||||
client, err := newNotificationHTTPClient("https://1.1.1.1/webhook", true)
|
||||
if err != nil {
|
||||
t.Fatalf("expected client construction: %v", err)
|
||||
}
|
||||
req, err := http.NewRequest(http.MethodGet, "https://1.1.1.1/start", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("new request: %v", err)
|
||||
}
|
||||
via := []*http.Request{req}
|
||||
if err := client.CheckRedirect(req, via); err != http.ErrUseLastResponse {
|
||||
t.Fatalf("expected ErrUseLastResponse, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user