Example #1
0
    def __init__(self, is_superuser=False, *args, **kwargs):
        super(InitiateAddSMSBackendForm, self).__init__(*args, **kwargs)
        backend_classes = get_available_backends()
        backend_choices = []
        for name, klass in backend_classes.items():
            if is_superuser or name == "TelerivetBackend":
                try:
                    friendly_name = klass.get_generic_name()
                except NotImplementedError:
                    friendly_name = name
                backend_choices.append((name, friendly_name))
        self.fields['backend_type'].choices = backend_choices

        self.helper = FormHelper()
        self.helper.form_class = "form form-horizontal"
        self.helper.layout = crispy.Layout(
            BootstrapMultiField(
                _("Create Another Connection"),
                InlineField('action'),
                InlineField('backend_type'),
                StrictButton(
                    mark_safe('<i class="icon-plus"></i> %s' % "Add Another Gateway"),
                    css_class='btn-success',
                    type='submit',
                    style="margin-left:5px;"
                ),
            ),
        )
Example #2
0
    def clean_name(self):
        value = self.cleaned_data.get("name")
        if value is not None:
            value = value.strip().upper()
        if value is None or value == "":
            raise ValidationError(_("This field is required."))
        if re.compile("\s").search(value) is not None:
            raise ValidationError(_("Name may not contain any spaces."))

        backend_classes = get_available_backends()
        if self._cchq_domain is None:
            # Ensure name is not duplicated among other global backends
            backend = SMSBackend.view(
                "sms/global_backends",
                classes=backend_classes,
                key=[value],
                include_docs=True,
                reduce=False
            ).one()
        else:
            # Ensure name is not duplicated among other backends owned by this domain
            backend = SMSBackend.view("sms/backend_by_owner_domain", classes=backend_classes, key=[self._cchq_domain, value], include_docs=True).one()
        if backend is not None and backend._id != self._cchq_backend_id:
            raise ValidationError(_("Name is already in use."))
        
        return value
Example #3
0
    def __init__(self, is_superuser=False, *args, **kwargs):
        super(InitiateAddSMSBackendForm, self).__init__(*args, **kwargs)
        backend_classes = get_available_backends()
        backend_choices = []
        for name, klass in backend_classes.items():
            if is_superuser or name == "TelerivetBackend":
                try:
                    friendly_name = klass.get_generic_name()
                except NotImplementedError:
                    friendly_name = name
                backend_choices.append((name, friendly_name))
        self.fields['backend_type'].choices = backend_choices

        self.helper = FormHelper()
        self.helper.form_class = "form form-horizontal"
        self.helper.layout = crispy.Layout(
            BootstrapMultiField(
                _("Create Another Connection"),
                InlineField('action'),
                InlineField('backend_type'),
                StrictButton(mark_safe('<i class="icon-plus"></i> %s' %
                                       "Add Another Gateway"),
                             css_class='btn-success',
                             type='submit',
                             style="margin-left:5px;"),
            ), )
Example #4
0
    def clean_name(self):
        value = self.cleaned_data.get("name")
        if value is not None:
            value = value.strip().upper()
        if value is None or value == "":
            raise ValidationError(_("This field is required."))
        if re.compile("\s").search(value) is not None:
            raise ValidationError(_("Name may not contain any spaces."))

        backend_classes = get_available_backends()
        if self._cchq_domain is None:
            # Ensure name is not duplicated among other global backends
            backend = SMSBackend.view("sms/global_backends",
                                      classes=backend_classes,
                                      key=[value],
                                      include_docs=True,
                                      reduce=False).one()
        else:
            # Ensure name is not duplicated among other backends owned by this domain
            backend = SMSBackend.view("sms/backend_by_owner_domain",
                                      classes=backend_classes,
                                      key=[self._cchq_domain, value],
                                      include_docs=True).one()
        if backend is not None and backend._id != self._cchq_backend_id:
            raise ValidationError(_("Name is already in use."))

        return value
Example #5
0
def arbitrary_fees_by_backend_instance(backend_ids):
    fees = {}
    for direction in DIRECTIONS:
        fees_by_backend = {}
        for backend in get_available_backends().values():
            fees_by_backend[backend.get_api_id()] = (backend_ids[backend.get_api_id()], arbitrary_fee())
        fees[direction] = fees_by_backend
    return fees
Example #6
0
def arbitrary_fees_by_direction_and_backend():
    fees = {}
    for direction in DIRECTIONS:
        fees_by_backend = {}
        for backend in get_available_backends().values():
            fees_by_backend[backend.get_api_id()] = arbitrary_fee()
        fees[direction] = fees_by_backend
    return fees
Example #7
0
def arbitrary_fees_by_direction_and_backend():
    fees = {}
    for direction in DIRECTIONS:
        fees_by_backend = {}
        for backend in get_available_backends().values():
            fees_by_backend[backend.get_api_id()] = arbitrary_fee()
        fees[direction] = fees_by_backend
    return fees
Example #8
0
 def wrap_correctly(self):
     from corehq.apps.sms.util import get_available_backends
     backend_classes = get_available_backends()
     doc_type = self.doc_type
     if doc_type in backend_classes:
         return backend_classes[doc_type].wrap(self.to_json())
     else:
         raise UnrecognizedBackendException("Backend %s has an "
             "unrecognized doc type." % self._id)
Example #9
0
def arbitrary_fees_by_backend_instance(backend_ids):
    fees = {}
    for direction in DIRECTIONS:
        fees_by_backend = {}
        for backend in get_available_backends().values():
            fees_by_backend[backend.get_api_id()] = (
                backend_ids[backend.get_api_id()], arbitrary_fee())
        fees[direction] = fees_by_backend
    return fees
Example #10
0
def arbitrary_backend_ids():
    backend_ids = {}
    for backend in get_available_backends().values():
        backend_instance = data_gen.arbitrary_unique_name("back")
        backend_ids[backend.get_api_id()] = backend_instance
        sms_backend = SMSBackend()
        sms_backend._id = backend_instance
        sms_backend.is_global = True
        sms_backend.save()
    return backend_ids
Example #11
0
def arbitrary_backend_ids():
    backend_ids = {}
    for backend in get_available_backends().values():
        backend_instance = data_gen.arbitrary_unique_name("back")
        backend_ids[backend.get_api_id()] = backend_instance
        sms_backend = SMSBackend()
        sms_backend._id = backend_instance
        sms_backend.is_global = True
        sms_backend.save()
    return backend_ids
Example #12
0
 def wrap_correctly(self):
     from corehq.apps.sms.util import get_available_backends
     backend_classes = get_available_backends()
     doc_type = self.doc_type
     if doc_type in backend_classes:
         return backend_classes[doc_type].wrap(self.to_json())
     else:
         raise UnrecognizedBackendException("Backend %s has an "
                                            "unrecognized doc type." %
                                            self._id)
Example #13
0
def _list_backends(request, show_global=False, domain=None):
    backend_classes = get_available_backends()
    backends = []
    editable_backend_ids = []
    default_sms_backend_id = None
    if not show_global:
        domain_obj = Domain.get_by_name(domain, strict=True)
    raw_backends = []
    if not show_global:
        raw_backends += SMSBackend.view(
            "sms/backend_by_domain",
            reduce=False,
            classes=backend_classes,
            startkey=[domain],
            endkey=[domain, {}],
            include_docs=True,
        ).all()
        if len(raw_backends) > 0 and domain_obj.default_sms_backend_id in [None, ""]:
            messages.error(
                request,
                _(
                    "WARNING: You have not specified a default SMS connection. By default, the system will automatically select one of the SMS connections owned by the system when sending sms."
                ),
            )
    raw_backends += SMSBackend.view(
        "sms/global_backends", classes=backend_classes, include_docs=True, reduce=False
    ).all()
    for backend in raw_backends:
        backends.append(backend_classes[backend.doc_type].wrap(backend.to_json()))
        if show_global or (not backend.is_global and backend.domain == domain):
            editable_backend_ids.append(backend._id)
        if not show_global and domain_obj.default_sms_backend_id == backend._id:
            default_sms_backend_id = backend._id
    instantiable_backends = []
    for name, klass in backend_classes.items():
        try:
            assert (
                request.couch_user.is_superuser or show_global or name == "TelerivetBackend"
            )  # TODO: Remove this once domain-specific billing is sorted out
            klass.get_generic_name()
            klass.get_form_class()
            instantiable_backends.append((name, klass))
        except Exception:
            pass
    instantiable_backends.sort(key=lambda t: t[0])
    context = {
        "show_global": show_global,
        "domain": domain,
        "backends": backends,
        "editable_backend_ids": editable_backend_ids,
        "default_sms_backend_id": default_sms_backend_id,
        "instantiable_backends": instantiable_backends,
    }
    return render(request, "sms/list_backends.html", context)
Example #14
0
def arbitrary_fees_by_country():
    fees = {}
    for direction in DIRECTIONS:
        fees_by_backend = {}
        for backend in get_available_backends().values():
            fees_by_country = {}
            for country in TEST_COUNTRY_CODES:
                fees_by_country[country] = arbitrary_fee()
            fees_by_backend[backend.get_api_id()] = fees_by_country
        fees[direction] = fees_by_backend
    return fees
Example #15
0
def arbitrary_fees_by_country():
    fees = {}
    for direction in DIRECTIONS:
        fees_by_backend = {}
        for backend in get_available_backends().values():
            fees_by_country = {}
            for country in TEST_COUNTRY_CODES:
                fees_by_country[country] = arbitrary_fee()
            fees_by_backend[backend.get_api_id()] = fees_by_country
        fees[direction] = fees_by_backend
    return fees
Example #16
0
 def load(cls, backend_id):
     """load a mobile backend
         backend_id  - the Couch document _id of the backend to load
     """
     # Circular import
     from corehq.apps.sms.util import get_available_backends
     backend_classes = get_available_backends()
     backend = cls.get(backend_id)
     if backend.doc_type not in backend_classes:
         raise Exception("Unexpected backend doc_type found '%s' for backend '%s'" % (backend.doc_type, backend._id))
     else:
         return backend_classes[backend.doc_type].wrap(backend.to_json())
Example #17
0
def global_backend_map(request):
    backend_classes = get_available_backends()
    global_backends = SMSBackend.view(
        "sms/global_backends",
        classes=backend_classes,
        include_docs=True,
        reduce=False
    ).all()
    current_map = {}
    catchall_entry = None
    for entry in BackendMapping.view("sms/backend_map", startkey=["*"], endkey=["*", {}], include_docs=True).all():
        if entry.prefix == "*":
            catchall_entry = entry
        else:
            current_map[entry.prefix] = entry
    if request.method == "POST":
        form = BackendMapForm(request.POST)
        if form.is_valid():
            new_backend_map = form.cleaned_data.get("backend_map")
            new_catchall_backend_id = form.cleaned_data.get("catchall_backend_id")
            for prefix, entry in current_map.items():
                if prefix not in new_backend_map:
                    current_map[prefix].delete()
                    del current_map[prefix]
            for prefix, backend_id in new_backend_map.items():
                if prefix in current_map:
                    current_map[prefix].backend_id = backend_id
                    current_map[prefix].save()
                else:
                    current_map[prefix] = BackendMapping(is_global=True, prefix=prefix, backend_id=backend_id)
                    current_map[prefix].save()
            if new_catchall_backend_id is None:
                if catchall_entry is not None:
                    catchall_entry.delete()
                    catchall_entry = None
            else:
                if catchall_entry is None:
                    catchall_entry = BackendMapping(is_global=True, prefix="*", backend_id=new_catchall_backend_id)
                else:
                    catchall_entry.backend_id = new_catchall_backend_id
                catchall_entry.save()
            messages.success(request, _("Changes Saved."))
    else:
        initial = {
            "catchall_backend_id" : catchall_entry.backend_id if catchall_entry is not None else None,
            "backend_map" : [{"prefix" : prefix, "backend_id" : entry.backend_id} for prefix, entry in current_map.items()],
        }
        form = BackendMapForm(initial=initial)
    context = {
        "backends" : global_backends,
        "form" : form,
    }
    return render(request, "sms/backend_map.html", context)
Example #18
0
def _add_backend(request, backend_class_name, is_global, domain=None, backend_id=None):
    # We can remove this restriction once we implement throttling of http backends, and billing for domain-specific backends
    if not (request.couch_user.is_superuser or is_global or backend_class_name == "TelerivetBackend"):
        raise Http404
    backend_classes = get_available_backends()
    backend_class = backend_classes[backend_class_name]
    
    backend = None
    if backend_id is not None:
        backend = backend_class.get(backend_id)
        if not is_global and backend.domain != domain:
            raise Http404
    
    ignored_fields = ["give_other_domains_access"]
    if request.method == "POST":
        form = backend_class.get_form_class()(request.POST)
        form._cchq_domain = domain
        form._cchq_backend_id = backend._id if backend is not None else None
        if form.is_valid():
            if backend is None:
                backend = backend_class(domain=domain, is_global=is_global)
            for key, value in form.cleaned_data.items():
                if key not in ignored_fields:
                    setattr(backend, key, value)
            backend.save()
            if is_global:
                return HttpResponseRedirect(reverse("list_backends"))
            else:
                return HttpResponseRedirect(reverse("list_domain_backends", args=[domain]))
    else:
        initial = {}
        if backend is not None:
            for field in backend_class.get_form_class()():
                if field.name not in ignored_fields:
                    if field.name == "authorized_domains":
                        initial[field.name] = ",".join(backend.authorized_domains)
                    else:
                        initial[field.name] = getattr(backend, field.name, None)
            if len(backend.authorized_domains) > 0:
                initial["give_other_domains_access"] = True
            else:
                initial["give_other_domains_access"] = False
        form = backend_class.get_form_class()(initial=initial)
    context = {
        "is_global" : is_global,
        "domain" : domain,
        "form" : form,
        "backend_class_name" : backend_class_name,
        "backend_generic_name" : backend_class.get_generic_name(),
        "backend_id" : backend_id,
    }
    return render(request, backend_class.get_template(), context)
Example #19
0
 def load(cls, backend_id):
     """load a mobile backend
         backend_id  - the Couch document _id of the backend to load
     """
     # Circular import
     from corehq.apps.sms.util import get_available_backends
     backend_classes = get_available_backends()
     backend = cls.get(backend_id)
     if backend.doc_type not in backend_classes:
         raise Exception(
             "Unexpected backend doc_type found '%s' for backend '%s'" %
             (backend.doc_type, backend._id))
     else:
         return backend_classes[backend.doc_type].wrap(backend.to_json())
Example #20
0
 def get_wrapped(cls, backend_id):
     from corehq.apps.sms.util import get_available_backends
     backend_classes = get_available_backends()
     try:
         backend = SMSBackend.get(backend_id)
     except ResourceNotFound:
         raise UnrecognizedBackendException("Backend %s not found" %
             backend_id)
     doc_type = backend.doc_type
     if doc_type in backend_classes:
         backend = backend_classes[doc_type].wrap(backend.to_json())
         return backend
     else:
         raise UnrecognizedBackendException("Backend %s has an "
             "unrecognized doc type." % backend_id)
    def setUp(self):
        self.currency_usd, _ = Currency.objects.get_or_create(
            code=settings.DEFAULT_CURRENCY,
            name="Default Currency",
            symbol="$",
            rate_to_default=Decimal('1.0')
        )
        self.available_backends = get_available_backends().values()

        self.backend_ids = generator.arbitrary_backend_ids()
        self.message_logs = generator.arbitrary_messages_by_backend_and_direction(self.backend_ids)

        self.least_specific_fees = generator.arbitrary_fees_by_direction_and_backend()
        self.country_code_fees = generator.arbitrary_fees_by_country()
        self.instance_fees = generator.arbitrary_fees_by_backend_instance(self.backend_ids)
        self.most_specific_fees = generator.arbitrary_fees_by_all(self.backend_ids)
Example #22
0
def arbitrary_fees_by_prefix(backend_ids, country_codes_and_prefixes):
    fees = {}
    for direction in DIRECTIONS:
        fees_by_backend = {}
        for backend in get_available_backends().values():
            fees_by_country_code = {}
            for country_code, _ in country_codes_and_prefixes:
                fees_by_country_code[country_code] = {}
            for country_code, prefix in country_codes_and_prefixes:
                fees_by_prefix = {
                    backend_instance: arbitrary_fee()
                    for backend_instance in [backend_ids[backend.get_api_id()], None]
                }
                fees_by_country_code[country_code][prefix] = fees_by_prefix
            fees_by_backend[backend.get_api_id()] = fees_by_country_code
        fees[direction] = fees_by_backend
    return fees
Example #23
0
def arbitrary_fees_by_prefix(backend_ids, country_codes_and_prefixes):
    fees = {}
    for direction in DIRECTIONS:
        fees_by_backend = {}
        for backend in get_available_backends().values():
            fees_by_country_code = {}
            for country_code, _ in country_codes_and_prefixes:
                fees_by_country_code[country_code] = {}
            for country_code, prefix in country_codes_and_prefixes:
                fees_by_prefix = {
                    backend_instance: arbitrary_fee()
                    for backend_instance in
                    [backend_ids[backend.get_api_id()], None]
                }
                fees_by_country_code[country_code][prefix] = fees_by_prefix
            fees_by_backend[backend.get_api_id()] = fees_by_country_code
        fees[direction] = fees_by_backend
    return fees
Example #24
0
    def setUp(self):
        SmsGatewayFee.objects.all().delete()
        SmsGatewayFeeCriteria.objects.all().delete()

        self.currency_usd = init_default_currency()
        self.available_backends = get_available_backends().values()

        self.backend_ids = generator.arbitrary_backend_ids()
        self.message_logs = generator.arbitrary_messages_by_backend_and_direction(
            self.backend_ids)

        self.least_specific_fees = generator.arbitrary_fees_by_direction_and_backend(
        )
        self.country_code_fees = generator.arbitrary_fees_by_country()
        self.instance_fees = generator.arbitrary_fees_by_backend_instance(
            self.backend_ids)
        self.most_specific_fees = generator.arbitrary_fees_by_all(
            self.backend_ids)
        self.country_code_and_prefixes = generator.arbitrary_country_code_and_prefixes(
        )
        self.prefix_fees = generator.arbitrary_fees_by_prefix(
            self.backend_ids, self.country_code_and_prefixes)

        self.other_currency = generator.arbitrary_currency()
Example #25
0
 def backend_classes(self):
     return get_available_backends()
Example #26
0
def get_opt_keywords(msg):
    backend_classes = get_available_backends(index_by_api_id=True)
    backend_class = backend_classes.get(msg.backend_api, SMSBackend)
    return (backend_class.get_opt_in_keywords(),
        backend_class.get_opt_out_keywords())
Example #27
0
def get_opt_keywords(msg):
    backend_classes = get_available_backends(index_by_api_id=True)
    backend_class = backend_classes.get(msg.backend_api, SMSBackend)
    return (backend_class.get_opt_in_keywords(),
            backend_class.get_opt_out_keywords())
Example #28
0
def arbitrary_backend_ids():
    backend_ids = {}
    for backend in get_available_backends().values():
        backend_ids[backend.get_api_id()] = data_gen.arbitrary_unique_name("back")
    return backend_ids
Example #29
0
def arbitrary_backend_ids():
    backend_ids = {}
    for backend in get_available_backends().values():
        backend_ids[backend.get_api_id()] = data_gen.arbitrary_unique_name(
            "back")
    return backend_ids