User authentication to specific users - python

Hello i use #login_required to restrict access to some pages that stores bookmarks for users, but in some cases i want the user to access only his bookmarks and must be stopped if he try to enter a url that edits a bookmark that belongs to another user. how can i do that?

#login_required can help you make sure the user is logged in to even access the view.
Once the view is accessed you could check to make sure the user is allowed to access the bookmarks, and only fetch bookmarks they are allowed to access
for example if your url looked something like
/bookmarks/ and corresponds to function bookmarks
#loggin_required
def bookmarks():
# only fetch book makrs for this user
bookmarks = Bookmarks.objects.filter(user=request.user)
This will make sure user is logged in to access the url and that book marks are only displayed for the user that is viewing the page. You could add some sort of permission system if some users can view other users bookmarks
if this view were to show all book marks for a user and you wanted to provide a url to edit bookmarks or something like
bookmarks/{{ bookmark_id }}/edit that maps to edit_bookmark
#login_required
def edit_bookmark(bookmark_id):
# user is guarenteed to be logged in so request.user is available
# your permission system will depend on how you authenticate whether a user can edit
# a bookmark or not
# CHECK if user has permission to edit bookmark
pass

Related

Django Staff Member Required Decorator does Infinite Loop if access denied

I am using the Django staff_member_required decorator to protect an admin area of the site.
I am using it like this
#staff_member_required(login_url=reverse_lazy('account_login'))
def kommando_home(request):
# business logic
return render(request, 'kommando/home.html', context)
I am using the custom login so users do not see the Django login page if they hit the URL.
However, if a user who does not have staff permision logs in, it just results in this:
I can add a redirect parameter to the decorator but that always redirects the user to the url provided even if the user has permission.
I tried looking into customizing the decorator but I do not see any way to check if permission denied is raised.
The reason for the infinite loop is this. The #staff_member_required requirement is not met since the user is not staff, which takes the user to the login_url, but the user is already logged in, so the account_login takes the user to it's next parameter, which is the original page with staff_member_required, etc...
What you might try instead is to check for the permission in the view itself, then redirect from there:
Check out Serafeim's answer at How to check the user's permissions in views.py?
Use has_perm:
So, from inside your get_context_data you can do something like this:
if self.request.user.has_perm('applications.admin_access'):
# redirect to one page
else:
# redirect to the other page

Page not found http://127.0.0.1:8000/manageAccount/a/delete

I don't know why I get this page because I think all works right. I couldn't identify why the browser gives this error but below url is not worked because user object not get because its redirect on login page but i am going on this url http://127.0.0.1:8000/user_homeview/a/delete its work successfully but user_homeview that template is after login show means homepage i dont know what can i do please tell me:
Page not found http://127.0.0.1:8000/manageAccount/a/delete
Here is my code:
template.html:
Delete Account<Br>
urls.py:
path('<str:username>/delete', delete_user, name='delete-user')
views.py:
def delete_user(request, username):
context = {}
u = User.objects.filter(username=username)
u.delete()
messages.success(request,'your account delete')
return render(request, 'home/login.html', context=context)
Check on your developer tools what is being rendered on your href attribute. I think the url is not being rendered correctly by your current template tag. It should be like this, according to Django's documentation:
Delete Account<Br>
Note that you don't have access to request by default in your templates. If you are deleting a user by its username, the previous code would be:
Delete Account<Br>
as user is accessible by default in your templates.
Be aware that this is not the secure way of deleting users, as anyone with other user's information can access this link to delete accounts. You should use POST requests and check if the user requesting the delete link is the owner of the account.

How do I check authentication across all views in Django using Pyrebase?

Okay so, ordinary Django allows you to simply:
if request.user.is_authenticated:
I want to be able to do the same in Pyrebase. Have the views sort of already know which user has logged in based on the current session without having to sign the user in in all views.
I have tried:
def sign_in(request):
user = firebase.auth().sign_in_with_email_and_password('email', 'password')
user_token = firebase.auth().refresh(user['refreshToken']
request.session['session_id'] = user_token
I noticed this creates a session ID for me. But I don't know how to associate it with the current user and I know it has something to do with the refresh token.
If I don't check authentication, anyone can visit any page of my site without signing in.

django: keep each users data separate

I am trying to workout how / the best, most secure way to keep a user's data separate within a django site that I need to write.
Here is an example of what I need to do...
example app ToDoList
Using django contrib.auth to manage users / passwords etc, I will have the following users
tom
jim
lee
There will be a ToDo model (in my real app there will be additional models)
class ToDo(models.Model):
user = models.ForeignKey(User)
description = models.CharField(max_length=20)
details = models.CharField(max_length=50)
created = models.DateTimeField('created on')
The issue that I am having - and may be over thinking this: How would this be locked down so tom can only see Tom's todo list, lee can only see his todo list and so on...
I have seen a few posts stating that you could use filter in every query, or use urls, so the url could look like www.domain.com/username/todo
But either way I am not sure if this is the right way / best way, or bonkers in terms of stopping users seeing each others data
cheers
Richard
One approach is to filter the ToDo items by the currently logged in user:
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from your_app.models import ToDo
#login_required
def todos_for_user(request):
todos = ToDo.objects.filter(user=request.user)
return render(request, 'todos/index.html', {'todos' : todos})
This locks down the view for authenticated users only, and filtering by the logged in user from the request, another user, even if logged in, can't access another user's ToDo records. Hope that helps you out.
Make url like www.domain.com/username/todo is one way to implement it, but it doesn't guarantee you achieve security.
What you should do keep your user's login information in a session data after user login, and every time you check certain view,
check whether that particular user has right to see this view.
using user's login info (ID, or username) when querying user's Todo list.
And I guess this link will help you to do your job.
Sessions, Users, and Registration.

Converting separate functions into class-based

I have several function that need to have a 'redirect' filter. The redirect filter goes something like this --
1) if a user is not logged in and has no session data, redirect to login page.
2) if a user is logged in and has already filled out the page, redirect to user home.
3) if a user is logged in and has not already filled out the page, stay on the page.
4) if a user is not logged in and has session data, stay on the page
I've started to convert the functions into a class-based approach to make it more efficient and less code (previously my view functions were pretty massive). This is my first stab at trying make something class-based, and this is what I have so far --
def redirect_filter(request):
if request.user.is_authenticated():
user = User.objects.get(email=request.user.username)
if user.get_profile().getting_started_boolean:
return redirect('/home/') ## redirect to home if a logged-in user with profile filled out
else:
pass ## otherwise, stay on the current page
else
username = request.session.get('username')
if not username: ## if not logged in, no session info, redirect to user login
return redirect('/account/login')
else:
pass ## otherwise, stay on the current page
def getting_started_info(request, positions=[]):
location = request.session.get('location')
redirect_filter(request)
if request.method == 'POST':
form = GettingStartedForm(request.POST)
...(run the function)...
else:
form = GettingStartedForm() # inital = {'location': location}
return render_to_response('registration/getting_started_info1.html', {'form':form, 'positions': positions,}, context_instance=RequestContext(request))
Obviously, this view is not fully working yet. How would I convert this into something that's functional?
Also, I have three variables that will need to be reused in several of the getting_started functions:
user = User.objects.get(email=request.user.username)
profile = UserProfile.objects.get(user=user)
location = profile.location
Where would I put these variable definitions so I can reuse them in all the functions, and how would I call them?
Thank you.
Django actually already includes a login_required decorator that makes handling user authentication trivial. Just include the following at the top of your view.py page:
from django.contrib.auth.decorators import login_required
and then add
#login_required
before any views that require a login. It even handles redirecting the user to the appropriate page once they log in.
More info here:
https://docs.djangoproject.com/en/dev/topics/auth/#the-login-required-decorator
This should greatly simplify your views, and may result in not having to write a separate class, since all that's left is a simple re-direct.
As for the variables, each request already contains a request.user object with information on the user. You can do a search in the docs for Request and response objects to learn more.
You can use that user object to get the profile variable by extending the user module. Set AUTH_PROFILE_MODULE = 'myapp.UserProfile' in your Settings, which will allow you to access a users profile as follows:
user.get_profile().location.
More about that here:
http://www.b-list.org/weblog/2006/jun/06/django-tips-extending-user-model/

Categories

Resources