Skip to content

Commit ee9170e

Browse files
committed
chore: refactor ExtractUserParam to call function
1 parent 211718f commit ee9170e

File tree

1 file changed

+69
-61
lines changed

1 file changed

+69
-61
lines changed

coderd/httpmw/userparam.go

+69-61
Original file line numberDiff line numberDiff line change
@@ -39,73 +39,81 @@ func UserParam(r *http.Request) database.User {
3939
func ExtractUserParam(db database.Store, redirectToLoginOnMe bool) func(http.Handler) http.Handler {
4040
return func(next http.Handler) http.Handler {
4141
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
5446
return
5547
}
48+
ctx = context.WithValue(ctx, userParamContextKey{}, user)
49+
next.ServeHTTP(rw, r.WithContext(ctx))
50+
})
51+
}
52+
}
5653

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+
}
6464

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
10571
}
10672

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),
109115
})
116+
return database.User{}, false
110117
}
118+
return user, true
111119
}

0 commit comments

Comments
 (0)