Skip to content

Commit 6e06d89

Browse files
authored
Update all other endpoints that are impacted by multi-tenancy (#3795)
Any endpoints that use `tenantId` explicitly in the request path or in the request body are updated to account for `Tenant` settings and any other tenant specific logic in this PR. Some things to highlight - Providers are disabled by default on tenant projects based on observable behavior on Cloud dashboard. Agent projects have settings default enabled to be consistent with existing behavior until project `Config` management is introduced - Supported tenant operations are listed at go/firebase-tools-3795-tenantOps; all other endpoints throw errors when called with a `TenantProjectState`. Some endpoints are not explicitly listed but are supported on tenant projects including: - `getRecaptchaParams` - `createSessionCookie` - `grantToken` - Some, but not all, emulator endpoints were modified to take `tenantId` as a query param to correctly retrieve `TenantProjectState`. Not all emulator endpoints were updated but should be - a `TODO` was added in `gen-auth-api-spec.ts` that will be addressed in a subsequent PR (this one was getting bloated)
1 parent b9420dd commit 6e06d89

22 files changed

+1622
-57
lines changed

scripts/gen-auth-api-spec.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ function pushServersDownToEachPath(openapi3: any): void {
305305
});
306306
}
307307

308+
// TODO(lisajian): add tenantId as query param for all emulator config endpoints
308309
function addEmulatorOperations(openapi3: any): void {
309310
openapi3.tags.push({ name: "emulator" });
310311
openapi3.paths["/emulator/v1/projects/{targetProjectId}/accounts"] = {
@@ -446,6 +447,46 @@ function addEmulatorOperations(openapi3: any): void {
446447
tags: ["emulator"],
447448
},
448449
};
450+
openapi3.paths["/emulator/v1/projects/{targetProjectId}/tenants/{tenantId}/oobCodes"] = {
451+
parameters: [
452+
{
453+
name: "targetProjectId",
454+
in: "path",
455+
description: "The ID of the Google Cloud project that the confirmation codes belongs to.",
456+
required: true,
457+
schema: {
458+
type: "string",
459+
},
460+
},
461+
{
462+
name: "tenantId",
463+
in: "path",
464+
description:
465+
"The ID of the Identity Platform tenant the accounts belongs to. If not specified, accounts on the Identity Platform project are returned.",
466+
required: true,
467+
schema: { type: "string" },
468+
},
469+
],
470+
servers: [{ url: "" }],
471+
get: {
472+
description: "List all pending confirmation codes for the project.",
473+
operationId: "emulator.projects.oobCodes.list",
474+
responses: {
475+
"200": {
476+
description: "Successful response",
477+
content: {
478+
"application/json": {
479+
schema: {
480+
$ref: "#/components/schemas/EmulatorV1ProjectsOobCodes",
481+
},
482+
},
483+
},
484+
},
485+
},
486+
security: [],
487+
tags: ["emulator"],
488+
},
489+
};
449490
openapi3.components.schemas.EmulatorV1ProjectsOobCodes = {
450491
type: "object",
451492
description: "Details of all pending confirmation codes.",
@@ -496,6 +537,46 @@ function addEmulatorOperations(openapi3: any): void {
496537
tags: ["emulator"],
497538
},
498539
};
540+
openapi3.paths["/emulator/v1/projects/{targetProjectId}/tenants/{tenantId}/verificationCodes"] = {
541+
parameters: [
542+
{
543+
name: "targetProjectId",
544+
in: "path",
545+
description: "The ID of the Google Cloud project that the verification codes belongs to.",
546+
required: true,
547+
schema: {
548+
type: "string",
549+
},
550+
},
551+
{
552+
name: "tenantId",
553+
in: "path",
554+
description:
555+
"The ID of the Identity Platform tenant the accounts belongs to. If not specified, accounts on the Identity Platform project are returned.",
556+
required: true,
557+
schema: { type: "string" },
558+
},
559+
],
560+
servers: [{ url: "" }],
561+
get: {
562+
description: "List all pending phone verification codes for the project.",
563+
operationId: "emulator.projects.verificationCodes.list",
564+
responses: {
565+
"200": {
566+
description: "Successful response",
567+
content: {
568+
"application/json": {
569+
schema: {
570+
$ref: "#/components/schemas/EmulatorV1ProjectsOobCodes",
571+
},
572+
},
573+
},
574+
},
575+
},
576+
security: [],
577+
tags: ["emulator"],
578+
},
579+
};
499580
openapi3.components.schemas.EmulatorV1ProjectsVerificationCodes = {
500581
type: "object",
501582
description: "Details of all pending verification codes.",

src/emulator/auth/apiSpec.js

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3725,6 +3725,42 @@ export default {
37253725
tags: ["emulator"],
37263726
},
37273727
},
3728+
"/emulator/v1/projects/{targetProjectId}/tenants/{tenantId}/oobCodes": {
3729+
parameters: [
3730+
{
3731+
name: "targetProjectId",
3732+
in: "path",
3733+
description: "The ID of the Google Cloud project that the confirmation codes belongs to.",
3734+
required: true,
3735+
schema: { type: "string" },
3736+
},
3737+
{
3738+
name: "tenantId",
3739+
in: "path",
3740+
description:
3741+
"The ID of the Identity Platform tenant the accounts belongs to. If not specified, accounts on the Identity Platform project are returned.",
3742+
required: true,
3743+
schema: { type: "string" },
3744+
},
3745+
],
3746+
servers: [{ url: "" }],
3747+
get: {
3748+
description: "List all pending confirmation codes for the project.",
3749+
operationId: "emulator.projects.oobCodes.list",
3750+
responses: {
3751+
200: {
3752+
description: "Successful response",
3753+
content: {
3754+
"application/json": {
3755+
schema: { $ref: "#/components/schemas/EmulatorV1ProjectsOobCodes" },
3756+
},
3757+
},
3758+
},
3759+
},
3760+
security: [],
3761+
tags: ["emulator"],
3762+
},
3763+
},
37283764
"/emulator/v1/projects/{targetProjectId}/verificationCodes": {
37293765
parameters: [
37303766
{
@@ -3753,6 +3789,42 @@ export default {
37533789
tags: ["emulator"],
37543790
},
37553791
},
3792+
"/emulator/v1/projects/{targetProjectId}/tenants/{tenantId}/verificationCodes": {
3793+
parameters: [
3794+
{
3795+
name: "targetProjectId",
3796+
in: "path",
3797+
description: "The ID of the Google Cloud project that the verification codes belongs to.",
3798+
required: true,
3799+
schema: { type: "string" },
3800+
},
3801+
{
3802+
name: "tenantId",
3803+
in: "path",
3804+
description:
3805+
"The ID of the Identity Platform tenant the accounts belongs to. If not specified, accounts on the Identity Platform project are returned.",
3806+
required: true,
3807+
schema: { type: "string" },
3808+
},
3809+
],
3810+
servers: [{ url: "" }],
3811+
get: {
3812+
description: "List all pending phone verification codes for the project.",
3813+
operationId: "emulator.projects.verificationCodes.list",
3814+
responses: {
3815+
200: {
3816+
description: "Successful response",
3817+
content: {
3818+
"application/json": {
3819+
schema: { $ref: "#/components/schemas/EmulatorV1ProjectsOobCodes" },
3820+
},
3821+
},
3822+
},
3823+
},
3824+
security: [],
3825+
tags: ["emulator"],
3826+
},
3827+
},
37563828
},
37573829
components: {
37583830
schemas: {
@@ -6578,7 +6650,7 @@ export default {
65786650
},
65796651
bindings: {
65806652
description:
6581-
"Associates a list of `members` to a `role`. Optionally, may specify a `condition` that determines how and when the `bindings` are applied. Each of the `bindings` must contain at least one member.",
6653+
"Associates a list of `members` to a `role`. Optionally, may specify a `condition` that determines how and when the `bindings` are applied. Each of the `bindings` must contain at least one member.",
65826654
items: { $ref: "#/components/schemas/GoogleIamV1Binding" },
65836655
type: "array",
65846656
},

src/emulator/auth/handlers.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@ import { PROVIDERS_LIST_PLACEHOLDER, WIDGET_UI } from "./widget_ui";
1212
*/
1313
export function registerHandlers(
1414
app: express.Express,
15-
getProjectStateByApiKey: (apiKey: string) => ProjectState
15+
getProjectStateByApiKey: (apiKey: string, tenantId?: string) => ProjectState
1616
): void {
1717
app.get(`/emulator/action`, (req, res) => {
18-
const { mode, oobCode, continueUrl, apiKey } = req.query as Record<string, string | undefined>;
18+
const { mode, oobCode, continueUrl, apiKey, tenantId } = req.query as Record<
19+
string,
20+
string | undefined
21+
>;
1922

2023
if (!apiKey) {
2124
return res.status(400).json({
@@ -33,7 +36,7 @@ export function registerHandlers(
3336
},
3437
});
3538
}
36-
const state = getProjectStateByApiKey(apiKey);
39+
const state = getProjectStateByApiKey(apiKey, tenantId);
3740

3841
switch (mode) {
3942
case "recoverEmail": {
@@ -169,14 +172,15 @@ export function registerHandlers(
169172
res.set("Content-Type", "text/html; charset=utf-8");
170173
const apiKey = req.query.apiKey as string | undefined;
171174
const providerId = req.query.providerId as string | undefined;
175+
const tenantId = req.query.tenantId as string | undefined;
172176
if (!apiKey || !providerId) {
173177
return res.status(400).json({
174178
authEmulator: {
175179
error: "missing apiKey or providerId query parameters",
176180
},
177181
});
178182
}
179-
const state = getProjectStateByApiKey(apiKey);
183+
const state = getProjectStateByApiKey(apiKey, tenantId);
180184
const providerInfos = state.listProviderInfosByProviderId(providerId);
181185

182186
const options = providerInfos

0 commit comments

Comments
 (0)