mirror of
https://github.com/OpenHands/OpenHands.git
synced 2026-03-22 05:37:20 +08:00
Add Enterprise SSO login button to V1 login page (#13390)
Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
@@ -15,6 +15,7 @@ vi.mock("#/hooks/use-auth-url", () => ({
|
||||
bitbucket: "https://bitbucket.org/site/oauth2/authorize",
|
||||
bitbucket_data_center:
|
||||
"https://bitbucket-dc.example.com/site/oauth2/authorize",
|
||||
enterprise_sso: "https://auth.example.com/realms/test/protocol/openid-connect/auth",
|
||||
};
|
||||
if (config.appMode === "saas") {
|
||||
return urls[config.identityProvider] || null;
|
||||
@@ -117,6 +118,74 @@ describe("LoginContent", () => {
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should display Enterprise SSO button when configured", () => {
|
||||
render(
|
||||
<MemoryRouter>
|
||||
<LoginContent
|
||||
githubAuthUrl="https://github.com/oauth/authorize"
|
||||
appMode="saas"
|
||||
authUrl="https://auth.example.com"
|
||||
providersConfigured={["enterprise_sso"]}
|
||||
/>
|
||||
</MemoryRouter>,
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.getByRole("button", { name: /ENTERPRISE_SSO\$CONNECT_TO_ENTERPRISE_SSO/i }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should display Enterprise SSO alongside other providers when all configured", () => {
|
||||
render(
|
||||
<MemoryRouter>
|
||||
<LoginContent
|
||||
githubAuthUrl="https://github.com/oauth/authorize"
|
||||
appMode="saas"
|
||||
authUrl="https://auth.example.com"
|
||||
providersConfigured={["github", "gitlab", "bitbucket", "enterprise_sso"]}
|
||||
/>
|
||||
</MemoryRouter>,
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.getByRole("button", { name: "GITHUB$CONNECT_TO_GITHUB" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("button", { name: "GITLAB$CONNECT_TO_GITLAB" }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("button", { name: /BITBUCKET\$CONNECT_TO_BITBUCKET/i }),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("button", { name: /ENTERPRISE_SSO\$CONNECT_TO_ENTERPRISE_SSO/i }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should redirect to Enterprise SSO auth URL when Enterprise SSO button is clicked", async () => {
|
||||
const user = userEvent.setup();
|
||||
const mockUrl = "https://auth.example.com/realms/test/protocol/openid-connect/auth";
|
||||
|
||||
render(
|
||||
<MemoryRouter>
|
||||
<LoginContent
|
||||
githubAuthUrl="https://github.com/oauth/authorize"
|
||||
appMode="saas"
|
||||
authUrl="https://auth.example.com"
|
||||
providersConfigured={["enterprise_sso"]}
|
||||
/>
|
||||
</MemoryRouter>,
|
||||
);
|
||||
|
||||
const enterpriseSsoButton = screen.getByRole("button", {
|
||||
name: /ENTERPRISE_SSO\$CONNECT_TO_ENTERPRISE_SSO/i,
|
||||
});
|
||||
await user.click(enterpriseSsoButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(window.location.href).toContain(mockUrl);
|
||||
});
|
||||
});
|
||||
|
||||
it("should display message when no providers are configured", () => {
|
||||
render(
|
||||
<MemoryRouter>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { FaUserShield } from "react-icons/fa";
|
||||
import { I18nKey } from "#/i18n/declaration";
|
||||
import OpenHandsLogoWhite from "#/assets/branding/openhands-logo-white.svg?react";
|
||||
import GitHubLogo from "#/assets/branding/github-logo.svg?react";
|
||||
@@ -65,6 +66,12 @@ export function LoginContent({
|
||||
authUrl,
|
||||
});
|
||||
|
||||
const enterpriseSsoAuthUrl = useAuthUrl({
|
||||
appMode: appMode || null,
|
||||
identityProvider: "enterprise_sso",
|
||||
authUrl,
|
||||
});
|
||||
|
||||
const handleAuthRedirect = async (
|
||||
redirectUrl: string,
|
||||
provider: Provider,
|
||||
@@ -127,6 +134,12 @@ export function LoginContent({
|
||||
}
|
||||
};
|
||||
|
||||
const handleEnterpriseSsoAuth = () => {
|
||||
if (enterpriseSsoAuthUrl) {
|
||||
handleAuthRedirect(enterpriseSsoAuthUrl, "enterprise_sso");
|
||||
}
|
||||
};
|
||||
|
||||
const showGithub =
|
||||
providersConfigured &&
|
||||
providersConfigured.length > 0 &&
|
||||
@@ -143,6 +156,10 @@ export function LoginContent({
|
||||
providersConfigured &&
|
||||
providersConfigured.length > 0 &&
|
||||
providersConfigured.includes("bitbucket_data_center");
|
||||
const showEnterpriseSso =
|
||||
providersConfigured &&
|
||||
providersConfigured.length > 0 &&
|
||||
providersConfigured.includes("enterprise_sso");
|
||||
|
||||
const noProvidersConfigured =
|
||||
!providersConfigured || providersConfigured.length === 0;
|
||||
@@ -261,6 +278,19 @@ export function LoginContent({
|
||||
</span>
|
||||
</button>
|
||||
)}
|
||||
|
||||
{showEnterpriseSso && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleEnterpriseSsoAuth}
|
||||
className={`${buttonBaseClasses} bg-[#374151] text-white`}
|
||||
>
|
||||
<FaUserShield size={14} className="shrink-0" />
|
||||
<span className={buttonLabelClasses}>
|
||||
{t(I18nKey.ENTERPRISE_SSO$CONNECT_TO_ENTERPRISE_SSO)}
|
||||
</span>
|
||||
</button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user