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