def app_from_template(request, domain, slug): send_hubspot_form(HUBSPOT_APP_TEMPLATE_FORM_ID, request) clear_app_cache(request, domain) template = load_app_template(slug) app = import_app_util(template, domain, { 'created_from_template': '%s' % slug, }) for path in get_template_app_multimedia_paths(slug): media_class = None with open(os.path.join(app_template_dir(slug), path), "rb") as f: f.seek(0) data = f.read() media_class = CommCareMultimedia.get_class_by_data(data) if media_class: multimedia = media_class.get_by_data(data) multimedia.attach_data( data, original_filename=os.path.basename(path), username=request.user.username) multimedia.add_domain(domain, owner=True) app.create_mapping(multimedia, MULTIMEDIA_PREFIX + path) comment = _("A sample application you can try out in Web Apps") build = make_async_build(app, request.user.username, release=True, comment=comment) cloudcare_state = '{{"appId":"{}"}}'.format(build._id) return HttpResponseRedirect( reverse(FormplayerMain.urlname, args=[domain]) + '#' + cloudcare_state)
def send_preparation_analytics(self, export_instances, export_filters): send_hubspot_form(HUBSPOT_DOWNLOADED_EXPORT_FORM_ID, self.request) track_workflow(self.request.couch_user.username, 'Downloaded {} Exports With {}Data'.format( self.model[0].upper() + self.model[1:], '' if any(get_export_size(instance, export_filters) > 0 for instance in export_instances) else 'No ', ))
def app_from_template(request, domain, slug): send_hubspot_form(HUBSPOT_APP_TEMPLATE_FORM_ID, request) clear_app_cache(request, domain) build = load_app_from_slug(domain, request.user.username, slug) cloudcare_state = '{{"appId":"{}"}}'.format(build._id) return HttpResponseRedirect(reverse(FormplayerMain.urlname, args=[domain]) + '#' + cloudcare_state)
def _process_invitation(request, invitation, web_user, is_new_user=False): """ Processes the Invitation (if available) and sets up the user in the new domain they were invited to. :param request: HttpRequest :param invitation: Invitation or None :param web_user: WebUser """ if invitation.is_expired: request.sso_new_user_messages['error'].append( _("Could not accept invitation because it is expired.") ) return invitation.accept_invitation_and_join_domain(web_user) request.sso_new_user_messages['success'].append( _('You have been added to the "{}" project space.').format( invitation.domain, ) ) if settings.IS_SAAS_ENVIRONMENT and is_new_user: track_workflow( web_user.username, "New User Accepted a project invitation with SSO", {"New User Accepted a project invitation": "yes"} ) send_hubspot_form( HUBSPOT_NEW_USER_INVITE_FORM, request, user=web_user )
def send_preparation_analytics(self, export_instances, export_filters): send_hubspot_form(HUBSPOT_DOWNLOADED_EXPORT_FORM_ID, self.request) track_workflow(self.request.couch_user.username, 'Downloaded {} Exports With {}Data'.format( self.model[0].upper() + self.model[1:], '' if any(get_export_size(instance, export_filters) > 0 for instance in export_instances) else 'No ', ))
def app_from_template(request, domain, slug): send_hubspot_form(HUBSPOT_APP_TEMPLATE_FORM_ID, request) track_workflow(request.couch_user.username, "User created an application from a template") clear_app_cache(request, domain) build = load_app_from_slug(domain, request.user.username, slug) cloudcare_state = '{{"appId":"{}"}}'.format(build._id) return HttpResponseRedirect(reverse(FormplayerMain.urlname, args=[domain]) + '#' + cloudcare_state)
def _get_form_designer_view(request, domain, app, module, form): if app and app.copy_of: messages.warning(request, _( "You tried to edit a form that was from a previous release, so " "we have directed you to the latest version of your application." )) return back_to_main(request, domain, app_id=app.id) if form.no_vellum: messages.warning(request, _( "You tried to edit this form in the Form Builder. " "However, your administrator has locked this form against editing " "in the form builder, so we have redirected you to " "the form's front page instead." )) return back_to_main(request, domain, app_id=app.id, form_unique_id=form.unique_id) send_hubspot_form(HUBSPOT_FORM_BUILDER_FORM_ID, request) def _form_too_large(_app, _form): # form less than 0.1MB, anything larger starts to have # performance issues with fullstory return _app.blobs['{}.xml'.format(_form.unique_id)]['content_length'] > 102400 context = get_apps_base_context(request, domain, app) context.update(locals()) vellum_options = _get_base_vellum_options(request, domain, app, context['lang']) vellum_options['core'] = _get_vellum_core_context(request, domain, app, module, form, context['lang']) vellum_options['plugins'] = _get_vellum_plugins(domain, form, module) vellum_options['features'] = _get_vellum_features(request, domain, app) context['vellum_options'] = vellum_options context.update({ 'vellum_debug': settings.VELLUM_DEBUG, 'nav_form': form, 'formdesigner': True, 'include_fullstory': not _form_too_large(app, form), 'CKEDITOR_BASEPATH': "app_manager/js/vellum/lib/ckeditor/", 'show_live_preview': should_show_preview_app( request, app, request.couch_user.username, ), 'show_ui_notification_to_hide_translations': (len(app.langs) > 2), }) context.update(_get_requirejs_context()) if request.user.is_superuser: context.update({'notification_options': _get_notification_options(request, domain, app, form)}) notify_form_opened(domain, request.couch_user, app.id, form.unique_id) return render(request, "app_manager/form_designer.html", context)
def default_new_app(request, domain): """New Blank Application according to defaults. So that we can link here instead of creating a form and posting to the above link, which was getting annoying for the Dashboard. """ send_hubspot_form(HUBSPOT_APP_TEMPLATE_FORM_ID, request) lang = 'en' app = Application.new_app(domain, _("Untitled Application"), lang=lang) add_ons.init_app(request, app) if request.project.secure_submissions: app.secure_submissions = True clear_app_cache(request, domain) app.save() return HttpResponseRedirect(reverse('view_app', args=[domain, app._id]))
def default_new_app(request, domain): """New Blank Application according to defaults. So that we can link here instead of creating a form and posting to the above link, which was getting annoying for the Dashboard. """ send_hubspot_form(HUBSPOT_APP_TEMPLATE_FORM_ID, request) lang = 'en' app = Application.new_app(domain, _("Untitled Application"), lang=lang) add_ons.init_app(request, app) if request.project.secure_submissions: app.secure_submissions = True clear_app_cache(request, domain) app.save() return HttpResponseRedirect(reverse('view_app', args=[domain, app._id]))
def post(self, request, *args, **kwargs): if self.invite_web_user_form.is_valid(): # If user exists and has already requested access, just add them to the project # Otherwise, send an invitation create_invitation = True data = self.invite_web_user_form.cleaned_data domain_request = DomainRequest.by_email(self.domain, data["email"]) if domain_request is not None: domain_request.is_approved = True domain_request.save() user = CouchUser.get_by_username(domain_request.email) if user is not None: domain_request.send_approval_email() create_invitation = False user.add_as_web_user(self.domain, role=data["role"], location_id=data.get( "supply_point", None), program_id=data.get("program", None)) messages.success(request, "%s added." % data["email"]) else: track_workflow(request.couch_user.get_email(), "Sent a project invitation", {"Sent a project invitation": "yes"}) send_hubspot_form(HUBSPOT_INVITATION_SENT_FORM, request) messages.success(request, "Invitation sent to %s" % data["email"]) if create_invitation: data["invited_by"] = request.couch_user.user_id data["invited_on"] = datetime.utcnow() data["domain"] = self.domain invite = SQLInvitation(**data) invite.save() invite.send_activation_email() return HttpResponseRedirect( reverse(ListWebUsersView.urlname, args=[self.domain])) return self.get(request, *args, **kwargs)
def post(self, request, *args, **kwargs): if self.invite_web_user_form.is_valid(): # If user exists and has already requested access, just add them to the project # Otherwise, send an invitation create_invitation = True data = self.invite_web_user_form.cleaned_data domain_request = DomainRequest.by_email(self.domain, data["email"]) if domain_request is not None: domain_request.is_approved = True domain_request.save() user = CouchUser.get_by_username(domain_request.email) if user is not None: domain_request.send_approval_email() create_invitation = False user.add_as_web_user(self.domain, role=data["role"], location_id=data.get("supply_point", None), program_id=data.get("program", None)) messages.success(request, "%s added." % data["email"]) else: track_workflow(request.couch_user.get_email(), "Sent a project invitation", {"Sent a project invitation": "yes"}) send_hubspot_form(HUBSPOT_INVITATION_SENT_FORM, request) messages.success(request, "Invitation sent to %s" % data["email"]) if create_invitation: data["invited_by"] = request.couch_user.user_id data["invited_on"] = datetime.utcnow() data["domain"] = self.domain invite = Invitation(**data) invite.save() invite.send_activation_email() return HttpResponseRedirect(reverse( ListWebUsersView.urlname, args=[self.domain] )) return self.get(request, *args, **kwargs)
def _get_form_designer_view(request, domain, app, module, form): if app and app.copy_of: messages.warning(request, _( "You tried to edit a form that was from a previous release, so " "we have directed you to the latest version of your application." )) return back_to_main(request, domain, app_id=app.id) if form.no_vellum: messages.warning(request, _( "You tried to edit this form in the Form Builder. " "However, your administrator has locked this form against editing " "in the form builder, so we have redirected you to " "the form's front page instead." )) return back_to_main(request, domain, app_id=app.id, form_unique_id=form.unique_id) if app.doc_type == 'LinkedApplication': messages.warning(request, _( "You tried to edit this form in the Form Builder. " "However, this is a linked application and you can only make changes to the " "upstream version." )) return back_to_main(request, domain, app_id=app.id) send_hubspot_form(HUBSPOT_FORM_BUILDER_FORM_ID, request) def _form_too_large(_app, _form): # form less than 0.1MB, anything larger starts to have # performance issues with fullstory return _app.blobs['{}.xml'.format(_form.unique_id)]['content_length'] > 102400 context = get_apps_base_context(request, domain, app) context.update(locals()) vellum_options = _get_base_vellum_options(request, domain, app, context['lang']) vellum_options['core'] = _get_vellum_core_context(request, domain, app, module, form, context['lang']) vellum_options['plugins'] = _get_vellum_plugins(domain, form, module) vellum_options['features'] = _get_vellum_features(request, domain, app) context['vellum_options'] = vellum_options context.update({ 'vellum_debug': settings.VELLUM_DEBUG, 'nav_form': form, 'formdesigner': True, 'include_fullstory': not _form_too_large(app, form), 'CKEDITOR_BASEPATH': "app_manager/js/vellum/lib/ckeditor/", 'show_live_preview': should_show_preview_app( request, app, request.couch_user.username, ), 'show_ui_notification_to_hide_translations': (len(app.langs) > 2), }) context.update(_get_requirejs_context()) if request.user.is_superuser: context.update({'notification_options': _get_notification_options(request, domain, app, form)}) notify_form_opened(domain, request.couch_user, app.id, form.unique_id) response = render(request, "app_manager/form_designer.html", context) set_lang_cookie(response, context['lang']) return response
def request_new_domain(request, form, is_new_user=True): now = datetime.utcnow() current_user = CouchUser.from_django_user(request.user) dom_req = RegistrationRequest() if is_new_user: dom_req.request_time = now dom_req.request_ip = get_ip(request) dom_req.activation_guid = uuid.uuid1().hex project_name = form.cleaned_data.get('hr_name') or form.cleaned_data.get( 'project_name') name = name_to_url(project_name, "project") with CriticalSection(['request_domain_name_{}'.format(name)]): name = Domain.generate_name(name) new_domain = Domain(name=name, hr_name=project_name, is_active=False, date_created=datetime.utcnow(), creating_user=current_user.username, secure_submissions=True, use_sql_backend=True, first_domain_for_user=is_new_user) # Avoid projects created by dimagi.com staff members as self started new_domain.internal.self_started = not current_user.is_dimagi if form.cleaned_data.get('domain_timezone'): new_domain.default_timezone = form.cleaned_data['domain_timezone'] if not is_new_user: new_domain.is_active = True # ensure no duplicate domain documents get created on cloudant new_domain.save(**get_safe_write_kwargs()) if not new_domain.name: new_domain.name = new_domain._id new_domain.save() # we need to get the name from the _id if is_new_user: # Only new-user domains are eligible for Advanced trial # domains with no subscription are equivalent to be on free Community plan create_30_day_advanced_trial(new_domain, current_user.username) else: ensure_explicit_community_subscription( new_domain.name, date.today(), SubscriptionAdjustmentMethod.USER, web_user=current_user.username, ) UserRole.init_domain_with_presets(new_domain.name) # add user's email as contact email for billing account for the domain account = BillingAccount.get_account_by_domain(new_domain.name) billing_contact, _ = BillingContactInfo.objects.get_or_create( account=account) billing_contact.email_list = [current_user.email] billing_contact.save() dom_req.domain = new_domain.name if request.user.is_authenticated: if not current_user: current_user = WebUser() current_user.sync_from_django_user(request.user) current_user.save() current_user.add_domain_membership(new_domain.name, is_admin=True) current_user.save() dom_req.requesting_user_username = request.user.username dom_req.new_user_username = request.user.username if is_new_user: dom_req.save() send_domain_registration_email(request.user.email, dom_req.domain, dom_req.activation_guid, request.user.get_full_name(), request.user.first_name) send_new_request_update_email(request.user, get_ip(request), new_domain.name, is_new_user=is_new_user) send_hubspot_form(HUBSPOT_CREATED_NEW_PROJECT_SPACE_FORM_ID, request) return new_domain.name
def request_new_domain(request, form, is_new_user=True): now = datetime.utcnow() current_user = CouchUser.from_django_user(request.user, strict=True) dom_req = RegistrationRequest() if is_new_user: dom_req.request_time = now dom_req.request_ip = get_ip(request) dom_req.activation_guid = uuid.uuid1().hex project_name = form.cleaned_data.get('hr_name') or form.cleaned_data.get('project_name') name = name_to_url(project_name, "project") with CriticalSection(['request_domain_name_{}'.format(name)]): name = Domain.generate_name(name) new_domain = Domain( name=name, hr_name=project_name, is_active=False, date_created=datetime.utcnow(), creating_user=current_user.username, secure_submissions=True, use_sql_backend=True, first_domain_for_user=is_new_user ) # Avoid projects created by dimagi.com staff members as self started new_domain.internal.self_started = not current_user.is_dimagi if form.cleaned_data.get('domain_timezone'): new_domain.default_timezone = form.cleaned_data['domain_timezone'] if not is_new_user: new_domain.is_active = True # ensure no duplicate domain documents get created on cloudant new_domain.save(**get_safe_write_kwargs()) if not new_domain.name: new_domain.name = new_domain._id new_domain.save() # we need to get the name from the _id if is_new_user: # Only new-user domains are eligible for Advanced trial # domains with no subscription are equivalent to be on free Community plan create_30_day_advanced_trial(new_domain, current_user.username) else: ensure_explicit_community_subscription( new_domain.name, date.today(), SubscriptionAdjustmentMethod.USER, web_user=current_user.username, ) UserRole.init_domain_with_presets(new_domain.name) # add user's email as contact email for billing account for the domain account = BillingAccount.get_account_by_domain(new_domain.name) billing_contact, _ = BillingContactInfo.objects.get_or_create(account=account) billing_contact.email_list = [current_user.email] billing_contact.save() dom_req.domain = new_domain.name if request.user.is_authenticated: if not current_user: current_user = WebUser() current_user.sync_from_django_user(request.user) current_user.save() current_user.add_domain_membership(new_domain.name, is_admin=True) current_user.save() dom_req.requesting_user_username = request.user.username dom_req.new_user_username = request.user.username if is_new_user: dom_req.save() if settings.IS_SAAS_ENVIRONMENT: from corehq.apps.app_manager.tasks import load_appcues_template_app chain( load_appcues_template_app.si(new_domain.name, current_user.username, HEALTH_APP), load_appcues_template_app.si(new_domain.name, current_user.username, AGG_APP), load_appcues_template_app.si(new_domain.name, current_user.username, WASH_APP), send_domain_registration_email.si( request.user.email, dom_req.domain, dom_req.activation_guid, request.user.get_full_name(), request.user.first_name ) ).apply_async() else: send_domain_registration_email(request.user.email, dom_req.domain, dom_req.activation_guid, request.user.get_full_name(), request.user.first_name) send_new_request_update_email(request.user, get_ip(request), new_domain.name, is_new_user=is_new_user) send_hubspot_form(HUBSPOT_CREATED_NEW_PROJECT_SPACE_FORM_ID, request) return new_domain.name
def __call__(self, request, uuid, **kwargs): # add the correct parameters to this instance self.request = request if 'domain' in kwargs: self.domain = kwargs['domain'] if request.GET.get('switch') == 'true': logout(request) return redirect_to_login(request.path) if request.GET.get('create') == 'true': logout(request) return HttpResponseRedirect(request.path) # Recently-sent invitations will use a URL based on UUID try: invitation = SQLInvitation.objects.get(uuid=uuid) except (SQLInvitation.DoesNotExist, ValidationError): invitation = None # Older invitations, created before PR#26975, will use a URL based on SQL id if not invitation: try: invitation = SQLInvitation.objects.get(id=int(uuid)) except (SQLInvitation.DoesNotExist, ValueError): invitation = None # The oldest invitations, created before PR#26686, will use a URL based on couch id. if not invitation: invitation = SQLInvitation.objects.filter(couch_id=uuid).first() if not invitation: messages.error( request, _("Sorry, it looks like your invitation has expired. " "Please check the invitation link you received and try again, or " "request a project administrator to send you the invitation again." )) return HttpResponseRedirect(reverse("login")) if invitation.is_accepted: messages.error( request, _("Sorry, that invitation has already been used up. " "If you feel this is a mistake please ask the inviter for " "another invitation.")) return HttpResponseRedirect(reverse("login")) self.validate_invitation(invitation) if invitation.is_expired: return HttpResponseRedirect(reverse("no_permissions")) # Add zero-width space to username for better line breaking username = self.request.user.username.replace("@", "​@") context = { 'formatted_username': username, 'domain': self.domain, 'invite_to': self.domain, 'invite_type': _('Project'), 'hide_password_feedback': settings.ENABLE_DRACONIAN_SECURITY_FEATURES, } if request.user.is_authenticated: context['current_page'] = {'page_name': _('Project Invitation')} else: context['current_page'] = { 'page_name': _('Project Invitation, Account Required') } if request.user.is_authenticated: is_invited_user = request.couch_user.username.lower( ) == invitation.email.lower() if self.is_invited(invitation, request.couch_user ) and not request.couch_user.is_superuser: if is_invited_user: # if this invite was actually for this user, just mark it accepted messages.info( request, _("You are already a member of {entity}.").format( entity=self.inviting_entity)) invitation.is_accepted = True invitation.save() else: messages.error( request, _("It looks like you are trying to accept an invitation for " "{invited} but you are already a member of {entity} with the " "account {current}. Please sign out to accept this invitation " "as another user.").format( entity=self.inviting_entity, invited=invitation.email, current=request.couch_user.username, )) return HttpResponseRedirect(self.redirect_to_on_success) if not is_invited_user: messages.error( request, _("The invited user {invited} and your user {current} do not match!" ).format(invited=invitation.email, current=request.couch_user.username)) if request.method == "POST": couch_user = CouchUser.from_django_user(request.user, strict=True) self._invite(invitation, couch_user) track_workflow( request.couch_user.get_email(), "Current user accepted a project invitation", {"Current user accepted a project invitation": "yes"}) send_hubspot_form(HUBSPOT_EXISTING_USER_INVITE_FORM, request) return HttpResponseRedirect(self.redirect_to_on_success) else: mobile_user = CouchUser.from_django_user( request.user).is_commcare_user() context.update({ 'mobile_user': mobile_user, "invited_user": invitation.email if request.couch_user.username != invitation.email else "", }) return render(request, self.template, context) else: if request.method == "POST": form = WebUserInvitationForm(request.POST) if form.is_valid(): # create the new user user = activate_new_user(form, domain=invitation.domain) user.save() messages.success( request, _("User account for %s created!") % form.cleaned_data["email"]) self._invite(invitation, user) authenticated = authenticate( username=form.cleaned_data["email"], password=form.cleaned_data["password"]) if authenticated is not None and authenticated.is_active: login(request, authenticated) track_workflow( request.POST['email'], "New User Accepted a project invitation", {"New User Accepted a project invitation": "yes"}) send_hubspot_form(HUBSPOT_NEW_USER_INVITE_FORM, request, user) return HttpResponseRedirect( reverse("domain_homepage", args=[invitation.domain])) else: if CouchUser.get_by_username(invitation.email): return HttpResponseRedirect( reverse("login") + '?next=' + reverse('domain_accept_invitation', args=[invitation.domain, invitation.uuid])) form = WebUserInvitationForm(initial={ 'email': invitation.email, }) context.update({"form": form}) return render(request, self.template, context)
def __call__(self, request, uuid, **kwargs): # add the correct parameters to this instance self.request = request if 'domain' in kwargs: self.domain = kwargs['domain'] if request.GET.get('switch') == 'true': logout(request) return redirect_to_login(request.path) if request.GET.get('create') == 'true': logout(request) return HttpResponseRedirect(request.path) try: invitation = Invitation.objects.get(uuid=uuid) except (Invitation.DoesNotExist, ValidationError): messages.error( request, _("Sorry, it looks like your invitation has expired. " "Please check the invitation link you received and try again, or " "request a project administrator to send you the invitation again." )) return HttpResponseRedirect(reverse("login")) if invitation.is_accepted: messages.error( request, _("Sorry, that invitation has already been used up. " "If you feel this is a mistake please ask the inviter for " "another invitation.")) return HttpResponseRedirect(reverse("login")) self.validate_invitation(invitation) if invitation.is_expired: return HttpResponseRedirect(reverse("no_permissions")) # Add zero-width space to username for better line breaking username = self.request.user.username.replace("@", "​@") context = { 'formatted_username': username, 'domain': self.domain, 'invite_to': self.domain, 'invite_type': _('Project'), 'hide_password_feedback': has_custom_clean_password(), } if request.user.is_authenticated: context['current_page'] = {'page_name': _('Project Invitation')} else: context['current_page'] = { 'page_name': _('Project Invitation, Account Required') } if request.user.is_authenticated: is_invited_user = request.couch_user.username.lower( ) == invitation.email.lower() if self.is_invited(invitation, request.couch_user ) and not request.couch_user.is_superuser: if is_invited_user: # if this invite was actually for this user, just mark it accepted messages.info( request, _("You are already a member of {entity}.").format( entity=self.inviting_entity)) invitation.is_accepted = True invitation.save() else: messages.error( request, _("It looks like you are trying to accept an invitation for " "{invited} but you are already a member of {entity} with the " "account {current}. Please sign out to accept this invitation " "as another user.").format( entity=self.inviting_entity, invited=invitation.email, current=request.couch_user.username)) return HttpResponseRedirect( self.redirect_to_on_success(invitation.email, self.domain)) if not is_invited_user: messages.error( request, _("The invited user {invited} and your user {current} " "do not match!").format( invited=invitation.email, current=request.couch_user.username)) if request.method == "POST": couch_user = CouchUser.from_django_user(request.user, strict=True) invitation.accept_invitation_and_join_domain(couch_user) log_user_change( by_domain=invitation.domain, for_domain=invitation.domain, couch_user=couch_user, changed_by_user=CouchUser.get_by_user_id( invitation.invited_by), changed_via=USER_CHANGE_VIA_INVITATION, change_messages=UserChangeMessage.domain_addition( invitation.domain)) track_workflow( request.couch_user.get_email(), "Current user accepted a project invitation", {"Current user accepted a project invitation": "yes"}) send_hubspot_form(HUBSPOT_EXISTING_USER_INVITE_FORM, request) return HttpResponseRedirect( self.redirect_to_on_success(invitation.email, self.domain)) else: mobile_user = CouchUser.from_django_user( request.user).is_commcare_user() context.update({ 'mobile_user': mobile_user, "invited_user": invitation.email if request.couch_user.username != invitation.email else "", }) return render(request, self.template, context) else: idp = None if settings.ENFORCE_SSO_LOGIN: idp = IdentityProvider.get_active_identity_provider_by_username( invitation.email) if request.method == "POST": form = WebUserInvitationForm(request.POST, is_sso=idp is not None) if form.is_valid(): # create the new user invited_by_user = CouchUser.get_by_user_id( invitation.invited_by) if idp: signup_request = AsyncSignupRequest.create_from_invitation( invitation) return HttpResponseRedirect( idp.get_login_url(signup_request.username)) user = activate_new_user_via_reg_form( form, created_by=invited_by_user, created_via=USER_CHANGE_VIA_INVITATION, domain=invitation.domain, is_domain_admin=False, ) user.save() messages.success( request, _("User account for %s created!") % form.cleaned_data["email"]) invitation.accept_invitation_and_join_domain(user) messages.success( self.request, _('You have been added to the "{}" project space.'). format(self.domain)) authenticated = authenticate( username=form.cleaned_data["email"], password=form.cleaned_data["password"], request=request) if authenticated is not None and authenticated.is_active: login(request, authenticated) track_workflow( request.POST['email'], "New User Accepted a project invitation", {"New User Accepted a project invitation": "yes"}) send_hubspot_form(HUBSPOT_NEW_USER_INVITE_FORM, request, user) return HttpResponseRedirect( self.redirect_to_on_success(invitation.email, invitation.domain)) else: if (CouchUser.get_by_username(invitation.email) or User.objects.filter( username__iexact=invitation.email).count() > 0): login_url = reverse("login") accept_invitation_url = reverse( 'domain_accept_invitation', args=[invitation.domain, invitation.uuid]) return HttpResponseRedirect( f"{login_url}" f"?next={accept_invitation_url}" f"&username={invitation.email}") form = WebUserInvitationForm( initial={ 'email': invitation.email, }, is_sso=idp is not None, ) context.update({ 'is_sso': idp is not None, 'idp_name': idp.name if idp else None, 'invited_user': invitation.email, }) context.update({"form": form}) return render(request, self.template, context)
def request_new_domain(request, form, is_new_user=True): now = datetime.utcnow() current_user = CouchUser.from_django_user(request.user, strict=True) dom_req = RegistrationRequest() if is_new_user: dom_req.request_time = now dom_req.request_ip = get_ip(request) dom_req.activation_guid = uuid.uuid1().hex project_name = form.cleaned_data.get('hr_name') or form.cleaned_data.get( 'project_name') name = name_to_url(project_name, "project") with CriticalSection(['request_domain_name_{}'.format(name)]): name = Domain.generate_name(name) new_domain = Domain(name=name, hr_name=project_name, is_active=False, date_created=datetime.utcnow(), creating_user=current_user.username, secure_submissions=True, use_sql_backend=True, first_domain_for_user=is_new_user) # Avoid projects created by dimagi.com staff members as self started new_domain.internal.self_started = not current_user.is_dimagi if form.cleaned_data.get('domain_timezone'): new_domain.default_timezone = form.cleaned_data['domain_timezone'] if not is_new_user: new_domain.is_active = True # ensure no duplicate domain documents get created on cloudant new_domain.save(**get_safe_write_kwargs()) if not new_domain.name: new_domain.name = new_domain._id new_domain.save() # we need to get the name from the _id with transaction.atomic(): ensure_community_or_paused_subscription( new_domain.name, date.today(), SubscriptionAdjustmentMethod.USER, web_user=current_user.username, ) UserRole.init_domain_with_presets(new_domain.name) # add user's email as contact email for billing account for the domain account = BillingAccount.get_account_by_domain(new_domain.name) billing_contact, _ = BillingContactInfo.objects.get_or_create( account=account) billing_contact.email_list = [current_user.email] billing_contact.save() dom_req.domain = new_domain.name if request.user.is_authenticated: if not current_user: current_user = WebUser() current_user.sync_from_django_user(request.user) current_user.save() current_user.add_domain_membership(new_domain.name, is_admin=True) current_user.save() dom_req.requesting_user_username = request.user.username dom_req.new_user_username = request.user.username if is_new_user: dom_req.save() if settings.IS_SAAS_ENVIRONMENT: # Load template apps to the user's new domain in parallel from corehq.apps.app_manager.tasks import load_appcues_template_app header = [ load_appcues_template_app.si(new_domain.name, current_user.username, slug) for slug in APPCUES_APP_SLUGS ] callback = send_domain_registration_email.si( request.user.email, dom_req.domain, dom_req.activation_guid, request.user.get_full_name(), request.user.first_name) chord(header)(callback) else: send_domain_registration_email(request.user.email, dom_req.domain, dom_req.activation_guid, request.user.get_full_name(), request.user.first_name) send_new_request_update_email(request.user, get_ip(request), new_domain.name, is_new_user=is_new_user) send_hubspot_form(HUBSPOT_CREATED_NEW_PROJECT_SPACE_FORM_ID, request) return new_domain.name
def request_new_domain(request, form, is_new_user=True): now = datetime.utcnow() current_user = CouchUser.from_django_user(request.user, strict=True) dom_req = RegistrationRequest() if is_new_user: dom_req.request_time = now dom_req.request_ip = get_ip(request) dom_req.activation_guid = uuid.uuid1().hex project_name = form.cleaned_data.get('hr_name') or form.cleaned_data.get( 'project_name') name = name_to_url(project_name, "project") with CriticalSection(['request_domain_name_{}'.format(name)]): name = Domain.generate_name(name) new_domain = Domain(name=name, hr_name=project_name, is_active=False, date_created=datetime.utcnow(), creating_user=current_user.username, secure_submissions=True, use_sql_backend=True, first_domain_for_user=is_new_user) # Avoid projects created by dimagi.com staff members as self started new_domain.internal.self_started = not current_user.is_dimagi if form.cleaned_data.get('domain_timezone'): new_domain.default_timezone = form.cleaned_data['domain_timezone'] if not is_new_user: new_domain.is_active = True # ensure no duplicate domain documents get created on cloudant new_domain.save(**get_safe_write_kwargs()) if not new_domain.name: new_domain.name = new_domain._id new_domain.save() # we need to get the name from the _id dom_req.domain = new_domain.name if not settings.ENTERPRISE_MODE: _setup_subscription(new_domain.name, current_user) UserRole.init_domain_with_presets(new_domain.name) if request.user.is_authenticated: if not current_user: current_user = WebUser() current_user.sync_from_django_user(request.user) current_user.save() current_user.add_domain_membership(new_domain.name, is_admin=True) current_user.save() dom_req.requesting_user_username = request.user.username dom_req.new_user_username = request.user.username elif is_new_user: _soft_assert_registration_issues( f"A new user {request.user.username} was not added to their domain " f"{new_domain.name} during registration") if is_new_user: dom_req.save() if settings.IS_SAAS_ENVIRONMENT: # Load template apps to the user's new domain in parallel from corehq.apps.app_manager.tasks import load_appcues_template_app header = [ load_appcues_template_app.si(new_domain.name, current_user.username, slug) for slug in APPCUES_APP_SLUGS ] callback = send_domain_registration_email.si( request.user.email, dom_req.domain, dom_req.activation_guid, request.user.get_full_name(), request.user.first_name) chord(header)(callback) else: send_domain_registration_email(request.user.email, dom_req.domain, dom_req.activation_guid, request.user.get_full_name(), request.user.first_name) send_new_request_update_email(request.user, get_ip(request), new_domain.name, is_new_user=is_new_user) send_hubspot_form(HUBSPOT_CREATED_NEW_PROJECT_SPACE_FORM_ID, request) return new_domain.name
def __call__(self, request, invitation_id, **kwargs): logging.info("Don't use this view in more apps until it gets cleaned up.") # add the correct parameters to this instance self.request = request self.inv_id = invitation_id if 'domain' in kwargs: self.domain = kwargs['domain'] if request.GET.get('switch') == 'true': logout(request) return redirect_to_login(request.path) if request.GET.get('create') == 'true': logout(request) return HttpResponseRedirect(request.path) try: invitation = Invitation.get(invitation_id) except ResourceNotFound: messages.error(request, _("Sorry, it looks like your invitation has expired. " "Please check the invitation link you received and try again, or request a " "project administrator to send you the invitation again.")) return HttpResponseRedirect(reverse("login")) if invitation.is_accepted: messages.error(request, _("Sorry, that invitation has already been used up. " "If you feel this is a mistake please ask the inviter for " "another invitation.")) return HttpResponseRedirect(reverse("login")) self.validate_invitation(invitation) if invitation.is_expired: return HttpResponseRedirect(reverse("no_permissions")) # Add zero-width space to username for better line breaking username = self.request.user.username.replace("@", "​@") context = { 'create_domain': False, 'formatted_username': username, 'domain': self.domain, 'invite_to': self.domain, 'invite_type': _('Project'), 'hide_password_feedback': settings.ENABLE_DRACONIAN_SECURITY_FEATURES, } if request.user.is_authenticated: context['current_page'] = {'page_name': _('Project Invitation')} else: context['current_page'] = {'page_name': _('Project Invitation, Account Required')} if request.user.is_authenticated: is_invited_user = request.couch_user.username.lower() == invitation.email.lower() if self.is_invited(invitation, request.couch_user) and not request.couch_user.is_superuser: if is_invited_user: # if this invite was actually for this user, just mark it accepted messages.info(request, _("You are already a member of {entity}.").format( entity=self.inviting_entity)) invitation.is_accepted = True invitation.save() else: messages.error(request, _("It looks like you are trying to accept an invitation for " "{invited} but you are already a member of {entity} with the " "account {current}. Please sign out to accept this invitation " "as another user.").format( entity=self.inviting_entity, invited=invitation.email, current=request.couch_user.username, )) return HttpResponseRedirect(self.redirect_to_on_success) if not is_invited_user: messages.error(request, _("The invited user {invited} and your user {current} do not match!").format( invited=invitation.email, current=request.couch_user.username)) if request.method == "POST": couch_user = CouchUser.from_django_user(request.user) self._invite(invitation, couch_user) track_workflow(request.couch_user.get_email(), "Current user accepted a project invitation", {"Current user accepted a project invitation": "yes"}) send_hubspot_form(HUBSPOT_EXISTING_USER_INVITE_FORM, request) return HttpResponseRedirect(self.redirect_to_on_success) else: mobile_user = CouchUser.from_django_user(request.user).is_commcare_user() context.update({ 'mobile_user': mobile_user, "invited_user": invitation.email if request.couch_user.username != invitation.email else "", }) return render(request, self.template, context) else: if request.method == "POST": form = WebUserInvitationForm(request.POST) if form.is_valid(): # create the new user user = activate_new_user(form, domain=invitation.domain) user.save() messages.success(request, _("User account for %s created!") % form.cleaned_data["email"]) self._invite(invitation, user) authenticated = authenticate(username=form.cleaned_data["email"], password=form.cleaned_data["password"]) if authenticated is not None and authenticated.is_active: login(request, authenticated) track_workflow(request.POST['email'], "New User Accepted a project invitation", {"New User Accepted a project invitation": "yes"}) send_hubspot_form(HUBSPOT_NEW_USER_INVITE_FORM, request, user) return HttpResponseRedirect(reverse("domain_homepage", args=[invitation.domain])) else: if CouchUser.get_by_username(invitation.email): return HttpResponseRedirect(reverse("login") + '?next=' + reverse('domain_accept_invitation', args=[invitation.domain, invitation.get_id])) form = WebUserInvitationForm(initial={ 'email': invitation.email, 'hr_name': invitation.domain, 'create_domain': False, }) context.update({"form": form}) return render(request, self.template, context)