Example #1
0
 def test_get_wrapped_user(self):
     user = CommCareUser.create(self.domain, 'wrapped-user-test',
                                'password')
     user.save()
     self.addCleanup(user.delete)
     wrapped = get_wrapped_owner(user._id)
     self.assertTrue(isinstance(wrapped, CommCareUser))
Example #2
0
def is_valid_id(uploaded_id, domain, cache):
    if uploaded_id in cache:
        return cache[uploaded_id]

    owner = get_wrapped_owner(uploaded_id)
    return owner and is_user_or_case_sharing_group(
        owner) and owner.is_member_of(domain)
Example #3
0
    def id_to_choice_tuple(self, id_):
        for static_id, text in self.static_options:
            if (id_ == static_id[3:]
                    and static_id[:3] == "t__") or id_ == static_id:
                return (static_id, text)

        owner = get_wrapped_owner(id_, support_deleted=True)
        if isinstance(owner, Group):
            ret = self._group_to_choice_tuple(owner)
        elif isinstance(owner, SQLLocation):
            ret = self.location_tuple(owner)
        elif isinstance(owner, (CommCareUser, WebUser)):
            ret = self.user_tuple(owner)
        elif owner is None:
            return None
        else:
            raise Exception("Unexpcted id: {}".format(id_))

        if hasattr(owner, 'is_deleted'):
            if (callable(owner.is_deleted)
                    and owner.is_deleted()) or owner.is_deleted == True:
                # is_deleted may be an attr or callable depending on owner type
                ret = (ret[0], 'Deleted - ' + ret[1])

        return ret
Example #4
0
def is_valid_owner(owner_id):
    owner = get_wrapped_owner(owner_id)
    if not owner:
        return False
    if isinstance(owner, Group) and not owner.case_sharing:
        return False
    return True
Example #5
0
    def testRecursiveUpdates(self):
        parent_case = self._make_case(self.other_user._id, self.other_user._id)
        case = self._make_case(self.other_user._id, self.other_user._id,
                               index={'parent': ('parent-case', parent_case._id)})
        subcase1 = self._make_case(self.other_user._id, self.other_user._id,
                                   index={'parent': ('parent-case', case._id)})
        subcase2 = self._make_case(self.other_user._id, self.other_user._id,
                                   index={'parent': ('parent-case', case._id)})
        subsub1 = self._make_case(self.other_user._id, self.other_user._id,
                                  index={'parent': ('parent-case', subcase1._id)})
        subsub2 = self._make_case(self.other_user._id, self.other_user._id,
                                  index={'parent': ('parent-case', subcase1._id)})
        cases = [case, subcase1, subcase2, subsub1, subsub2]
        for c in cases:
            self.assertEqual(self.other_user._id, c.owner_id)
        reconcile_ownership(case, self.user, recursive=True)
        case = CommCareCase.get(case._id)
        owner = get_wrapped_owner(get_owner_id(case))
        self.assertTrue(isinstance(owner, Group))
        self.assertTrue(self.other_user._id in owner.users)
        self.assertTrue(self.user._id in owner.users)
        self.assertTrue(owner.case_sharing)
        self.assertFalse(owner.reporting)
        for c in cases:
            c = CommCareCase.get(c._id)
            self.assertEqual(owner._id, c.owner_id)

        parent_case = CommCareCase.get(parent_case._id)
        self.assertEqual(self.other_user._id, parent_case.owner_id)
Example #6
0
 def recipient(self):
     handler = self.handler
     if handler.recipient == RECIPIENT_USER:
         return self.user
     elif handler.recipient == RECIPIENT_CASE:
         return CommConnectCase.get(self.case_id)
     elif handler.recipient == RECIPIENT_SURVEY_SAMPLE:
         return SurveySample.get(self.sample_id)
     elif handler.recipient == RECIPIENT_OWNER:
         return get_wrapped_owner(get_owner_id(self.case))
     elif handler.recipient == RECIPIENT_PARENT_CASE:
         indices = self.case.indices
         for index in indices:
             # TODO: The data model allows for more than one parent.
             # For now, send to the first parent, but need to decide how to handle multiple ones.
             if index.identifier == "parent":
                 return CommConnectCase.get(index.referenced_id)
         return None
     elif handler.recipient == RECIPIENT_SUBCASE:
         indices = self.case.reverse_indices
         recipients = []
         for index in indices:
             if index.identifier == "parent":
                 subcase = CommConnectCase.get(index.referenced_id)
                 if case_matches_criteria(subcase, handler.recipient_case_match_type, handler.recipient_case_match_property, handler.recipient_case_match_value):
                     recipients.append(subcase)
         return recipients
     else:
         return None
Example #7
0
def get_owner_location(domain, owner_id):
    owner = get_wrapped_owner(owner_id)
    if not owner:
        return None
    if isinstance(owner, SQLLocation):
        return owner
    location_id = owner.get_location_id(domain)
    return SQLLocation.by_location_id(location_id) if location_id else None
Example #8
0
def process_survey_keyword_actions(verified_number, survey_keyword, text, msg=None):
    from corehq.apps.reminders.models import (
        RECIPIENT_SENDER,
        RECIPIENT_OWNER,
        RECIPIENT_USER_GROUP,
        METHOD_SMS,
        METHOD_SMS_SURVEY,
        METHOD_STRUCTURED_SMS,
        REMINDER_TYPE_KEYWORD_INITIATED,
    )

    sender = verified_number.owner
    if sender.doc_type == "CommCareCase":
        case = sender
    else:
        case = None
    for survey_keyword_action in survey_keyword.actions:
        if survey_keyword_action.recipient == RECIPIENT_SENDER:
            contact = sender
        elif survey_keyword_action.recipient == RECIPIENT_OWNER:
            if sender.doc_type == "CommCareCase":
                contact = get_wrapped_owner(get_owner_id(sender))
            else:
                contact = None
        elif survey_keyword_action.recipient == RECIPIENT_USER_GROUP:
            try:
                contact = Group.get(survey_keyword_action.recipient_id)
                assert contact.doc_type == "Group"
                assert contact.domain == verified_number.domain
            except Exception:
                contact = None
        else:
            contact = None

        if contact is None:
            continue

        if survey_keyword_action.action == METHOD_SMS:
            create_immediate_reminder(
                contact,
                METHOD_SMS,
                reminder_type=REMINDER_TYPE_KEYWORD_INITIATED,
                message=survey_keyword_action.message_content,
                case=case,
            )
        elif survey_keyword_action.action == METHOD_SMS_SURVEY:
            create_immediate_reminder(
                contact,
                METHOD_SMS_SURVEY,
                reminder_type=REMINDER_TYPE_KEYWORD_INITIATED,
                form_unique_id=survey_keyword_action.form_unique_id,
                case=case,
            )
        elif survey_keyword_action.action == METHOD_STRUCTURED_SMS:
            handle_structured_sms(
                survey_keyword, survey_keyword_action, sender, verified_number, text, send_response=True, msg=msg
            )
Example #9
0
 def _check_owner_id(self, owner_id):
     """
     Raises InvalidOwner if the owner cannot own cases.
     Raises InvalidLocation if a location-restricted user tries to assign
         an owner outside their location hierarchy.
     Returns True if owner ID is valid.
     """
     owner = get_wrapped_owner(owner_id)
     self._check_owner(owner, 'owner_id')
Example #10
0
def get_user_from_usercase(usercase):
    if usercase.type != USERCASE_TYPE:
        raise ValueError(f"Expected '{USERCASE_TYPE}' case, got {usercase.type}")

    user = get_wrapped_owner(get_owner_id(usercase))
    if not isinstance(user, CommCareUser):
        return None

    return user
Example #11
0
def _cached_owner_id_to_display(owner_id):
    key = 'owner_id_to_display_cache_{id}'.format(id=owner_id)
    ret = cache.get(key)
    if ret:
        return ret
    owner = get_wrapped_owner(owner_id)
    if owner is None:
        return None
    else:
        ret = raw_username(owner.username) if isinstance(owner, CouchUser) else owner.name
        cache.set(key, ret)
        return ret
Example #12
0
def is_valid_id(uploaded_id, domain, cache):
    if uploaded_id in cache:
        return cache[uploaded_id]

    owner = get_wrapped_owner(uploaded_id)
    return (
        (
            owner and
            is_user_or_case_sharing_group(owner) and
            owner.is_member_of(domain)
        ) or
        is_location_group(uploaded_id, domain)
    )
Example #13
0
 def testUserToGroup(self):
     # 2. If the case has an owner that is a user create a new case sharing group,
     # add that user and the new user to the case sharing group make the group the owner.
     case = self._make_case(self.other_user._id, self.other_user._id)
     self.assertEqual(self.other_user._id, case.owner_id)
     reconcile_ownership(case, self.user)
     case = CommCareCase.get(case._id)
     self.assertNotEqual(self.other_user._id, case.owner_id)
     owner = get_wrapped_owner(get_owner_id(case))
     self.assertTrue(isinstance(owner, Group))
     self.assertTrue(self.other_user._id in owner.users)
     self.assertTrue(self.user._id in owner.users)
     self.assertTrue(owner.case_sharing)
     self.assertFalse(owner.reporting)
Example #14
0
def cached_owner_id_to_display(owner_id):
    from corehq.apps.users.cases import get_wrapped_owner
    from corehq.apps.users.models import CouchUser
    key = 'owner_id_to_display_cache_{id}'.format(id=owner_id)
    ret = cache.get(key)
    if ret:
        return ret
    owner = get_wrapped_owner(owner_id)
    if owner is None:
        return None
    else:
        ret = raw_username(owner.username) if isinstance(owner, CouchUser) else owner.name
        cache.set(key, ret)
        return ret
Example #15
0
def cached_owner_id_to_display(owner_id):
    from corehq.apps.users.cases import get_wrapped_owner
    from corehq.apps.users.models import CouchUser
    key = 'owner_id_to_display_cache_{id}'.format(id=owner_id)
    ret = cache.get(key)
    if ret:
        return ret
    owner = get_wrapped_owner(owner_id)
    if owner is None:
        return None
    else:
        ret = raw_username(owner.username) if isinstance(owner, CouchUser) else owner.name
        cache.set(key, ret)
        return ret
Example #16
0
def assign_cases(caselist, owner_id, acting_user=None, update=None):
    """
    Assign all cases in a list to an owner. Won't update if the owner is already
    set on the case. Doesn't touch parent cases or subcases.

    Returns the list of ids of cases that were reassigned.
    """
    if not caselist:
        return

    def _assert(bool, msg):
        if not bool:
            raise CaseAssignmentError(msg)

    from corehq.apps.users.cases import get_wrapped_owner
    # "security"
    unique_domains = set([c.domain for c in caselist])
    _assert(
        len(unique_domains) == 1,
        'case list had cases spanning multiple domains')
    [domain] = unique_domains
    _assert(domain, 'domain for cases was empty')
    owner = get_wrapped_owner(owner_id)
    _assert(owner, 'no owner with id "%s" found' % owner_id)
    _assert(owner.domain == domain,
            'owner was not in domain %s for cases' % domain)

    username = acting_user.username if acting_user else 'system'
    user_id = acting_user._id if acting_user else 'system'
    filtered_cases = set([c for c in caselist if c.owner_id != owner_id])
    if filtered_cases:
        caseblocks = [
            ElementTree.tostring(
                CaseBlock(
                    create=False,
                    case_id=c.case_id,
                    owner_id=owner_id,
                    update=update,
                ).as_xml()) for c in filtered_cases
        ]
        # todo: this should check whether the submit_case_blocks call actually succeeds
        device_id = __name__ + ".assign_cases"
        submit_case_blocks(caseblocks,
                           domain,
                           username=username,
                           user_id=user_id,
                           device_id=device_id)

    return [c._id for c in filtered_cases]
Example #17
0
    def id_to_choice_tuple(self, id_):
        for static_id, text in self.static_options:
            if (id_ == static_id[3:] and static_id[:3] == "t__") or id_ == static_id:
                return (static_id, text)

        owner = get_wrapped_owner(id_)
        if isinstance(owner, Group):
            return self._group_to_choice_tuple(owner)
        elif isinstance(owner, SQLLocation):
            return self.location_tuple(owner)
        elif isinstance(owner, (CommCareUser, WebUser)):
            return self.user_tuple(owner)
        elif owner is None:
            return None
        else:
            raise Exception("Unexpcted id: {}".format(id_))
Example #18
0
    def convert_owner_id_to_select_choice(owner_id, domain):
        utils = _CallCenterOwnerOptionsUtils(domain)
        for id, text in utils.static_options:
            if owner_id == id:
                return (id, text)

        owner = get_wrapped_owner(owner_id)
        if isinstance(owner, Group):
            return utils.reporting_group_tuple(owner)
        elif isinstance(owner, Location):
            return utils.location_tuple(owner.sql_location)
        elif isinstance(owner, CommCareUser):
            return utils.user_tuple(owner)
        elif owner is None:
            return None
        else:
            raise Exception("Unexpcted owner type")
Example #19
0
    def convert_owner_id_to_select_choice(owner_id, domain):
        utils = _CallCenterOwnerOptionsUtils(domain)
        for id, text in utils.static_options:
            if owner_id == id:
                return (id, text)

        owner = get_wrapped_owner(owner_id)
        if isinstance(owner, Group):
            return utils.reporting_group_tuple(owner)
        elif isinstance(owner, SQLLocation):
            return utils.location_tuple(owner)
        elif isinstance(owner, CommCareUser):
            return utils.user_tuple(owner)
        elif owner is None:
            return None
        else:
            raise Exception("Unexpcted owner type")
Example #20
0
    def __get_owner_result(self):
        """
        memoized doesn't seem to work with overriding __getattr__ at the same time,
        so we cache the result using a private attribute.
        """
        if self.__owner_result:
            return self.__owner_result

        owner = get_wrapped_owner(get_owner_id(self.__case))
        if isinstance(owner, CouchUser):
            if owner.is_member_of(self.__domain):
                self.__owner_result = SimpleDictTemplateParam(_get_obj_template_info(owner))
        elif isinstance(owner, (Group, SQLLocation)):
            if owner.domain == self.__domain:
                self.__owner_result = SimpleDictTemplateParam(_get_obj_template_info(owner))

        self.__owner_result = self.__owner_result or SimpleMessagingTemplateParam(UNKNOWN_VALUE)
        return self.__owner_result
Example #21
0
    def __get_owner_result(self):
        """
        memoized doesn't seem to work with overriding __getattr__ at the same time,
        so we cache the result using a private attribute.
        """
        if self.__owner_result:
            return self.__owner_result

        owner = get_wrapped_owner(get_owner_id(self.__case))
        if isinstance(owner, CouchUser):
            if owner.is_member_of(self.__domain):
                self.__owner_result = SimpleDictTemplateParam(_get_obj_template_info(owner))
        elif isinstance(owner, (Group, SQLLocation)):
            if owner.domain == self.__domain:
                self.__owner_result = SimpleDictTemplateParam(_get_obj_template_info(owner))

        self.__owner_result = self.__owner_result or SimpleMessagingTemplateParam(UNKNOWN_VALUE)
        return self.__owner_result
Example #22
0
def assign_cases(caselist, owner_id, acting_user=None, update=None):
    """
    Assign all cases in a list to an owner. Won't update if the owner is already
    set on the case. Doesn't touch parent cases or subcases.

    Returns the list of ids of cases that were reassigned.
    """
    if not caselist:
        return

    def _assert(bool, msg):
        if not bool:
            raise CaseAssignmentError(msg)

    from corehq.apps.users.cases import get_wrapped_owner
    # "security"
    unique_domains = set([c.domain for c in caselist])
    _assert(len(unique_domains) == 1, 'case list had cases spanning multiple domains')
    [domain] = unique_domains
    _assert(domain, 'domain for cases was empty')
    owner = get_wrapped_owner(owner_id)
    _assert(owner, 'no owner with id "%s" found' % owner_id)
    _assert(owner.domain == domain, 'owner was not in domain %s for cases' % domain)

    username = acting_user.username if acting_user else 'system'
    user_id = acting_user._id if acting_user else 'system'
    filtered_cases = set([c for c in caselist if c.owner_id != owner_id])
    if filtered_cases:
        caseblocks = [ElementTree.tostring(CaseBlock(
                create=False,
                case_id=c._id,
                owner_id=owner_id,
                version=V2,
                update=update,
            ).as_xml(format_datetime=json_format_datetime)) for c in filtered_cases
        ]
        # todo: this should check whether the submit_case_blocks call actually succeeds
        submit_case_blocks(caseblocks, domain, username=username,
                           user_id=user_id)

    return [c._id for c in filtered_cases]
Example #23
0
    def _check_owner_id(self, owner_id):
        """
        Raises InvalidOwnerId if the owner cannot own cases.
        Raises InvalidLocation if a location-restricted user tries to assign
            an owner outside their location hierarchy.
        Returns True if owner ID is valid.
        """
        if owner_id in self.id_cache:
            if isinstance(self.id_cache[owner_id], CaseRowError):
                raise self.id_cache[owner_id]
            return True

        owner = get_wrapped_owner(owner_id)
        try:
            _check_owner(owner, self.domain, self.user_id, self.accessible_locations)
        except CaseRowError as err:
            self.id_cache[owner_id] = err
            raise
        else:
            self.id_cache[owner_id] = True
        return True
Example #24
0
    def id_to_choice_tuple(self, id_):
        for static_id, text in self.static_options:
            if (id_ == static_id[3:] and static_id[:3] == "t__") or id_ == static_id:
                return (static_id, text)

        owner = get_wrapped_owner(id_, support_deleted=True)
        if isinstance(owner, Group):
            ret = self._group_to_choice_tuple(owner)
        elif isinstance(owner, SQLLocation):
            ret = self.location_tuple(owner)
        elif isinstance(owner, (CommCareUser, WebUser)):
            ret = self.user_tuple(owner)
        elif owner is None:
            return None
        else:
            raise Exception("Unexpcted id: {}".format(id_))

        if hasattr(owner, 'is_deleted'):
            if (callable(owner.is_deleted) and owner.is_deleted()) or owner.is_deleted == True:
                # is_deleted may be an attr or callable depending on owner type
                ret = (ret[0], 'Deleted - ' + ret[1])

        return ret
Example #25
0
 def test_get_wrapped_group(self):
     group = Group(domain=self.domain, name='wrapped-group-test')
     group.save()
     wrapped = get_wrapped_owner(group._id)
     self.assertTrue(isinstance(wrapped, Group))
Example #26
0
 def test_get_wrapped_user(self):
     user = CommCareUser.create(self.domain, 'wrapped-user-test', 'password')
     user.save()
     wrapped = get_wrapped_owner(user._id)
     self.assertTrue(isinstance(wrapped, CommCareUser))
Example #27
0
def is_valid_id(uploaded_id, domain, cache):
    if uploaded_id in cache:
        return cache[uploaded_id]

    owner = get_wrapped_owner(uploaded_id)
    return is_valid_owner(owner, domain)
Example #28
0
def get_user_from_usercase(usercase):
    user = get_wrapped_owner(get_owner_id(usercase))
    if not isinstance(user, CommCareUser):
        return None

    return user
Example #29
0
def process_survey_keyword_actions(verified_number, survey_keyword, text, msg):
    sender = verified_number.owner
    case = None
    args = split_args(text, survey_keyword)

    logged_event = MessagingEvent.create_from_keyword(survey_keyword, sender)

    # Log a messaging subevent for the incoming message
    subevent = logged_event.create_subevent_for_single_sms(
        msg.couch_recipient_doc_type,
        msg.couch_recipient
    )
    subevent.completed()
    add_msg_tags(msg, MessageMetadata(messaging_subevent_id=subevent.pk))

    # Close any open sessions even if it's just an sms that we're
    # responding with.
    SQLXFormsSession.close_all_open_sms_sessions(verified_number.domain,
        verified_number.owner_id)

    if sender.doc_type == "CommCareCase":
        case = sender
        args = args[1:]
    elif sender.doc_type == "CommCareUser":
        if keyword_uses_form_that_requires_case(survey_keyword):
            if len(args) > 1:
                external_id = args[1]
                case, matches = get_case_by_external_id(verified_number.domain,
                    external_id, sender)
                if matches == 0:
                    send_keyword_response(verified_number, MSG_CASE_NOT_FOUND, logged_event)
                    logged_event.error(MessagingEvent.ERROR_CASE_EXTERNAL_ID_NOT_FOUND)
                    return
                elif matches > 1:
                    send_keyword_response(verified_number, MSG_MULTIPLE_CASES_FOUND, logged_event)
                    logged_event.error(MessagingEvent.ERROR_MULTIPLE_CASES_WITH_EXTERNAL_ID_FOUND)
                    return
            else:
                send_keyword_response(verified_number, MSG_MISSING_EXTERNAL_ID, logged_event)
                logged_event.error(MessagingEvent.ERROR_NO_EXTERNAL_ID_GIVEN)
                return
            args = args[2:]
        else:
            args = args[1:]
    def cmp_fcn(a1, a2):
        a1_ss = (a1.action == METHOD_STRUCTURED_SMS)
        a2_ss = (a2.action == METHOD_STRUCTURED_SMS)
        if a1_ss and a2_ss:
            return 0
        elif a1_ss:
            return -1
        elif a2_ss:
            return 1
        else:
            return 0

    if case:
        subevent.case_id = case.get_id
        subevent.save()

    # Process structured sms actions first
    actions = sorted(survey_keyword.actions, cmp=cmp_fcn)
    for survey_keyword_action in actions:
        if survey_keyword_action.recipient == RECIPIENT_SENDER:
            contact = sender
        elif survey_keyword_action.recipient == RECIPIENT_OWNER:
            if sender.doc_type == "CommCareCase":
                contact = get_wrapped_owner(get_owner_id(sender))
            else:
                contact = None
        elif survey_keyword_action.recipient == RECIPIENT_USER_GROUP:
            try:
                contact = Group.get(survey_keyword_action.recipient_id)
                assert contact.doc_type == "Group"
                assert contact.domain == verified_number.domain
            except Exception:
                contact = None
        else:
            contact = None

        if contact is None:
            continue

        if survey_keyword_action.action == METHOD_SMS:
            create_immediate_reminder(contact, METHOD_SMS, 
                reminder_type=REMINDER_TYPE_KEYWORD_INITIATED,
                message=survey_keyword_action.message_content,
                case=case, logged_event=logged_event)
        elif survey_keyword_action.action == METHOD_SMS_SURVEY:
            create_immediate_reminder(contact, METHOD_SMS_SURVEY,
                reminder_type=REMINDER_TYPE_KEYWORD_INITIATED,
                form_unique_id=survey_keyword_action.form_unique_id,
                case=case, logged_event=logged_event)
        elif survey_keyword_action.action == METHOD_STRUCTURED_SMS:
            res = handle_structured_sms(survey_keyword, survey_keyword_action,
                sender, verified_number, text, send_response=True, msg=msg,
                case=case, text_args=args, logged_event=logged_event)
            if not res:
                # If the structured sms processing wasn't successful, don't
                # process any of the other actions
                return
    logged_event.completed()
Example #30
0
def test_invalid_ids(self, invalid_id):
    self.assertEqual(None, get_wrapped_owner(invalid_id))
    self.assertEqual(None, user_id_to_username(invalid_id))
Example #31
0
 def test_get_wrapped_group(self):
     group = Group(domain=self.domain, name='wrapped-group-test')
     group.save()
     self.addCleanup(group.delete)
     wrapped = get_wrapped_owner(group._id)
     self.assertTrue(isinstance(wrapped, Group))
Example #32
0
    def case_owner(self):
        if self.case:
            return get_wrapped_owner(get_owner_id(self.case))

        return None
Example #33
0
def process_survey_keyword_actions(verified_number, survey_keyword, text, msg):
    sender = verified_number.owner
    case = None
    args = split_args(text, survey_keyword)

    logged_event = MessagingEvent.create_from_keyword(survey_keyword, sender)

    # Log a messaging subevent for the incoming message
    subevent = logged_event.create_subevent_for_single_sms(
        msg.couch_recipient_doc_type,
        msg.couch_recipient,
        completed=True
    )
    add_msg_tags(msg, MessageMetadata(messaging_subevent_id=subevent.pk))

    # Close any open sessions even if it's just an sms that we're
    # responding with.
    SQLXFormsSession.close_all_open_sms_sessions(verified_number.domain,
        verified_number.owner_id)

    if is_commcarecase(sender):
        case = sender
        args = args[1:]
    elif isinstance(sender, CommCareUser):
        if keyword_uses_form_that_requires_case(survey_keyword):
            if len(args) > 1:
                external_id = args[1]
                case, matches = get_case_by_external_id(verified_number.domain,
                    external_id, sender)
                if matches == 0:
                    send_keyword_response(verified_number, MSG_CASE_NOT_FOUND, logged_event)
                    logged_event.error(MessagingEvent.ERROR_CASE_EXTERNAL_ID_NOT_FOUND)
                    return
                elif matches > 1:
                    send_keyword_response(verified_number, MSG_MULTIPLE_CASES_FOUND, logged_event)
                    logged_event.error(MessagingEvent.ERROR_MULTIPLE_CASES_WITH_EXTERNAL_ID_FOUND)
                    return
            else:
                send_keyword_response(verified_number, MSG_MISSING_EXTERNAL_ID, logged_event)
                logged_event.error(MessagingEvent.ERROR_NO_EXTERNAL_ID_GIVEN)
                return
            args = args[2:]
        else:
            args = args[1:]

    def cmp_fcn(a1, a2):
        a1_ss = (a1.action == KeywordAction.ACTION_STRUCTURED_SMS)
        a2_ss = (a2.action == KeywordAction.ACTION_STRUCTURED_SMS)
        if a1_ss and a2_ss:
            return 0
        elif a1_ss:
            return -1
        elif a2_ss:
            return 1
        else:
            return 0

    if case:
        subevent.case_id = case.case_id
        subevent.save()

    # Process structured sms actions first
    actions = sorted(survey_keyword.keywordaction_set.all(), cmp=cmp_fcn)
    for survey_keyword_action in actions:
        if survey_keyword_action.recipient == KeywordAction.RECIPIENT_SENDER:
            contact = sender
        elif survey_keyword_action.recipient == KeywordAction.RECIPIENT_OWNER:
            if is_commcarecase(sender):
                contact = get_wrapped_owner(get_owner_id(sender))
            else:
                contact = None
        elif survey_keyword_action.recipient == KeywordAction.RECIPIENT_USER_GROUP:
            try:
                contact = Group.get(survey_keyword_action.recipient_id)
                assert contact.doc_type == "Group"
                assert contact.domain == verified_number.domain
            except Exception:
                contact = None
        else:
            contact = None

        if contact is None:
            continue

        # contact can be either a user, case, group, or location
        if survey_keyword_action.action in (KeywordAction.ACTION_SMS, KeywordAction.ACTION_SMS_SURVEY):
            if isinstance(contact, Group):
                recipients = list(ScheduleInstance.expand_group(contact))
            elif isinstance(contact, SQLLocation):
                recipients = list(ScheduleInstance.expand_location_ids(contact.domain, [contact.location_id]))
            else:
                recipients = [contact]

            recipient_is_sender = survey_keyword_action.recipient == KeywordAction.RECIPIENT_SENDER

            if survey_keyword_action.action == KeywordAction.ACTION_SMS:
                content = SMSContent(message={'*': survey_keyword_action.message_content})
                content.set_context(case=case)
            elif survey_keyword_action.action == KeywordAction.ACTION_SMS_SURVEY:
                content = SMSSurveyContent(
                    form_unique_id=survey_keyword_action.form_unique_id,
                    expire_after=SQLXFormsSession.MAX_SESSION_LENGTH,
                )
                content.set_context(
                    case=case,
                    critical_section_already_acquired=recipient_is_sender,
                )
            else:
                raise ValueError("Unexpected action %s" % survey_keyword_action.action)

            for recipient in recipients:
                phone_entry = verified_number if recipient_is_sender else None
                content.send(recipient, logged_event, phone_entry=phone_entry)

        elif survey_keyword_action.action == KeywordAction.ACTION_STRUCTURED_SMS:
            res = handle_structured_sms(survey_keyword, survey_keyword_action,
                sender, verified_number, text, send_response=True, msg=msg,
                case=case, text_args=args, logged_event=logged_event)
            if not res:
                # If the structured sms processing wasn't successful, don't
                # process any of the other actions
                return
    logged_event.completed()
Example #34
0
            return 1
        else:
            return 0

    if case:
        subevent.case_id = case.case_id
        subevent.save()

    # Process structured sms actions first
    actions = sorted(survey_keyword.keywordaction_set.all(), cmp=cmp_fcn)
    for survey_keyword_action in actions:
        if survey_keyword_action.recipient == KeywordAction.RECIPIENT_SENDER:
            contact = sender
        elif survey_keyword_action.recipient == KeywordAction.RECIPIENT_OWNER:
            if is_commcarecase(sender):
                contact = get_wrapped_owner(get_owner_id(sender))
            else:
                contact = None
        elif survey_keyword_action.recipient == KeywordAction.RECIPIENT_USER_GROUP:
            try:
                contact = Group.get(survey_keyword_action.recipient_id)
                assert contact.doc_type == "Group"
                assert contact.domain == verified_number.domain
            except Exception:
                contact = None
        else:
            contact = None

        if contact is None:
            continue
Example #35
0
def get_user_from_usercase(usercase):
    user = get_wrapped_owner(get_owner_id(usercase))
    if not isinstance(user, CommCareUser):
        return None

    return user
Example #36
0
def test_invalid_ids(self, invalid_id):
    self.assertEqual(None, get_wrapped_owner(invalid_id))
    self.assertEqual(None, user_id_to_username(invalid_id))
Example #37
0
def is_valid_id(uploaded_id, domain, cache):
    if uploaded_id in cache:
        return cache[uploaded_id]

    owner = get_wrapped_owner(uploaded_id)
    return is_valid_owner(owner, domain)
Example #38
0
def _add_owner_to_template_params(case, result):
    owner = get_wrapped_owner(get_owner_id(case))
    if owner:
        result['case']['owner'] = _get_obj_template_info(owner)
Example #39
0
def process_survey_keyword_actions(verified_number, survey_keyword, text, msg):
    sender = verified_number.owner
    case = None
    args = split_args(text, survey_keyword)

    # Close any open sessions even if it's just an sms that we're
    # responding with.
    XFormsSession.close_all_open_sms_sessions(verified_number.domain,
        verified_number.owner_id)

    if sender.doc_type == "CommCareCase":
        case = sender
        args = args[1:]
    elif sender.doc_type == "CommCareUser":
        if keyword_uses_form_that_requires_case(survey_keyword):
            if len(args) > 1:
                external_id = args[1]
                case = get_case_by_external_id(verified_number.domain,
                    external_id)
                if case is None or not user_can_access_case(sender, case):
                    send_keyword_response(verified_number, MSG_CASE_NOT_FOUND)
                    return
            else:
                send_keyword_response(verified_number, MSG_MISSING_EXTERNAL_ID)
                return
            args = args[2:]
        else:
            args = args[1:]
    def cmp_fcn(a1, a2):
        a1_ss = (a1.action == METHOD_STRUCTURED_SMS)
        a2_ss = (a2.action == METHOD_STRUCTURED_SMS)
        if a1_ss and a2_ss:
            return 0
        elif a1_ss:
            return -1
        elif a2_ss:
            return 1
        else:
            return 0
    # Process structured sms actions first
    actions = sorted(survey_keyword.actions, cmp=cmp_fcn)
    for survey_keyword_action in actions:
        if survey_keyword_action.recipient == RECIPIENT_SENDER:
            contact = sender
        elif survey_keyword_action.recipient == RECIPIENT_OWNER:
            if sender.doc_type == "CommCareCase":
                contact = get_wrapped_owner(get_owner_id(sender))
            else:
                contact = None
        elif survey_keyword_action.recipient == RECIPIENT_USER_GROUP:
            try:
                contact = Group.get(survey_keyword_action.recipient_id)
                assert contact.doc_type == "Group"
                assert contact.domain == verified_number.domain
            except Exception:
                contact = None
        else:
            contact = None

        if contact is None:
            continue

        if survey_keyword_action.action == METHOD_SMS:
            create_immediate_reminder(contact, METHOD_SMS, 
                reminder_type=REMINDER_TYPE_KEYWORD_INITIATED,
                message=survey_keyword_action.message_content,
                case=case)
        elif survey_keyword_action.action == METHOD_SMS_SURVEY:
            create_immediate_reminder(contact, METHOD_SMS_SURVEY,
                reminder_type=REMINDER_TYPE_KEYWORD_INITIATED,
                form_unique_id=survey_keyword_action.form_unique_id,
                case=case)
        elif survey_keyword_action.action == METHOD_STRUCTURED_SMS:
            res = handle_structured_sms(survey_keyword, survey_keyword_action,
                sender, verified_number, text, send_response=True, msg=msg,
                case=case, text_args=args)
            if not res:
                # If the structured sms processing wasn't successful, don't
                # process any of the other actions
                return