Skip to content

Commit fbb6292

Browse files
authored
feat: add withJWT client option (#1682)
1 parent df4e9fa commit fbb6292

File tree

4 files changed

+78
-1
lines changed

4 files changed

+78
-1
lines changed

internal/auth/auth.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,18 @@ type Auth interface {
1212
// This method could be use for logging purpose.
1313
AnonymizedHeaders() http.Header
1414
}
15+
16+
type headerAnonymizer func(header http.Header) http.Header
17+
18+
var headerAnonymizers = []headerAnonymizer{
19+
AnonymizeTokenHeaders,
20+
AnonymizeJWTHeaders,
21+
}
22+
23+
func AnonymizeHeaders(headers http.Header) http.Header {
24+
for _, anonymizer := range headerAnonymizers {
25+
headers = anonymizer(headers)
26+
}
27+
28+
return headers
29+
}

internal/auth/jwt.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package auth
2+
3+
import (
4+
"net/http"
5+
"strings"
6+
)
7+
8+
// JWT is the session token used in browser.
9+
type JWT struct {
10+
Token string
11+
}
12+
13+
// XSessionTokenHeader is Scaleway auth header for browser
14+
const XSessionTokenHeader = "x-session-token" // #nosec G101
15+
16+
// NewJWT create a token authentication from a jwt
17+
func NewJWT(token string) *JWT {
18+
return &JWT{Token: token}
19+
}
20+
21+
// Headers returns headers that must be added to the http request
22+
func (j *JWT) Headers() http.Header {
23+
headers := http.Header{}
24+
headers.Set(XSessionTokenHeader, j.Token)
25+
return headers
26+
}
27+
28+
func AnonymizeJWTHeaders(headers http.Header) http.Header {
29+
token := headers.Get(XSessionTokenHeader)
30+
31+
if token != "" {
32+
headers.Set(XSessionTokenHeader, HideJWT(token))
33+
}
34+
35+
return headers
36+
}
37+
38+
// AnonymizedHeaders returns an anonymized version of Headers()
39+
// This method could be used for logging purpose.
40+
func (j *JWT) AnonymizedHeaders() http.Header {
41+
return AnonymizeJWTHeaders(j.Headers())
42+
}
43+
44+
func HideJWT(token string) string {
45+
if len(token) == 0 {
46+
return ""
47+
}
48+
// token should be (header).(payload).(signature)
49+
lastDot := strings.LastIndex(token, ".")
50+
if lastDot != -1 {
51+
token = token[:lastDot]
52+
}
53+
54+
return token
55+
}

scw/client_option.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ func WithAuth(accessKey, secretKey string) ClientOption {
3838
}
3939
}
4040

41+
// WithJWT client option sets the client session token.
42+
func WithJWT(token string) ClientOption {
43+
return func(s *settings) {
44+
s.token = auth.NewJWT(token)
45+
}
46+
}
47+
4148
// WithAPIURL client option overrides the API URL of the Scaleway API to the given URL.
4249
func WithAPIURL(apiURL string) ClientOption {
4350
return func(s *settings) {

scw/transport.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func (l *requestLoggerTransport) RoundTrip(request *http.Request) (*http.Respons
2222
originalHeaders := request.Header
2323

2424
// Get anonymized headers
25-
request.Header = auth.AnonymizeTokenHeaders(request.Header.Clone())
25+
request.Header = auth.AnonymizeHeaders(request.Header.Clone())
2626

2727
dump, err := httputil.DumpRequestOut(request, true)
2828
if err != nil {

0 commit comments

Comments
 (0)