Skip to content
Snippets Groups Projects
Commit 6273a767 authored by ale's avatar ale
Browse files

Fix isCriticalError() check

parent 20150213
No related branches found
No related tags found
1 merge request!142Refactor validation code for readability
package accountserver package accountserver
import ( import (
"errors"
"testing" "testing"
) )
...@@ -14,6 +15,74 @@ func TestErrors(t *testing.T) { ...@@ -14,6 +15,74 @@ func TestErrors(t *testing.T) {
if !IsValidationError(rerr) { if !IsValidationError(rerr) {
t.Errorf("IsValidationError() returned false") t.Errorf("IsValidationError() returned false")
} }
if !IsValidationError(errors.Join(
newValidationErrorStr("field1", "bad"),
newValidationErrorStr("field2", "bad"),
)) {
t.Errorf("IsValidationError() does not survive aggregation")
}
}
func TestErrors_Criticality(t *testing.T) {
for _, isAdmin := range []bool{false, true} {
for idx, td := range []struct {
err error
crit bool
}{
{errors.New("bare error"), true},
{newValidationErrorStr("field", "bad"), true},
{nonCriticalErr(newValidationErrorStr("field", "bad")), false},
{errors.Join(
newValidationErrorStr("field1", "bad"),
newValidationErrorStr("field2", "bad"),
), true},
{errors.Join(
newValidationErrorStr("field1", "bad"),
nonCriticalErr(newValidationErrorStr("field2", "bad")),
), true},
{errors.Join(
nonCriticalErr(newValidationErrorStr("field1", "bad")),
nonCriticalErr(newValidationErrorStr("field2", "bad")),
), false},
} {
rctx := &RequestContext{
Auth: Auth{IsAdmin: isAdmin},
}
crit := isCriticalErr(rctx, td.err)
// All errors are critical for non-admins.
expectCrit := td.crit
if !isAdmin {
expectCrit = true
}
if crit != expectCrit {
t.Errorf("[%d] test failed, crit=%v expected=%v", idx, crit, expectCrit)
}
}
}
}
func TestErrors_CriticalMasking(t *testing.T) {
rctx := &RequestContext{
Auth: Auth{IsAdmin: true},
}
err := errors.Join(
newValidationErrorStr("field1", "bad"),
nonCriticalErr(newValidationErrorStr("field2", "not too bad")),
)
if !isCriticalErr(rctx, err) {
t.Fatal("critical error was masked")
}
err = errors.Join(
nonCriticalErr(newValidationErrorStr("field1", "not too bad")),
nonCriticalErr(newValidationErrorStr("field2", "not too bad")),
)
if isCriticalErr(rctx, err) {
t.Fatal("non-critical error status was lost in aggregation")
}
} }
func TestErrors_JSON(t *testing.T) { func TestErrors_JSON(t *testing.T) {
......
package accountserver package accountserver
import "errors"
// Some validation errors are non-critical, i.e. they can be safely // Some validation errors are non-critical, i.e. they can be safely
// overridden if the request is made by an administrator. // overridden if the request is made by an administrator.
type nonCriticalValidationError struct { type nonCriticalValidationError struct {
...@@ -21,11 +19,6 @@ func nonCriticalErr(err error) error { ...@@ -21,11 +19,6 @@ func nonCriticalErr(err error) error {
return &nonCriticalValidationError{wrap: err} return &nonCriticalValidationError{wrap: err}
} }
func isCriticalErr(rctx *RequestContext, err error) bool {
return !(errors.Is(err, &nonCriticalValidationError{}) &&
rctx.Auth.IsAdmin)
}
func nonCritical(f ValidatorFunc) ValidatorFunc { func nonCritical(f ValidatorFunc) ValidatorFunc {
return func(rctx *RequestContext, s string) error { return func(rctx *RequestContext, s string) error {
if err := f(rctx, s); err != nil { if err := f(rctx, s); err != nil {
...@@ -34,3 +27,23 @@ func nonCritical(f ValidatorFunc) ValidatorFunc { ...@@ -34,3 +27,23 @@ func nonCritical(f ValidatorFunc) ValidatorFunc {
return nil return nil
} }
} }
func unwrapCriticalErrs(err error) bool {
if _, ok := err.(*nonCriticalValidationError); ok {
return false
} else if t, ok := err.(wrappedErrorMulti); ok {
for _, innerErr := range t.Unwrap() {
if crit := unwrapCriticalErrs(innerErr); crit {
return true
}
}
return false
} else if t, ok := err.(wrappedError); ok {
return unwrapCriticalErrs(t.Unwrap())
}
return true
}
func isCriticalErr(rctx *RequestContext, err error) bool {
return !(rctx.Auth.IsAdmin && !unwrapCriticalErrs(err))
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment