Skip to content

Commit

Permalink
Merge pull request #74 from dmlambea/master
Browse files Browse the repository at this point in the history
Added basic support for WSS Security header
  • Loading branch information
c4milo authored May 23, 2017
2 parents 21c7151 + a165afc commit 9e55fc9
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 22 deletions.
12 changes: 6 additions & 6 deletions header_tmpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ var headerTmpl = `
package {{.}}
import (
"bytes"
"crypto/tls"
"encoding/xml"
"time"
"bytes"
"crypto/tls"
"encoding/xml"
"io/ioutil"
"net/http"
"io/ioutil"
"log"
"math/rand"
"net"
"net/http"
"time"
{{/*range .Imports*/}}
{{/*.*/}}
Expand Down
7 changes: 6 additions & 1 deletion operations_tmpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,13 @@ var opsTmpl = `
}
}
func (service *{{$portType}}) AddHeader(header interface{}) {
service.client.AddHeader(header)
}
// Backwards-compatible function: use AddHeader instead
func (service *{{$portType}}) SetHeader(header interface{}) {
service.client.SetHeader(header)
service.client.AddHeader(header)
}
{{range .Operations}}
Expand Down
111 changes: 96 additions & 15 deletions soap_tmpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ type SOAPEnvelope struct {
type SOAPHeader struct {
XMLName xml.Name ` + "`" + `xml:"http://schemas.xmlsoap.org/soap/envelope/ Header"` + "`" + `
Header interface{}
Items []interface{} ` + "`" + `xml:",omitempty"` + "`" + `
}
type SOAPBody struct {
Expand All @@ -39,16 +39,97 @@ type SOAPFault struct {
Detail string ` + "`" + `xml:"detail,omitempty"` + "`" + `
}
const (
// Predefined WSS namespaces to be used in
WssNsWSSE string = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
WssNsWSU string = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
WssNsType string = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"
)
type WSSSecurityHeader struct {
XMLName xml.Name ` + "`" + `xml:"http://schemas.xmlsoap.org/soap/envelope/ wsse:Security"` + "`" + `
XmlNSWsse string ` + "`" + `xml:"xmlns:wsse,attr"` + "`" + `
MustUnderstand string ` + "`" + `xml:"mustUnderstand,attr,omitempty"` + "`" + `
Token *WSSUsernameToken ` + "`" + `xml:",omitempty"` + "`" + `
}
type WSSUsernameToken struct {
XMLName xml.Name ` + "`" + `xml:"wsse:UsernameToken"` + "`" + `
XmlNSWsu string ` + "`" + `xml:"xmlns:wsu,attr"` + "`" + `
XmlNSWsse string ` + "`" + `xml:"xmlns:wsse,attr"` + "`" + `
Id string ` + "`" + `xml:"wsu:Id,attr,omitempty"` + "`" + `
Username *WSSUsername ` + "`" + `xml:",omitempty"` + "`" + `
Password *WSSPassword ` + "`" + `xml:",omitempty"` + "`" + `
}
type WSSUsername struct {
XMLName xml.Name ` + "`" + `xml:"wsse:Username"` + "`" + `
XmlNSWsse string ` + "`" + `xml:"xmlns:wsse,attr"` + "`" + `
Data string ` + "`" + `xml:",chardata"` + "`" + `
}
type WSSPassword struct {
XMLName xml.Name ` + "`" + `xml:"wsse:Password"` + "`" + `
XmlNSWsse string ` + "`" + `xml:"xmlns:wsse,attr"` + "`" + `
XmlNSType string ` + "`" + `xml:"Type,attr"` + "`" + `
Data string ` + "`" + `xml:",chardata"` + "`" + `
}
type BasicAuth struct {
Login string
Login string
Password string
}
type SOAPClient struct {
url string
tls bool
auth *BasicAuth
header interface{}
url string
tls bool
auth *BasicAuth
headers []interface{}
}
// **********
// Accepted solution from http://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-golang
// Author: Icza - http://stackoverflow.com/users/1705598/icza
const (
letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
letterIdxBits = 6 // 6 bits to represent a letter index
letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits
)
func randStringBytesMaskImprSrc(n int) string {
src := rand.NewSource(time.Now().UnixNano())
b := make([]byte, n)
// A src.Int63() generates 63 random bits, enough for letterIdxMax characters!
for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; {
if remain == 0 {
cache, remain = src.Int63(), letterIdxMax
}
if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
b[i] = letterBytes[idx]
i--
}
cache >>= letterIdxBits
remain--
}
return string(b)
}
// **********
func NewWSSSecurityHeader(user, pass, mustUnderstand string) *WSSSecurityHeader {
hdr := &WSSSecurityHeader{XmlNSWsse: WssNsWSSE, MustUnderstand: mustUnderstand}
hdr.Token = &WSSUsernameToken{XmlNSWsu: WssNsWSU, XmlNSWsse: WssNsWSSE, Id: "UsernameToken-" + randStringBytesMaskImprSrc(9)}
hdr.Token.Username = &WSSUsername{XmlNSWsse: WssNsWSSE, Data: user}
hdr.Token.Password = &WSSPassword{XmlNSWsse: WssNsWSSE, XmlNSType: WssNsType, Data: pass}
return hdr
}
func (b *SOAPBody) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
Expand Down Expand Up @@ -113,15 +194,17 @@ func NewSOAPClient(url string, tls bool, auth *BasicAuth) *SOAPClient {
}
}
func (s *SOAPClient) SetHeader(header interface{}) {
s.header = header
func (s *SOAPClient) AddHeader(header interface{}) {
s.headers = append(s.headers, header)
}
func (s *SOAPClient) Call(soapAction string, request, response interface{}) error {
envelope := SOAPEnvelope{}
if s.header != nil {
envelope.Header = &SOAPHeader{Header: s.header}
if s.headers != nil && len(s.headers) > 0 {
soapHeader := &SOAPHeader{Items: make([]interface{}, len(s.headers))}
copy(soapHeader.Items, s.headers)
envelope.Header = soapHeader
}
envelope.Body.Content = request
Expand Down Expand Up @@ -149,10 +232,8 @@ func (s *SOAPClient) Call(soapAction string, request, response interface{}) erro
}
req.Header.Add("Content-Type", "text/xml; charset=\"utf-8\"")
if soapAction != "" {
req.Header.Add("SOAPAction", soapAction)
}
req.Header.Add("SOAPAction", soapAction)
req.Header.Set("User-Agent", "gowsdl/0.1")
req.Close = true
Expand Down

0 comments on commit 9e55fc9

Please sign in to comment.