Files
teleport/lib/utils/aws/xml.go
T
STeve (Xin) Huang 2111f51441 Support assumed roles for "tsh proxy aws" (#20568)
* Support assumed roles for "tsh proxy aws"

* fix typo for RenameHeader

* add error handler

* review comments

* enhance bad parameter

* fix typo

* Forbit requests by assumed role in endpoint url mode.

* fix host check
2023-01-30 21:21:43 +00:00

82 lines
2.5 KiB
Go

/*
Copyright 2023 Gravitational, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package aws
import (
"bytes"
"encoding/xml"
"github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil"
"github.com/gravitational/trace"
)
// IsXMLOfLocalName returns true if the root XML has the provided (local) name.
func IsXMLOfLocalName(data []byte, wantLocalName string) bool {
var name xml.Name
if err := xml.Unmarshal(data, &name); err == nil {
return wantLocalName == name.Local
}
return false
}
// UnmarshalXMLChildNode decodes the XML-encoded data and stores the child node
// with the specified name to v, where v is a pointer to an AWS SDK v1 struct.
func UnmarshalXMLChildNode(v interface{}, data []byte, childName string) error {
return trace.Wrap(xmlutil.UnmarshalXML(v, xml.NewDecoder(bytes.NewReader(data)), childName))
}
// MarshalXML marshals the provided root name and a map of children in XML with
// default indent (prefix "", indent " ").
func MarshalXML(rootName xml.Name, children map[string]any) ([]byte, error) {
var buf bytes.Buffer
encoder := xml.NewEncoder(&buf)
encoder.Indent("", " ")
err := encodeXMLNode(encoder, rootName, func() error {
for childName, childValue := range children {
if err := encodeXMLNodeAWSSDKV1(encoder, childName, childValue); err != nil {
return trace.Wrap(err)
}
}
return nil
})
if err != nil {
return nil, trace.Wrap(err)
}
if err := trace.Wrap(encoder.Flush()); err != nil {
return nil, trace.Wrap(err)
}
return buf.Bytes(), nil
}
func encodeXMLNode(encoder *xml.Encoder, name xml.Name, encodeChildren func() error) error {
startElement := xml.StartElement{Name: name}
if err := encoder.EncodeToken(startElement); err != nil {
return trace.Wrap(err)
}
if err := encodeChildren(); err != nil {
return trace.Wrap(err)
}
return trace.Wrap(encoder.EncodeToken(startElement.End()))
}
func encodeXMLNodeAWSSDKV1(encoder *xml.Encoder, name string, v any) error {
return encodeXMLNode(encoder, xml.Name{Local: name}, func() error {
return trace.Wrap(xmlutil.BuildXML(v, encoder))
})
}