foam

package module
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 15, 2019 License: Apache-2.0 Imports: 11 Imported by: 0

README

Foam: SOAP's best friend

Build Status GoDoc

Foam is a SOAP 1.1 client for Go which implements the WSS BinarySecurityToken and XML Signature standards.

It supports signing with X.509 certificates using the rsa-sha1 algorithm.

Dependencies

This package uses cgo and has an hard-dependency on XMLSec and LibXML2, so don't skimp on the installation instructions.

Due to this dependency, this library is not recommended for simpler use-cases where XML Digital Signature is not a requirement.

Usage

package foam_test

import (
    "context"
    "encoding/xml"
    "io/ioutil"
    "log"
    "net/http"
    "time"

    "github.com/cabify/foam"
)

type foo struct {
    XMLName xml.Name `xml:"foo"`
    ID      string   `xml:"id,attr"`
}

type baz struct {
    XMLName xml.Name `xml:"baz"`
    Value   string   `xml:"value,attr"`
}

func main() {
    // Read the RSA certificate and private key
    cert, err := ioutil.ReadFile("my_server.crt")
    if err != nil {
        log.Fatalf("read certificate: %v", err)
    }
    key, err := ioutil.ReadFile("my_server.key")
    if err != nil {
        log.Fatalf("read key: %v", err)
    }

    // Create an HTTP client with a timeout
    httpClient := &http.Client{
        Timeout: 3 * time.Second,
    }

    client, err := foam.NewClient("https://example.com/MyServer?wsdl",
        foam.WithBinarySecurityToken(cert, key),
        foam.WithHTTPClient(httpClient))
    if err != nil {
        log.Fatalf("read key: %v", err)
    }

    var res baz
    if err := client.Call(context.Background(), "MyEndpoint", &foo{ID: "1"}, &res); err != nil {
        log.Fatalf("make request: %v", err)
    }
}

Installation

macOS

The easiest way to install all the required dependencies is with Homebrew:

brew install libxmlsec1 libxml2 pkg-config

Make sure to follow the post-install instructions printed by homebrew, otherwise the Go compiler won't be able to find the libraries on your machine.

Linux
Debian
apt-get install -y libxml2-dev libxmlsec1-dev pkg-config

Build

When building the package, you must have CGO enabled and set the CGO_CFLAGS_ALLOW to -w|-UXMLSEC_CRYPTO_DYNAMIC_LOADING. For example:

CGO_CFLAGS_ALLOW="-w|-UXMLSEC_CRYPTO_DYNAMIC_LOADING" go build

License

Foam is copyright (c) 2019 Maxi Mobility Spain.

Licensed under the Apache License, Version 2.0.

Check LICENSE for more information.

Documentation

Overview

Package foam is a SOAP 1.1 client for Go which implements the WSS BinarySecurityToken and XML Digital Signature standards.

Due to limitations in Go abilities to handle XML, it uses CGO and depends on xmlsec and LibXML2 to sign the generated XML documents. For simpler use-cases that don't require signed documents, a different library is recommended.

To compile the package, you must allow some CGO flags:

CGO_CFLAGS_ALLOW="-w|-UXMLSEC_CRYPTO_DYNAMIC_LOADING"

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BinarySecurityTokenHeader

type BinarySecurityTokenHeader struct {
	XMLName      xml.Name `xml:"wsse:BinarySecurityToken"`
	WSUID        string   `xml:"wsu:Id,attr"`
	EncodingType string   `xml:"EncodingType,attr"`
	ValueType    string   `xml:"ValueType,attr"`
	Token        string   `xml:",innerxml"`
}

type CanonicalizationMethod

type CanonicalizationMethod struct {
	XMLName   xml.Name `xml:"ds:CanonicalizationMethod"`
	Algorithm string   `xml:"Algorithm,attr"`
}

type Client

type Client struct {
	// contains filtered or unexported fields
}

A Client is a SOAP client. The zero value is not useful, you should instead call NewClient to get an initialized client.

func NewClient

func NewClient(wsdlUrl string, setters ...Option) (*Client, error)

NewClients creates a new SOAP client with the provided options

Example
package main

import (
	"context"
	"encoding/xml"
	"io/ioutil"
	"log"
	"net/http"
	"time"

	"github.com/cabify/foam"
)

type foo struct {
	XMLName xml.Name `xml:"foo"`
	ID      string   `xml:"id,attr"`
}

type baz struct {
	XMLName xml.Name `xml:"baz"`
	Value   string   `xml:"value,attr"`
}

func main() {
	// Read the RSA certificate and private key
	cert, err := ioutil.ReadFile("my_server.crt")
	if err != nil {
		log.Fatalf("read certificate: %v", err)
	}
	key, err := ioutil.ReadFile("my_server.key")
	if err != nil {
		log.Fatalf("read key: %v", err)
	}

	// Create an HTTP client with a timeout
	httpClient := &http.Client{
		Timeout: 3 * time.Second,
	}

	client, err := foam.NewClient("https://example.com/MyServer?wsdl",
		foam.WithBinarySecurityToken(cert, key),
		foam.WithHTTPClient(httpClient))
	if err != nil {
		log.Fatalf("read key: %v", err)
	}

	var res baz
	if err := client.Call(context.Background(), "MyEndpoint", &foo{ID: "1"}, &res); err != nil {
		log.Fatalf("make request: %v", err)
	}
}
Output:

func (*Client) Call

func (c *Client) Call(ctx context.Context, endpoint string, payload, response interface{}) error

Call performs a SOAP 1.1 request to the specified endpoint.

The payload will be seialized to XML and then included into a SOAP 1.1 evelope, containing the BinarySecurityToken WSSE header. The generated XML body is then signled with xmlsec.

The response body will be unmarshalled into the response interface.

type DSReference

type DSReference struct {
	XMLName      xml.Name `xml:"ds:Reference"`
	URI          string   `xml:"URI,attr"`
	Transforms   Transforms
	DigestMethod DigestMethod
	DigestValue  DigestValue
}

type DigestMethod

type DigestMethod struct {
	XMLName   xml.Name `xml:"ds:DigestMethod"`
	Algorithm string   `xml:"Algorithm,attr"`
}

type DigestValue

type DigestValue struct {
	XMLName xml.Name `xml:"ds:DigestValue"`
}

type Doer

type Doer interface {
	Do(req *http.Request) (*http.Response, error)
}

Doer is the interface used to perform HTTP request. The stdlib http.Client implements this interface.

type ErrHTTP added in v1.1.0

type ErrHTTP struct {
	StatusCode int
	Status     string
}

func (ErrHTTP) Error added in v1.1.0

func (e ErrHTTP) Error() string

type KeyInfo

type KeyInfo struct {
	XMLName                xml.Name `xml:"ds:KeyInfo"`
	SecurityTokenReference SecurityTokenReference
}

type Option

type Option func(*Options) error

Option is a setter for a client option

func WithBinarySecurityToken

func WithBinarySecurityToken(cert, key []byte) Option

WithBinarySecurityToken adds a binary security token to every otugoing requests. The requests will also be signed with the provided private key.

func WithHTTPClient

func WithHTTPClient(client Doer) Option

WithHTTPClient sets the client that will be used to send the HTTP requests.

type Options

type Options struct {
	// contains filtered or unexported fields
}

Options contains the options that can be set on the client. Options should only be modified by the provided setter functions.

type SOAPBody

type SOAPBody struct {
	XMLName xml.Name `xml:"soapenv:Body"`
	WSUNS   string   `xml:"xmlns:wsu,attr"`
	WSUID   string   `xml:"wsu:Id,attr"`
	XMLID   string   `xml:"xml:id,attr"`
	Payload interface{}
}

type SOAPEnvelope

type SOAPEnvelope struct {
	XMLName xml.Name `xml:"soapenv:Envelope"`
	SOAPNS  string   `xml:"xmlns:soapenv,attr"`
	Header  *SOAPHeader
	Body    *SOAPBody
}

type SOAPHeader

type SOAPHeader struct {
	XMLName  xml.Name `xml:"soapenv:Header"`
	Security *SecurityHeader
}

type SecurityHeader

type SecurityHeader struct {
	XMLName             xml.Name `xml:"wsse:Security"`
	XMLNSWSSE           string   `xml:"xmlns:wsse,attr"`
	XMLNSWSU            string   `xml:"xmlns:wsu,attr"`
	BinarySecurityToken *BinarySecurityTokenHeader
	Signature           *SignatureHeader
}

type SecurityTokenReference

type SecurityTokenReference struct {
	XMLName   xml.Name `xml:"wsse:SecurityTokenReference"`
	Reference WSSEReference
}

type SignatureHeader

type SignatureHeader struct {
	XMLName        xml.Name `xml:"ds:Signature"`
	XMLNSDS        string   `xml:"xmlns:ds,attr"`
	ID             string   `xml:"Id,attr"`
	SignedInfo     SignedInfo
	SignatureValue SignatureValue
	KeyInfo        KeyInfo
}

type SignatureMethod

type SignatureMethod struct {
	XMLName   xml.Name `xml:"ds:SignatureMethod"`
	Algorithm string   `xml:"Algorithm,attr"`
}

type SignatureValue

type SignatureValue struct {
	XMLName xml.Name `xml:"ds:SignatureValue"`
}

type SignedInfo

type SignedInfo struct {
	XMLName                xml.Name `xml:"ds:SignedInfo"`
	CanonicalizationMethod CanonicalizationMethod
	SignatureMethod        SignatureMethod
	Reference              DSReference
}

type Transform

type Transform struct {
	XMLName   xml.Name `xml:"ds:Transform"`
	Algorithm string   `xml:"Algorithm,attr"`
}

type Transforms

type Transforms struct {
	XMLName   xml.Name `xml:"ds:Transforms"`
	Transform Transform
}

type WSSEReference

type WSSEReference struct {
	XMLName   xml.Name `xml:"wsse:Reference"`
	URI       string   `xml:"URI,attr"`
	ValueType string   `xml:"ValueType,attr"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL