Skip to content

Commit 81735a5

Browse files
committed
fix lint errors, update github test configuration for current go versions
1 parent aee3fb1 commit 81735a5

File tree

5 files changed

+78
-73
lines changed

5 files changed

+78
-73
lines changed

.github/workflows/test.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
runs-on: ubuntu-latest
1212
strategy:
1313
matrix:
14-
go: [ '1.16.x', '1.17.x', '1.18.x' ]
14+
go: [ '1.18.x', '1.19.x', '1.20.x' ]
1515
steps:
1616
- name: Check out code into the Go module directory
1717
uses: actions/checkout@v2

saml.go

+70-64
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
// Package saml contains a partial implementation of the SAML standard in golang.
22
// SAML is a standard for identity federation, i.e. either allowing a third party to authenticate your users or allowing third parties to rely on us to authenticate their users.
33
//
4-
// Introduction
4+
// # Introduction
55
//
66
// In SAML parlance an Identity Provider (IDP) is a service that knows how to authenticate users. A Service Provider (SP) is a service that delegates authentication to an IDP. If you are building a service where users log in with someone else's credentials, then you are a Service Provider. This package supports implementing both service providers and identity providers.
77
//
88
// The core package contains the implementation of SAML. The package samlsp provides helper middleware suitable for use in Service Provider applications. The package samlidp provides a rudimentary IDP service that is useful for testing or as a starting point for other integrations.
99
//
10-
// Breaking Changes
10+
// # Breaking Changes
1111
//
1212
// Version 0.4.0 introduces a few breaking changes to the _samlsp_ package in order to make the package more extensible, and to clean up the interfaces a bit. The default behavior remains the same, but you can now provide interface implementations of _RequestTracker_ (which tracks pending requests), _Session_ (which handles maintaining a session) and _OnError_ which handles reporting errors.
1313
//
@@ -32,90 +32,96 @@
3232
// - `CookieDomain` - Instead assign a custom CookieRequestTracker or CookieSessionProvider
3333
// - `CookieDomain` - Instead assign a custom CookieRequestTracker or CookieSessionProvider
3434
//
35-
// Getting Started as a Service Provider
35+
// # Getting Started as a Service Provider
3636
//
3737
// Let us assume we have a simple web application to protect. We'll modify this application so it uses SAML to authenticate users.
3838
//
3939
// ```golang
4040
// package main
4141
//
4242
// import (
43-
// "fmt"
44-
// "net/http"
43+
//
44+
// "fmt"
45+
// "net/http"
46+
//
4547
// )
4648
//
47-
// func hello(w http.ResponseWriter, r *http.Request) {
48-
// fmt.Fprintf(w, "Hello, World!")
49-
// }
49+
// func hello(w http.ResponseWriter, r *http.Request) {
50+
// fmt.Fprintf(w, "Hello, World!")
51+
// }
52+
//
53+
// func main() {
54+
// app := http.HandlerFunc(hello)
55+
// http.Handle("/hello", app)
56+
// http.ListenAndServe(":8000", nil)
57+
// }
5058
//
51-
// func main() {
52-
// app := http.HandlerFunc(hello)
53-
// http.Handle("/hello", app)
54-
// http.ListenAndServe(":8000", nil)
55-
// }
5659
// ```
5760
//
5861
// Each service provider must have an self-signed X.509 key pair established. You can generate your own with something like this:
5962
//
60-
// openssl req -x509 -newkey rsa:2048 -keyout myservice.key -out myservice.cert -days 365 -nodes -subj "/CN=myservice.example.com"
63+
// openssl req -x509 -newkey rsa:2048 -keyout myservice.key -out myservice.cert -days 365 -nodes -subj "/CN=myservice.example.com"
6164
//
6265
// We will use `samlsp.Middleware` to wrap the endpoint we want to protect. Middleware provides both an `http.Handler` to serve the SAML specific URLs and a set of wrappers to require the user to be logged in. We also provide the URL where the service provider can fetch the metadata from the IDP at startup. In our case, we'll use [samltest.id](https://samltest.id/), an identity provider designed for testing.
6366
//
6467
// ```golang
6568
// package main
6669
//
6770
// import (
68-
// "crypto/rsa"
69-
// "crypto/tls"
70-
// "crypto/x509"
71-
// "fmt"
72-
// "net/http"
73-
// "net/url"
74-
//
75-
// "github.com/crewjam/saml/samlsp"
71+
//
72+
// "crypto/rsa"
73+
// "crypto/tls"
74+
// "crypto/x509"
75+
// "fmt"
76+
// "net/http"
77+
// "net/url"
78+
//
79+
// "github.com/crewjam/saml/samlsp"
80+
//
7681
// )
7782
//
78-
// func hello(w http.ResponseWriter, r *http.Request) {
79-
// fmt.Fprintf(w, "Hello, %s!", samlsp.Token(r.Context()).Attributes.Get("cn"))
80-
// }
81-
//
82-
// func main() {
83-
// keyPair, err := tls.LoadX509KeyPair("myservice.cert", "myservice.key")
84-
// if err != nil {
85-
// panic(err) // TODO handle error
86-
// }
87-
// keyPair.Leaf, err = x509.ParseCertificate(keyPair.Certificate[0])
88-
// if err != nil {
89-
// panic(err) // TODO handle error
90-
// }
91-
//
92-
// idpMetadataURL, err := url.Parse("https://samltest.id/saml/idp")
93-
// if err != nil {
94-
// panic(err) // TODO handle error
95-
// }
96-
//
97-
// rootURL, err := url.Parse("http://localhost:8000")
98-
// if err != nil {
99-
// panic(err) // TODO handle error
100-
// }
101-
//
102-
// samlSP, _ := samlsp.New(samlsp.Options{
103-
// URL: *rootURL,
104-
// Key: keyPair.PrivateKey.(*rsa.PrivateKey),
105-
// Certificate: keyPair.Leaf,
106-
// IDPMetadataURL: idpMetadataURL,
107-
// })
108-
// app := http.HandlerFunc(hello)
109-
// http.Handle("/hello", samlSP.RequireAccount(app))
110-
// http.Handle("/saml/", samlSP)
111-
// http.ListenAndServe(":8000", nil)
112-
// }
83+
// func hello(w http.ResponseWriter, r *http.Request) {
84+
// fmt.Fprintf(w, "Hello, %s!", samlsp.Token(r.Context()).Attributes.Get("cn"))
85+
// }
86+
//
87+
// func main() {
88+
// keyPair, err := tls.LoadX509KeyPair("myservice.cert", "myservice.key")
89+
// if err != nil {
90+
// panic(err) // TODO handle error
91+
// }
92+
// keyPair.Leaf, err = x509.ParseCertificate(keyPair.Certificate[0])
93+
// if err != nil {
94+
// panic(err) // TODO handle error
95+
// }
96+
//
97+
// idpMetadataURL, err := url.Parse("https://samltest.id/saml/idp")
98+
// if err != nil {
99+
// panic(err) // TODO handle error
100+
// }
101+
//
102+
// rootURL, err := url.Parse("http://localhost:8000")
103+
// if err != nil {
104+
// panic(err) // TODO handle error
105+
// }
106+
//
107+
// samlSP, _ := samlsp.New(samlsp.Options{
108+
// URL: *rootURL,
109+
// Key: keyPair.PrivateKey.(*rsa.PrivateKey),
110+
// Certificate: keyPair.Leaf,
111+
// IDPMetadataURL: idpMetadataURL,
112+
// })
113+
// app := http.HandlerFunc(hello)
114+
// http.Handle("/hello", samlSP.RequireAccount(app))
115+
// http.Handle("/saml/", samlSP)
116+
// http.ListenAndServe(":8000", nil)
117+
// }
118+
//
113119
// ```
114120
//
115121
// Next we'll have to register our service provider with the identity provider to establish trust from the service provider to the IDP. For [samltest.id](https://samltest.id/), you can do something like:
116122
//
117-
// mdpath=saml-test-$USER-$HOST.xml
118-
// curl localhost:8000/saml/metadata > $mdpath
123+
// mdpath=saml-test-$USER-$HOST.xml
124+
// curl localhost:8000/saml/metadata > $mdpath
119125
//
120126
// Navigate to https://samltest.id/upload.php and upload the file you fetched.
121127
//
@@ -133,25 +139,25 @@
133139
//
134140
// 1. This time when `localhost:8000/hello` is requested there is a valid session and so the main content is served.
135141
//
136-
// Getting Started as an Identity Provider
142+
// # Getting Started as an Identity Provider
137143
//
138144
// Please see `example/idp/` for a substantially complete example of how to use the library and helpers to be an identity provider.
139145
//
140-
// Support
146+
// # Support
141147
//
142148
// The SAML standard is huge and complex with many dark corners and strange, unused features. This package implements the most commonly used subset of these features required to provide a single sign on experience. The package supports at least the subset of SAML known as [interoperable SAML](http://saml2int.org).
143149
//
144150
// This package supports the Web SSO profile. Message flows from the service provider to the IDP are supported using the HTTP Redirect binding and the HTTP POST binding. Message flows from the IDP to the service provider are supported via the HTTP POST binding.
145151
//
146152
// The package can produce signed SAML assertions, and can validate both signed and encrypted SAML assertions. It does not support signed or encrypted requests.
147153
//
148-
// RelayState
154+
// # RelayState
149155
//
150156
// The _RelayState_ parameter allows you to pass user state information across the authentication flow. The most common use for this is to allow a user to request a deep link into your site, be redirected through the SAML login flow, and upon successful completion, be directed to the originally requested link, rather than the root.
151157
//
152158
// Unfortunately, _RelayState_ is less useful than it could be. Firstly, it is not authenticated, so anything you supply must be signed to avoid XSS or CSRF. Secondly, it is limited to 80 bytes in length, which precludes signing. (See section 3.6.3.1 of SAMLProfiles.)
153159
//
154-
// References
160+
// # References
155161
//
156162
// The SAML specification is a collection of PDFs (sadly):
157163
//
@@ -165,7 +171,7 @@
165171
//
166172
// [SAMLtest](https://samltest.id/) is a testing ground for SAML service and identity providers.
167173
//
168-
// Security Issues
174+
// # Security Issues
169175
//
170176
// Please do not report security issues in the issue tracker. Rather, please contact me directly at [email protected] ([PGP Key `78B6038B3B9DFB88`](https://keybase.io/crewjam)).
171177
package saml

samlsp/middleware.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,8 @@ func (m *Middleware) CreateSessionFromAssertion(w http.ResponseWriter, r *http.R
209209
//
210210
// For example:
211211
//
212-
// goji.Use(m.RequireAccount)
213-
// goji.Use(RequireAttributeMiddleware("eduPersonAffiliation", "Staff"))
214-
//
212+
// goji.Use(m.RequireAccount)
213+
// goji.Use(RequireAttributeMiddleware("eduPersonAffiliation", "Staff"))
215214
func RequireAttribute(name, value string) func(http.Handler) http.Handler {
216215
return func(handler http.Handler) http.Handler {
217216
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

samlsp/request_tracker.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ import (
88
//
99
// There are two main reasons for this:
1010
//
11-
// 1. When the middleware initiates an authentication request it must track the original URL
12-
// in order to redirect the user to the right place after the authentication completes.
11+
// 1. When the middleware initiates an authentication request it must track the original URL
12+
// in order to redirect the user to the right place after the authentication completes.
1313
//
14-
// 2. After the authentication completes, we want to ensure that the user presenting the
15-
// assertion is actually the one the request it, to mitigate request forgeries.
14+
// 2. After the authentication completes, we want to ensure that the user presenting the
15+
// assertion is actually the one the request it, to mitigate request forgeries.
1616
type RequestTracker interface {
1717
// TrackRequest starts tracking the SAML request with the given ID. It returns an
1818
// `index` that should be used as the RelayState in the SAMl request flow.

service_provider.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -934,7 +934,7 @@ func (sp *ServiceProvider) parseResponse(responseEl *etree.Element, possibleRequ
934934

935935
// if we have at least one assertion, return the first one. It is almost universally true that valid responses
936936
// contain only one assertion. This is less that fully correct, but we didn't realize that there could be more
937-
// than one assertion at the time of establishing the public interface of ParseXMLResponse(), so for compatability
937+
// than one assertion at the time of establishing the public interface of ParseXMLResponse(), so for compatibility
938938
// we return the first one.
939939
return &assertions[0], nil
940940
}

0 commit comments

Comments
 (0)