def handle_new_user(auth_provider, organization, request, identity): user = User.objects.create(username=uuid4().hex, email=identity["email"], name=identity.get("name", "")[:200]) if settings.TERMS_URL and settings.PRIVACY_URL: user.update( flags=F("flags").bitor(User.flags.newsletter_consent_prompt)) try: with transaction.atomic(): auth_identity = AuthIdentity.objects.create( auth_provider=auth_provider, user=user, ident=identity["id"], data=identity.get("data", {}), ) except IntegrityError: auth_identity = AuthIdentity.objects.get(auth_provider=auth_provider, ident=identity["id"]) auth_identity.update(user=user, data=identity.get("data", {})) user.send_confirm_emails(is_new_user=True) provider = auth_provider.provider if auth_provider else None user_signup.send_robust(sender=handle_new_user, user=user, source="sso", provider=provider, referrer="in-app") handle_new_membership(auth_provider, organization, request, auth_identity) return auth_identity
def handle_basic_auth(self, request, **kwargs): can_register = self.can_register(request) op = request.POST.get("op") organization = kwargs.pop("organization", None) if not op: # Detect that we are on the register page by url /register/ and # then activate the register tab by default. if "/register" in request.path_info and can_register: op = "register" elif request.GET.get("op") == "sso": op = "sso" login_form = self.get_login_form(request) if can_register: register_form = self.get_register_form( request, initial={"username": request.session.get("invite_email", "")} ) else: register_form = None if can_register and register_form.is_valid(): user = register_form.save() user.send_confirm_emails(is_new_user=True) user_signup.send_robust( sender=self, user=user, source="register-form", referrer="in-app" ) # HACK: grab whatever the first backend is and assume it works user.backend = settings.AUTHENTICATION_BACKENDS[0] auth.login(request, user, organization_id=organization.id if organization else None) # can_register should only allow a single registration request.session.pop("can_register", None) request.session.pop("invite_email", None) # In single org mode, associate the user to the orgnaization if settings.SENTRY_SINGLE_ORGANIZATION: organization = Organization.get_default() OrganizationMember.objects.create( organization=organization, role=organization.default_role, user=user ) # Attempt to directly accept any pending invites invite_helper = ApiInviteHelper.from_cookie(request=request, instance=self) if invite_helper and invite_helper.valid_request: invite_helper.accept_invite() response = self.redirect_to_org(request) remove_invite_cookie(request, response) return response return self.redirect(auth.get_login_redirect(request)) elif request.method == "POST": from sentry.app import ratelimiter from sentry.utils.hashlib import md5_text login_attempt = ( op == "login" and request.POST.get("username") and request.POST.get("password") ) if login_attempt and ratelimiter.is_limited( u"auth:login:username:{}".format( md5_text(login_form.clean_username(request.POST["username"])).hexdigest() ), limit=10, window=60, # 10 per minute should be enough for anyone ): login_form.errors["__all__"] = [ u"You have made too many login attempts. Please try again later." ] metrics.incr( "login.attempt", instance="rate_limited", skip_internal=True, sample_rate=1.0 ) elif login_form.is_valid(): user = login_form.get_user() auth.login(request, user, organization_id=organization.id if organization else None) metrics.incr( "login.attempt", instance="success", skip_internal=True, sample_rate=1.0 ) if not user.is_active: return self.redirect(reverse("sentry-reactivate-account")) return self.redirect(auth.get_login_redirect(request)) else: metrics.incr( "login.attempt", instance="failure", skip_internal=True, sample_rate=1.0 ) context = { "op": op or "login", "server_hostname": get_server_hostname(), "login_form": login_form, "organization": organization, "register_form": register_form, "CAN_REGISTER": can_register, "join_request_link": self.get_join_request_link(organization), } context.update(additional_context.run_callbacks(request)) return self.respond_login(request, context, **kwargs)