index.tsx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import {Fragment, useEffect, useState} from 'react';
  2. import {addErrorMessage} from 'sentry/actionCreators/indicator';
  3. import {updateOrganization} from 'sentry/actionCreators/organizations';
  4. import Form from 'sentry/components/forms/form';
  5. import JsonForm from 'sentry/components/forms/jsonForm';
  6. import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
  7. import organizationSecurityAndPrivacyGroups from 'sentry/data/forms/organizationSecurityAndPrivacyGroups';
  8. import {t} from 'sentry/locale';
  9. import ConfigStore from 'sentry/stores/configStore';
  10. import type {AuthProvider} from 'sentry/types/auth';
  11. import type {Organization} from 'sentry/types/organization';
  12. import useApi from 'sentry/utils/useApi';
  13. import useOrganization from 'sentry/utils/useOrganization';
  14. import DataSecrecy from 'sentry/views/settings/components/dataSecrecy/index';
  15. import SettingsPageHeader from 'sentry/views/settings/components/settingsPageHeader';
  16. import {DataScrubbing} from '../components/dataScrubbing';
  17. export default function OrganizationSecurityAndPrivacyContent() {
  18. const api = useApi();
  19. const organization = useOrganization();
  20. const [authProvider, setAuthProvider] = useState<AuthProvider | null>(null);
  21. useEffect(() => {
  22. async function fetchAuthProvider() {
  23. try {
  24. const response: AuthProvider = await api.requestPromise(
  25. `/organizations/${organization.slug}/auth-provider/`
  26. );
  27. setAuthProvider(response);
  28. } catch {
  29. addErrorMessage(t('Unable to fetch authentication provider'));
  30. }
  31. }
  32. fetchAuthProvider();
  33. }, [organization.slug, api]);
  34. const initialData = organization;
  35. const endpoint = `/organizations/${organization.slug}/`;
  36. const features = new Set(organization.features);
  37. const relayPiiConfig = organization.relayPiiConfig;
  38. const title = t('Security & Privacy');
  39. function handleUpdateOrganization(data: Organization) {
  40. // This will update OrganizationStore (as well as OrganizationsStore
  41. // which is slightly incorrect because it has summaries vs a detailed org)
  42. updateOrganization(data);
  43. }
  44. const {isSelfHosted} = ConfigStore.getState();
  45. // only need data secrecy in saas
  46. const showDataSecrecySettings =
  47. organization.features.includes('data-secrecy') && !isSelfHosted;
  48. return (
  49. <Fragment>
  50. <SentryDocumentTitle title={title} orgSlug={organization.slug} />
  51. <SettingsPageHeader title={title} />
  52. <Form
  53. data-test-id="organization-settings-security-and-privacy"
  54. apiMethod="PUT"
  55. apiEndpoint={endpoint}
  56. initialData={initialData}
  57. additionalFieldProps={{hasSsoEnabled: !!authProvider}}
  58. onSubmitSuccess={handleUpdateOrganization}
  59. onSubmitError={() => addErrorMessage(t('Unable to save change'))}
  60. saveOnBlur
  61. allowUndo
  62. >
  63. <JsonForm
  64. features={features}
  65. forms={organizationSecurityAndPrivacyGroups}
  66. disabled={!organization.access.includes('org:write')}
  67. additionalFieldProps={{showDataSecrecySettings}}
  68. />
  69. </Form>
  70. {showDataSecrecySettings && <DataSecrecy />}
  71. <DataScrubbing
  72. additionalContext={t('These rules can be configured for each project.')}
  73. endpoint={endpoint}
  74. relayPiiConfig={relayPiiConfig}
  75. organization={organization}
  76. disabled={!organization.access.includes('org:write')}
  77. onSubmitSuccess={data => handleUpdateOrganization({...organization, ...data})}
  78. />
  79. </Fragment>
  80. );
  81. }