invalid(empty) response with Django - python

AM building a USSD application, in Django with this API https://documenter.getpostman.com/view/7705958/UyrEhaLQ#intro. I get the responses from the API and initialize the data to be processed. But I don't get the menu (MSG) to display on the user phone successfully. The error I get is invalid(empty) response. This is the response to the user’s request. The content provider should provide a response to the request in the same format.
USERID = This is the ID provided by NALO to the client
MSISDN = The mobile number of the user
MSG =This is a mandatory parameter that holds the message to be displayed on the user’s phone
MSGTYPE = This indicates whether the session should continue or be terminated (True/false)
#csrf_exempt
def ussd(request):
if request.method == 'GET':
html = "<html><body>Nothing here baby!</body></html>"
return HttpResponse(html)
elif request.method == 'POST':
url = "https://99c9-102-176-94-213.ngrok.io/ussd"
response_data = json.loads(request.body)
code_id = response_data["USERID"]
serviceCode = response_data["MSISDN"]
type = response_data["MSGTYPE"]
session_id = response_data["SESSIONID"]
text = response_data["USERDATA"]
msg = ""
if text == "":
msg = "Welcome To TEST Dev"
elif text == "1":
msg = "This is Test Two"
payload ={
"USERID": code_id,
"MSISDN": serviceCode,
"MSGTYPE": type,
"USERDATA": text,
"SESSIONID": session_id,
"MSG": msg,
}
headers = {
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=json.dumps(payload))
return HttpResponse(response, status=200)

Related

Where to store jwt token in flask app so that its picked up automatic jwt_required(optional=True)?

I was trying to create a flask app with user-login API call that generates access and refresh token and upon successful creation redirect back to homepage view which has jwt_required(optional=True) decorator but no matter how i try to save the token i'm unable to fetch it via get_jwt()
This is the API for generating the access and refresh token.
class UserLogin(MethodResource, Resource):
#doc(description='This is User Login Endpoint', tags=['User Endpoint'])
#use_kwargs(User_RequestSchema(exclude=("name", "email","admin")))
#marshal_with(Login_ResponseToken, code=200, description="Success | Returns: \nUser Registered Succesfully")
#marshal_with(Msg_ResponseSchema, code=401, description="Unauthorized | Returns: \n-Invalid User Credentials!")
#marshal_with(Msg_ResponseSchema, code=400, description="Bad Request | Returns: \n-Error loading Json body on request")
def post(self,**kwargs):
"""
If user roll_num and password correct create a new access and refresh token
else return invalid credentials 401 error
"""
try:
schema = User_RequestSchema(exclude=("name", "email","admin"))
data = schema.load(kwargs,unknown=EXCLUDE)
except:
output = {"message":"Error loading Json body in request"}
return output, 400 #Status-Bad Request
user = UserModel.find_by_rollnum(data['roll_num'])
# User Present and password correct
if user is not None and user.check_password(data['password']) and user.roll_num==data['roll_num']:
additional_claims = {"admin_access":user.admin}
access_token = create_access_token(identity=user.roll_num, additional_claims=additional_claims,fresh=True)
refresh_token = create_refresh_token(user.roll_num)
resp = jsonify(login=True)
set_access_cookies(resp, access_token.encode('utf-8'))
set_refresh_cookies(resp, refresh_token.encode('utf-8'))
resp.set_cookie('X-CSRF-TOKEN-ACCESS', access_token.encode('utf-8'))
resp.set_cookie('X-CSRF-TOKEN-REFRESH', refresh_token.encode('utf-8'))
output={"access_token":access_token,
"refresh_token":refresh_token,
"message": "Successful Login"}
return output, 200 # Status-OK
output = {"message": "Invalid User Credentials!"}
return output, 401 # Status-Unauthorized
This is the code that calls the login API and provides login information from login Form
#auth.route("/user_login", methods=["GET", "POST"])
def user_login():
form = LoginForm()
if form.validate_on_submit():
data = {"roll_num": form.roll_num.data,
"password": form.password.data}
# send request to login API
headers = CaseInsensitiveDict()
headers["Accept"] = "application/json"
headers["Content-Type"] = "application/json"
headers["Authorization"] = "Bearer {token}"
r = requests.post('http://localhost:5000/login', json=data, headers=headers)
if r.status_code==401:
flash("Wrong Roll Number or Password")
elif r.status_code==200:
print("Login correct")
flash("Log In successful")
access_token = r.json()['access_token']
resp = redirect(url_for('home.index'),access_token)
resp.headers = {'Authorization': 'Bearer {}'.format(access_token)}
return resp
print('Login_response',r)
print('Status Code',r.status_code)
print('data',r.text)
return render_template("login.html", form=form)
This is where the login should redirect on successful token generation
#home.route('/')
#home.route('/index')
#jwt_required(optional=True, locations=['headers', 'cookies'])
def index():
logged_in = 0
admin = 0
head = get_jwt_header()
print(head)
identity = get_jwt_identity()
print(identity)
claims = get_jwt()
print('claims:', claims)
if len(claims)!=0:
logged_in = 1
# If user is admin give ability to register
if claims['admin_access']==1:
admin = 1
print("Logged In: ", logged_in)
print("Admin: ", admin)
return render_template('index.html', admin=admin, logged_in=logged_in)
As far as I read should be able to get jwt claims and identity form the stored token, but no matter what I do i can't get this to work. It works in post man through assignment in environment variable. I can't figure out what I'm doing wrong?

Django Redirect: No errors, but no redirect [duplicate]

This question already has answers here:
Redirecting after AJAX post in Django
(3 answers)
Closed 1 year ago.
I POST some data via an HTML form using AJAX to modify data in my database. The data is successfully modified by executing stored procedures on the DB. Final line of the view.py function call is return redirect('Home').
The redirect is successfully executing, but I am not being redirected. I can overcome this by adding window.location.href = 'http://127.0.0.1:8000/ in the success function of the AJAX call. The problem is, I want to use messages.success(request, 'Data Successfully Updated'), which only appears after refreshing the AJAX-originating redirect.
Is there a reason why return redirect('Home') is not working here, and is there a way to overcome this?
Home is the name of my path in urls.py
[06/May/2021 17:23:52] "POST /search/ HTTP/1.1" 302 0 // submitting changes to database
[06/May/2021 17:23:55] "GET / HTTP/1.1" 200 4750 // The page I am intending to redirect to
Ajax Call
function updateCards(){
ajaxUpdCard().done()
function ajaxUpdCard() {
return $.ajax({
type: 'POST',
url: '',
data: {csrfmiddlewaretoken: window.CSRF_TOKEN, Action: 'Card', CardID: $('#currentCardID').val(),
BCard: $('#sr-bad_card').val(), CNum: $('#sr-card_number').val(), CPin: $('#sr-pin_number').val(),
Bal: $('#sr-balance').val()}
})
}
}
views.py
if request.method == 'POST' and request.POST['Action'] == 'Card':
cardID = request.POST['CardID']
Bcard = int(request.POST['BCard'])
CNum = int(request.POST['CNum'])
CPin = int(request.POST['CPin']) if request.POST['CPin'] != '' and request.POST['CPin'] != 'XXXX' else 'Null'
print(CPin)
Bal = request.POST['Bal']
update_card_transaction(entityID, userID, cardID, Bcard, CNum, CPin, Bal)
messages.success(request, 'Data Successfully Updated')
return redirect('Home')
You shood return some data from backend side, and redirect on your clinet side
views.py
if request.method == 'POST' and request.POST['Action'] == 'Card':
cardID = request.POST['CardID']
Bcard = int(request.POST['BCard'])
CNum = int(request.POST['CNum'])
CPin = int(request.POST['CPin']) if request.POST['CPin'] != '' and request.POST['CPin'] != 'XXXX' else 'Null'
print(CPin)
Bal = request.POST['Bal']
update_card_transaction(entityID, userID, cardID, Bcard, CNum, CPin, Bal)
messages.success(request, 'Data Successfully Updated')
return JsonResponse({'foo':'bar'})
Ajax Call
function updateCards() {
ajaxUpdCard().done()
function ajaxUpdCard() {
return $.ajax({
type: 'POST',
url: '',
data: {
csrfmiddlewaretoken: window.CSRF_TOKEN, Action: 'Card', CardID: $('#currentCardID').val(),
BCard: $('#sr-bad_card').val(), CNum: $('#sr-card_number').val(), CPin: $('#sr-pin_number').val(),
Bal: $('#sr-balance').val()
},
success:function(response) {
window.location.href='/home'
}
})
}
}
redirect take as argument the full path as string or view name :
if request.method == 'POST' and request.POST['Action'] == 'Card':
cardID = request.POST['CardID']
Bcard = int(request.POST['BCard'])
CNum = int(request.POST['CNum'])
CPin = int(request.POST['CPin']) if request.POST['CPin'] != '' and request.POST['CPin'] != 'XXXX' else 'Null'
print(CPin)
Bal = request.POST['Bal']
update_card_transaction(entityID, userID, cardID, Bcard, CNum, CPin, Bal)
messages.success(request, 'Data Successfully Updated')
return redirect(Home)
or you can use reverse :
if request.method == 'POST' and request.POST['Action'] == 'Card':
cardID = request.POST['CardID']
Bcard = int(request.POST['BCard'])
CNum = int(request.POST['CNum'])
CPin = int(request.POST['CPin']) if request.POST['CPin'] != '' and request.POST['CPin'] != 'XXXX' else 'Null'
print(CPin)
Bal = request.POST['Bal']
update_card_transaction(entityID, userID, cardID, Bcard, CNum, CPin, Bal)
messages.success(request, 'Data Successfully Updated')
return redirect(reverse('Home'))

request.POST.get() returning none

I am running a website using Django. I am trying to Login but it is returning none and i am not getting any error. It shows 200 status code.
Here is my views.py code:
def user_login(request):
datas= {'log':False}
if request.method == "POST":
usern=request.POST.get('Username')
passw=request.POST.get('password')
response = requests.post(url='http://www.onebookingsystem.com/productionApi/API/Admin/login.php',data={"Username":usern,"password":passw})
json_data = response.json()
if json_data['status'] == 1:
user=authenticate(Username=usern,password=passw)
login(request,user)
range_yearly = 0
range_monthly = 0
respo = requests.get(url='http://www.onebookingsystem.com/productionApi/API/Admin/admin_dashboard.php')
data_dash = json.loads(respo.text)
when i am running in POST HTTP request,it shows successfully logged in,but
in GET HTTP request, it shows :Status 0 "mobile or password is missing".//required post params is missing.
This is propably because you're using requests without the session storage.
You can try it this (untested) way:
def user_login(request):
# Create client with session storage to store session cookies
client = requests.Session()
datas= {'log':False}
if request.method == "POST":
usern=request.POST.get('Username')
passw=request.POST.get('password')
# client stores session cookie at login
response = client.post(url='http://www.onebookingsystem.com/productionApi/API/Admin/login.php',data={"Username":usern,"password":passw})
# you can check that with
# print(client.cookies)
json_data = response.json()
if json_data['status'] == 1:
user=authenticate(Username=usern,password=passw)
login(request,user)
range_yearly = 0
range_monthly = 0
# client should be able to access because of its stored session cookie
respo = client.get(url='http://www.onebookingsystem.com/productionApi/API/Admin/admin_dashboard.php')
data_dash = json.loads(respo.text)
More information

Middleware logging limitation Django 1.11

Background:
I have integration test which is working fine, but later on failed when I
added the customized middleware
def test_mobile_update_customer(self):
user = User.objects.create(username='warhead')
self.client.force_authenticate(user=user)
mommy.make(Customer, family_name='IBM', created_user=self.soken_staff, updated_user=self.soken_staff)
data = {
"family_name": "C0D1UM"
}
customer = Customer.objects.first()
res = self.client.patch(reverse('api:customer-detail', kwargs={'pk': customer.id}), data=data)
self.assertEqual(200, res.status_code)
customer.refresh_from_db()
self.assertEqual('C0D1UM', customer.family_name)
self.assertEqual('spearhead', customer.created_user.username)
self.assertEqual('warhead', customer.updated_user.username)
Problem:
The middleware break it with Exception
File "/Users/el/Code/norak-cutter/soken/soken-web/soken_web/middleware.py", line 47, in process_request
data['PATCH'] = json.loads(request.body)
File "/Users/el/.pyenv/versions/soken/lib/python3.6/site-packages/django/http/request.py", line 264, in body
raise RawPostDataException("You cannot access body after reading from request's data stream")
django.http.request.RawPostDataException: You cannot access body after reading from request's data stream
The problem is data has been read before the RESTful api do the job.
Then the program raises an exception.
def process_request(self, request):
if request.path.startswith('/api/'):
data = collections.OrderedDict()
data["user"] = request.user.username
data["path"] = request.path
data["method"] = request.method
data["content-type"] = request.content_type
if request.method == 'GET':
data['GET'] = request.GET
elif request.method == 'POST':
data['POST'] = request.POST
# https://stackoverflow.com/questions/4994789/django-where-are-the-params-stored-on-a-put-delete-request
# elif request.method == 'PUT':
# data['PUT'] = json.loads(request.body)
# test_mobile_update_customer
# raise RawPostDataException("You cannot access body after reading from request's data stream")
# django.http.request.RawPostDataException: You cannot access body after reading from request's data stream
# elif request.method == 'PATCH':
# data['PATCH'] = json.loads(request.body)
elif request.method == 'DELETE':
pass
self.__uuid = str(uuid.uuid4())
request_logger.info(f'{self.__uuid} {json.dumps(data)}')
Update2
Attempt:
I change client constructor refer to https://github.com/encode/django-rest-framework/issues/2774
def test_mobile_update_customer(self):
user = User.objects.create(username='warhead')
# self.client.force_authenticate(user=user)
from django.test import Client
client = Client()
client.force_login(user)
mommy.make(Customer, family_name='IBM', created_user=self.soken_staff, updated_user=self.soken_staff)
data = {
"family_name": "C0D1UM"
}
customer = Customer.objects.first()
res = client.patch(reverse('api:customer-detail', kwargs={'pk': customer.id}), data=data, content_type='application/json')
self.assertEqual(200, res.status_code)
customer.refresh_from_db()
self.assertEqual('C0D1UM', customer.family_name)
self.assertEqual('spearhead', customer.created_user.username)
self.assertEqual('warhead', customer.updated_user.username)
It does not work. The Client misinterpret the payload
>>> res.content
b'{"detail":"JSON parse error - Expecting property name enclosed in double quotes: line 1 column 2 (char 1)"}'
Workaround:
I don't know this is correct for all cases or not, but I workaround by this
test.py
https://gist.github.com/elcolie/88eb7c90cfca1c369a020ac232c7fbcc
middleware.py
https://gist.github.com/elcolie/5d9b1a2f890a0efcb46fdb95c0e90908
result.py
https://gist.github.com/elcolie/298e595b404c1a5839ed8dd584d2f07f
Question:
How do I do integration test of PATCH with the same time that testcase will not break by my middleware?
Right now I have to choose either one of them.

Python Token based authentication error

I am using token based authentication to restrict the access to user for my site, I am getting following error
{"_status": "ERR", "_error": {"message": "Please provide proper credentials", "code": 401}}weber#weber-desktop:/var/www/lunar-cloud-web-ui/kukunako$
my sample code shown below.
class TokenAuth(TokenAuth):
def check_auth(self, token, allowed_roles, resource, method):
accounts = app.data.driver.db['people']
return accounts.find_one({'token': token})
app = Eve(__name__,static_url_path='/static', auth = TokenAuth)
app.debug = True,
app.config.update(
DEBUG=True,
#EMAIL SETTINGS
MAIL_SERVER='smtp.gmail.com',
MAIL_PORT=465,
MAIL_USE_SSL=True,
MAIL_USERNAME = '<username>',
MAIL_PASSWORD = '<password>'
)
mail=Mail(app)
socketio = SocketIO(app)
def create_token(user):
payload = {
'sub': str(user['_id']),
'iat': datetime.now(),
'exp': datetime.now() + timedelta(days=14)
}
token = jwt.encode(payload, TOKEN_SECRET)
return token.decode('unicode_escape')
def login_required(f):
#wraps(f)
def decorated_function(*args, **kwargs):
if not request.headers.get('Authorization'):
response = jsonify(error='Missing authorization header')
response.status_code = 401
return response
payload = parse_token(request)
if datetime.fromtimestamp(payload['exp']) < datetime.now():
response = jsonify(error='Token has expired')
response.status_code = 401
return response
g.user_id = payload['sub']
return f(*args, **kwargs)
return decorated_function
#app.route('/auth/login', methods=['POST'])
def login():
accounts = app.data.driver.db['people']
user = accounts.find_one({'email': request.json['email']})
if not user:
response = jsonify(error='Your email does not exist')
response.status_code = 401
return response
if not user['email_confirmed'] == True:
response = jsonify(error='Email is not confirmed')
response.status_code = 401
return response
if not user or not check_password_hash(user['password']['password'], request.json['password']):
response = jsonify(error='Wrong Email or Password')
response.status_code = 401
return response
token = create_token(user)
return jsonify(token=token)
my all code is show in following for settings file and server code file
settings file
server code file
How are you testing it?
I can think of two possible problems.
JWT token needs to be base64 encoded
You may have forgotten : at the end
e.g. If your token is as follows (Taken from jwt.io site)
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
You need to do the following:
$ echo 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ:' | base64
ZXlKaGJHY2lPaUpJVXpJMU5pSXNJblI1Y0NJNklrcFhWQ0o5LmV5SnpkV0lpT2lJeE1qTTBOVFkzT0Rrd0lpd2libUZ0WlNJNklrcHZhRzRnUkc5bElpd2lZV1J0YVc0aU9uUnlkV1Y5LlRKVkE5NU9yTTdFMmNCYWIzMFJNSHJIRGNFZnhqb1laZ2VGT05GaDdIZ1E6Cg==
Now use this as follows (with curl)
curl -H "Authorization Basic ZXlKaGJHY2lPaUpJVXpJMU5pSXNJblI1Y0NJNklrcFhWQ0o5LmV5SnpkV0lpT2lJeE1qTTBOVFkzT0Rrd0lpd2libUZ0WlNJNklrcHZhRzRnUkc5bElpd2lZV1J0YVc0aU9uUnlkV1Y5LlRKVkE5NU9yTTdFMmNCYWIzMFJNSHJIRGNFZnhqb1laZ2VGT05GaDdIZ1E6Cg==" http://127.0.0.1:5000/my_secure_endpoint

Categories