Skip to content

Commit 59a9753

Browse files
committed
chore: refactor ExtractUserParam to call function
1 parent c83af5e commit 59a9753

File tree

1 file changed

+71
-61
lines changed

1 file changed

+71
-61
lines changed

coderd/httpmw/userparam.go

+71-61
Original file line numberDiff line numberDiff line change
@@ -39,73 +39,83 @@ 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+
//
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+
}
6466

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
10573
}
10674

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),
109117
})
118+
return database.User{}, false
110119
}
120+
return user, true
111121
}

0 commit comments

Comments
 (0)