Skip to content

Commit

Permalink
BED-5069 feat: Add sso config options to providers (#990)
Browse files Browse the repository at this point in the history
  • Loading branch information
mistahj67 authored Jan 2, 2025
1 parent 19089bc commit ec2580a
Show file tree
Hide file tree
Showing 25 changed files with 605 additions and 213 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { rest } from 'msw';
import { setupServer } from 'msw/node';
import { render, screen, waitFor } from '../../test-utils';
import CreateUserDialog from './CreateUserDialog';
import { ListSSOProvidersResponse, SAMLProviderInfo, SSOProvider } from 'js-client-library';
import { ListSSOProvidersResponse, SAMLProviderInfo, SSOProvider, SSOProviderConfiguration } from 'js-client-library';

const testRoles = [
{ id: 1, name: 'Role 1' },
Expand All @@ -34,76 +34,48 @@ const testSSOProviders: SSOProvider[] = [
name: 'saml-provider-1',
slug: 'saml-provider-1',
type: 'SAML',
details: {
idp_issuer_uri: '',
idp_sso_uri: '',
principal_attribute_mappings: null,
sp_issuer_uri: '',
sp_sso_uri: '',
sp_metadata_uri: '',
sp_acs_uri: '',
} as SAMLProviderInfo,
login_uri: '',
callback_uri: '',
created_at: '',
updated_at: '',
details: {} as SAMLProviderInfo,
config: {} as SSOProviderConfiguration['config'],
},
{
id: 2,
name: 'saml-provider-2',
slug: 'saml-provider-2',
type: 'SAML',
details: {
idp_issuer_uri: '',
idp_sso_uri: '',
principal_attribute_mappings: null,
sp_issuer_uri: '',
sp_sso_uri: '',
sp_metadata_uri: '',
sp_acs_uri: '',
} as SAMLProviderInfo,
login_uri: '',
callback_uri: '',
created_at: '',
updated_at: '',
details: {} as SAMLProviderInfo,
config: {} as SSOProviderConfiguration['config'],
},
{
id: 3,
name: 'saml-provider-3',
slug: 'saml-provider-3',
type: 'SAML',
details: {
idp_issuer_uri: '',
idp_sso_uri: '',
principal_attribute_mappings: null,
sp_issuer_uri: '',
sp_sso_uri: '',
sp_metadata_uri: '',
sp_acs_uri: '',
} as SAMLProviderInfo,
login_uri: '',
callback_uri: '',
created_at: '',
updated_at: '',
details: {} as SAMLProviderInfo,
config: {} as SSOProviderConfiguration['config'],
},
{
id: 4,
name: 'saml-provider-4',
slug: 'saml-provider-4',
type: 'SAML',
details: {
idp_issuer_uri: '',
idp_sso_uri: '',
principal_attribute_mappings: null,
sp_issuer_uri: '',
sp_sso_uri: '',
sp_metadata_uri: '',
sp_acs_uri: '',
} as SAMLProviderInfo,
login_uri: '',
callback_uri: '',
created_at: '',
updated_at: '',
details: {} as SAMLProviderInfo,
config: {} as SSOProviderConfiguration['config'],
},
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,51 +17,32 @@
import userEvent from '@testing-library/user-event';
import { act, render, screen } from '../../test-utils';
import LoginViaSSOForm from './LoginViaSSOForm';
import { SSOProvider } from 'js-client-library';
import { OIDCProviderInfo, SAMLProviderInfo, SSOProvider, SSOProviderConfiguration } from 'js-client-library';

const testSSOProviders: SSOProvider[] = [
{
name: 'sso-provider-1',
slug: 'test-slug-1',
type: 'OIDC',
details: {
client_id: '',
issuer: '',
sso_provider_id: 2,
id: 1,
created_at: '',
updated_at: '',
},
login_uri: '',
callback_uri: '',
id: 1,
created_at: '',
updated_at: '',
details: {} as OIDCProviderInfo,
config: {} as SSOProviderConfiguration['config'],
},
{
name: 'sso-provider-2',
slug: 'test-slug-2',
type: 'SAML',
details: {
name: '',
display_name: '',
idp_issuer_uri: '',
idp_sso_uri: '',
principal_attribute_mappings: null,
sp_issuer_uri: '',
sp_metadata_uri: '',
sp_acs_uri: '',
sp_sso_uri: '',
sso_provider_id: 1,
id: 1,
created_at: '',
updated_at: '',
},
login_uri: '',
callback_uri: '',
id: 2,
created_at: '',
updated_at: '',
details: {} as SAMLProviderInfo,
config: {} as SSOProviderConfiguration['config'],
},
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ const samlProvider: SSOProvider = {
callback_uri: '',
created_at: '2022-02-24T23:38:41.420271Z',
updated_at: '2022-02-24T23:38:41.420271Z',
config: {
auto_provision: { enabled: false, role_provision: false, default_role_id: 0 },
},
};

const oidcProvider: SSOProvider = {
Expand All @@ -49,9 +52,12 @@ const oidcProvider: SSOProvider = {
client_id: 'gotham-oidc',
} as OIDCProviderInfo,
login_uri: '',
callback_uri: '',
callback_uri: 'http://bloodhound.localhost/api/v2/sso/test-idp-2/callback',
created_at: '2022-02-24T23:38:41.420271Z',
updated_at: '2022-02-24T23:38:41.420271Z',
config: {
auto_provision: { enabled: true, role_provision: true, default_role_id: 1 },
},
};

describe('SSOProviderTable', () => {
Expand All @@ -64,6 +70,15 @@ describe('SSOProviderTable', () => {
expect(await screen.findByText(samlInfo.sp_sso_uri)).toBeInTheDocument();
expect(await screen.findByText(samlInfo.sp_acs_uri)).toBeInTheDocument();
expect(await screen.findByText(samlInfo.sp_metadata_uri)).toBeInTheDocument();

expect(await screen.findByText('Automatically create new users on login')).toBeInTheDocument();
// This provider has IDP provisioning disabled which should hide these 2 fields
expect(screen.queryByText('Allow SSO provider to manage roles for new users')).not.toBeInTheDocument();
expect(screen.queryByText('Default role when creating new users')).not.toBeInTheDocument();

expect(
screen.getByRole('button', { name: `Download ${samlProvider.name} SP Certificate` })
).toBeInTheDocument();
});

it('should render oidc info provider', async () => {
Expand All @@ -73,5 +88,10 @@ describe('SSOProviderTable', () => {

expect(await screen.findByText(oidcInfo.issuer)).toBeInTheDocument();
expect(await screen.findByText(oidcInfo.client_id)).toBeInTheDocument();
expect(await screen.findByText(oidcProvider.callback_uri)).toBeInTheDocument();

expect(await screen.findByText('Automatically create new users on login')).toBeInTheDocument();
expect(await screen.findByText('Allow SSO provider to manage roles for new users')).toBeInTheDocument();
expect(await screen.findByText('Default role when creating new users')).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
// SPDX-License-Identifier: Apache-2.0

import { Paper, Box, Typography, useTheme } from '@mui/material';
import { FC } from 'react';
import { FC, useMemo } from 'react';
import fileDownload from 'js-file-download';
import { OIDCProviderInfo, SAMLProviderInfo, SSOProvider } from 'js-client-library';
import { Button } from '@bloodhoundenterprise/doodleui';
import { OIDCProviderInfo, SAMLProviderInfo, SSOProvider, Role } from 'js-client-library';
import { Button, Label } from '@bloodhoundenterprise/doodleui';
import { Field, FieldsContainer, usePaneStyles, useHeaderStyles } from '../../views/Explore';
import LabelWithCopy from '../LabelWithCopy';
import { apiClient } from '../../utils';
Expand All @@ -27,7 +27,7 @@ import { useNotifications } from '../../providers';
const SAMLProviderInfoPanel: FC<{
samlProviderDetails: SAMLProviderInfo;
}> = ({ samlProviderDetails }) => (
<FieldsContainer>
<>
<Field
label={<LabelWithCopy label='IdP SSO URL' valueToCopy={samlProviderDetails.idp_sso_uri} hoverOnly />}
value={samlProviderDetails.idp_sso_uri}
Expand All @@ -46,15 +46,15 @@ const SAMLProviderInfoPanel: FC<{
}
value={samlProviderDetails.sp_metadata_uri}
/>
</FieldsContainer>
</>
);

const OIDCProviderInfoPanel: FC<{
ssoProvider: SSOProvider;
}> = ({ ssoProvider }) => {
const oidcProviderDetails = ssoProvider.details as OIDCProviderInfo;
return (
<FieldsContainer>
<>
<Field
label={<LabelWithCopy label='Client ID' valueToCopy={oidcProviderDetails.client_id} hoverOnly />}
value={oidcProviderDetails.client_id}
Expand All @@ -67,32 +67,38 @@ const OIDCProviderInfoPanel: FC<{
label={<LabelWithCopy label='Callback URL' valueToCopy={ssoProvider.callback_uri} hoverOnly />}
value={ssoProvider.callback_uri}
/>
</FieldsContainer>
</>
);
};

const SSOProviderInfoPanel: FC<{
ssoProvider: SSOProvider;
}> = ({ ssoProvider }) => {
roles?: Role[];
}> = ({ ssoProvider, roles }) => {
const theme = useTheme();
const paneStyles = usePaneStyles();
const headerStyles = useHeaderStyles();
const { addNotification } = useNotifications();

const defaultRoleName = useMemo(
() => roles?.find((role) => role.id === ssoProvider.config?.auto_provision?.default_role_id)?.name,
[roles, ssoProvider.config?.auto_provision?.default_role_id]
);

if (!ssoProvider.type) {
return null;
}

let infoPanel;
let innerInfoPanel;
switch (ssoProvider.type.toLowerCase()) {
case 'saml':
infoPanel = <SAMLProviderInfoPanel samlProviderDetails={ssoProvider.details as SAMLProviderInfo} />;
innerInfoPanel = <SAMLProviderInfoPanel samlProviderDetails={ssoProvider.details as SAMLProviderInfo} />;
break;
case 'oidc':
infoPanel = <OIDCProviderInfoPanel ssoProvider={ssoProvider} />;
innerInfoPanel = <OIDCProviderInfoPanel ssoProvider={ssoProvider} />;
break;
default:
infoPanel = null;
innerInfoPanel = null;
}

const downloadSAMLSigningCertificate = () => {
Expand Down Expand Up @@ -157,7 +163,25 @@ const SSOProviderInfoPanel: FC<{
<Box flexShrink={0} flexGrow={1} fontWeight='bold' ml={theme.spacing(1)} fontSize={'small'}>
Provider Information:
</Box>
{infoPanel}
<FieldsContainer>
{innerInfoPanel}
<Field
label={<Label>Automatically create new users on login</Label>}
value={ssoProvider.config?.auto_provision?.enabled ? 'Yes' : 'No'}
/>
{ssoProvider.config?.auto_provision?.enabled && (
<>
<Field
label={<Label>Allow SSO provider to manage roles for new users</Label>}
value={ssoProvider.config?.auto_provision?.role_provision ? 'Yes' : 'No'}
/>
<Field
label={<Label>Default role when creating new users</Label>}
value={defaultRoleName ?? 'Read-Only'}
/>
</>
)}
</FieldsContainer>
</Paper>
</Paper>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// SPDX-License-Identifier: Apache-2.0

import userEvent from '@testing-library/user-event';
import { OIDCProviderInfo, SAMLProviderInfo, SSOProvider } from 'js-client-library';
import { OIDCProviderInfo, SAMLProviderInfo, SSOProvider, SSOProviderConfiguration } from 'js-client-library';
import { render, screen } from '../../test-utils';
import { SortOrder } from '../../utils';
import SSOProviderTable from './SSOProviderTable';
Expand All @@ -30,6 +30,7 @@ const samlProvider: SSOProvider = {
created_at: '2022-02-24T23:38:41.420271Z',
updated_at: '2022-02-24T23:38:41.420271Z',
details: {} as SAMLProviderInfo,
config: {} as SSOProviderConfiguration['config'],
};

const oidcProvider: SSOProvider = {
Expand All @@ -42,6 +43,7 @@ const oidcProvider: SSOProvider = {
created_at: '2022-02-24T23:38:41.420271Z',
updated_at: '2022-02-24T23:38:41.420271Z',
details: {} as OIDCProviderInfo,
config: {} as SSOProviderConfiguration['config'],
};

const ssoProviders = [samlProvider, oidcProvider];
Expand Down
Loading

0 comments on commit ec2580a

Please sign in to comment.