@@ -2030,14 +2030,23 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
2030
2030
return await this . projectsService . getProjectEnvironmentVariables ( projectId ) ;
2031
2031
}
2032
2032
2033
- protected async guardTeamOperation ( teamId : string | undefined , op : ResourceAccessOp ) : Promise < Team > {
2034
- const team = await this . teamDB . findTeamById ( teamId || "" ) ;
2033
+ protected async guardTeamOperation (
2034
+ teamId : string ,
2035
+ op : ResourceAccessOp ,
2036
+ ) : Promise < { team : Team ; members : TeamMemberInfo [ ] } > {
2037
+ if ( ! uuidValidate ( teamId ) ) {
2038
+ throw new ResponseError ( ErrorCodes . BAD_REQUEST , "organization ID must be a valid UUID" ) ;
2039
+ }
2040
+
2041
+ const team = await this . teamDB . findTeamById ( teamId ) ;
2035
2042
if ( ! team ) {
2036
- throw new ResponseError ( ErrorCodes . NOT_FOUND , "Organization not found" ) ;
2043
+ // We return Permission Denied because we don't want to leak the existence, or not of the Organization.
2044
+ throw new ResponseError ( ErrorCodes . PERMISSION_DENIED , `No access to Organization ID: ${ teamId } ` ) ;
2037
2045
}
2046
+
2038
2047
const members = await this . teamDB . findMembersByTeam ( team . id ) ;
2039
2048
await this . guardAccess ( { kind : "team" , subject : team , members } , op ) ;
2040
- return team ;
2049
+ return { team, members } ;
2041
2050
}
2042
2051
2043
2052
public async getTeams ( ctx : TraceContext ) : Promise < Team [ ] > {
@@ -2049,33 +2058,17 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
2049
2058
public async getTeam ( ctx : TraceContext , teamId : string ) : Promise < Team > {
2050
2059
traceAPIParams ( ctx , { teamId } ) ;
2051
2060
2052
- if ( ! uuidValidate ( teamId ) ) {
2053
- throw new ResponseError ( ErrorCodes . BAD_REQUEST , "organization ID must be a valid UUID" ) ;
2054
- }
2055
-
2056
2061
this . checkAndBlockUser ( "getTeam" ) ;
2057
2062
2058
- const team = await this . guardTeamOperation ( teamId , "get" ) ;
2059
- if ( ! team ) {
2060
- throw new ResponseError ( ErrorCodes . NOT_FOUND , `Team ${ teamId } does not exist` ) ;
2061
- }
2062
-
2063
+ const { team } = await this . guardTeamOperation ( teamId , "get" ) ;
2063
2064
return team ;
2064
2065
}
2065
2066
2066
2067
public async updateTeam ( ctx : TraceContext , teamId : string , team : Pick < Team , "name" > ) : Promise < Team > {
2067
2068
traceAPIParams ( ctx , { teamId } ) ;
2068
-
2069
- if ( ! teamId || ! uuidValidate ( teamId ) ) {
2070
- throw new ResponseError ( ErrorCodes . BAD_REQUEST , "organization ID must be a valid UUID" ) ;
2071
- }
2072
2069
this . checkUser ( "updateTeam" ) ;
2073
- const existingTeam = await this . teamDB . findTeamById ( teamId ) ;
2074
- if ( ! existingTeam ) {
2075
- throw new ResponseError ( ErrorCodes . NOT_FOUND , `Organization ${ teamId } does not exist` ) ;
2076
- }
2077
- const members = await this . teamDB . findMembersByTeam ( teamId ) ;
2078
- await this . guardAccess ( { kind : "team" , subject : existingTeam , members } , "update" ) ;
2070
+
2071
+ await this . guardTeamOperation ( teamId , "update" ) ;
2079
2072
2080
2073
const updatedTeam = await this . teamDB . updateTeam ( teamId , team ) ;
2081
2074
return updatedTeam ;
@@ -2084,14 +2077,8 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
2084
2077
public async getTeamMembers ( ctx : TraceContext , teamId : string ) : Promise < TeamMemberInfo [ ] > {
2085
2078
traceAPIParams ( ctx , { teamId } ) ;
2086
2079
2087
- if ( ! uuidValidate ( teamId ) ) {
2088
- throw new ResponseError ( ErrorCodes . BAD_REQUEST , "organization ID must be a valid UUID" ) ;
2089
- }
2080
+ const { members } = await this . guardTeamOperation ( teamId , "get" ) ;
2090
2081
2091
- this . checkUser ( "getTeamMembers" ) ;
2092
- const team = await this . getTeam ( ctx , teamId ) ;
2093
- const members = await this . teamDB . findMembersByTeam ( team . id ) ;
2094
- await this . guardAccess ( { kind : "team" , subject : team , members } , "get" ) ;
2095
2082
return members ;
2096
2083
}
2097
2084
@@ -2152,10 +2139,6 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
2152
2139
) : Promise < void > {
2153
2140
traceAPIParams ( ctx , { teamId, userId, role } ) ;
2154
2141
2155
- if ( ! uuidValidate ( teamId ) ) {
2156
- throw new ResponseError ( ErrorCodes . BAD_REQUEST , "organization ID must be a valid UUID" ) ;
2157
- }
2158
-
2159
2142
if ( ! uuidValidate ( userId ) ) {
2160
2143
throw new ResponseError ( ErrorCodes . BAD_REQUEST , "user ID must be a valid UUID" ) ;
2161
2144
}
@@ -2166,16 +2149,13 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
2166
2149
2167
2150
this . checkAndBlockUser ( "setTeamMemberRole" ) ;
2168
2151
await this . guardTeamOperation ( teamId , "update" ) ;
2152
+
2169
2153
await this . teamDB . setTeamMemberRole ( userId , teamId , role ) ;
2170
2154
}
2171
2155
2172
2156
public async removeTeamMember ( ctx : TraceContext , teamId : string , userId : string ) : Promise < void > {
2173
2157
traceAPIParams ( ctx , { teamId, userId } ) ;
2174
2158
2175
- if ( ! uuidValidate ( teamId ) ) {
2176
- throw new ResponseError ( ErrorCodes . BAD_REQUEST , "organization ID must be a valid UUID" ) ;
2177
- }
2178
-
2179
2159
if ( ! uuidValidate ( userId ) ) {
2180
2160
throw new ResponseError ( ErrorCodes . BAD_REQUEST , "user ID must be a valid UUID" ) ;
2181
2161
}
@@ -2202,12 +2182,9 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
2202
2182
public async getGenericInvite ( ctx : TraceContext , teamId : string ) : Promise < TeamMembershipInvite > {
2203
2183
traceAPIParams ( ctx , { teamId } ) ;
2204
2184
2205
- if ( ! uuidValidate ( teamId ) ) {
2206
- throw new ResponseError ( ErrorCodes . BAD_REQUEST , "organization ID must be a valid UUID" ) ;
2207
- }
2208
-
2209
2185
this . checkUser ( "getGenericInvite" ) ;
2210
2186
await this . guardTeamOperation ( teamId , "get" ) ;
2187
+
2211
2188
const invite = await this . teamDB . findGenericInviteByTeamId ( teamId ) ;
2212
2189
if ( invite ) {
2213
2190
return invite ;
@@ -2218,10 +2195,6 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
2218
2195
public async resetGenericInvite ( ctx : TraceContext , teamId : string ) : Promise < TeamMembershipInvite > {
2219
2196
traceAPIParams ( ctx , { teamId } ) ;
2220
2197
2221
- if ( ! uuidValidate ( teamId ) ) {
2222
- throw new ResponseError ( ErrorCodes . BAD_REQUEST , "organization ID must be a valid UUID" ) ;
2223
- }
2224
-
2225
2198
this . checkAndBlockUser ( "resetGenericInvite" ) ;
2226
2199
await this . guardTeamOperation ( teamId , "update" ) ;
2227
2200
return this . teamDB . resetGenericInvite ( teamId ) ;
@@ -2240,7 +2213,7 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
2240
2213
}
2241
2214
} else {
2242
2215
// Anyone who can read a team's information (i.e. any team member) can manage team projects
2243
- await this . guardTeamOperation ( project . teamId , "get" ) ;
2216
+ await this . guardTeamOperation ( project . teamId || "" , "get" ) ;
2244
2217
}
2245
2218
}
2246
2219
@@ -2267,7 +2240,7 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
2267
2240
}
2268
2241
} else {
2269
2242
// Anyone who can read a team's information (i.e. any team member) can create a new project.
2270
- await this . guardTeamOperation ( params . teamId , "get" ) ;
2243
+ await this . guardTeamOperation ( params . teamId || "" , "get" ) ;
2271
2244
}
2272
2245
2273
2246
return this . projectsService . createProject ( params , user ) ;
@@ -3048,7 +3021,7 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
3048
3021
throw new ResponseError ( ErrorCodes . NOT_FOUND , "Provider resource not found." ) ;
3049
3022
}
3050
3023
3051
- await this . guardTeamOperation ( authProvider . organizationId , "delete" ) ;
3024
+ await this . guardTeamOperation ( authProvider . organizationId || "" , "delete" ) ;
3052
3025
3053
3026
try {
3054
3027
await this . authProviderService . deleteAuthProvider ( authProvider ) ;
0 commit comments