fix(17): T-17-15 refuse an unsafe frontend_url on save and import

- Settings.BeforeValidate answers a cabana validation error on
  frontend_url, so the settings save is a 422 and the row is unchanged
- sitemap:import-winter stops on a frontend_url that
  models.AllowedFrontendURL refuses, before the dry-run branch and before
  any database use; the value is printed quoted
- errors.frontend_url phrase in en and pl
- TestSettingsBeforeValidate, TestWinterSettingsFrontendURL and the save
  and import refusals in the Postgres smokes
This commit is contained in:
Jakub Zych
2026-10-13 00:59:24 +02:00
parent b9804ddf17
commit 1bb89ce006
9 changed files with 204 additions and 8 deletions

View File

@@ -37,7 +37,8 @@ var droppedTypes = map[string]bool{
// are checked. PageURLs turns a static or CMS page item into a url item:
// its key is the item's reference (the PHP page file name, for example
// blog), its value the page's URL (/blog). Force replaces a definition that
// has items; DryRun reports without writing.
// has items; DryRun reports without writing. A frontend_url that
// models.AllowedFrontendURL refuses stops the import and nothing is written.
type WinterOptions struct {
DefinitionsFile string
SettingsFile string
@@ -71,7 +72,8 @@ type WinterReport struct {
// (signpost.ValidItemPattern) is cleared, and every dropped, remapped or
// cleared item is printed. A definition that already has items is refused
// without --force. Settings keys missing from the export take the PHP
// defaults.
// defaults. A frontend_url that models.AllowedFrontendURL refuses stops the
// import and nothing is written.
func ImportWinter(app *backpack.App) bonfire.Command {
return bonfire.Command{
Name: "sitemap:import-winter",
@@ -418,7 +420,8 @@ func describeItem(label string, item models.DefinitionItem) string {
}
// readWinterSettings reads the exported settings object onto the PHP
// defaults.
// defaults. A frontend_url that models.AllowedFrontendURL refuses is an
// error; the value is quoted so its control characters are not printed raw.
func readWinterSettings(file string, report *WinterReport) (models.Settings, error) {
raw, err := os.ReadFile(file)
if err != nil {
@@ -460,5 +463,8 @@ func readWinterSettings(file string, report *WinterReport) (models.Settings, err
}
report.Lines = append(report.Lines, fmt.Sprintf("setting '%s' ignored (not a sitemap setting of this port)", key))
}
if url := models.Text(s.FrontendURL); !models.AllowedFrontendURL(url) {
return models.Settings{}, fmt.Errorf("%s: setting frontend_url %q must be empty or an absolute http:// or https:// URL without whitespace, control characters, quotes or the characters <, > and &", file, url)
}
return s, nil
}