diff --git a/schema.go b/schema.go index 1a543de2..f214f27f 100644 --- a/schema.go +++ b/schema.go @@ -1155,10 +1155,10 @@ func (a *SubjectLocality) Element() *etree.Element { // // See http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf §2.7.2.2 type AuthnContext struct { - AuthnContextClassRef *AuthnContextClassRef + AuthnContextClassRef *AuthnContextClassRef + AuthenticatingAuthorities []AuthenticatingAuthority `xml:"AuthenticatingAuthority"` // AuthnContextDecl *AuthnContextDecl ... TODO // AuthnContextDeclRef *AuthnContextDeclRef ... TODO - // AuthenticatingAuthorities []AuthenticatingAuthority... TODO } // Element returns an etree.Element representing the object in XML form. @@ -1167,6 +1167,10 @@ func (a *AuthnContext) Element() *etree.Element { if a.AuthnContextClassRef != nil { el.AddChild(a.AuthnContextClassRef.Element()) } + + for _, v := range a.AuthenticatingAuthorities { + el.AddChild(v.Element()) + } return el } @@ -1184,6 +1188,20 @@ func (a *AuthnContextClassRef) Element() *etree.Element { return el } +// AuthenticatingAuthority represents the SAML element AuthenticatingAuthority. +// +// See http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf §2.7.2.2 +type AuthenticatingAuthority struct { + Value string `xml:",chardata"` +} + +// Element returns an etree.Element representing the object in XML form. +func (a *AuthenticatingAuthority) Element() *etree.Element { + el := etree.NewElement("saml:AuthenticatingAuthority") + el.SetText(a.Value) + return el +} + // AttributeStatement represents the SAML element AttributeStatement. // // See http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf §2.7.3 diff --git a/schema_test.go b/schema_test.go index 3d9f793a..4cfd7804 100644 --- a/schema_test.go +++ b/schema_test.go @@ -108,6 +108,54 @@ func TestRequestedAuthnContext(t *testing.T) { string(x))) } +func TestAuthenticatingAuthority(t *testing.T) { + expected := AuthenticatingAuthority{ + Value: "value", + } + + doc := etree.NewDocument() + doc.SetRoot(expected.Element()) + x, err := doc.WriteToBytes() + assert.Check(t, err) + assert.Check(t, is.Equal(`value`, + string(x))) +} + +func TestAuthnContextNoAuthenticatingAuthority(t *testing.T) { + expected := AuthnContext{ + AuthnContextClassRef: &AuthnContextClassRef{ + Value: "value", + }, + AuthenticatingAuthorities: nil, + } + + doc := etree.NewDocument() + doc.SetRoot(expected.Element()) + x, err := doc.WriteToBytes() + assert.Check(t, err) + assert.Check(t, is.Equal(`value`, + string(x))) +} + +func TestAuthnContextMultiAuthenticatingAuthority(t *testing.T) { + expected := AuthnContext{ + AuthnContextClassRef: &AuthnContextClassRef{ + Value: "value", + }, + AuthenticatingAuthorities: []AuthenticatingAuthority{ + {Value: "value1"}, + {Value: "value2"}, + }, + } + + doc := etree.NewDocument() + doc.SetRoot(expected.Element()) + x, err := doc.WriteToBytes() + assert.Check(t, err) + assert.Check(t, is.Equal(`valuevalue1value2`, + string(x))) +} + func TestArtifactResolveElement(t *testing.T) { issueInstant := time.Date(2020, 7, 21, 12, 30, 45, 0, time.UTC) expected := ArtifactResolve{