Added populateOrgName param in /v1/workspace api which adds orgName and displayName in result

Updated the CLI to use this new paramter to display organization name with project name with support for backward compatibility keeping original behaviour for older apis
This commit is contained in:
Rhythm Bhiwani
2024-03-03 12:12:25 +05:30
parent 2192985291
commit 756c1e5098
8 changed files with 69 additions and 37 deletions

View File

@@ -341,6 +341,7 @@ export const registerRoutes = async (
const projectService = projectServiceFactory({ const projectService = projectServiceFactory({
permissionService, permissionService,
projectDAL, projectDAL,
orgDAL,
projectQueue: projectQueueService, projectQueue: projectQueueService,
secretBlindIndexDAL, secretBlindIndexDAL,
identityProjectDAL, identityProjectDAL,

View File

@@ -16,7 +16,9 @@ import { sanitizedServiceTokenSchema } from "../v2/service-token-router";
const projectWithEnv = ProjectsSchema.merge( const projectWithEnv = ProjectsSchema.merge(
z.object({ z.object({
_id: z.string(), _id: z.string(),
environments: z.object({ name: z.string(), slug: z.string(), id: z.string() }).array() environments: z.object({ name: z.string(), slug: z.string(), id: z.string() }).array(),
orgName: z.string().optional(),
displayName: z.string().optional()
}) })
); );
@@ -91,6 +93,12 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
url: "/", url: "/",
method: "GET", method: "GET",
schema: { schema: {
querystring: z.object({
populateOrgName: z
.enum(["true", "false"])
.default("false")
.transform((value) => value === "true")
}),
response: { response: {
200: z.object({ 200: z.object({
workspaces: projectWithEnv.array() workspaces: projectWithEnv.array()
@@ -99,7 +107,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY]),
handler: async (req) => { handler: async (req) => {
const workspaces = await server.services.project.getProjects(req.permission.id); const workspaces = await server.services.project.getProjects(req.permission.id, req.query.populateOrgName);
return { workspaces }; return { workspaces };
} }
}); });

View File

@@ -17,6 +17,7 @@ import { TProjectPermission } from "@app/lib/types";
import { ActorType } from "../auth/auth-type"; import { ActorType } from "../auth/auth-type";
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal"; import { TIdentityOrgDALFactory } from "../identity/identity-org-dal";
import { TIdentityProjectDALFactory } from "../identity-project/identity-project-dal"; import { TIdentityProjectDALFactory } from "../identity-project/identity-project-dal";
import { TOrgDALFactory } from "../org/org-dal";
import { TOrgServiceFactory } from "../org/org-service"; import { TOrgServiceFactory } from "../org/org-service";
import { TProjectBotDALFactory } from "../project-bot/project-bot-dal"; import { TProjectBotDALFactory } from "../project-bot/project-bot-dal";
import { TProjectEnvDALFactory } from "../project-env/project-env-dal"; import { TProjectEnvDALFactory } from "../project-env/project-env-dal";
@@ -46,6 +47,7 @@ type TProjectServiceFactoryDep = {
projectDAL: TProjectDALFactory; projectDAL: TProjectDALFactory;
projectQueue: TProjectQueueFactory; projectQueue: TProjectQueueFactory;
userDAL: TUserDALFactory; userDAL: TUserDALFactory;
orgDAL: TOrgDALFactory;
folderDAL: TSecretFolderDALFactory; folderDAL: TSecretFolderDALFactory;
projectEnvDAL: Pick<TProjectEnvDALFactory, "insertMany" | "find">; projectEnvDAL: Pick<TProjectEnvDALFactory, "insertMany" | "find">;
identityOrgMembershipDAL: TIdentityOrgDALFactory; identityOrgMembershipDAL: TIdentityOrgDALFactory;
@@ -64,6 +66,7 @@ export type TProjectServiceFactory = ReturnType<typeof projectServiceFactory>;
export const projectServiceFactory = ({ export const projectServiceFactory = ({
projectDAL, projectDAL,
projectQueue, projectQueue,
orgDAL,
projectKeyDAL, projectKeyDAL,
permissionService, permissionService,
userDAL, userDAL,
@@ -306,8 +309,19 @@ export const projectServiceFactory = ({
return deletedProject; return deletedProject;
}; };
const getProjects = async (actorId: string) => { const getProjects = async (actorId: string, populateOrgName?: boolean) => {
const workspaces = await projectDAL.findAllProjects(actorId); const workspaces = await projectDAL.findAllProjects(actorId);
if (populateOrgName) {
const orgs = await orgDAL.findAllOrgsByUserId(actorId);
return workspaces.map((workspace) => {
const orgName = orgs.find((org) => org.id === workspace.orgId)?.name || "";
return {
...workspace,
orgName,
displayName: `${workspace.name} (${orgName})`
};
});
}
return workspaces; return workspaces;
}; };

View File

@@ -170,6 +170,7 @@ func CallGetAllWorkSpacesUserBelongsTo(httpClient *resty.Client) (GetWorkSpacesR
R(). R().
SetResult(&workSpacesResponse). SetResult(&workSpacesResponse).
SetHeader("User-Agent", USER_AGENT). SetHeader("User-Agent", USER_AGENT).
SetQueryParam("populateOrgName", "true").
Get(fmt.Sprintf("%v/v1/workspace", config.INFISICAL_URL)) Get(fmt.Sprintf("%v/v1/workspace", config.INFISICAL_URL))
if err != nil { if err != nil {
@@ -180,22 +181,6 @@ func CallGetAllWorkSpacesUserBelongsTo(httpClient *resty.Client) (GetWorkSpacesR
return GetWorkSpacesResponse{}, fmt.Errorf("CallGetAllWorkSpacesUserBelongsTo: Unsuccessful response: [response=%v]", response) return GetWorkSpacesResponse{}, fmt.Errorf("CallGetAllWorkSpacesUserBelongsTo: Unsuccessful response: [response=%v]", response)
} }
// Call the organization API
orgResponse, err := CallGetAllOrganizations(httpClient)
if err != nil {
return GetWorkSpacesResponse{}, err
}
// Update organization names in workspacesResponse
for i, workspace := range workSpacesResponse.Workspaces {
for _, organization := range orgResponse.Organizations {
if workspace.Organization == organization.ID {
workSpacesResponse.Workspaces[i].Organization = organization.Name
break
}
}
}
return workSpacesResponse, nil return workSpacesResponse, nil
} }

View File

@@ -120,11 +120,12 @@ type PullSecretsByInfisicalTokenResponse struct {
type GetWorkSpacesResponse struct { type GetWorkSpacesResponse struct {
Workspaces []struct { Workspaces []struct {
ID string `json:"_id"` ID string `json:"_id"`
Name string `json:"name"` Name string `json:"name"`
Plan string `json:"plan,omitempty"` Plan string `json:"plan,omitempty"`
V int `json:"__v"` V int `json:"__v"`
Organization string `json:"orgId,omitempty"` Organization *string `json:"orgName,omitempty"`
DisplayName *string `json:"displayName,omitempty"`
} `json:"workspaces"` } `json:"workspaces"`
} }

View File

@@ -5,7 +5,6 @@ package cmd
import ( import (
"encoding/json" "encoding/json"
"fmt"
"github.com/Infisical/infisical-merge/packages/api" "github.com/Infisical/infisical-merge/packages/api"
"github.com/Infisical/infisical-merge/packages/models" "github.com/Infisical/infisical-merge/packages/models"
@@ -58,14 +57,10 @@ var initCmd = &cobra.Command{
} }
workspaces := workspaceResponse.Workspaces workspaces := workspaceResponse.Workspaces
if len(workspaces) == 0 {
message := fmt.Sprintf("You don't have any projects created in Infisical. You must first create a project at %s", util.INFISICAL_TOKEN_NAME)
util.PrintErrorMessageAndExit(message)
}
var workspaceNames []string workspaceNames, err := util.GetWorkspacesNameList(workspaceResponse)
for _, workspace := range workspaces { if err != nil {
workspaceNames = append(workspaceNames, fmt.Sprintf("%s (%s)", workspace.Name, workspace.Organization)) util.HandleError(err, "Error extracting workspace names")
} }
prompt := promptui.Select{ prompt := promptui.Select{

View File

@@ -45,11 +45,12 @@ type SingleFolder struct {
} }
type Workspace struct { type Workspace struct {
ID string `json:"_id"` ID string `json:"_id"`
Name string `json:"name"` Name string `json:"name"`
Plan string `json:"plan,omitempty"` Plan string `json:"plan,omitempty"`
V int `json:"__v"` V int `json:"__v"`
Organization string `json:"orgId,omitempty"` Organization *string `json:"orgName,omitempty"`
DisplayName *string `json:"displayName,omitempty"`
} }
type WorkspaceConfigFile struct { type WorkspaceConfigFile struct {

27
cli/packages/util/init.go Normal file
View File

@@ -0,0 +1,27 @@
package util
import (
"fmt"
"github.com/Infisical/infisical-merge/packages/api"
)
func GetWorkspacesNameList(workspaceResponse api.GetWorkSpacesResponse) ([]string, error) {
workspaces := workspaceResponse.Workspaces
if len(workspaces) == 0 {
message := fmt.Sprintf("You don't have any projects created in Infisical. You must first create a project at %s", INFISICAL_TOKEN_NAME)
PrintErrorMessageAndExit(message)
}
var workspaceNames []string
for _, workspace := range workspaces {
if workspace.DisplayName != nil {
workspaceNames = append(workspaceNames, *workspace.DisplayName)
} else {
workspaceNames = append(workspaceNames, workspace.Name)
}
}
return workspaceNames, nil
}