Example #1
0
    class Form(forms.Form):
        SLOT_CHOICES = (("staging", _("Staging")), ("production",
                                                    _("Production")))

        name = forms.CharField(help_text=_("The name of your LUIS app"))
        app_id = forms.CharField(label=_("App ID"),
                                 help_text=_("The ID of your LUIS app"))
        authoring_endpoint = ExternalURLField(
            help_text=_("The authoring resource endpoint URL"))
        authoring_key = forms.CharField(
            help_text=_("The authoring resource access key"))
        prediction_endpoint = ExternalURLField(
            help_text=_("The prediction resource endpoint URL"))
        prediction_key = forms.CharField(
            help_text=_("The prediction resource access key"))
        slot = forms.ChoiceField(help_text=_(
            "The slot where the prediction resource has been published"),
                                 choices=SLOT_CHOICES)

        def clean(self):
            cleaned = super().clean()

            if not self.is_valid():
                return cleaned

            # first check authoring credentials work
            try:
                client = AuthoringClient(cleaned["authoring_endpoint"],
                                         cleaned["authoring_key"])
                app_info = client.get_app(cleaned["app_id"])
                app_endpoints = app_info["endpoints"]
                if cleaned["slot"].upper() not in app_endpoints:
                    raise forms.ValidationError(
                        _("App has not yet been published to %s slot.") %
                        cleaned["slot"])
            except requests.RequestException as e:
                raise forms.ValidationError(
                    _("Check authoring credentials: %s") % str(e))

            # then check prediction credentials work
            try:
                client = PredictionClient(cleaned["prediction_endpoint"],
                                          cleaned["prediction_key"])
                client.predict(cleaned["app_id"], cleaned["slot"], "test")
            except requests.RequestException as e:
                raise forms.ValidationError(
                    _("Check prediction credentials: %s") % str(e))

            return cleaned
Example #2
0
 class Form(ClaimViewMixin.Form):
     country = forms.ChoiceField(
         choices=ALL_COUNTRIES,
         widget=SelectWidget(attrs={"searchable": True}),
         label=_("Country"),
         help_text=_("The country this phone number is used in"),
     )
     number = forms.CharField(
         max_length=14,
         min_length=4,
         label=_("Number"),
         help_text=("The shortcode or phone number you are connecting."),
     )
     url = ExternalURLField(
         label=_("URL"),
         help_text=
         _("The URL for the Junebug channel. ex: https://junebug.praekelt.org/jb/channels/3853bb51-d38a-4bca-b332-8a57c00f2a48/messages.json"
           ),
     )
     username = forms.CharField(
         label=_("Username"),
         help_text=_("The username to be used to authenticate to Junebug"),
         required=False)
     password = forms.CharField(
         label=_("Password"),
         help_text=_("The password to be used to authenticate to Junebug"),
         required=False)
     secret = forms.CharField(
         label=_("Secret"),
         help_text=_("The token Junebug should use to authenticate"),
         required=False)
Example #3
0
 class PMClaimForm(ClaimViewMixin.Form):
     base_url = ExternalURLField(label=_("Base URL"), help_text=_("The base URL for PlayMobile"))
     shortcode = forms.CharField(
         label=_("Shortcode"), max_length=15, min_length=1, help_text=_("The short code you are connecting")
     )
     username = forms.CharField(label=_("Username"), help_text=_("The username for your API account"))
     password = forms.CharField(label=_("Password"), help_text=_("The password for your API account"))
Example #4
0
    class Form(ClaimViewMixin.Form):
        number = forms.CharField(
            help_text=_("Your enterprise WhatsApp number"))
        country = forms.ChoiceField(
            choices=ALL_COUNTRIES,
            label=_("Country"),
            help_text=_("The country this phone number is used in"))
        base_url = ExternalURLField(help_text=_(
            "The base URL for your 360 Dialog WhatsApp enterprise installation"
        ))

        api_key = forms.CharField(
            max_length=256,
            help_text=_(
                "The 360 Dialog API key generated after account registration"))

        def clean(self):
            # first check that our phone number looks sane
            number, valid = URN.normalize_number(self.cleaned_data["number"],
                                                 self.cleaned_data["country"])
            if not valid:
                raise forms.ValidationError(
                    _("Please enter a valid phone number"))
            self.cleaned_data["number"] = number

            return self.cleaned_data
Example #5
0
    class Form(forms.Form):
        name = forms.CharField(help_text=_("The name of your LUIS app"))
        app_id = forms.CharField(label=_("App ID"),
                                 help_text=_("The ID for your LUIS app"))
        version = forms.CharField(
            help_text=_("The name of the version of your LUIS app to use"))
        primary_key = forms.CharField(
            help_text=_("The primary key for your LUIS app"))
        endpoint_url = ExternalURLField(
            help_text=_("The endpoint URL for your LUIS app"))

        def clean(self):
            from .type import LuisType

            cleaned = super().clean()

            if not self.is_valid():
                return cleaned

            endpoint = cleaned["endpoint_url"]

            # try to look up intents
            response = requests.get(
                endpoint + "/apps/" + cleaned["app_id"] + "/versions/" +
                cleaned["version"] + "/intents",
                headers={LuisType.AUTH_HEADER: cleaned["primary_key"]},
            )

            if response.status_code != 200:
                raise forms.ValidationError(
                    _("Unable to get intents for your app, please check credentials and try again"
                      ))

            return cleaned
Example #6
0
    class Form(BaseConnectView.Form):
        base_url = ExternalURLField(
            label=_("URL"),
            widget=forms.URLInput(
                attrs={
                    "placeholder":
                    _("Ex.: https://my.rocket.chat/api/apps/public/51c5cebe-b8e4-48ae-89d3-2b7746019cc4"
                      )
                }),
            help_text=_("URL of the Rocket.Chat Tickets app"),
        )
        admin_user_id = forms.CharField(
            label=_("Admin User ID"),
            help_text=_("User ID of an administrator user"))
        admin_auth_token = forms.CharField(
            label=_("Admin Auth Token"),
            help_text=_("Authentication token of an administrator user"))
        secret = forms.CharField(
            label=_("Secret"),
            widget=forms.HiddenInput(),
            help_text=_("Secret to be passed to Rocket.Chat"),
        )

        def clean(self):
            secret = self.cleaned_data.get("secret")
            if not secret:
                raise forms.ValidationError(_("Invalid secret code."))

            initial = self.initial.get("secret")
            if secret != initial:
                self.data = self.data.copy()
                self.data["secret"] = initial
                raise forms.ValidationError(_("Secret code change detected."))
            return self.cleaned_data

        def clean_base_url(self):
            from .type import RocketChatType

            org = self.request.user.get_org()
            base_url = RE_BASE_URL.search(
                self.cleaned_data.get("base_url") or "")
            if base_url:
                base_url = base_url.group()
            else:
                raise forms.ValidationError(
                    _("Invalid URL: %(base_url)s") % self.cleaned_data)

            base_url_exists = org.ticketers.filter(
                is_active=True,
                ticketer_type=RocketChatType.slug,
                **{
                    f"config__{RocketChatType.CONFIG_BASE_URL}": base_url
                },
            ).exists()
            if base_url_exists:
                raise forms.ValidationError(
                    _("There is already a ticketing service configured for this URL."
                      ))

            return base_url
Example #7
0
 class ShaqodoonForm(ClaimViewMixin.Form):
     country = forms.ChoiceField(
         choices=ALL_COUNTRIES, label=_("Country"), help_text=_("The country this phone number is used in")
     )
     number = forms.CharField(
         max_length=14, min_length=1, label=_("Number"), help_text=_("The short code you are connecting with.")
     )
     url = ExternalURLField(label=_("URL"), help_text=_("The url provided to deliver messages"))
     username = forms.CharField(label=_("Username"), help_text=_("The username provided to use their API"))
     password = forms.CharField(label=_("Password"), help_text=_("The password provided to use their API"))
Example #8
0
 class KannelClaimForm(ClaimViewMixin.Form):
     number = forms.CharField(
         max_length=14,
         min_length=1,
         label=_("Number"),
         help_text=_("The phone number or short code you are connecting"),
     )
     country = forms.ChoiceField(
         choices=ALL_COUNTRIES,
         widget=SelectWidget(attrs={"searchable": True}),
         label=_("Country"),
         help_text=_("The country this phone number is used in"),
     )
     url = ExternalURLField(
         max_length=1024,
         label=_("Send URL"),
         help_text=_(
             "The publicly accessible URL for your Kannel instance for sending. "
             "ex: https://kannel.macklemore.co/cgi-bin/sendsms"),
     )
     username = forms.CharField(
         max_length=64,
         required=False,
         help_text=_(
             "The username to use to authenticate to Kannel, if left blank we "
             "will generate one for you"),
     )
     password = forms.CharField(
         max_length=64,
         required=False,
         help_text=_(
             "The password to use to authenticate to Kannel, if left blank we "
             "will generate one for you"),
     )
     encoding = forms.ChoiceField(
         choices=Channel.ENCODING_CHOICES,
         label=_("Encoding"),
         help_text=_("What encoding to use for outgoing messages"),
     )
     verify_ssl = forms.BooleanField(
         initial=True,
         required=False,
         label=_("Verify SSL"),
         help_text=_("Whether to verify the SSL connection (recommended)"),
     )
     use_national = forms.BooleanField(
         initial=False,
         required=False,
         label=_("Use National Numbers"),
         help_text=_("Use only the national number (no country code) when "
                     "sending (not recommended)"),
     )
Example #9
0
 class TwimlApiClaimForm(ClaimViewMixin.Form):
     ROLES = (
         (Channel.ROLE_SEND + Channel.ROLE_RECEIVE, _("Messaging")),
         (Channel.ROLE_CALL + Channel.ROLE_ANSWER, _("Voice")),
         (Channel.ROLE_SEND + Channel.ROLE_RECEIVE + Channel.ROLE_CALL +
          Channel.ROLE_ANSWER, _("Both")),
     )
     country = forms.ChoiceField(
         choices=ALL_COUNTRIES,
         widget=SelectWidget(attrs={"searchable": True}),
         label=_("Country"),
         help_text=_("The country this phone number is used in"),
     )
     number = forms.CharField(
         max_length=14,
         min_length=1,
         label=_("Number"),
         help_text=
         _("The phone number without country code or short code you are connecting."
           ),
     )
     url = ExternalURLField(
         max_length=1024,
         label=_("TwiML REST API Host"),
         help_text=
         _("The publicly accessible URL for your TwiML REST API instance ex: https://api.twilio.com"
           ),
     )
     role = forms.ChoiceField(
         choices=ROLES,
         label=_("Role"),
         help_text=_("Choose the role that this channel supports"))
     account_sid = forms.CharField(
         max_length=64,
         required=False,
         help_text=_(
             "The Account SID to use to authenticate to the TwiML REST API"
         ),
         widget=forms.TextInput(attrs={"autocomplete": "off"}),
     )
     account_token = forms.CharField(
         max_length=64,
         required=False,
         help_text=_(
             "The Account Token to use to authenticate to the TwiML REST API"
         ),
         widget=forms.TextInput(attrs={"autocomplete": "off"}),
     )
     max_concurrent_events = forms.IntegerField(
         min_value=1,
         required=False,
         help_text=_("Max active calls at the same time"))
Example #10
0
    class SendClaimForm(ClaimViewMixin.Form):
        url = ExternalURLField(
            max_length=1024,
            label=_("Send URL"),
            help_text=_("The URL we will POST to when sending messages, with variable substitutions"),
        )

        method = forms.ChoiceField(
            choices=(("POST", "HTTP POST"), ("GET", "HTTP GET"), ("PUT", "HTTP PUT")),
            help_text=_("What HTTP method to use when calling the URL"),
        )

        encoding = forms.ChoiceField(
            choices=Channel.ENCODING_CHOICES,
            label=_("Encoding"),
            help_text=_("What encoding to use for outgoing messages"),
        )

        content_type = forms.ChoiceField(
            choices=Channel.CONTENT_TYPE_CHOICES, help_text=_("The content type used when sending the request")
        )

        max_length = forms.IntegerField(
            initial=160,
            validators=[MaxValueValidator(640), MinValueValidator(60)],
            help_text=_(
                "The maximum length of any single message on this channel. " "(longer messages will be split)"
            ),
        )

        send_authorization = forms.CharField(
            max_length=2048,
            label=_("Authorization Header Value"),
            required=False,
            help_text=_("The Authorization header value added when calling the URL (if any)"),
        )

        body = forms.CharField(
            max_length=2048,
            label=_("Request Body"),
            required=False,
            widget=forms.Textarea,
            help_text=_("The request body if any, with variable substitutions (only used for PUT or POST)"),
        )

        mt_response_check = forms.CharField(
            max_length=2048,
            label=_("MT Response check"),
            required=False,
            widget=forms.Textarea,
            help_text=_("The content that must be in the response to consider the request successful"),
        )
Example #11
0
    class JasminForm(ClaimViewMixin.Form):
        country = forms.ChoiceField(
            choices=ALL_COUNTRIES,
            widget=SelectWidget(attrs={"searchable": True}),
            label=_("Country"),
            help_text=_("The country this phone number is used in"),
        )
        number = forms.CharField(
            max_length=14,
            min_length=3,
            label=_("Number"),
            help_text=_("The short code or phone number you are connecting."),
        )
        url = ExternalURLField(
            widget=forms.URLInput(
                attrs={"placeholder": _("Ex: https://jasmin.gateway.io/send")
                       }),
            label=_("URL"),
            help_text=_("The URL for the Jasmin server send path"),
        )
        username = forms.CharField(
            label=_("Username"),
            help_text=_("The username to be used to authenticate to Jasmin"))
        password = forms.CharField(
            label=_("Password"),
            help_text=_("The password to be used to authenticate to Jasmin"))

        def clean_number(self):
            number = self.data["number"]

            # number is a shortcode, accept as is
            if len(number) > 0 and len(number) < 7:
                return number

            # otherwise, try to parse into an international format
            if number and number[0] != "+":
                number = "+" + number

            try:
                cleaned = phonenumbers.parse(number, None)
                return phonenumbers.format_number(
                    cleaned, phonenumbers.PhoneNumberFormat.E164)
            except Exception:  # pragma: needs cover
                raise forms.ValidationError(
                    _("Invalid phone number, please include the country code. ex: +250788123123"
                      ))
Example #12
0
 class TelesomForm(ClaimViewMixin.Form):
     country = forms.ChoiceField(
         choices=ALL_COUNTRIES,
         widget=SelectWidget(attrs={"searchable": True}),
         label=_("Country"),
         help_text=_("The country this phone number is used in"),
     )
     number = forms.CharField(
         max_length=14,
         min_length=1,
         label=_("Number"),
         help_text=_("The short code you are connecting with."))
     url = ExternalURLField(
         label=_("URL"),
         help_text=_("The url provided to deliver messages"))
     username = forms.CharField(
         label=_("Username"),
         help_text=_("The username provided to use their API"))
     password = forms.CharField(
         label=_("Password"),
         help_text=_("The password provided to use their API"))
     secret = forms.CharField(
         label=_("Private Key"),
         help_text=_("The private key provided to use their API"))
Example #13
0
    class Form(ClaimViewMixin.Form):
        api_endpoint = ExternalURLField(
            label=_("API Endpoint"),
            help_text=_("The API endpoint for your TextIt WhatsApp number"))
        access_token = forms.CharField(
            label=_("Access Token"),
            max_length=256,
            help_text=_("The access token for your TextIt WhatsApp number"))

        def clean(self):
            cleaned = self.cleaned_data

            cleaned["api_endpoint"] = urljoin(cleaned["api_endpoint"], "/")
            headers = {
                "Authorization": f"Bearer {cleaned['access_token']}",
                "Content-Type": "application/json",
            }

            conf_url = urljoin(cleaned["api_endpoint"], "/conf")
            response = requests.get(conf_url, headers=headers)
            if response.status_code != 200:
                raise forms.ValidationError(
                    "Error reaching endpoint, please check access token and URL"
                )

            conf = response.json()

            if conf["status"] != "activated":
                raise forms.ValidationError(
                    "WhatsApp number not active, cannot connect")

            self.cleaned_data["address"] = conf["address"]
            self.cleaned_data["country"] = conf["country"]
            self.cleaned_data["name"] = conf["name"]

            return self.cleaned_data
Example #14
0
    class Form(ClaimViewMixin.Form):
        number = forms.CharField(
            help_text=_("Your enterprise WhatsApp number"))
        country = forms.ChoiceField(
            choices=ALL_COUNTRIES,
            label=_("Country"),
            help_text=_("The country this phone number is used in"))
        base_url = ExternalURLField(help_text=_(
            "The base URL for your WhatsApp enterprise installation"))
        username = forms.CharField(
            max_length=32,
            help_text=_(
                "The username to access your WhatsApp enterprise account"))
        password = forms.CharField(
            max_length=64,
            help_text=_(
                "The password to access your WhatsApp enterprise account"))

        facebook_template_list_domain = forms.CharField(
            label=_("Templates Domain"),
            help_text=_("Which domain to retrieve the message templates from"),
            initial="graph.facebook.com",
        )

        facebook_business_id = forms.CharField(
            max_length=128,
            help_text=_(
                "The Facebook waba-id that will be used for template syncing"))

        facebook_access_token = forms.CharField(
            max_length=256,
            help_text=_(
                "The Facebook access token that will be used for syncing"))

        facebook_namespace = forms.CharField(
            max_length=128,
            help_text=_("The namespace for your WhatsApp templates"))

        def clean(self):
            # first check that our phone number looks sane
            number, valid = URN.normalize_number(self.cleaned_data["number"],
                                                 self.cleaned_data["country"])
            if not valid:
                raise forms.ValidationError(
                    _("Please enter a valid phone number"))
            self.cleaned_data["number"] = number

            try:
                resp = requests.post(
                    self.cleaned_data["base_url"] + "/v1/users/login",
                    auth=(self.cleaned_data["username"],
                          self.cleaned_data["password"]),
                )

                if resp.status_code != 200:
                    raise Exception("Received non-200 response: %d",
                                    resp.status_code)

                self.cleaned_data["auth_token"] = resp.json(
                )["users"][0]["token"]

            except Exception:
                raise forms.ValidationError(
                    _("Unable to check WhatsApp enterprise account, please check username and password"
                      ))

            # check we can access their facebook templates
            from .type import TEMPLATE_LIST_URL

            response = requests.get(
                TEMPLATE_LIST_URL %
                (self.cleaned_data["facebook_template_list_domain"],
                 self.cleaned_data["facebook_business_id"]),
                params=dict(
                    access_token=self.cleaned_data["facebook_access_token"]),
            )

            if response.status_code != 200:
                raise forms.ValidationError(
                    _("Unable to access Facebook templates, please check user id and access token and make sure "
                      +
                      "the whatsapp_business_management permission is enabled")
                )
            return self.cleaned_data
Example #15
0
    class ClaimForm(ClaimViewMixin.Form):
        scheme = forms.ChoiceField(
            choices=URN.SCHEME_CHOICES,
            label=_("URN Type"),
            help_text=_("The type of URNs handled by this channel"))

        number = forms.CharField(
            max_length=14,
            min_length=1,
            label=_("Number"),
            required=False,
            help_text=_(
                "The phone number or that this channel will send from"),
        )

        address = forms.CharField(
            max_length=64,
            min_length=1,
            label=_("Address"),
            required=False,
            help_text=_(
                "The external address that this channel will send from"),
        )

        country = forms.ChoiceField(
            choices=ALL_COUNTRIES,
            label=_("Country"),
            required=False,
            widget=SelectWidget(attrs={"searchable": True}),
            help_text=_("The country this phone number is used in"),
        )

        method = forms.ChoiceField(
            choices=(("POST", "HTTP POST"), ("GET", "HTTP GET"), ("PUT",
                                                                  "HTTP PUT")),
            help_text=_("What HTTP method to use when calling the URL"),
        )

        encoding = forms.ChoiceField(
            choices=Channel.ENCODING_CHOICES,
            label=_("Encoding"),
            help_text=_("What encoding to use for outgoing messages"),
        )

        content_type = forms.ChoiceField(
            choices=Channel.CONTENT_TYPE_CHOICES,
            help_text=_("The content type used when sending the request"))

        max_length = forms.IntegerField(
            initial=160,
            validators=[MaxValueValidator(6400),
                        MinValueValidator(60)],
            help_text=_(
                "The maximum length of any single message on this channel. "
                "(longer messages will be split)"),
        )

        send_authorization = forms.CharField(
            max_length=2048,
            label=_("Authorization Header Value"),
            required=False,
            help_text=
            _("The Authorization header value added when calling the URL (if any)"
              ),
        )

        url = ExternalURLField(
            max_length=1024,
            label=_("Send URL"),
            help_text=
            _("The URL we will call when sending messages, with variable substitutions"
              ),
        )

        body = forms.CharField(
            max_length=2048,
            label=_("Request Body"),
            required=False,
            widget=forms.Textarea,
            help_text=
            _("The request body if any, with variable substitutions (only used for PUT or POST)"
              ),
        )

        mt_response_check = forms.CharField(
            max_length=2048,
            label=_("MT Response check"),
            required=False,
            widget=forms.Textarea,
            help_text=
            _("The content that must be in the response to consider the request successful"
              ),
        )

        def clean(self):
            cleaned_data = super().clean()
            scheme = cleaned_data.get("scheme")
            if scheme == URN.TEL_SCHEME and not cleaned_data.get("number"):
                raise ValidationError({"number": _("This field is required.")})
            elif scheme != URN.TEL_SCHEME and not cleaned_data.get("address"):
                raise ValidationError(
                    {"address": _("This field is required.")})
Example #16
0
    class ClaimForm(ClaimViewMixin.Form):
        scheme = forms.ChoiceField(
            choices=ContactURN.SCHEME_CHOICES,
            label=_("URN Type"),
            help_text=_("The type of URNs handled by this channel"),
        )

        number = forms.CharField(
            max_length=14,
            min_length=1,
            label=_("Number"),
            required=False,
            help_text=_("The phone number or that this channel will send from"),
        )

        handle = forms.CharField(
            max_length=32,
            min_length=1,
            label=_("Handle"),
            required=False,
            help_text=_("The Twitter handle that this channel will send from"),
        )

        address = forms.CharField(
            max_length=64,
            min_length=1,
            label=_("Address"),
            required=False,
            help_text=_("The external address that this channel will send from"),
        )

        country = forms.ChoiceField(
            choices=ALL_COUNTRIES,
            label=_("Country"),
            required=False,
            help_text=_("The country this phone number is used in"),
        )

        method = forms.ChoiceField(
            choices=(("POST", "HTTP POST"), ("GET", "HTTP GET"), ("PUT", "HTTP PUT")),
            help_text=_("What HTTP method to use when calling the URL"),
        )

        encoding = forms.ChoiceField(
            choices=Channel.ENCODING_CHOICES,
            label=_("Encoding"),
            help_text=_("What encoding to use for outgoing messages"),
        )

        content_type = forms.ChoiceField(
            choices=Channel.CONTENT_TYPE_CHOICES, help_text=_("The content type used when sending the request")
        )

        max_length = forms.IntegerField(
            initial=160,
            validators=[MaxValueValidator(640), MinValueValidator(60)],
            help_text=_(
                "The maximum length of any single message on this channel. " "(longer messages will be split)"
            ),
        )

        url = ExternalURLField(
            max_length=1024,
            label=_("Send URL"),
            help_text=_("The URL we will call when sending messages, with variable substitutions"),
        )

        body = forms.CharField(
            max_length=2048,
            label=_("Request Body"),
            required=False,
            widget=forms.Textarea,
            help_text=_("The request body if any, with variable substitutions (only used for PUT or POST)"),
        )

        mt_response_check = forms.CharField(
            max_length=2048,
            label=_("MT Response check"),
            required=False,
            widget=forms.Textarea,
            help_text=_("The content that must be in the response to consider the request successful"),
        )