コード例 #1
0
def log_commcare_user_locations_changes(request, user, old_location_id,
                                        old_assigned_location_ids):
    change_messages = {}
    fields_changed = {}
    if old_location_id != user.location_id:
        location = None
        fields_changed['location_id'] = user.location_id
        if user.location_id:
            location = SQLLocation.objects.get(location_id=user.location_id)
        change_messages.update(
            UserChangeMessage.primary_location_info(location))
    if old_assigned_location_ids != user.assigned_location_ids:
        locations = []
        fields_changed['assigned_location_ids'] = user.assigned_location_ids
        if user.assigned_location_ids:
            locations = SQLLocation.objects.filter(
                location_id__in=user.assigned_location_ids)
        change_messages.update(
            UserChangeMessage.assigned_locations_info(locations))

    if change_messages:
        log_user_change(by_domain=request.domain,
                        for_domain=user.domain,
                        couch_user=user,
                        changed_by_user=request.couch_user,
                        changed_via=USER_CHANGE_VIA_WEB,
                        fields_changed=fields_changed,
                        change_messages=change_messages)
コード例 #2
0
ファイル: importer.py プロジェクト: soitun/commcare-hq
def remove_web_user_from_domain(domain,
                                user,
                                username,
                                upload_user,
                                user_change_logger=None,
                                is_web_upload=False):
    if not user or not user.is_member_of(domain):
        if is_web_upload:
            remove_invited_web_user(domain, username)
            if user_change_logger:
                user_change_logger.add_info(
                    UserChangeMessage.invitation_revoked_for_domain(domain))
        else:
            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=user))
    elif username == upload_user.username:
        raise UserUploadError(
            _("You cannot remove yourself from a domain via bulk upload"))
    else:
        user.delete_domain_membership(domain)
        user.save()
        if user_change_logger:
            user_change_logger.add_info(
                UserChangeMessage.domain_removal(domain))
コード例 #3
0
 def handle(self, *args, **options):
     save = options['save']
     # since we need locations removed, filter for update logs
     records = UserHistory.objects.filter(
         Q(changes__has_key='location_id')
         | Q(changes__has_key='assigned_location_ids'),
         user_type='CommCareUser',
         action=UserHistory.UPDATE,
     )
     with open("add_location_change_message.csv", "w") as _file:
         for record in records.order_by('pk').iterator():
             updated = False
             if 'location_id' in record.changes and record.changes[
                     'location_id'] is None:
                 if 'location' not in record.change_messages:
                     record.change_messages.update(
                         UserChangeMessage.primary_location_removed())
                     updated = True
             if record.changes.get('assigned_location_ids') == []:
                 if 'assigned_locations' not in record.change_messages:
                     record.change_messages.update(
                         UserChangeMessage.assigned_locations_info([]))
                     updated = True
             if updated:
                 _file.write(
                     f"{record.pk},{record.user_id},{record.changes},{record.change_messages}\n"
                 )
                 if save:
                     record.save()
コード例 #4
0
    def test_domain_transfer(self):
        self.transfer.transfer_domain(by_user=self.user, transfer_via='test')

        self.assertFalse(self.transfer.active)
        self.assertFalse(self.transfer.from_user.is_member_of(self.domain))
        self.assertTrue(self.transfer.to_user.is_member_of(self.domain))

        user_history = UserHistory.objects.get(
            user_id=self.transfer.from_user.get_id)
        self.assertEqual(user_history.by_domain, self.domain.name)
        self.assertEqual(user_history.for_domain, self.domain.name)
        self.assertEqual(user_history.changed_by, self.user.get_id)
        self.assertEqual(user_history.change_messages,
                         UserChangeMessage.domain_removal(self.domain.name))
        self.assertEqual(user_history.changed_via, 'test')
        self.assertEqual(user_history.changes, {})

        user_history = UserHistory.objects.get(
            user_id=self.transfer.to_user.get_id)
        self.assertEqual(user_history.by_domain, self.domain.name)
        self.assertEqual(user_history.for_domain, self.domain.name)
        self.assertEqual(user_history.changed_by, self.user.get_id)
        self.assertEqual(user_history.change_messages,
                         UserChangeMessage.domain_addition(self.domain.name))
        self.assertEqual(user_history.changed_via, 'test')
        self.assertEqual(user_history.changes, {})
コード例 #5
0
ファイル: users.py プロジェクト: soitun/commcare-hq
    def form_valid(self, form):
        change_messages = {}
        if not self.user:
            return self.redirect_response(self.request)

        reset_password = form.cleaned_data['reset_password']
        if reset_password:
            self.user.set_password(uuid.uuid4().hex)
            change_messages.update(UserChangeMessage.password_reset())

        # toggle active state
        self.user.is_active = not self.user.is_active
        self.user.save()

        verb = 're-enabled' if self.user.is_active else 'disabled'
        reason = form.cleaned_data['reason']
        change_messages.update(
            UserChangeMessage.status_update(self.user.is_active, reason))
        couch_user = CouchUser.from_django_user(self.user)
        log_user_change(by_domain=None,
                        for_domain=None,
                        couch_user=couch_user,
                        changed_by_user=self.request.couch_user,
                        changed_via=USER_CHANGE_VIA_WEB,
                        change_messages=change_messages,
                        fields_changed={'is_active': self.user.is_active},
                        by_domain_required_for_log=False,
                        for_domain_required_for_log=False)
        mail_admins(
            "User account {}".format(verb),
            "The following user account has been {verb}: \n"
            "    Account: {username}\n"
            "    Reset by: {reset_by}\n"
            "    Password reset: {password_reset}\n"
            "    Reason: {reason}".format(
                verb=verb,
                username=self.username,
                reset_by=self.request.user.username,
                password_reset=str(reset_password),
                reason=reason,
            ))
        send_HTML_email(
            "%sYour account has been %s" %
            (settings.EMAIL_SUBJECT_PREFIX, verb),
            self.user.get_email() if self.user else self.username,
            render_to_string('hqadmin/email/account_disabled_email.html',
                             context={
                                 'support_email': settings.SUPPORT_EMAIL,
                                 'password_reset': reset_password,
                                 'user': self.user,
                                 'verb': verb,
                                 'reason': form.cleaned_data['reason'],
                             }),
        )

        messages.success(self.request,
                         _('Account successfully %(verb)s.' % {'verb': verb}))
        return redirect(self.redirect_url)
コード例 #6
0
ファイル: views.py プロジェクト: soitun/commcare-hq
 def post(self, request, *args, **kwargs):
     if self.request.couch_user.is_domain_admin(self.domain_to_remove):
         messages.error(
             request,
             _("Unable remove membership because you are the admin of %s") %
             self.domain_to_remove)
     else:
         try:
             self.request.couch_user.delete_domain_membership(
                 self.domain_to_remove, create_record=True)
             self.request.couch_user.save()
             log_user_change(
                 by_domain=None,
                 for_domain=self.domain_to_remove,
                 couch_user=request.couch_user,
                 changed_by_user=request.couch_user,
                 changed_via=USER_CHANGE_VIA_WEB,
                 change_messages=UserChangeMessage.domain_removal(
                     self.domain_to_remove),
                 by_domain_required_for_log=False,
             )
             messages.success(
                 request,
                 _("You are no longer part of the project %s") %
                 self.domain_to_remove)
         except Exception:
             messages.error(
                 request,
                 _("There was an error removing you from this project."))
     return self.get(request, *args, **kwargs)
コード例 #7
0
ファイル: views.py プロジェクト: soitun/commcare-hq
 def process_add_phone_number(self):
     if self.phone_number_is_valid():
         user = self.request.couch_user
         is_new_phone_number = self.phone_number not in user.phone_numbers
         user.add_phone_number(self.phone_number)
         user.save()
         if is_new_phone_number:
             log_user_change(
                 by_domain=None,
                 for_domain=None,
                 couch_user=user,
                 changed_by_user=user,
                 changed_via=USER_CHANGE_VIA_WEB,
                 change_messages=UserChangeMessage.phone_numbers_added(
                     [self.phone_number]),
                 by_domain_required_for_log=False,
                 for_domain_required_for_log=False,
             )
         messages.success(self.request, _("Phone number added."))
     else:
         messages.error(
             self.request,
             _("Invalid phone number format entered. "
               "Please enter number, including country code, in digits only."
               ))
     return HttpResponseRedirect(reverse(MyAccountSettingsView.urlname))
コード例 #8
0
def _log_web_user_membership_removed(user, domain, via):
    log_user_change(by_domain=None,
                    for_domain=domain,
                    couch_user=user,
                    changed_by_user=SYSTEM_USER_ID,
                    changed_via=via,
                    change_messages=UserChangeMessage.domain_removal(domain))
コード例 #9
0
 def update_deactivate_after(self, deactivate_after):
     change_message = DeactivateMobileWorkerTrigger.update_trigger(
         self.user_domain, self.user.user_id, deactivate_after)
     if change_message:
         self.logger.add_info(
             UserChangeMessage.updated_deactivate_after(
                 deactivate_after, change_message))
コード例 #10
0
    def test_users_domain_membership(self):
        web_user = WebUser.create(
            self.domain.name,
            f'webuser@{self.domain.name}.{HQ_ACCOUNT_ROOT}',
            '******',
            created_by=None,
            created_via=None)

        another_domain = Domain(name="another-test", is_active=True)
        another_domain.save()
        self.addCleanup(another_domain.delete)

        # add more than 1 domain membership to trigger _log_web_user_membership_removed in tests
        web_user.add_domain_membership(another_domain.name)
        web_user.save()

        self.domain.delete()

        user_history = UserHistory.objects.last()
        self.assertEqual(user_history.by_domain, None)
        self.assertEqual(user_history.for_domain, self.domain.name)
        self.assertEqual(user_history.changed_by, SYSTEM_USER_ID)
        self.assertEqual(user_history.user_id, web_user.get_id)
        self.assertEqual(user_history.change_messages,
                         UserChangeMessage.domain_removal(self.domain.name))
        self.assertEqual(
            user_history.changed_via,
            'corehq.apps.domain.deletion._delete_web_user_membership')
        self.assertEqual(user_history.changes, {})
コード例 #11
0
    def update_user_data(self, data, uncategorized_data, profile, domain_info):
        # Add in existing data. Don't use metadata - we don't want to add profile-controlled fields.
        current_profile_id = self.user.user_data.get(PROFILE_SLUG)

        for key, value in self.user.user_data.items():
            if key not in data:
                data[key] = value
        if profile:
            profile_obj = domain_info.profiles_by_name[profile]
            data[PROFILE_SLUG] = profile_obj.id
            for key in profile_obj.fields.keys():
                self.user.pop_metadata(key)
        try:
            self.user.update_metadata(data)
        except ValueError as e:
            raise UserUploadError(str(e))
        if uncategorized_data:
            self.user.update_metadata(uncategorized_data)

        # Clear blank user data so that it can be purged by remove_unused_custom_fields_from_users_task
        for key in dict(data, **uncategorized_data):
            value = self.user.metadata[key]
            if value is None or value == '':
                self.user.pop_metadata(key)

        new_profile_id = self.user.user_data.get(PROFILE_SLUG)
        if new_profile_id and new_profile_id != current_profile_id:
            profile_name = domain_info.profile_name_by_id[new_profile_id]
            self.logger.add_info(
                UserChangeMessage.profile_info(new_profile_id, profile_name))
コード例 #12
0
    def save_log(self):
        # Tracking for role is done post save to have role setup correctly on save
        if self.role_updated:
            new_role = self.user.get_role(domain=self.user_domain)
            self.logger.add_info(UserChangeMessage.role_change(new_role))

        self._include_user_data_changes()
        return self.logger.save()
コード例 #13
0
    def _log_phone_number_changes(self, old_phone_numbers, new_phone_numbers):
        (items_added,
         items_removed) = find_differences_in_list(target=new_phone_numbers,
                                                   source=old_phone_numbers)

        change_messages = {}
        if items_added:
            change_messages.update(
                UserChangeMessage.phone_numbers_added(
                    list(items_added))["phone_numbers"])

        if items_removed:
            change_messages.update(
                UserChangeMessage.phone_numbers_removed(
                    list(items_removed))["phone_numbers"])

        if change_messages:
            self.logger.add_change_message({'phone_numbers': change_messages})
コード例 #14
0
ファイル: user_updates.py プロジェクト: soitun/commcare-hq
def _update_password(user, password, user_change_logger):
    domain = Domain.get_by_name(user.domain)
    if domain.strong_mobile_passwords:
        clean_password(password)
    user.set_password(password)

    if user_change_logger:
        user_change_logger.add_change_message(
            UserChangeMessage.password_reset())
コード例 #15
0
ファイル: user_updates.py プロジェクト: soitun/commcare-hq
def _update_groups(user, group_ids, user_change_logger):
    groups_updated = user.set_groups(group_ids)
    if user_change_logger and groups_updated:
        groups = []
        if group_ids:
            groups = [
                Group.wrap(doc) for doc in get_docs(Group.get_db(), group_ids)
            ]
        user_change_logger.add_info(UserChangeMessage.groups_info(groups))
コード例 #16
0
    def add_to_domain(self, role_qualified_id, location_id):
        self.user.add_as_web_user(self.user_domain,
                                  role=role_qualified_id,
                                  location_id=location_id)
        self.role_updated = bool(role_qualified_id)

        self.logger.add_info(
            UserChangeMessage.added_as_web_user(self.user_domain))
        if location_id:
            self._log_primary_location_info()
コード例 #17
0
ファイル: user_updates.py プロジェクト: soitun/commcare-hq
def _log_phone_number_change(new_phone_numbers, old_phone_numbers,
                             user_change_logger):
    numbers_added, numbers_removed = find_differences_in_list(
        target=list(new_phone_numbers), source=list(old_phone_numbers))

    change_messages = {}
    if numbers_removed:
        change_messages.update(
            UserChangeMessage.phone_numbers_removed(
                list(numbers_removed))["phone_numbers"])

    if numbers_added:
        change_messages.update(
            UserChangeMessage.phone_numbers_added(
                list(numbers_added))["phone_numbers"])

    if change_messages:
        user_change_logger.add_change_message(
            {'phone_numbers': change_messages})
コード例 #18
0
    def transfer_domain(self, by_user, *args, transfer_via=None, **kwargs):

        self.confirm_time = datetime.utcnow()
        if 'ip' in kwargs:
            self.confirm_ip = kwargs['ip']

        self.from_user.transfer_domain_membership(self.domain,
                                                  self.to_user,
                                                  is_admin=True)
        self.from_user.save()
        if by_user:
            log_user_change(by_domain=self.domain,
                            for_domain=self.domain,
                            couch_user=self.from_user,
                            changed_by_user=by_user,
                            changed_via=transfer_via,
                            change_messages=UserChangeMessage.domain_removal(
                                self.domain))
            log_user_change(by_domain=self.domain,
                            for_domain=self.domain,
                            couch_user=self.to_user,
                            changed_by_user=by_user,
                            changed_via=transfer_via,
                            change_messages=UserChangeMessage.domain_addition(
                                self.domain))
        self.to_user.save()
        self.active = False
        self.save()

        html_content = render_to_string(
            "{template}.html".format(template=self.DIMAGI_CONFIRM_EMAIL),
            self.as_dict())
        text_content = render_to_string(
            "{template}.txt".format(template=self.DIMAGI_CONFIRM_EMAIL),
            self.as_dict())

        send_html_email_async.delay(
            _('There has been a transfer of ownership of {domain}').format(
                domain=self.domain),
            settings.SUPPORT_EMAIL,
            html_content,
            text_content=text_content,
        )
コード例 #19
0
 def update_primary_location(self, location_id):
     current_primary_location_id = get_user_primary_location_id(
         self.user, self.user_domain)
     if location_id:
         self.user.set_location(self.user_domain, location_id)
         if current_primary_location_id != location_id:
             self._log_primary_location_info()
     else:
         self.user.unset_location(self.user_domain)
         # if there was a location before, log that it was cleared
         if current_primary_location_id:
             self.logger.add_info(
                 UserChangeMessage.primary_location_removed())
コード例 #20
0
def log_user_groups_change(domain, request, user, group_ids=None):
    groups = []
    # no groups assigned would be group ids as []
    # so if group ids were NOT passed or if some were passed, get groups for user
    if group_ids is None or group_ids:
        groups = Group.by_user_id(user.get_id)
    log_user_change(
        by_domain=domain,
        for_domain=domain,  # Groups are bound to a domain, so use domain
        couch_user=user,
        changed_by_user=request.couch_user,
        changed_via=USER_CHANGE_VIA_WEB,
        change_messages=UserChangeMessage.groups_info(groups))
コード例 #21
0
    def update_locations(self, location_codes, domain_info):
        from corehq.apps.user_importer.importer import (
            check_modified_user_loc, find_location_id,
            get_location_from_site_code)

        location_ids = find_location_id(location_codes,
                                        domain_info.location_cache)
        user_current_primary_location_id = self.user.location_id
        locations_updated, primary_loc_removed = check_modified_user_loc(
            location_ids, self.user.location_id,
            self.user.assigned_location_ids)
        if primary_loc_removed:
            self.user.unset_location(commit=False)
        if locations_updated:
            self.user.reset_locations(location_ids, commit=False)
            self.logger.add_changes({'assigned_location_ids': location_ids})
            if location_ids:
                locations = [
                    get_location_from_site_code(code,
                                                domain_info.location_cache)
                    for code in location_codes
                ]
                self.logger.add_info(
                    UserChangeMessage.assigned_locations_info(locations))
            else:
                self.logger.add_info(
                    UserChangeMessage.assigned_locations_info([]))

        # log this after assigned locations are updated, which can re-set primary location
        if self.user.location_id != user_current_primary_location_id:
            self.logger.add_changes({'location_id': self.user.location_id})
            if self.user.location_id:
                self.logger.add_info(
                    UserChangeMessage.primary_location_info(
                        self.user.get_sql_location(self.user_domain)))
            else:
                self.logger.add_info(
                    UserChangeMessage.primary_location_removed())
コード例 #22
0
    def update_locations(self, location_codes, membership, domain_info):
        from corehq.apps.user_importer.importer import (
            check_modified_user_loc, find_location_id,
            get_location_from_site_code)

        location_ids = find_location_id(location_codes,
                                        domain_info.location_cache)
        user_current_primary_location_id = membership.location_id
        locations_updated, primary_loc_removed = check_modified_user_loc(
            location_ids, membership.location_id,
            membership.assigned_location_ids)
        if primary_loc_removed:
            self.user.unset_location(self.user_domain, commit=False)
        if locations_updated:
            self.user.reset_locations(self.user_domain,
                                      location_ids,
                                      commit=False)
            if location_ids:
                locations = [
                    get_location_from_site_code(code,
                                                domain_info.location_cache)
                    for code in location_codes
                ]
            else:
                locations = []
            self.logger.add_info(
                UserChangeMessage.assigned_locations_info(locations))

        # log this after assigned locations are updated, which can re-set primary location
        user_updated_primary_location_id = get_user_primary_location_id(
            self.user, self.user_domain)
        if user_updated_primary_location_id != user_current_primary_location_id:
            if user_updated_primary_location_id:
                self._log_primary_location_info()
            else:
                self.logger.add_info(
                    UserChangeMessage.primary_location_removed())
コード例 #23
0
ファイル: views.py プロジェクト: soitun/commcare-hq
 def process_delete_phone_number(self):
     self.request.couch_user.delete_phone_number(self.phone_number)
     log_user_change(
         by_domain=None,
         for_domain=None,
         couch_user=self.request.couch_user,
         changed_by_user=self.request.couch_user,
         changed_via=USER_CHANGE_VIA_WEB,
         change_messages=UserChangeMessage.phone_numbers_removed(
             [self.phone_number]),
         by_domain_required_for_log=False,
         for_domain_required_for_log=False,
     )
     messages.success(self.request, _("Phone number deleted."))
     return HttpResponseRedirect(reverse(MyAccountSettingsView.urlname))
コード例 #24
0
ファイル: test_views.py プロジェクト: soitun/commcare-hq
    def test_process_delete_phone_number(self):
        phone_number = "9999999999"
        self.client.post(self.url, {
            "form_type": "delete-phone-number",
            "phone_number": phone_number
        })

        user_history_log = UserHistory.objects.get(
            user_id=self.couch_user.get_id)
        self.assertIsNone(user_history_log.message)
        self.assertEqual(
            user_history_log.change_messages,
            UserChangeMessage.phone_numbers_removed([phone_number]))
        self.assertEqual(user_history_log.changed_by, self.couch_user.get_id)
        self.assertIsNone(user_history_log.by_domain)
        self.assertIsNone(user_history_log.for_domain)
        self.assertEqual(user_history_log.changed_via, USER_CHANGE_VIA_WEB)
コード例 #25
0
    def test_delete_phone_number(self):
        phone_number = '99999999'
        self.client.post(
            reverse('delete_phone_number',
                    args=[self.domain, self.commcare_user.get_id]),
            {'phone_number': phone_number})

        user_history_log = UserHistory.objects.get(
            user_id=self.commcare_user.get_id)
        self.assertIsNone(user_history_log.message)
        self.assertEqual(
            user_history_log.change_messages,
            UserChangeMessage.phone_numbers_removed([phone_number]))
        self.assertEqual(user_history_log.changed_by, self.web_user.get_id)
        self.assertEqual(user_history_log.by_domain, self.domain)
        self.assertEqual(user_history_log.for_domain, self.domain)
        self.assertEqual(user_history_log.changed_via, USER_CHANGE_VIA_WEB)
コード例 #26
0
    def update_user_groups(self, domain_info, group_names):
        """
        Add/remove user from groups without save and return change message for changes, if any
        """
        old_group_ids = set()
        for group in domain_info.group_memoizer.by_user_id(self.user.user_id):
            old_group_ids.add(group.get_id)
            if group.name not in group_names:
                group.remove_user(self.user)
                domain_info.group_memoizer.updated_groups.add(group.get_id)

        new_groups = {}
        for group_name in group_names:
            group = domain_info.group_memoizer.by_name(group_name)
            new_groups[group.get_id] = group
            if group.add_user(self.user, save=False):
                domain_info.group_memoizer.group_updated(group.get_id)

        if set(new_groups) != old_group_ids:
            return UserChangeMessage.groups_info(list(new_groups.values()))
コード例 #27
0
    def test_update(self):
        restore_phone_numbers_to = self.commcare_user.to_json(
        )['phone_numbers']

        self.commcare_user.add_phone_number("9999999999")

        change_messages = UserChangeMessage.phone_numbers_added(["9999999999"])
        user_history = log_user_change(
            self.domain,
            self.domain,
            self.commcare_user,
            self.web_user,
            changed_via=USER_CHANGE_VIA_BULK_IMPORTER,
            change_messages=change_messages,
            fields_changed={
                'phone_numbers': self.commcare_user.phone_numbers,
                'password': '******'
            },
            action=UserModelAction.UPDATE)

        self.assertEqual(user_history.by_domain, self.domain)
        self.assertEqual(user_history.for_domain, self.domain)
        self.assertEqual(user_history.user_type, "CommCareUser")
        self.assertIsNotNone(user_history.user_id)
        self.assertEqual(user_history.user_id, self.commcare_user.get_id)
        self.assertIsNotNone(user_history.changed_by)
        self.assertEqual(user_history.changed_by, self.web_user.get_id)
        self.assertEqual(user_history.changes,
                         {'phone_numbers': ['9999999999']})
        self.assertEqual(user_history.changed_via,
                         USER_CHANGE_VIA_BULK_IMPORTER)
        self.assertEqual(user_history.change_messages, change_messages)
        self.assertEqual(user_history.action, UserModelAction.UPDATE.value)
        self.assertEqual(user_history.user_repr,
                         user_id_to_username(self.commcare_user.get_id))
        self.assertEqual(user_history.changed_by_repr,
                         user_id_to_username(self.web_user.get_id))

        self.commcare_user.phone_numbers = restore_phone_numbers_to
コード例 #28
0
ファイル: importer.py プロジェクト: soitun/commcare-hq
def create_or_update_web_user_invite(email,
                                     domain,
                                     role_qualified_id,
                                     upload_user,
                                     location_id,
                                     user_change_logger=None,
                                     send_email=True):
    invite, invite_created = Invitation.objects.update_or_create(
        email=email,
        domain=domain,
        is_accepted=False,
        defaults={
            'invited_by': upload_user.user_id,
            'invited_on': datetime.utcnow(),
            'supply_point': location_id,
            'role': role_qualified_id
        },
    )
    if invite_created and send_email:
        invite.send_activation_email()
    if invite_created and user_change_logger:
        user_change_logger.add_info(
            UserChangeMessage.invited_to_domain(domain))
コード例 #29
0
    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)
コード例 #30
0
ファイル: users.py プロジェクト: soitun/commcare-hq
    def form_valid(self, form):
        from django_otp import devices_for_user

        username = form.cleaned_data['username']
        user = User.objects.get(username__iexact=username)
        for device in devices_for_user(user):
            device.delete()

        couch_user = CouchUser.from_django_user(user)
        disable_for_days = form.cleaned_data['disable_for_days']
        if disable_for_days:
            disable_until = datetime.utcnow() + timedelta(
                days=disable_for_days)
            couch_user.two_factor_auth_disabled_until = disable_until
            couch_user.save()

        verification = form.cleaned_data['verification_mode']
        verified_by = form.cleaned_data['via_who'] or self.request.user.username
        change_messages = UserChangeMessage.two_factor_disabled_with_verification(
            verified_by, verification, disable_for_days)
        log_user_change(by_domain=None,
                        for_domain=None,
                        couch_user=couch_user,
                        changed_by_user=self.request.couch_user,
                        changed_via=USER_CHANGE_VIA_WEB,
                        change_messages=change_messages,
                        by_domain_required_for_log=False,
                        for_domain_required_for_log=False)
        mail_admins(
            "Two-Factor account reset",
            "Two-Factor auth was reset. Details: \n"
            "    Account reset: {username}\n"
            "    Reset by: {reset_by}\n"
            "    Request Verification Mode: {verification}\n"
            "    Verified by: {verified_by}\n"
            "    Two-Factor disabled for {days} days.".format(
                username=username,
                reset_by=self.request.user.username,
                verification=verification,
                verified_by=verified_by,
                days=disable_for_days),
        )
        send_HTML_email(
            "%sTwo-Factor authentication reset" %
            settings.EMAIL_SUBJECT_PREFIX,
            couch_user.get_email(),
            render_to_string(
                'hqadmin/email/two_factor_reset_email.html',
                context={
                    'until':
                    disable_until.strftime('%Y-%m-%d %H:%M:%S UTC')
                    if disable_for_days else None,
                    'support_email':
                    settings.SUPPORT_EMAIL,
                    'email_subject':
                    "[URGENT] Possible Account Breach",
                    'email_body':
                    "Two Factor Auth on my CommCare account "
                    "was disabled without my request. My username is: %s" %
                    username,
                }),
        )

        messages.success(self.request,
                         _('Two-Factor Auth successfully disabled.'))
        return redirect('{}?q={}'.format(reverse('web_user_lookup'), username))