Reading XML by attribute

Trying to connect to MS sharepoint using Golang as explained here, so I wrote the below that is returning XML text:

package main

import (
	"bytes"
	"encoding/xml"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"strings"
)

func main() {
	const myurl = "https://login.microsoftonline.com/extSTS.srf"
	const username = "myuser@mydmain.com"
	const password = "mypassword"
	const endpoint = "https://mydomain.sharepoint.com/"
	const xmlbody = `
	<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
	xmlns:a="http://www.w3.org/2005/08/addressing"
	xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
  <a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</a:Action>
  <a:ReplyTo>
	<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
  </a:ReplyTo>
  <a:To s:mustUnderstand="1">https://login.microsoftonline.com/extSTS.srf</a:To>
  <o:Security s:mustUnderstand="1"
	 xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
	<o:UsernameToken>
	  <o:Username>` + username + `</o:Username>
	  <o:Password>` + password + `</o:Password>
	</o:UsernameToken>
  </o:Security>
</s:Header>
<s:Body>
  <t:RequestSecurityToken xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">
	<wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
	  <a:EndpointReference>
		<a:Address>` + endpoint + `</a:Address>
	  </a:EndpointReference>
	</wsp:AppliesTo>
	<t:KeyType>http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey</t:KeyType>
	<t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType>
	<t:TokenType>urn:oasis:names:tc:SAML:1.0:assertion</t:TokenType>
  </t:RequestSecurityToken>
</s:Body>
</s:Envelope>`

	resp, err := http.Post(myurl, "text/xml", strings.NewReader(xmlbody))
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

	body, _ := ioutil.ReadAll(resp.Body)
	fmt.Println("response Body:", string(body))
}

The above was able to do the first step perfectly, now I want to fetch the returned string and read the xml element that had ID="Compact0", so I tried this:

type Node struct {
	XMLName xml.Name
	Attrs   []xml.Attr `xml:"-"`
	Content []byte     `xml:",innerxml"`
	Nodes   []Node     `xml:",any"`
}

func walk(nodes []Node, f func(Node) bool) {
	for _, n := range nodes {
		if f(n) {
			walk(n.Nodes, f)
		}
	}
}

func main() {
	// My code above, followed by:
	var n Node
	var data = []byte(body)
	buf := bytes.NewBuffer(data)
	dec := xml.NewDecoder(buf)
	err = dec.Decode(&n)
	if err != nil {
		panic(err)
	}
	walk([]Node{n}, func(n Node) bool {
		if n.Attrs == "Compact0" {.  // <= ERROR
			fmt.Println(string(n.Content))
		}
		return true
	})
}

But I got this error:

cannot convert “Compact0” (untyped string constant) to
[]xml.AttrcompilerInvalidUntypedConversion

At:

if n.Attrs == “Compact0” {}

The returned XML response is:

<?xml version="1.0" encoding="utf-8"?>
<S:Envelope xmlns:wsa="http://www.w3.org/2005/08/addressing" 
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" 
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" 
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" 
xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust" 
xmlns:S="http://www.w3.org/2003/05/soap-envelope">
    <S:Header>
        <wsa:Action S:mustUnderstand="1" wsu:Id="Action">http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue</wsa:Action>
        <wsa:To S:mustUnderstand="1" wsu:Id="To">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
        <wsse:Security S:mustUnderstand="1">
            <wsu:Timestamp wsu:Id="TS" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
            <wsu:Created>2021-06-30T18:38:50.5911765Z</wsu:Created>
            <wsu:Expires>2021-06-30T18:43:50.5911765Z</wsu:Expires>
            </wsu:Timestamp>
        </wsse:Security>
    </S:Header>
    <S:Body xmlns:S="http://www.w3.org/2003/05/soap-envelope">
        <wst:RequestSecurityTokenResponse xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" x
        mlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" 
        xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust">
            <wst:TokenType>urn:passport:compact</wst:TokenType>
            <wsp:AppliesTo>
                <wsa:EndpointReference xmlns:wsa="http://www.w3.org/2005/08/addressing">
                    <wsa:Address>https://mydomain.sharepoint.com/</wsa:Address>
                </wsa:EndpointReference>
            </wsp:AppliesTo>
            <wst:Lifetime>
                <wsu:Created>2021-06-30T18:38:49Z</wsu:Created>
                <wsu:Expires>2021-07-01T18:38:49Z</wsu:Expires>
            </wst:Lifetime>
            <wst:RequestedSecurityToken>
                <wsse:BinarySecurityToken Id="Compact0" 
                xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
                t=blablabla==&amp;p=
                </wsse:BinarySecurityToken>
            </wst:RequestedSecurityToken>
            <wst:RequestedAttachedReference>
                <wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
                    <wsse:Reference URI="VkETyJDRdMqocUhjsNftrfT9Z8U="></wsse:Reference>
                </wsse:SecurityTokenReference>
            </wst:RequestedAttachedReference>
            <wst:RequestedUnattachedReference>
                <wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
                    <wsse:Reference URI="VkETyJDRdMqocUhjsNftrfT9Z8U="></wsse:Reference>
                </wsse:SecurityTokenReference>
            </wst:RequestedUnattachedReference>
        </wst:RequestSecurityTokenResponse>
    </S:Body>
</S:Envelope>

From which I need to get the blablabla at:

                <wsse:BinarySecurityToken Id="Compact0" 
                xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
                t=blablabla==&amp;p=
                </wsse:BinarySecurityToken>

One of the issues could be that you are trying to compare a string with an array of xml.Attr.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.