1
+ package clientcredentials
2
+
3
+ import (
4
+ "encoding/base64"
5
+ "fmt"
6
+ "net/http"
7
+ "net/http/httptest"
8
+ "net/url"
9
+ "strings"
10
+ "testing"
11
+ )
12
+
13
+ func TestHandleTokenRequest (t * testing.T ) {
14
+ tests := []struct {
15
+ name string
16
+ setupRequest func () * http.Request
17
+ wantStatus int
18
+ wantAccessToken string
19
+ }{
20
+ {
21
+ name : "valid form credentials" ,
22
+ setupRequest : func () * http.Request {
23
+ form := url.Values {}
24
+ form .Set ("grant_type" , "client_credentials" )
25
+ form .Set ("client_id" , "speakeasy-sdks" )
26
+ form .Set ("client_secret" , "supersecret-123" )
27
+ form .Set ("scope" , "read write" )
28
+
29
+ req := httptest .NewRequest (http .MethodPost , "/token" , strings .NewReader (form .Encode ()))
30
+ req .Header .Set ("Content-Type" , "application/x-www-form-urlencoded" )
31
+ return req
32
+ },
33
+ wantStatus : http .StatusOK ,
34
+ wantAccessToken : firstAccessToken ,
35
+ },
36
+ {
37
+ name : "valid basic auth" ,
38
+ setupRequest : func () * http.Request {
39
+ form := url.Values {}
40
+ form .Set ("grant_type" , "client_credentials" )
41
+ form .Set ("scope" , "read write" )
42
+
43
+ req := httptest .NewRequest (http .MethodPost , "/token" , strings .NewReader (form .Encode ()))
44
+ req .Header .Set ("Content-Type" , "application/x-www-form-urlencoded" )
45
+
46
+ // Create basic auth header
47
+ creds := base64 .StdEncoding .EncodeToString ([]byte ("speakeasy-sdks:supersecret-123" ))
48
+ req .Header .Set ("Authorization" , fmt .Sprintf ("Basic %s" , creds ))
49
+
50
+ return req
51
+ },
52
+ wantStatus : http .StatusOK ,
53
+ wantAccessToken : firstAccessToken ,
54
+ },
55
+ {
56
+ name : "invalid basic auth format" ,
57
+ setupRequest : func () * http.Request {
58
+ req := httptest .NewRequest (http .MethodPost , "/token" , nil )
59
+ req .Header .Set ("Authorization" , "Basic invalid-base64" )
60
+ return req
61
+ },
62
+ wantStatus : http .StatusUnauthorized ,
63
+ },
64
+ {
65
+ name : "missing credentials in basic auth" ,
66
+ setupRequest : func () * http.Request {
67
+ req := httptest .NewRequest (http .MethodPost , "/token" , nil )
68
+ // Encode just username without password
69
+ creds := base64 .StdEncoding .EncodeToString ([]byte ("speakeasy-sdks" ))
70
+ req .Header .Set ("Authorization" , fmt .Sprintf ("Basic %s" , creds ))
71
+ return req
72
+ },
73
+ wantStatus : http .StatusUnauthorized ,
74
+ },
75
+ {
76
+ name : "invalid credentials in basic auth" ,
77
+ setupRequest : func () * http.Request {
78
+ form := url.Values {}
79
+ form .Set ("grant_type" , "client_credentials" )
80
+ req := httptest .NewRequest (http .MethodPost , "/token" , strings .NewReader (form .Encode ()))
81
+ req .Header .Set ("Content-Type" , "application/x-www-form-urlencoded" )
82
+ creds := base64 .StdEncoding .EncodeToString ([]byte ("wrong:wrong" ))
83
+ req .Header .Set ("Authorization" , fmt .Sprintf ("Basic %s" , creds ))
84
+
85
+ return req
86
+ },
87
+ wantStatus : http .StatusUnauthorized ,
88
+ },
89
+ {
90
+ name : "missing required scope in basic auth" ,
91
+ setupRequest : func () * http.Request {
92
+ form := url.Values {}
93
+ form .Set ("grant_type" , "client_credentials" )
94
+ form .Set ("scope" , "read" ) // missing write scope
95
+
96
+ req := httptest .NewRequest (http .MethodPost , "/token" , strings .NewReader (form .Encode ()))
97
+ req .Header .Set ("Content-Type" , "application/x-www-form-urlencoded" )
98
+
99
+ creds := base64 .StdEncoding .EncodeToString ([]byte ("speakeasy-sdks:supersecret-123" ))
100
+ req .Header .Set ("Authorization" , fmt .Sprintf ("Basic %s" , creds ))
101
+
102
+ return req
103
+ },
104
+ wantStatus : http .StatusBadRequest ,
105
+ },
106
+ {
107
+ name : "case insensitive basic prefix" ,
108
+ setupRequest : func () * http.Request {
109
+ form := url.Values {}
110
+ form .Set ("grant_type" , "client_credentials" )
111
+ form .Set ("scope" , "read write" )
112
+
113
+ req := httptest .NewRequest (http .MethodPost , "/token" , strings .NewReader (form .Encode ()))
114
+ req .Header .Set ("Content-Type" , "application/x-www-form-urlencoded" )
115
+
116
+ creds := base64 .StdEncoding .EncodeToString ([]byte ("speakeasy-sdks:supersecret-123" ))
117
+ req .Header .Set ("Authorization" , fmt .Sprintf ("BASIC %s" , creds ))
118
+
119
+ return req
120
+ },
121
+ wantStatus : http .StatusOK ,
122
+ wantAccessToken : firstAccessToken ,
123
+ },
124
+ }
125
+
126
+ for _ , tt := range tests {
127
+ t .Run (tt .name , func (t * testing.T ) {
128
+ w := httptest .NewRecorder ()
129
+ HandleTokenRequest (w , tt .setupRequest ())
130
+
131
+ if got := w .Code ; got != tt .wantStatus {
132
+ t .Errorf ("HandleTokenRequest() status = %v, want %v" , got , tt .wantStatus )
133
+ }
134
+
135
+ if tt .wantStatus == http .StatusOK {
136
+ if ! strings .Contains (w .Body .String (), tt .wantAccessToken ) {
137
+ t .Errorf ("HandleTokenRequest() response doesn't contain expected access token" )
138
+ }
139
+ }
140
+ })
141
+ }
142
+ }
0 commit comments