build scripts for kube2msb
[oom/registrator.git] / kube2msb / src / kube2msb / vendor / github.com / coreos / go-oidc / oidc / transport.go
1 package oidc
2
3 import (
4         "fmt"
5         "net/http"
6         "sync"
7
8         phttp "github.com/coreos/go-oidc/http"
9         "github.com/coreos/go-oidc/jose"
10 )
11
12 type TokenRefresher interface {
13         // Verify checks if the provided token is currently valid or not.
14         Verify(jose.JWT) error
15
16         // Refresh attempts to authenticate and retrieve a new token.
17         Refresh() (jose.JWT, error)
18 }
19
20 type ClientCredsTokenRefresher struct {
21         Issuer     string
22         OIDCClient *Client
23 }
24
25 func (c *ClientCredsTokenRefresher) Verify(jwt jose.JWT) (err error) {
26         _, err = VerifyClientClaims(jwt, c.Issuer)
27         return
28 }
29
30 func (c *ClientCredsTokenRefresher) Refresh() (jwt jose.JWT, err error) {
31         if err = c.OIDCClient.Healthy(); err != nil {
32                 err = fmt.Errorf("unable to authenticate, unhealthy OIDC client: %v", err)
33                 return
34         }
35
36         jwt, err = c.OIDCClient.ClientCredsToken([]string{"openid"})
37         if err != nil {
38                 err = fmt.Errorf("unable to verify auth code with issuer: %v", err)
39                 return
40         }
41
42         return
43 }
44
45 type AuthenticatedTransport struct {
46         TokenRefresher
47         http.RoundTripper
48
49         mu  sync.Mutex
50         jwt jose.JWT
51 }
52
53 func (t *AuthenticatedTransport) verifiedJWT() (jose.JWT, error) {
54         t.mu.Lock()
55         defer t.mu.Unlock()
56
57         if t.TokenRefresher.Verify(t.jwt) == nil {
58                 return t.jwt, nil
59         }
60
61         jwt, err := t.TokenRefresher.Refresh()
62         if err != nil {
63                 return jose.JWT{}, fmt.Errorf("unable to acquire valid JWT: %v", err)
64         }
65
66         t.jwt = jwt
67         return t.jwt, nil
68 }
69
70 // SetJWT sets the JWT held by the Transport.
71 // This is useful for cases in which you want to set an initial JWT.
72 func (t *AuthenticatedTransport) SetJWT(jwt jose.JWT) {
73         t.mu.Lock()
74         defer t.mu.Unlock()
75
76         t.jwt = jwt
77 }
78
79 func (t *AuthenticatedTransport) RoundTrip(r *http.Request) (*http.Response, error) {
80         jwt, err := t.verifiedJWT()
81         if err != nil {
82                 return nil, err
83         }
84
85         req := phttp.CopyRequest(r)
86         req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", jwt.Encode()))
87         return t.RoundTripper.RoundTrip(req)
88 }