diff --git a/v2/account_claims.go b/v2/account_claims.go index 5c1665d..fa8fc58 100644 --- a/v2/account_claims.go +++ b/v2/account_claims.go @@ -152,10 +152,20 @@ type Mapping map[Subject][]WeightedMapping func (m *Mapping) Validate(vr *ValidationResults) { for ubFrom, wm := range (map[Subject][]WeightedMapping)(*m) { ubFrom.Validate(vr) + perCluster := make(map[string]uint8) total := uint8(0) - for _, wm := range wm { - wm.Subject.Validate(vr) - total += wm.GetWeight() + for _, e := range wm { + e.Subject.Validate(vr) + if e.Cluster != "" { + t := perCluster[e.Cluster] + t += e.Weight + perCluster[e.Cluster] = t + if t > 100 { + vr.AddError("Mapping %q in cluster %q exceeds 100%% among all of it's weighted to mappings", ubFrom, e.Cluster) + } + } else { + total += e.GetWeight() + } } if total > 100 { vr.AddError("Mapping %q exceeds 100%% among all of it's weighted to mappings", ubFrom) diff --git a/v2/account_claims_test.go b/v2/account_claims_test.go index 19dbf93..c3cfa5e 100644 --- a/v2/account_claims_test.go +++ b/v2/account_claims_test.go @@ -709,6 +709,40 @@ func TestAccountMapping(t *testing.T) { // don't block encoding!!! } } +func TestAccountClusterMany100MappingOK(t *testing.T) { // don't block encoding!!! + akp := createAccountNKey(t) + apk := publicKey(akp, t) + + account := NewAccountClaims(apk) + vr := &ValidationResults{} + + account.AddMapping("q", + WeightedMapping{Subject: "qq", Weight: 100, Cluster: "A"}, + WeightedMapping{Subject: "qq", Weight: 100, Cluster: "B"}, + WeightedMapping{Subject: "bb", Weight: 100, Cluster: "C"}, + WeightedMapping{Subject: "qq", Weight: 100}) + account.Validate(vr) + if !vr.IsEmpty() { + t.Fatal("Expected no errors") + } +} + +func TestAccountClusterNoOver100Mapping(t *testing.T) { // don't block encoding!!! + akp := createAccountNKey(t) + apk := publicKey(akp, t) + + account := NewAccountClaims(apk) + vr := &ValidationResults{} + + account.AddMapping("q", + WeightedMapping{Subject: "qq", Weight: 100, Cluster: "A"}, + WeightedMapping{Subject: "qq", Weight: 5, Cluster: "A"}) + account.Validate(vr) + if !vr.IsBlocking(false) { + t.Fatal("Expected blocking error as sum of weights is > 100") + } +} + func TestAccountExternalAuthorization(t *testing.T) { akp := createAccountNKey(t) apk := publicKey(akp, t)