@@ -39,73 +39,81 @@ func UserParam(r *http.Request) database.User {
39
39
func ExtractUserParam (db database.Store , redirectToLoginOnMe bool ) func (http.Handler ) http.Handler {
40
40
return func (next http.Handler ) http.Handler {
41
41
return http .HandlerFunc (func (rw http.ResponseWriter , r * http.Request ) {
42
- var (
43
- ctx = r .Context ()
44
- user database.User
45
- err error
46
- )
47
-
48
- // userQuery is either a uuid, a username, or 'me'
49
- userQuery := chi .URLParam (r , "user" )
50
- if userQuery == "" {
51
- httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
52
- Message : "\" user\" must be provided." ,
53
- })
42
+ ctx := r .Context ()
43
+ user , ok := extractUserContext (ctx , db , rw , r , redirectToLoginOnMe )
44
+ if ! ok {
45
+ // response already handled
54
46
return
55
47
}
48
+ ctx = context .WithValue (ctx , userParamContextKey {}, user )
49
+ next .ServeHTTP (rw , r .WithContext (ctx ))
50
+ })
51
+ }
52
+ }
56
53
57
- if userQuery == "me" {
58
- apiKey , ok := APIKeyOptional (r )
59
- if ! ok {
60
- if redirectToLoginOnMe {
61
- RedirectToLogin (rw , r , nil , SignedOutErrorMessage )
62
- return
63
- }
54
+ // extractUserContext queries the database for the parameterized `{user}` from the request URL.
55
+ func extractUserContext (ctx context.Context , db database.Store , rw http.ResponseWriter , r * http.Request , redirectToLoginOnMe bool ) (user database.User , ok bool ) {
56
+ // userQuery is either a uuid, a username, or 'me'
57
+ userQuery := chi .URLParam (r , "user" )
58
+ if userQuery == "" {
59
+ httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
60
+ Message : "\" user\" must be provided." ,
61
+ })
62
+ return database.User {}, true
63
+ }
64
64
65
- httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
66
- Message : "Cannot use \" me\" without a valid session." ,
67
- })
68
- return
69
- }
70
- //nolint:gocritic // System needs to be able to get user from param.
71
- user , err = db .GetUserByID (dbauthz .AsSystemRestricted (ctx ), apiKey .UserID )
72
- if httpapi .Is404Error (err ) {
73
- httpapi .ResourceNotFound (rw )
74
- return
75
- }
76
- if err != nil {
77
- httpapi .Write (ctx , rw , http .StatusInternalServerError , codersdk.Response {
78
- Message : "Internal error fetching user." ,
79
- Detail : err .Error (),
80
- })
81
- return
82
- }
83
- } else if userID , err := uuid .Parse (userQuery ); err == nil {
84
- //nolint:gocritic // If the userQuery is a valid uuid
85
- user , err = db .GetUserByID (dbauthz .AsSystemRestricted (ctx ), userID )
86
- if err != nil {
87
- httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
88
- Message : userErrorMessage ,
89
- Detail : fmt .Sprintf ("queried user=%q" , userQuery ),
90
- })
91
- return
92
- }
93
- } else {
94
- // nolint:gocritic // Try as a username last
95
- user , err = db .GetUserByEmailOrUsername (dbauthz .AsSystemRestricted (ctx ), database.GetUserByEmailOrUsernameParams {
96
- Username : userQuery ,
97
- })
98
- if err != nil {
99
- httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
100
- Message : userErrorMessage ,
101
- Detail : fmt .Sprintf ("queried user=%q" , userQuery ),
102
- })
103
- return
104
- }
65
+ if userQuery == "me" {
66
+ apiKey , ok := APIKeyOptional (r )
67
+ if ! ok {
68
+ if redirectToLoginOnMe {
69
+ RedirectToLogin (rw , r , nil , SignedOutErrorMessage )
70
+ return database.User {}, false
105
71
}
106
72
107
- ctx = context .WithValue (ctx , userParamContextKey {}, user )
108
- next .ServeHTTP (rw , r .WithContext (ctx ))
73
+ httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
74
+ Message : "Cannot use \" me\" without a valid session." ,
75
+ })
76
+ return database.User {}, false
77
+ }
78
+ //nolint:gocritic // System needs to be able to get user from param.
79
+ user , err := db .GetUserByID (dbauthz .AsSystemRestricted (ctx ), apiKey .UserID )
80
+ if httpapi .Is404Error (err ) {
81
+ httpapi .ResourceNotFound (rw )
82
+ return database.User {}, false
83
+ }
84
+ if err != nil {
85
+ httpapi .Write (ctx , rw , http .StatusInternalServerError , codersdk.Response {
86
+ Message : "Internal error fetching user." ,
87
+ Detail : err .Error (),
88
+ })
89
+ return database.User {}, false
90
+ }
91
+ return user , true
92
+ }
93
+
94
+ if userID , err := uuid .Parse (userQuery ); err == nil {
95
+ //nolint:gocritic // If the userQuery is a valid uuid
96
+ user , err = db .GetUserByID (dbauthz .AsSystemRestricted (ctx ), userID )
97
+ if err != nil {
98
+ httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
99
+ Message : userErrorMessage ,
100
+ Detail : fmt .Sprintf ("queried user=%q" , userQuery ),
101
+ })
102
+ return database.User {}, false
103
+ }
104
+ return user , true
105
+ }
106
+
107
+ // nolint:gocritic // Try as a username last
108
+ user , err := db .GetUserByEmailOrUsername (dbauthz .AsSystemRestricted (ctx ), database.GetUserByEmailOrUsernameParams {
109
+ Username : userQuery ,
110
+ })
111
+ if err != nil {
112
+ httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
113
+ Message : userErrorMessage ,
114
+ Detail : fmt .Sprintf ("queried user=%q" , userQuery ),
109
115
})
116
+ return database.User {}, false
110
117
}
118
+ return user , true
111
119
}
0 commit comments