Django security - django

hope someone can help me.
I have a stack with Django and tasty pie (I use apikey to authenticate and authorize the users). Let me explain what Im trying to do.
I have several users who can only access their data, so imagine that a user through a rest service access all the rows of the model requestoffer, as follows.
http://127.0.0.1:8001/api/v1/requestoffer/?format=json&username=door1&api_key=84051c6fd1581ad60ffa96bcf5a50d3fc11ccdd3
But I dont want that user access all the requestoffers, I just want him to access the ones he is "proprietary".
Do you have any idea how to do this with either Django or Tastypie?
Did I make myself clear?

If every row belongs to one specific user then you can add it as a foreign key to requestoffer and filter the queryset by the user. Another approach would be to extend Authorization class and implement apply_limits.
class MyAuthorization(DjangoAuthorization):
def apply_limits(self, request, object_list):
if request and hasattr(request, 'user'):
return object_list.filter(requestoffer__user=request.user.id)
return object_list.none()

There are a lot of ways to achieve permission management. Which one suits your needs is totally up to you. One way to achieve this might be to create an 'ownership' relation with the model in question, then create a manager for that model only returning records based on the request. The documentation on model managers is pretty straight forward (and elegant).
To automate the record ownership you could create a CurrentUserField as described in Pro Django, there's also multiple ways to implement that. So a long story short, you should just learn by trial-and-error.

Related

how to exclude results in loopback based on related models

I am using mongo connector.
I have a offers model which has a hasMany relation with my Users model via interested_users key. Basically the idea is that an user can mark an offer as interested or not_interested, and I need to exclude the not_interested offers. What is the best/efficient way to achieve this?
I am still not sure I fully understand your issue, but it is definitely related to querying data with loopback REST API, and especially where filter
If your model offer has a property someone_is_interested (boolean), then the following request could work for you
GET /api/offers/?filter[where][someone_is_interested]=true
But I have the feeling you want to use the relation to store all users that are interested in an offer. In this case, simply establish the relation between any interested user and the offer with this request (in the database, one instance of offer with id=1, and a user with id=2:
PUT /api/offers/1/interested_users/rel/2
And to remove the relation (just the relation, not the user or offer)
DELETE /api/offers/1/interested_users/rel/2
Then, you can simply query all related users of offer with id=1, which will give you all interested users on that offer
GET /api/offers/1/interested_users

Level Specific Access to pages on Django

I currently have a website that has three kinds of permissions:
Active
Staff
SuperUser
What I want to do is limit what a user can view depending on his subaccess level on Driver i.e. Driver has three sub access levels - 100, 200, 300. I was thinking of doing this by
def email_check(user):
return user.accesslevel
#user_passes_test(accesslevel=100)
def my_view(request):
...
How do I add the additional property of the subaccess level to the user model? Is there any other way to implement this? ALso, since this is a an already live project, there are a lot of user on-board already. I'll also need to provide them a default access value.
Your idea to go with user_passes_test looks good to me.
So your main issue is basically how to extend the user model. This topic is covered thoroughly under Django documentation: Customizing authentication.
To sum up, there are mainly two ways to go with. One is to extend your user model with a custom model with an one-to-one relationship with User and any custom fields such as access level.
Alternatively, you can provide with a custom user model and substitute the Django User model, but this seems not appropriate for your case.

How to get django model relations using JSON?

I had no idea how to structure an accurate title for this question, but I did my best so please bear with me.
I am working on a app for my hockey team that consists of a django app and an mobile app that communicates with the django app using JSON (django-rest-framework). However, one problem I am struggeling with figuring out how to solve is as follows:
You create a user (using Token Authentication), and then you create a player and/or a manager.
However, what I am struggling with is what to do when an existing user logs in. How do I check whether or not there is a player or manager associated with that user? When I log in, all I get in return from the rest framework is that user's authentication token, so from a programming perspective, I have no clue what user it actually is since I dont have the user's Id. Even if I did, how can I look up players by anything other than their Id? Currently the only idea I have is to grab all players and loop through them to find one with the same email address as the user currently signed in has.
Hope this made some degree of sense!
Thanks
This isn't really a question about JSON.
Surely the token is associated with a user ID? I don't use django-rest-framework, but the documentation for TokenAuthentication is pretty clear that once the user logs in with their token, you'll get a normal auth.User instance in request.user just like you would with a standard web-based login.
Your second question is probably made irrelevant by that, but even so, you can always query by an email address, without needing to loop through:
Manager.objects.get(email=my_email_address)
Again this is standard Django querying - if you're not familiar with that syntax, you should do the Django tutorial.
Of course, since you have a User already, you can do a more efficient foreign key lookup:
Manager.objects.get(user=request.user)
or even
request.user.manager
(assuming you have a one-to-one relationship from User to Manager - it would have been helpful to see your models).

Tastypie - Queryset or filters

Im using tastypie and i just ran into a problem.
My problem:
Users can post messages and if other users are subscribed to that user they can see those message on their homepage. Its exactly like twitter users tweeting and followers looking at their tweets.
I have a public api for all messages.
I can filter a particular users messages using ?userid=1
Bad solution to problem:
I can filter multiple users messages (and thus solve the problem) using
?userid__in=1&userid__=5&...
But this is not a good way because the url length is going to increase to a possibly unallowed amount. (2000 characters)
Is there a better way of doing this?
Is there a way I can use request.user in a queryset to do a join?
Or should I use some sort of advanced filtering?
Thank YOU!
Tastypie already supports this via __in filtering (everything that ORM supports Tastypie exposes, except negations). No coding is necessary.
Look here: http://django-tastypie.readthedocs.org/en/v0.9.11/resources.html#basic-filtering
path/to/api/resource/?user_id__in=1,2,3,4,5,6
However, you can still have the problem of your URL becoming huge with someone subscribed to many users. What you can do instead is keep this information in the DB model (which user is subscribed to which user as a recursive ManyToMany relationship within the model through a separate joint model).
Then you could expose this through your resource without ever having to specify subscriptions through your URL as a parameter and/or filter. Instead your base queryset in the resource would be:
userids = request.user.subscription_userset.values(id)
provided that you have a self ManyToManyRelationship in your User model. Look here, and here.
What if you had someone pass in a list of user_ids they wanted to see updates for, and then filtered on that? Something like this:
URL: your/api/messages.json?user_ids=5,8,10,25
And then in the code you'd convert that into an actual list, and query:
Message.objects.filter(user__id__in=user_ids)

is that possible to access caller principal in model class in django?

Is that possible to access user principal in model class?
For example, in java, in ejb class, there is ejbcontext variable always available which gives you caller details (authenticated user)
I am wondering are there any way to get this in django in model class only?
obviously that I can pass the request.user into model class but which is very cumbersome.
It's not too clear from your question, but I'm guessing you want "automagic" access to the current user from a model instance.
The short answer is no, it's not possible.
Since models can be manipulated from outside the normal request-response flow (for example, from a cronjob script), a user might not even exist. Aside from that, requests and authenticated users are the domain of views (MVC controllers), not models.
The best you're going to get is manually passing request.user to the model methods you want to use them in. There's some magic you can do with python execution frames and the inspect module, but explicit is really much better than implicit. And, like I said before, request.user (or even request itself) doesn't always exist.