def page_context(self): prefills = { 'email': self.prefilled_email, 'atypical_user': True if self.atypical_user else False } context = { 'reg_form': RegisterWebUserForm(initial=prefills), 'reg_form_defaults': prefills, 'hide_password_feedback': has_custom_clean_password(), 'professional_features': [ _("Custom mobile app builder"), _("Powerful case management"), _("Field staff reports"), _("Unlimited mobile users"), _("Full suite of data tools"), _("3rd party integrations"), _("2-way SMS workflows"), _("Guaranteed tech support"), _("Access to Dimagi's Customer Success team"), ], 'community_features': [ _("Custom mobile app builder"), _("Basic case management"), _("Field staff reports"), _("5 mobile users"), ], } if settings.IS_SAAS_ENVIRONMENT: context['demo_workflow_ab_v2'] = ab_tests.SessionAbTest( ab_tests.DEMO_WORKFLOW_V2, self.request).context return context
def post(self, request, *args, **kwargs): self.extra_context['hide_password_feedback'] = has_custom_clean_password() response = super().post(request, *args, **kwargs) uidb64 = kwargs.get('uidb64') uid = urlsafe_base64_decode(uidb64) user = User.objects.get(pk=uid) couch_user = CouchUser.from_django_user(user) clear_login_attempts(couch_user) return response
def page_context(self): is_using_sso = is_request_using_sso(self.request) idp_name = None if is_using_sso: idp = IdentityProvider.get_active_identity_provider_by_username( self.request.user.username) idp_name = idp.name return { 'form': self.password_change_form, 'hide_password_feedback': has_custom_clean_password(), 'is_using_sso': is_using_sso, 'idp_name': idp_name, }
def post(self, request, *args, **kwargs): self.extra_context['hide_password_feedback'] = has_custom_clean_password() if request.POST['new_password1'] == request.POST['new_password2']: try: clean_password(request.POST['new_password1']) except ValidationError as e: messages.error(request, _(e.message)) return HttpResponseRedirect(request.path_info) response = super().post(request, *args, **kwargs) uidb64 = kwargs.get('uidb64') uid = urlsafe_base64_decode(uidb64) user = User.objects.get(pk=uid) couch_user = CouchUser.from_django_user(user) clear_login_attempts(couch_user) return response
def get(self, request, *args, **kwargs): self.extra_context[ 'hide_password_feedback'] = has_custom_clean_password() return super().get(request, *args, **kwargs)
def page_context(self): return { 'form': self.password_change_form, 'hide_password_feedback': has_custom_clean_password(), }
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 __init__(self, project, request_user, *args, **kwargs): super(NewMobileWorkerForm, self).__init__(*args, **kwargs) email_string = "@{}.{}".format(project.name, settings.HQ_ACCOUNT_ROOT) max_chars_username = 80 - len(email_string) self.project = project self.domain = self.project.name self.request_user = request_user self.can_access_all_locations = request_user.has_permission(self.domain, 'access_all_locations') if not self.can_access_all_locations: self.fields['location_id'].required = True if self.project.strong_mobile_passwords: # Use normal text input so auto-generated strong password is visible self.fields['new_password'].widget = forms.TextInput() self.fields['new_password'].help_text = mark_safe_lazy( format_lazy( '<i class="fa fa-warning"></i>{}<br />', ugettext_lazy( 'This password is automatically generated. ' 'Please copy it or create your own. It will not be shown again.'), ) ) if project.uses_locations: self.fields['location_id'].widget = forms.Select() location_field = crispy.Field( 'location_id', data_bind='value: location_id', data_query_url=reverse('location_search', args=[self.domain]), ) else: location_field = crispy.Hidden( 'location_id', '', data_bind='value: location_id', ) self.two_stage_provisioning_enabled = TWO_STAGE_USER_PROVISIONING.enabled(self.domain) if self.two_stage_provisioning_enabled: confirm_account_field = crispy.Field( 'force_account_confirmation', data_bind='checked: force_account_confirmation', ) email_field = crispy.Div( crispy.Field( 'email', data_bind="value: email, valueUpdate: 'keyup'", ), data_bind=''' css: { 'has-error': $root.emailStatus() === $root.STATUS.ERROR, }, ''' ) send_email_field = crispy.Field( 'send_account_confirmation_email', data_bind='checked: send_account_confirmation_email, enable: sendConfirmationEmailEnabled', ) else: confirm_account_field = crispy.Hidden( 'force_account_confirmation', '', data_bind='value: force_account_confirmation', ) email_field = crispy.Hidden( 'email', '', data_bind='value: email', ) send_email_field = crispy.Hidden( 'send_account_confirmation_email', '', data_bind='value: send_account_confirmation_email', ) self.helper = HQModalFormHelper() self.helper.form_tag = False self.helper.layout = Layout( Fieldset( _('Basic Information'), crispy.Div( crispy.Field( 'username', data_bind="value: username, valueUpdate: 'keyup'", maxlength=max_chars_username, ), data_bind=''' css: { 'has-pending': $root.usernameAvailabilityStatus() === $root.STATUS.PENDING, 'has-success': $root.usernameAvailabilityStatus() === $root.STATUS.SUCCESS, 'has-warning': $root.usernameAvailabilityStatus() === $root.STATUS.WARNING, 'has-error': $root.usernameAvailabilityStatus() === $root.STATUS.ERROR, }, ''' ), crispy.Field( 'first_name', data_bind='value: first_name', ), crispy.Field( 'last_name', data_bind='value: last_name', ), location_field, confirm_account_field, email_field, send_email_field, crispy.Div( hqcrispy.B3MultiField( _("Password"), InlineField( 'new_password', data_bind="value: password, valueUpdate: 'input', enable: passwordEnabled", ), crispy.HTML(''' <p class="help-block" data-bind="if: $root.isSuggestedPassword"> <i class="fa fa-warning"></i> {suggested} </p> <p class="help-block" data-bind="ifnot: $root.isSuggestedPassword()"> <!-- ko ifnot: $root.skipStandardValidations() --> <!-- ko if: $root.passwordStatus() === $root.STATUS.SUCCESS --> <i class="fa fa-check"></i> {strong} <!-- /ko --> <!-- ko if: $root.passwordStatus() === $root.STATUS.WARNING --> {almost} <!-- /ko --> <!-- ko if: $root.passwordStatus() === $root.STATUS.ERROR --> <i class="fa fa-warning"></i> {weak} <!-- /ko --> <!-- /ko --> <!-- ko if: $root.skipStandardValidations() --> <i class="fa fa-info-circle"></i> {custom_warning} <!-- /ko --> <!-- ko if: $root.passwordStatus() === $root.STATUS.DISABLED --> <i class="fa fa-warning"></i> {disabled} <!-- /ko --> </p> '''.format( suggested=_("This password is automatically generated. Please copy it or create " "your own. It will not be shown again."), strong=_("Good Job! Your password is strong!"), almost=_("Your password is almost strong enough! Try adding numbers or symbols!"), weak=_("Your password is too weak! Try adding numbers or symbols!"), custom_warning=_(settings.CUSTOM_PASSWORD_STRENGTH_MESSAGE), disabled=_("Setting a password is disabled. " "The user will set their own password on confirming their account email."), )), required=True, ), data_bind=''' css: { 'has-success': $root.passwordStatus() === $root.STATUS.SUCCESS, 'has-warning': $root.passwordStatus() === $root.STATUS.WARNING, 'has-error': $root.passwordStatus() === $root.STATUS.ERROR, } ''' if not has_custom_clean_password() else '' ), ) )