Tornado set_secure_cookie - python

When I set a value in a set_secure_cookie function in Python Tornado, I can get the value whit a get_secure_cookie function when I make a redirec, but when I use a render action it doesn't appear.
form = UserAddForm(self.request.arguments)
if form.validate():
record = User(**form.data)
self.db.add(record)
self.db.commit()
self.set_secure_cookie("flash", "success")
self.redirect("/user") # Show the flash message with self.get_secure_cookie("flash")
else:
self.set_secure_cookie("flash", "error")
self.render("user/add.html", form=form) # Don't show the flash message with self.get_secure_cookie("flash")

Function "set_cookie" will set cookie in the HTTP response header which will effect in the next request.

Related

Redirect to the same page and display a message if user insert wrong data

I am building a web chat application with chat rooms.
I have a page where users can open a new room, inside the page, there is a form.
I want to display a message to the user if he submits the form with a room that already exists.
For example:
Room 456 already exists and the user tried to open 456 room.
so I want to pop up a message that the room already exists.
The server side
#app.route('/NewRoom')
def newRm():
return render_template('NewRoom.html')
#app.route('/chat',methods=['GET','POST'])
def CreateRm():
if(request.method=='POST'):
username = request.form['username'].lower()
room = request.form['room'].lower()
ExistRoom = DBManage.ExistRoom(room)
error = "YOU ENTERED ROOM THAT ALREADY EXISTS"
if not ExistRoom:
limit = request.form['limit']
if limit == '':
limit = 'UNLIMITED'
session['limit'] = limit
image = request.files['getFile']
newImgs = open("static/images/" + username + ".jpg","wb")
newImgs.write(image.read())
newImgs.close()
room = room[:5].strip()
DBManage.newRoom(room,limit)
DBManage.newPerson(username,room)
#sDBManage.RoomUsers(room)
#Store the data in session
session['username'] = username
session['room'] = room
return render_template('chat.html', session = session)
else:
flash(error)
return redirect(url_for('newRm',error=error))
Inside CreateRm function the else at the end didn't work for me well, it's refreshing the page but doesn't send the error message, not really know how to solve that.
Client side
{% if error %}
<p class=error><strong>Error:</strong> {{ error }}
{% endif %}
Thanks all.
The problem is that you are returning a redirect to another route as well as trying to pass a variable to a template in that route. One way you could do this is by simply re-rendering the template, passing the variable, error to it at the same time. Try replacing:
return redirect(url_for('newRm',error=error))
with
return render_template('NewRoom.html', error=error)
Another option would be configuring your newRm route to accept optional arguments. This could look something like this:
#app.route('/NewRoom', defaults={'error':''})
#app.route('/Newroom/<error>')
def newRm():
return render_template('NewRoom.html')
You then pass an error to this route exactly as you have been doing.
return redirect(url_for('newRm', error=error))
To completely solve your problem, you'll also have to add a return statement outside your if(request.method=='POST'): to catch any GET requests. It could be something like this:
return render_template('NewRoom.html')

How to send authorization header from html to flask

I have a project that use flask in backend and jinja and html for frontend.
What i need is to send a request that has an authorization header and all my routes read that header to see if its from an valid user or not?
def show_admin():
data = request.headers.get('Authorization')
# data = "TOKEN123"
# واکشی اطلاعات مورد نیاز صفحه داشبورد
content = {
'user': mydb.selectalluser(),
'doreh': mydb.selectalldoreh()
}
# چک میشود اگر توکن ارسالی توسط کاربری معتبر است یا خیر
if str(data) == "TOKEN123":
return render_template('admin/dashboard.html', content=content)
# return hello
else:
# اگر توکن معتبر باشد صفحه لود خواهد شد
return render_template('login/index.html')
In the if statement it check if the token is valid or not. but...
1. how to generate a request that included Authorization header
2. how to generate a token for login page
You can't control the client-side request header (i.e. Authorization) on the server-side. IMO, what you want is manage user login/session status, you can implement this with Flask session, the information stored on session can be obtained between requests (use Cookie):
from flask import session
#app.route('/login')
def login():
session['token'] = 'TOKEN123' # store token, use it as a dict
return 'login success'
#app.route('/admin')
def show_admin():
if session.get('token') == "TOKEN123": # get token
return 'admin page'
else:
return 'login page'
However, I would recommend using Flask-Login to handle user session manganment.

Twilio: Create two outgoing calls and join the conference using Python

I am trying to create a conferencing app with max 2 speakers using Twilio using Python/Django. However, in the docs I found out that you can do this by having inbound calls. but, my business model doesnt work like that. Is there a way for this to work like:
My Twilio number calls number 1
My Twilio number calls number 2
Twilio brings two channels to a new conference
I've tried this solution:
Twilio how to make two outbound calls and join(conference) them using node js
but it didn't help me much..
Here's my code:
#csrf_exempt
def conference(request):
print("success")
response = VoiceResponse()
dial = Dial()
dial.conference('Rooxm 1234')
response.append(dial)
print(response)
return HttpResponse('')
def call(number):
client = Client(TWILIO_ACCOUNT_SID,TWILIO_AUTH_TOKEN)
call = client.calls.create(
url='https://<blahblah_removed_purposefully>.ngrok.io/conf/',
to='+' + str(number),
from_='<removed_my_twilio_num>'
)
print(call.sid)
def index(request):
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = CallForm(request.POST)
# check whether it's valid:
if form.is_valid():
#print(dir(form.data.values))
call(form.cleaned_data['inline'])
call(form.cleaned_data['outline'])
return HttpResponseRedirect('/thanks/')
# if a GET (or any other method) we'll create a blank form
else:
form = CallForm()
return render(request, 'CallForm.html', {'form': form})
This gave me an error message during the call which is:
"An application error has occurred. Goodbye"
And I also get this in the debugger:
"Error on line 1 of document : Premature end of file. "
Any idea?
Okay so, I figured this out. The only thing that was needed to make that setup work is I had to modify the response, add the xml string there and then set the content_type of the returned object.
return HttpResponse(str(response),content_type='application/xml')

How to set cookie values and then immediately redirect to the next page and display what's in them

So I need to store two variables from one view and redirect to another view and display them. The obvious solution would be to use sessions but I don't have access to sessions because I don't have a database for this project so I'm trying to do sessions client sided because this isn't really a security issue anyways. This is my attempt so far:
View where I set the cookies:
response = HttpResponse('/result')
response.set_cookie('passes', True)
response.set_cookie('errors', [])
v = jsonschema.Draft4Validator(schema)
#Uses lazy validation to add all errors to validationErrors array
for error in v.iter_errors(jsonFile):
validationErrors.append(error)
response.set_cookie('passes', False)
for error in validationErrors:
error.schma_path = error.schema_path.__str__()[5:]
print error.schma_path
print error.schema_path
response.set_cookie('errors',validationErrors)
...
return redirect('/result')
View where I try to get the cookies:
passes = request.COOKIES.get('passes',"Doesn't Exist")
errors = request.COOKIES.get('errors', "Doesn't Exist")
return render(request, 'result.html', context = {'errors': errors, 'passes': passes})
passes and errors isn't set because they both return Doesn't Exist. How would I do this without returning to the original page? I don't want to return response where response = render_to_response(current view's template) because it defeats the purpose of what I'm trying to do.
You are not getting any cookies values, because actually after assigning the response a cookie, the function returns another Http response.
response = HttpResponse('/result') # first Http Response
response.set_cookie('errors', [])
...
return redirect('/result') # An other one
In the last line, you return another response.
so you should return the same response:
response = redirect('/result') # redirect is here
response.set_cookie('errors', [])
...
return response

Returning error indication when flask POST Request fails

I'm trying to create a simple flask application that takes a string from an iOS application and stores it in a local data base. I'm a bit confused whats happening in the return portion of the submitPost() function. I'm trying to return a dictionary that contains a BOOL that indicates whether the Post request executed fully. However, i'm not sure how to variate between returning a 0 or a 1.
//Function that handles the Post request
#app.route('/submitPost/', methods=['POST'])
def submitPost():
post = Post.from_json(request.json)
db.session.add(post)
db.session.commit()
return jsonify(post.to_json), {'Success': 1}
Try the below. This way if an exception is thrown when trying to insert data it will be caught and the transaction will be rolled back as well as a response being send back.
you could also replace the zero and one with True & False depending on your preference
Below code hasn't been tested
#app.route('/submitPost/', methods=['POST'])
def submitPost():
try:
post = Post.from_json(request.json)
db.session.add(post)
db.session.commit()
return jsonify({'Success': 1})
except Exception: # replace with a more meaningful exception
db.session.rollback()
return jsonify{'Failure': 0}

Categories

Resources