diff --git a/openflare_server/service/config_version.go b/openflare_server/service/config_version.go index 97950966..35b3c45e 100644 --- a/openflare_server/service/config_version.go +++ b/openflare_server/service/config_version.go @@ -86,6 +86,9 @@ type snapshotRoute struct { CustomHeaders []ProxyRouteCustomHeaderInput `json:"custom_headers,omitempty"` PoWEnabled bool `json:"pow_enabled,omitempty"` PoWConfig *ProxyRoutePoWConfig `json:"pow_config,omitempty"` + BasicAuthEnabled bool `json:"basic_auth_enabled,omitempty"` + BasicAuthUsername string `json:"basic_auth_username,omitempty"` + BasicAuthPassword string `json:"basic_auth_password,omitempty"` Remark string `json:"remark,omitempty"` } @@ -529,6 +532,9 @@ func buildSnapshotRoutes(routes []*model.ProxyRoute) ([]snapshotRoute, error) { CustomHeaders: customHeaders, PoWEnabled: route.PoWEnabled, PoWConfig: powConfig, + BasicAuthEnabled: route.BasicAuthEnabled, + BasicAuthUsername: route.BasicAuthUsername, + BasicAuthPassword: route.BasicAuthPassword, Remark: route.Remark, }) } @@ -644,6 +650,10 @@ func normalizeSnapshotRoutes(routes []snapshotRoute) []snapshotRoute { } else { routes[index].PoWConfig = nil } + if !routes[index].BasicAuthEnabled { + routes[index].BasicAuthUsername = "" + routes[index].BasicAuthPassword = "" + } } return routes } @@ -669,7 +679,7 @@ func flattenSnapshotRoutesByDomain(routes []snapshotRoute) map[string]snapshotRo } func snapshotRouteConfigEqual(left snapshotRoute, right snapshotRoute) bool { - if left.SiteName != right.SiteName || left.Domain != right.Domain || left.OriginURL != right.OriginURL || left.OriginHost != right.OriginHost || left.EnableHTTPS != right.EnableHTTPS || left.RedirectHTTP != right.RedirectHTTP || left.LimitConnPerServer != right.LimitConnPerServer || left.LimitConnPerIP != right.LimitConnPerIP || left.LimitRate != right.LimitRate || left.CacheEnabled != right.CacheEnabled || left.CachePolicy != right.CachePolicy || left.PoWEnabled != right.PoWEnabled || !uintSliceEqual(left.CertIDs, right.CertIDs) || !uintSliceEqual(left.DomainCertIDs, right.DomainCertIDs) { + if left.SiteName != right.SiteName || left.Domain != right.Domain || left.OriginURL != right.OriginURL || left.OriginHost != right.OriginHost || left.EnableHTTPS != right.EnableHTTPS || left.RedirectHTTP != right.RedirectHTTP || left.LimitConnPerServer != right.LimitConnPerServer || left.LimitConnPerIP != right.LimitConnPerIP || left.LimitRate != right.LimitRate || left.CacheEnabled != right.CacheEnabled || left.CachePolicy != right.CachePolicy || left.PoWEnabled != right.PoWEnabled || left.BasicAuthEnabled != right.BasicAuthEnabled || left.BasicAuthUsername != right.BasicAuthUsername || left.BasicAuthPassword != right.BasicAuthPassword || !uintSliceEqual(left.CertIDs, right.CertIDs) || !uintSliceEqual(left.DomainCertIDs, right.DomainCertIDs) { return false } if len(left.Domains) != len(right.Domains) { diff --git a/openflare_server/service/https_phase1_test.go b/openflare_server/service/https_phase1_test.go index 798836fc..7f02c5e2 100644 --- a/openflare_server/service/https_phase1_test.go +++ b/openflare_server/service/https_phase1_test.go @@ -1072,6 +1072,54 @@ func TestPublishConfigVersionRendersBasicAuthWithPoW(t *testing.T) { if !strings.Contains(result.Version.RenderedConfig, "proxy_pass http://backend_xbot_example_com_1;") { t.Fatal("expected proxy_pass to stay in the root location after basic auth") } + if !strings.Contains(result.Version.SnapshotJSON, `"basic_auth_enabled":true`) { + t.Fatal("expected snapshot to include basic auth enabled state") + } + if !strings.Contains(result.Version.SnapshotJSON, `"basic_auth_username":"admin"`) { + t.Fatal("expected snapshot to include basic auth username") + } + if !strings.Contains(result.Version.SnapshotJSON, `"basic_auth_password":"123"`) { + t.Fatal("expected snapshot to include basic auth password") + } +} + +func TestDiffConfigVersionDetectsBasicAuthChanges(t *testing.T) { + setupServiceTestDB(t) + + route, err := CreateProxyRoute(ProxyRouteInput{ + Domain: "auth.example.com", + OriginURL: "http://c1:8080", + Enabled: true, + }) + if err != nil { + t.Fatalf("CreateProxyRoute failed: %v", err) + } + if _, err = PublishConfigVersion("root", false); err != nil { + t.Fatalf("initial PublishConfigVersion failed: %v", err) + } + + _, err = UpdateProxyRoute(route.ID, ProxyRouteInput{ + Domain: route.Domain, + OriginURL: route.OriginURL, + Enabled: true, + BasicAuthEnabled: true, + BasicAuthUsername: "admin", + BasicAuthPassword: "123", + }) + if err != nil { + t.Fatalf("UpdateProxyRoute failed: %v", err) + } + + diff, err := DiffConfigVersion() + if err != nil { + t.Fatalf("DiffConfigVersion failed: %v", err) + } + if len(diff.ModifiedDomains) != 1 || diff.ModifiedDomains[0] != "auth.example.com" { + t.Fatalf("expected basic auth change to mark domain as modified, got %#v", diff.ModifiedDomains) + } + if len(diff.ModifiedSites) != 1 || diff.ModifiedSites[0] != "auth.example.com" { + t.Fatalf("expected basic auth change to mark site as modified, got %#v", diff.ModifiedSites) + } } func TestRenderConfigUsesDefaultServerFallback(t *testing.T) {