func getReferencedXML(reference *etree.Element, inputDoc *etree.Document) (outputDoc *etree.Document, err error) { uri := reference.SelectAttrValue("URI", "") uri = strings.Replace(uri, "#", "", 1) // populate doc with the referenced xml from the Reference URI if uri == "" { outputDoc = inputDoc } else { path := fmt.Sprintf(".//[@ID='%s']", uri) e := inputDoc.FindElement(path) if e != nil { outputDoc = etree.NewDocument() outputDoc.SetRoot(e.Copy()) } else { // SAML v1.1 Assertions use AssertionID path := fmt.Sprintf(".//[@AssertionID='%s']", uri) e := inputDoc.FindElement(path) if e != nil { outputDoc = etree.NewDocument() outputDoc.SetRoot(e.Copy()) } } } if outputDoc == nil { return nil, errors.New("signedxml: unable to find refereced xml") } return outputDoc, nil }
func (aut Person) CreateXml(e *etree.Element) *etree.Element { a := e.CreateElement("author") a_ln := a.CreateElement("last-name") a_mn := a.CreateElement("middle-name") a_fn := a.CreateElement("first-name") a_ln.SetText(aut.Lname) a_mn.SetText(aut.Mname) a_fn.SetText(aut.Fname) return a }
// getSortedNamespaces sorts the namespace attributes by their prefix func getSortedNamespaces(list map[string]string) []etree.Attr { var keys []string for k := range list { keys = append(keys, k) } sort.Strings(keys) elem := etree.Element{} for _, k := range keys { elem.CreateAttr(k, list[k]) } return elem.Attr }
func removeTokenFromElement(token etree.Token, e *etree.Element) *etree.Token { for i, t := range e.Child { if t == token { e.Child = append(e.Child[0:i], e.Child[i+1:]...) return &t } } return nil }
func TestJustSetLocElement(t *testing.T) { smu, err := NewSitemapURL(URL{"loc": "path", "host": "http://example.com"}) if err != nil { t.Fatalf(`Fatal to validate! This is a critical error: %s`, err) } doc := etree.NewDocument() doc.ReadFromBytes(smu.XML()) var elm *etree.Element url := doc.SelectElement("url") elm = url.SelectElement("loc") if elm == nil { t.Errorf(`Failed to generate xml that loc element is blank: %s`, elm) } if elm != nil && elm.Text() != "http://example.com/path" { t.Errorf(`Failed to generate xml thats deferrent value in loc element: %s`, elm.Text()) } }
func calculateHash(reference *etree.Element, doc *etree.Document) (string, error) { digestMethodElement := reference.SelectElement("DigestMethod") if digestMethodElement == nil { return "", errors.New("signedxml: unable to find DigestMethod") } digestMethodURI := digestMethodElement.SelectAttrValue("Algorithm", "") if digestMethodURI == "" { return "", errors.New("signedxml: unable to find Algorithm in DigestMethod") } digestAlgo, ok := hashAlgorithms[digestMethodURI] if !ok { return "", fmt.Errorf("signedxml: unable to find matching hash"+ "algorithm for %s in hashAlgorithms", digestMethodURI) } doc.WriteSettings.CanonicalEndTags = true doc.WriteSettings.CanonicalText = true doc.WriteSettings.CanonicalAttrVal = true h := digestAlgo.New() docBytes, err := doc.WriteToBytes() if err != nil { return "", err } //ioutil.WriteFile("C:/Temp/SignedXML/Suspect.xml", docBytes, 0644) //s, _ := doc.WriteToString() //logger.Println(s) h.Write(docBytes) d := h.Sum(nil) calculatedValue := base64.StdEncoding.EncodeToString(d) return calculatedValue, nil }
func TestSetNilValue(t *testing.T) { smu, err := NewSitemapURL(&Options{}, URL{"loc": "path", "priority": nil, "changefreq": nil, "lastmod": nil, "host": "http://example.com"}) if err != nil { t.Fatalf(`Fatal to validate! This is a critical error: %s`, err) } doc := etree.NewDocument() doc.ReadFromBytes(smu.XML()) var elm *etree.Element url := doc.SelectElement("url") elm = url.SelectElement("loc") if elm == nil { t.Errorf(`Failed to generate xml that loc element is blank: %s`, elm) } if elm != nil && elm.Text() != "http://example.com/path" { t.Errorf(`Failed to generate xml thats deferrent value in loc element: %s`, elm.Text()) } elm = url.SelectElement("priority") if elm != nil { t.Errorf(`Failed to generate xml that priority element must be nil: %s`, elm) } elm = url.SelectElement("changefreq") if elm != nil { t.Errorf(`Failed to generate xml that changefreq element must be nil: %s`, elm) } elm = url.SelectElement("lastmod") if elm != nil { t.Errorf(`Failed to generate xml that lastmod element must be nil: %s`, elm) } }
func processTransform(transform *etree.Element, docIn *etree.Document) (docOut *etree.Document, err error) { transformAlgoURI := transform.SelectAttrValue("Algorithm", "") if transformAlgoURI == "" { return nil, errors.New("signedxml: unable to find Algorithm in Transform") } transformAlgo, ok := CanonicalizationAlgorithms[transformAlgoURI] if !ok { return nil, fmt.Errorf("signedxml: unable to find matching transform"+ "algorithm for %s in CanonicalizationAlgorithms", transformAlgoURI) } var transformContent string if transform.ChildElements() != nil { tDoc := etree.NewDocument() tDoc.SetRoot(transform.Copy()) transformContent, err = tDoc.WriteToString() if err != nil { return nil, err } } docString, err := docIn.WriteToString() if err != nil { return nil, err } docString, err = transformAlgo.Process(docString, transformContent) if err != nil { return nil, err } docOut = etree.NewDocument() docOut.ReadFromString(docString) return docOut, nil }
func TestJustSetLocElementAndThenItNeedsCompleteValues(t *testing.T) { smu, err := NewSitemapURL(URL{"loc": "path", "host": "http://example.com"}) if err != nil { t.Fatalf(`Fatal to validate! This is a critical error: %s`, err) } doc := etree.NewDocument() doc.ReadFromBytes(smu.XML()) var elm *etree.Element url := doc.SelectElement("url") elm = url.SelectElement("loc") if elm == nil { t.Errorf(`Failed to generate xml that loc element is blank: %s`, elm) } if elm != nil && elm.Text() != "http://example.com/path" { t.Errorf(`Failed to generate xml thats deferrent value in loc element: %s`, elm.Text()) } elm = url.SelectElement("priority") if elm == nil { t.Errorf(`Failed to generate xml that priority element is nil: %s`, elm) } if elm != nil && elm.Text() != "0.5" { t.Errorf(`Failed to generate xml thats deferrent value in priority element: %s`, elm.Text()) } elm = url.SelectElement("changefreq") if elm == nil { t.Errorf(`Failed to generate xml that changefreq element is nil: %s`, elm) } if elm != nil && elm.Text() != "weekly" { t.Errorf(`Failed to generate xml thats deferrent value in changefreq element: %s`, elm.Text()) } elm = url.SelectElement("lastmod") if elm == nil { t.Errorf(`Failed to generate xml that lastmod element is nil: %s`, elm) } if elm != nil { if _, err := time.Parse(time.RFC3339, elm.Text()); err != nil { t.Errorf(`Failed to generate xml thats failed to parse datetime in lastmod element: %s`, err) } } }
// SetBuilderElementValue if it will change to struct from map if the future's // author is feeling a bothersome in this function. func SetBuilderElementValue(elm *etree.Element, data map[string]interface{}, basekey string) (*etree.Element, bool) { var child *etree.Element key := basekey ts, tk := spaceDecompose(elm.Tag) _, sk := spaceDecompose(elm.Space) if elm.Tag != "" && ts != "" && tk != "" { key = fmt.Sprintf("%s:%s", elm.Space, basekey) } else if sk != "" { key = fmt.Sprintf("%s:%s", sk, basekey) } if values, ok := data[basekey]; ok { switch value := values.(type) { case nil: default: child = elm.CreateElement(key) child.SetText(fmt.Sprint(value)) case int: child = elm.CreateElement(key) child.SetText(fmt.Sprint(value)) case string: child = elm.CreateElement(key) child.SetText(value) case float64, float32: child = elm.CreateElement(key) child.SetText(fmt.Sprint(value)) case time.Time: child = elm.CreateElement(key) child.SetText(value.Format(time.RFC3339)) case bool: _ = elm.CreateElement(fmt.Sprintf("%s:%s", key, key)) case []int: for _, v := range value { child = elm.CreateElement(key) child.SetText(fmt.Sprint(v)) } case []string: for _, v := range value { child = elm.CreateElement(key) child.SetText(v) } case Attrs: val, attrs := value[0], value[1] child, _ = SetBuilderElementValue(elm, URL{basekey: val}, basekey) switch attr := attrs.(type) { case map[string]string: for k, v := range attr { child.CreateAttr(k, v) } // TODO: gotta remove below case Attr: for k, v := range attr { child.CreateAttr(k, v) } } case interface{}: var childkey string if sk == "" { childkey = fmt.Sprintf("%s:%s", key, key) } else { childkey = fmt.Sprint(key) } switch value := values.(type) { case []URL: for _, v := range value { child := elm.CreateElement(childkey) for ck := range v { SetBuilderElementValue(child, v, ck) } } case URL: child := elm.CreateElement(childkey) for ck := range value { SetBuilderElementValue(child, value, ck) } } } return child, true } return child, false }
// SetBuilderElementValue if it will change to struct from map if the future's // author is feeling a bothersome in this function. func SetBuilderElementValue(elm *etree.Element, data map[string]interface{}, basekey string) bool { key := basekey ts, tk := spaceDecompose(elm.Tag) _, sk := spaceDecompose(elm.Space) if elm.Tag != "" && ts != "" && tk != "" { key = fmt.Sprintf("%s:%s", elm.Space, basekey) } else if sk != "" { key = fmt.Sprintf("%s:%s", sk, basekey) } if values, ok := data[basekey]; ok { switch value := values.(type) { case nil: default: child := elm.CreateElement(key) child.SetText(fmt.Sprint(value)) case int: child := elm.CreateElement(key) child.SetText(fmt.Sprint(value)) case string: child := elm.CreateElement(key) child.SetText(value) case float64, float32: child := elm.CreateElement(key) child.SetText(fmt.Sprint(value)) case time.Time: child := elm.CreateElement(key) child.SetText(value.Format(time.RFC3339)) case bool: _ = elm.CreateElement(fmt.Sprintf("%s:%s", key, key)) case []int: for _, v := range value { child := elm.CreateElement(key) child.SetText(fmt.Sprint(v)) } case []string: for _, v := range value { child := elm.CreateElement(key) child.SetText(v) } case interface{}: var childkey string if sk == "" { childkey = fmt.Sprintf("%s:%s", key, key) } else { childkey = fmt.Sprint(key) } switch value := values.(type) { case []URL: for _, v := range value { child := elm.CreateElement(childkey) for ck := range v { SetBuilderElementValue(child, v, ck) } } case URL: child := elm.CreateElement(childkey) for ck := range value { SetBuilderElementValue(child, value, ck) } } } return true } return false }
func (e ExclusiveCanonicalization) renderAttributes(node *etree.Element, prefixesInScope []string, defaultNS string) (newDefaultNS string, newPrefixesInScope []string) { currentNS := node.SelectAttrValue("xmlns", defaultNS) elementAttributes := []etree.Attr{} nsListToRender := make(map[string]string) attrListToRender := attributes{} // load map with for prefix -> uri lookup for _, attr := range node.Attr { if attr.Space == "xmlns" { e.namespaces[attr.Key] = attr.Value } } // handle the namespace of the node itself if node.Space != "" { if !contains(prefixesInScope, node.Space) { nsListToRender["xmlns:"+node.Space] = e.namespaces[node.Space] prefixesInScope = append(prefixesInScope, node.Space) } } else if defaultNS != currentNS { newDefaultNS = currentNS elementAttributes = append(elementAttributes, etree.Attr{Key: "xmlns", Value: currentNS}) } for _, attr := range node.Attr { // include the namespaces if they are in the inclusiveNamespacePrefixList if attr.Space == "xmlns" { if !contains(prefixesInScope, attr.Key) && contains(e.inclusiveNamespacePrefixList, attr.Key) { nsListToRender["xmlns:"+attr.Key] = attr.Value prefixesInScope = append(prefixesInScope, attr.Key) } } // include namespaces for qualfied attributes if attr.Space != "" && attr.Space != "xmlns" && !contains(prefixesInScope, attr.Space) { nsListToRender["xmlns:"+attr.Space] = e.namespaces[attr.Space] prefixesInScope = append(prefixesInScope, attr.Space) } // inclued all non-namespace attributes if attr.Space != "xmlns" && attr.Key != "xmlns" { attrListToRender = append(attrListToRender, attribute{ prefix: attr.Space, uri: e.namespaces[attr.Space], key: attr.Key, value: attr.Value, }) } } // sort and add the namespace attributes first sortedNSList := getSortedNamespaces(nsListToRender) elementAttributes = append(elementAttributes, sortedNSList...) // then sort and add the non-namespace attributes sortedAttributes := getSortedAttributes(attrListToRender) elementAttributes = append(elementAttributes, sortedAttributes...) // replace the nodes attributes with the sorted copy node.Attr = elementAttributes return currentNS, prefixesInScope }