def _finish_setup_pipeline(self, identity): """ The setup flow creates the auth provider as well as an identity linked to the active user. """ request = self.request if not request.user.is_authenticated(): return self.error(ERR_NOT_AUTHED) if request.user.id != self.state.uid: return self.error(ERR_UID_MISMATCH) data = self.fetch_state() config = self.provider.build_config(data) try: om = OrganizationMember.objects.get(user=request.user, organization=self.organization) except OrganizationMember.DoesNotExist: return self.error(ERR_UID_MISMATCH) # disable require 2FA for the organization # since only SSO or require 2FA can be enabled self.disable_2fa_required() self.auth_provider = AuthProvider.objects.create( organization=self.organization, provider=self.provider.key, config=config ) handle_attach_identity( self.auth_provider, self.request, self.organization, self.provider, identity, om ) auth.mark_sso_complete(request, self.organization.id) sso_enabled.send_robust( organization=self.organization, user=request.user, provider=self.provider.key, sender=self.__class__, ) AuditLogEntry.objects.create( organization=self.organization, actor=request.user, ip_address=request.META["REMOTE_ADDR"], target_object=self.auth_provider.id, event=AuditLogEntryEvent.SSO_ENABLE, data=self.auth_provider.get_audit_log_data(), ) email_missing_links.delay(self.organization.id, request.user.id, self.provider.key) messages.add_message(self.request, messages.SUCCESS, OK_SETUP_SSO) self.clear_session() next_uri = reverse( "sentry-organization-auth-provider-settings", args=[self.organization.slug] ) return HttpResponseRedirect(next_uri)
def _finish_setup_pipeline(self, identity): """ The setup flow creates the auth provider as well as an identity linked to the active user. """ request = self.request if not request.user.is_authenticated(): return self.error(ERR_NOT_AUTHED) if request.user.id != self.state.uid: return self.error(ERR_UID_MISMATCH) data = self.fetch_state() config = self.provider.build_config(data) try: om = OrganizationMember.objects.get( user=request.user, organization=self.organization, ) except OrganizationMember.DoesNotExist: return self.error(ERR_UID_MISMATCH) self.auth_provider = AuthProvider.objects.create( organization=self.organization, provider=self.provider.key, config=config, ) self._handle_attach_identity(identity, om) auth.mark_sso_complete(request, self.organization.id) AuditLogEntry.objects.create( organization=self.organization, actor=request.user, ip_address=request.META['REMOTE_ADDR'], target_object=self.auth_provider.id, event=AuditLogEntryEvent.SSO_ENABLE, data=self.auth_provider.get_audit_log_data(), ) email_missing_links.delay(self.organization.id, request.user.id, self.provider.key) messages.add_message( self.request, messages.SUCCESS, OK_SETUP_SSO, ) self.clear_session() next_uri = reverse( 'sentry-organization-auth-provider-settings', args=[ self.organization.slug, ] ) return HttpResponseRedirect(next_uri)
def _finish_setup_pipeline(self, identity): """ The setup flow creates the auth provider as well as an identity linked to the active user. """ request = self.request if not request.user.is_authenticated(): return self.error(ERR_NOT_AUTHED) if request.user.id != request.session['auth']['uid']: return self.error(ERR_UID_MISMATCH) state = request.session['auth']['state'] config = self.provider.build_config(state) try: om = OrganizationMember.objects.get( user=request.user, organization=self.organization, ) except OrganizationMember.DoesNotExist: return self.error(ERR_UID_MISMATCH) self.auth_provider = AuthProvider.objects.create( organization=self.organization, provider=self.provider.key, config=config, ) self._handle_attach_identity(identity, om) auth.mark_sso_complete(request, self.organization.id) AuditLogEntry.objects.create( organization=self.organization, actor=request.user, ip_address=request.META['REMOTE_ADDR'], target_object=self.auth_provider.id, event=AuditLogEntryEvent.SSO_ENABLE, data=self.auth_provider.get_audit_log_data(), ) email_missing_links.delay(organization_id=self.organization.id, ) messages.add_message( self.request, messages.SUCCESS, OK_SETUP_SSO, ) self.clear_session() next_uri = reverse('sentry-organization-auth-settings', args=[ self.organization.slug, ]) return HttpResponseRedirect(next_uri)
def post(self, request, organization): if not features.has("organizations:sso-basic", organization, actor=request.user): return Response(ERR_NO_SSO, status=403) try: auth_provider = AuthProvider.objects.get(organization=organization) except AuthProvider.DoesNotExist: raise ResourceDoesNotExist email_missing_links.delay(organization.id, request.user.id, auth_provider.key) return Response(status=200)
def post(self, request, organization): if not features.has('organizations:sso', organization, actor=request.user): return Response(ERR_NO_SSO, status=403) try: auth_provider = AuthProvider.objects.get( organization=organization, ) except AuthProvider.DoesNotExist: raise ResourceDoesNotExist email_missing_links.delay( organization.id, request.user.id, auth_provider.key) return Response(status=200)
def handle_existing_provider(self, request, organization, auth_provider): provider = auth_provider.get_provider() if request.method == 'POST': op = request.POST.get('op') if op == 'disable': self._disable_provider(request, organization, auth_provider) messages.add_message( request, messages.SUCCESS, OK_PROVIDER_DISABLED, ) next_uri = u'/settings/{}/auth/'.format(organization.slug) return self.redirect(next_uri) elif op == 'reinvite': email_missing_links.delay(organization.id, request.user.id, provider.key) messages.add_message( request, messages.SUCCESS, OK_REMINDERS_SENT, ) next_uri = reverse( 'sentry-organization-auth-provider-settings', args=[ organization.slug]) return self.redirect(next_uri) form = AuthProviderSettingsForm( data=request.POST if request.POST.get('op') == 'settings' else None, initial={ 'require_link': not auth_provider.flags.allow_unlinked, 'default_role': organization.default_role, }, ) if form.is_valid(): auth_provider.flags.allow_unlinked = not form.cleaned_data['require_link'] auth_provider.save() organization.default_role = form.cleaned_data['default_role'] organization.save() view = provider.get_configure_view() response = view(request, organization, auth_provider) if isinstance(response, HttpResponse): return response elif isinstance(response, Response): response = response.render( request, { 'auth_provider': auth_provider, 'organization': organization, 'provider': provider, } ) pending_links_count = OrganizationMember.objects.filter( organization=organization, flags=F('flags').bitand(~OrganizationMember.flags['sso:linked']), ).count() context = { 'form': form, 'pending_links_count': pending_links_count, 'login_url': absolute_uri(reverse('sentry-organization-home', args=[organization.slug])), 'auth_provider': auth_provider, 'provider_name': provider.name, 'content': response, } return self.respond('sentry/organization-auth-provider-settings.html', context)
def handle_existing_provider(self, request: Request, organization, auth_provider): provider = auth_provider.get_provider() if request.method == "POST": op = request.POST.get("op") if op == "disable": self._disable_provider(request, organization, auth_provider) messages.add_message(request, messages.SUCCESS, OK_PROVIDER_DISABLED) next_uri = f"/settings/{organization.slug}/auth/" return self.redirect(next_uri) elif op == "reinvite": email_missing_links.delay(organization.id, request.user.id, provider.key) messages.add_message(request, messages.SUCCESS, OK_REMINDERS_SENT) next_uri = reverse( "sentry-organization-auth-provider-settings", args=[organization.slug]) return self.redirect(next_uri) form = auth_provider_settings_form(provider, auth_provider, organization, request) if form.is_valid(): auth_provider.flags.allow_unlinked = not form.cleaned_data[ "require_link"] form_scim_enabled = form.cleaned_data.get("enable_scim", False) if auth_provider.flags.scim_enabled != form_scim_enabled: if form_scim_enabled: auth_provider.enable_scim(request.user) else: auth_provider.disable_scim(request.user) auth_provider.save() organization.default_role = form.cleaned_data["default_role"] organization.save() if form.initial != form.cleaned_data: changed_data = {} for key, value in form.cleaned_data.items(): if form.initial.get(key) != value: changed_data[key] = f"to {value}" self.create_audit_entry( request, organization=organization, target_object=auth_provider.id, event=AuditLogEntryEvent.SSO_EDIT, data=changed_data, ) view = provider.get_configure_view() response = view(request, organization, auth_provider) if isinstance(response, HttpResponse): return response elif isinstance(response, Response): response = response.render( request, { "auth_provider": auth_provider, "organization": organization, "provider": provider, }, ) pending_links_count = OrganizationMember.objects.filter( organization=organization, flags=F("flags").bitand(~OrganizationMember.flags["sso:linked"]), ).count() context = { "form": form, "pending_links_count": pending_links_count, "login_url": absolute_uri(organization.get_url()), "auth_provider": auth_provider, "provider_name": provider.name, "scim_api_token": auth_provider.get_scim_token(), "scim_url": auth_provider.get_scim_url(), "content": response, } return self.respond("sentry/organization-auth-provider-settings.html", context)