Пример #1
0
 def test_new_user_created_and_invitation_accepted(self):
     """
     When SsoBackend creates a new user and an invitation is present, that
     invitation should add the user to the invited project
     space and accept the invitation
     """
     admin_role = UserRole.admin_role(self.domain.name)
     invitation = Invitation(
         domain=self.domain.name,
         email='*****@*****.**',
         invited_by=self.user.couch_id,
         invited_on=datetime.datetime.utcnow(),
         role=admin_role.get_qualified_id(),
     )
     invitation.save()
     prepare_session_for_sso_invitation(self.request, invitation)
     generator.store_full_name_in_saml_user_data(self.request, 'Isa',
                                                 'Baas')
     user = auth.authenticate(
         request=self.request,
         username=invitation.email,
         idp_slug=self.idp.slug,
         is_handshake_successful=True,
     )
     self.assertIsNotNone(user)
     self.assertEqual(user.username, invitation.email)
     self.assertEqual(user.first_name, 'Isa')
     self.assertEqual(user.last_name, 'Baas')
     self.assertEqual(self.request.sso_new_user_messages['success'], [
         f'User account for {invitation.email} created.',
         f'You have been added to the "{invitation.domain}" project space.',
     ])
Пример #2
0
def invite_web_user(request, domain, template="users/invite_web_user.html"):
    role_choices = UserRole.role_choices(domain)
    if request.method == "POST":
        form = AdminInvitesUserForm(request.POST,
            excluded_emails=[user.username for user in WebUser.by_domain(domain)],
            role_choices=role_choices
        )
        if form.is_valid():
            data = form.cleaned_data
            # create invitation record
            data["invited_by"] = request.couch_user.user_id
            data["invited_on"] = datetime.utcnow()
            data["domain"] = domain
            invite = Invitation(**data)
            invite.save()
            invite.send_activation_email()
            messages.success(request, "Invitation sent to %s" % invite.email)
            return HttpResponseRedirect(reverse("web_users", args=[domain]))
    else:
        form = AdminInvitesUserForm(role_choices=role_choices)
    context = _users_context(request, domain)
    context.update(
        registration_form=form
    )
    return render_to_response(request, template, context)
Пример #3
0
 def setUpClass(cls):
     cls.invitations = []
     for kwargs in [
         {'domain': 'domain_1', 'email': '*****@*****.**'},
         {'domain': 'domain_1', 'email': '*****@*****.**', 'is_accepted': True},
         {'domain': 'domain_2', 'email': '*****@*****.**'},
     ]:
         inv = Invitation(**kwargs)
         inv.save()
         cls.invitations.append(inv)
Пример #4
0
 def setUpClass(cls):
     super(InvitationTest, cls).setUpClass()
     cls.invitations = []
     for kwargs in [
         {'domain': 'domain_1', 'email': '*****@*****.**'},
         {'domain': 'domain_1', 'email': '*****@*****.**', 'is_accepted': True},
         {'domain': 'domain_2', 'email': '*****@*****.**'},
     ]:
         inv = Invitation(**kwargs)
         inv.save()
         cls.invitations.append(inv)
Пример #5
0
    def rows_for_domain(self, domain_obj):

        rows = []
        for user in get_all_user_rows(domain_obj.name,
                                      include_web_users=True,
                                      include_mobile_users=False,
                                      include_inactive=False,
                                      include_docs=True):
            user = CouchUser.wrap_correctly(user['doc'])
            domain_membership = user.get_domain_membership(domain_obj.name)
            last_accessed_domain = None
            if domain_membership:
                last_accessed_domain = domain_membership.last_accessed
            rows.append([
                user.username, user.full_name,
                user.role_label(domain_obj.name),
                self.format_date(user.last_login), last_accessed_domain,
                _('Active User')
            ] + self.domain_properties(domain_obj))
        for invite in Invitation.by_domain(domain_obj.name):
            rows.append([
                invite.email, 'N/A',
                invite.get_role_name(), 'N/A', 'N/A',
                _('Invited')
            ] + self.domain_properties(domain_obj))
        return rows
Пример #6
0
 def invite_web_user_form(self):
     role_choices = _get_editable_role_choices(self.domain,
                                               self.request.couch_user,
                                               allow_admin_role=True)
     loc = None
     domain_request = DomainRequest.objects.get(
         id=self.request_id) if self.request_id else None
     initial = {
         'email': domain_request.email if domain_request else None,
     }
     if 'location_id' in self.request.GET:
         from corehq.apps.locations.models import SQLLocation
         loc = SQLLocation.objects.get(
             location_id=self.request.GET.get('location_id'))
     if self.request.method == 'POST':
         current_users = [
             user.username for user in WebUser.by_domain(self.domain)
         ]
         pending_invites = [
             di.email for di in Invitation.by_domain(self.domain)
         ]
         return AdminInvitesUserForm(self.request.POST,
                                     excluded_emails=current_users +
                                     pending_invites,
                                     role_choices=role_choices,
                                     domain=self.domain)
     return AdminInvitesUserForm(initial=initial,
                                 role_choices=role_choices,
                                 domain=self.domain,
                                 location=loc)
Пример #7
0
def parse_web_users(domain, task=None, total_count=None):
    user_dicts = []
    max_location_length = 0
    location_cache = LocationIdToSiteCodeCache(domain)
    for n, user in enumerate(get_all_user_rows(domain, include_web_users=True, include_mobile_users=False,
                                               include_inactive=False, include_docs=True)):
        user_dict = make_web_user_dict(user, location_cache, domain)
        user_dicts.append(user_dict)
        max_location_length = max(max_location_length, len(user_dict["location_code"]))
        if task:
            DownloadBase.set_progress(task, n, total_count)
    for m, invite in enumerate(Invitation.by_domain(domain)):
        user_dict = make_invited_web_user_dict(invite, location_cache)
        user_dicts.append(user_dict)
        if task:
            DownloadBase.set_progress(task, n + m, total_count)

    user_headers = [
        'username', 'first_name', 'last_name', 'email', 'role', 'last_access_date (read only)',
        'last_login (read only)', 'status', 'remove'
    ]
    if domain_has_privilege(domain, privileges.LOCATIONS):
        user_headers.extend(json_to_headers(
            {'location_code': list(range(1, max_location_length + 1))}
        ))
    return user_headers, get_user_rows(user_dicts, user_headers)
Пример #8
0
 def redirect_to_on_success(self, email, domain):
     if Invitation.by_email(email).count() > 0 and not self.request.GET.get(
             'no_redirect'):
         return reverse("domain_select_redirect")
     else:
         return reverse("domain_homepage", args=[
             domain,
         ])
Пример #9
0
def reinvite_web_user(request, domain):
    invitation_id = request.POST["invite"]
    try:
        invitation = Invitation.get(invitation_id)
        invitation.invited_on = datetime.utcnow()
        invitation.save()
        invitation.send_activation_email()
        return json_response({"response": _("Invitation resent"), "status": "ok"})
    except ResourceNotFound:
        return json_response({"response": _("Error while attempting resend"), "status": "error"})
Пример #10
0
def reinvite_web_user(request, domain):
    invitation_id = request.POST['invite']
    try:
        invitation = Invitation.get(invitation_id)
        invitation.invited_on = datetime.utcnow()
        invitation.save()
        invitation.send_activation_email()
        return json_response({'response': _("Invitation resent"), 'status': 'ok'})
    except ResourceNotFound:
        return json_response({'response': _("Error while attempting resend"), 'status': 'error'})
Пример #11
0
 def setUpClass(cls):
     super(InvitationTest, cls).setUpClass()
     cls.invitations = [
         Invitation(domain='domain_1',
                    email='*****@*****.**',
                    invited_by='*****@*****.**',
                    invited_on=datetime.utcnow()),
         Invitation(domain='domain_1',
                    email='*****@*****.**',
                    invited_by='*****@*****.**',
                    invited_on=datetime.utcnow(),
                    is_accepted=True),
         Invitation(domain='domain_2',
                    email='*****@*****.**',
                    invited_by='*****@*****.**',
                    invited_on=datetime.utcnow()),
     ]
     for inv in cls.invitations:
         inv.save()
Пример #12
0
def reinvite_web_user(request, domain):
    invitation_id = request.POST['invite']
    try:
        invitation = Invitation.get(invitation_id)
        invitation.invited_on = datetime.utcnow()
        invitation.save()
        invitation.send_activation_email()
        return json_response({'response': _("Invitation resent"), 'status': 'ok'})
    except ResourceNotFound:
        return json_response({'response': _("Error while attempting resend"), 'status': 'error'})
Пример #13
0
def resend_pending_invitations():
    from corehq.apps.users.models import Invitation
    days_to_resend = (15, 29)
    days_to_expire = 30
    domains = Domain.get_all()
    for domain in domains:
        invitations = Invitation.by_domain(domain.name)
        for invitation in invitations:
            days = (datetime.utcnow() - invitation.invited_on).days
            if days in days_to_resend:
                invitation.send_activation_email(days_to_expire - days)
Пример #14
0
 def invitations(self):
     return [
         {
             "uuid": str(invitation.uuid),
             "email": invitation.email,
             "email_marked_as_bounced": bool(invitation.email_marked_as_bounced),
             "invited_on": invitation.invited_on,
             "role_label": self.role_labels.get(invitation.role, ""),
         }
         for invitation in Invitation.by_domain(self.domain)
     ]
Пример #15
0
def accept_all_invitations(request):
    user = request.couch_user
    invites = Invitation.by_email(user.username)
    for invitation in invites:
        if not invitation.is_expired:
            invitation.accept_invitation_and_join_domain(user)
            messages.success(
                request,
                _(f'You have been added to the "{invitation.domain}" project space.'
                  ))
    return HttpResponseRedirect(reverse('domain_select_redirect'))
Пример #16
0
def resend_pending_invitations():
    from corehq.apps.users.models import Invitation
    days_to_resend = (15, 29)
    days_to_expire = 30
    domains = Domain.get_all()
    for domain in domains:
        invitations = Invitation.by_domain(domain.name)
        for invitation in invitations:
            days = (datetime.utcnow() - invitation.invited_on).days
            if days in days_to_resend:
                invitation.send_activation_email(days_to_expire - days)
Пример #17
0
    def test_update_pending_user_role(self, mock_send_activation_email):
        import_users_and_groups(
            self.domain.name,
            [
                self._get_spec(
                    web_user='******',
                    is_account_confirmed='False',
                    send_confirmation_email='True',
                    role=self.role.name
                )
            ],
            [],
            self.uploading_user,
            mock.MagicMock()
        )
        self.assertEqual(mock_send_activation_email.call_count, 1)
        self.assertEqual(self.user.get_role(self.domain_name).name, self.role.name)
        self.assertEqual(Invitation.by_email('*****@*****.**')[0].role.split(":")[1], self.role._id)

        added_user_id = self.user._id
        import_users_and_groups(
            self.domain.name,
            [
                self._get_spec(
                    web_user='******',
                    user_id=added_user_id,
                    is_account_confirmed='False',
                    send_confirmation_email='True',
                    role=self.other_role.name
                )
            ],
            [],
            self.uploading_user,
            mock.MagicMock()
        )
        self.assertEqual(mock_send_activation_email.call_count, 1)  # invite only sent once
        self.assertEqual(len(Invitation.by_email('*****@*****.**')), 1)  # only one invite associated with user
        self.assertEqual(self.user.get_role(self.domain.name).name, self.other_role.name)
        self.assertEqual(Invitation.by_email('*****@*****.**')[0].role, self.other_role.get_qualified_id())
Пример #18
0
def select(request, do_not_redirect=False, next_view=None):
    if not hasattr(request, 'couch_user'):
        return redirect('registration_domain')

    # next_view must be a url that expects exactly one parameter, a domain name
    next_view = next_view or request.GET.get('next_view')
    show_invitations = False
    if not next_view:
        next_view = "domain_homepage"
        show_invitations = True
    domain_links = get_domain_links_for_dropdown(request.couch_user, view_name=next_view)
    if not domain_links:
        return redirect('registration_domain')
    domain_links += get_mirror_domain_links_for_dropdown(request.couch_user, view_name=next_view)
    domain_links = sorted(domain_links, key=lambda link: link['display_name'].lower())

    email = request.couch_user.get_email()
    open_invitations = [e for e in Invitation.by_email(email) if not e.is_expired]

    additional_context = {
        'domain_links': domain_links,
        'invitation_links': [{
            'display_name': i.domain,
            'url': reverse("domain_accept_invitation", args=[i.domain, i.uuid]) + '?no_redirect=true',
        } for i in open_invitations] if show_invitations else [],
        'current_page': {'page_name': _('Select A Project')},
    }

    domain_select_template = "domain/select.html"
    last_visited_domain = get_last_visited_domain(request.couch_user)
    if open_invitations \
       or do_not_redirect \
       or not last_visited_domain:
        return render(request, domain_select_template, additional_context)
    else:
        domain_obj = Domain.get_by_name(last_visited_domain)
        if domain_obj and domain_obj.is_active:
            # mirrors logic in login_and_domain_required
            if (
                request.couch_user.is_member_of(domain_obj, allow_mirroring=True)
                or (request.user.is_superuser and not domain_obj.restrict_superusers)
                or domain_obj.is_snapshot
            ):
                try:
                    return HttpResponseRedirect(reverse(next_view or 'dashboard_default',
                                                args=[last_visited_domain]))
                except Http404:
                    pass

        set_last_visited_domain(request.couch_user, None)
        return render(request, domain_select_template, additional_context)
Пример #19
0
    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"})
                meta = get_meta(request)
                track_sent_invite_on_hubspot.delay(request.couch_user, request.COOKIES, meta)
                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)
Пример #20
0
def accept_all_invitations(request):
    def _invite(invitation, user):
        user.add_as_web_user(invitation.domain, role=invitation.role,
                             location_id=invitation.supply_point, program_id=invitation.program)
        invitation.is_accepted = True
        invitation.save()
        send_confirmation_email(invitation)

    user = request.couch_user
    invites = Invitation.by_email(user.username)
    for invitation in invites:
        if not invitation.is_expired:
            _invite(invitation, user)
            messages.success(request, _(f'You have been added to the "{invitation.domain}" project space.'))
    return HttpResponseRedirect(reverse('domain_select_redirect'))
Пример #21
0
def accept_invitation(request, domain, invitation_id):
    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)
    invitation = Invitation.get(invitation_id)
    assert(invitation.domain == domain)
    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"))
    if request.user.is_authenticated():
        # if you are already authenticated, just add the domain to your
        # list of domains
        if request.couch_user.username != invitation.email:
            messages.error(request, "The invited user %s and your user %s do not match!" % (invitation.email, request.couch_user.username))

        if request.method == "POST":
            couch_user = CouchUser.from_django_user(request.user)
            couch_user.add_domain_membership(domain=domain)
            couch_user.set_role(domain, invitation.role)
            couch_user.save()
            invitation.is_accepted = True
            invitation.save()
            messages.success(request, "You have been added to the %s domain" % domain)
            return HttpResponseRedirect(reverse("domain_homepage", args=[domain,]))
        else:
            return render_to_response(request, 'users/accept_invite.html', {'domain': domain,
                                                                            "invited_user": invitation.email if request.couch_user.username != invitation.email else ""})
    else:
        # if you're not authenticated we need you to fill out your information
        if request.method == "POST":
            form = NewWebUserRegistrationForm(request.POST)
            if form.is_valid():
                user = activate_new_user(form, is_domain_admin=False, domain=invitation.domain)
                user.set_role(domain, invitation.role)
                user.save()
                invitation.is_accepted = True
                invitation.save()
                messages.success(request, "User account for %s created! You may now login." % form.cleaned_data["email"])
                return HttpResponseRedirect(reverse("login"))
        else:
            form = NewWebUserRegistrationForm(initial={'email': invitation.email})

        return render_to_response(request, "users/accept_invite.html", {"form": form})
Пример #22
0
 def extra_context(self):
     invitations = [
         e for e in Invitation.by_email(self.request.user.username)
         if not e.is_expired
     ]
     return {
         'invitation_links': [{
             'domain':
             i.domain,
             'url':
             reverse("domain_accept_invitation", args=[i.domain, i.uuid]) +
             '?no_redirect=true',
         } for i in invitations],
         'show_multiple_invites':
         len(invitations) > 1,
     }
Пример #23
0
    def invite_web_user_form(self):
        role_choices = UserRole.role_choices(self.domain)
        loc = None
        domain_request = DomainRequest.objects.get(id=self.request_id) if self.request_id else None
        initial = {"email": domain_request.email if domain_request else None}
        if "location_id" in self.request.GET:
            from corehq.apps.locations.models import SQLLocation

            loc = SQLLocation.objects.get(location_id=self.request.GET.get("location_id"))
        if self.request.method == "POST":
            current_users = [user.username for user in WebUser.by_domain(self.domain)]
            pending_invites = [di.email for di in Invitation.by_domain(self.domain)]
            return AdminInvitesUserForm(
                self.request.POST,
                excluded_emails=current_users + pending_invites,
                role_choices=role_choices,
                domain=self.domain,
            )
        return AdminInvitesUserForm(initial=initial, role_choices=role_choices, domain=self.domain, location=loc)
Пример #24
0
def select(request,
           domain_select_template='domain/select.html',
           do_not_redirect=False):
    domains_for_user = Domain.active_for_user(request.user)
    if not domains_for_user:
        from corehq.apps.registration.views import track_domainless_new_user
        track_domainless_new_user(request)
        return redirect('registration_domain')

    email = request.couch_user.get_email()
    open_invitations = [
        e for e in Invitation.by_email(email) if not e.is_expired
    ]

    additional_context = {
        'domains_for_user': domains_for_user,
        'open_invitations': open_invitations,
        'current_page': {
            'page_name': _('Select A Project')
        },
    }

    last_visited_domain = request.session.get('last_visited_domain')
    if open_invitations \
       or do_not_redirect \
       or not last_visited_domain:
        return render(request, domain_select_template, additional_context)
    else:
        domain_obj = Domain.get_by_name(last_visited_domain)
        if domain_obj and domain_obj.is_active:
            # mirrors logic in login_and_domain_required
            if (request.couch_user.is_member_of(domain_obj)
                    or (request.user.is_superuser
                        and not domain_obj.restrict_superusers)
                    or domain_obj.is_snapshot):
                try:
                    from corehq.apps.dashboard.views import dashboard_default
                    return dashboard_default(request, last_visited_domain)
                except Http404:
                    pass

        del request.session['last_visited_domain']
        return render(request, domain_select_template, additional_context)
Пример #25
0
def parse_web_users(domain, task=None, total_count=None):
    user_dicts = []
    for n, user in enumerate(get_all_user_rows(domain, include_web_users=True, include_mobile_users=False,
                                               include_inactive=False, include_docs=True)):
        user_dict = make_web_user_dict(user, domain)
        user_dicts.append(user_dict)
        if task:
            DownloadBase.set_progress(task, n, total_count)
    for m, invite in enumerate(Invitation.by_domain(domain)):
        user_dict = make_invited_web_user_dict(invite)
        user_dicts.append(user_dict)
        if task:
            DownloadBase.set_progress(task, n + m, total_count)

    user_headers = [
        'username', 'first_name', 'last_name', 'email', 'role', 'last_access_date (read only)',
        'last_login (read only)', 'status', 'remove'
    ]
    return user_headers, get_user_rows(user_dicts, user_headers)
Пример #26
0
 def invite_web_user_form(self):
     role_choices = _get_editable_role_choices(self.domain, self.request.couch_user, allow_admin_role=True)
     loc = None
     domain_request = DomainRequest.objects.get(id=self.request_id) if self.request_id else None
     initial = {
         'email': domain_request.email if domain_request else None,
     }
     if 'location_id' in self.request.GET:
         from corehq.apps.locations.models import SQLLocation
         loc = SQLLocation.objects.get(location_id=self.request.GET.get('location_id'))
     if self.request.method == 'POST':
         current_users = [user.username for user in WebUser.by_domain(self.domain)]
         pending_invites = [di.email for di in Invitation.by_domain(self.domain)]
         return AdminInvitesUserForm(
             self.request.POST,
             excluded_emails=current_users + pending_invites,
             role_choices=role_choices,
             domain=self.domain
         )
     return AdminInvitesUserForm(initial=initial, role_choices=role_choices, domain=self.domain, location=loc)
Пример #27
0
def _get_invitations_by_filters(domain, user_filters, count_only=False):
    """
    Similar to _get_users_by_filters, but applites to invitations.

    Applies "search_string" filter to the invitations' emails. This does not
    support ES search syntax, it's just a case-insensitive substring search.
    Ignores any other filters.
    """
    filters = {}
    search_string = user_filters.get("search_string", None)
    if search_string:
        filters["email__icontains"] = search_string
    role_id = user_filters.get("role_id", None)
    if role_id:
        role = UserRole.objects.by_couch_id(role_id)
        filters["role"] = role.get_qualified_id()

    invitations = Invitation.by_domain(domain, **filters)
    if count_only:
        return invitations.count()
    return invitations
Пример #28
0
def select(request, domain_select_template='domain/select.html', do_not_redirect=False):
    domains_for_user = Domain.active_for_user(request.user)
    if not domains_for_user:
        from corehq.apps.registration.views import track_domainless_new_user
        track_domainless_new_user(request)
        return redirect('registration_domain')

    email = request.couch_user.get_email()
    open_invitations = [e for e in Invitation.by_email(email) if not e.is_expired]

    additional_context = {
        'domains_for_user': domains_for_user,
        'open_invitations': open_invitations,
        'current_page': {'page_name': _('Select A Project')},
    }

    last_visited_domain = request.session.get('last_visited_domain')
    if open_invitations \
       or do_not_redirect \
       or not last_visited_domain:
        return render(request, domain_select_template, additional_context)
    else:
        domain_obj = Domain.get_by_name(last_visited_domain)
        if domain_obj and domain_obj.is_active:
            # mirrors logic in login_and_domain_required
            if (
                request.couch_user.is_member_of(domain_obj)
                or (request.user.is_superuser and not domain_obj.restrict_superusers)
                or domain_obj.is_snapshot
            ):
                try:
                    from corehq.apps.dashboard.views import dashboard_default
                    return dashboard_default(request, last_visited_domain)
                except Http404:
                    pass

        del request.session['last_visited_domain']
        return render(request, domain_select_template, additional_context)
Пример #29
0
    def rows_for_domain(self, domain_obj):
        def _get_role_name(role):
            if role:
                if role == 'admin':
                    return role
                else:
                    role_id = role[len('user-role:'):]
                    try:
                        return UserRole.get(role_id).name
                    except ResourceNotFound:
                        return _('Unknown Role')
            else:
                return 'N/A'

        rows = []
        for user in get_all_user_rows(domain_obj.name,
                                      include_web_users=True,
                                      include_mobile_users=False,
                                      include_inactive=False,
                                      include_docs=True):
            user = CouchUser.wrap_correctly(user['doc'])
            domain_membership = user.get_domain_membership(domain_obj.name)
            last_accessed_domain = None
            if domain_membership:
                last_accessed_domain = domain_membership.last_accessed
            rows.append([
                user.username, user.full_name,
                user.role_label(domain_obj.name),
                self.format_date(user.last_login), last_accessed_domain,
                _('Active User')
            ] + self.domain_properties(domain_obj))
        for invite in Invitation.by_domain(domain_obj.name):
            rows.append([
                invite.email, 'N/A',
                _get_role_name(invite.role), 'N/A', 'N/A',
                _('Invited')
            ] + self.domain_properties(domain_obj))
        return rows
Пример #30
0
    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"})
                meta = get_meta(request)
                track_sent_invite_on_hubspot.delay(request.couch_user,
                                                   request.COOKIES, meta)
                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)
Пример #31
0
 def test_by_email(self):
     self.assertEqual(len(Invitation.by_email('*****@*****.**')), 1)
     self.assertEqual(len(Invitation.by_email('*****@*****.**')), 1)
     self.assertEqual(len(Invitation.by_email('*****@*****.**')), 0)
Пример #32
0
    def __call__(self, request, invitation_id, **kwargs):
        logging.warning("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"))

        context = self.added_context()
        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"},
                )
                meta = get_meta(request)
                track_existing_user_accepted_invite_on_hubspot.delay(request.couch_user, request.COOKIES, meta)
                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 = NewWebUserRegistrationForm(request.POST)
                if form.is_valid():
                    # create the new user
                    user = activate_new_user(form)
                    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"},
                    )
                    meta = get_meta(request)
                    track_new_user_accepted_invite_on_hubspot.delay(user, request.COOKIES, meta)
                    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])
                    )
                domain = Domain.get_by_name(invitation.domain)
                form = NewWebUserRegistrationForm(
                    initial={
                        "email": invitation.email,
                        "hr_name": domain.display_name() if domain else invitation.domain,
                        "create_domain": False,
                    }
                )

        context.update({"form": form})
        return render(request, self.template, context)
Пример #33
0
 def test_by_domain(self):
     self.assertEqual(len(Invitation.by_domain('domain_1')), 1)
     self.assertEqual(
         len(Invitation.by_domain('domain_1', is_accepted=True)), 2)
     self.assertEqual(len(Invitation.by_domain('domain_2')), 1)
     self.assertEqual(len(Invitation.by_domain('domain_3')), 0)
Пример #34
0
def delete_invitation(request, domain):
    invitation_id = request.POST['id']
    invitation = Invitation.get(invitation_id)
    invitation.delete()
    return json_response({'status': 'ok'})
Пример #35
0
 def invitations(self):
     invitations = Invitation.by_domain(self.domain)
     for invitation in invitations:
         invitation.role_label = self.role_labels.get(invitation.role, "")
     return invitations
Пример #36
0
    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"})
                meta = get_meta(request)
                track_existing_user_accepted_invite_on_hubspot.delay(request.couch_user, request.COOKIES, meta)
                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"})
                    meta = get_meta(request)
                    track_new_user_accepted_invite_on_hubspot.delay(user, request.COOKIES, meta)
                    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)
Пример #37
0
    def setUpClass(cls):
        super().setUpClass()

        plan = DefaultProductPlan.get_default_plan_version(
            edition=SoftwarePlanEdition.ADVANCED)

        cls.blocked_account = generator.billing_account(
            '*****@*****.**', '*****@*****.**')
        cls.blocked_account.block_hubspot_data_for_all_users = True
        cls.blocked_account.save()

        # this is one domain linked to the billing account that blocks hubspot
        cls.blocked_domain = create_domain('block-domain-hubspot')
        first_blocked_sub = Subscription.new_domain_subscription(
            cls.blocked_account, cls.blocked_domain.name, plan)
        first_blocked_sub.is_active = True
        first_blocked_sub.save()

        # this is another domain linked to the billing account that blocks hubspot
        cls.second_blocked_domain = create_domain('block-domain-hubspot-002')
        second_blocked_sub = Subscription.new_domain_subscription(
            cls.blocked_account, cls.second_blocked_domain.name, plan)
        second_blocked_sub.is_active = True
        second_blocked_sub.save()

        # this domain is not linked to an account that is blocking hubspot
        cls.allowed_domain = create_domain('allow-domain-hubspot')
        allowed_account = generator.billing_account('*****@*****.**',
                                                    '*****@*****.**')
        allowed_sub = Subscription.new_domain_subscription(
            allowed_account, cls.allowed_domain.name, plan)
        allowed_sub.is_active = True
        allowed_sub.save()

        cls.allowed_user = WebUser.create(cls.allowed_domain.name,
                                          '*****@*****.**', '*****', None,
                                          None)
        cls.allowed_user.save()

        cls.blocked_user = WebUser.create(cls.blocked_domain.name,
                                          '*****@*****.**', '*****', None,
                                          None)
        cls.blocked_user.save()
        cls.blocked_couch_user = CouchUser.get_by_username(
            cls.blocked_user.username)

        cls.second_blocked_user = WebUser.create(
            cls.second_blocked_domain.name, '*****@*****.**', '*****',
            None, None)
        cls.second_blocked_user.save()
        cls.second_blocked_couch_user = CouchUser.get_by_username(
            cls.second_blocked_user.username)

        cls.blocked_invitation_user = WebUser.create(
            cls.blocked_domain.name, '*****@*****.**',
            '*****', None, None)
        invite_to_blocked_domain = Invitation(
            email=cls.blocked_invitation_user.username,
            is_accepted=True,
            domain=cls.blocked_domain.name,
            invited_on=datetime.now(),
            invited_by="*****@*****.**",
        )
        invite_to_blocked_domain.save()

        cls.blocked_commcare_user = CommCareUser.create(
            cls.blocked_domain.name, 'testuser', '****', None, None)
        cls.blocked_commcare_user.save()
Пример #38
0
def delete_invitation(request, domain):
    invitation_id = request.POST["id"]
    invitation = Invitation.get(invitation_id)
    invitation.delete()
    return json_response({"status": "ok"})
Пример #39
0
 def test_by_domain(self):
     self.assertEqual(len(Invitation.by_domain('domain_1')), 1)
     self.assertEqual(len(Invitation.by_domain('domain_2')), 1)
     self.assertEqual(len(Invitation.by_domain('domain_3')), 0)
Пример #40
0
 def test_by_domain(self):
     self.assertEqual(len(Invitation.by_domain('domain_1')), 1)
     self.assertEqual(len(Invitation.by_domain('domain_2')), 1)
     self.assertEqual(len(Invitation.by_domain('domain_3')), 0)
Пример #41
0
def create_or_update_users_and_groups(upload_domain, user_specs, upload_user, group_memoizer=None, update_progress=None):
    domain_info_by_domain = {}

    def _get_domain_info(domain):
        domain_info = domain_info_by_domain.get(domain)
        if domain_info:
            return domain_info
        if domain == upload_domain:
            domain_group_memoizer = group_memoizer or GroupMemoizer(domain)
        else:
            domain_group_memoizer = GroupMemoizer(domain)
        domain_group_memoizer.load_all()
        can_assign_locations = domain_has_privilege(domain, privileges.LOCATIONS)
        location_cache = None
        if can_assign_locations:
            location_cache = SiteCodeToLocationCache(domain)

        domain_obj = Domain.get_by_name(domain)
        allowed_group_names = [group.name for group in domain_group_memoizer.groups]
        roles_by_name = {role.name: role for role in UserRole.by_domain(domain)}
        domain_user_specs = [spec for spec in user_specs if spec.get('domain', upload_domain) == domain]
        validators = get_user_import_validators(
            domain_obj,
            domain_user_specs,
            allowed_group_names,
            list(roles_by_name),
            upload_domain
        )

        domain_info = DomainInfo(
            validators,
            can_assign_locations,
            location_cache,
            roles_by_name,
            domain_group_memoizer
        )
        domain_info_by_domain[domain] = domain_info
        return domain_info

    ret = {"errors": [], "rows": []}

    current = 0

    try:
        for row in user_specs:
            if update_progress:
                update_progress(current)
                current += 1

            username = row.get('username')
            domain = row.get('domain') or upload_domain
            username = normalize_username(str(username), domain) if username else None
            status_row = {
                'username': username,
                'row': row,
            }

            domain_info = _get_domain_info(domain)

            try:
                for validator in domain_info.validators:
                    validator(row)
            except UserUploadError as e:
                status_row['flag'] = str(e)
                ret['rows'].append(status_row)
                continue

            data = row.get('data')
            email = row.get('email')
            group_names = list(map(str, row.get('group') or []))
            language = row.get('language')
            name = row.get('name')
            password = row.get('password')
            phone_number = row.get('phone-number')
            uncategorized_data = row.get('uncategorized_data')
            user_id = row.get('user_id')
            location_codes = row.get('location_code') or []
            if location_codes and not isinstance(location_codes, list):
                location_codes = [location_codes]
            # ignore empty
            location_codes = [code for code in location_codes if code]
            role = row.get('role', None)
            web_user = row.get('web_user')

            try:
                password = str(password) if password else None

                is_active = spec_value_to_boolean_or_none(row, 'is_active')
                is_account_confirmed = spec_value_to_boolean_or_none(row, 'is_account_confirmed')
                send_account_confirmation_email = spec_value_to_boolean_or_none(row, 'send_confirmation_email')
                remove_web_user = spec_value_to_boolean_or_none(row, 'remove_web_user')

                if user_id:
                    user = CommCareUser.get_by_user_id(user_id, domain)
                    if not user:
                        raise UserUploadError(_(
                            "User with ID '{user_id}' not found"
                        ).format(user_id=user_id, domain=domain))

                    if username and user.username != username:
                        raise UserUploadError(_(
                            'Changing usernames is not supported: %(username)r to %(new_username)r'
                        ) % {'username': user.username, 'new_username': username})

                    # note: explicitly not including "None" here because that's the default value if not set.
                    # False means it was set explicitly to that value
                    if is_account_confirmed is False and not web_user:
                        raise UserUploadError(_(
                            "You can only set 'Is Account Confirmed' to 'False' on a new User."
                        ))

                    if is_password(password):
                        user.set_password(password)
                        # overwrite password in results so we do not save it to the db
                        status_row['row']['password'] = '******'
                    status_row['flag'] = 'updated'
                else:
                    kwargs = {}
                    if is_account_confirmed is not None and not web_user:
                        kwargs['is_account_confirmed'] = is_account_confirmed
                    user = CommCareUser.create(domain, username, password, created_by=upload_user,
                                               created_via=USER_CHANGE_VIA_BULK_IMPORTER, commit=False, **kwargs)
                    status_row['flag'] = 'created'

                if phone_number:
                    user.add_phone_number(_fmt_phone(phone_number), default=True)
                if name:
                    user.set_full_name(str(name))
                if data:
                    user.user_data.update(data)
                if uncategorized_data:
                    user.user_data.update(uncategorized_data)
                if language:
                    user.language = language
                if email:
                    user.email = email.lower()
                if is_active is not None:
                    user.is_active = is_active

                if domain_info.can_assign_locations:
                    # Do this here so that we validate the location code before we
                    # save any other information to the user, this way either all of
                    # the user's information is updated, or none of it
                    location_ids = []
                    for code in location_codes:
                        loc = get_location_from_site_code(code, domain_info.location_cache)
                        location_ids.append(loc.location_id)

                    locations_updated = set(user.assigned_location_ids) != set(location_ids)
                    primary_location_removed = (user.location_id and not location_ids or
                                                user.location_id not in location_ids)

                    if primary_location_removed:
                        user.unset_location(commit=False)
                    if locations_updated:
                        user.reset_locations(location_ids, commit=False)

                if role:
                    role_qualified_id = domain_info.roles_by_name[role].get_qualified_id()
                    user.set_role(domain, role_qualified_id)

                if web_user:
                    user.user_data.update({'login_as_user': web_user})

                user.save()

                if web_user:
                    if not upload_user.can_edit_web_users():
                        raise UserUploadError(_(
                            "Only users with the edit web users permission can upload web users"
                        ))
                    current_user = CouchUser.get_by_username(web_user)
                    if remove_web_user:
                        if not current_user or not current_user.is_member_of(domain):
                            raise UserUploadError(_(
                                "You cannot remove a web user that is not a member of this project. {web_user} is not a member.").format(web_user=web_user)
                            )
                        else:
                            current_user.delete_domain_membership(domain)
                            current_user.save()
                    else:
                        if not role:
                            raise UserUploadError(_(
                                "You cannot upload a web user without a role. {web_user} does not have a role").format(web_user=web_user)
                            )
                        if not current_user and is_account_confirmed:
                            raise UserUploadError(_(
                                "You can only set 'Is Account Confirmed' to 'True' on an existing Web User. {web_user} is a new username.").format(web_user=web_user)
                            )
                        if current_user and not current_user.is_member_of(domain) and is_account_confirmed:
                            current_user.add_as_web_user(domain, role=role_qualified_id, location_id=user.location_id)
                        elif not current_user or not current_user.is_member_of(domain):
                            invite_data = {
                                'email': web_user,
                                'invited_by': upload_user.user_id,
                                'invited_on': datetime.utcnow(),
                                'domain': domain,
                                'role': role_qualified_id,
                                'supply_point': user.location_id
                            }
                            invite = Invitation(**invite_data)
                            invite.save()
                            if send_account_confirmation_email:
                                invite.send_activation_email()

                        elif current_user.is_member_of(domain):
                            # edit existing user in the domain
                            current_user.set_role(domain, role_qualified_id)
                            if user.location_id:
                                current_user.set_location(domain, user.location_id)
                            else:
                                current_user.unset_location(domain)
                            current_user.save()

                if send_account_confirmation_email and not web_user:
                    send_account_confirmation_if_necessary(user)

                if is_password(password):
                    # Without this line, digest auth doesn't work.
                    # With this line, digest auth works.
                    # Other than that, I'm not sure what's going on
                    # Passing use_primary_db=True because of https://dimagi-dev.atlassian.net/browse/ICDS-465
                    user.get_django_user(use_primary_db=True).check_password(password)

                for group in domain_info.group_memoizer.by_user_id(user.user_id):
                    if group.name not in group_names:
                        group.remove_user(user)

                for group_name in group_names:
                    domain_info.group_memoizer.by_name(group_name).add_user(user, save=False)

            except (UserUploadError, CouchUser.Inconsistent) as e:
                status_row['flag'] = str(e)

            ret["rows"].append(status_row)
    finally:
        try:
            for domain_info in domain_info_by_domain.values():
                domain_info.group_memoizer.save_all()
        except BulkSaveError as e:
            _error_message = (
                "Oops! We were not able to save some of your group changes. "
                "Please make sure no one else is editing your groups "
                "and try again."
            )
            logging.exception((
                'BulkSaveError saving groups. '
                'User saw error message "%s". Errors: %s'
            ) % (_error_message, e.errors))
            ret['errors'].append(_error_message)

    return ret
Пример #42
0
 def test_by_email(self):
     self.assertEqual(len(Invitation.by_email('*****@*****.**')), 1)
     self.assertEqual(len(Invitation.by_email('*****@*****.**')), 1)
     self.assertEqual(len(Invitation.by_email('*****@*****.**')), 0)
Пример #43
0
def delete_invitation(request, domain):
    invitation_id = request.POST['id']
    invitation = Invitation.get(invitation_id)
    invitation.delete()
    return json_response({'status': 'ok'})
Пример #44
0
    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"})
                meta = get_meta(request)
                track_existing_user_accepted_invite_on_hubspot.delay(
                    request.couch_user, request.COOKIES, meta)
                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"})
                    meta = get_meta(request)
                    track_new_user_accepted_invite_on_hubspot.delay(
                        user, request.COOKIES, meta)
                    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)
Пример #45
0
 def invitations(self):
     invitations = Invitation.by_domain(self.domain)
     for invitation in invitations:
         invitation.role_label = self.role_labels.get(invitation.role, "")
     return invitations