Complex routes for Flask-Restless (e.g. "forgot password") - python

I wish to make a route for "forgot password"-functionality, while using Flask-Restless. My idea was that the request could look like this:
POST /api/user/<id>/forgot_password
and Flask-Restless would send this request to a custom "forgot password"-route which I provided. This way, I could define my own complex operations here on the user object (store intermediate stuff in DB, email password reset link, etc.)
I have not been able to find such functionality in the docs for Flask-Restless. Also, while trying to make a quick (hacky) separate route (outside of Flask-Restless) which simply corresponded to the above route, Flask-Restless still picked up on the request and returned a 405 (Method Not Allowed).
One can imagine this kind of functionality for other complex operations as well (e.g. change password, change email).
Is it possible to achieve this routing scheme somehow? If so, how?
If not, what would be an alternative? An ordinary route in a separate blueprint?

This is not possible within the Flask-Restless extension. One might be able to add it manually.
I made a feature request for this on the Flask-Restless issue tracker, and it was determined to be out of scope by the author.

Related

Middleware in flask

I just stated using Flask and was trying to implement a small feature in my project. The objective is to set a cookie only if the request comes from a authenticated user.
I found two ways of doing this.
First method
#app.before_request
def before_request():
# set cookie if user is logged in
Second method, by implementing something like this
adding-a-simple-middleware-to-your-flask-application
Can someone explain to me what are the main differences between the two methods and when and where which method should be used.
Also, I am currently using "flask-login" to keep track of the logged in user.
If I use the first method, I can easily verify if someone is logged in by importing the current_user
from flask.ext.login import current_user
but if I try to do the same while using the second method, the current_user is always "None" as the application context is incorrect.
So, I wanted to know if I decided to go ahead with the second implementation, how do I check if the user is logged in or not.
I've never used the second method you've mentioned. I'm sure that it can be done with it, but it's very uncommon. I would suggest to use more common features of flask. For sake of maintainers of your code :)
So the first method you've mentioned is fine.
Or you can use decorators for more granular access restrictions. Keep in mind that setting cookies in flask can be done when making actual response object. That means you should use Deferred Request Callbacks for setting cookies in decorated function.

web service requests authentication django token-api

I want to implement a web service for an iOS application in django.
I need some kind of authentication, and I googled and heard good things about django token-api.
The only thing I don't understand, is how I make sure one authenticated user can not perform actions for another.
For example, If i have a view that has the #token-required, that only promises that a valid token has been sent, however someone can just change the PK in the request itself and make changes for another user.
How do I make sure the user who has the token, can only perform actions for himself?
On a very broad level, you need to distinguish between authentication and authorization. You can read this page as an example, or google it for more, but the basic distinction is that authentication determines that a user is who he says he is, while authorization determines what a certain user is able to see or do.
As you noted above, you can use the django-token-api to help with the authentication issue. But once you've determined that, you need to move to authorization. This is more an issue of permissions that you can see on a per-user (or per-group) basis for individual objects, views, etc.
As Ambroise noted in the comments, using an API framework can make this easier. Here is the django-rest-framework documentation for setting permissions once you have authenticated the user.

Save additional info to Facebook authenticated user?

I'm using python-social-auth and I'm successfully able to authenticate a user with his Facebook account, but only the email is persisted. How do I:
persist the birthday?
add and persist information that doesn't come from FB, like his pet name? (as far as I know, I'll have to use a pipeline but don't know how)
Any help will be appreciated.
Thanks in advance!
PS: Would someone with enough reputation create a tag 'python-socialauth'?
Birthdate persistence is as simple as defining SOCIAL_AUTH_FACEBOOK_EXTRA_DATA = [('birthdate', 'birthdate')], later you can access it by doing user.social_auth.get(provider='facebook').extra_data['birthdate'].
Other data must be saved with a pipeline, which is not as simple, but not hard to do. A pipeline is a function that will be called during the auth process (even on signup, login or association, so the function needs to check for that if needed). The function will get many parameters like the strategy, backend, social, user, response, requests, details, etc, it's best to define the needed parameters and then use **kwargs to ignore the others.
Once the function is coded, it should be added to SOCIAL_AUTH_PIPELINE setting (be sure to add the default entries also, or the auth process won't work, those can be find here http://psa.matiasaguirre.net/docs/pipeline.html#authentication-pipeline).

Checking login status at every page load in CherryPy

I am in the midst of writing a web app in CherryPy. I have set it up so that it uses OpenID auth, and can successfully get user's ID/email address.
I would like to have it set so that whenever a page loads, it checks to see if the user is logged in, and if so displays some information about their login.
As I see it, the basic workflow should be like this:
Is there a userid stored in the current session? If so, we're golden.
If not, does the user have cookies with a userid and login token? If so, process them, invalidate the current token and assign a new one, and add the user information to the session. Once again, we're good.
If neither condition holds, display a "Login" link directing to my OpenID form.
Obviously, I could just include code (or a decorator) in every public page that would handle this. But that seems very... irritating.
I could also set up a default index method in each class, which would do this and then use a (page-by-page) helper method to display the rest of the content. But this seems like a nightmare when it comes to the occasional exposed method other than index.
So, my hope is this: is there a way in CherryPy to set some code to be run whenever a request is received? If so, I could use this to have it set up so that the current session always includes all the information I need.
Alternatively, is it safe to create a wrapper around the cherrypy.expose decorator, so that every exposed page also runs this code?
Or, failing either of those: I'm also open to suggestions of a different workflow. I haven't written this kind of system before, and am always open to advice.
Edit: I have included an answer below on how to accomplish what I want. However, if anybody has any workflow change suggestions, I would love the advice! Thanks all.
Nevermind, folks. Turns out that this isn't so bad to do; it is simply a matter of doing the following:
Write a function that does what I want.
Make the function in to a custom CherryPy Tool, set to the before_handler hook.
Enable that tool globally in my config.

requests using django session table

I have an application that uses the requests library to make calls to a web service. On django, I use a table to keep sessions using the standard django_session library.
I've noticed that I have a new record in the database for every time the requests library fires off a call. I find this quite bizarre, since I'm not using request sessions (explicitly) and most of my calls are single GET calls that shouldn't need any kind of persistance.
Has anybody else had this problem?
django.contrib.sessions.middleware.SessionMiddleware will create a new session for each request.
If you want to disable this behavior, consider replacing django.contrib.sessions.middleware.SessionMiddleware with a custom middleware that extends django.contrib.sessions.middleware.SessionMiddleware but prevents sessions from being created in instances where you don't want them.
This answer provides an example of how to do so. It parses request.path_info to determine whether a session should be created, but you could use a number of different techniques, such as adding a custom header to your request, including a post variable, etc.
Turns out I had this setting turned on
SESSION_SAVE_EVERY_REQUEST=True
When I started with sessions I wanted to be safe to make sure nothing falls through the cracks. Turns out this was then writing empty session information to the db.

Categories