@@ -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
}
0 commit comments