I'm trying to use Tornado with SqlAlchemy, I need to pass the current user from RequestHandler (tornado) to models (SqlAlchemy) in the insert or update action. But I don't want to pass the value directly to the model, example:
#### RequestHandler POST method...
user = Session.query(User).get(1)
user.name = "bla, bla, bla..."
user.updated_by = self.current_user # don't use...
session.commit()
I'm using a global variable, in a __ init__.py file, and set the current user value in the RequestHandler and after, get the value, in before update event with SqlAlchemy.
The idea is to know what user is the creator and updater.
Why I don't want pass the current user directly to model like the before example ?, because this will be a tool for other developers, and I'm trying to make comfortable for them, also, they can forget about it and it is important.
Is this a good idea, or maybe is there other better way ?
Your solution will have issues if you're handling more than one request at a time. Tornado is an async web framework so another request might overwrite your global var and set the user to someone else. It's good practice to store request depending data on self, tornado will make sure that data is altered by other simultaneous requests.
A solution that might work for you is to add your tool in the basic handler or create a decorator. It's tricky to sugest more details, please include more info in your question if you would like to get better alternatives.
The current user is available in every handler (and template). How you determine, authenticate and set the current user is up to you.
Basically just subclass tornado.web.RequestHandlerand override the get_current_user method in your new/own BaseHandler.
Here the quote from the tornado docs:
tornado User authentication
User authentication
The currently authenticated user is available in every request handler as self.current_user, and in every template as current_user. By default, current_user is None.
To implement user authentication in your application, you need to override the get_current_user() method in your request handlers to determine the current user based on, e.g., the value of a cookie. Here is an example that lets users log into the application simply by specifying a nickname, which is then saved in a cookie.
You can see a fully working example in the official tornado blog demo
Related
I am building a very small API using Python and was wondering whether it is generally acceptable to place API code in a model class when using frameworks like Django or Flask (with an ORM like Peewee or Pony). Let me explain what I mean...
To illustrate what I mean, imagine I have a package with all my models and then another package with my API code which executes when a client pings a particular route that I have defined. As you know, the models are basically only for mapping objects to the database. Although, under certain circumstances, it personally makes more sense for some reason to place some of the API code in one of the model classes I have defined.
For example, I have a User model that maps a user to the database. Additionally, in the API code, I have a function to login the user. This function basically sets the cookies to login the user so it might make sense to place it in the API package. However, I feel like if I make this function a method and place it in the user model, it makes more sense semantically and might be easier to understand.
class UserModel(Peewee or Pony or Django.model...):
def login(self):
"""" Login code goes here. Set cookies, login the user, etc. """
add_cookies(self.username)
return jsonify({"logged_in": True}) # Flask example...
user = UserModel()
user.login()
One caveat of doing this, however, is that the models code and the API code are no longer decoupled and now strongly rely on each other.
Therefore, I guess my "objective" question is about the acceptability of each of these. Is keeping the models (database and ORM stuff) and the API routes decoupled better practice than combining them together? What are some of the advantages and disadvantages of doing each of these? What is the most common and recommended practice?
Thanks in advance.
TL;DR: it's fine to put a function within the model class however if you want secure logins you will need to pass the login information within a token using something like Flask-Login (I'm not sure what the equivalent extension is for django).
Putting a function within the class is fine, however this won't be very secure for a login, so I'd suggest following a tutorial for implementing a secure login extention.
For example, on one of my projects the views function for the login page is:
#user.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm(next=request.args.get('next'))
if form.validate_on_submit():
u = User.find_by_identity(request.form.get('identity'))
if u and u.authenticated(password=request.form.get('password')):
if login_user(u, remember=True) and u.is_active():
# Handle optionally redirecting to the next URL safely.
next_url = request.form.get('next')
if next_url:
return redirect(safe_next_url(next_url))
return redirect(url_for('user.settings'))
else:
flash('Identity or password is incorrect.', 'error')
return render_template('user/login.html', form=form)
Note that the u.authenticated is a function within my User model Class that checks the users password hash is correct:
def authenticated(self, with_password=True, password=''):
#Ensure a user is authenticated, and optionally check their password.
if with_password:
return check_password_hash(self.password, password)
return True
TL;DR : your login method - which is only about HTTP-related stuff - doesn't belong to the model layer, period.
Longest answer : adding logic to models is of course a good design, but this has to be domain logic, not UI-related stuff. The point (since you ask about "good practices") is to keep the domain layer (models) totally independant of the UI (views and controllers) so you can use the same domain layer with different UIs (remember that command-line scripts ARE a UI too).
I had to work with quite a few badly designed applications/frameworks that mixed concerns and actually required having a "request" (http request) and "response" object at hand whatever you wanted to do and those were a complete nightmare to deal with, so from experience the "separation of concerns" rule is not something you want to break.
Just note that this doesn't mean the UI layer should not know about the domain - this would make no sense, and would actually be just impossible from a technical POV.
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.
I'm using django rest framework and trying to save some data so it will be accessible by GET, PUT, DELETE.
So when user send GET request server send some information (a random number, for example) and that information is needed after user sends PUT request on the same url. How would one save such information? I'm using class-based views.
So i want to save that information on GET method.
I tried saving that information to class variable self.information, but the problem is self.information is empty when PUT method is getting called.
I also tried saving it to session, but like class variable, session is also empty when PUT method is being executed.
class SampleClass(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, generics.GenericAPIView):
serializer_class = SampleSerializer
def get(self, request):
random_number = random.randint(0, 10)
request.session['number'] = random_number;
content = {'random_number': random_number}
return Response(content)
def put(self, request):
number = request.session['number'] # key doesn't exists
process_number(number)
# ...
Before I begin, it's important to note that HTTP is a stateless protocol, and you are looking to add state into the mix. If you can rework what you are doing to not depend on previous requests, that will probably be better in the long run.
I tried saving that information to class variable self.information, but the problem is self.information is empty when PUT method is getting called.
This is because the class is re-initialized for each request. Because of that, the class variables don't persist across requests. Even if they did, that would mean everyone would get access to the persisted value, and it isn't made clear if that is what you are looking for.
I also tried saving it to session, but like class variable, session is also empty when PUT method is being executed
This doesn't work because Django sessions are persisted through the use of cookies. While this might work for SessionAuthentication, it won't work for any authentication that happens outside of the browser. This is because the session cookies won't be included, so Django will think the new requests are under a different session.
Now, just because HTTP is mostly stateless and doing this might lead to future trouble, that doesn't mean that you should never do it. The Django sessions wouldn't exist if there wasn't a need for it, and there are ways to save state without Django sessions.
Create a new model for the state - This is usually the best way to save state per-user and ensure that it doesn't fade away. The model needs a user field along with the fields that the state will be stored in, and all you need to do is have a query that retrieves the state object for the user.
Use the Django cache - This is the way I would recommend it for the case that you specified in your question. When you don't need to store much state, the state is shared among everyone, or you can live with it not existing (expiring), storing the data in a simple cache environment will probably work the best. You have much more control over what is stored, but at the expense of having to do more work.
I'm using Python + Pylons to authenticate a user, and am then sending a unique md5 sum and storing it as a cookie to verify the user at every page load. Where in my application is the best place to put the cookie handling functions so that they are accessible throughout my application? Should I declare a global variable such as, USER, that would be accessible throughout the application storing important values like first name, last name, etc ... of the logged in user? Thanks.
It sounds like you've already got the userid in a cookie, you just want to make it more accessible. You'll probably find it useful to have a simple helper function that takes the request and returns the user.
def get_user(request):
""" Load the user from the request, or None if unauthenticated."""
if not hasattr(request, '_cookie_user'):
# parse the userid from the cookie
# make sure you actually trust this cookie by signing it
# or storing it in something that's already protected
# like beaker instead of a raw cookie
userid = request.cookies['mycookie']
request._cookie_user = DBSession.query(User).get(userid)
if user and user.is_active:
request._cookie_user = user
return getattr(request, '_cookie_user', None)
Later in your app you can simply call user = get_user(request).
A database or memcache is usually the place to store this kind of information.
Pylons provides Beaker: http://docs.pylonsproject.org/projects/pylons-webframework/en/latest/sessions.html
I'm working on a medium sized project in django and i want to be able to access the current user from within my query manager. I need to be able to design a custom manager to limit the results and querysets so that the current user only get's information related to him/her.
I've received a few suggestions, I've also seen the not so supported example of using threadlocals from a django middleware. However, i'm very confused as this seems to be most promising solution now. I am looking for a better way to do this, so i can gain access to the current user from within a model manager.
you can store the user object in the session object and get it out when needed
refer to how-to-lookup-django-session-for-a-particular-user
There is no sane way to get the user outside of the request. If the current user matters then pass it to any functions that need it.