index.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicator';
  2. import {t} from 'sentry/locale';
  3. import {AuthProvider, Organization} from 'sentry/types';
  4. import routeTitleGen from 'sentry/utils/routeTitle';
  5. import {normalizeUrl} from 'sentry/utils/withDomainRequired';
  6. import withOrganization from 'sentry/utils/withOrganization';
  7. import AsyncView from 'sentry/views/asyncView';
  8. import OrganizationAuthList from './organizationAuthList';
  9. type Props = AsyncView['props'] & {
  10. organization: Organization;
  11. };
  12. type State = AsyncView['state'] & {
  13. provider: AuthProvider | null;
  14. providerList: AuthProvider[] | null;
  15. };
  16. class OrganizationAuth extends AsyncView<Props, State> {
  17. componentDidUpdate() {
  18. const {organization} = this.props;
  19. const access = organization.access;
  20. if (this.state.provider && access.includes('org:write')) {
  21. // If SSO provider is configured, keep showing loading while we redirect
  22. // to django configuration view
  23. const path = normalizeUrl(`/organizations/${organization.slug}/auth/configure/`);
  24. // Don't break the back button by first replacing the current history
  25. // state so pressing back skips this react view.
  26. this.props.router?.replace(path);
  27. window.location.assign(path);
  28. }
  29. }
  30. getEndpoints(): ReturnType<AsyncView['getEndpoints']> {
  31. const {organization} = this.props;
  32. return [
  33. ['providerList', `/organizations/${organization.slug}/auth-providers/`],
  34. ['provider', `/organizations/${organization.slug}/auth-provider/`],
  35. ];
  36. }
  37. getTitle() {
  38. return routeTitleGen(t('Auth Settings'), this.props.organization.slug, false);
  39. }
  40. /**
  41. * TODO(epurkhiser): This does not work right now as we still fallback to the
  42. * old SSO auth configuration page
  43. */
  44. handleSendReminders = (_provider: AuthProvider) => {
  45. const {organization} = this.props;
  46. this.setState({sendRemindersBusy: true});
  47. this.api.request(
  48. `/organizations/${organization.slug}/auth-provider/send-reminders/`,
  49. {
  50. method: 'POST',
  51. data: {},
  52. success: () => addSuccessMessage(t('Sent reminders to members')),
  53. error: () => addErrorMessage(t('Failed to send reminders')),
  54. complete: () => this.setState({sendRemindersBusy: false}),
  55. }
  56. );
  57. };
  58. /**
  59. * TODO(epurkhiser): This does not work right now as we still fallback to the
  60. * old SSO auth configuration page
  61. */
  62. handleConfigure = (provider: AuthProvider) => {
  63. const {organization} = this.props;
  64. this.setState({busy: true});
  65. this.api.request(`/organizations/${organization.slug}/auth-provider/`, {
  66. method: 'POST',
  67. data: {provider, init: true},
  68. success: data => {
  69. // Redirect to auth provider URL
  70. if (data && data.auth_url) {
  71. window.location.href = data.auth_url;
  72. }
  73. },
  74. error: () => {
  75. this.setState({busy: false});
  76. },
  77. });
  78. };
  79. /**
  80. * TODO(epurkhiser): This does not work right now as we still fallback to the
  81. * old SSO auth configuration page
  82. */
  83. handleDisableProvider = (provider: AuthProvider) => {
  84. const {organization} = this.props;
  85. this.setState({busy: true});
  86. this.api.request(`/organizations/${organization.slug}/auth-provider/`, {
  87. method: 'DELETE',
  88. data: {provider},
  89. success: () => {
  90. this.setState({provider: null, busy: false});
  91. },
  92. error: () => {
  93. this.setState({busy: false});
  94. },
  95. });
  96. };
  97. renderBody() {
  98. const {providerList, provider} = this.state;
  99. if (providerList === null) {
  100. return null;
  101. }
  102. if (this.props.organization.access.includes('org:write') && provider) {
  103. // If SSO provider is configured, keep showing loading while we redirect
  104. // to django configuration view
  105. return this.renderLoading();
  106. }
  107. const activeProvider = providerList?.find(p => p.key === provider?.key);
  108. return (
  109. <OrganizationAuthList activeProvider={activeProvider} providerList={providerList} />
  110. );
  111. }
  112. }
  113. export default withOrganization(OrganizationAuth);