예제 #1
0
    def test_update_web_apps_list(self):
        self.assertEqual([], UserRole.by_domain(self.linked_domain))

        report_mapping = {'master_report_id': 'linked_report_id'}
        with patch('corehq.apps.linked_domain.updates.get_static_report_mapping', return_value=report_mapping):
            update_user_roles(self.domain_link)

        roles = UserRole.by_domain(self.linked_domain)
        self.assertEqual(1, len(roles))
        self.assertEqual(roles[0].permissions.view_web_apps_list, [self.linked_app._id])
        self.assertEqual(roles[0].permissions.view_report_list, [get_ucr_class_name('linked_report_id')])
def _has_helpdesk_role(domain, couch_user):
    user_roles = UserRole.by_domain(domain)
    helpdesk_roles_id = [
        role.get_id for role in user_roles if role.name in const.HELPDESK_ROLES
    ]
    domain_membership = couch_user.get_domain_membership(domain)
    return domain_membership.role_id in helpdesk_roles_id
예제 #3
0
def get_editable_role_choices(domain,
                              couch_user,
                              allow_admin_role,
                              use_qualified_id=True):
    """
    :param domain: roles for domain
    :param couch_user: user accessing the roles
    :param allow_admin_role: to include admin role, in case user is admin
    :param use_qualified_id: use role's qualified id as the id for the choice else the db id
    """
    def role_to_choice(role):
        return (role.get_qualified_id() if use_qualified_id else role.get_id,
                role.name or _('(No Name)'))

    roles = UserRole.by_domain(domain)
    if not couch_user.is_domain_admin(domain):
        try:
            user_role = couch_user.get_role(domain)
        except DomainMembershipError:
            user_role = None
        user_role_id = user_role.get_id if user_role else None
        roles = [
            role for role in roles
            if role.accessible_by_non_admin_role(user_role_id)
        ]
    elif allow_admin_role:
        roles = [AdminUserRole(domain=domain)] + roles
    return [role_to_choice(role) for role in roles]
예제 #4
0
    def __init__(self, *args, **kwargs):
        self.domain = kwargs.pop('domain')
        super(CommCareUserFilterForm, self).__init__(*args, **kwargs)

        roles = UserRole.by_domain(self.domain)
        self.fields['role_id'].choices =  [('', _('All Roles'))] + [
            (role._id, role.name or _('(No Name)')) for role in roles]

        self.helper = FormHelper()
        self.helper.form_method = 'GET'
        self.helper.form_id = 'user-filters'
        self.helper.form_class = 'form-horizontal'
        self.helper.form_action = reverse('download_commcare_users', args=[self.domain])

        self.helper.label_class = 'col-sm-3 col-md-2'
        self.helper.field_class = 'col-sm-9 col-md-8 col-lg-6'
        self.helper.form_text_inline = True

        self.helper.layout = crispy.Layout(
            crispy.Fieldset(
                _("Filter and Download Users"),
                crispy.Field('role_id'),
                crispy.Field('search_string'),
            ),
            hqcrispy.FormActions(
                twbscrispy.StrictButton(
                    _("Download All Users"),
                    type="submit",
                    css_class="btn btn-success submit_button",
                )
            ),
        )
예제 #5
0
def orgs_team_members(request, org, team_id, template="orgs/orgs_team_members.html"):
    organization = Organization.get_by_name(org)

    ctxt = base_context(request, organization)
    ctxt["tab"] = "teams"

    try:
        team = Team.get(team_id)
    except ResourceNotFound:
        raise Http404("Team %s does not exist" % team_id)

    team_members = team.get_members()
    team_members.sort(key=lambda user: user.username)

    # inspect the domains of the team
    domain_names = team.get_domains()
    team_domains = list()
    for name in domain_names:
        team_domains.append([Domain.get_by_name(name), team.role_label(domain=name), UserRole.by_domain(name)])

    nonmembers = [
        m.username for m in filter(lambda m: m.username not in [tm.username for tm in team_members], ctxt["members"])
    ]
    nondomains = [d.name for d in filter(lambda d: d.name not in [td[0].name for td in team_domains], ctxt["domains"])]

    ctxt.update(
        dict(
            team=team,
            team_members=team_members,
            nonmembers=nonmembers,
            team_domains=team_domains,
            nondomains=nondomains,
        )
    )
    return render(request, template, ctxt)
예제 #6
0
    def user_roles(self):
        user_roles = [AdminUserRole(domain=self.domain)]
        user_roles.extend(
            sorted(UserRole.by_domain(self.domain),
                   key=lambda role: role.name if role.name else '\uFFFF'))

        show_es_issue = False
        # skip the admin role since it's not editable
        for role in user_roles[1:]:
            try:
                role.hasUsersAssigned = bool(role.ids_of_assigned_users)
            except TypeError:
                # when query_result['hits'] returns None due to an ES issue
                show_es_issue = True
            role.has_unpermitted_location_restriction = (
                not self.can_restrict_access_by_location
                and not role.permissions.access_all_locations)
        if show_es_issue:
            messages.error(
                self.request,
                mark_safe(
                    _("We might be experiencing issues fetching the entire list "
                      "of user roles right now. This issue is likely temporary and "
                      "nothing to worry about, but if you keep seeing this for "
                      "more than a day, please <a href='#modalReportIssue' "
                      "data-toggle='modal'>Report an Issue</a>.")))
        return user_roles
예제 #7
0
파일: forms.py 프로젝트: dimagi/commcare-hq
    def __init__(self, *args, **kwargs):
        self.domain = kwargs.pop('domain')
        super(CommCareUserFilterForm, self).__init__(*args, **kwargs)

        roles = UserRole.by_domain(self.domain)
        self.fields['role_id'].choices = [('', _('All Roles'))] + [
            (role._id, role.name or _('(No Name)')) for role in roles]

        self.helper = FormHelper()
        self.helper.form_method = 'GET'
        self.helper.form_id = 'user-filters'
        self.helper.form_class = 'form-horizontal'
        self.helper.form_action = reverse('download_commcare_users', args=[self.domain])

        self.helper.label_class = 'col-sm-3 col-md-2'
        self.helper.field_class = 'col-sm-9 col-md-8 col-lg-6'
        self.helper.form_text_inline = True

        self.helper.layout = crispy.Layout(
            crispy.Fieldset(
                _("Filter and Download Users"),
                crispy.Field('role_id'),
                crispy.Field('search_string'),
            ),
            hqcrispy.FormActions(
                twbscrispy.StrictButton(
                    _("Download All Users"),
                    type="submit",
                    css_class="btn btn-primary submit_button",
                )
            ),
        )
예제 #8
0
    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
예제 #9
0
def orgs_team_members(request, org, team_id, template="orgs/orgs_team_members.html"):
    class TeamMembersNotification(Notification):
        doc_type = 'OrgTeamMembersNotification'

        def template(self):
            return 'orgs/partials/team_members_notification.html'

    MainNotification.display_if_needed(messages, request, ctxt={"org": request.organization})
    TeamMembersNotification.display_if_needed(messages, request)

    ctxt = base_context(request, request.organization)
    ctxt["tab"] = "teams"

    try:
        team = Team.get(team_id)
    except ResourceNotFound:
        raise Http404("Team %s does not exist" % team_id)

    team_members = team.get_members()
    team_members.sort(key=lambda user: user.username)

    #inspect the domains of the team
    domain_names = team.get_domains()
    team_domains = list()
    for name in domain_names:
        team_domains.append([Domain.get_by_name(name), team.role_label(domain=name), UserRole.by_domain(name)])

    nonmembers = filter(lambda m: m.username not in [tm.username for tm in team_members], ctxt["members"])
    nondomains = filter(lambda d: d.name not in [td[0].name for td in team_domains], ctxt["domains"])

    ctxt.update(dict(team=team, team_members=team_members, nonmembers=nonmembers,
                     team_domains=team_domains, nondomains=nondomains))
    return render(request, template, ctxt)
예제 #10
0
def orgs_team_members(request, org, team_id, template="orgs/orgs_team_members.html"):
    class TeamMembersNotification(Notification):
        doc_type = 'OrgTeamMembersNotification'

        def template(self):
            return 'orgs/partials/team_members_notification.html'

    MainNotification.display_if_needed(messages, request, ctxt={"org": request.organization})
    TeamMembersNotification.display_if_needed(messages, request)

    ctxt = base_context(request, request.organization)
    ctxt["tab"] = "teams"

    try:
        team = Team.get(team_id)
    except ResourceNotFound:
        raise Http404("Team %s does not exist" % team_id)

    team_members = team.get_members()
    team_members.sort(key=lambda user: user.username)

    #inspect the domains of the team
    domain_names = team.get_domains()
    team_domains = list()
    for name in domain_names:
        team_domains.append([Domain.get_by_name(name), team.role_label(domain=name), UserRole.by_domain(name)])

    nonmembers = filter(lambda m: m.username not in [tm.username for tm in team_members], ctxt["members"])
    nondomains = filter(lambda d: d.name not in [td[0].name for td in team_domains], ctxt["domains"])

    ctxt.update(dict(team=team, team_members=team_members, nonmembers=nonmembers,
                     team_domains=team_domains, nondomains=nondomains))
    return render(request, template, ctxt)
예제 #11
0
    def user_roles(self):
        user_roles = [AdminUserRole(domain=self.domain)]
        user_roles.extend(sorted(
            UserRole.by_domain(self.domain),
            key=lambda role: role.name if role.name else '\uFFFF'
        ))

        show_es_issue = False
        # skip the admin role since it's not editable
        for role in user_roles[1:]:
            try:
                role.hasUsersAssigned = bool(role.ids_of_assigned_users)
            except TypeError:
                # when query_result['hits'] returns None due to an ES issue
                show_es_issue = True
            role.has_unpermitted_location_restriction = (
                not self.can_restrict_access_by_location
                and not role.permissions.access_all_locations
            )
        if show_es_issue:
            messages.error(
                self.request,
                mark_safe(_(
                    "We might be experiencing issues fetching the entire list "
                    "of user roles right now. This issue is likely temporary and "
                    "nothing to worry about, but if you keep seeing this for "
                    "more than a day, please <a href='#modalReportIssue' "
                    "data-toggle='modal'>Report an Issue</a>."
                ))
            )
        return user_roles
    def setUp(self):
        super(TestUserRoleSubscriptionChanges, self).setUp()
        self.domain = generator.arbitrary_domain()
        UserRole.init_domain_with_presets(self.domain.name)
        self.user_roles = UserRole.by_domain(self.domain.name)
        self.custom_role = UserRole.get_or_create_with_permissions(
            self.domain.name,
            Permissions(edit_apps=True, edit_web_users=True),
            "Custom Role"
        )
        self.custom_role.save()
        self.read_only_role = UserRole.get_read_only_role_by_domain(self.domain.name)

        self.admin_user = generator.arbitrary_web_user()
        self.admin_user.add_domain_membership(self.domain.name, is_admin=True)
        self.admin_user.save()

        self.web_users = []
        self.commcare_users = []
        for role in [self.custom_role] + self.user_roles:
            web_user = generator.arbitrary_web_user()
            web_user.add_domain_membership(self.domain.name, role_id=role.get_id)
            web_user.save()
            self.web_users.append(web_user)

            commcare_user = generator.arbitrary_commcare_user(
                domain=self.domain.name)
            commcare_user.set_role(self.domain.name, role.get_qualified_id())
            commcare_user.save()
            self.commcare_users.append(commcare_user)

        self.account = BillingAccount.get_or_create_account_by_domain(
            self.domain.name,created_by=self.admin_user.username)[0]
        self.advanced_plan = DefaultProductPlan.get_default_plan_by_domain(
            self.domain.name,edition=SoftwarePlanEdition.ADVANCED)
예제 #13
0
    def setUpClass(cls):
        super(AllCommCareUsersTest, cls).setUpClass()
        delete_all_users()
        hard_delete_deleted_users()
        cls.ccdomain = Domain(name='cc_user_domain')
        cls.ccdomain.save()
        cls.other_domain = Domain(name='other_domain')
        cls.other_domain.save()

        UserRole.init_domain_with_presets(cls.ccdomain.name)
        cls.user_roles = UserRole.by_domain(cls.ccdomain.name)
        cls.custom_role = UserRole.get_or_create_with_permissions(
            cls.ccdomain.name,
            Permissions(
                edit_apps=True,
                edit_web_users=True,
                view_web_users=True,
                view_roles=True,
            ),
            "Custom Role"
        )
        cls.custom_role.save()

        cls.ccuser_1 = CommCareUser.create(
            domain=cls.ccdomain.name,
            username='******',
            password='******',
            email='*****@*****.**',
        )
        cls.ccuser_2 = CommCareUser.create(
            domain=cls.ccdomain.name,
            username='******',
            password='******',
            email='*****@*****.**',
        )
        cls.ccuser_2.set_role(cls.ccdomain.name, cls.custom_role.get_qualified_id())
        cls.ccuser_2.save()

        cls.web_user = WebUser.create(
            domain=cls.ccdomain.name,
            username='******',
            password='******',
            email='*****@*****.**',
        )
        cls.ccuser_other_domain = CommCareUser.create(
            domain=cls.other_domain.name,
            username='******',
            password='******',
            email='*****@*****.**',
        )
        cls.retired_user = CommCareUser.create(
            domain=cls.ccdomain.name,
            username='******',
            password='******',
            email='*****@*****.**',
        )
        cls.retired_user.retire()
예제 #14
0
    def test_update_report_list(self):
        self.assertEqual([], UserRole.by_domain(self.linked_domain))

        report_mapping = {'master_report_id': 'linked_report_id'}
        with patch(
                'corehq.apps.linked_domain.updates.get_static_report_mapping',
                return_value=report_mapping):
            update_user_roles(self.domain_link)

        roles = {r.name: r for r in UserRole.by_domain(self.linked_domain)}
        self.assertEqual(2, len(roles))
        self.assertEqual(roles['test'].permissions.view_report_list,
                         [get_ucr_class_name('linked_report_id')])
        self.assertTrue(roles['test'].is_non_admin_editable)

        self.assertTrue(roles['other_test'].permissions.edit_web_users)
        self.assertEqual(roles['other_test'].assignable_by,
                         [roles['test'].get_id])
예제 #15
0
    def setUpClass(cls):
        super(AllCommCareUsersTest, cls).setUpClass()
        delete_all_users()
        hard_delete_deleted_users()
        cls.ccdomain = Domain(name='cc_user_domain')
        cls.ccdomain.save()
        cls.other_domain = Domain(name='other_domain')
        cls.other_domain.save()

        UserRole.init_domain_with_presets(cls.ccdomain.name)
        cls.user_roles = UserRole.by_domain(cls.ccdomain.name)
        cls.custom_role = UserRole.get_or_create_with_permissions(
            cls.ccdomain.name,
            Permissions(
                edit_apps=True,
                edit_web_users=True,
                view_web_users=True,
                view_roles=True,
            ), "Custom Role")
        cls.custom_role.save()

        cls.ccuser_1 = CommCareUser.create(
            domain=cls.ccdomain.name,
            username='******',
            password='******',
            email='*****@*****.**',
        )
        cls.ccuser_2 = CommCareUser.create(
            domain=cls.ccdomain.name,
            username='******',
            password='******',
            email='*****@*****.**',
        )
        cls.ccuser_2.set_role(cls.ccdomain.name,
                              cls.custom_role.get_qualified_id())
        cls.ccuser_2.save()

        cls.web_user = WebUser.create(
            domain=cls.ccdomain.name,
            username='******',
            password='******',
            email='*****@*****.**',
        )
        cls.ccuser_other_domain = CommCareUser.create(
            domain=cls.other_domain.name,
            username='******',
            password='******',
            email='*****@*****.**',
        )
        cls.retired_user = CommCareUser.create(
            domain=cls.ccdomain.name,
            username='******',
            password='******',
            email='*****@*****.**',
        )
        cls.retired_user.retire()
예제 #16
0
파일: views.py 프로젝트: mchampanis/core-hq
def web_users(request, domain, template="users/web_users.html"):
    context = _users_context(request, domain)
    user_roles = [AdminUserRole(domain=domain)]
    user_roles.extend(sorted(UserRole.by_domain(domain), key=lambda role: role.name if role.name else u'\uFFFF'))
    context.update({
        'user_roles': user_roles,
        'default_role': UserRole.get_default(),
        'report_list': get_possible_reports(domain),
    })
    return render_to_response(request, template, context)
예제 #17
0
def _get_editable_role_choices(domain, couch_user, allow_admin_role):
    def role_to_choice(role):
        return (role.get_qualified_id(), role.name or _('(No Name)'))

    roles = UserRole.by_domain(domain)
    if not couch_user.is_domain_admin(domain):
        roles = [role for role in roles if role.is_non_admin_editable]
    elif allow_admin_role:
        roles = [AdminUserRole(domain=domain)] + roles
    return [role_to_choice(role) for role in roles]
예제 #18
0
def _get_editable_role_choices(domain, couch_user, allow_admin_role):
    def role_to_choice(role):
        return (role.get_qualified_id(), role.name or _('(No Name)'))

    roles = UserRole.by_domain(domain)
    if not couch_user.is_domain_admin(domain):
        roles = [role for role in roles if role.is_non_admin_editable]
    elif allow_admin_role:
        roles = [AdminUserRole(domain=domain)] + roles
    return [role_to_choice(role) for role in roles]
예제 #19
0
    def user_roles(self):
        user_roles = [AdminUserRole(domain=self.domain)]
        user_roles.extend(sorted(UserRole.by_domain(self.domain),
                                 key=lambda role: role.name if role.name else u'\uFFFF'))

        #  indicate if a role has assigned users, skip admin role
        for i in range(1, len(user_roles)):
            role = user_roles[i]
            role.__setattr__('hasUsersAssigned',
                             True if len(role.ids_of_assigned_users) > 0 else False)
        return user_roles
예제 #20
0
    def user_roles(self):
        user_roles = [AdminUserRole(domain=self.domain)]
        user_roles.extend(sorted(UserRole.by_domain(self.domain),
                                 key=lambda role: role.name if role.name else u'\uFFFF'))

        #  indicate if a role has assigned users, skip admin role
        for i in range(1, len(user_roles)):
            role = user_roles[i]
            role.__setattr__('hasUsersAssigned',
                             True if len(role.ids_of_assigned_users) > 0 else False)
        return user_roles
예제 #21
0
    def test_match_ids(self):
        self.assertEqual([], UserRole.by_domain(self.linked_domain))

        role = UserRole(domain=self.linked_domain,
                        name='id_test',
                        permissions=Permissions(
                            edit_web_users=False,
                            view_locations=True,
                        ),
                        assignable_by=[self.role.get_id],
                        upstream_id=self.other_role.get_id)
        role.save()

        update_user_roles(self.domain_link)
        roles = {r.name: r for r in UserRole.by_domain(self.linked_domain)}
        self.assertEqual(2, len(roles))
        self.assertIsNotNone(roles.get('other_test'))
        self.assertTrue(roles['other_test'].permissions.edit_web_users)
        self.assertEqual(roles['other_test'].upstream_id,
                         self.other_role.get_id)
예제 #22
0
 def response_role_based_access(self):
     """
     Perform Role Based Access Upgrade
     - Un-archive custom roles.
     """
     if self.verbose:
         num_archived_roles = len(
             UserRole.by_domain(self.domain.name, is_archived=True))
         if num_archived_roles:
             print "Re-Activating %d archived roles." % num_archived_roles
     UserRole.unarchive_roles_for_domain(self.domain.name)
     return True
예제 #23
0
 def response_role_based_access(self):
     """
     Perform Role Based Access Upgrade
     - Un-archive custom roles.
     """
     if self.verbose:
         num_archived_roles = len(UserRole.by_domain(self.domain.name,
                                                     is_archived=True))
         if num_archived_roles:
             print "Re-Activating %d archived roles." % num_archived_roles
     UserRole.unarchive_roles_for_domain(self.domain.name)
     return True
예제 #24
0
    def user_roles(self):
        user_roles = [AdminUserRole(domain=self.domain)]
        user_roles.extend(
            sorted(UserRole.by_domain(self.domain),
                   key=lambda role: role.name if role.name else u'\uFFFF'))

        # skip the admin role since it's not editable
        for role in user_roles[1:]:
            role.hasUsersAssigned = bool(role.ids_of_assigned_users)
            role.has_unpermitted_location_restriction = (
                not self.can_restrict_access_by_location
                and not role.permissions.access_all_locations)
        return user_roles
예제 #25
0
    def __init__(self, *args, **kwargs):
        from corehq.apps.locations.forms import LocationSelectWidget
        from corehq.apps.users.views import get_editable_role_choices
        self.domain = kwargs.pop('domain')
        self.couch_user = kwargs.pop('couch_user')
        super(CommCareUserFilterForm, self).__init__(*args, **kwargs)
        self.fields['location_id'].widget = LocationSelectWidget(self.domain)
        self.fields['location_id'].help_text = ExpandedMobileWorkerFilter.location_search_help

        if is_icds_cas_project(self.domain) and not self.couch_user.is_domain_admin(self.domain):
            roles = get_editable_role_choices(self.domain, self.couch_user, allow_admin_role=True,
                                              use_qualified_id=False)
            self.fields['role_id'].choices = roles
        else:
            roles = UserRole.by_domain(self.domain)
            self.fields['role_id'].choices = [('', _('All Roles'))] + [
                (role._id, role.name or _('(No Name)')) for role in roles]

        self.fields['domains'].choices = [(self.domain, self.domain)]
        if len(DomainPermissionsMirror.mirror_domains(self.domain)) > 0:
            self.fields['domains'].choices = [('all_project_spaces', _('All Project Spaces'))] + \
                                             [(self.domain, self.domain)] + \
                                             [(domain, domain) for domain in
                                              DomainPermissionsMirror.mirror_domains(self.domain)]
        self.helper = FormHelper()
        self.helper.form_method = 'GET'
        self.helper.form_id = 'user-filters'
        self.helper.form_class = 'form-horizontal'
        self.helper.form_action = reverse('download_commcare_users', args=[self.domain])

        self.helper.label_class = 'col-sm-3 col-md-2'
        self.helper.field_class = 'col-sm-9 col-md-8 col-lg-6'
        self.helper.form_text_inline = True

        self.helper.layout = crispy.Layout(
            crispy.Fieldset(
                _("Filter and Download Users"),
                crispy.Field('role_id', css_class="hqwebapp-select2"),
                crispy.Field('search_string'),
                crispy.Field('location_id'),
                crispy.Field('columns'),
                crispy.Field('domains'),
            ),
            hqcrispy.FormActions(
                twbscrispy.StrictButton(
                    _("Download All Users"),
                    type="submit",
                    css_class="btn btn-primary submit_button",
                )
            ),
        )
    def setUp(self):
        super(TestUserRoleSubscriptionChanges, self).setUp()
        self.domain = Domain(
            name="test-sub-changes",
            is_active=True,
        )
        self.domain.save()
        self.other_domain = Domain(
            name="other-domain",
            is_active=True,
        )
        self.other_domain.save()
        UserRole.init_domain_with_presets(self.domain.name)
        self.user_roles = UserRole.by_domain(self.domain.name)
        self.custom_role = UserRole.get_or_create_with_permissions(
            self.domain.name,
            Permissions(
                edit_apps=True,
                edit_web_users=True,
                view_web_users=True,
                view_roles=True,
            ), "Custom Role")
        self.custom_role.save()
        self.read_only_role = UserRole.get_read_only_role_by_domain(
            self.domain.name)

        self.admin_username = generator.create_arbitrary_web_user_name()

        self.web_users = []
        self.commcare_users = []
        for role in [self.custom_role] + self.user_roles:
            web_user = WebUser.create(
                self.other_domain.name,
                generator.create_arbitrary_web_user_name(), 'test123', None,
                None)
            web_user.is_active = True
            web_user.add_domain_membership(self.domain.name,
                                           role_id=role.get_id)
            web_user.save()
            self.web_users.append(web_user)

            commcare_user = generator.arbitrary_commcare_user(
                domain=self.domain.name)
            commcare_user.set_role(self.domain.name, role.get_qualified_id())
            commcare_user.save()
            self.commcare_users.append(commcare_user)

        self.account = BillingAccount.get_or_create_account_by_domain(
            self.domain.name, created_by=self.admin_username)[0]
        self.advanced_plan = DefaultProductPlan.get_default_plan_version(
            edition=SoftwarePlanEdition.ADVANCED)
예제 #27
0
    def user_roles(self):
        user_roles = [AdminUserRole(domain=self.domain)]
        user_roles.extend(sorted(
            UserRole.by_domain(self.domain),
            key=lambda role: role.name if role.name else u'\uFFFF'
        ))

        # skip the admin role since it's not editable
        for role in user_roles[1:]:
            role.hasUsersAssigned = bool(role.ids_of_assigned_users)
            role.has_unpermitted_location_restriction = (
                not self.can_restrict_access_by_location
                and not role.permissions.access_all_locations
            )
        return user_roles
예제 #28
0
def update_user_roles(domain_link):
    if domain_link.is_remote:
        master_results = remote_get_user_roles(domain_link)
    else:
        master_results = local_get_user_roles(domain_link.master_domain)

    _convert_reports_permissions(domain_link, master_results)

    local_roles = UserRole.by_domain(domain_link.linked_domain,
                                     include_archived=True)
    local_roles_by_name = {}
    local_roles_by_upstream_id = {}
    for role in local_roles:
        local_roles_by_name[role.name] = role
        if role.upstream_id:
            local_roles_by_upstream_id[role.upstream_id] = role

    # Update downstream roles based on upstream roles
    for role_def in master_results:
        role = local_roles_by_upstream_id.get(
            role_def['_id']) or local_roles_by_name.get(role_def['name'])
        if role:
            role_json = role.to_json()
        else:
            role_json = {'domain': domain_link.linked_domain}
        role_json['upstream_id'] = role_def['_id']

        upstream_role = copy(role_def)
        upstream_role.pop('_id')
        upstream_role.pop('upstream_id')
        role_json.update(upstream_role)
        local_roles_by_upstream_id[role_json['upstream_id']] = role_json
        UserRole.wrap(role_json).save()

    # Update assignable_by ids - must be done after main update to guarantee all local roles have ids
    for role in local_roles_by_upstream_id.values():
        if role['assignable_by']:
            role['assignable_by'] = [
                local_roles_by_upstream_id[role_id]['_id']
                for role_id in role['assignable_by']
            ]
            UserRole.wrap(role).save()
예제 #29
0
def web_users(request, domain, template="users/web_users.html"):
    context = _users_context(request, domain)
    user_roles = [AdminUserRole(domain=domain)]
    user_roles.extend(sorted(UserRole.by_domain(domain), key=lambda role: role.name if role.name else u'\uFFFF'))

    role_labels = {}
    for r in user_roles:
        key = 'user-role:%s' % r.get_id if r.get_id else r.get_qualified_id()
        role_labels[key] = r.name

    invitations = DomainInvitation.by_domain(domain)
    for invitation in invitations:
        invitation.role_label = role_labels.get(invitation.role, "")

    context.update({
        'user_roles': user_roles,
        'default_role': UserRole.get_default(),
        'report_list': get_possible_reports(domain),
        'invitations': invitations
    })
    return render(request, template, context)
예제 #30
0
def web_users(request, domain, template="users/web_users.html"):
    context = _users_context(request, domain)
    user_roles = [AdminUserRole(domain=domain)]
    user_roles.extend(sorted(UserRole.by_domain(domain), key=lambda role: role.name if role.name else u'\uFFFF'))

    role_labels = {}
    for r in user_roles:
        key = 'user-role:%s' % r.get_id if r.get_id else r.get_qualified_id()
        role_labels[key] = r.name

    invitations = DomainInvitation.by_domain(domain)
    for invitation in invitations:
        invitation.role_label = role_labels.get(invitation.role, "")

    context.update({
        'user_roles': user_roles,
        'default_role': UserRole.get_default(),
        'report_list': get_possible_reports(domain),
        'invitations': invitations
    })
    return render(request, template, context)
예제 #31
0
파일: views.py 프로젝트: ekush/commcare-hq
def orgs_team_members(request,
                      org,
                      team_id,
                      template="orgs/orgs_team_members.html"):
    ctxt = base_context(request, request.organization)
    ctxt["tab"] = "teams"

    try:
        team = Team.get(team_id)
    except ResourceNotFound:
        raise Http404("Team %s does not exist" % team_id)

    team_members = team.get_members()
    team_members.sort(key=lambda user: user.username)

    #inspect the domains of the team
    domain_names = team.get_domains()
    team_domains = list()
    for name in domain_names:
        team_domains.append([
            Domain.get_by_name(name),
            team.role_label(domain=name),
            UserRole.by_domain(name)
        ])

    nonmembers = filter(
        lambda m: m.username not in [tm.username for tm in team_members],
        ctxt["members"])
    nondomains = filter(
        lambda d: d.name not in [td[0].name for td in team_domains],
        ctxt["domains"])

    ctxt.update(
        dict(team=team,
             team_members=team_members,
             nonmembers=nonmembers,
             team_domains=team_domains,
             nondomains=nondomains))
    return render(request, template, ctxt)
예제 #32
0
파일: forms.py 프로젝트: OmairK/commcare-hq
    def __init__(self, *args, **kwargs):
        from corehq.apps.locations.forms import LocationSelectWidget
        self.domain = kwargs.pop('domain')
        super(CommCareUserFilterForm, self).__init__(*args, **kwargs)
        self.fields['location_id'].widget = LocationSelectWidget(self.domain)
        self.fields[
            'location_id'].help_text = ExpandedMobileWorkerFilter.location_search_help

        roles = UserRole.by_domain(self.domain)
        self.fields['role_id'].choices = [('', _('All Roles'))] + [
            (role._id, role.name or _('(No Name)')) for role in roles
        ]

        self.helper = FormHelper()
        self.helper.form_method = 'GET'
        self.helper.form_id = 'user-filters'
        self.helper.form_class = 'form-horizontal'
        self.helper.form_action = reverse('download_commcare_users',
                                          args=[self.domain])

        self.helper.label_class = 'col-sm-3 col-md-2'
        self.helper.field_class = 'col-sm-9 col-md-8 col-lg-6'
        self.helper.form_text_inline = True

        self.helper.layout = crispy.Layout(
            crispy.Fieldset(
                _("Filter and Download Users"),
                crispy.Field('role_id', css_class="hqwebapp-select2"),
                crispy.Field('search_string'),
                crispy.Field('location_id'),
                crispy.Field('columns'),
            ),
            hqcrispy.FormActions(
                twbscrispy.StrictButton(
                    _("Download All Users"),
                    type="submit",
                    css_class="btn btn-primary submit_button",
                )),
        )
예제 #33
0
def num_location_restricted_roles(domain):
    roles = [
        r for r in UserRole.by_domain(domain)
        if not r.permissions.access_all_locations
    ]
    return len(roles)
예제 #34
0
def create_or_update_users_and_groups(domain,
                                      user_specs,
                                      group_memoizer=None,
                                      update_progress=None):
    ret = {"errors": [], "rows": []}

    group_memoizer = group_memoizer or GroupMemoizer(domain)
    group_memoizer.load_all()

    current = 0

    can_assign_locations = domain_has_privilege(domain, privileges.LOCATIONS)
    if can_assign_locations:
        location_cache = SiteCodeToLocationCache(domain)

    domain_obj = Domain.get_by_name(domain)
    allowed_group_names = [group.name for group in group_memoizer.groups]
    roles_by_name = {role.name: role for role in UserRole.by_domain(domain)}
    validators = get_user_import_validators(domain_obj, user_specs,
                                            allowed_group_names,
                                            list(roles_by_name))
    try:
        for row in user_specs:
            if update_progress:
                update_progress(current)
                current += 1

            username = row.get('username')
            status_row = {
                'username': username,
                'row': row,
            }

            try:
                for validator in 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', '')

            try:
                username = normalize_username(str(username),
                                              domain) if username else None
                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')

                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:
                        raise UserUploadError(
                            _(f"You can only set 'Is Account Confirmed' to 'False' on a new User."
                              ))

                    if is_password(password):
                        user.set_password(password)
                    status_row['flag'] = 'updated'
                else:
                    kwargs = {}
                    if is_account_confirmed is not None:
                        kwargs['is_account_confirmed'] = is_account_confirmed
                    user = CommCareUser.create(domain,
                                               username,
                                               password,
                                               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 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, 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:
                    user.set_role(domain,
                                  roles_by_name[role].get_qualified_id())

                user.save()

                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 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:
                    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:
            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
예제 #35
0
 def tearDown(self):
     for role in UserRole.by_domain(self.linked_domain):
         role.delete()
     super(TestUpdateRoles, self).tearDown()
예제 #36
0
def num_location_restricted_roles(domain):
    roles = [r for r in UserRole.by_domain(domain)
             if not r.permissions.access_all_locations]
    return len(roles)
예제 #37
0
 def tearDown(self):
     for role in UserRole.by_domain(self.linked_domain):
         role.delete()
     super(TestUpdateRoles, self).tearDown()
예제 #38
0
def create_or_update_users_and_groups(domain, user_specs, group_specs, task=None):
    from corehq.apps.users.views.mobile.custom_data_fields import UserFieldsView
    custom_data_validator = UserFieldsView.get_validator(domain)
    ret = {"errors": [], "rows": []}
    total = len(user_specs) + len(group_specs)

    def _set_progress(progress):
        if task is not None:
            DownloadBase.set_progress(task, progress, total)

    group_memoizer = create_or_update_groups(domain, group_specs, log=ret)
    current = len(group_specs)

    usernames = set()
    user_ids = set()
    allowed_groups = set(group_memoizer.groups)
    allowed_group_names = [group.name for group in allowed_groups]
    allowed_roles = UserRole.by_domain(domain)
    roles_by_name = {role.name: role for role in allowed_roles}
    can_assign_locations = domain_has_privilege(domain, privileges.LOCATIONS)
    if can_assign_locations:
        location_cache = SiteCodeToLocationCache(domain)
    domain_obj = Domain.get_by_name(domain)
    usernames_with_dupe_passwords = users_with_duplicate_passwords(user_specs)

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

            data = row.get('data')
            email = row.get('email')
            group_names = list(map(six.text_type, 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')
            username = row.get('username')
            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', '')

            if password:
                password = six.text_type(password)
            try:
                username = normalize_username(six.text_type(username), domain)
            except TypeError:
                username = None
            except ValidationError:
                ret['rows'].append({
                    'username': username,
                    'row': row,
                    'flag': _('username cannot contain spaces or symbols'),
                })
                continue
            status_row = {
                'username': raw_username(username) if username else None,
                'row': row,
            }

            is_active = row.get('is_active')
            if isinstance(is_active, six.string_types):
                soft_assert_type_text(is_active)
                try:
                    is_active = string_to_boolean(is_active) if is_active else None
                except ValueError:
                    ret['rows'].append({
                        'username': username,
                        'row': row,
                        'flag': _("'is_active' column can only contain 'true' or 'false'"),
                    })
                    continue

            if username in usernames or user_id in user_ids:
                status_row['flag'] = 'repeat'
            elif not username and not user_id:
                status_row['flag'] = 'missing-data'
            else:
                try:
                    if username:
                        usernames.add(username)
                    if user_id:
                        user_ids.add(user_id)
                    if user_id:
                        user = CommCareUser.get_by_user_id(user_id, domain)
                    else:
                        user = CommCareUser.get_by_username(username)

                    if domain_obj.strong_mobile_passwords and is_password(password):
                        if raw_username(username) in usernames_with_dupe_passwords:
                            raise UserUploadError(_("Provide a unique password for each mobile worker"))

                        try:
                            clean_password(password)
                        except forms.ValidationError:
                            if settings.ENABLE_DRACONIAN_SECURITY_FEATURES:
                                msg = _("Mobile Worker passwords must be 8 "
                                    "characters long with at least 1 capital "
                                    "letter, 1 special character and 1 number")
                            else:
                                msg = _("Please provide a stronger password")
                            raise UserUploadError(msg)

                    if user:
                        if user.domain != domain:
                            raise UserUploadError(_(
                                'User with username %(username)r is '
                                'somehow in domain %(domain)r'
                            ) % {'username': user.username, 'domain': user.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})
                        if is_password(password):
                            user.set_password(password)
                        status_row['flag'] = 'updated'
                    else:
                        max_username_length = get_mobile_worker_max_username_length(domain)
                        if len(raw_username(username)) > max_username_length:
                            ret['rows'].append({
                                'username': username,
                                'row': row,
                                'flag': _("username cannot contain greater than %d characters" %
                                          max_username_length)
                            })
                            continue
                        if not is_password(password):
                            raise UserUploadError(_("Cannot create a new user with a blank password"))
                        user = CommCareUser.create(domain, username, password, commit=False)
                        status_row['flag'] = 'created'
                    if phone_number:
                        user.add_phone_number(_fmt_phone(phone_number), default=True)
                    if name:
                        user.set_full_name(six.text_type(name))
                    if data:
                        error = custom_data_validator(data)
                        if error:
                            raise UserUploadError(error)
                        user.user_data.update(data)
                    if uncategorized_data:
                        user.user_data.update(uncategorized_data)
                    if language:
                        user.language = language
                    if email:
                        try:
                            validate_email(email)
                        except ValidationError:
                            raise UserUploadError(_("User has an invalid email address"))

                        user.email = email.lower()
                    if is_active is not None:
                        user.is_active = is_active

                    if 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, location_cache)
                            location_ids.append(loc.location_id)

                    if role:
                        if role in roles_by_name:
                            user.set_role(domain, roles_by_name[role].get_qualified_id())
                        else:
                            raise UserUploadError(_(
                                "Role '%s' does not exist"
                            ) % role)

                    if can_assign_locations:
                        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)

                    user.save()

                    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_id in Group.by_user(user, wrap=False):
                        group = group_memoizer.get(group_id)
                        if group.name not in group_names:
                            group.remove_user(user)

                    for group_name in group_names:
                        if group_name not in allowed_group_names:
                            raise UserUploadError(_(
                                "Can't add to group '%s' "
                                "(try adding it to your spreadsheet)"
                            ) % group_name)
                        group_memoizer.by_name(group_name).add_user(user, save=False)

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

            ret["rows"].append(status_row)
    finally:
        try:
            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)

    _set_progress(total)
    return ret
예제 #39
0
def get_domain_info(domain,
                    upload_domain,
                    user_specs,
                    domain_info_by_domain,
                    upload_user=None,
                    group_memoizer=None,
                    is_web_upload=False):
    from corehq.apps.users.views.mobile.custom_data_fields import UserFieldsView
    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
    ]
    profiles_by_name = {}
    domain_user_specs = [
        spec for spec in user_specs
        if spec.get('domain', upload_domain) == domain
    ]
    if is_web_upload:
        roles_by_name = {
            role[1]: role[0]
            for role in get_editable_role_choices(
                domain, upload_user, allow_admin_role=True)
        }
        validators = get_user_import_validators(
            Domain.get_by_name(domain),
            domain_user_specs,
            True,
            allowed_roles=list(roles_by_name),
            upload_domain=upload_domain,
        )
    else:
        roles_by_name = {
            role.name: role
            for role in UserRole.by_domain(domain)
        }
        definition = CustomDataFieldsDefinition.get(domain,
                                                    UserFieldsView.field_type)
        if definition:
            profiles_by_name = {
                profile.name: profile
                for profile in definition.get_profiles()
            }
        validators = get_user_import_validators(domain_obj, domain_user_specs,
                                                False, allowed_group_names,
                                                list(roles_by_name),
                                                list(profiles_by_name),
                                                upload_domain)

    domain_info = DomainInfo(validators, can_assign_locations, location_cache,
                             roles_by_name, profiles_by_name,
                             domain_group_memoizer)
    domain_info_by_domain[domain] = domain_info
    return domain_info
예제 #40
0
def create_or_update_users_and_groups(domain,
                                      user_specs,
                                      group_specs,
                                      task=None):
    from corehq.apps.users.views.mobile.custom_data_fields import UserFieldsView
    custom_data_validator = UserFieldsView.get_validator(domain)
    ret = {"errors": [], "rows": []}
    total = len(user_specs) + len(group_specs)

    def _set_progress(progress):
        if task is not None:
            DownloadBase.set_progress(task, progress, total)

    group_memoizer = create_or_update_groups(domain, group_specs, log=ret)
    current = len(group_specs)

    usernames = set()
    user_ids = set()
    allowed_groups = set(group_memoizer.groups)
    allowed_group_names = [group.name for group in allowed_groups]
    allowed_roles = UserRole.by_domain(domain)
    roles_by_name = {role.name: role for role in allowed_roles}
    can_assign_locations = domain_has_privilege(domain, privileges.LOCATIONS)
    if can_assign_locations:
        location_cache = SiteCodeToLocationCache(domain)
    domain_obj = Domain.get_by_name(domain)
    usernames_with_dupe_passwords = users_with_duplicate_passwords(user_specs)

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

            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')
            username = row.get('username')
            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', '')

            if password:
                password = str(password)
            try:
                username = normalize_username(str(username), domain)
            except TypeError:
                username = None
            except ValidationError:
                ret['rows'].append({
                    'username':
                    username,
                    'row':
                    row,
                    'flag':
                    _('username cannot contain spaces or symbols'),
                })
                continue
            status_row = {
                'username': raw_username(username) if username else None,
                'row': row,
            }

            is_active = row.get('is_active')
            if isinstance(is_active, str):
                try:
                    is_active = string_to_boolean(
                        is_active) if is_active else None
                except ValueError:
                    ret['rows'].append({
                        'username':
                        username,
                        'row':
                        row,
                        'flag':
                        _("'is_active' column can only contain 'true' or 'false'"
                          ),
                    })
                    continue

            if username in usernames or user_id in user_ids:
                status_row['flag'] = 'repeat'
            elif not username and not user_id:
                status_row['flag'] = 'missing-data'
            else:
                try:
                    if username:
                        usernames.add(username)
                    if user_id:
                        user_ids.add(user_id)
                    if user_id:
                        user = CommCareUser.get_by_user_id(user_id, domain)
                    else:
                        user = CommCareUser.get_by_username(username)

                    if domain_obj.strong_mobile_passwords and is_password(
                            password):
                        if raw_username(
                                username) in usernames_with_dupe_passwords:
                            raise UserUploadError(
                                _("Provide a unique password for each mobile worker"
                                  ))

                        try:
                            clean_password(password)
                        except forms.ValidationError:
                            if settings.ENABLE_DRACONIAN_SECURITY_FEATURES:
                                msg = _(
                                    "Mobile Worker passwords must be 8 "
                                    "characters long with at least 1 capital "
                                    "letter, 1 special character and 1 number")
                            else:
                                msg = _("Please provide a stronger password")
                            raise UserUploadError(msg)

                    if user:
                        if user.domain != domain:
                            raise UserUploadError(
                                _('User with username %(username)r is '
                                  'somehow in domain %(domain)r') % {
                                      'username': user.username,
                                      'domain': user.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
                                  })
                        if is_password(password):
                            user.set_password(password)
                        status_row['flag'] = 'updated'
                    else:
                        max_username_length = get_mobile_worker_max_username_length(
                            domain)
                        if len(raw_username(username)) > max_username_length:
                            ret['rows'].append({
                                'username':
                                username,
                                'row':
                                row,
                                'flag':
                                _("username cannot contain greater than %d characters"
                                  % max_username_length)
                            })
                            continue
                        if not is_password(password):
                            raise UserUploadError(
                                _("Cannot create a new user with a blank password"
                                  ))
                        user = CommCareUser.create(domain,
                                                   username,
                                                   password,
                                                   commit=False)
                        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:
                        error = custom_data_validator(data)
                        if error:
                            raise UserUploadError(error)
                        user.user_data.update(data)
                    if uncategorized_data:
                        user.user_data.update(uncategorized_data)
                    if language:
                        user.language = language
                    if email:
                        try:
                            validate_email(email)
                        except ValidationError:
                            raise UserUploadError(
                                _("User has an invalid email address"))

                        user.email = email.lower()
                    if is_active is not None:
                        user.is_active = is_active

                    if 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, location_cache)
                            location_ids.append(loc.location_id)

                    if role:
                        if role in roles_by_name:
                            user.set_role(
                                domain, roles_by_name[role].get_qualified_id())
                        else:
                            raise UserUploadError(
                                _("Role '%s' does not exist") % role)

                    if can_assign_locations:
                        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)

                    user.save()

                    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_id in Group.by_user_id(user.user_id, wrap=False):
                        group = group_memoizer.get(group_id)
                        if group.name not in group_names:
                            group.remove_user(user)

                    for group_name in group_names:
                        if group_name not in allowed_group_names:
                            raise UserUploadError(
                                _("Can't add to group '%s' "
                                  "(try adding it to your spreadsheet)") %
                                group_name)
                        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:
            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)

    _set_progress(total)
    return ret
예제 #41
0
 def user_roles(self):
     user_roles = [AdminUserRole(domain=self.domain)]
     user_roles.extend(sorted(UserRole.by_domain(self.domain),
                              key=lambda role: role.name if role.name else u'\uFFFF'))
     return user_roles
예제 #42
0
    def setUpClass(cls):
        super(AllCommCareUsersTest, cls).setUpClass()
        delete_all_users()
        hard_delete_deleted_users()
        cls.ccdomain = Domain(name='cc_user_domain')
        cls.ccdomain.save()
        cls.other_domain = Domain(name='other_domain')
        cls.other_domain.save()
        bootstrap_location_types(cls.ccdomain.name)

        UserRole.init_domain_with_presets(cls.ccdomain.name)
        cls.user_roles = UserRole.by_domain(cls.ccdomain.name)
        cls.custom_role = UserRole.get_or_create_with_permissions(
            cls.ccdomain.name,
            Permissions(
                edit_apps=True,
                edit_web_users=True,
                view_web_users=True,
                view_roles=True,
            ), "Custom Role")
        cls.custom_role.save()

        cls.loc1 = make_loc('spain', domain=cls.ccdomain.name, type="district")
        cls.loc2 = make_loc('madagascar',
                            domain=cls.ccdomain.name,
                            type="district")

        cls.ccuser_1 = CommCareUser.create(
            domain=cls.ccdomain.name,
            username='******',
            password='******',
            created_by=None,
            created_via=None,
            email='*****@*****.**',
        )
        cls.ccuser_1.set_location(cls.loc1)
        cls.ccuser_1.save()
        cls.ccuser_2 = CommCareUser.create(
            domain=cls.ccdomain.name,
            username='******',
            password='******',
            created_by=None,
            created_via=None,
            email='*****@*****.**',
        )
        cls.ccuser_2.set_role(cls.ccdomain.name,
                              cls.custom_role.get_qualified_id())
        cls.ccuser_2.set_location(cls.loc2)
        cls.ccuser_2.save()

        cls.web_user = WebUser.create(
            domain=cls.ccdomain.name,
            username='******',
            password='******',
            created_by=None,
            created_via=None,
            email='*****@*****.**',
        )
        cls.ccuser_other_domain = CommCareUser.create(
            domain=cls.other_domain.name,
            username='******',
            password='******',
            created_by=None,
            created_via=None,
            email='*****@*****.**',
        )
        cls.retired_user = CommCareUser.create(
            domain=cls.ccdomain.name,
            username='******',
            password='******',
            created_by=None,
            created_via=None,
            email='*****@*****.**',
        )
        cls.retired_user.retire(deleted_by=None)
예제 #43
0
def get_user_roles(domain):
    def _to_json(role):
        return _clean_json(role.to_json())

    return [_to_json(role) for role in UserRole.by_domain(domain)]