Django tastypie: User sees no data - django

I want to add authentication to my API, so only authorized people can see the data.
To my resource class I added:
authentication = BasicAuthentication()
authorization = DjangoAuthorization()
Then I added a new user using Django admin. He's listed as active and staff. No other permissions have been given.
Now whey I try the resource URL, it asks for credentials.
When I use the new users credentials, I get nothing:
{"meta": {"limit": 20, "next": null, "offset": 0, "previous": null, "total_count": 0}, "objects": []}
No objects, nothing. If I login as root, I see all the data.
How do I assign stuff to the user so it can see the resources?

Firstly, stuff status only designates whether the user can log into this admin site.
You should see
What's the difference between staff, admin, superuser in django?
Secondly, Tastypie's DjangoAuthorization checks the permission a user has granted to them on the resource’s model (via django.contrib.auth.models.Permission).
https://django-tastypie.readthedocs.io/en/latest/authorization.html#djangoauthorization
Obviously, the reason of why root can see all the data is that the root is superuser.Thus, you can do:
grant the user superuser;
grant the user read permission(can change ..) of current resource_model;

Related

How to make Django REST User API with complex permissions

I want to make a Django REST User API with complex permissions as follows:
GET
Only Admin should be able to get all User data
Logged in User should be to get himself and the names of other Users
PUT
Only Admin and Self should be able to PUT
Except for is_staff and is_superuser only is_superuser should be able to change the status of a user
Password changes by a User should require the old password
if User is !is_staff password reset should be possible
POST / DELETE
Only Admin should be able POST/DELETE User
User should be able to update his own Profile
Unfortunately, I have no idea how to control the view or serializer to allow such permissions. Is there a template how I can exactly control the permissions?
You can write your custom permission according to DRF docs.
And add YourCustomPermission in your view:
class ExampleView(APIView):
permission_classes = (YourCustomPermission,)

Normal user/token user authentication

In my Django project I need two type of users:
- users authenticated with login/password (django.contrib.auth.models.User)
- users authenticated with token (Django REST Framework)
What's more I wish I could keep both of them in one table and display only "User" page in admin panel.
What would you suggest will be the best solution?
The token from DRF doesn't create a new User table it just creates a Token table with a one-to-one relationship with the existing User table, so you'll always have a single table (admin page) "User"
You decide what users should have a Token. for example:
# create API Token
regular_user = User.objects.create_user(....)
api_user = User.objects.create_user(...)
Token.objects.create(user=api_user)
now regular_user can only access using login/password (since he doesn't have a Token) and api_user can do both
Hope this helps

Where in database does python-social-auth store access token?

I am using python-social-auth (within django) to implement facebook-login. I am able to successfully sign into my app using facebook and extract user email. But where in the database can I find the OAuth token generated by facebook? Is it in the password field in the user table?
It's in the UserSocialAuth extra_data field which is a JSONField.
Example of the value stored:
{"expires": "5184000", "id": "00000000000000000", "access_token": "the-token-value"}

Django Integrating Python Social Auth And The Default Auth With A Custom User Model:

I have a project I am working on that requires some users to be authenticated via facebook and others to sign up using a custom model. The facebook users will not have the same sign up credentials as the custom model. For example- there will be a restaurant owner sign up and a customer signup. The customer will not have to put a street address location, they can simply login.
My intentions were to have the restaurant owners sign up via the custom profile model and the facebook users to simply login via the defualt social auth, but whenever I combine the two, social auth starts to use the custom model because I define a custom user model within settings. Is there a way to distinguish to the python social auth backend to only use the default or a way to update my current custom user model to have a facebook segment. I have searched the web for a long time for this, but can not seem to find anything that can combine the two besides (1), but it did not work successfully. I can however get one or the other working successfully depending on if I specify a user model in my settings.py file or not.
It is quite simple, but I do not know of a way to get social auth to look at its default and djangos authentication to look at my custom model.
(1)-http://code.techandstartup.com/django/profiles/
In order to distinguish one type of user from another, you can do something like this:
First, in your settings file, store the following:
FIELDS_STORED_IN_SESSION = ['type']
This will be stored in strategy parameter in every function of pipeline
Then, change the pipeline wherever necessary. For example, in your create_user pipeline function, you can do this:
user_type = strategy.session_get('type')
if user_type != 'customuser':
return {
'is_new': True,
'user': strategy.create_user(**fields)
}
else:
return {
'is_new': True,
'user': create_restaurant(**fields)
}

Django Multiple Authentication Backends Based On Status

I was wondering how to tell Django which authentication backend to use based on if the user is marked as staff or if they are not.
Can this be done?
Since the authentication backend is used by Django to get the user object, it is not known at the time we're calling the backend wether the user will be marked as staff or not.
Is is still possible to use different backends for staff and non-staff user, by chaining backends as explained in Specifying authentication backends. For example if your settings are:
AUTHENTICATION_BACKEND = (
'myapp.auth.StaffUserBackend',
'django.contrib.auth.backends.ModelBackend',
)
where myapp.auth.StaffUserBackend only recognizes staff users, this will happen when an user authenticates:
The credentials are checked against StaffUserBackend.
If the user is staff and the credentials are correct, StaffUserBackend returns the user object and we're done.
If the user is not staff, credentials are checked against ModelBackend.
If the credentials are valid for a standard user, ModelBackend returns the User object and the user is authenticated as usual.
If the credentials are not accepted by any backend, the authentication fails.
As Django Runs all the backends one after another. What you can do is use the authenticate function in your views.py file.
For example you want check for staff user then
email = form.cleaned_data['email']
try:
name = StaffUser.objects.get(email=email)
except StaffUser.DoesNotExist:
return "Do whatever you want"
user = authenticate(username=form.cleaned_data['email'], password=form.cleaned_data['password'])
In this your autheticaton function will be called only when the user exists.
This is kind of rough idea use it as per your convenience.