diff --git a/docs/changelog.md b/docs/changelog.md index 912518d4..e38b81d3 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -15,11 +15,12 @@ pages](https://github.com/dalibo/ldap2pg/pulls?utf8=%E2%9C%93&q=is%3Apr%20is%3Am - Fix memory usage value. - Experimental GSSAPI authentication method. -- Run CI on rockylinux 10 with PostgreSQL19 beta1 -- Bump PostgreSQL developpement version to 18 +- Run CI on rockylinux 10 with PostgreSQL19 beta1. +- Bump PostgreSQL developpement version to 18. - Fix duplicate CREATE ROLE. - Resolve ~ in path. - Fix empty filter in configuration file leading to panic. +- Strict yaml configuration file decoding. # ldap2pg 6.5.1 diff --git a/internal/cmd/ldap2pg.go b/internal/cmd/ldap2pg.go index e6b3ed4d..d91e4a1a 100644 --- a/internal/cmd/ldap2pg.go +++ b/internal/cmd/ldap2pg.go @@ -40,11 +40,8 @@ func Main() { } if err != nil { - if errs, ok := err.(interface{ Len() int }); ok { - // Assume error are already logged before. - slog.Error("Some errors occurred. See above for more details.", "err", err, "count", errs.Len()) - } else { - slog.Error("Fatal error.", "err", err) + for _, werr := range errorlist.Unwrap(err) { + slog.Error(werr.Error()) } if internal.CurrentLevel > slog.LevelDebug { slog.Error("Run ldap2pg with --verbose to get more informations.") diff --git a/internal/config/yaml.go b/internal/config/yaml.go index d6bd12b7..b12843fc 100644 --- a/internal/config/yaml.go +++ b/internal/config/yaml.go @@ -8,7 +8,9 @@ import ( "log/slog" "os" "reflect" + "strings" + "github.com/dalibo/ldap2pg/v6/internal/errorlist" "github.com/dalibo/ldap2pg/v6/internal/ldap" "github.com/dalibo/ldap2pg/v6/internal/postgres" "github.com/dalibo/ldap2pg/v6/internal/pyfmt" @@ -83,11 +85,24 @@ func (c *Config) DecodeYaml(yaml any) (err error) { Metadata: &mapstructure.Metadata{}, Result: c, WeaklyTypedInput: true, + ErrorUnused: true, }) if err != nil { return } err = d.Decode(yaml) + + // Converting joined error into errorlist. + // Lower the error message to align it with the LDAP parameters. + yamlErrors := errorlist.New("invalid configuration file") + for _, werr := range errorlist.Unwrap(err) { + lowerErr := strings.ToLower(werr.Error()) + if !yamlErrors.Append(fmt.Errorf("%s", lowerErr)) { + err = yamlErrors.Value() + return + } + } + err = yamlErrors.Value() return } diff --git a/internal/config/yaml_test.go b/internal/config/yaml_test.go index 97a15acc..fa79ca36 100644 --- a/internal/config/yaml_test.go +++ b/internal/config/yaml_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/dalibo/ldap2pg/v6/internal/config" + "github.com/dalibo/ldap2pg/v6/internal/errorlist" "github.com/lithammer/dedent" "github.com/stretchr/testify/require" "gopkg.in/yaml.v3" @@ -31,3 +32,26 @@ func TestLoadPrivilege(t *testing.T) { r.Equal("CONNECT", p[0].Type) r.Equal("DATABASE", p[0].On) } + +func TestStrictYaml(t *testing.T) { + r := require.New(t) + + rawYaml := dedent.Dedent(` + postgres: + uri: "postgres://user:xx@localhost" + roles_blacklist_query: [postgres] + databases_query: [nominal] + ldap: + password: "secret" + `) + var value map[string]any + yaml.Unmarshal([]byte(rawYaml), &value) //nolint:errcheck + + c := config.New() + err := c.DecodeYaml(value) + r.EqualError(err, "invalid configuration file\n'ldap' has invalid keys: password\n'postgres' has invalid keys: uri") + errs := errorlist.Unwrap(err) + r.Len(errs, 3) + r.EqualError(errs[1], "'ldap' has invalid keys: password") + r.EqualError(errs[2], "'postgres' has invalid keys: uri") +} diff --git a/internal/errorlist/errorlist.go b/internal/errorlist/errorlist.go index 26b56280..70e53731 100644 --- a/internal/errorlist/errorlist.go +++ b/internal/errorlist/errorlist.go @@ -77,8 +77,8 @@ func (errl *List) Value() error { case 0: return nil case 1: - return errl.errors[0] + return fmt.Errorf("%s: %w", errl.message, errl.errors[0]) default: - return errl + return errors.Join(append([]error{errors.New(errl.message)}, errl.errors...)...) } } diff --git a/internal/errorlist/errorlist_test.go b/internal/errorlist/errorlist_test.go index a45cbe6e..cf913005 100644 --- a/internal/errorlist/errorlist_test.go +++ b/internal/errorlist/errorlist_test.go @@ -35,3 +35,20 @@ func buildErrors(n int) []error { } return errors } + +func TestErrorListValue(t *testing.T) { + r := require.New(t) + + err := errorlist.New("context") + err.Append(fmt.Errorf("content")) + errs := errorlist.Unwrap(err.Value()) + r.Equal(1, len(errs)) + r.Equal("context: content", errs[0].Error()) + + err.Append(fmt.Errorf("content 2")) + errs = errorlist.Unwrap(err.Value()) + r.Equal(3, len(errs)) + r.Equal("context", errs[0].Error()) + r.Equal("content", errs[1].Error()) + r.Equal("content 2", errs[2].Error()) +}