コード例 #1
0
ファイル: forms.py プロジェクト: puttarajubr/commcare-hq
    def clean(self):
        try:
            password = self.cleaned_data['password']
            password_2 = self.cleaned_data['password_2']
        except KeyError:
            pass
        else:
            if password != password_2:
                raise forms.ValidationError("Passwords do not match")
            if self.password_format == 'n' and not password.isnumeric():
                raise forms.ValidationError("Password is not numeric")

        try:
            username = self.cleaned_data['username']
        except KeyError:
            pass
        else:
            if len(username) > CommCareAccountForm.max_len_username:
                raise forms.ValidationError(
                    "Username %s is too long.  Must be under %d characters."
                    % (username, CommCareAccountForm.max_len_username))
            validate_username('*****@*****.**' % username)
            domain = self.cleaned_data['domain']
            username = format_username(username, domain)
            num_couch_users = len(CouchUser.view("users/by_username",
                                                 key=username,
                                                 reduce=False))
            if num_couch_users > 0:
                raise forms.ValidationError("CommCare user already exists")

            # set the cleaned username to [email protected]
            self.cleaned_data['username'] = username
        return self.cleaned_data
コード例 #2
0
    def clean(self):
        try:
            password = self.cleaned_data['password']
            password_2 = self.cleaned_data['password_2']
        except KeyError:
            pass
        else:
            if password != password_2:
                raise forms.ValidationError("Passwords do not match")
            if self.password_format == 'n' and not password.isnumeric():
                raise forms.ValidationError("Password is not numeric")

        try:
            username = self.cleaned_data['username']
        except KeyError:
            pass
        else:
            if len(username) > CommCareAccountForm.max_len_username:
                raise forms.ValidationError(
                    "Username %s is too long.  Must be under %d characters." %
                    (username, CommCareAccountForm.max_len_username))
            validate_username('*****@*****.**' % username)
            domain = self.cleaned_data['domain']
            username = format_username(username, domain)
            num_couch_users = len(
                CouchUser.view("users/by_username", key=username))
            if num_couch_users > 0:
                raise forms.ValidationError("CommCare user already exists")

            # set the cleaned username to [email protected]
            self.cleaned_data['username'] = username
        return self.cleaned_data
コード例 #3
0
ファイル: utils.py プロジェクト: ekush/commcare-hq
def handle_changed_mailchimp_email(user, old_email, new_email):
    """
        Checks whether there are other users with old_email who are also subscribed to any mailchimp lists.
        If not, it safely unsubscribes that email from mailchimp. Then, adds new_email to mailchimp.
    """
    users_with_old_email = User.objects.filter(email=old_email).values_list('username', flat=True)

    couch_users = CouchUser.view('users/by_username',
                                 keys=list(users_with_old_email),
                                 include_docs=True,
                                 reduce=False,
                                 ).all()

    if user.subscribed_to_commcare_users:
        users_subscribed_with_old_email = [couch_user.get_id for couch_user in couch_users
                                           if couch_user.subscribed_to_commcare_users]
        if (len(users_subscribed_with_old_email) == 1 and users_subscribed_with_old_email[0] == user.get_id):
            safe_unsubscribe_user_from_mailchimp_list(user, settings.MAILCHIMP_COMMCARE_USERS_ID, email=old_email)

    if not user.email_opt_out:
        users_subscribed_with_old_email = [couch_user.get_id for couch_user in couch_users
                                           if not couch_user.email_opt_out]
        if (len(users_subscribed_with_old_email) == 1 and users_subscribed_with_old_email[0] == user.get_id):
            safe_unsubscribe_user_from_mailchimp_list(user, settings.MAILCHIMP_MASS_EMAIL_ID, email=old_email)

    # subscribe new_email to lists
    if user.subscribed_to_commcare_users:
        safe_subscribe_user_to_mailchimp_list(user, settings.MAILCHIMP_COMMCARE_USERS_ID, email=new_email)
    if not user.email_opt_out:
        safe_subscribe_user_to_mailchimp_list(user, settings.MAILCHIMP_MASS_EMAIL_ID, email=new_email)
コード例 #4
0
def group_members(request,
                  domain,
                  group_id,
                  template="groups/group_members.html"):
    context = _users_context(request, domain)
    all_groups = _get_sorted_groups(domain)
    try:
        group = Group.get(group_id)
    except ResourceNotFound:
        raise Http404("Group %s does not exist" % group_id)
    member_ids = group.get_user_ids()
    members = CouchUser.view("_all_docs", keys=member_ids,
                             include_docs=True).all()
    members.sort(key=lambda user: user.username)
    all_users = CommCareUser.by_domain(domain)
    member_ids = set(member_ids)
    nonmembers = [user for user in all_users if user.user_id not in member_ids]

    context.update({
        "domain": domain,
        "group": group,
        "all_groups": all_groups,
        "members": members,
        "nonmembers": nonmembers,
    })
    return render(request, template, context)
コード例 #5
0
ファイル: log.py プロジェクト: NoahCarnahan/commcare-hq
 def get_user_id(self, username, domain):
     cc_username = format_username(username, domain)
     result = CouchUser.view(
         'users/by_username',
         key=cc_username,
         include_docs=False,
     )
     row = result.one()
     if row:
         return row["id"]
コード例 #6
0
def run():
    users = CouchUser.view('users/all_users', include_docs=True)
    for user in users:
        save = False
        for dm in user.web_account.domain_memberships:
            if not dm.is_admin:
                save = True
                user.set_permission(dm.domain, OldPermissions.EDIT_APPS, True, save=False)
        if save:
            user.save()
コード例 #7
0
 def get_user_id(self, username, domain):
     cc_username = format_username(username, domain)
     result = CouchUser.view(
         'users/by_username',
         key=cc_username,
         include_docs=False,
         reduce=False,
     )
     row = result.one()
     if row:
         return row["id"]
コード例 #8
0
def get_user_id_by_username(username):
    result = CouchUser.view(
        'users/by_username',
        key=username,
        include_docs=False,
        reduce=False,
        stale=stale_ok(),
    )
    row = result.one()
    if row:
        return row["id"]
    return None
コード例 #9
0
ファイル: couch_users.py プロジェクト: ye-man/commcare-hq
def get_user_id_and_doc_type_by_domain(domain):
    key = ['active', domain]
    return [
        {"id": u['id'], "doc_type":u['key'][2]}
        for u in CouchUser.view(
            'users/by_domain',
            reduce=False,
            startkey=key,
            endkey=key + [{}],
            include_docs=False,
        ).all()
    ]
コード例 #10
0
ファイル: couch_users.py プロジェクト: ansarbek/commcare-hq
def get_user_id_by_username(username):
    result = CouchUser.view(
        'users/by_username',
        key=username,
        include_docs=False,
        reduce=False,
        stale=stale_ok(),
    )
    row = result.one()
    if row:
        return row["id"]
    return None
コード例 #11
0
def run():
    users = CouchUser.view('users/all_users', include_docs=True)
    for user in users:
        save = False
        for dm in user.web_account.domain_memberships:
            if not dm.is_admin:
                save = True
                user.set_permission(dm.domain,
                                    OldPermissions.EDIT_APPS,
                                    True,
                                    save=False)
        if save:
            user.save()
コード例 #12
0
ファイル: views.py プロジェクト: kennknowles/commcare-hq
def get_sms_autocomplete_context(request, domain):
    """A helper view for sms autocomplete"""
    phone_users = CouchUser.view("users/phone_users_by_domain",
        startkey=[domain], endkey=[domain, {}], include_docs=True
    )
    groups = Group.view("groups/by_domain", key=domain, include_docs=True)

    contacts = ["[send to all]"]
    contacts.extend(['%s [group]' % group.name for group in groups])
    user_id = None
    for user in phone_users:
        if user._id == user_id:
            continue
        contacts.append(user.username)
        user_id = user._id
    return {"sms_contacts": contacts}
コード例 #13
0
ファイル: views.py プロジェクト: tsinkala/commcare-hq
def get_sms_autocomplete_context(request, domain):
    """A helper view for sms autocomplete"""
    phone_users = CouchUser.view("users/phone_users_by_domain",
                                 startkey=[domain],
                                 endkey=[domain, {}],
                                 include_docs=True)
    groups = Group.view("groups/by_domain", key=domain, include_docs=True)

    contacts = ["[send to all]"]
    contacts.extend(['%s [group]' % group.name for group in groups])
    user_id = None
    for user in phone_users:
        if user._id == user_id:
            continue
        contacts.append(user.username)
        user_id = user._id
    return {"sms_contacts": contacts}
コード例 #14
0
ファイル: utils.py プロジェクト: ekush/commcare-hq
def handle_changed_mailchimp_email(user, old_email, new_email):
    """
        Checks whether there are other users with old_email who are also subscribed to any mailchimp lists.
        If not, it safely unsubscribes that email from mailchimp. Then, adds new_email to mailchimp.
    """
    users_with_old_email = User.objects.filter(email=old_email).values_list(
        'username', flat=True)

    couch_users = CouchUser.view(
        'users/by_username',
        keys=list(users_with_old_email),
        include_docs=True,
        reduce=False,
    ).all()

    if user.subscribed_to_commcare_users:
        users_subscribed_with_old_email = [
            couch_user.get_id for couch_user in couch_users
            if couch_user.subscribed_to_commcare_users
        ]
        if (len(users_subscribed_with_old_email) == 1
                and users_subscribed_with_old_email[0] == user.get_id):
            safe_unsubscribe_user_from_mailchimp_list(
                user, settings.MAILCHIMP_COMMCARE_USERS_ID, email=old_email)

    if not user.email_opt_out:
        users_subscribed_with_old_email = [
            couch_user.get_id for couch_user in couch_users
            if not couch_user.email_opt_out
        ]
        if (len(users_subscribed_with_old_email) == 1
                and users_subscribed_with_old_email[0] == user.get_id):
            safe_unsubscribe_user_from_mailchimp_list(
                user, settings.MAILCHIMP_MASS_EMAIL_ID, email=old_email)

    # subscribe new_email to lists
    if user.subscribed_to_commcare_users:
        safe_subscribe_user_to_mailchimp_list(
            user, settings.MAILCHIMP_COMMCARE_USERS_ID, email=new_email)
    if not user.email_opt_out:
        safe_subscribe_user_to_mailchimp_list(user,
                                              settings.MAILCHIMP_MASS_EMAIL_ID,
                                              email=new_email)
コード例 #15
0
ファイル: api.py プロジェクト: sheelio/commcare-hq
def process_username(username, domain):
    """
    Loosely based on code from apps/users/forms.py:255
    """
    from corehq.apps.users.forms import validate_username

    max_len_username = 80
    if len(username) > max_len_username:
        raise forms.ValidationError(get_message(MSG_USERNAME_TOO_LONG, context=(username, max_len_username)))
    # Check if the username contains invalid characters w/ django checker
    validate_username('*****@*****.**' % username)
    username = format_username(username, domain)
    num_couch_users = len(CouchUser.view("users/by_username",
                                         key=username,
                                         reduce=False))
    if num_couch_users > 0:
        raise forms.ValidationError(get_message(MSG_DUPLICATE_USERNAME, context=(username,)))

    return username
コード例 #16
0
ファイル: groups.py プロジェクト: tsinkala/core-hq
def group_members(request, domain, group_id, template="groups/group_members.html"):
    context = _users_context(request, domain)
    all_groups = _get_sorted_groups(domain)
    group = Group.get(group_id)
    if group is None:
        raise Http404("Group %s does not exist" % group_id)
    member_ids = group.get_user_ids()
    members = CouchUser.view("_all_docs", keys=member_ids, include_docs=True).all()
    members.sort(key=lambda user: user.username)
    all_users = CommCareUser.by_domain(domain)
    member_ids = set(member_ids)
    nonmembers = [user for user in all_users if user.user_id not in member_ids]

    context.update({"domain": domain,
                    "group": group,
                    "all_groups": all_groups,
                    "members": members,
                    "nonmembers": nonmembers,
                    })
    return render(request, template, context)
コード例 #17
0
ファイル: api.py プロジェクト: ekush/commcare-hq
def process_username(username, domain):
    """
    Loosely based on code from apps/users/forms.py:255
    """
    from corehq.apps.users.forms import validate_username

    max_len_username = 80
    if len(username) > max_len_username:
        raise forms.ValidationError(
            get_message(MSG_USERNAME_TOO_LONG,
                        context=(username, max_len_username)))
    # Check if the username contains invalid characters w/ django checker
    validate_username('*****@*****.**' % username)
    username = format_username(username, domain)
    num_couch_users = len(
        CouchUser.view("users/by_username", key=username, reduce=False))
    if num_couch_users > 0:
        raise forms.ValidationError(
            get_message(MSG_DUPLICATE_USERNAME, context=(username, )))

    return username
コード例 #18
0
ファイル: views.py プロジェクト: kennknowles/commcare-hq
def send_to_recipients(request, domain):
    recipients = request.POST.get('recipients')
    message = request.POST.get('message')
    if not recipients:
        messages.error(request, _("You didn't specify any recipients"))
    elif not message:
        messages.error(request, _("You can't send an empty message"))
    else:
        recipients = [x.strip() for x in recipients.split(',') if x.strip()]
        phone_numbers = []
        # formats: GroupName (group), "Username", +15555555555
        group_names = []
        usernames = []
        phone_numbers = []

        unknown_usernames = []
        GROUP = "[group]"
        send_to_all_checked = False

        for recipient in recipients:
            if recipient == "[send to all]":
                send_to_all_checked = True
                phone_users = CouchUser.view("users/phone_users_by_domain",
                    startkey=[domain], endkey=[domain, {}], include_docs=True
                )
                for user in phone_users:
                    usernames.append(user.username)
                group_names = []
                break
            elif (not send_to_all_checked) and recipient.endswith(GROUP):
                name = recipient[:-len(GROUP)].strip()
                group_names.append(name)
            elif re.match(r'^\+\d+', recipient): # here we expect it to have a plus sign
                def wrap_user_by_type(u):
                    return getattr(user_models, u['doc']['doc_type']).wrap(u['doc'])

                phone_users = CouchUser.view("users/by_default_phone", # search both with and w/o the plus
                    keys=[recipient, recipient[1:]], include_docs=True,
                    wrapper=wrap_user_by_type).all()

                phone_users = filter(lambda u: u.is_member_of(domain), phone_users)
                if len(phone_users) > 0:
                    phone_numbers.append((phone_users[0], recipient))
                else:
                    phone_numbers.append((None, recipient))
            elif (not send_to_all_checked) and re.match(r'[\w\.]+', recipient):
                usernames.append(recipient)
            else:
                unknown_usernames.append(recipient)


        login_ids = dict([(r['key'], r['id']) for r in get_db().view("users/by_username", keys=usernames).all()])
        for username in usernames:
            if username not in login_ids:
                unknown_usernames.append(username)
        login_ids = login_ids.values()

        users = []
        empty_groups = []
        if len(group_names) > 0:
            users.extend(CouchUser.view('users/by_group', keys=[[domain, gn] for gn in group_names],
                                        include_docs=True).all())
            if len(users) == 0:
                empty_groups = group_names

        users.extend(CouchUser.view('_all_docs', keys=login_ids, include_docs=True).all())
        users = [user for user in users if user.is_active and not user.is_deleted()]

        phone_numbers.extend([(user, user.phone_number) for user in users])

        failed_numbers = []
        no_numbers = []
        sent = []
        for user, number in phone_numbers:
            if not number:
                no_numbers.append(user.raw_username)
            elif send_sms(domain, user.user_id if user else "", number, message):
                sent.append("%s" % (user.raw_username if user else number))
            else:
                failed_numbers.append("%s (%s)" % (
                    number,
                    user.raw_username if user else "<no username>"
                ))

        if empty_groups or failed_numbers or unknown_usernames or no_numbers:
            if empty_groups:
                messages.error(request, _("The following groups don't exist: ") + (', '.join(empty_groups)))
            if no_numbers:
                messages.error(request, _("The following users don't have phone numbers: ") + (', '.join(no_numbers)))
            if failed_numbers:
                messages.error(request, _("Couldn't send to the following number(s): ") + (', '.join(failed_numbers)))
            if unknown_usernames:
                messages.error(request, _("Couldn't find the following user(s): ") + (', '.join(unknown_usernames)))
            if sent:
                messages.success(request, _("Successfully sent: ") + (', '.join(sent)))
            else:
                messages.info(request, _("No messages were sent."))
        else:
            messages.success(request, _("Message sent"))

    return HttpResponseRedirect(
        request.META.get('HTTP_REFERER') or
        reverse(compose_message, args=[domain])
    )
コード例 #19
0
ファイル: views.py プロジェクト: tsinkala/commcare-hq
def send_to_recipients(request, domain):
    recipients = request.POST.get('recipients')
    message = request.POST.get('message')
    if not recipients:
        messages.error(request, "You didn't specify any recipients")
    elif not message:
        messages.error(request, "You can't send an empty message")
    else:
        recipients = [x.strip() for x in recipients.split(',') if x.strip()]
        phone_numbers = []
        # formats: GroupName (group), "Username", +15555555555
        group_names = []
        usernames = []
        phone_numbers = []

        unknown_usernames = []
        GROUP = "[group]"
        send_to_all_checked = False

        for recipient in recipients:
            if recipient == "[send to all]":
                send_to_all_checked = True
                phone_users = CouchUser.view("users/phone_users_by_domain",
                                             startkey=[domain],
                                             endkey=[domain, {}],
                                             include_docs=True)
                for user in phone_users:
                    usernames.append(user.username)
                group_names = []
                break
            elif (not send_to_all_checked) and recipient.endswith(GROUP):
                name = recipient[:-len(GROUP)].strip()
                group_names.append(name)
            elif re.match(r'^\+\d+',
                          recipient):  # here we expect it to have a plus sign

                def wrap_user_by_type(u):
                    return getattr(user_models,
                                   u['doc']['doc_type']).wrap(u['doc'])

                phone_users = CouchUser.view(
                    "users/by_default_phone",  # search both with and w/o the plus
                    keys=[recipient, recipient[1:]],
                    include_docs=True,
                    wrapper=wrap_user_by_type).all()

                phone_users = filter(lambda u: u.is_member_of(domain),
                                     phone_users)
                if len(phone_users) > 0:
                    phone_numbers.append((phone_users[0], recipient))
                else:
                    phone_numbers.append((None, recipient))
            elif (not send_to_all_checked) and re.match(r'[\w\.]+', recipient):
                usernames.append(recipient)
            else:
                unknown_usernames.append(recipient)

        login_ids = dict([
            (r['key'], r['id'])
            for r in get_db().view("users/by_username", keys=usernames).all()
        ])
        for username in usernames:
            if username not in login_ids:
                unknown_usernames.append(username)
        login_ids = login_ids.values()

        users = []
        empty_groups = []
        if len(group_names) > 0:
            users.extend(
                CouchUser.view('users/by_group',
                               keys=[[domain, gn] for gn in group_names],
                               include_docs=True).all())
            if len(users) == 0:
                empty_groups = group_names

        users.extend(
            CouchUser.view('_all_docs', keys=login_ids,
                           include_docs=True).all())
        users = [
            user for user in users if user.is_active and not user.is_deleted()
        ]

        phone_numbers.extend([(user, user.phone_number) for user in users])

        failed_numbers = []
        no_numbers = []
        sent = []
        for user, number in phone_numbers:
            if not number:
                no_numbers.append(user.raw_username)
            elif send_sms(domain, user.user_id if user else "", number,
                          message):
                sent.append("%s" % (user.raw_username if user else number))
            else:
                failed_numbers.append(
                    "%s (%s)" %
                    (number, user.raw_username if user else "<no username>"))

        if empty_groups or failed_numbers or unknown_usernames or no_numbers:
            if empty_groups:
                messages.error(
                    request, "The following groups don't exist: %s" %
                    (', '.join(empty_groups)))
            if no_numbers:
                messages.error(
                    request,
                    "The following users don't have phone numbers: %s" %
                    (', '.join(no_numbers)))
            if failed_numbers:
                messages.error(
                    request, "Couldn't send to the following number(s): %s" %
                    (', '.join(failed_numbers)))
            if unknown_usernames:
                messages.error(
                    request, "Couldn't find the following user(s): %s" %
                    (', '.join(unknown_usernames)))
            if sent:
                messages.success(request,
                                 "Successfully sent: %s" % (', '.join(sent)))
            else:
                messages.info(request, "No messages were sent.")
        else:
            messages.success(request, "Message sent")

    return HttpResponseRedirect(
        request.META.get('HTTP_REFERER')
        or reverse(compose_message, args=[domain]))
コード例 #20
0
ファイル: phone_users.py プロジェクト: dimagi/commcare-hq
 def testPhoneUsersViewNoNumberSet(self):
     phone_users_count = CouchUser.view("users/phone_users_by_domain", 
                                        key=self.domain).count()
     self.assertEquals(phone_users_count, 0)
コード例 #21
0
 def testPhoneUsersViewNoNumberSet(self):
     phone_users_count = CouchUser.view("users/phone_users_by_domain",
                                        key=self.domain).count()
     self.assertEqual(phone_users_count, 0)
コード例 #22
0
    def handle(self, *args, **options):
        django_domains = OldDomain.objects.all()
        django_domain_names = set([domain.name for domain in django_domains])
        couch_domain_names = set([x['key'][0] for x in get_db().view('domain/docs', group_level=1).all()])
        couch_user_domain_names = set([x['key'] for x in get_db().view('users/by_domain', group=True).all()])
        print get_db().view('users/by_domain').all()
        normalized_names = {}
        domains_that_need_to_change = set()


        # print some warnings if things are fishy
        for domain in couch_domain_names.union(couch_user_domain_names):
            if domain not in django_domain_names:
                print "Warning: domain '%s' not in SQL" % domain

            normalized = normalize_domain_name(domain)
            if normalized in normalized_names:
                print "Warning: domains '%s' and '%s' both exist" % (domain, normalized_names[normalized])
            normalized_names[normalized] = domain
            if normalized != domain:
                domains_that_need_to_change.add(domain)

        print "Going to change the following domains:"
        for domain in domains_that_need_to_change:
            print "    %s" % domain
        print
        if raw_input("Are you sure you want to continue? (Y/n)") != 'Y':
            print "Mission aborted"
            return

        print "Migrating SQL domains"
        for django_domain in django_domains:
            django_domain.name = normalize_domain_name(django_domain.name)
            django_domain.save()

        print "Migrating domains in Couch docs"
        class MyDoc(Document):
            class Meta:
                app_label = 'domain'
        def get_docs(domain):
            chunk_size = 500
            i = 0
            while True:
                docs = MyDoc.view('domain/docs',
                                  startkey=[domain], endkey=[domain, {}],
                                  reduce=False, include_docs=True, skip=i*chunk_size, limit=chunk_size)
                for doc in docs:
                    yield doc
                if not len(docs):
                    break
                i += 1
        for domain in domains_that_need_to_change:
            print "%s:" % domain
            for doc in get_docs(domain):
                print '.',
                if 'domain' in doc:
                    doc['domain'] = normalize_domain_name(doc['domain'])
                if 'domains' in doc:
                    for i,domain in enumerate(doc['domains']):
                        doc['domains'][i] = normalize_domain_name(doc['domains'][i])
                doc.save()
            print

        print "Patching users"
        for domain in domains_that_need_to_change:
            print '.',
            couch_users = CouchUser.view('users/by_domain', key=domain, include_docs=True, reduce=False)
            for user in couch_users:
                for dm in user.web_account.domain_memberships:
                    dm.domain = normalize_domain_name(dm.domain)
                for account in user.commcare_accounts:
                    if account.domain:
                        account.domain = normalize_domain_name(account.domain)
                user.save()