fix(cmd/api): normalise authentik spec public paths
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
bfef7237cc
commit
a07896d88e
3 changed files with 72 additions and 1 deletions
|
|
@ -29,3 +29,39 @@ func splitUniqueCSV(raw string) []string {
|
|||
|
||||
return values
|
||||
}
|
||||
|
||||
// normalisePublicPaths trims whitespace, ensures a leading slash, and removes
|
||||
// duplicate entries while preserving the first occurrence of each path.
|
||||
func normalisePublicPaths(paths []string) []string {
|
||||
if len(paths) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
out := make([]string, 0, len(paths))
|
||||
seen := make(map[string]struct{}, len(paths))
|
||||
|
||||
for _, path := range paths {
|
||||
path = strings.TrimSpace(path)
|
||||
if path == "" {
|
||||
continue
|
||||
}
|
||||
if !strings.HasPrefix(path, "/") {
|
||||
path = "/" + path
|
||||
}
|
||||
path = strings.TrimRight(path, "/")
|
||||
if path == "" {
|
||||
path = "/"
|
||||
}
|
||||
if _, ok := seen[path]; ok {
|
||||
continue
|
||||
}
|
||||
seen[path] = struct{}{}
|
||||
out = append(out, path)
|
||||
}
|
||||
|
||||
if len(out) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
|
|
|||
|
|
@ -368,6 +368,41 @@ func TestAPISpecCmd_Good_EnabledExtensionsFollowProvidedPaths(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestAPISpecCmd_Good_AuthentikPublicPathsAreNormalised(t *testing.T) {
|
||||
root := &cli.Command{Use: "root"}
|
||||
AddAPICommands(root)
|
||||
|
||||
outputFile := t.TempDir() + "/spec.json"
|
||||
root.SetArgs([]string{
|
||||
"api", "spec",
|
||||
"--authentik-public-paths", " /public/ ,docs,/public",
|
||||
"--output", outputFile,
|
||||
})
|
||||
root.SetErr(new(bytes.Buffer))
|
||||
|
||||
if err := root.Execute(); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(outputFile)
|
||||
if err != nil {
|
||||
t.Fatalf("expected spec file to be written: %v", err)
|
||||
}
|
||||
|
||||
var spec map[string]any
|
||||
if err := json.Unmarshal(data, &spec); err != nil {
|
||||
t.Fatalf("expected valid JSON spec, got error: %v", err)
|
||||
}
|
||||
|
||||
paths, ok := spec["x-authentik-public-paths"].([]any)
|
||||
if !ok {
|
||||
t.Fatalf("expected x-authentik-public-paths array, got %T", spec["x-authentik-public-paths"])
|
||||
}
|
||||
if len(paths) != 2 || paths[0] != "/public" || paths[1] != "/docs" {
|
||||
t.Fatalf("expected normalised public paths [/public /docs], got %v", paths)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAPISpecCmd_Good_ContactFlagsPopulateSpecInfo(t *testing.T) {
|
||||
root := &cli.Command{Use: "root"}
|
||||
AddAPICommands(root)
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ func newSpecBuilder(cfg specBuilderConfig) (*goapi.SpecBuilder, error) {
|
|||
AuthentikIssuer: strings.TrimSpace(cfg.authentikIssuer),
|
||||
AuthentikClientID: strings.TrimSpace(cfg.authentikClientID),
|
||||
AuthentikTrustedProxy: cfg.authentikTrustedProxy,
|
||||
AuthentikPublicPaths: splitUniqueCSV(cfg.authentikPublicPaths),
|
||||
AuthentikPublicPaths: normalisePublicPaths(splitUniqueCSV(cfg.authentikPublicPaths)),
|
||||
}
|
||||
|
||||
builder.I18nSupportedLocales = parseLocales(cfg.i18nSupportedLocales)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue