Merge branch 'philip/fix-africastalking-parser' into 'master'

Philip/fix africastalking parser

Closes cic-ussd#41

See merge request grassrootseconomics/cic-internal-integration!140
This commit is contained in:
Philip Wafula 2021-05-11 10:58:00 +00:00
commit 1f668384cc
6 changed files with 43 additions and 30 deletions

View File

@ -4,7 +4,7 @@ LOCALE_FALLBACK=en
LOCALE_PATH=/usr/src/cic-ussd/var/lib/locale/
MAX_BODY_LENGTH=1024
PASSWORD_PEPPER=QYbzKff6NhiQzY3ygl2BkiKOpER8RE/Upqs/5aZWW+I=
SERVICE_CODE=*483*46#
SERVICE_CODE=*483*46#,*483*061#,*384*96#
[phone_number]
REGION=KE

View File

@ -13,7 +13,7 @@ import argparse
import logging
import urllib
from xdg.BaseDirectory import xdg_config_home
from urllib import request
from urllib import parse, request
# third-party imports
from confini import Config
@ -92,9 +92,9 @@ def main():
data['text'] = user_input
req = urllib.request.Request(url)
data_str = json.dumps(data)
data_bytes = data_str.encode('utf-8')
req.add_header('Content-Type', 'application/json')
urlencoded_data = parse.urlencode(data)
data_bytes = urlencoded_data.encode('utf-8')
req.add_header('Content-Type', 'application/x-www-form-urlencoded')
req.data = data_bytes
response = urllib.request.urlopen(req)
response_data = response.read().decode('utf-8')

View File

@ -4,6 +4,7 @@
# standard imports
import json
import logging
from urllib.parse import parse_qs
# third-party imports
import celery
@ -33,8 +34,7 @@ from cic_ussd.requests import (get_request_endpoint,
from cic_ussd.runnable.server_base import exportable_parser, logg
from cic_ussd.session.ussd_session import UssdSession as InMemoryUssdSession
from cic_ussd.state_machine import UssdStateMachine
from cic_ussd.validator import check_ip, check_request_content_length, check_service_code, validate_phone_number, \
validate_presence
from cic_ussd.validator import check_ip, check_request_content_length, validate_phone_number, validate_presence
args = exportable_parser.parse_args()
@ -124,6 +124,9 @@ else:
raise InitializationError(f'Default token data for: {chain_str} not found.')
valid_service_codes = config.get('APP_SERVICE_CODE').split(",")
def application(env, start_response):
"""Loads python code for application to be accessible over web server
:param env: Object containing server and request information
@ -139,13 +142,27 @@ def application(env, start_response):
if get_request_method(env=env) == 'POST' and get_request_endpoint(env=env) == '/':
# get post data
post_data = json.load(env.get('wsgi.input'))
if env.get('CONTENT_TYPE') != 'application/x-www-form-urlencoded':
start_response('405 Play by the rules', errors_headers)
return []
service_code = post_data.get('serviceCode')
phone_number = post_data.get('phoneNumber')
external_session_id = post_data.get('sessionId')
user_input = post_data.get('text')
post_data = env.get('wsgi.input').read()
post_data = post_data.decode('utf-8')
try:
post_data = parse_qs(post_data)
except TypeError:
start_response('400 Size matters', errors_headers)
return []
service_code = post_data.get('serviceCode')[0]
phone_number = post_data.get('phoneNumber')[0]
external_session_id = post_data.get('sessionId')[0]
try:
user_input = post_data.get('text')[0]
except TypeError:
user_input = ""
# add validation for phone number
if phone_number:
@ -162,14 +179,14 @@ def application(env, start_response):
return []
# validate service code
if not check_service_code(code=service_code, config=config):
if service_code not in valid_service_codes:
response = define_multilingual_responses(
key='ussd.kenya.invalid_service_code',
locales=['en', 'sw'],
prefix='END',
valid_service_code=config.get('APP_SERVICE_CODE'))
response_bytes, headers = define_response_with_content(headers=errors_headers, response=response)
start_response('400 Invalid service code', headers)
valid_service_code=valid_service_codes[0])
response_bytes, headers = define_response_with_content(headers=headers, response=response)
start_response('200 OK', headers)
return [response_bytes]
# validate phone number
@ -192,3 +209,8 @@ def application(env, start_response):
start_response('200 OK,', headers)
SessionBase.session.close()
return [response_bytes]
else:
start_response('405 Play by the rules', errors_headers)
return []

View File

@ -45,19 +45,6 @@ def check_request_content_length(config: Config, env: dict):
config.get('APP_MAX_BODY_LENGTH'))
def check_service_code(code: str, config: Config):
"""Checks whether provided code matches expected service code
:param config: A dictionary object containing configuration values
:type config: Config
:param code: Service code passed over request
:type code: str
:return: Service code validity
:rtype: boolean
"""
return code == config.get('APP_SERVICE_CODE')
def check_known_user(phone: str):
"""
This method attempts to ascertain whether the user already exists and is known to the system.

View File

@ -158,6 +158,8 @@ en:
Your Sarafu-Network balances is: %{token_balance}
00. Back
99. Exit
invalid_service_code: |-
Please dial %{valid_service_code} to access Sarafu Network
help: |-
CON For assistance call %{support_phone}
00. Back

View File

@ -158,6 +158,8 @@ sw:
Akaunti yako ya Sarafu-Network ina salio ifuatayo: %{token_balance}
00. Nyuma
99. Ondoka
invalid_service_code: |-
Bonyeza %{valid_service_code} kutumia mtandao wa Sarafu
help: |-
CON Kwa usaidizi piga simu %{support_phone}
0. Nyuma