├── .gitignore
├── response.go
├── certificate.go
├── README.md
├── authnrequestInterface.go
├── authnrequest.go
└── LICENSE
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files, Static and Dynamic libs (Shared Objects)
2 | *.o
3 | *.a
4 | *.so
5 |
6 | # Folders
7 | _obj
8 | _test
9 |
10 | # Architecture specific extensions/prefixes
11 | *.[568vq]
12 | [568vq].out
13 |
14 | *.cgo1.go
15 | *.cgo2.c
16 | _cgo_defun.c
17 | _cgo_gotypes.go
18 | _cgo_export.*
19 |
20 | _testmain.go
21 |
22 | *.exe
23 |
--------------------------------------------------------------------------------
/response.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Matthew Baird
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package saml
16 |
17 | import (
18 | "crypto/x509"
19 | )
20 |
21 | type Response struct {
22 | XmlDoc string
23 | Settings AccountSettings
24 | certificate x509.Certificate
25 | }
26 |
--------------------------------------------------------------------------------
/certificate.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Matthew Baird, Andrew Mussey
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package saml
16 |
17 | import (
18 | "io/ioutil"
19 | "regexp"
20 | "strings"
21 | )
22 |
23 | func LoadCertificate(crtFile string) (string, error) {
24 | crtByte, err := ioutil.ReadFile(crtFile)
25 | if err != nil {
26 | return "", err
27 | }
28 | crtString := string(crtByte)
29 |
30 | re := regexp.MustCompile("---(.*)CERTIFICATE(.*)---")
31 | crtString = re.ReplaceAllString(crtString, "")
32 | crtString = strings.Trim(crtString, " \n")
33 | crtString = strings.Replace(crtString, "\n", "", -1)
34 |
35 | return crtString, err
36 | }
37 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | gosaml
2 | ======
3 |
4 | SAML client library written in Go (golang)
5 |
6 | SAML is the successful OASIS standard for cloud based single sign on (SSO). SAML allows for companies that maintain a security infrastructure internally to allow using that same set of credentials via a safe, secure mechanism with externally hosted services.
7 |
8 | For instance, New Relic allows you to configure a saml provider (https://newrelic.com/docs/subscriptions/saml-service-providers) so you can maintain your own credentials instead of using New Relic's.
9 |
10 | Ping Identity has a nice video for SAML here: https://www.pingidentity.com/resource-center/Introduction-to-SAML-Video.cfm
11 |
12 | Installation
13 | ------------
14 |
15 | Use the `go get` command to fetch `gosaml` and its dependencies into your local `$GOPATH`:
16 |
17 | $ go get github.com/mattbaird/gosaml
18 |
19 | Usage
20 | -----
21 |
22 | ### Generating Unsigned AuthnRequests
23 |
24 | ```go
25 | package main
26 |
27 | import (
28 | "fmt"
29 | "github.com/mattbaird/gosaml"
30 | )
31 |
32 | func main() {
33 | // Configure the app and account settings
34 | appSettings := saml.NewAppSettings("http://www.onelogin.net", "issuer")
35 | accountSettings := saml.NewAccountSettings("cert", "http://www.onelogin.net")
36 |
37 | // Construct an AuthnRequest
38 | authRequest := saml.NewAuthorizationRequest(*appSettings, *accountSettings)
39 |
40 | // Return a SAML AuthnRequest as a string
41 | saml, err := authRequest.GetRequest(false)
42 |
43 | if err != nil {
44 | fmt.Println(err)
45 | return
46 | }
47 | fmt.Println(saml)
48 | }
49 | ```
50 |
51 | The above code will generate the following AuthnRequest XML:
52 |
53 | ```xml
54 |
55 |
59 | https://sp.example.com/SAML2
60 |
61 |
62 |
63 | urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
64 |
65 |
66 | ```
67 |
68 | ### Generating Signed AuthnRequests
69 |
70 | See the github wiki for basic instructions on [generating an X.509 certificate for signing](https://github.com/mattbaird/gosaml/wiki/Generating-an-X.509-Certificate-for-Signing).
71 |
72 | ```go
73 | package main
74 |
75 | import (
76 | "fmt"
77 | "github.com/mattbaird/gosaml"
78 | )
79 |
80 | func main() {
81 | // Configure the app and account settings
82 | appSettings := saml.NewAppSettings("http://www.onelogin.net", "issuer")
83 | accountSettings := saml.NewAccountSettings("cert", "http://www.onelogin.net")
84 |
85 | // Construct an AuthnRequest
86 | authRequest := saml.NewAuthorizationRequest(*appSettings, *accountSettings)
87 |
88 | // Return a SAML AuthnRequest as a string
89 | saml, err := authRequest.GetSignedRequest(false, "/path/to/publickey.cer", "/path/to/privatekey.pem")
90 |
91 | if err != nil {
92 | fmt.Println(err)
93 | return
94 | }
95 | fmt.Println(saml)
96 | }
97 | ```
98 |
99 | The above code will generate the following AuthnRequest XML:
100 |
101 | ```xml
102 |
103 |
107 | https://sp.example.com/SAML2
108 |
109 |
110 |
111 | urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 | 8nJJwstdugjt6LJ+pbICc2iBwCc=
123 |
124 |
125 | J35w3/wk5pmrKn6qdfo4L0r0c...t2MGKH8w==
126 |
127 |
128 | MIICKzCCAdWgAwIBA...JHpg+GVGdcCty+4xA==
129 |
130 |
131 |
132 |
133 | ```
134 |
--------------------------------------------------------------------------------
/authnrequestInterface.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Matthew Baird
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package saml
16 |
17 | import (
18 | "encoding/xml"
19 | )
20 |
21 | type AuthorizationRequest struct {
22 | Id string
23 | IssueInstant string
24 | AppSettings AppSettings
25 | AccountSettings AccountSettings
26 | Base64 int
27 | }
28 |
29 | type AuthnRequest struct {
30 | XMLName xml.Name
31 | SAMLP string `xml:"xmlns:samlp,attr"`
32 | SAML string `xml:"xmlns:saml,attr"`
33 | ID string `xml:"ID,attr"`
34 | Version string `xml:"Version,attr"`
35 | ProtocolBinding string `xml:"ProtocolBinding,attr"`
36 | AssertionConsumerServiceURL string `xml:"AssertionConsumerServiceURL,attr,omitempty"`
37 | IssueInstant string `xml:"IssueInstant,attr"`
38 | AttributeConsumingServiceIndex int `xml:"AttributeConsumingServiceIndex,attr"`
39 | AssertionConsumerServiceIndex int `xml:"AssertionConsumerServiceIndex,attr,omitempty"`
40 | Issuer Issuer `xml:"Issuer"`
41 | NameIDPolicy NameIDPolicy `xml:"NameIDPolicy"`
42 | RequestedAuthnContext RequestedAuthnContext `xml:"RequestedAuthnContext"`
43 | }
44 |
45 | type AuthnSignedRequest struct {
46 | XMLName xml.Name
47 | SAMLP string `xml:"xmlns:samlp,attr"`
48 | SAML string `xml:"xmlns:saml,attr"`
49 | SAMLSIG string `xml:"xmlns:samlsig,attr"`
50 | ID string `xml:"ID,attr"`
51 | Version string `xml:"Version,attr"`
52 | ProtocolBinding string `xml:"ProtocolBinding,attr"`
53 | AssertionConsumerServiceURL string `xml:"AssertionConsumerServiceURL,attr"`
54 | IssueInstant string `xml:"IssueInstant,attr"`
55 | AssertionConsumerServiceIndex int `xml:"AssertionConsumerServiceIndex,attr"`
56 | AttributeConsumingServiceIndex int `xml:"AttributeConsumingServiceIndex,attr"`
57 | Issuer Issuer `xml:"Issuer"`
58 | NameIDPolicy NameIDPolicy `xml:"NameIDPolicy"`
59 | RequestedAuthnContext RequestedAuthnContext `xml:"RequestedAuthnContext"`
60 | AuthnContextClassRef AuthnContextClassRef `xml:"AuthnContextClassRef"`
61 | Signature Signature `xml:"Signature"`
62 | }
63 |
64 | type Issuer struct {
65 | XMLName xml.Name
66 | Url string `xml:",innerxml"`
67 | }
68 |
69 | type NameIDPolicy struct {
70 | XMLName xml.Name
71 | AllowCreate bool `xml:"AllowCreate,attr"`
72 | Format string `xml:"Format,attr"`
73 | }
74 |
75 | type RequestedAuthnContext struct {
76 | XMLName xml.Name
77 | SAMLP string `xml:"xmlns:samlp,attr"`
78 | Comparison string `xml:"Comparison,attr"`
79 | AuthnContextClassRef AuthnContextClassRef `xml:"AuthnContextClassRef"`
80 | }
81 |
82 | type AuthnContextClassRef struct {
83 | XMLName xml.Name
84 | SAML string `xml:"xmlns:saml,attr"`
85 | Transport string `xml:",innerxml"`
86 | }
87 |
88 | type Signature struct {
89 | XMLName xml.Name
90 | Id string `xml:"Id,attr"`
91 | SignedInfo SignedInfo `xml:",innerxml"`
92 | SignatureValue SignatureValue `xml:",innerxml"`
93 | KeyInfo KeyInfo `xml:",innerxml"`
94 | }
95 |
96 | type SignedInfo struct {
97 | XMLName xml.Name
98 | CanonicalizationMethod CanonicalizationMethod `xml:",innerxml"`
99 | SignatureMethod SignatureMethod `xml:",innerxml"`
100 | SamlsigReference SamlsigReference `xml:",innerxml"`
101 | }
102 |
103 | type SignatureValue struct {
104 | XMLName xml.Name
105 | }
106 |
107 | type KeyInfo struct {
108 | XMLName xml.Name
109 | X509Data X509Data `xml:",innerxml"`
110 | }
111 |
112 | type CanonicalizationMethod struct {
113 | XMLName xml.Name
114 | Algorithm string `xml:"Algorithm,attr"`
115 | }
116 |
117 | type SignatureMethod struct {
118 | XMLName xml.Name
119 | Algorithm string `xml:"Algorithm,attr"`
120 | }
121 |
122 | type SamlsigReference struct {
123 | XMLName xml.Name
124 | URI string `xml:"URI,attr"`
125 | Transforms Transforms `xml:",innerxml"`
126 | DigestMethod DigestMethod `xml:",innerxml"`
127 | DigestValue DigestValue `xml:",innerxml"`
128 | }
129 |
130 | type X509Data struct {
131 | XMLName xml.Name
132 | X509Certificate X509Certificate `xml:",innerxml"`
133 | }
134 |
135 | type Transforms struct {
136 | XMLName xml.Name
137 | Transform Transform
138 | }
139 |
140 | type DigestMethod struct {
141 | XMLName xml.Name
142 | Algorithm string `xml:"Algorithm,attr"`
143 | }
144 |
145 | type DigestValue struct {
146 | XMLName xml.Name
147 | }
148 |
149 | type X509Certificate struct {
150 | XMLName xml.Name
151 | Cert string `xml:",innerxml"`
152 | }
153 |
154 | type Transform struct {
155 | XMLName xml.Name
156 | Algorithm string `xml:"Algorithm,attr"`
157 | }
158 |
159 | type AccountSettings struct {
160 | Certificate string
161 | IDP_SSO_Target_URL string
162 | }
163 |
164 | type AppSettings struct {
165 | AssertionConsumerServiceURL string
166 | Issuer string
167 | }
168 |
--------------------------------------------------------------------------------
/authnrequest.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Matthew Baird, Andrew Mussey
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package saml
16 |
17 | import (
18 | "encoding/base64"
19 | "encoding/xml"
20 | "fmt"
21 | "github.com/nu7hatch/gouuid"
22 | "io/ioutil"
23 | "net/url"
24 | "os"
25 | "os/exec"
26 | "strings"
27 | "time"
28 | )
29 |
30 | func NewAuthorizationRequest(appSettings AppSettings, accountSettings AccountSettings) *AuthorizationRequest {
31 | myIdUUID, err := uuid.NewV4()
32 | if err != nil {
33 | fmt.Println("Error is UUID Generation:", err)
34 | }
35 | //yyyy-MM-dd'T'H:mm:ss
36 | layout := "2006-01-02T15:04:05"
37 | t := time.Now().UTC().Format(layout)
38 |
39 | return &AuthorizationRequest{AccountSettings: accountSettings, AppSettings: appSettings, Id: "_" + myIdUUID.String(), IssueInstant: t}
40 | }
41 |
42 | // GetRequest returns a string formatted XML document that represents the SAML document
43 | // TODO: parameterize more parts of the request
44 | func (ar AuthorizationRequest) GetRequest(base64Encode bool) (string, error) {
45 | d := AuthnRequest{
46 | XMLName: xml.Name{
47 | Local: "samlp:AuthnRequest",
48 | },
49 | SAMLP: "urn:oasis:names:tc:SAML:2.0:protocol",
50 | SAML: "urn:oasis:names:tc:SAML:2.0:assertion",
51 | ID: ar.Id,
52 | ProtocolBinding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
53 | Version: "2.0",
54 | AssertionConsumerServiceURL: ar.AppSettings.AssertionConsumerServiceURL,
55 | Issuer: Issuer{
56 | XMLName: xml.Name{
57 | Local: "saml:Issuer",
58 | },
59 | Url: ar.AppSettings.Issuer,
60 | },
61 | IssueInstant: ar.IssueInstant,
62 | NameIDPolicy: NameIDPolicy{
63 | XMLName: xml.Name{
64 | Local: "samlp:NameIDPolicy",
65 | },
66 | AllowCreate: true,
67 | Format: "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
68 | },
69 | RequestedAuthnContext: RequestedAuthnContext{
70 | XMLName: xml.Name{
71 | Local: "samlp:RequestedAuthnContext",
72 | },
73 | SAMLP: "urn:oasis:names:tc:SAML:2.0:protocol",
74 | Comparison: "exact",
75 |
76 | AuthnContextClassRef: AuthnContextClassRef{
77 | XMLName: xml.Name{
78 | Local: "saml:AuthnContextClassRef",
79 | },
80 | SAML: "urn:oasis:names:tc:SAML:2.0:assertion",
81 | Transport: "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport",
82 | },
83 | },
84 | }
85 | b, err := xml.MarshalIndent(d, "", " ")
86 | if err != nil {
87 | return "", err
88 | }
89 |
90 | xmlAuthnRequest := fmt.Sprintf("\n%s", b)
91 |
92 | if base64Encode {
93 | data := []byte(xmlAuthnRequest)
94 | return base64.StdEncoding.EncodeToString(data), nil
95 | } else {
96 | return string(xmlAuthnRequest), nil
97 | }
98 | }
99 |
100 | // GetSignedRequest returns a string formatted XML document that represents the SAML document
101 | // TODO: parameterize more parts of the request
102 | func (ar AuthorizationRequest) GetSignedRequest(base64Encode bool, publicCert string, privateCert string) (string, error) {
103 | cert, err := LoadCertificate(publicCert)
104 | if err != nil {
105 | return "", err
106 | }
107 |
108 | d := AuthnSignedRequest{
109 | XMLName: xml.Name{
110 | Local: "samlp:AuthnRequest",
111 | },
112 | SAMLP: "urn:oasis:names:tc:SAML:2.0:protocol",
113 | SAML: "urn:oasis:names:tc:SAML:2.0:assertion",
114 | SAMLSIG: "http://www.w3.org/2000/09/xmldsig#",
115 | ID: ar.Id,
116 | ProtocolBinding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
117 | Version: "2.0",
118 | AssertionConsumerServiceURL: ar.AppSettings.AssertionConsumerServiceURL,
119 | Issuer: Issuer{
120 | XMLName: xml.Name{
121 | Local: "saml:Issuer",
122 | },
123 | Url: ar.AppSettings.Issuer,
124 | },
125 | IssueInstant: ar.IssueInstant,
126 | NameIDPolicy: NameIDPolicy{
127 | XMLName: xml.Name{
128 | Local: "samlp:NameIDPolicy",
129 | },
130 | AllowCreate: true,
131 | Format: "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
132 | },
133 | RequestedAuthnContext: RequestedAuthnContext{
134 | XMLName: xml.Name{
135 | Local: "samlp:RequestedAuthnContext",
136 | },
137 | SAMLP: "urn:oasis:names:tc:SAML:2.0:protocol",
138 | Comparison: "exact",
139 | },
140 | AuthnContextClassRef: AuthnContextClassRef{
141 | XMLName: xml.Name{
142 | Local: "saml:AuthnContextClassRef",
143 | },
144 | SAML: "urn:oasis:names:tc:SAML:2.0:assertion",
145 | Transport: "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport",
146 | },
147 | Signature: Signature{
148 | XMLName: xml.Name{
149 | Local: "samlsig:Signature",
150 | },
151 | Id: "Signature1",
152 | SignedInfo: SignedInfo{
153 | XMLName: xml.Name{
154 | Local: "samlsig:SignedInfo",
155 | },
156 | CanonicalizationMethod: CanonicalizationMethod{
157 | XMLName: xml.Name{
158 | Local: "samlsig:CanonicalizationMethod",
159 | },
160 | Algorithm: "http://www.w3.org/2001/10/xml-exc-c14n#",
161 | },
162 | SignatureMethod: SignatureMethod{
163 | XMLName: xml.Name{
164 | Local: "samlsig:SignatureMethod",
165 | },
166 | Algorithm: "http://www.w3.org/2000/09/xmldsig#rsa-sha1",
167 | },
168 | SamlsigReference: SamlsigReference{
169 | XMLName: xml.Name{
170 | Local: "samlsig:Reference",
171 | },
172 | URI: "#" + ar.Id,
173 | Transforms: Transforms{
174 | XMLName: xml.Name{
175 | Local: "samlsig:Transforms",
176 | },
177 | Transform: Transform{
178 | XMLName: xml.Name{
179 | Local: "samlsig:Transform",
180 | },
181 | Algorithm: "http://www.w3.org/2000/09/xmldsig#enveloped-signature",
182 | },
183 | },
184 | DigestMethod: DigestMethod{
185 | XMLName: xml.Name{
186 | Local: "samlsig:DigestMethod",
187 | },
188 | Algorithm: "http://www.w3.org/2000/09/xmldsig#sha1",
189 | },
190 | DigestValue: DigestValue{
191 | XMLName: xml.Name{
192 | Local: "samlsig:DigestValue",
193 | },
194 | },
195 | },
196 | },
197 | SignatureValue: SignatureValue{
198 | XMLName: xml.Name{
199 | Local: "samlsig:SignatureValue",
200 | },
201 | },
202 | KeyInfo: KeyInfo{
203 | XMLName: xml.Name{
204 | Local: "samlsig:KeyInfo",
205 | },
206 | X509Data: X509Data{
207 | XMLName: xml.Name{
208 | Local: "samlsig:X509Data",
209 | },
210 | X509Certificate: X509Certificate{
211 | XMLName: xml.Name{
212 | Local: "samlsig:X509Certificate",
213 | },
214 | Cert: cert,
215 | },
216 | },
217 | },
218 | },
219 | }
220 | b, err := xml.MarshalIndent(d, "", " ")
221 | if err != nil {
222 | return "", err
223 | }
224 |
225 | samlAuthnRequest := string(b)
226 | // Write the SAML to a file.
227 |
228 | samlXmlsecInput, err := ioutil.TempFile(os.TempDir(), "tmpgs")
229 | if err != nil {
230 | return "", err
231 | }
232 | samlXmlsecOutput, err := ioutil.TempFile(os.TempDir(), "tmpgs")
233 | if err != nil {
234 | return "", err
235 | }
236 |
237 | samlXmlsecOutput.Close()
238 |
239 | samlXmlsecInput.WriteString("\n")
240 | samlXmlsecInput.WriteString(samlAuthnRequest)
241 | samlXmlsecInput.Close()
242 |
243 | _, errOut := exec.Command("xmlsec1", "--sign", "--privkey-pem", privateCert,
244 | "--id-attr:ID", "urn:oasis:names:tc:SAML:2.0:protocol:AuthnRequest",
245 | "--output", samlXmlsecOutput.Name(), samlXmlsecInput.Name()).Output()
246 | if errOut != nil {
247 | return "", errOut
248 | }
249 |
250 | samlSignedRequest, err := ioutil.ReadFile(samlXmlsecOutput.Name())
251 | if err != nil {
252 | return "", err
253 | }
254 | samlSignedRequestXml := strings.Trim(string(samlSignedRequest), "\n")
255 |
256 | if base64Encode {
257 | data := []byte(samlSignedRequestXml)
258 | return base64.StdEncoding.EncodeToString(data), nil
259 | } else {
260 | return string(samlSignedRequestXml), nil
261 | }
262 | }
263 |
264 | // String reqString = accSettings.getIdp_sso_target_url()+"?SAMLRequest=" +
265 | // AuthRequest.getRidOfCRLF(URLEncoder.encode(authReq.getRequest(AuthRequest.base64),"UTF-8"));
266 | func (ar AuthorizationRequest) GetRequestUrl() (string, error) {
267 | u, err := url.Parse(ar.AccountSettings.IDP_SSO_Target_URL)
268 | if err != nil {
269 | return "", err
270 | }
271 | base64EncodedUTF8SamlRequest, err := ar.GetRequest(true)
272 | if err != nil {
273 | return "", err
274 | }
275 |
276 | q := u.Query()
277 | q.Add("SAMLRequest", base64EncodedUTF8SamlRequest)
278 |
279 | u.RawQuery = q.Encode()
280 | return u.String(), nil
281 | }
282 |
283 | func NewAccountSettings(cert string, targetUrl string) *AccountSettings {
284 | return &AccountSettings{cert, targetUrl}
285 | }
286 |
287 | func NewAppSettings(assertionServiceUrl string, issuer string) *AppSettings {
288 | return &AppSettings{assertionServiceUrl, issuer}
289 | }
290 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction, and
10 | distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright
13 | owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all other entities
16 | that control, are controlled by, or are under common control with that entity.
17 | For the purposes of this definition, "control" means (i) the power, direct or
18 | indirect, to cause the direction or management of such entity, whether by
19 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
20 | outstanding shares, or (iii) beneficial ownership of such entity.
21 |
22 | "You" (or "Your") shall mean an individual or Legal Entity exercising
23 | permissions granted by this License.
24 |
25 | "Source" form shall mean the preferred form for making modifications, including
26 | but not limited to software source code, documentation source, and configuration
27 | files.
28 |
29 | "Object" form shall mean any form resulting from mechanical transformation or
30 | translation of a Source form, including but not limited to compiled object code,
31 | generated documentation, and conversions to other media types.
32 |
33 | "Work" shall mean the work of authorship, whether in Source or Object form, made
34 | available under the License, as indicated by a copyright notice that is included
35 | in or attached to the work (an example is provided in the Appendix below).
36 |
37 | "Derivative Works" shall mean any work, whether in Source or Object form, that
38 | is based on (or derived from) the Work and for which the editorial revisions,
39 | annotations, elaborations, or other modifications represent, as a whole, an
40 | original work of authorship. For the purposes of this License, Derivative Works
41 | shall not include works that remain separable from, or merely link (or bind by
42 | name) to the interfaces of, the Work and Derivative Works thereof.
43 |
44 | "Contribution" shall mean any work of authorship, including the original version
45 | of the Work and any modifications or additions to that Work or Derivative Works
46 | thereof, that is intentionally submitted to Licensor for inclusion in the Work
47 | by the copyright owner or by an individual or Legal Entity authorized to submit
48 | on behalf of the copyright owner. For the purposes of this definition,
49 | "submitted" means any form of electronic, verbal, or written communication sent
50 | to the Licensor or its representatives, including but not limited to
51 | communication on electronic mailing lists, source code control systems, and
52 | issue tracking systems that are managed by, or on behalf of, the Licensor for
53 | the purpose of discussing and improving the Work, but excluding communication
54 | that is conspicuously marked or otherwise designated in writing by the copyright
55 | owner as "Not a Contribution."
56 |
57 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf
58 | of whom a Contribution has been received by Licensor and subsequently
59 | incorporated within the Work.
60 |
61 | 2. Grant of Copyright License.
62 |
63 | Subject to the terms and conditions of this License, each Contributor hereby
64 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
65 | irrevocable copyright license to reproduce, prepare Derivative Works of,
66 | publicly display, publicly perform, sublicense, and distribute the Work and such
67 | Derivative Works in Source or Object form.
68 |
69 | 3. Grant of Patent License.
70 |
71 | Subject to the terms and conditions of this License, each Contributor hereby
72 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
73 | irrevocable (except as stated in this section) patent license to make, have
74 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where
75 | such license applies only to those patent claims licensable by such Contributor
76 | that are necessarily infringed by their Contribution(s) alone or by combination
77 | of their Contribution(s) with the Work to which such Contribution(s) was
78 | submitted. If You institute patent litigation against any entity (including a
79 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a
80 | Contribution incorporated within the Work constitutes direct or contributory
81 | patent infringement, then any patent licenses granted to You under this License
82 | for that Work shall terminate as of the date such litigation is filed.
83 |
84 | 4. Redistribution.
85 |
86 | You may reproduce and distribute copies of the Work or Derivative Works thereof
87 | in any medium, with or without modifications, and in Source or Object form,
88 | provided that You meet the following conditions:
89 |
90 | You must give any other recipients of the Work or Derivative Works a copy of
91 | this License; and
92 | You must cause any modified files to carry prominent notices stating that You
93 | changed the files; and
94 | You must retain, in the Source form of any Derivative Works that You distribute,
95 | all copyright, patent, trademark, and attribution notices from the Source form
96 | of the Work, excluding those notices that do not pertain to any part of the
97 | Derivative Works; and
98 | If the Work includes a "NOTICE" text file as part of its distribution, then any
99 | Derivative Works that You distribute must include a readable copy of the
100 | attribution notices contained within such NOTICE file, excluding those notices
101 | that do not pertain to any part of the Derivative Works, in at least one of the
102 | following places: within a NOTICE text file distributed as part of the
103 | Derivative Works; within the Source form or documentation, if provided along
104 | with the Derivative Works; or, within a display generated by the Derivative
105 | Works, if and wherever such third-party notices normally appear. The contents of
106 | the NOTICE file are for informational purposes only and do not modify the
107 | License. You may add Your own attribution notices within Derivative Works that
108 | You distribute, alongside or as an addendum to the NOTICE text from the Work,
109 | provided that such additional attribution notices cannot be construed as
110 | modifying the License.
111 | You may add Your own copyright statement to Your modifications and may provide
112 | additional or different license terms and conditions for use, reproduction, or
113 | distribution of Your modifications, or for any such Derivative Works as a whole,
114 | provided Your use, reproduction, and distribution of the Work otherwise complies
115 | with the conditions stated in this License.
116 |
117 | 5. Submission of Contributions.
118 |
119 | Unless You explicitly state otherwise, any Contribution intentionally submitted
120 | for inclusion in the Work by You to the Licensor shall be under the terms and
121 | conditions of this License, without any additional terms or conditions.
122 | Notwithstanding the above, nothing herein shall supersede or modify the terms of
123 | any separate license agreement you may have executed with Licensor regarding
124 | such Contributions.
125 |
126 | 6. Trademarks.
127 |
128 | This License does not grant permission to use the trade names, trademarks,
129 | service marks, or product names of the Licensor, except as required for
130 | reasonable and customary use in describing the origin of the Work and
131 | reproducing the content of the NOTICE file.
132 |
133 | 7. Disclaimer of Warranty.
134 |
135 | Unless required by applicable law or agreed to in writing, Licensor provides the
136 | Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
137 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
138 | including, without limitation, any warranties or conditions of TITLE,
139 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
140 | solely responsible for determining the appropriateness of using or
141 | redistributing the Work and assume any risks associated with Your exercise of
142 | permissions under this License.
143 |
144 | 8. Limitation of Liability.
145 |
146 | In no event and under no legal theory, whether in tort (including negligence),
147 | contract, or otherwise, unless required by applicable law (such as deliberate
148 | and grossly negligent acts) or agreed to in writing, shall any Contributor be
149 | liable to You for damages, including any direct, indirect, special, incidental,
150 | or consequential damages of any character arising as a result of this License or
151 | out of the use or inability to use the Work (including but not limited to
152 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or
153 | any and all other commercial damages or losses), even if such Contributor has
154 | been advised of the possibility of such damages.
155 |
156 | 9. Accepting Warranty or Additional Liability.
157 |
158 | While redistributing the Work or Derivative Works thereof, You may choose to
159 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or
160 | other liability obligations and/or rights consistent with this License. However,
161 | in accepting such obligations, You may act only on Your own behalf and on Your
162 | sole responsibility, not on behalf of any other Contributor, and only if You
163 | agree to indemnify, defend, and hold each Contributor harmless for any liability
164 | incurred by, or claims asserted against, such Contributor by reason of your
165 | accepting any such warranty or additional liability.
166 |
167 | END OF TERMS AND CONDITIONS
168 |
169 | APPENDIX: How to apply the Apache License to your work
170 |
171 | To apply the Apache License to your work, attach the following boilerplate
172 | notice, with the fields enclosed by brackets "[]" replaced with your own
173 | identifying information. (Don't include the brackets!) The text should be
174 | enclosed in the appropriate comment syntax for the file format. We also
175 | recommend that a file or class name and description of purpose be included on
176 | the same "printed page" as the copyright notice for easier identification within
177 | third-party archives.
178 |
179 | Copyright [yyyy] [name of copyright owner]
180 |
181 | Licensed under the Apache License, Version 2.0 (the "License");
182 | you may not use this file except in compliance with the License.
183 | You may obtain a copy of the License at
184 |
185 | http://www.apache.org/licenses/LICENSE-2.0
186 |
187 | Unless required by applicable law or agreed to in writing, software
188 | distributed under the License is distributed on an "AS IS" BASIS,
189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
190 | See the License for the specific language governing permissions and
191 | limitations under the License.
192 |
--------------------------------------------------------------------------------