@@ -110,61 +110,51 @@ type OrganizationMember struct {
110
110
func ExtractOrganizationMemberParam (db database.Store )func (http.Handler ) http.Handler {
111
111
return func (next http.Handler ) http.Handler {
112
112
return http .HandlerFunc (func (rw http.ResponseWriter ,r * http.Request ) {
113
- organization := OrganizationParam (r )
114
- organizationMember ,ok := ExtractOrganizationMemberContext (rw ,r ,db ,organization .ID )
113
+ ctx := r .Context ()
114
+ // We need to resolve the `{user}` URL parameter so that we can get the userID and
115
+ // username. We do this as SystemRestricted since the caller might have permission
116
+ // to access the OrganizationMember object, but *not* the User object. So, it is
117
+ // very important that we do not add the User object to the request context or otherwise
118
+ // leak it to the API handler.
119
+ // nolint:gocritic
120
+ user ,ok := ExtractUserContext (dbauthz .AsSystemRestricted (ctx ),db ,rw ,r )
115
121
if ! ok {
116
122
return
117
123
}
124
+ organization := OrganizationParam (r )
118
125
119
- ctx := r .Context ()
120
- ctx = context .WithValue (ctx ,organizationMemberParamContextKey {},organizationMember )
121
- next .ServeHTTP (rw ,r .WithContext (ctx ))
122
- })
123
- }
124
- }
125
-
126
- func ExtractOrganizationMemberContext (rw http.ResponseWriter ,r * http.Request ,db database.Store ,orgID uuid.UUID ) (OrganizationMember ,bool ) {
127
- ctx := r .Context ()
128
-
129
- // We need to resolve the `{user}` URL parameter so that we can get the userID and
130
- // username. We do this as SystemRestricted since the caller might have permission
131
- // to access the OrganizationMember object, but *not* the User object. So, it is
132
- // very important that we do not add the User object to the request context or otherwise
133
- // leak it to the API handler.
134
- // nolint:gocritic
135
- user ,ok := extractUserContext (dbauthz .AsSystemRestricted (ctx ),db ,rw ,r )
136
- if ! ok {
137
- return OrganizationMember {},false
138
- }
126
+ organizationMember ,err := database .ExpectOne (db .OrganizationMembers (ctx , database.OrganizationMembersParams {
127
+ OrganizationID :organization .ID ,
128
+ UserID :user .ID ,
129
+ IncludeSystem :false ,
130
+ }))
131
+ if httpapi .Is404Error (err ) {
132
+ httpapi .ResourceNotFound (rw )
133
+ return
134
+ }
135
+ if err != nil {
136
+ httpapi .Write (ctx ,rw ,http .StatusInternalServerError , codersdk.Response {
137
+ Message :"Internal error fetching organization member." ,
138
+ Detail :err .Error (),
139
+ })
140
+ return
141
+ }
139
142
140
- organizationMember ,err := database .ExpectOne (db .OrganizationMembers (ctx , database.OrganizationMembersParams {
141
- OrganizationID :orgID ,
142
- UserID :user .ID ,
143
- IncludeSystem :false ,
144
- }))
145
- if httpapi .Is404Error (err ) {
146
- httpapi .ResourceNotFound (rw )
147
- return OrganizationMember {},false
148
- }
149
- if err != nil {
150
- httpapi .Write (ctx ,rw ,http .StatusInternalServerError , codersdk.Response {
151
- Message :"Internal error fetching organization member." ,
152
- Detail :err .Error (),
143
+ ctx = context .WithValue (ctx ,organizationMemberParamContextKey {},OrganizationMember {
144
+ OrganizationMember :organizationMember .OrganizationMember ,
145
+ // Here we're making two exceptions to the rule about not leaking data about the user
146
+ // to the API handler, which is to include the username and avatar URL.
147
+ // If the caller has permission to read the OrganizationMember, then we're explicitly
148
+ // saying here that they also have permission to see the member's username and avatar.
149
+ // This is OK!
150
+ //
151
+ // API handlers need this information for audit logging and returning the owner's
152
+ // username in response to creating a workspace. Additionally, the frontend consumes
153
+ // the Avatar URL and this allows the FE to avoid an extra request.
154
+ Username :user .Username ,
155
+ AvatarURL :user .AvatarURL ,
156
+ })
157
+ next .ServeHTTP (rw ,r .WithContext (ctx ))
153
158
})
154
- return OrganizationMember {},false
155
159
}
156
- return OrganizationMember {
157
- OrganizationMember :organizationMember .OrganizationMember ,
158
- // Here we're making two exceptions to the rule about not leaking data about the user
159
- // to the API handler, which is to include the username and avatar URL.
160
- // If the caller has permission to read the OrganizationMember, then we're explicitly
161
- // saying here that they also have permission to see the member's username and avatar.
162
- // This is OK!
163
- //
164
- // API handlers need this information for audit logging and returning the owner's
165
- // username in response to creating a workspace. Additionally, the frontend consumes
166
- // the Avatar URL and this allows the FE to avoid an extra request.
167
- Username :user .Username ,
168
- AvatarURL :user .AvatarURL ,
169
- },true
170
160
}