/
credentials.go
70 lines (63 loc) · 2 KB
/
credentials.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package xml
import (
"regexp"
"strings"
"github.com/beevik/etree"
)
type Credential struct {
Tags map[string]string
}
/*
Converts credentials.xml into a slice of structs with all fields reduced.
XML version is ignored as I could no find a parser which could handle xml 1.0+
Jenkins credentials.xml is using xml 1.1 but it does not seem to be using any of the new features.
With xml 1.0+ this can eventually blow up.
*/
func ParseCredentialsXml(credentialsXml []byte) (*[]Credential, error) {
credentialsXpaths := []string{"//java.util.concurrent.CopyOnWriteArrayList/*", "//list/*"}
credentials := make([]Credential, 0)
credentialsDocument, err := parseXml(credentialsXml)
if err != nil {
return &credentials, err
}
for _, credentialsXpath := range credentialsXpaths {
for _, credentialNode := range credentialsDocument.FindElements(credentialsXpath) {
credential := &Credential{
Tags: map[string]string{},
}
for _, child := range credentialNode.ChildElements() {
reduceFields(child, credential)
}
credentials = append(credentials, *credential)
}
}
return &credentials, nil
}
/*
There is a possibility that a field could get overridden but I haven't seen an example of that yet.
*/
func reduceFields(node *etree.Element, credential *Credential) {
credential.Tags[node.Tag] = strings.TrimSpace(node.Text())
for _, child := range node.ChildElements() {
credential.Tags[child.Tag] = strings.TrimSpace(child.Text())
reduceFields(child, credential)
}
}
func parseXml(credentialsXml []byte) (*etree.Document, error) {
document := etree.NewDocument()
err := document.ReadFromString(stripXmlVersion(credentialsXml))
if err != nil {
return nil, err
}
return document, nil
}
/*
HACK ALERT:
Stripping xml version because I could not find any decoder which would parse xml version 1.0+
Jenkins uses xml version 1.1+ so this may blow up.
*/
func stripXmlVersion(credentials []byte) string {
return regexp.
MustCompile("(?m)^.*<?xml.*$").
ReplaceAllString(string(credentials), "")
}