Django, the user model, profiles, and security - django

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.

Related

Generating user profiles with request.user rather than id in url

I am creating user profiles using Django 1.8.
The way I have currently got it is the 'my_profile' view will use request.user() at the top of the view and then generate the information required from there.
My question is weather this is a bad practise for creating profiles.
In the past I have passed the user ID into the URL to create a profile but as it stands I think the request.user() method seems more secure and easier.
Are there any negative implications in creating it like this such as speed issues etc.?
Firstly, you will never be able to view another users profile if you do not use their ID in the URL to generate the view.
However, there is no reason why there would be any negative implications such as speed etc. by designing your user profile in this way.
I would personally recommend against it as it will limit the possibilities of what you can achieve with the user profiles.
And in terms of security, you could just add a check around the user profile view to check the current user has permission to be there.

How to reference a Model from within the User model

The overall use case is that I want to lookup the correct Business for an authenticated User at the start of each view function so that I can look up relevant info for the appropriate Business.
In my app, an User can only be mapped to one Business, and a Business can map to many Users. To create this mapping, I would like to put a foreign key for a Business in the User model. The Django documentation I've read states that creating a custom User model, which this would require, is not necessary for most applications.
Having such a mapping of an User to something else seems like a pretty common use case, so I'm wondering if there is a simpler way to do this that I'm not aware of.
One approach I thought of would be to have a BusinessUserMapping model, which would contain foreign keys to both Businesses and Users. I could then do a lookup of a BusinessUserMapping where the User foreign key matches the current User, but this seems somewhat convoluted.
Any advice on a better way to look up a Business based on the User?

Does Django store information about who has edited and/or created a record, and if so, where?

Django has an authentication and authorization scheme baked in ('django.contrib.auth') as well as modelforms to generate forms for easy input of data into the database.
I'd like to be able to record who created a record, leveraging django.contrib.auth, with the explicit purpose of limiting editing of that same record to just that user and/or people with an "edit" permission. I know that I could use the #user_passes_test decorator to restrict access to editing my record in some fashion, but I don't know what I would compare the request.user.name to in order to determine if the current user originally created that record.
How much of this do I need to roll on my own? Do I need to capture the name author, save it to the model, and then read it - or is there something already in the framework that would do this for me?
And, if I was to attempt to save the author in a field, how would I go about doing that in such a way as to not let the user edit their own credentials?
There are a couple of apps to do something similar, please check https://www.djangopackages.com/grids/g/model-audit/
About the last questions, to prevent the user not to edit its own credentials, you can mark the field with editable=False so it wont appear in the admin or ModelForms.

DRY approach to add user information without using Auth.user in Django

I'm writing an application where I need to register user information even if the user does not exists (yet) in Django. Basically I need to insert almost every fields used by Auth.user (I don't care about password). I've also created a Profile model connected with a OneToOneField to the Auth.user model and I need to fill in these fileds as well for users that do not exist yet.
If a user will register later to the site (using Auth.user) I will look for him by email and if I will find him I will merge my inserted information and the ones that he provided.
QUESTION:
What is the best approach to implement user persistence without repeating myself in creating models very similar to each other?
I would recommend using a dummy value in either the date_joined or last_login fields for the User model, if you wanted to implement a solution without adding a new field just to serve as an indicator flag.
The potential problem with using the is_active flag is that you may end up wanting to use this flag to "blacklist" or effectively delete an account without actually removing their record from your database (to prevent re-creation of the account with same credentials, etc.) If you start relying on the fact that the password is not set, then if the day ever comes where you want to implement alternative login methods (OAuth) then your password field will not be set in these cases as well (huge conflict).

Should I ForeignKey to Django User or a Profile model?

I'm wondering what people's thoughts are on joining models directly to the auth.User object vs to the user's profile model.
I'm storing some different types of models which my user are adding in my app. App users will search for other users via criteria on these models.
On the one hand, I'm thinking that if I join straight to User then I won't need to do request.user.get_profile() each time I need to grab the User's records, and it doesn't presuppose that a User always has a profile (they do in my app at the mo, but still). This leaves the profile model as just containing the user's contact details.
On the other hand, I imagine I'll most likely need values from the Profile (eg name, location) when I'm looking up these other models.
No doubt either will work, so maybe it doesn't matter, but I just wondered what other people's thoughts were.
Thanks!
Ludo.
I would also recommend creating foreign-keys to the User model. It just makes your life simpler when working with the user object in the view, for one. So, you can do things like request.user.foo_set, etc. without having to go through the profile model.
In general: If you want to make your apps reusable, always create foreign keys to User model.
As you already said, in most cases you will need User as well as Profile instance, so to prevent multiple database queries, use cache.
If reusability isn't relevant, create foreign key to Profile and use select_related() to get User instance with single query.