Ejemplo n.º 1
0
    def deliver_sm(self, *args, **kwargs):
        message_type = kwargs.get('message_type', 'sms')
        message = {
            'message_id': kwargs['message_id'],
            'to_addr': kwargs['destination_addr'],
            'from_addr': kwargs['source_addr'],
            'content': kwargs['short_message'],
            'transport_type': message_type,
            'transport_metadata': {},
            }

        if message_type == 'ussd':
            session_event = {
                'new': TransportUserMessage.SESSION_NEW,
                'continue': TransportUserMessage.SESSION_RESUME,
                'close': TransportUserMessage.SESSION_CLOSE,
                }[kwargs['session_event']]
            message['session_event'] = session_event
            session_info = kwargs.get('session_info')
            message['transport_metadata']['session_info'] = session_info

        log.msg("PUBLISHING INBOUND: %s" % (message,))
        # TODO: This logs messages that fail to serialize to JSON
        #       Usually this happens when an SMPP message has content
        #       we can't decode (e.g. data_coding == 4). We should
        #       remove the try-except once we handle such messages
        #       better.
        return self.publish_message(**message).addErrback(log.err)
Ejemplo n.º 2
0
    def get_shortened_url(self, msg, config, url):
        if isinstance(url, unicode):
            url = url.encode('utf-8')

        user_token = self.hash_user(msg.user())

        headers = {
            'User-Agent': 'vumi-wikipedia-http-request',
            'content-type': 'application/json'
        }

        shortening_api_url = config.shortening_api_url.geturl()
        auth_header, clean_api_url = self.get_basic_auth_header(
            shortening_api_url
        )
        if auth_header:
            headers.update(auth_header)

        payload = {'long_url': url, 'user_token': user_token}
        api_url = urljoin(clean_api_url, 'create')
        response = yield http_request_full(
            api_url, json.dumps(payload), headers, method='PUT')
        try:
            result = json.loads(response.delivered_body)
            returnValue(result['short_url'])
        except Exception, e:
            log.msg("Error reading API response: %s %r" % (
                    response.code, response.delivered_body))
            log.err()
            raise APIError(e)
Ejemplo n.º 3
0
    def setup_transport(self):
        config = self.get_static_config()
        log.msg('Starting SMPP Transport for: %s' % (config.twisted_endpoint,))

        default_prefix = '%s@%s' % (config.system_id,
                                    config.transport_name)
        redis_prefix = config.split_bind_prefix or default_prefix
        self.redis = (yield TxRedisManager.from_config(
            config.redis_manager)).sub_manager(redis_prefix)

        self.dr_processor = config.delivery_report_processor(
            self, config.delivery_report_processor_config)
        self.deliver_sm_processor = config.deliver_short_message_processor(
            self, config.deliver_short_message_processor_config)
        self.submit_sm_processor = config.submit_short_message_processor(
            self, config.submit_short_message_processor_config)

        self.sequence_generator = self.sequence_class(self.redis)
        self.message_stash = SmppMessageDataStash(self.redis, config)
        self.throttled = None
        self._throttled_message_ids = []
        self._unthrottle_delayedCall = None
        self.factory = self.factory_class(self)

        self.service = self.start_service(self.factory)

        self.tps_counter = 0
        self.tps_limit = config.mt_tps
        if config.mt_tps > 0:
            self.mt_tps_lc = LoopingCall(self.reset_mt_tps)
            self.mt_tps_lc.clock = self.clock
            self.mt_tps_lc.start(1, now=True)
        else:
            self.mt_tps_lc = None
Ejemplo n.º 4
0
 def finish_expired_request(self, request_id, request):
     """
     Called on requests that timed out.
     """
     del self._requests[request_id]
     log.msg('Timing out on response for %s' % request.session['from_addr'])
     request.deferred.callback(self.response_for_error())
Ejemplo n.º 5
0
    def handle_inbound_text_message(self, request, wc_msg):
        double_delivery = yield self.check_for_double_delivery(
            request, wc_msg.msg_id)
        if double_delivery:
            log.msg('WeChat double delivery of message: %s' % (wc_msg.msg_id,))
            return

        lock = yield self.mark_as_seen_recently(wc_msg.msg_id)
        if not lock:
            log.msg('Unable to get lock for message id: %s' % (wc_msg.msg_id,))
            return

        config = self.get_static_config()
        if config.embed_user_profile:
            user_profile = yield self.get_user_profile(wc_msg.from_user_name)
        else:
            user_profile = {}

        mask = yield self.get_addr_mask(wc_msg.from_user_name)
        msg = yield self.publish_message(
            content=wc_msg.content,
            from_addr=wc_msg.from_user_name,
            to_addr=self.mask_addr(wc_msg.to_user_name, mask),
            timestamp=datetime.fromtimestamp(int(wc_msg.create_time)),
            transport_type=self.transport_type,
            transport_metadata={
                'wechat': {
                    'FromUserName': wc_msg.from_user_name,
                    'ToUserName': wc_msg.to_user_name,
                    'MsgType': 'text',
                    'MsgId': wc_msg.msg_id,
                    'UserProfile': user_profile,
                }
            })
        returnValue(msg)
Ejemplo n.º 6
0
    def handle_event(self, event, handler_config):
        sms_copy = handler_config['sms_copy']
        conversation_key = handler_config['conversation_key']

        account_key = event['account_key']
        from_addr = event['content']['from_addr']

        user_api = self.get_user_api(account_key)
        contact = yield self.find_contact(account_key, from_addr)

        if not contact:
            log.msg('Unable to find contact for %s' % (from_addr,))
            return

        content = (sms_copy['swahili'] if contact.extra['language'] == '2'
                    else sms_copy['english'])

        conversation = yield user_api.get_wrapped_conversation(
                                                conversation_key)

        yield conversation.dispatch_command(
            'send_message', account_key, conversation.key,
            command_data={
                'batch_id': conversation.batch.key,
                'to_addr': from_addr,
                'content': content,
                'msg_options': {},
            }
        )
Ejemplo n.º 7
0
    def handle_raw_inbound_message(self, request_id, request):
        values, errors = self.get_field_values(request, self.EXPECTED_FIELDS)
        if errors:
            log.msg('Unhappy incoming message: %r' % (errors,))
            self.finish_request(
                request_id, json.dumps(errors), code=http.BAD_REQUEST)
            return

        to_addr = values["ussdServiceCode"]
        from_addr = values["msisdn"]
        session_event = yield self.session_event_for_transaction(
            values["transactionId"])

        yield self.publish_message(
            message_id=request_id,
            content=values["ussdRequestString"],
            to_addr=to_addr,
            from_addr=from_addr,
            provider='dmark',
            session_event=session_event,
            transport_type=self.transport_type,
            transport_metadata={
                'dmark_ussd': {
                    'transaction_id': values['transactionId'],
                    'transaction_time': values['transactionTime'],
                    'creation_time': values['creationTime'],
                }
            })
Ejemplo n.º 8
0
    def switch_to_counters(self, batch_id):
        """
        Actively switch a batch from the old ``zcard()`` based approach
        to the new ``redis.incr()`` counter based approach.
        """
        uses_counters = yield self.uses_counters(batch_id)
        if uses_counters:
            log.msg('Batch %r has already switched to counters.' %
                    (batch_id, ))
            return

        # NOTE:     Under high load this may result in the counter being off
        #           by a few. Considering this is a cache that is to be
        #           reconciled we're happy for that to be the case.
        inbound_count = yield self.count_inbound_message_keys(batch_id)
        outbound_count = yield self.count_outbound_message_keys(batch_id)

        # We do `*_count or None` because there's a chance of getting back
        # a None if this is a new batch that's not received any traffic yet.
        yield self.redis.set(self.inbound_count_key(batch_id), inbound_count
                             or 0)
        yield self.redis.set(self.outbound_count_key(batch_id), outbound_count
                             or 0)

        yield self.truncate_inbound_message_keys(batch_id)
        yield self.truncate_outbound_message_keys(batch_id)
Ejemplo n.º 9
0
 def make_request(self, params):
     log.msg("Making HTTP request: %s" % (repr(params)))
     config = self.get_static_config()
     return http_request_full(config.outbound_url,
                              urlencode(params),
                              method='POST',
                              headers=self.headers)
Ejemplo n.º 10
0
 def render_(self, request):
     log.msg("Send request: %s" % (request,))
     request.setHeader("content-type", "application/json; charset=utf-8")
     d = self.application.handle_raw_outbound_message(request)
     d.addCallback(lambda msgs: self.finish_request(request, msgs))
     d.addErrback(lambda f: self.fail_request(request, f))
     return NOT_DONE_YET
Ejemplo n.º 11
0
 def _make_call(self, params):
     params.setdefault('format', 'json')
     url = '%s?%s' % (self.url, urlencode(params))
     if isinstance(url, unicode):
         url = url.encode('utf-8')
     headers = {'User-Agent': self.user_agent}
     if self.gzip:
         headers['Accept-Encoding'] = 'gzip'
     if self.PRINT_DEBUG:
         print "\n=====\n\n%s /?%s\n" % ('GET', url.split('?', 1)[1])
     response = yield http_request_full(url,
                                        '',
                                        headers,
                                        method='GET',
                                        timeout=self.api_timeout,
                                        agent_class=redirect_agent_builder)
     if self.PRINT_DEBUG:
         print response.delivered_body
         print "\n====="
     try:
         returnValue(json.loads(response.delivered_body))
     except Exception, e:
         log.msg("Error reading API response: %s %r" %
                 (response.code, response.delivered_body))
         log.err()
         raise APIError(e)
Ejemplo n.º 12
0
    def handle_raw_inbound_message(self, message_id, request):
        values, errors = self.get_field_values(request, self.EXPECTED_FIELDS)

        channel = values.get('channel')
        if channel is not None and channel not in self.CHANNEL_LOOKUP.values():
            errors['unsupported_channel'] = channel

        if errors:
            log.msg('Unhappy incoming message: %s' % (errors,))
            yield self.finish_request(message_id, json.dumps(errors),
                                      code=http.BAD_REQUEST)
            return

        self.emit("AppositTransport receiving inbound message from "
                  "%(from)s to %(to)s" % values)

        yield self.publish_message(
            transport_name=self.transport_name,
            message_id=message_id,
            content=values['content'],
            from_addr=values['from'],
            to_addr=values['to'],
            provider='apposit',
            transport_type=self.TRANSPORT_TYPE_LOOKUP[channel],
            transport_metadata={'apposit': {'isTest': values['isTest']}})

        yield self.finish_request(
            message_id, json.dumps({'message_id': message_id}))
Ejemplo n.º 13
0
 def finish_expired_request(self, request_id, request):
     """
     Called on requests that timed out.
     """
     del self._requests[request_id]
     log.msg('Timing out on response for %s' % request.session['from_addr'])
     request.deferred.callback(self.response_for_error())
Ejemplo n.º 14
0
    def handle_outbound_message(self, message):
        metadata = message['transport_metadata']['mtn_nigeria_ussd']

        try:
            self.validate_outbound_message(message)
        except CodedXmlOverTcpError as e:
            log.msg(e)
            yield self.publish_nack(message['message_id'], "%s" % e)
            yield self.factory.client.send_error_response(
                metadata.get('session_id'),
                message.payload.get('in_reply_to'),
                e.code)
            return

        log.msg(
            'MtnNigeriaUssdTransport sending outbound message: %s' % message)

        end_session = (
            message['session_event'] == TransportUserMessage.SESSION_CLOSE)
        yield self.send_response(
            message_id=message['message_id'],
            session_id=metadata['session_id'],
            request_id=metadata['requestId'],
            star_code=metadata['starCode'],
            client_id=metadata['clientId'],
            msisdn=message['to_addr'],
            user_data=message['content'].encode(self.ENCODING),
            end_session=end_session)
Ejemplo n.º 15
0
    def handle_outbound_message(self, message):
        metadata = message['transport_metadata']['mtn_nigeria_ussd']

        try:
            self.validate_outbound_message(message)
        except CodedXmlOverTcpError as e:
            log.msg(e)
            yield self.publish_nack(message['message_id'], "%s" % e)
            yield self.factory.client.send_error_response(
                metadata.get('session_id'), message.payload.get('in_reply_to'),
                e.code)
            return

        log.msg('MtnNigeriaUssdTransport sending outbound message: %s' %
                message)

        end_session = (
            message['session_event'] == TransportUserMessage.SESSION_CLOSE)
        yield self.send_response(message_id=message['message_id'],
                                 session_id=metadata['session_id'],
                                 request_id=metadata['requestId'],
                                 star_code=metadata['starCode'],
                                 client_id=metadata['clientId'],
                                 msisdn=message['to_addr'],
                                 user_data=message['content'].encode(
                                     self.ENCODING),
                                 end_session=end_session)
Ejemplo n.º 16
0
    def handle_raw_inbound_message(self, message_id, request):
        values, errors = self.get_field_values(request, self.EXPECTED_FIELDS)

        channel = values.get('channel')
        if channel is not None and channel not in self.CHANNEL_LOOKUP.values():
            errors['unsupported_channel'] = channel

        if errors:
            log.msg('Unhappy incoming message: %s' % (errors, ))
            yield self.finish_request(message_id,
                                      json.dumps(errors),
                                      code=http.BAD_REQUEST)
            return

        self.emit("AppositTransport receiving inbound message from "
                  "%(from)s to %(to)s" % values)

        yield self.publish_message(
            transport_name=self.transport_name,
            message_id=message_id,
            content=values['content'],
            from_addr=values['from'],
            to_addr=values['to'],
            provider='apposit',
            transport_type=self.TRANSPORT_TYPE_LOOKUP[channel],
            transport_metadata={'apposit': {
                'isTest': values['isTest']
            }})

        yield self.finish_request(message_id,
                                  json.dumps({'message_id': message_id}))
Ejemplo n.º 17
0
    def switch_to_counters(self, batch_id):
        """
        Actively switch a batch from the old ``zcard()`` based approach
        to the new ``redis.incr()`` counter based approach.
        """
        uses_counters = yield self.uses_counters(batch_id)
        if uses_counters:
            log.msg('Batch %r has already switched to counters.' % (
                batch_id,))
            return

        # NOTE:     Under high load this may result in the counter being off
        #           by a few. Considering this is a cache that is to be
        #           reconciled we're happy for that to be the case.
        inbound_count = yield self.count_inbound_message_keys(batch_id)
        outbound_count = yield self.count_outbound_message_keys(batch_id)

        # We do `*_count or None` because there's a chance of getting back
        # a None if this is a new batch that's not received any traffic yet.
        yield self.redis.set(self.inbound_count_key(batch_id),
                             inbound_count or 0)
        yield self.redis.set(self.outbound_count_key(batch_id),
                             outbound_count or 0)

        yield self.truncate_inbound_message_keys(batch_id)
        yield self.truncate_outbound_message_keys(batch_id)
Ejemplo n.º 18
0
    def handle_raw_inbound_message(self, request_id, request):
        values, errors = self.get_field_values(request, self.EXPECTED_FIELDS)
        if errors:
            log.msg('Unhappy incoming message: %r' % (errors, ))
            self.finish_request(request_id,
                                json.dumps(errors),
                                code=http.BAD_REQUEST)
            return

        to_addr = values["ussdServiceCode"]
        from_addr = values["msisdn"]
        session_event = yield self.session_event_for_transaction(
            values["transactionId"])

        yield self.publish_message(message_id=request_id,
                                   content=values["ussdRequestString"],
                                   to_addr=to_addr,
                                   from_addr=from_addr,
                                   provider='dmark',
                                   session_event=session_event,
                                   transport_type=self.transport_type,
                                   transport_metadata={
                                       'dmark_ussd': {
                                           'transaction_id':
                                           values['transactionId'],
                                           'transaction_time':
                                           values['transactionTime'],
                                           'creation_time':
                                           values['creationTime'],
                                       }
                                   })
Ejemplo n.º 19
0
    def handle_raw_inbound_message(self, msgid, request):
        parts = request.path.split('/')
        session_id = parts[-2]
        session_method = parts[-1]
        session_event, session_handler_name, sends_json = (
            self.METHOD_TO_HANDLER.get(session_method,
                                       (TransportUserMessage.SESSION_NONE,
                                       "handle_infobip_error", False)))
        session_handler = getattr(self, session_handler_name)
        req_content = request.content.read()
        log.msg("Incoming message: %r" % (req_content,))
        if sends_json:
            try:
                req_data = json.loads(req_content)
            except ValueError:
                # send bad JSON to error handler
                session_handler = self.handle_infobip_error
                req_data = {"error": "Invalid JSON"}
        else:
            req_data = {}

        message_dict = yield session_handler(msgid, session_id, req_data)
        if message_dict is not None:
            transport_metadata = {'session_id': session_id}
            message_dict.setdefault("message_id", msgid)
            message_dict.setdefault("session_event", session_event)
            message_dict.setdefault("content", None)
            message_dict["transport_name"] = self.transport_name
            message_dict["transport_type"] = self.config.get('transport_type',
                                                             'ussd')
            message_dict["transport_metadata"] = transport_metadata
            self.publish_message(**message_dict)
Ejemplo n.º 20
0
 def stopWorker(self):
     log.msg("HeartBeat: stopping worker")
     if self._task:
         self._task.stop()
         self._task = None
         yield self._task_done
     self._redis.close_manager()
Ejemplo n.º 21
0
 def handle_enquire_link(self, pdu):
     if pdu['header']['command_status'] == 'ESME_ROK':
         log.msg("enquire_link OK")
         sequence_number = pdu['header']['sequence_number']
         pdu_resp = EnquireLinkResp(sequence_number)
         self.send_pdu(pdu_resp)
     else:
         log.msg("enquire_link NOT OK: %r" % (pdu, ))
Ejemplo n.º 22
0
 def make_request(self, params):
     config = self.get_static_config()
     url = '%s?%s' % (config.outbound_url, urlencode(params))
     log.msg("Making HTTP request: %s" % (url, ))
     return http_request_full(url,
                              '',
                              method='POST',
                              agent_class=self.agent_factory)
Ejemplo n.º 23
0
 def connectionMade(self):
     self.state = 'OPEN'
     log.msg('STATE: %s' % (self.state))
     seq = yield self.get_next_seq()
     pdu = self.BIND_PDU(seq, **self.bind_params)
     log.msg(pdu.get_obj())
     self.send_pdu(pdu)
     self.schedule_lose_connection(self.CONNECTED_STATE)
Ejemplo n.º 24
0
 def reset_mt_tps(self):
     if self.throttled and self.need_mt_throttling():
         if not self.service.is_bound():
             # We don't have a bound SMPP connection, so try again later.
             log.msg("Can't stop throttling while unbound, trying later.")
             return
         self.reset_mt_throttle_counter()
         self.stop_throttling(quiet=True)
Ejemplo n.º 25
0
 def connectionMade(self):
     self.state = 'OPEN'
     log.msg('STATE: %s' % (self.state))
     seq = yield self.get_next_seq()
     pdu = self.BIND_PDU(seq, **self.bind_params)
     log.msg(pdu.get_obj())
     self.send_pdu(pdu)
     self.schedule_lose_connection(self.CONNECTED_STATE)
Ejemplo n.º 26
0
 def handle_enquire_link(self, pdu):
     if pdu['header']['command_status'] == 'ESME_ROK':
         log.msg("enquire_link OK")
         sequence_number = pdu['header']['sequence_number']
         pdu_resp = EnquireLinkResp(sequence_number)
         self.send_pdu(pdu_resp)
     else:
         log.msg("enquire_link NOT OK: %r" % (pdu,))
Ejemplo n.º 27
0
 def login(self):
     params = [
         ('requestId', self.gen_request_id()),
         ('userName', self.username),
         ('passWord', self.password),  # plaintext passwords, yay :/
         ('applicationId', self.application_id),
     ]
     self.send_packet(self.gen_session_id(), 'AUTHRequest', params)
     log.msg('Logging in')
Ejemplo n.º 28
0
 def register_client(self, client):
     # We add our own Deferred to the client here because we only want to
     # fire it after we're finished with our own deregistration process.
     client.registration_d = Deferred()
     client_addr = client.getAddress()
     log.msg("Registering client connected from %r" % client_addr)
     self._clients[client_addr] = client
     self.send_inbound_message(client, None,
                               TransportUserMessage.SESSION_NEW)
Ejemplo n.º 29
0
 def register_client(self, client):
     # We add our own Deferred to the client here because we only want to
     # fire it after we're finished with our own deregistration process.
     client.registration_d = Deferred()
     client_addr = client.getAddress()
     log.msg("Registering client connected from %r" % client_addr)
     self._clients[client_addr] = client
     self.send_inbound_message(client, None,
                               TransportUserMessage.SESSION_NEW)
Ejemplo n.º 30
0
 def lose_unbound_connection(self, required_state):
     if self.state != required_state:
         log.msg('Breaking connection due to binding delay, %s != %s\n' % (
             self.state, required_state))
         self._lose_conn = None
         self.transport.loseConnection()
     else:
         log.msg('Successful bind: %s, cancelling bind timeout' % (
             self.state))
Ejemplo n.º 31
0
 def lose_unbound_connection(self, required_state):
     if self.state != required_state:
         log.msg('Breaking connection due to binding delay, %s != %s\n' %
                 (self.state, required_state))
         self._lose_conn = None
         self.transport.loseConnection()
     else:
         log.msg('Successful bind: %s, cancelling bind timeout' %
                 (self.state))
Ejemplo n.º 32
0
    def log_action(self, msg, action, **kw):
        provider = msg.get('provider') or ''
        log_parts = [
            'WIKI', self.hash_user(msg.user()), msg['transport_name'],
            msg['transport_type'], provider,
            action, log_escape(msg['content']),
        ] + [u'%s=%s' % (k, log_escape(v)) for (k, v) in kw.items()]

        log.msg(u'\t'.join(unicode(s) for s in log_parts).encode('utf8'))
Ejemplo n.º 33
0
 def handle_outbound(self, config, msg, conn_name):
     log.msg("Processing outbound message: %s" % (msg,))
     user_id = msg['to_addr']
     session_event = msg['session_event']
     session_manager = yield self.session_manager(config)
     session = yield session_manager.load_session(user_id)
     if session and (session_event == TransportUserMessage.SESSION_CLOSE):
         yield session_manager.clear_session(user_id)
     yield self.publish_outbound(msg)
Ejemplo n.º 34
0
 def handle_state_selected(self, config, session, msg):
     active_endpoint = session['active_endpoint']
     if active_endpoint not in self.target_endpoints(config):
         log.msg(("Router configuration change forced session "
                  "termination for user %s" % msg['from_addr']))
         yield self.publish_error_reply(msg, config)
         returnValue((None, {}))
     else:
         yield self.publish_inbound(msg, active_endpoint)
         returnValue((self.STATE_SELECTED, {}))
Ejemplo n.º 35
0
    def startWorker(self):
        log.msg('Starting a %s dispatcher with config: %s'
                % (self.__class__.__name__, self.config))

        yield self.setup_endpoints()
        yield self.setup_router()
        yield self.setup_transport_publishers()
        yield self.setup_exposed_publishers()
        yield self.setup_transport_consumers()
        yield self.setup_exposed_consumers()
Ejemplo n.º 36
0
    def startWorker(self):
        log.msg('Starting a %s dispatcher with config: %s' %
                (self.__class__.__name__, self.config))

        yield self.setup_endpoints()
        yield self.setup_router()
        yield self.setup_transport_publishers()
        yield self.setup_exposed_publishers()
        yield self.setup_transport_consumers()
        yield self.setup_exposed_consumers()
Ejemplo n.º 37
0
    def log(self, api, msg, level):
        conv = self.app_worker.conversation_for_api(api)
        campaign_key = conv.user_account.key
        conversation_key = conv.key

        internal_msg = "[Account: %s, Conversation: %s] %s" % (
            campaign_key, conversation_key, msg)
        log.msg(internal_msg, logLevel=level)

        yield self.log_manager.add_log(campaign_key, conversation_key, msg,
                                       level)
Ejemplo n.º 38
0
 def is_authenticated(self, request):
     config = self.get_static_config()
     if self.EXPECTED_AUTH_FIELDS.issubset(request.args):
         username = request.args['userid'][0]
         password = request.args['password'][0]
         auth = (username == config.airtel_username and
                 password == config.airtel_password)
         if not auth:
             log.msg('Invalid authentication credentials: %s:%s' % (
                     username, password))
         return auth
Ejemplo n.º 39
0
    def log(self, api, msg, level):
        conv = self.app_worker.conversation_for_api(api)
        campaign_key = conv.user_account.key
        conversation_key = conv.key

        internal_msg = "[Account: %s, Conversation: %s] %s" % (
            campaign_key, conversation_key, msg)
        log.msg(internal_msg, logLevel=level)

        yield self.log_manager.add_log(campaign_key, conversation_key,
                                       msg, level)
Ejemplo n.º 40
0
 def is_authenticated(self, request):
     config = self.get_static_config()
     if self.EXPECTED_AUTH_FIELDS.issubset(request.args):
         username = request.args['userid'][0]
         password = request.args['password'][0]
         auth = (username == config.airtel_username
                 and password == config.airtel_password)
         if not auth:
             log.msg('Invalid authentication credentials: %s:%s' %
                     (username, password))
         return auth
Ejemplo n.º 41
0
    def start_periodic_enquire_link(self):
        if not self.authenticated:
            log.msg("Heartbeat could not be started, client not authenticated")
            return

        self.periodic_enquire_link.clock = self.clock
        d = self.periodic_enquire_link.start(
            self.enquire_link_interval, now=True)
        log.msg("Heartbeat started")

        return d
Ejemplo n.º 42
0
    def handle_login_response(self, session_id, params):
        try:
            self.validate_packet_fields(params, self.LOGIN_RESPONSE_FIELDS)
        except CodedXmlOverTcpError as e:
            self.disconnect()
            self.handle_error(session_id, params.get('requestId'), e)
            return

        log.msg("Client authentication complete.")
        self.authenticated = True
        self.start_periodic_enquire_link()
Ejemplo n.º 43
0
    def handle_inbound(self, config, msg, conn_name):
        log.msg("Handling inbound: %s" % (msg, ))

        try:
            contact = yield self.get_contact_for_message(msg, create=False)
        except ContactNotFoundError:
            contact = None
        except ContactError:
            log.err()
            return

        endpoint = self.endpoint_for_contact(config, contact)
        yield self.publish_inbound(msg, endpoint)
Ejemplo n.º 44
0
    def startWorker(self):
        log.msg("Garbage Worker is starting")
        super(GarbageWorker, self).startWorker()

        connection = pymongo.Connection('localhost', 27017)
        db = connection[self.config['database_name']]
        if not 'unmatchable_reply' in db.collection_names():
            db.create_collection('unmatchable_reply')
        self.unmatchable_reply_collection = db['unmatchable_reply']
        #if not 'shortcodes' in db.collection_names():
            #db.create_collection('shortcodes')
        self.shortcodes_collection = db['shortcodes']
        self.templates_collection = db['templates']
Ejemplo n.º 45
0
    def handle_inbound(self, config, msg, conn_name):
        log.msg("Handling inbound: %s" % (msg,))

        try:
            contact = yield self.get_contact_for_message(msg, create=False)
        except ContactNotFoundError:
            contact = None
        except ContactError:
            log.err()
            return

        endpoint = self.endpoint_for_contact(config, contact)
        yield self.publish_inbound(msg, endpoint)
Ejemplo n.º 46
0
 def delivery_report(self, message_id, message_state):
     delivery_status = self.delivery_status(message_state)
     message_id = yield self.r_get_id_for_third_party_id(message_id)
     if message_id is None:
         log.warning("Failed to retrieve message id for delivery report."
                     " Delivery report from %s discarded."
                     % self.transport_name)
         return
     log.msg("PUBLISHING DELIV REPORT: %s %s" % (message_id,
                                                 delivery_status))
     returnValue((yield self.publish_delivery_report(
                 user_message_id=message_id,
                 delivery_status=delivery_status)))
Ejemplo n.º 47
0
    def handle_raw_inbound_message(self, msgid, request):
        request_body = request.content.read()
        log.msg("Inbound message: %r" % (request_body,))
        try:
            body = ET.fromstring(request_body)
        except:
            log.warning("Error parsing request XML: %s" % (request_body,))
            yield self.finish_request(msgid, "", code=400)
            return

        # We always get this.
        session_id = body.find('session_id').text

        status_elem = body.find('status')
        if status_elem is not None:
            # We have a status message. These are all variations on "cancel".
            yield self.handle_status_message(msgid, session_id)
            return

        page_id = body.find('page_id').text

        # They sometimes send us page_id=0 in the middle of a session.
        if page_id == '0' and body.find('mobile_number') is not None:
            # This is a new session.
            session = yield self.save_session(
                session_id,
                from_addr=body.find('mobile_number').text,
                to_addr=body.find('gate').text)  # ???
            session_event = TransportUserMessage.SESSION_NEW
        else:
            # This is an existing session.
            session = yield self.session_manager.load_session(session_id)
            if 'from_addr' not in session:
                # We have a missing or broken session.
                yield self.finish_request(msgid, "", code=400)
                return
            session_event = TransportUserMessage.SESSION_RESUME

        content = body.find('data').text

        transport_metadata = {'session_id': session_id}
        self.publish_message(
                message_id=msgid,
                content=content,
                to_addr=session['to_addr'],
                from_addr=session['from_addr'],
                session_event=session_event,
                transport_name=self.transport_name,
                transport_type=self.config.get('transport_type'),
                transport_metadata=transport_metadata,
                )
Ejemplo n.º 48
0
    def handle_raw_inbound_message(self, session_id, params):
        # ensure the params are in the encoding we use internally
        params['session_id'] = session_id
        params = dict((k, v.decode(self.ENCODING))
                      for k, v in params.iteritems())

        session_event = self.determine_session_event(
            *self.pop_fields(params, 'msgtype', 'EndofSession'))

        # For the first message of a session, the `user_data` field is the ussd
        # code. For subsequent messages, 'user_data' is the user's content.  We
        # need to keep track of the ussd code we get in in the first session
        # message so we can link the correct `to_addr` to subsequent messages
        if session_event == TransportUserMessage.SESSION_NEW:
            # Set the content to none if this the start of the session.
            # Prevents this inbound message being mistaken as a user message.
            content = None

            to_addr = params.pop('userdata')
            session = yield self.session_manager.create_session(
                session_id, ussd_code=to_addr)
        else:
            session = yield self.session_manager.load_session(session_id)
            to_addr = session['ussd_code']
            content = params.pop('userdata')

        # pop the remaining needed field (the rest is left as metadata)
        [from_addr] = self.pop_fields(params, 'msisdn')

        log.msg('MtnNigeriaUssdTransport receiving inbound message from %s '
                'to %s: %s' % (from_addr, to_addr, content))

        if session_event == TransportUserMessage.SESSION_CLOSE:
            self.factory.client.send_data_response(
                session_id=session_id,
                request_id=params['requestId'],
                star_code=params['starCode'],
                client_id=params['clientId'],
                msisdn=from_addr,
                user_data=self.user_termination_response,
                end_session=True)

        yield self.publish_message(
            content=content,
            to_addr=to_addr,
            from_addr=from_addr,
            provider='mtn_nigeria',
            session_event=session_event,
            transport_type=self.transport_type,
            transport_metadata={'mtn_nigeria_ussd': params})