123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- import EmptyMessage from 'sentry/components/emptyMessage';
- import ExternalLink from 'sentry/components/links/externalLink';
- import Panel from 'sentry/components/panels/panel';
- import PanelAlert from 'sentry/components/panels/panelAlert';
- import PanelBody from 'sentry/components/panels/panelBody';
- import PanelHeader from 'sentry/components/panels/panelHeader';
- import {t, tct} from 'sentry/locale';
- import type {AuthProvider, Organization} from 'sentry/types';
- import {descopeFeatureName} from 'sentry/utils';
- import getCsrfToken from 'sentry/utils/getCsrfToken';
- import withOrganization from 'sentry/utils/withOrganization';
- import SettingsPageHeader from 'sentry/views/settings/components/settingsPageHeader';
- import PermissionAlert from 'sentry/views/settings/organization/permissionAlert';
- import ProviderItem from './providerItem';
- const PROVIDER_POPULARITY: Record<string, number> = {
- google: 0,
- github: 1,
- okta: 2,
- 'active-directory': 3,
- saml2: 4,
- onelogin: 5,
- rippling: 6,
- auth0: 7,
- jumpcloud: 8,
- };
- type Props = {
- organization: Organization;
- providerList: AuthProvider[];
- activeProvider?: AuthProvider;
- };
- function OrganizationAuthList({organization, providerList, activeProvider}: Props) {
- const features = organization.features;
- // Sort provider list twice: first, by popularity,
- // and then a second time, to sort unavailable providers for the current plan to the end of the list.
- const sortedByPopularity = (providerList ?? []).sort((a, b) => {
- if (!(a.key in PROVIDER_POPULARITY)) {
- return -1;
- }
- if (!(b.key in PROVIDER_POPULARITY)) {
- return 1;
- }
- if (PROVIDER_POPULARITY[a.key] === PROVIDER_POPULARITY[b.key]) {
- return 0;
- }
- return PROVIDER_POPULARITY[a.key] > PROVIDER_POPULARITY[b.key] ? 1 : -1;
- });
- const list = sortedByPopularity.sort((a, b) => {
- const aEnabled = features.includes(descopeFeatureName(a.requiredFeature));
- const bEnabled = features.includes(descopeFeatureName(b.requiredFeature));
- if (aEnabled === bEnabled) {
- return 0;
- }
- return aEnabled ? -1 : 1;
- });
- const warn2FADisable =
- organization.require2FA &&
- list.some(({requiredFeature}) =>
- features.includes(descopeFeatureName(requiredFeature))
- );
- return (
- <div className="sso">
- <SettingsPageHeader title="Authentication" />
- <PermissionAlert />
- <Panel>
- <PanelHeader>{t('Choose a provider')}</PanelHeader>
- <PanelBody>
- {!activeProvider && (
- <PanelAlert type="info">
- {tct(
- 'Get started with Single Sign-on for your organization by selecting a provider. Read more in our [link:SSO documentation].',
- {
- link: (
- <ExternalLink href="https://docs.sentry.io/product/accounts/sso/" />
- ),
- }
- )}
- </PanelAlert>
- )}
- {warn2FADisable && (
- <PanelAlert type="warning">
- {t('Require 2FA will be disabled if you enable SSO.')}
- </PanelAlert>
- )}
- <form
- action={`/organizations/${organization.slug}/auth/configure/`}
- method="POST"
- >
- <input type="hidden" name="csrfmiddlewaretoken" value={getCsrfToken()} />
- <input type="hidden" name="init" value="1" />
- {list.map(provider => (
- <ProviderItem
- key={provider.key}
- provider={provider}
- active={!!activeProvider && provider.key === activeProvider.key}
- />
- ))}
- {list.length === 0 && (
- <EmptyMessage>
- {t('No authentication providers are available.')}
- </EmptyMessage>
- )}
- </form>
- </PanelBody>
- </Panel>
- </div>
- );
- }
- export default withOrganization(OrganizationAuthList);
- // For tests
- export {OrganizationAuthList};
|