Example #1
0
    def _validate_intents(self):
        if domain_has_privilege(self.domain, privileges.CUSTOM_INTENTS):
            return []

        if hasattr(self.app, 'get_forms'):
            for form in self.app.get_forms():
                intents = form.wrapped_xform().odk_intents
                if intents:
                    if not domain_has_privilege(self.domain, privileges.TEMPLATED_INTENTS):
                        return [{
                            'type': 'error',
                            'message': _(
                                "Usage of integrations is not supported by your "
                                "current subscription. Please upgrade your "
                                "subscription before using this feature."
                            ),
                        }]
                    else:
                        templates = next(app_callout_templates)
                        if len(set(intents) - set(t['id'] for t in templates)):
                            return [{
                                'type': 'error',
                                'message': _(
                                    "Usage of external integration is not supported by your "
                                    "current subscription. Please upgrade your "
                                    "subscription before using this feature."
                                ),
                            }]
            return []
Example #2
0
def releases_ajax(request, domain, app_id, template='app_manager/v1/partials/releases.html'):
    app = get_app(domain, app_id)
    context = get_apps_base_context(request, domain, app)
    can_send_sms = domain_has_privilege(domain, privileges.OUTBOUND_SMS)
    build_profile_access = domain_has_privilege(domain, privileges.BUILD_PROFILES)

    context.update({
        'intro_only': len(app.modules) == 0,
        'release_manager': True,
        'can_send_sms': can_send_sms,
        'has_mobile_workers': get_doc_count_in_domain_by_class(domain, CommCareUser) > 0,
        'sms_contacts': (
            get_sms_autocomplete_context(request, domain)['sms_contacts']
            if can_send_sms else []
        ),
        'build_profile_access': build_profile_access and not toggles.APP_MANAGER_V2.enabled(domain),
        'lastest_j2me_enabled_build': CommCareBuildConfig.latest_j2me_enabled_config().label,
        'fetchLimit': request.GET.get('limit', DEFAULT_FETCH_LIMIT),
    })
    if not app.is_remote_app():
        # Multimedia is not supported for remote applications at this time.
        try:
            multimedia_state = app.check_media_state()
            context.update({
                'multimedia_state': multimedia_state,
            })
        except ReportConfigurationNotFoundError:
            pass
    response = render(request, template, context)
    response.set_cookie('lang', encode_if_unicode(context['lang']))
    return response
Example #3
0
def orgs_landing(request, org, template="orgs/orgs_landing.html", form=None, add_form=None, invite_member_form=None,
                 add_team_form=None, update_form=None, tab=None):
    organization = request.organization

    class LandingNotification(Notification):
        doc_type = 'OrgLandingNotification'

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

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

    reg_form_empty = not form
    add_form_empty = not add_form
    invite_member_form_empty = not invite_member_form
    add_team_form_empty = not add_team_form

    reg_form = form or DomainRegistrationForm(initial={'org': organization.name})
    add_form = add_form or AddProjectForm(org)
    invite_member_form = invite_member_form or InviteMemberForm(org)
    add_team_form = add_team_form or AddTeamForm(org)

    ctxt = base_context(request, organization, update_form=update_form)
    user_domains = []
    req_domains = []
    # display a notification for each org request that hasn't previously been seen
    if request.couch_user.is_org_admin(org):
        requests = OrgRequest.get_requests(org)
        for req in requests:
            if req.seen or req.domain in [d.name for d in ctxt["domains"]]:
                continue
            messages.info(request, render_to_string("orgs/partials/org_request_notification.html",
                {"requesting_user": WebUser.get(req.requested_by).username, "org_req": req, "org": organization}),
                extra_tags="html")

        def format_domains(dom_list, extra=None):
            extra = extra or []
            dom_list = list(set(filter(lambda d: d not in ctxt["domains"] + extra, dom_list)))
            return [Domain.get_by_name(d) for d in dom_list]

        # get the existing domains that an org admin would add to the organization
        user_domains = request.couch_user.domains or []
        user_domains = filter(
            lambda x: domain_has_privilege(x, privileges.CROSS_PROJECT_REPORTS),
            user_domains
        )
        req_domains = [req.domain for req in requests]
        user_domains = format_domains(user_domains)
        req_domains = format_domains(req_domains, [d.name for d in user_domains if d])
        filter(
            lambda x: domain_has_privilege(x, privileges.CROSS_PROJECT_REPORTS),
            req_domains
        )

    ctxt.update(dict(reg_form=reg_form, add_form=add_form, reg_form_empty=reg_form_empty, add_form_empty=add_form_empty,
                invite_member_form=invite_member_form, invite_member_form_empty=invite_member_form_empty,
                add_team_form=add_team_form, add_team_form_empty=add_team_form_empty, tab="projects",
                user_domains=user_domains, req_domains=req_domains))
    return render(request, template, ctxt)
Example #4
0
def releases_ajax(request, domain, app_id, template='app_manager/partials/releases.html'):
    app = get_app(domain, app_id)
    context = get_apps_base_context(request, domain, app)
    can_send_sms = domain_has_privilege(domain, privileges.OUTBOUND_SMS)
    build_profile_access = domain_has_privilege(domain, privileges.BUILD_PROFILES)

    context.update({
        'release_manager': True,
        'can_send_sms': can_send_sms,
        'has_mobile_workers': get_doc_count_in_domain_by_class(domain, CommCareUser) > 0,
        'sms_contacts': (
            get_sms_autocomplete_context(request, domain)['sms_contacts']
            if can_send_sms else []
        ),
        'build_profile_access': build_profile_access
    })
    if not app.is_remote_app():
        # Multimedia is not supported for remote applications at this time.
        try:
            multimedia_state = app.check_media_state()
            context.update({
                'multimedia_state': multimedia_state,
            })
        except ReportConfigurationNotFoundError:
            pass
    response = render(request, template, context)
    response.set_cookie('lang', encode_if_unicode(context['lang']))
    return response
Example #5
0
def process_incoming(msg):
    v = PhoneNumber.by_phone(msg.phone_number, include_pending=True)

    if v:
        msg.couch_recipient_doc_type = v.owner_doc_type
        msg.couch_recipient = v.owner_id
        msg.domain = v.domain
        msg.location_id = get_location_id_by_verified_number(v)
        msg.save()
    elif msg.domain_scope:
        msg.domain = msg.domain_scope
        msg.save()

    can_receive_sms = PhoneBlacklist.can_receive_sms(msg.phone_number)
    opt_in_keywords, opt_out_keywords = get_opt_keywords(msg)
    domain = v.domain if v else None

    if is_opt_message(msg.text, opt_out_keywords) and can_receive_sms:
        if PhoneBlacklist.opt_out_sms(msg.phone_number, domain=domain):
            metadata = MessageMetadata(ignore_opt_out=True)
            text = get_message(MSG_OPTED_OUT, v, context=(opt_in_keywords[0],))
            if v:
                send_sms_to_verified_number(v, text, metadata=metadata)
            else:
                send_sms(msg.domain, None, msg.phone_number, text, metadata=metadata)
    elif is_opt_message(msg.text, opt_in_keywords) and not can_receive_sms:
        if PhoneBlacklist.opt_in_sms(msg.phone_number, domain=domain):
            text = get_message(MSG_OPTED_IN, v, context=(opt_out_keywords[0],))
            if v:
                send_sms_to_verified_number(v, text)
            else:
                send_sms(msg.domain, None, msg.phone_number, text)
    else:
        handled = False
        is_verified = v is not None and v.verified

        if msg.domain and domain_has_privilege(msg.domain, privileges.INBOUND_SMS):
            handled = load_and_call(settings.CUSTOM_SMS_HANDLERS, v, msg.text, msg)

            if not handled and is_verified and is_contact_active(v.domain, v.owner_doc_type, v.owner_id):
                handled = load_and_call(settings.SMS_HANDLERS, v, msg.text, msg)

        if not handled and not is_verified:
            handled = process_pre_registration(msg)

            if not handled:
                handled = process_sms_registration(msg)

            if not handled:
                import verify
                verify.process_verification(v, msg)

    # If the sms queue is enabled, then the billable gets created in remove_from_queue()
    if (
        not settings.SMS_QUEUE_ENABLED and
        msg.domain and
        domain_has_privilege(msg.domain, privileges.INBOUND_SMS)
    ):
        create_billable_for_sms(msg)
Example #6
0
 def page_context(self):
     owner_id = self.export_instance.owner_id
     return {
         'export_instance': self.export_instance,
         'export_home_url': self.export_home_url,
         'allow_deid': has_privilege(self.request, privileges.DEIDENTIFIED_DATA),
         'has_excel_dashboard_access': domain_has_privilege(self.domain, EXCEL_DASHBOARD),
         'has_daily_saved_export_access': domain_has_privilege(self.domain, DAILY_SAVED_EXPORT),
         'can_edit': self.export_instance.can_edit(self.request.couch_user),
         'has_other_owner': owner_id and owner_id != self.request.couch_user.user_id,
         'owner_name': WebUser.get_by_user_id(owner_id).username if owner_id else None,
     }
Example #7
0
def download_daily_saved_export(req, domain, export_instance_id):
    with CriticalSection(['export-last-accessed-{}'.format(export_instance_id)]):
        try:
            export_instance = get_properly_wrapped_export_instance(export_instance_id)
        except ResourceNotFound:
            raise Http404(_("Export not found"))

        assert domain == export_instance.domain

        if export_instance.export_format == "html":
            if not domain_has_privilege(domain, EXCEL_DASHBOARD):
                raise Http404
        elif export_instance.is_daily_saved_export:
            if not domain_has_privilege(domain, DAILY_SAVED_EXPORT):
                raise Http404

        if not export_instance.filters.is_location_safe_for_user(req):
            return location_restricted_response(req)

        if not can_download_daily_saved_export(export_instance, domain, req.couch_user):
            raise Http404

        if export_instance.export_format == "html":
            message = "Download Excel Dashboard"
        else:
            message = "Download Saved Export"
        track_workflow(req.couch_user.username, message, properties={
            'domain': domain,
            'is_dimagi': req.couch_user.is_dimagi
        })

        if should_update_export(export_instance.last_accessed):
            try:
                rebuild_saved_export(export_instance_id, manual=False)
            except Exception:
                notify_exception(
                    req,
                    'Failed to rebuild export during download',
                    {
                        'export_instance_id': export_instance_id,
                        'domain': domain,
                    },
                )

        export_instance.last_accessed = datetime.utcnow()
        export_instance.save()

    payload = export_instance.get_payload(stream=True)
    format = Format.from_format(export_instance.export_format)
    return get_download_response(payload, export_instance.file_size, format, export_instance.filename, req)
Example #8
0
 def page_context(self):
     context = {
         'are_groups': bool(len(self.all_groups)),
         'groups_url': reverse('all_groups', args=[self.domain]),
         'group_form': self.group_form,
         'reset_password_form': self.reset_password_form,
         'is_currently_logged_in_user': self.is_currently_logged_in_user,
         'data_fields_form': self.custom_data.form,
         'can_use_inbound_sms': domain_has_privilege(self.domain, privileges.INBOUND_SMS),
         'needs_to_downgrade_locations': (
             users_have_locations(self.domain) and
             not has_privilege(self.request, privileges.LOCATIONS)
         ),
         'demo_restore_date': naturaltime(demo_restore_date_created(self.editable_user)),
         'hide_password_feedback': settings.ENABLE_DRACONIAN_SECURITY_FEATURES
     }
     if self.commtrack_form.errors:
         messages.error(self.request, _(
             "There were some errors while saving user's locations. Please check the 'Locations' tab"
         ))
     if self.domain_object.commtrack_enabled or self.domain_object.uses_locations:
         context.update({
             'commtrack_enabled': self.domain_object.commtrack_enabled,
             'uses_locations': self.domain_object.uses_locations,
             'commtrack': {
                 'update_form': self.commtrack_form,
             },
         })
     return context
 def handle(self, *args, **options):
     for domain in Domain.get_all():
         if (
             self.domain_has_active_reminders(domain) and
             not domain_has_privilege(domain, privileges.REMINDERS_FRAMEWORK)
         ):
             print "%s has active reminders without a subscription" % domain.name
Example #10
0
 def dispatch(self, request, *args, **kwargs):
     domain = args[0]
     if not domain_has_privilege(domain, privileges.ZAPIER_INTEGRATION) or not request.couch_user.is_member_of(
         domain
     ):
         return HttpResponseForbidden()
     return super(SubscribeView, self).dispatch(request, *args, **kwargs)
def get_per_domain_context(project, request=None):
    domain_type = get_domain_type(project, request)
    if domain_type == COMMTRACK:
        logo_url = static('hqstyle/img/commtrack-logo.png')
        site_name = "CommCare Supply"
        public_site = "http://www.commtrack.org"
        can_be_your = _("mobile logistics solution")
    else:
        logo_url = static('hqstyle/img/commcare-logo.png')
        site_name = "CommCare HQ"
        public_site = "http://www.commcarehq.org"
        can_be_your = _("mobile solution for your frontline workforce")

    if (project and project.has_custom_logo
        and domain_has_privilege(project.name, privileges.CUSTOM_BRANDING)
    ):
        logo_url = reverse('logo', args=[project.name])

    return {
        'DOMAIN_TYPE': domain_type,
        'LOGO_URL': logo_url,
        'SITE_NAME': site_name,
        'CAN_BE_YOUR': can_be_your,
        'PUBLIC_SITE': public_site,
    }
Example #12
0
def release_build(request, domain, app_id, saved_app_id):
    is_released = request.POST.get('is_released') == 'true'
    if not is_released:
        if LatestEnabledBuildProfiles.objects.filter(build_id=saved_app_id).exists():
            return json_response({'error': _('Please disable any enabled profiles to un-release this build.')})
    ajax = request.POST.get('ajax') == 'true'
    saved_app = get_app(domain, saved_app_id)
    if saved_app.copy_of != app_id:
        raise Http404
    saved_app.is_released = is_released
    saved_app.is_auto_generated = False
    saved_app.save(increment_version=False)
    from corehq.apps.app_manager.signals import app_post_release
    app_post_release.send(Application, application=saved_app)

    if is_released:
        if saved_app.build_profiles and domain_has_privilege(domain, privileges.BUILD_PROFILES):
            create_build_files_for_all_app_profiles.delay(domain, saved_app_id)
        _track_build_for_app_preview(domain, request.couch_user, app_id, 'User starred a build')

    if ajax:
        return json_response({
            'is_released': is_released,
            'latest_released_version': get_latest_released_app_version(domain, app_id)
        })
    else:
        return HttpResponseRedirect(reverse('release_manager', args=[domain, app_id]))
Example #13
0
def process_verification(phone_number, msg, backend_id=None):
    v = VerifiedNumber.by_phone(phone_number, True)
    if not v:
        return

    if not verification_response_ok(msg.text):
        return

    msg.domain = v.domain
    msg.couch_recipient_doc_type = v.owner_doc_type
    msg.couch_recipient = v.owner_id
    msg.save()

    if not domain_has_privilege(msg.domain, privileges.INBOUND_SMS):
        return

    if backend_id:
        backend = MobileBackend.load(backend_id)
    else:
        backend = MobileBackend.auto_load(phone_number, v.domain)

    # i don't know how to dynamically instantiate this object, which may be any number of doc types...
    #owner = CommCareMobileContactMixin.get(v.owner_id)
    assert v.owner_doc_type == 'CommCareUser'
    owner = CommCareUser.get(v.owner_id)

    v = owner.save_verified_number(v.domain, phone_number, True, backend.name)
    with localize(owner.language):
        send_sms_to_verified_number(v, _(CONFIRM))
Example #14
0
def user_can_view_deid_exports(domain, couch_user):
    return (domain_has_privilege(domain, privileges.DEIDENTIFIED_DATA)
            and couch_user.has_permission(
                domain,
                get_permission_name(Permissions.view_report),
                data=DEID_EXPORT_PERMISSION
            ))
Example #15
0
 def dispatch(self, request, *args, **kwargs):
     render_as = kwargs.get('render_as')
     if not render_as == 'email':
         return self.dispatch_with_priv(request, *args, **kwargs)
     if not domain_has_privilege(request.domain, privileges.CUSTOM_REPORTS):
         raise PermissionDenied()
     return super(CustomProjectReportDispatcher, self).dispatch(request, *args, **kwargs)
Example #16
0
 def dispatch(self, request_type, request, **kwargs):
     if request.user.is_superuser or domain_has_privilege(request.domain, privileges.API_ACCESS):
         return super(HqBaseResource, self).dispatch(request_type, request, **kwargs)
     else:
         raise ImmediateHttpResponse(HttpResponse(json.dumps({"error": "not authorized"}),
                                         content_type="application/json",
                                         status=401))
Example #17
0
def send_message_via_backend(msg, backend=None, orig_phone_number=None):
    """send sms using a specific backend

    msg - outbound message object
    backend - backend to use for sending; if None, msg.outbound_backend is used
    orig_phone_number - the originating phone number to use when sending; this
      is sent in if the backend supports load balancing
    """
    sms_load_counter("outbound", msg.domain)()
    try:
        msg.text = clean_text(msg.text)
    except Exception:
        logging.exception("Could not clean text for sms dated '%s' in domain '%s'" % (msg.date, msg.domain))
    try:
        # We need to send SMS when msg.domain is None to support sending to
        # people who opt in without being tied to a domain
        if msg.domain and not domain_has_privilege(msg.domain, privileges.OUTBOUND_SMS):
            raise Exception(
                ("Domain '%s' does not have permission to send SMS."
                 "  Please investigate why this function was called.") % msg.domain
            )

        phone_obj = PhoneBlacklist.get_by_phone_number_or_none(msg.phone_number)
        if phone_obj and not phone_obj.send_sms:
            if msg.ignore_opt_out and phone_obj.can_opt_in:
                # If ignore_opt_out is True on the message, then we'll still
                # send it. However, if we're not letting the phone number
                # opt back in and it's in an opted-out state, we will not
                # send anything to it no matter the state of the ignore_opt_out
                # flag.
                pass
            else:
                msg.set_system_error(SMS.ERROR_PHONE_NUMBER_OPTED_OUT)
                return False

        if not backend:
            backend = msg.outbound_backend

        if backend.domain_is_authorized(msg.domain):
            backend.send(msg, orig_phone_number=orig_phone_number)
        else:
            raise BackendAuthorizationException(
                "Domain '%s' is not authorized to use backend '%s'" % (msg.domain, backend.pk)
            )

        msg.backend_api = backend.hq_api_id
        msg.backend_id = backend.couch_id
        msg.save()
        return True
    except Exception:
        should_log_exception = True

        if backend:
            should_log_exception = should_log_exception_for_backend(backend)

        if should_log_exception:
            log_sms_exception(msg)

        return False
Example #18
0
def process_sms_registration(msg):
    """
    This method handles registration via sms.
    Returns True if a contact was registered, False if not.
    
    To have a case register itself, do the following:

        1) Select "Enable Case Registration Via SMS" in project settings, and fill in the
        associated Case Registration settings.

        2) Text in "join <domain>", where <domain> is the domain to join. If the sending
        number does not exist in the system, a case will be registered tied to that number.
        The "join" keyword can be any keyword in REGISTRATION_KEYWORDS. This is meant to
        support multiple translations.
    
    To have a mobile worker register itself, do the following:

        NOTE: This is not yet implemented and may change slightly.

        1) Select "Enable Mobile Worker Registration via SMS" in project settings.

        2) Text in "join <domain> worker", where <domain> is the domain to join. If the
        sending number does not exist in the system, a PendingCommCareUser object will be
        created, tied to that number.
        The "join" and "worker" keywords can be any keyword in REGISTRATION_KEYWORDS and
        REGISTRATION_MOBILE_WORKER_KEYWORDS, respectively. This is meant to support multiple 
        translations.

        3) A domain admin will have to approve the addition of the mobile worker before
        a CommCareUser can actually be created.
    """
    registration_processed = False
    text_words = msg.text.upper().split()
    keyword1 = text_words[0] if len(text_words) > 0 else ""
    keyword2 = text_words[1].lower() if len(text_words) > 1 else ""
    keyword3 = text_words[2] if len(text_words) > 2 else ""
    if keyword1 in REGISTRATION_KEYWORDS and keyword2 != "":
        domain = Domain.get_by_name(keyword2, strict=True)
        if domain is not None:
            if domain_has_privilege(domain, privileges.INBOUND_SMS):
                if keyword3 in REGISTRATION_MOBILE_WORKER_KEYWORDS and domain.sms_mobile_worker_registration_enabled:
                    #TODO: Register a PendingMobileWorker object that must be approved by a domain admin
                    pass
                elif domain.sms_case_registration_enabled:
                    register_sms_contact(
                        domain=domain.name,
                        case_type=domain.sms_case_registration_type,
                        case_name="unknown",
                        user_id=domain.sms_case_registration_user_id,
                        contact_phone_number=strip_plus(msg.phone_number),
                        contact_phone_number_is_verified="1",
                        owner_id=domain.sms_case_registration_owner_id,
                    )
                    registration_processed = True
            msg.domain = domain.name
            msg.save()

    return registration_processed
Example #19
0
def parse_users(group_memoizer, domain, user_data_model, location_cache):

    def _get_group_names(user):
        return sorted(map(
            lambda id: group_memoizer.get(id).name,
            Group.by_user(user, wrap=False)
        ), key=alphanumeric_sort_key)

    def _make_user_dict(user, group_names, location_cache):
        model_data, uncategorized_data = (
            user_data_model.get_model_and_uncategorized(user.user_data)
        )
        return {
            'data': model_data,
            'uncategorized_data': uncategorized_data,
            'group': group_names,
            'name': user.full_name,
            'password': "******",  # dummy display string for passwords
            'phone-number': user.phone_number,
            'email': user.email,
            'username': user.raw_username,
            'language': user.language,
            'user_id': user._id,
            'is_active': str(user.is_active),
            'location_code': location_cache.get(user.location_id),
        }

    unrecognized_user_data_keys = set()
    user_groups_length = 0
    user_dicts = []
    for user in get_all_commcare_users_by_domain(domain):
        group_names = _get_group_names(user)
        user_dict = _make_user_dict(user, group_names, location_cache)
        user_dicts.append(user_dict)
        unrecognized_user_data_keys.update(user_dict['uncategorized_data'].keys())
        user_groups_length = max(user_groups_length, len(group_names))

    user_headers = [
        'username', 'password', 'name', 'phone-number', 'email',
        'language', 'user_id', 'is_active',
    ]
    if domain_has_privilege(domain, privileges.LOCATIONS):
        user_headers.append('location_code')
    user_data_fields = [f.slug for f in user_data_model.get_fields(include_system=False)]
    user_headers.extend(build_data_headers(user_data_fields))
    user_headers.extend(build_data_headers(
        unrecognized_user_data_keys,
        header_prefix='uncategorized_data'
    ))
    user_headers.extend(json_to_headers(
        {'group': range(1, user_groups_length + 1)}
    ))

    def _user_rows():
        for user_dict in user_dicts:
            row = dict(flatten_json(user_dict))
            yield [row.get(header) or '' for header in user_headers]
    return user_headers, _user_rows()
Example #20
0
def send_message_via_backend(msg, backend=None, orig_phone_number=None):
    """send sms using a specific backend

    msg - outbound message object
    backend - MobileBackend object to use for sending; if None, use
      msg.outbound_backend
    orig_phone_number - the originating phone number to use when sending; this
      is sent in if the backend supports load balancing
    """
    try:
        msg.text = clean_text(msg.text)
    except Exception:
        logging.exception("Could not clean text for sms dated '%s' in domain '%s'" % (msg.date, msg.domain))
    try:
        if not domain_has_privilege(msg.domain, privileges.OUTBOUND_SMS):
            raise Exception(
                ("Domain '%s' does not have permission to send SMS."
                 "  Please investigate why this function was called.") % msg.domain
            )

        phone_obj = PhoneNumber.get_by_phone_number_or_none(msg.phone_number)
        if phone_obj and not phone_obj.send_sms:
            if msg.ignore_opt_out and phone_obj.can_opt_in:
                # If ignore_opt_out is True on the message, then we'll still
                # send it. However, if we're not letting the phone number
                # opt back in and it's in an opted-out state, we will not
                # send anything to it no matter the state of the ignore_opt_out
                # flag.
                pass
            else:
                msg.set_system_error(SMS.ERROR_PHONE_NUMBER_OPTED_OUT)
                return False

        if not backend:
            backend = msg.outbound_backend
            # note: this will handle "verified" contacts that are still pending
            # verification, thus the backend is None. it's best to only call
            # send_sms_to_verified_number on truly verified contacts, though

        if not msg.backend_id:
            msg.backend_id = backend._id

        if backend.domain_is_authorized(msg.domain):
            backend.send(msg, orig_phone_number=orig_phone_number)
        else:
            raise BackendAuthorizationException("Domain '%s' is not authorized to use backend '%s'" % (msg.domain, backend._id))

        try:
            msg.backend_api = backend.__class__.get_api_id()
        except Exception:
            pass
        msg.save()
        create_billable_for_sms(msg)
        return True
    except Exception:
        log_sms_exception(msg)
        return False
Example #21
0
def get_extra_permissions():
    from corehq.apps.export.views import FormExportListView, DeIdFormExportListView, CaseExportListView
    yield ReportPermission(
        FORM_EXPORT_PERMISSION, FormExportListView.page_title, lambda domain: True)
    yield ReportPermission(
        DEID_EXPORT_PERMISSION, DeIdFormExportListView.page_title,
        lambda domain: domain_has_privilege(domain, privileges.DEIDENTIFIED_DATA))
    yield ReportPermission(
        CASE_EXPORT_PERMISSION, CaseExportListView.page_title, lambda domain: True)
Example #22
0
def post_user_role(request, domain):
    if not domain_has_privilege(domain, privileges.ROLE_BASED_ACCESS):
        return json_response({})
    role_data = json.loads(request.body)
    role_data = dict(
        (p, role_data[p])
        for p in set(list(UserRole.properties()) + ['_id', '_rev']) if p in role_data
    )
    if (
        not domain_has_privilege(domain, privileges.RESTRICT_ACCESS_BY_LOCATION)
        and not role_data['permissions']['access_all_locations']
    ):
        # This shouldn't be possible through the UI, but as a safeguard...
        role_data['permissions']['access_all_locations'] = True

    role = UserRole.wrap(role_data)
    role.domain = domain
    if role.get_id:
        old_role = UserRole.get(role.get_id)
        assert(old_role.doc_type == UserRole.__name__)
        assert(old_role.domain == domain)

    if role.permissions.edit_web_users:
        role.permissions.view_web_users = True

    if role.permissions.edit_commcare_users:
        role.permissions.view_commcare_users = True

    if role.permissions.edit_groups:
        role.permissions.view_groups = True

    if role.permissions.edit_locations:
        role.permissions.view_locations = True

    if not role.permissions.edit_groups:
        role.permissions.edit_users_in_groups = False

    if not role.permissions.edit_locations:
        role.permissions.edit_users_in_locations = False

    role.save()
    role.__setattr__('hasUsersAssigned',
                     True if len(role.ids_of_assigned_users) > 0 else False)
    return json_response(role)
def get_per_domain_context(project, request=None):
    custom_logo_url = None
    if (project and project.has_custom_logo
        and domain_has_privilege(project.name, privileges.CUSTOM_BRANDING)
    ):
        custom_logo_url = reverse('logo', args=[project.name])

    return {
        'CUSTOM_LOGO_URL': custom_logo_url,
    }
Example #24
0
 def page_context(self):
     context = {
         'can_use_inbound_sms': domain_has_privilege(self.domain, privileges.INBOUND_SMS),
     }
     if (self.request.project.commtrack_enabled or
             self.request.project.locations_enabled):
         context.update({
             'update_form': self.commtrack_form,
         })
     return context
Example #25
0
    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user', None)
        domain = kwargs.get('domain', None)
        super(DomainMetadataForm, self).__init__(*args, **kwargs)

        project = Domain.get_by_name(domain)
        if project.cloudcare_releases == 'default' or not domain_has_privilege(domain, privileges.CLOUDCARE):
            # if the cloudcare_releases flag was just defaulted, don't bother showing
            # this setting at all
            self.fields['cloudcare_releases'].widget = forms.HiddenInput()
Example #26
0
def process_repeat_record(repeat_record):

    # A RepeatRecord should ideally never get into this state, as the
    # domain_has_privilege check is also triggered in the create_repeat_records
    # in signals.py. But if it gets here, forcefully cancel the RepeatRecord.
    # todo reconcile ZAPIER_INTEGRATION and DATA_FORWARDING
    #  they each do two separate things and are priced differently,
    #  but use the same infrastructure
    if not (domain_has_privilege(repeat_record.domain, ZAPIER_INTEGRATION)
            or domain_has_privilege(repeat_record.domain, DATA_FORWARDING)):
        repeat_record.cancel()
        repeat_record.save()

    if (repeat_record.state == RECORD_FAILURE_STATE and
            repeat_record.overall_tries >= repeat_record.max_possible_tries):
        repeat_record.cancel()
        repeat_record.save()
        return
    if repeat_record.cancelled:
        return

    repeater = repeat_record.repeater
    if not repeater:
        repeat_record.cancel()
        repeat_record.save()
        return

    try:
        if repeater.paused:
            # postpone repeat record by 1 day so that these don't get picked in each cycle and
            # thus clogging the queue with repeat records with paused repeater
            repeat_record.postpone_by(timedelta(days=1))
            return
        if repeater.doc_type.endswith(DELETED_SUFFIX):
            if not repeat_record.doc_type.endswith(DELETED_SUFFIX):
                repeat_record.doc_type += DELETED_SUFFIX
                repeat_record.save()
        elif repeat_record.state == RECORD_PENDING_STATE or repeat_record.state == RECORD_FAILURE_STATE:
            repeat_record.fire()
    except Exception:
        logging.exception('Failed to process repeat record: {}'.format(
            repeat_record._id))
Example #27
0
def get_releases_context(request, domain, app_id):
    app = get_app(domain, app_id)
    can_send_sms = domain_has_privilege(domain, privileges.OUTBOUND_SMS)
    build_profile_access = domain_has_privilege(domain, privileges.BUILD_PROFILES)
    prompt_settings_form = PromptUpdateSettingsForm.from_app(app, request_user=request.couch_user)

    context = {
        'release_manager': True,
        'can_send_sms': can_send_sms,
        'can_view_cloudcare': has_privilege(request, privileges.CLOUDCARE),
        'has_mobile_workers': get_doc_count_in_domain_by_class(domain, CommCareUser) > 0,
        'latest_released_version': get_latest_released_app_version(domain, app_id),
        'sms_contacts': (
            get_sms_autocomplete_context(request, domain)['sms_contacts']
            if can_send_sms else []
        ),
        'build_profile_access': build_profile_access,
        'application_profile_url': reverse(LanguageProfilesView.urlname, args=[domain, app_id]),
        'lastest_j2me_enabled_build': CommCareBuildConfig.latest_j2me_enabled_config().label,
        'fetchLimit': request.GET.get('limit', DEFAULT_FETCH_LIMIT),
        'latest_build_id': get_latest_build_id(domain, app_id),
        'prompt_settings_url': reverse(PromptSettingsUpdateView.urlname, args=[domain, app_id]),
        'prompt_settings_form': prompt_settings_form,
        'full_name': request.couch_user.full_name,
        'can_manage_releases': can_manage_releases(request.couch_user, request.domain, app_id)
    }
    if not app.is_remote_app():
        context.update({
            'enable_update_prompts': app.enable_update_prompts,
        })
        if len(app.modules) == 0:
            context.update({'intro_only': True})

        # Multimedia is not supported for remote applications at this time.
        try:
            multimedia_state = app.check_media_state()
            context.update({
                'multimedia_state': multimedia_state,
            })
        except ReportConfigurationNotFoundError:
            pass
    return context
Example #28
0
def get_releases_context(request, domain, app_id):
    app = get_app(domain, app_id)
    can_send_sms = domain_has_privilege(domain, privileges.OUTBOUND_SMS)
    build_profile_access = domain_has_privilege(domain, privileges.BUILD_PROFILES)
    prompt_settings_form = PromptUpdateSettingsForm.from_app(app, request_user=request.couch_user)

    context = {
        'release_manager': True,
        'can_send_sms': can_send_sms,
        'can_view_cloudcare': has_privilege(request, privileges.CLOUDCARE),
        'has_mobile_workers': get_doc_count_in_domain_by_class(domain, CommCareUser) > 0,
        'latest_released_version': get_latest_released_app_version(domain, app_id),
        'sms_contacts': (
            get_sms_autocomplete_context(request, domain)['sms_contacts']
            if can_send_sms else []
        ),
        'build_profile_access': build_profile_access,
        'application_profile_url': reverse(LanguageProfilesView.urlname, args=[domain, app_id]),
        'lastest_j2me_enabled_build': CommCareBuildConfig.latest_j2me_enabled_config().label,
        'latest_build_id': get_latest_build_id(domain, app_id),
        'prompt_settings_url': reverse(PromptSettingsUpdateView.urlname, args=[domain, app_id]),
        'prompt_settings_form': prompt_settings_form,
        'full_name': request.couch_user.full_name,
        'can_manage_releases': can_manage_releases(request.couch_user, request.domain, app_id),
        'can_edit_apps': request.couch_user.can_edit_apps(),
    }
    if not app.is_remote_app():
        context.update({
            'enable_update_prompts': app.enable_update_prompts,
        })
        if len(app.modules) == 0:
            context.update({'intro_only': True})

        # Multimedia is not supported for remote applications at this time.
        try:
            multimedia_state = app.check_media_state()
            context.update({
                'multimedia_state': multimedia_state,
            })
        except ReportConfigurationNotFoundError:
            pass
    return context
Example #29
0
    def obj_get_list(self, bundle, **kwargs):
        domain = kwargs['domain']
        couch_user = CouchUser.from_django_user(bundle.request.user)
        if not domain_has_privilege(domain, privileges.ZAPIER_INTEGRATION) or not couch_user.is_member_of(domain):
            raise ImmediateHttpResponse(
                HttpForbidden('You are not allowed to get list of case types for this domain')
            )

        case_types = get_case_types_for_domain_es(domain)
        results = [CaseType(case_type=case_type) for case_type in case_types]
        return results
Example #30
0
 def page_context(self):
     owner_id = self.export_instance.owner_id
     return {
         'export_instance':
         self.export_instance,
         'export_home_url':
         self.export_home_url,
         'allow_deid':
         has_privilege(self.request, privileges.DEIDENTIFIED_DATA),
         'has_excel_dashboard_access':
         domain_has_privilege(self.domain, EXCEL_DASHBOARD),
         'has_daily_saved_export_access':
         domain_has_privilege(self.domain, DAILY_SAVED_EXPORT),
         'can_edit':
         self.export_instance.can_edit(self.request.couch_user),
         'has_other_owner':
         owner_id and owner_id != self.request.couch_user.user_id,
         'owner_name':
         WebUser.get_by_user_id(owner_id).username if owner_id else None,
     }
Example #31
0
    def obj_get_list(self, bundle, **kwargs):
        domain = kwargs['domain']
        couch_user = CouchUser.from_django_user(bundle.request.user)
        if not domain_has_privilege(domain, privileges.ZAPIER_INTEGRATION) or not couch_user.is_member_of(domain):
            raise ImmediateHttpResponse(
                HttpForbidden('You are not allowed to get list of case types for this domain')
            )

        case_types = get_case_types_for_domain_es(domain)
        results = [CaseType(case_type=case_type) for case_type in case_types]
        return results
Example #32
0
def process_incoming(msg, delay=True):
    v = VerifiedNumber.by_phone(msg.phone_number, include_pending=True)

    if v is not None and v.verified:
        msg.couch_recipient_doc_type = v.owner_doc_type
        msg.couch_recipient = v.owner_id
        msg.domain = v.domain
        contact = v.owner
        if isinstance(contact, CommCareUser) and hasattr(contact, 'location_id'):
            msg.location_id = contact.location_id
        msg.save()

    if msg.domain_scope:
        # only process messages for phones known to be associated with this domain
        if v is None or v.domain != msg.domain_scope:
            raise DomainScopeValidationError(
                'Attempted to simulate incoming sms from phone number not ' \
                'verified with this domain'
            )

    can_receive_sms = PhoneNumber.can_receive_sms(msg.phone_number)
    opt_in_keywords, opt_out_keywords = get_opt_keywords(msg)
    if is_opt_message(msg.text, opt_out_keywords) and can_receive_sms:
        if PhoneNumber.opt_out_sms(msg.phone_number):
            metadata = MessageMetadata(ignore_opt_out=True)
            text = get_message(MSG_OPTED_OUT, v, context=(opt_in_keywords[0],))
            if v:
                send_sms_to_verified_number(v, text, metadata=metadata)
            else:
                send_sms(msg.domain, None, msg.phone_number, text, metadata=metadata)
    elif is_opt_message(msg.text, opt_in_keywords) and not can_receive_sms:
        if PhoneNumber.opt_in_sms(msg.phone_number):
            text = get_message(MSG_OPTED_IN, v, context=(opt_out_keywords[0],))
            if v:
                send_sms_to_verified_number(v, text)
            else:
                send_sms(msg.domain, None, msg.phone_number, text)
    elif v is not None and v.verified:
        if domain_has_privilege(msg.domain, privileges.INBOUND_SMS):
            for h in settings.SMS_HANDLERS:
                try:
                    handler = to_function(h)
                except:
                    notify_exception(None, message=('error loading sms handler: %s' % h))
                    continue

                try:
                    was_handled = handler(v, msg.text, msg=msg)
                except Exception, e:
                    log_sms_exception(msg)
                    was_handled = False

                if was_handled:
                    break
Example #33
0
def _get_vellum_features(request, domain, app):
    """
    Returns the context of features passed into vellum when it is initialized.
    """
    vellum_features = toggles.toggles_dict(username=request.user.username,
                                           domain=domain)
    vellum_features.update({
        'group_in_field_list': app.enable_group_in_field_list,
        'image_resize': app.enable_image_resize,
        'markdown_in_groups': app.enable_markdown_in_groups,
        'lookup_tables': domain_has_privilege(domain, privileges.LOOKUP_TABLES),
        'templated_intents': domain_has_privilege(domain,
                                                  privileges.TEMPLATED_INTENTS),
        'custom_intents': domain_has_privilege(domain,
                                               privileges.CUSTOM_INTENTS),
        'rich_text': True,
        'sorted_itemsets': app.enable_sorted_itemsets,
        'advanced_itemsets': add_ons.show("advanced_itemsets", request, app),
    })
    return vellum_features
Example #34
0
def get_extra_permissions():
    from corehq.apps.export.views.list import (
        FormExportListView,
        CaseExportListView,
        ODataFeedListView,
    )
    from corehq.apps.export.views.download import DownloadNewSmsExportView
    yield ReportPermission(
        FORM_EXPORT_PERMISSION, FormExportListView.page_title, lambda domain: True)
    yield ReportPermission(
        DEID_EXPORT_PERMISSION, ugettext_noop("Export De-Identified Data"),
        lambda domain: domain_has_privilege(domain, privileges.DEIDENTIFIED_DATA))
    yield ReportPermission(
        CASE_EXPORT_PERMISSION, CaseExportListView.page_title, lambda domain: True)
    yield ReportPermission(
        SMS_EXPORT_PERMISSION, DownloadNewSmsExportView.page_title, lambda domain: True)
    yield ReportPermission(
        ODATA_FEED_PERMISSION, ODataFeedListView.page_title,
        lambda domain: domain_has_privilege(domain, privileges.ODATA_FEED)
    )
Example #35
0
def commit_filters(request, domain):
    permissions = ExportsPermissionsManager(request.POST.get('model_type'),
                                            domain, request.couch_user)
    if not permissions.has_edit_permissions:
        raise Http404
    export_id = request.POST.get('export_id')
    form_data = json.loads(request.POST.get('form_data'))
    export = get_properly_wrapped_export_instance(export_id)
    if export.is_daily_saved_export and not domain_has_privilege(
            domain, DAILY_SAVED_EXPORT):
        raise Http404
    if export.export_format == "html" and not domain_has_privilege(
            domain, EXCEL_DASHBOARD):
        raise Http404
    if not export.filters.is_location_safe_for_user(request):
        return location_restricted_response(request)
    domain_object = Domain.get_by_name(domain)
    filter_form = DashboardFeedFilterForm(domain_object, form_data)
    if filter_form.is_valid():
        old_can_access_all_locations = export.filters.can_access_all_locations
        old_accessible_location_ids = export.filters.accessible_location_ids
        filters = filter_form.to_export_instance_filters(
            # using existing location restrictions prevents a less restricted user from modifying
            # restrictions on an export that a more restricted user created (which would mean the more
            # restricted user would lose access to the export)
            old_can_access_all_locations,
            old_accessible_location_ids)
        if export.filters != filters:
            export.filters = filters
            export.save()
            rebuild_saved_export(export_id, manual=True)
        return json_response({
            'success': True,
        })
    else:
        return json_response({
            'success':
            False,
            'error':
            _("Problem saving dashboard feed filters: Invalid form"),
        })
Example #36
0
 def permissions_check(self,
                       report,
                       request,
                       domain=None,
                       is_navigation_check=False):
     from corehq.motech.repeaters.views import DomainForwardingRepeatRecords
     if (report.endswith(DomainForwardingRepeatRecords.__name__) and
             not domain_has_privilege(domain, privileges.DATA_FORWARDING)):
         return False
     return super(DomainReportDispatcher,
                  self).permissions_check(report, request, domain,
                                          is_navigation_check)
Example #37
0
 def get_object_list(self, request):
     couch_user = CouchUser.from_django_user(request.user)
     results = []
     for domain in couch_user.get_domains():
         if not domain_has_privilege(domain, privileges.ZAPIER_INTEGRATION):
             continue
         domain_object = Domain.get_by_name(domain)
         results.append(
             UserDomain(domain_name=domain_object.name,
                        project_name=domain_object.hr_name
                        or domain_object.name))
     return results
Example #38
0
def delete_user_role(request, domain):
    if not domain_has_privilege(domain, privileges.ROLE_BASED_ACCESS):
        return json_response({})
    role_data = json.loads(request.body)
    try:
        role = UserRole.get(role_data["_id"])
    except ResourceNotFound:
        return json_response({})
    copy_id = role._id
    role.delete()
    # return removed id in order to remove it from UI
    return json_response({"_id": copy_id})
Example #39
0
def delete_user_role(request, domain):
    if not domain_has_privilege(domain, privileges.ROLE_BASED_ACCESS):
        return json_response({})
    role_data = json.loads(request.body)
    try:
        role = UserRole.get(role_data["_id"])
    except ResourceNotFound:
        return json_response({})
    copy_id = role._id
    role.delete()
    # return removed id in order to remove it from UI
    return json_response({"_id": copy_id})
Example #40
0
 def page_context(self):
     bulk_sms_verification_enabled = (
         any(toggles.BULK_SMS_VERIFICATION.enabled(item)
             for item in [self.request.couch_user.username, self.domain]) and
         domain_has_privilege(self.domain, privileges.INBOUND_SMS)
     )
     return {
         'group': self.group,
         'bulk_sms_verification_enabled': bulk_sms_verification_enabled,
         'num_users': len(self.member_ids),
         'user_form': self.user_selection_form
     }
Example #41
0
 def dispatch(self, request_type, request, **kwargs):
     if not domain_has_privilege(request.domain, privileges.ODATA_FEED):
         raise ImmediateHttpResponse(
             response=HttpResponseNotFound('Feature flag not enabled.'))
     self.config_id = kwargs['config_id']
     self.table_id = int(kwargs.get('table_id', 0))
     with TimingContext() as timer:
         response = super(BaseODataResource,
                          self).dispatch(request_type, request, **kwargs)
     record_feed_access_in_datadog(request, self.config_id, timer.duration,
                                   response)
     return response
Example #42
0
    def permissions_check(self, report, request, domain=None, is_navigation_check=False):
        from corehq.motech.repeaters.views import DomainForwardingRepeatRecords
        from corehq.apps.export.views.incremental import IncrementalExportLogView

        from corehq.toggles import INCREMENTAL_EXPORTS

        if (report.endswith(DomainForwardingRepeatRecords.__name__)
                and not domain_has_privilege(domain, privileges.DATA_FORWARDING)):
            return False
        if (report.endswith(IncrementalExportLogView.__name__) and not INCREMENTAL_EXPORTS.enabled(domain)):
            return False
        return super(DomainReportDispatcher, self).permissions_check(report, request, domain, is_navigation_check)
Example #43
0
def get_releases_context(request, domain, app_id):
    app = get_app(domain, app_id)
    context = get_apps_base_context(request, domain, app)
    can_send_sms = domain_has_privilege(domain, privileges.OUTBOUND_SMS)
    build_profile_access = domain_has_privilege(domain,
                                                privileges.BUILD_PROFILES)

    context.update({
        'release_manager':
        True,
        'can_send_sms':
        can_send_sms,
        'has_mobile_workers':
        get_doc_count_in_domain_by_class(domain, CommCareUser) > 0,
        'sms_contacts': (get_sms_autocomplete_context(
            request, domain)['sms_contacts'] if can_send_sms else []),
        'build_profile_access':
        build_profile_access,
        'application_profile_url':
        reverse(LanguageProfilesView.urlname, args=[domain, app_id]),
        'lastest_j2me_enabled_build':
        CommCareBuildConfig.latest_j2me_enabled_config().label,
        'fetchLimit':
        request.GET.get('limit', DEFAULT_FETCH_LIMIT),
        'latest_build_id':
        get_latest_build_id(domain, app_id)
    })
    if not app.is_remote_app():
        if toggles.APP_MANAGER_V2.enabled(request.user.username) and len(
                app.modules) == 0:
            context.update({'intro_only': True})
        # Multimedia is not supported for remote applications at this time.
        try:
            multimedia_state = app.check_media_state()
            context.update({
                'multimedia_state': multimedia_state,
            })
        except ReportConfigurationNotFoundError:
            pass
    return context
Example #44
0
    def page_context(self):
        owner_id = self.export_instance.owner_id
        schema = self.get_export_schema(
            self.domain,
            self.request.GET.get('app_id')
            or getattr(self.export_instance, 'app_id'),
            self.export_instance.identifier,
        )
        if self.export_instance.owner_id or not self.export_instance._id:
            sharing_options = SharingOption.CHOICES
        else:
            sharing_options = [SharingOption.EDIT_AND_EXPORT]

        allow_deid = has_privilege(self.request, privileges.DEIDENTIFIED_DATA)

        return {
            'export_instance':
            self.export_instance,
            'export_home_url':
            self.export_home_url,
            'allow_deid':
            allow_deid,
            'has_excel_dashboard_access':
            domain_has_privilege(self.domain, EXCEL_DASHBOARD),
            'has_daily_saved_export_access':
            domain_has_privilege(self.domain, DAILY_SAVED_EXPORT),
            'can_edit':
            self.export_instance.can_edit(self.request.couch_user),
            'has_other_owner':
            owner_id and owner_id != self.request.couch_user.user_id,
            'owner_name':
            WebUser.get_by_user_id(owner_id).username if owner_id else None,
            'format_options': ["xls", "xlsx", "csv"],
            'number_of_apps_to_process':
            schema.get_number_of_apps_to_process(),
            'sharing_options':
            sharing_options,
            'terminology':
            self.terminology,
        }
Example #45
0
def make_mobile_user_dict(user, group_names, location_cache, domain, fields_definition):
    model_data = {}
    uncategorized_data = {}
    model_data, uncategorized_data = (
        fields_definition.get_model_and_uncategorized(user.metadata)
    )
    role = user.get_role(domain)
    profile = None
    if PROFILE_SLUG in user.metadata and domain_has_privilege(domain, privileges.APP_USER_PROFILES):
        try:
            profile = CustomDataFieldsProfile.objects.get(id=user.metadata[PROFILE_SLUG])
        except CustomDataFieldsProfile.DoesNotExist:
            profile = None
    activity = user.reporting_metadata

    location_codes = []
    try:
        location_codes.append(location_cache.get(user.location_id))
    except SQLLocation.DoesNotExist:
        pass
    for location_id in user.assigned_location_ids:
        # skip if primary location_id, as it is already added to the start of list above
        if location_id != user.location_id:
            try:
                location_codes.append(location_cache.get(location_id))
            except SQLLocation.DoesNotExist:
                pass

    def _format_date(date):
        return date.strftime('%Y-%m-%d %H:%M:%S') if date else ''

    return {
        'data': model_data,
        'uncategorized_data': uncategorized_data,
        'group': group_names,
        'name': user.full_name,
        'password': "******",  # dummy display string for passwords
        'phone-number': user.phone_number,
        'email': user.email,
        'username': user.raw_username,
        'language': user.language,
        'user_id': user._id,
        'is_active': str(user.is_active),
        'User IMEIs (read only)': get_devices(user),
        'location_code': location_codes,
        'role': role.name if role else '',
        'domain': domain,
        'user_profile': profile.name if profile else '',
        'registered_on (read only)': _format_date(user.created_on),
        'last_submission (read only)': _format_date(activity.last_submission_for_user.submission_date),
        'last_sync (read only)': activity.last_sync_for_user.sync_date,
    }
Example #46
0
def send_message_via_backend(msg, backend=None, orig_phone_number=None):
    """send sms using a specific backend

    msg - outbound message object
    backend - backend to use for sending; if None, msg.outbound_backend is used
    orig_phone_number - the originating phone number to use when sending; this
      is sent in if the backend supports load balancing
    """
    try:
        msg.text = clean_text(msg.text)
    except Exception:
        logging.exception(
            "Could not clean text for sms dated '%s' in domain '%s'" %
            (msg.date, msg.domain))
    try:
        if not domain_has_privilege(msg.domain, privileges.OUTBOUND_SMS):
            raise Exception(
                ("Domain '%s' does not have permission to send SMS."
                 "  Please investigate why this function was called.") %
                msg.domain)

        phone_obj = PhoneBlacklist.get_by_phone_number_or_none(
            msg.phone_number)
        if phone_obj and not phone_obj.send_sms:
            if msg.ignore_opt_out and phone_obj.can_opt_in:
                # If ignore_opt_out is True on the message, then we'll still
                # send it. However, if we're not letting the phone number
                # opt back in and it's in an opted-out state, we will not
                # send anything to it no matter the state of the ignore_opt_out
                # flag.
                pass
            else:
                msg.set_system_error(SMS.ERROR_PHONE_NUMBER_OPTED_OUT)
                return False

        if not backend:
            backend = msg.outbound_backend

        if backend.domain_is_authorized(msg.domain):
            backend.send(msg, orig_phone_number=orig_phone_number)
        else:
            raise BackendAuthorizationException(
                "Domain '%s' is not authorized to use backend '%s'" %
                (msg.domain, backend.pk))

        msg.backend_api = backend.hq_api_id
        msg.backend_id = backend.couch_id
        msg.save()
        return True
    except Exception:
        log_sms_exception(msg)
        return False
Example #47
0
def get_extra_permissions():
    from corehq.apps.export.views import (
        FormExportListView, DeIdFormExportListView, CaseExportListView, DownloadNewSmsExportView
    )
    yield ReportPermission(
        FORM_EXPORT_PERMISSION, FormExportListView.page_title, lambda domain: True)
    yield ReportPermission(
        DEID_EXPORT_PERMISSION, DeIdFormExportListView.page_title,
        lambda domain: domain_has_privilege(domain, privileges.DEIDENTIFIED_DATA))
    yield ReportPermission(
        CASE_EXPORT_PERMISSION, CaseExportListView.page_title, lambda domain: True)
    yield ReportPermission(
        SMS_EXPORT_PERMISSION, DownloadNewSmsExportView.page_title, lambda domain: True)
Example #48
0
 def page_context(self):
     domain_has_reminders_or_keywords = (domain_has_reminders(
         self.domain) or Keyword.domain_has_keywords(self.domain))
     bulk_sms_verification_enabled = (
         domain_has_reminders_or_keywords
         and domain_has_privilege(self.domain, privileges.INBOUND_SMS))
     return {
         'group': self.group,
         'bulk_sms_verification_enabled': bulk_sms_verification_enabled,
         'num_users': len(self.members),
         'group_membership_form': self.group_membership_form,
         'domain_uses_case_sharing': self.domain_uses_case_sharing,
     }
Example #49
0
 def page_context(self):
     bulk_sms_verification_enabled = (
         any(
             toggles.BULK_SMS_VERIFICATION.enabled(item)
             for item in [self.request.couch_user.username, self.domain])
         and domain_has_privilege(self.domain, privileges.INBOUND_SMS))
     return {
         'group': self.group,
         'bulk_sms_verification_enabled': bulk_sms_verification_enabled,
         'num_users': len(self.member_ids),
         'user_form': self.user_selection_form,
         'domain_uses_case_sharing': self.domain_uses_case_sharing,
     }
Example #50
0
    def obj_get_list(self, bundle, **kwargs):
        domain = kwargs['domain']

        couch_user = CouchUser.from_django_user(bundle.request.user)
        if not domain_has_privilege(domain, privileges.ZAPIER_INTEGRATION) or not couch_user.is_member_of(domain):
            raise ImmediateHttpResponse(
                HttpForbidden('You are not allowed to get list of usernames for this domain')
            )
        user_ids_username_pairs = get_all_user_id_username_pairs_by_domain(domain)

        results = [UserInfo(user_id=user_pair[0], user_name=raw_username(user_pair[1]))
                   for user_pair in user_ids_username_pairs]
        return results
Example #51
0
 def dispatch(self, request_type, request, **kwargs):
     if request.user.is_superuser or domain_has_privilege(
             request.domain, privileges.API_ACCESS):
         return super(HqBaseResource,
                      self).dispatch(request_type, request, **kwargs)
     else:
         raise ImmediateHttpResponse(
             HttpResponse(json.dumps({
                 "error":
                 "Your current plan does not have access to this feature"
             }),
                          content_type="application/json",
                          status=401))
Example #52
0
    def page_context(self):

        if self.request.is_view_only:
            make_form_readonly(self.commtrack_form)
            make_form_readonly(self.form_user_update.user_form)
            make_form_readonly(self.form_user_update.custom_data.form)

        context = {
            'are_groups':
            bool(len(self.all_groups)),
            'groups_url':
            reverse('all_groups', args=[self.domain]),
            'group_form':
            self.group_form,
            'reset_password_form':
            self.reset_password_form,
            'is_currently_logged_in_user':
            self.is_currently_logged_in_user,
            'is_delete_allowed':
            self.is_delete_allowed,
            'data_fields_form':
            self.form_user_update.custom_data.form,
            'can_use_inbound_sms':
            domain_has_privilege(self.domain, privileges.INBOUND_SMS),
            'can_create_groups':
            (self.request.couch_user.has_permission(self.domain, 'edit_groups')
             and self.request.couch_user.has_permission(
                 self.domain, 'access_all_locations')),
            'needs_to_downgrade_locations':
            (users_have_locations(self.domain)
             and not has_privilege(self.request, privileges.LOCATIONS)),
            'demo_restore_date':
            naturaltime(demo_restore_date_created(self.editable_user)),
            'hide_password_feedback':
            settings.ENABLE_DRACONIAN_SECURITY_FEATURES,
            'group_names': [g.name for g in self.groups],
        }
        if self.commtrack_form.errors:
            messages.error(
                self.request,
                _("There were some errors while saving user's locations. Please check the 'Locations' tab"
                  ))
        if self.domain_object.commtrack_enabled or self.domain_object.uses_locations:
            context.update({
                'commtrack_enabled': self.domain_object.commtrack_enabled,
                'uses_locations': self.domain_object.uses_locations,
                'commtrack': {
                    'update_form': self.commtrack_form,
                },
            })
        return context
Example #53
0
    def get(self, request, domain, app_id, **kwargs):
        app_access = get_application_access_for_domain(domain)

        app = get_current_app(domain, app_id)

        if not app_access.user_can_access_app(request.couch_user, app):
            raise Http404()

        role = request.couch_user.get_role(domain)
        if role and not role.permissions.view_web_app(app.master_id):
            raise Http404()

        def _default_lang():
            try:
                return app['langs'][0]
            except Exception:
                return 'en'

        # default language to user's preference, followed by
        # first app's default, followed by english
        language = request.couch_user.language or _default_lang()
        domain_obj = Domain.get_by_name(domain)

        context = {
            "domain":
            domain,
            "default_geocoder_location":
            domain_obj.default_geocoder_location,
            "language":
            language,
            "apps": [_format_app(app)],
            "mapbox_access_token":
            settings.MAPBOX_ACCESS_TOKEN,
            "username":
            request.user.username,
            "formplayer_url":
            settings.FORMPLAYER_URL,
            "single_app_mode":
            True,
            "home_url":
            reverse(self.urlname, args=[domain, app_id]),
            "environment":
            WEB_APPS_ENVIRONMENT,
            'use_live_query':
            toggles.FORMPLAYER_USE_LIVEQUERY.enabled(domain),
            "integrations":
            integration_contexts(domain),
            "has_geocoder_privs":
            domain_has_privilege(domain, privileges.GEOCODER),
        }
        return render(request, "cloudcare/formplayer_home.html", context)
Example #54
0
 def get_by_organization(cls, organization):
     result = cache_core.cached_view(cls.get_db(),
                                     "domain/by_organization",
                                     startkey=[organization],
                                     endkey=[organization, {}],
                                     reduce=False,
                                     include_docs=True,
                                     wrapper=cls.wrap)
     from corehq.apps.accounting.utils import domain_has_privilege
     from corehq import privileges
     result = filter(
         lambda x: domain_has_privilege(x.name, privileges.
                                        CROSS_PROJECT_REPORTS), result)
     return result
Example #55
0
    def commit(self, request):
        export = self.export_instance_cls.wrap(json.loads(request.body))
        if (self.domain != export.domain
                or (export.export_format == "html"
                    and not domain_has_privilege(self.domain, EXCEL_DASHBOARD))
                or
            (export.is_daily_saved_export
             and not domain_has_privilege(self.domain, DAILY_SAVED_EXPORT))):
            raise BadExportConfiguration()

        if not export._rev:
            if toggles.EXPORT_OWNERSHIP.enabled(request.domain):
                export.owner_id = request.couch_user.user_id
            if getattr(settings, "ENTERPRISE_MODE"):
                # default auto rebuild to False for enterprise clusters
                # only do this on first save to prevent disabling on every edit
                export.auto_rebuild_enabled = False
        export.save()
        messages.success(
            request,
            mark_safe(
                _("Export <strong>{}</strong> saved.").format(export.name)))
        return export._id
Example #56
0
def get_per_domain_context(project, request=None):
    custom_logo_url = None
    if (project and project.has_custom_logo
            and domain_has_privilege(project.name, privileges.CUSTOM_BRANDING)):
        custom_logo_url = reverse('logo', args=[project.name])

    report_an_issue = True
    if (hasattr(request, 'couch_user') and request.couch_user and project
            and not request.couch_user.has_permission(project.name, 'report_an_issue')):
        report_an_issue = False
    return {
        'CUSTOM_LOGO_URL': custom_logo_url,
        'allow_report_an_issue': report_an_issue,
    }
Example #57
0
    def get_main(self, request, domain):
        restore_as, set_cookie = self.get_restore_as_user(request, domain)
        apps = self.get_web_apps_available_to_user(domain, restore_as)

        def _default_lang():
            try:
                return apps[0]['langs'][0]
            except Exception:
                return 'en'

        # default language to user's preference, followed by
        # first app's default, followed by english
        language = request.couch_user.language or _default_lang()

        domain_obj = Domain.get_by_name(domain)

        context = {
            "domain":
            domain,
            "default_geocoder_location":
            domain_obj.default_geocoder_location,
            "language":
            language,
            "apps":
            apps,
            "domain_is_on_trial":
            domain_is_on_trial(domain),
            "mapbox_access_token":
            settings.MAPBOX_ACCESS_TOKEN,
            "username":
            request.couch_user.username,
            "formplayer_url":
            settings.FORMPLAYER_URL,
            "single_app_mode":
            False,
            "home_url":
            reverse(self.urlname, args=[domain]),
            "environment":
            WEB_APPS_ENVIRONMENT,
            'use_live_query':
            toggles.FORMPLAYER_USE_LIVEQUERY.enabled(domain),
            "integrations":
            integration_contexts(domain),
            "change_form_language":
            toggles.CHANGE_FORM_LANGUAGE.enabled(domain),
            "has_geocoder_privs":
            domain_has_privilege(domain, privileges.GEOCODER),
        }
        return set_cookie(
            render(request, "cloudcare/formplayer_home.html", context))
Example #58
0
def get_default_export_settings_if_available(domain):
    """
    Only creates settings if the domain has the DEFAULT_EXPORT_SETTINGS privilege
    """
    settings = None
    current_subscription = Subscription.get_active_subscription_by_domain(
        domain)
    if current_subscription and domain_has_privilege(domain,
                                                     DEFAULT_EXPORT_SETTINGS):
        from corehq.apps.export.models import DefaultExportSettings
        settings = DefaultExportSettings.objects.get_or_create(
            account=current_subscription.account)[0]

    return settings
Example #59
0
    def _check_subscription(self):

        def app_uses_usercase(app):
            return any(m.uses_usercase() for m in app.get_modules())

        errors = []
        if app_uses_usercase(self.app) and not domain_has_privilege(self.domain, privileges.USER_CASE):
            errors.append({
                'type': 'subscription',
                'message': _('Your application is using User Properties and your current subscription does not '
                             'support that. You can remove User Properties functionality by opening the User '
                             'Properties tab in a form that uses it, and clicking "Remove User Properties".'),
            })
        return errors
Example #60
0
def post_user_role(request, domain):
    if not domain_has_privilege(domain, privileges.ROLE_BASED_ACCESS):
        return json_response({})
    role_data = json.loads(request.body)
    role_data = dict(
        (p, role_data[p])
        for p in set(list(UserRole.properties()) + ['_id', '_rev']) if p in role_data
    )
    if (
        not domain_has_privilege(domain, privileges.RESTRICT_ACCESS_BY_LOCATION)
        and not role_data['permissions']['access_all_locations']
    ):
        # This shouldn't be possible through the UI, but as a safeguard...
        role_data['permissions']['access_all_locations'] = True

    role = UserRole.wrap(role_data)
    role.domain = domain
    if role.get_id:
        old_role = UserRole.get(role.get_id)
        assert(old_role.doc_type == UserRole.__name__)
        assert(old_role.domain == domain)

    # temporarily assign new permissions until migration has finished, then we
    # can update the UI accordingly.
    role.permissions.view_web_users = role.permissions.edit_web_users
    role.permissions.view_roles = role.permissions.edit_web_users

    role.permissions.view_commcare_users = role.permissions.edit_commcare_users
    role.permissions.edit_groups = role.permissions.edit_commcare_users
    role.permissions.view_groups = role.permissions.edit_commcare_users

    role.permissions.view_locations = role.permissions.edit_locations

    role.save()
    role.__setattr__('hasUsersAssigned',
                     True if len(role.ids_of_assigned_users) > 0 else False)
    return json_response(role)