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.
Related
I just started fidling with the user model, and I'm probably wrong on this but I just had a thought and I'm not knowledgable enough to persuade myself it is indeed wrong.
I have a user model, which I extended with a profile via a one-to-one model. (most sources I could find recommended this as a best practice).
Now, it is possible for general users on my app to access bits of the profile data, such as someone's username (part of the user model) or nationality (part of the profile model).
I grab this data in a view I created via objects.get and pass on the results to a template. But doesn't this also pass on the (hashed) passwords? And if so isn't this unsafe?
No. Why would passing the user model to the template be unsafe? End users don't have control of the template, only your code does. If you don't use the password in the template anywhere, then the end user will not have access to it.
In any case, even if you did use it, as you point out only the hashed password is present; but a hash itself is useless. To log a user in, Django needs a raw password which hashes to the same value; but hashes are not easily reversible, which is the whole point of using them.
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.
I wanna build a simple ember app with sails as the backend.
There are nice blueprints that will help me with that, but I want all data to be complete user isolated. So its actually a single user application, but for multiple users.
So all data is different for each user. So when ember makes a request to /notes/findAll I only wanna return the notes corresponding to the user. On the other side a user has full rights on all data that belongs to him (except maybe the user model, which is the only special case).
What is the simplest way to do this?
I could modify the blueprints itself! But is this a good idea? It would be nice to be able to combine it later by configuration on a per-model-base.
Is there a way to do this with a policy? So a policy setting a safe user-filter?
Is there another better/default way to solve my problem?
Thanks!
I am building the same sort of application. I accomplish this by adding an owner attribute to every model, and setting it in a policy.
https://github.com/tjwebb/xtuple-api/blob/master/api/models/base/xTupleObject.js#L29-L32
I created Permission and Role models, and if the object the user is asking for relates to their User object via a Permission and Role, then they are authorized for a particular action.
https://github.com/tjwebb/xtuple-api/blob/master/api/policies/authorize.js#L51-L56
If you want to grant access to the findAll method, you might want to re-implement it in a superclass that all your controllers inherit from. I haven't gotten to this part yet, but this is my plan for solving this problem.
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.
I'm currently developing a Django site in which users can have multiple 'accounts', so that they can seamlessly switch between different public profiles when interacting through the site. What I'm designing is likely to attract multiple registrations per person (and won't be discouraged), I just would like to offer this in such a way as that users can keep the profiles tied together, switch easily and only have to log in once.
The two approaches I've thought up so far include:
One (User model + SiteProfile model) pair and many PublicProfile models per person. AUTH_PROFILE_MODULE is set to point to the SiteProfile model. Issue with this is that I can't easily use per-object permissions: these will be set on the User object and not the public profile, thus permissions to see a page for "PublicProfileA" will also be applied to when the user is masquerading as "PublicProfileB".
One Account model and many (User model + UserProfile model) pairs per person. AUTH_PROFILE_MODULE is set to point to the UserProfile model. This would have the added benefit of the permissions working as intended, and that I can simply have a Custom Backend that will switch users by authenticating a user by if they are currently logged in as another user that has the same Account object as the Foreign Key. Authentication would happen by reading fields on the Account object though, which would mean the password field on every User object would be wasted.
As above, but subclassing Account from User. I've been advised strongly against this though (for reasons unclear).
Is there any pitfalls or better approaches to this? Ultimately, should I use the built-in User model as the one-per-person model that identifies a group of public facing profiles (of which these profiles have a FK back to the User object), or use it as the profile itself, linking back to a single Account object for each person?
Yes, I think the best approach would be to have one and only one User per person and several PublicProfile objects that they can "switch" between. This gives the benefit of only one username/password for them and seems to make the most sense with how Django's auth typically works.