Skip to content

Commit

Permalink
[adding] support for account mappings (#145)
Browse files Browse the repository at this point in the history
Signed-off-by: Matthias Hanel <mh@synadia.com>
  • Loading branch information
matthiashanel authored Feb 8, 2021
1 parent 9bde681 commit 397d4ee
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 0 deletions.
38 changes: 38 additions & 0 deletions v2/account_claims.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,41 @@ func (o *OperatorLimits) Validate(_ *ValidationResults) {
// negative values mean unlimited, so all numbers are valid
}

// Mapping for publishes
type WeightedMapping struct {
Subject Subject `json:"subject"`
Weight uint8 `json:"weight,omitempty"`
OptCluster string `json:"cluster,omitempty"`
}

type Mapping map[Subject][]WeightedMapping

func (m *Mapping) Validate(vr *ValidationResults) {
for ubFrom, wm := range (map[Subject][]WeightedMapping)(*m) {
ubFrom.Validate(vr)
total := uint8(0)
for _, wm := range wm {
wm.Subject.Validate(vr)
if wm.Subject.HasWildCards() {
vr.AddError("Subject %q in weighted mapping %q is not allowed to contains wildcard",
string(wm.Subject), ubFrom)
}
weight := wm.Weight
if wm.Weight == 0 {
weight += 100
}
total += weight
}
if total > 100 {
vr.AddError("Mapping %q exceeds 100%% among all of it's weighted to mappings", ubFrom)
}
}
}

func (a *Account) AddMapping(sub Subject, to ...WeightedMapping) {
a.Mappings[sub] = to
}

// Account holds account specific claims data
type Account struct {
Imports Imports `json:"imports,omitempty"`
Expand All @@ -92,6 +127,7 @@ type Account struct {
SigningKeys SigningKeys `json:"signing_keys,omitempty"`
Revocations RevocationList `json:"revocations,omitempty"`
DefaultPermissions Permissions `json:"default_permissions,omitempty"`
Mappings Mapping `json:"mappings,omitempty"`
Info
GenericFields
}
Expand All @@ -102,6 +138,7 @@ func (a *Account) Validate(acct *AccountClaims, vr *ValidationResults) {
a.Exports.Validate(vr)
a.Limits.Validate(vr)
a.DefaultPermissions.Validate(vr)
a.Mappings.Validate(vr)

if !a.Limits.IsEmpty() && a.Limits.Imports >= 0 && int64(len(a.Imports)) > a.Limits.Imports {
vr.AddError("the account contains more imports than allowed by the operator")
Expand Down Expand Up @@ -150,6 +187,7 @@ func NewAccountClaims(subject string) *AccountClaims {
AccountLimits{NoLimit, NoLimit, true, NoLimit, NoLimit},
JetStreamLimits{0, 0, 0, 0}}
c.Subject = subject
c.Mappings = Mapping{}
return c
}

Expand Down
46 changes: 46 additions & 0 deletions v2/account_claims_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -589,3 +589,49 @@ func TestInvalidAccountInfo(t *testing.T) {
t.Errorf("invalid info needs to be blocking")
}
}

func TestAccountMapping(t *testing.T) { // don't block encoding!!!
akp := createAccountNKey(t)
apk := publicKey(akp, t)

account := NewAccountClaims(apk)
vr := &ValidationResults{}

account.AddMapping("foo1", WeightedMapping{Subject: "to"})
account.Validate(vr)
if !vr.IsEmpty() {
t.Fatal("Expected no errors")
}
account.AddMapping("foo2",
WeightedMapping{Subject: "to1", Weight: 50},
WeightedMapping{Subject: "to2", Weight: 50})
account.Validate(vr)
if !vr.IsEmpty() {
t.Fatal("Expected no errors")
}
account.AddMapping("foo3",
WeightedMapping{Subject: "to1", Weight: 50},
WeightedMapping{Subject: "to2", Weight: 51})
account.Validate(vr)
if !vr.IsBlocking(false) {
t.Fatal("Expected blocking error as sum of weights is > 100")
}

vr = &ValidationResults{}
account.Mappings = Mapping{}
account.AddMapping("foo4",
WeightedMapping{Subject: "to1" }, // no weight means 100
WeightedMapping{Subject: "to2", Weight: 1})
account.Validate(vr)
if !vr.IsBlocking(false) {
t.Fatal("Expected blocking error as sum of weights is > 100")
}

vr = &ValidationResults{}
account.Mappings = Mapping{}
account.AddMapping("foo5", WeightedMapping{Subject: "to.*"})
account.Validate(vr)
if !vr.IsBlocking(false) {
t.Fatal("Expected errors due to wildcard in weighted mapping")
}
}

0 comments on commit 397d4ee

Please sign in to comment.