@@ -2,8 +2,6 @@ package httpmw
2
2
3
3
import (
4
4
"context"
5
- "encoding/base64"
6
- "encoding/json"
7
5
"fmt"
8
6
"net/http"
9
7
"net/url"
@@ -17,6 +15,7 @@ import (
17
15
"github.com/coder/coder/v2/coderd/httpapi"
18
16
"github.com/coder/coder/v2/coderd/promoauth"
19
17
"github.com/coder/coder/v2/codersdk"
18
+ "github.com/coder/coder/v2/cryptorand"
20
19
)
21
20
22
21
type oauth2StateKey struct {}
@@ -85,8 +84,7 @@ func ExtractOAuth2(config promoauth.OAuth2Config, client *http.Client, authURLOp
85
84
return
86
85
}
87
86
88
- // code := r.URL.Query().Get("code")
89
- deviceCode := r .URL .Query ().Get ("device_code" )
87
+ code := r .URL .Query ().Get ("code" )
90
88
state := r .URL .Query ().Get ("state" )
91
89
redirect := r .URL .Query ().Get ("redirect" )
92
90
if redirect != "" {
@@ -98,105 +96,76 @@ func ExtractOAuth2(config promoauth.OAuth2Config, client *http.Client, authURLOp
98
96
redirect = uriFromURL (redirect )
99
97
}
100
98
101
- var da * oauth2.DeviceAuthResponse
102
- if deviceCode != "" {
103
- // Decode base64-encoded device code
104
- decodedBytes , err := base64 .StdEncoding .DecodeString (deviceCode )
105
- if err != nil {
106
- httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
107
- Message : "Invalid device code format" ,
108
- Detail : err .Error (),
109
- })
110
- return
99
+ if code == "" {
100
+ // If the code isn't provided, we'll redirect!
101
+ var state string
102
+ // If this url param is provided, then a user is trying to merge
103
+ // their account with an OIDC account. Their password would have
104
+ // been required to get to this point, so we do not need to verify
105
+ // their password again.
106
+ oidcMergeState := r .URL .Query ().Get ("oidc_merge_state" )
107
+ if oidcMergeState != "" {
108
+ state = oidcMergeState
109
+ } else {
110
+ var err error
111
+ state , err = cryptorand .String (32 )
112
+ if err != nil {
113
+ httpapi .Write (ctx , rw , http .StatusInternalServerError , codersdk.Response {
114
+ Message : "Internal error generating state string." ,
115
+ Detail : err .Error (),
116
+ })
117
+ return
118
+ }
111
119
}
112
120
113
- // Unmarshal JSON into DeviceAuthResponse
114
- da = & oauth2.DeviceAuthResponse {}
115
- if err := json .Unmarshal (decodedBytes , da ); err != nil {
116
- httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
117
- Message : "Invalid device code data" ,
118
- Detail : err .Error (),
119
- })
120
- return
121
- }
122
- } else {
123
- httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
124
- Message : "Invalid device code data" ,
125
- Detail : "Device code is required for device flow." ,
121
+ http .SetCookie (rw , & http.Cookie {
122
+ Name : codersdk .OAuth2StateCookie ,
123
+ Value : state ,
124
+ Path : "/" ,
125
+ HttpOnly : true ,
126
+ SameSite : http .SameSiteLaxMode ,
127
+ })
128
+ // Redirect must always be specified, otherwise
129
+ // an old redirect could apply!
130
+ http .SetCookie (rw , & http.Cookie {
131
+ Name : codersdk .OAuth2RedirectCookie ,
132
+ Value : redirect ,
133
+ Path : "/" ,
134
+ HttpOnly : true ,
135
+ SameSite : http .SameSiteLaxMode ,
126
136
})
137
+
138
+ http .Redirect (rw , r , config .AuthCodeURL (state , opts ... ), http .StatusTemporaryRedirect )
127
139
return
128
140
}
129
141
130
- // if code == "" {
131
- // // If the code isn't provided, we'll redirect!
132
- // var state string
133
- // // If this url param is provided, then a user is trying to merge
134
- // // their account with an OIDC account. Their password would have
135
- // // been required to get to this point, so we do not need to verify
136
- // // their password again.
137
- // oidcMergeState := r.URL.Query().Get("oidc_merge_state")
138
- // if oidcMergeState != "" {
139
- // state = oidcMergeState
140
- // } else {
141
- // var err error
142
- // state, err = cryptorand.String(32)
143
- // if err != nil {
144
- // httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
145
- // Message: "Internal error generating state string.",
146
- // Detail: err.Error(),
147
- // })
148
- // return
149
- // }
150
- // }
151
-
152
- http .SetCookie (rw , & http.Cookie {
153
- Name : codersdk .OAuth2StateCookie ,
154
- Value : "hello" ,
155
- Path : "/" ,
156
- HttpOnly : true ,
157
- SameSite : http .SameSiteLaxMode ,
158
- })
159
- // // Redirect must always be specified, otherwise
160
- // // an old redirect could apply!
161
- // http.SetCookie(rw, &http.Cookie{
162
- // Name: codersdk.OAuth2RedirectCookie,
163
- // Value: redirect,
164
- // Path: "/",
165
- // HttpOnly: true,
166
- // SameSite: http.SameSiteLaxMode,
167
- // })
168
-
169
- // http.Redirect(rw, r, config.AuthCodeURL(state, opts...), http.StatusTemporaryRedirect)
170
- // return
171
- // }
172
-
173
- // if state == "" {
174
- // httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
175
- // Message: "State must be provided.",
176
- // })
177
- // return
178
- // }
142
+ if state == "" {
143
+ httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
144
+ Message : "State must be provided." ,
145
+ })
146
+ return
147
+ }
179
148
180
- // stateCookie, err := r.Cookie(codersdk.OAuth2StateCookie)
181
- // if err != nil {
182
- // httpapi.Write(ctx, rw, http.StatusUnauthorized, codersdk.Response{
183
- // Message: fmt.Sprintf("Cookie %q must be provided.", codersdk.OAuth2StateCookie),
184
- // })
185
- // return
186
- // }
187
- // if stateCookie.Value != state {
188
- // httpapi.Write(ctx, rw, http.StatusUnauthorized, codersdk.Response{
189
- // Message: "State mismatched.",
190
- // })
191
- // return
192
- // }
149
+ stateCookie , err := r .Cookie (codersdk .OAuth2StateCookie )
150
+ if err != nil {
151
+ httpapi .Write (ctx , rw , http .StatusUnauthorized , codersdk.Response {
152
+ Message : fmt .Sprintf ("Cookie %q must be provided." , codersdk .OAuth2StateCookie ),
153
+ })
154
+ return
155
+ }
156
+ if stateCookie .Value != state {
157
+ httpapi .Write (ctx , rw , http .StatusUnauthorized , codersdk.Response {
158
+ Message : "State mismatched." ,
159
+ })
160
+ return
161
+ }
193
162
194
163
stateRedirect , err := r .Cookie (codersdk .OAuth2RedirectCookie )
195
164
if err == nil {
196
165
redirect = stateRedirect .Value
197
166
}
198
167
199
- oauthToken , err := config .DeviceAccessToken (ctx , da )
168
+ oauthToken , err := config .Exchange (ctx , code )
200
169
if err != nil {
201
170
httpapi .Write (ctx , rw , http .StatusInternalServerError , codersdk.Response {
202
171
Message : "Internal error exchanging Oauth code." ,
0 commit comments