@@ -2,6 +2,7 @@ package coderd
2
2
3
3
import (
4
4
"context"
5
+ "crypto/sha256"
5
6
"database/sql"
6
7
"errors"
7
8
"fmt"
@@ -12,6 +13,7 @@ import (
12
13
"github.com/google/uuid"
13
14
14
15
"github.com/coder/coder/coderd/userpassword"
16
+ "github.com/coder/coder/cryptorand"
15
17
"github.com/coder/coder/database"
16
18
"github.com/coder/coder/httpapi"
17
19
"github.com/coder/coder/httpmw"
@@ -57,7 +59,7 @@ func (users *users) createInitialUser(rw http.ResponseWriter, r *http.Request) {
57
59
return
58
60
}
59
61
if userCount != 0 {
60
- httpapi .Write (rw , http .StatusForbidden , httpapi.Response {
62
+ httpapi .Write (rw , http .StatusConflict , httpapi.Response {
61
63
Message : "the initial user has already been created" ,
62
64
})
63
65
return
@@ -116,7 +118,7 @@ func (users *users) getAuthenticatedUser(rw http.ResponseWriter, r *http.Request
116
118
117
119
func (users * users ) loginWithPassword (rw http.ResponseWriter , r * http.Request ) {
118
120
var loginWithPassword LoginWithPasswordRequest
119
- if ! httpapi .Read (rw , r , loginWithPassword ) {
121
+ if ! httpapi .Read (rw , r , & loginWithPassword ) {
120
122
return
121
123
}
122
124
user , err := users .Database .GetUserByEmailOrUsername (r .Context (), database.GetUserByEmailOrUsernameParams {
@@ -149,25 +151,50 @@ func (users *users) loginWithPassword(rw http.ResponseWriter, r *http.Request) {
149
151
return
150
152
}
151
153
152
- // key, secret := (&database.APIKey{
153
- // UserID: actor.ID,
154
- // ExpiresAt: expiresAt,
155
- // LoginType: actor.LoginType,
156
- // OIDCAccessToken: oidcCfg.AccessToken,
157
- // OIDCRefreshToken: oidcCfg.RefreshToken,
158
- // OIDCIDToken: oidcCfg.IDToken,
159
- // // OIDCExpiry indicates when we need to fetch a new OIDC token.
160
- // OIDCExpiry: oidcCfg.Expiry,
161
- // DevurlToken: devurlToken,
162
- // }).Fill()
163
-
164
- users .Database .InsertAPIKey (r .Context (), database.InsertAPIKeyParams {
165
- ID : uuid .NewString (),
154
+ id , secret , err := generateAPIKeyIDSecret ()
155
+ hashed := sha256 .Sum256 ([]byte (secret ))
156
+
157
+ _ , err = users .Database .InsertAPIKey (r .Context (), database.InsertAPIKeyParams {
158
+ ID : id ,
166
159
UserID : user .ID ,
167
160
ExpiresAt : database .Now ().Add (24 * time .Hour ),
168
161
CreatedAt : database .Now (),
169
162
UpdatedAt : database .Now (),
170
- HashedSecret : [] byte ( "" ) ,
163
+ HashedSecret : hashed [:] ,
171
164
LoginType : database .LoginTypeBuiltIn ,
172
165
})
166
+ if err != nil {
167
+ httpapi .Write (rw , http .StatusInternalServerError , httpapi.Response {
168
+ Message : fmt .Sprintf ("insert api key: %s" , err .Error ()),
169
+ })
170
+ return
171
+ }
172
+
173
+ sessionToken := fmt .Sprintf ("%s-%s" , id , secret )
174
+ http .SetCookie (rw , & http.Cookie {
175
+ Name : httpmw .AuthCookie ,
176
+ Value : sessionToken ,
177
+ Path : "/" ,
178
+ HttpOnly : true ,
179
+ SameSite : http .SameSiteLaxMode ,
180
+ })
181
+
182
+ render .Status (r , http .StatusCreated )
183
+ render .JSON (rw , r , LoginWithPasswordResponse {
184
+ SessionToken : sessionToken ,
185
+ })
186
+ }
187
+
188
+ func generateAPIKeyIDSecret () (string , string , error ) {
189
+ // Length of an API Key ID.
190
+ id , err := cryptorand .String (10 )
191
+ if err != nil {
192
+ return "" , "" , err
193
+ }
194
+ // Length of an API Key secret.
195
+ secret , err := cryptorand .String (22 )
196
+ if err != nil {
197
+ return "" , "" , err
198
+ }
199
+ return id , secret , nil
173
200
}
0 commit comments