diff --git a/api/types/lock.go b/api/types/lock.go index b71ab849e637e..ab07fb3e0a21a 100644 --- a/api/types/lock.go +++ b/api/types/lock.go @@ -218,11 +218,6 @@ func (c *LockV2) CheckAndSetDefaults() error { return nil } -// IsEmpty returns true if none of the target's fields is set. -func (t LockTarget) IsEmpty() bool { - return protoKnownFieldsEqual(&t, &LockTarget{}) -} - // IntoMap returns the target attributes in the form of a map. func (t LockTarget) IntoMap() (map[string]string, error) { m := map[string]string{} @@ -237,6 +232,19 @@ func (t *LockTarget) FromMap(m map[string]string) error { return trace.Wrap(utils.ObjectToStruct(m, t)) } +// IsEmpty returns true if none of the target's fields is set. +func (t LockTarget) IsEmpty() bool { + return t.User == "" && + t.Role == "" && + t.Login == "" && + t.Node == "" && + t.MFADevice == "" && + t.WindowsDesktop == "" && + t.AccessRequest == "" && + t.Device == "" && + t.ServerID == "" +} + // Match returns true if the lock's target is matched by this target. func (t LockTarget) Match(lock Lock) bool { if t.IsEmpty() { diff --git a/api/types/lock_test.go b/api/types/lock_test.go index fee9ad3ddb862..020fa4d56513f 100644 --- a/api/types/lock_test.go +++ b/api/types/lock_test.go @@ -17,6 +17,8 @@ limitations under the License. package types import ( + "reflect" + "strings" "testing" "github.com/google/go-cmp/cmp" @@ -112,3 +114,22 @@ func TestLockTargetMatch(t *testing.T) { // Test that a lock with ServerID field set matches any target with ServerID. require.True(t, targetServerID.Match(lockServerID)) } + +// TestLockTargetIsEmpty checks that the implementation of [LockTarget.IsEmpty] +// is correct by filling one field at a time and expecting IsEmpty to return +// false. Only the public fields that don't start with `XXX_` are checked (as +// those are gogoproto-internal fields). +func TestLockTargetIsEmpty(t *testing.T) { + require.True(t, (LockTarget{}).IsEmpty()) + + for i, field := range reflect.VisibleFields(reflect.TypeOf(LockTarget{})) { + if strings.HasPrefix(field.Name, "XXX_") { + continue + } + + var lt LockTarget + // if we add non-string fields to LockTarget we need a type switch here + reflect.ValueOf(<).Elem().Field(i).SetString("nonempty") + require.False(t, lt.IsEmpty(), "field name: %v", field.Name) + } +}