You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kie.apache.org by th...@apache.org on 2025/05/09 21:28:25 UTC

(incubator-kie-tools) branch main updated: kie-issues#3118: Support Accelerators on private repositories and air-gap installations on KIE Sandbox (#3119)

This is an automated email from the ASF dual-hosted git repository.

thiagoelg pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-tools.git


The following commit(s) were added to refs/heads/main by this push:
     new a006a826a2d kie-issues#3118: Support Accelerators on private repositories and air-gap installations on KIE Sandbox (#3119)
a006a826a2d is described below

commit a006a826a2d4d197a694c75777812656efb779e1
Author: Kusuma04-dev <ku...@gmail.com>
AuthorDate: Sat May 10 02:58:21 2025 +0530

    kie-issues#3118: Support Accelerators on private repositories and air-gap installations on KIE Sandbox (#3119)
    
    Co-authored-by: chinnamatli kusumalatha <ch...@chinnamatlis-MacBook-Pro.local>
---
 .../src/accelerators/AcceleratorsHooks.tsx         |  10 +-
 .../src/authSessions/AuthSessionSelect.tsx         |   3 +-
 .../Toolbar/Accelerators/AcceleratorModal.tsx      | 106 +++++++++++++++++++--
 .../Toolbar/Accelerators/AcceleratorsDropdown.tsx  |  36 +++++--
 .../src/context/WorkspacesContext.tsx              |   4 +
 .../src/context/WorkspacesContextProvider.tsx      |   1 +
 .../workspaces-git-fs/src/services/GitService.tsx  |   5 +
 .../src/worker/api/WorkspacesWorkerGitApi.ts       |   4 +
 8 files changed, 152 insertions(+), 17 deletions(-)

diff --git a/packages/online-editor/src/accelerators/AcceleratorsHooks.tsx b/packages/online-editor/src/accelerators/AcceleratorsHooks.tsx
index 8998ed4d89d..b4a6ecf5d07 100644
--- a/packages/online-editor/src/accelerators/AcceleratorsHooks.tsx
+++ b/packages/online-editor/src/accelerators/AcceleratorsHooks.tsx
@@ -128,7 +128,14 @@ export function useAcceleratorsDispatch(workspace: ActiveWorkspace) {
   }, [workspace.descriptor.workspaceId, workspaces]);
 
   const applyAcceleratorToWorkspace = useCallback(
-    async (accelerator: AcceleratorConfig, currentFile: WorkspaceFile) => {
+    async (
+      accelerator: AcceleratorConfig,
+      currentFile: WorkspaceFile,
+      authInfo?: {
+        username: string;
+        password: string;
+      }
+    ) => {
       applyingAcceleratorAlert.show({ acceleratorName: accelerator.name });
 
       const workspaceId = workspace.descriptor.workspaceId;
@@ -237,6 +244,7 @@ export function useAcceleratorsDispatch(workspace: ActiveWorkspace) {
           workspaceId,
           remote: TEMP_ACCELERATOR_REMOTE_NAME,
           ref: accelerator.gitRepositoryGitRef,
+          authInfo: authInfo,
         });
 
         if (!fetchResult.fetchHead) {
diff --git a/packages/online-editor/src/authSessions/AuthSessionSelect.tsx b/packages/online-editor/src/authSessions/AuthSessionSelect.tsx
index 31ea58442be..eb26c8c5610 100644
--- a/packages/online-editor/src/authSessions/AuthSessionSelect.tsx
+++ b/packages/online-editor/src/authSessions/AuthSessionSelect.tsx
@@ -150,8 +150,7 @@ export function AuthSessionSelect(props: {
       }}
       className={props.isPlain ? "kie-tools--masthead-hoverable" : ""}
       menuAppendTo={props.menuAppendTo ?? "parent"}
-      maxHeight={"400px"}
-      style={{ minWidth: "400px" }}
+      style={{ minWidth: "300px", maxHeight: "300px", overflowY: "scroll" }}
       footer={
         <>
           {showedGroups?.length !== groups?.length && (
diff --git a/packages/online-editor/src/editor/Toolbar/Accelerators/AcceleratorModal.tsx b/packages/online-editor/src/editor/Toolbar/Accelerators/AcceleratorModal.tsx
index adb21c38c89..b7e8cf13e99 100644
--- a/packages/online-editor/src/editor/Toolbar/Accelerators/AcceleratorModal.tsx
+++ b/packages/online-editor/src/editor/Toolbar/Accelerators/AcceleratorModal.tsx
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-import React from "react";
+import React, { useEffect, useMemo, useState } from "react";
 import { AcceleratorAppliedConfig } from "../../../accelerators/AcceleratorsApi";
 import { useOnlineI18n } from "../../../i18n";
 import { Title } from "@patternfly/react-core/dist/js/components/Title";
@@ -26,18 +26,80 @@ import { Modal, ModalVariant } from "@patternfly/react-core/dist/js/components/M
 import { Button } from "@patternfly/react-core/dist/js/components/Button";
 import { AcceleratorIcon } from "./AcceleratorIcon";
 import { Divider } from "@patternfly/react-core/dist/js/components/Divider";
+import { AuthSession, AuthSessionStatus, GitAuthSession, isGitAuthSession } from "../../../authSessions/AuthSessionApi";
+import { Alert } from "@patternfly/react-core/dist/js/components/Alert";
+import {
+  getCompatibleAuthSessionWithUrlDomain,
+  gitAuthSessionSelectFilter,
+  isAuthSessionCompatibleWithUrlDomain,
+} from "../../../authSessions/CompatibleAuthSessions";
+import { AuthProvider, AuthProviderGroup, AuthProviderType } from "../../../authProviders/AuthProvidersApi";
+import { AuthSessionSelect } from "../../../authSessions/AuthSessionSelect";
+import { SelectPosition } from "@patternfly/react-core/deprecated";
+import { useAuthProvider, useAuthProviders } from "../../../authProviders/AuthProvidersContext";
+import { useAuthSession, useAuthSessions } from "../../../authSessions/AuthSessionsContext";
+import { AccountsDispatchActionKind, useAccountsDispatch } from "../../../accounts/AccountsContext";
 
 type Props = {
   accelerator: AcceleratorAppliedConfig;
   isOpen: boolean;
   onClose: () => any;
   isApplying?: boolean;
-  onApplyAccelerator?: () => void;
+  onApplyAccelerator?: (authSessionId?: string) => void;
 };
 
+function getDomainFromUrl(url: string | undefined): string | undefined {
+  if (!url) return undefined;
+  try {
+    return new URL(url).hostname;
+  } catch {
+    return undefined;
+  }
+}
+
 export function AcceleratorModal(props: Props) {
   const { i18n } = useOnlineI18n();
 
+  const urlDomain = useMemo(
+    () => getDomainFromUrl(props.accelerator.gitRepositoryUrl),
+    [props.accelerator.gitRepositoryUrl]
+  );
+
+  const { authSessions, authSessionStatus } = useAuthSessions();
+  const authProviders = useAuthProviders();
+
+  const [selectedAuthSessionId, setSelectedAuthSessionId] = useState<string | undefined>(undefined);
+
+  useEffect(() => {
+    const { compatible } = getCompatibleAuthSessionWithUrlDomain({
+      authProviders: authProviders,
+      authSessions: authSessions,
+      authSessionStatus: authSessionStatus,
+      urlDomain,
+    });
+
+    setSelectedAuthSessionId(compatible.length > 0 ? compatible[0].id : "");
+  }, [authProviders, authSessions, authSessionStatus, urlDomain]);
+
+  const accountsDispatch = useAccountsDispatch();
+  const { authSession } = useAuthSession(selectedAuthSessionId);
+  const selectedAuthProvider = useAuthProvider(authSession);
+  const selectedStatus = useMemo(() => {
+    return authSession ? authSessionStatus.get(authSession.id) : undefined;
+  }, [authSession, authSessionStatus]);
+
+  const isCompatibleAuthSession = useMemo(() => {
+    return (
+      authSession &&
+      isAuthSessionCompatibleWithUrlDomain({
+        authSession: authSession,
+        authProvider: selectedAuthProvider,
+        status: selectedStatus,
+        urlDomain,
+      })
+    );
+  }, [authSession, selectedAuthProvider, selectedStatus, urlDomain]);
+
   return (
     <Modal
       isOpen={props.isOpen}
@@ -46,7 +108,7 @@ export function AcceleratorModal(props: Props) {
       variant={ModalVariant.medium}
       actions={
         props.isApplying && [
-          <Button key="apply" variant="primary" onClick={props.onApplyAccelerator}>
+          <Button key="apply" variant="primary" onClick={() => props.onApplyAccelerator?.(selectedAuthSessionId)}>
             {i18n.terms.apply}
           </Button>,
           <Button key="cancel" variant="link" onClick={props.onClose}>
@@ -62,9 +124,41 @@ export function AcceleratorModal(props: Props) {
       </Title>
       <Grid style={{ margin: "1rem 0" }} hasGutter>
         {props.isApplying && (
-          <GridItem span={12}>
-            <i>{i18n.accelerators.acceleratorDescription}</i>
-          </GridItem>
+          <>
+            <GridItem span={12}>
+              <i>{i18n.accelerators.acceleratorDescription}</i>
+            </GridItem>
+
+            <GridItem span={12}>
+              <AuthSessionSelect
+                title={`Select Git authentication for '${props.accelerator.name}' Accelerator`}
+                authSessionId={selectedAuthSessionId}
+                setAuthSessionId={(newSelectedAuthSessionId) => {
+                  setSelectedAuthSessionId(newSelectedAuthSessionId);
+                  accountsDispatch({ kind: AccountsDispatchActionKind.CLOSE });
+                }}
+                isPlain={false}
+                position={SelectPosition.right}
+                filter={gitAuthSessionSelectFilter()}
+                showOnlyThisAuthProviderGroupWhenConnectingToNewAccount={AuthProviderGroup.GIT}
+              />
+            </GridItem>
+
+            {authSession && (
+              <GridItem span={12}>
+                {isCompatibleAuthSession ? (
+                  <Alert variant="info" isInline title="Authentication Status">
+                    Using {selectedAuthProvider?.domain} credentials for {(authSession as GitAuthSession).login}
+                  </Alert>
+                ) : (
+                  <Alert variant="danger" isInline title="Authentication Status">
+                    Selected account is not compatible with {urlDomain}, where {props.accelerator.name} Accelerator is
+                    hosted.
+                  </Alert>
+                )}
+              </GridItem>
+            )}
+          </>
         )}
         <GridItem span={12}>
           <p>
diff --git a/packages/online-editor/src/editor/Toolbar/Accelerators/AcceleratorsDropdown.tsx b/packages/online-editor/src/editor/Toolbar/Accelerators/AcceleratorsDropdown.tsx
index 7aa4d42a072..68b65d31817 100644
--- a/packages/online-editor/src/editor/Toolbar/Accelerators/AcceleratorsDropdown.tsx
+++ b/packages/online-editor/src/editor/Toolbar/Accelerators/AcceleratorsDropdown.tsx
@@ -17,7 +17,8 @@
  * under the License.
  */
 
-import React, { useCallback, useState } from "react";
+import * as React from "react";
+import { useCallback, useState } from "react";
 import { ResponsiveDropdown } from "../../../ResponsiveDropdown/ResponsiveDropdown";
 import { ResponsiveDropdownToggle } from "../../../ResponsiveDropdown/ResponsiveDropdownToggle";
 import { useEditorToolbarContext, useEditorToolbarDispatchContext } from "../EditorToolbarContextProvider";
@@ -33,6 +34,8 @@ import { AcceleratorConfig } from "../../../accelerators/AcceleratorsApi";
 import { useOnlineI18n } from "../../../i18n";
 import { AcceleratorModal } from "./AcceleratorModal";
 import { AcceleratorIcon } from "./AcceleratorIcon";
+import { useAuthSession, useAuthSessions } from "../../../authSessions/AuthSessionsContext";
+import { GitAuthSession, isGitAuthSession } from "../../../authSessions/AuthSessionApi";
 
 type Props = {
   workspaceFile: WorkspaceFile;
@@ -48,6 +51,7 @@ export function AcceleratorsDropdown(props: Props) {
   const [selectedAccelerator, setSelectedAccelerator] = useState<AcceleratorConfig | undefined>();
 
   const currentAccelerator = useCurrentAccelerator(props.workspaceFile.workspaceId);
+  const { authSessions } = useAuthSessions();
 
   const onOpenApplyAccelerator = useCallback(
     (accelerator: AcceleratorConfig) => {
@@ -58,13 +62,29 @@ export function AcceleratorsDropdown(props: Props) {
     [setAcceleratorsDropdownOpen]
   );
 
-  const onApplyAccelerator = useCallback(() => {
-    if (selectedAccelerator) {
-      applyAcceleratorToWorkspace(selectedAccelerator, props.workspaceFile);
-    }
-    setSelectedAccelerator(undefined);
-    setApplyModalOpen(false);
-  }, [applyAcceleratorToWorkspace, props.workspaceFile, selectedAccelerator]);
+  const onApplyAccelerator = useCallback(
+    async (authSessionId?: string) => {
+      if (!selectedAccelerator) {
+        console.error("Missing required parameters to apply accelerator");
+        return;
+      }
+      const authSession = authSessions.get(authSessionId || "");
+      const authInfo =
+        authSession && isGitAuthSession(authSession)
+          ? { username: authSession.login, password: authSession.token }
+          : undefined;
+
+      try {
+        await applyAcceleratorToWorkspace(selectedAccelerator, props.workspaceFile, authInfo);
+      } catch (error) {
+        console.error("Failed to apply accelerator:", error);
+      } finally {
+        setSelectedAccelerator(undefined);
+        setApplyModalOpen(false);
+      }
+    },
+    [applyAcceleratorToWorkspace, authSessions, props.workspaceFile, selectedAccelerator]
+  );
 
   if (currentAccelerator) {
     return <></>;
diff --git a/packages/workspaces-git-fs/src/context/WorkspacesContext.tsx b/packages/workspaces-git-fs/src/context/WorkspacesContext.tsx
index 3a4e9128ec5..ac89dc98c72 100644
--- a/packages/workspaces-git-fs/src/context/WorkspacesContext.tsx
+++ b/packages/workspaces-git-fs/src/context/WorkspacesContext.tsx
@@ -191,6 +191,10 @@ export interface WorkspacesContextType {
     workspaceId: string;
     remote: string;
     ref: string;
+    authInfo?: {
+      username: string;
+      password: string;
+    };
     insecurelyDisableTlsCertificateValidation?: boolean;
   }): Promise<FetchResult>;
 
diff --git a/packages/workspaces-git-fs/src/context/WorkspacesContextProvider.tsx b/packages/workspaces-git-fs/src/context/WorkspacesContextProvider.tsx
index 082375c579e..73b8e2078b6 100644
--- a/packages/workspaces-git-fs/src/context/WorkspacesContextProvider.tsx
+++ b/packages/workspaces-git-fs/src/context/WorkspacesContextProvider.tsx
@@ -168,6 +168,7 @@ export function WorkspacesContextProvider(props: Props) {
       workspaceId: string;
       remote: string;
       ref: string;
+      authInfo?: { username: string; password: string };
       insecurelyDisableTlsCertificateValidation?: boolean;
     }) =>
       workspacesSharedWorker.withBus((workspacesWorkerBus) =>
diff --git a/packages/workspaces-git-fs/src/services/GitService.tsx b/packages/workspaces-git-fs/src/services/GitService.tsx
index 1c17752bb89..31bdbd5adc7 100644
--- a/packages/workspaces-git-fs/src/services/GitService.tsx
+++ b/packages/workspaces-git-fs/src/services/GitService.tsx
@@ -170,6 +170,10 @@ export class GitService {
     dir: string;
     remote: string;
     ref: string;
+    authInfo?: {
+      username: string;
+      password: string;
+    };
     insecurelyDisableTlsCertificateValidation?: boolean;
   }): Promise<FetchResult> {
     return await git.fetch({
@@ -183,6 +187,7 @@ export class GitService {
       singleBranch: true,
       depth: 1,
       tags: true,
+      onAuth: () => args.authInfo,
     });
   }
 
diff --git a/packages/workspaces-git-fs/src/worker/api/WorkspacesWorkerGitApi.ts b/packages/workspaces-git-fs/src/worker/api/WorkspacesWorkerGitApi.ts
index 0b75a13f16b..c240208ef1c 100644
--- a/packages/workspaces-git-fs/src/worker/api/WorkspacesWorkerGitApi.ts
+++ b/packages/workspaces-git-fs/src/worker/api/WorkspacesWorkerGitApi.ts
@@ -144,6 +144,10 @@ export interface WorkspacesWorkerGitApi {
   kieSandboxWorkspacesGit_fetch(args: {
     workspaceId: string;
     remote: string;
+    authInfo?: {
+      username: string;
+      password: string;
+    };
     ref: string;
     insecurelyDisableTlsCertificateValidation?: boolean;
   }): Promise<FetchResult>;


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@kie.apache.org
For additional commands, e-mail: commits-help@kie.apache.org