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

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.

Related

Redirection in django and passing arguments

I spent some time reading through the documentation and forums, but not sure I understand this. I have this bit of code in the views of my app:
def billboard_index(request):
if request.method == 'POST':
form = SpotiForm(request.POST)
if form.is_valid():
date = form.cleaned_data['spotiread_date']
try:
url = 'https://www.billboard.com/charts/hot-100/' + date
billboard = requests.get(url)
billboard.raise_for_status()
except:
print("No response")
else:
soup = BeautifulSoup(billboard.text, 'html.parser')
positions = [int(i.text) for i in soup.find_all(name='span', class_='chart-element__rank__number')]
songs = [i.text for i in soup.find_all(name='span', class_='chart-element__information__song')]
artists = [i.text for i in soup.find_all(name='span', class_='chart-element__information__artist')]
top100 = list(zip(positions, songs, artists))
if Top100model.objects.exists():
Top100model.objects.all().delete()
for position in top100:
top100data = Top100model(
idtop=str(position[0]), artist=str(position[2]), song=str(position[1])
)
top100data.save()
params = {
'client_id': SPOTIPY_CLIENT_ID,
'response_type': 'code',
'redirect_uri': request.build_absolute_uri(reverse('spotiauth')),
'scope': 'playlist-modify-private'
}
query_string = urlencode(params)
url = '{}?{}'.format('https://accounts.spotify.com/authorize', query_string)
return redirect(to=url)
# if a GET (or any other method) we'll create a blank form
else:
form = SpotiForm()
return render(request, 'billboardapp.html', {'form': form})
on billboard_index I have a form with one field in which user puts a date. This date is then used as an input for a webscraper. I save the scraped data in the database, this works (I know this code will break in couple instances, but I'll deal with this later). Next I want to follow the spotify authorization flow, so I redirect to a url at spotify/authorization, it works. This gives me the code back when I'm redirected to spotiauth.html. At the same time, I print there all the database entries that were added during scraping. This is the spotiauth view:
def spotiauth(request):
Positions100 = Top100model.objects.all()
print(request)
context = {
'positions': Positions100,
}
return render(request, 'spotiauth.html', context=context)
I have couple questions:
How do I pass additional arguments to the spotiauth view? I tried
return redirect(to=url, date=date)
But I can't access it in spotiauth view. So I don't really want to pass it in the url, I just want it as an argument to another function, is this doable?
Is this the actual way to go about it? Not sure this is the simplest thing to do.
Thank you for your help!
Authentication is something that should be handled in a generic way, and not individually and explicitly per request. This is because you don't want to duplicate the authentication code in every request that needs authentication.
Lucky you, you are using Django which already comes with an authentication and authorization layer, and a great community that creates great libraries such as django-allauth that integrate OAuth2 authentication into Django's authentication layer.
OAuth2 against Spotify is what you are trying to implement here. Just
include django-allauth via pip,
configure the Spotify provider in the settings following their documentation,
include their URLs for login and registration (see their docs)
... and you should be able to sign into your app using a Spotify account.
For your regular views then, the decorator login_required would then suffice.
Django-allauth will do the following:
for users who sign in via OAuth2 providers, regular Django accounts will be created automatically
you can see these users in the Django admin, in the same list as the regular Django users
you can manage the configuration of the OAuth2 provider configuration via the Django Admin - django-allauth brings a model with an admin for it
django-allauth brings additional functionality like email verification, multiple email address management etc.
If you want to style the login and registration pages, you can implement your own templates using django-allauth's templates as basis.

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 website : make the url adress unchangeable

I would like to get your advices in order to block the url modification by my clients.
For example, I have a client in my website and he will redirect to his own page after the log process.
His homepage url looks like : http://localhost:8000/Compagny/id/ with id corresponding to the Compagny1.
For example : http://localhost:8000/Compagny/1/ with 1 is the first Compagny
But, in the url bar, if my client writes : http://localhost:8000/Compagny/2/ he will be redirected to Compagny2's homepage and I don't want this possibility.
My question is :
How I can implement some rules, functions, or anything else in order to set unchangeable the url adress ? Client couldn't change the url and see the homepage which make reference to another client ?
Thank you
EDIT :
This is my homepage view :
#login_required
def HomePage_Compagny(request, id) :
compagny = get_object_or_404(Compagny, pk=id)
intervention = CompagnyIntervention.objects.filter(Compagny__id=id).all()
pointsajoutes = CompagnyAjout.objects.filter(Compagny__id=id).all()
coefficient = CoefficientIntervention.objects.last()
if request.method == 'POST':
form_ajout = ContratAjoutFormulaire(request.POST or None)
if form_ajout.is_valid() :
#Several processes
return HttpResponseRedirect('http://mywebsite/'+id)
else:
form_ajout = ContratAjoutFormulaire()
context = {
...
}
return render(request, 'CompagnyHomePage.html', context)
My url for this part is : url(r'^Compagny/(?P<id>\d+)/$', views.Homepage_Compagny, name="Homepage"),
You can't prevent the user from typing a url in their browser. Instead, you should restrict access in the view, and return 404 if the user is not allowed to access that company.
For example, if the Compagny has a foreign key to User, then you could do:
#login_required
def HomePage_Compagny(request, id) :
compagny = get_object_or_404(Compagny, pk=id, user=request.user)
...
In your views.py file where you wrote the function for the page you should use user=request.user with this given you can apply multiple methods to block users from specific sites.
use the if user.is_authenticated(): method in views.
give users a group and deny access to specific pages
check in the template if the current user is allowed to see the site
If a user visits a url you can redirect him to the main page or display a 404 or tell him that he does not have access rights for this site.
For Example in the template you can display an error message like:
{% if request.user == pageowner %}
the site code
{%else%}
<h1>This is not your Site. Please Go back</h1>
{%endif%}
in the views.py function you would have to define a "pageowner" attribute where you define a user who "owns" or at least created that Page.

User authentication to specific users

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

Django user impersonation by admin

I have a Django app. When logged in as an admin user, I want to be able to pass a secret parameter in the URL and have the whole site behave as if I were another user.
Let's say I have the URL /my-profile/ which shows the currently logged in user's profile. I want to be able to do something like /my-profile/?__user_id=123 and have the underlying view believe that I am actually the user with ID 123 (thus render that user's profile).
Why do I want that?
Simply because it's much easier to reproduce certain bugs that only appear in a single user's account.
My questions:
What would be the easiest way to implement something like this?
Is there any security concern I should have in mind when doing this? Note that I (obviously) only want to have this feature for admin users, and our admin users have full access to the source code, database, etc. anyway, so it's not really a "backdoor"; it just makes it easier to access a user's account.
I don't have enough reputation to edit or reply yet (I think), but I found that although ionaut's solution worked in simple cases, a more robust solution for me was to use a session variable. That way, even AJAX requests are served correctly without modifying the request URL to include a GET impersonation parameter.
class ImpersonateMiddleware(object):
def process_request(self, request):
if request.user.is_superuser and "__impersonate" in request.GET:
request.session['impersonate_id'] = int(request.GET["__impersonate"])
elif "__unimpersonate" in request.GET:
del request.session['impersonate_id']
if request.user.is_superuser and 'impersonate_id' in request.session:
request.user = User.objects.get(id=request.session['impersonate_id'])
Usage:
log in: http://localhost/?__impersonate=[USERID]
log out (back to admin): http://localhost/?__unimpersonate=True
It looks like quite a few other people have had this problem and have written re-usable apps to do this and at least some are listed on the django packages page for user switching. The most active at time of writing appear to be:
django-hijack puts a "hijack" button in the user list in the admin, along with a bit at the top of page for while you've hijacked an account.
impostor means you can login with username "me as other" and your own password
django-impersonate sets up URLs to start impersonating a user, stop, search etc
I solved this with a simple middleware. It also handles redirects (that is, the GET parameter is preserved during a redirect). Here it is:
class ImpersonateMiddleware(object):
def process_request(self, request):
if request.user.is_superuser and "__impersonate" in request.GET:
request.user = models.User.objects.get(id=int(request.GET["__impersonate"]))
def process_response(self, request, response):
if request.user.is_superuser and "__impersonate" in request.GET:
if isinstance(response, http.HttpResponseRedirect):
location = response["Location"]
if "?" in location:
location += "&"
else:
location += "?"
location += "__impersonate=%s" % request.GET["__impersonate"]
response["Location"] = location
return response
#Charles Offenbacher's answer is great for impersonating users who are not being authenticated via tokens. However, it will not work with clients side apps that use token authentication. To get user impersonation to work with apps using tokens, one has to directly set the HTTP_AUTHORIZATION header in the Impersonate Middleware. My answer basically plagiarizes Charles's answer and adds lines for manually setting said header.
class ImpersonateMiddleware(object):
def process_request(self, request):
if request.user.is_superuser and "__impersonate" in request.GET:
request.session['impersonate_id'] = int(request.GET["__impersonate"])
elif "__unimpersonate" in request.GET:
del request.session['impersonate_id']
if request.user.is_superuser and 'impersonate_id' in request.session:
request.user = User.objects.get(id=request.session['impersonate_id'])
# retrieve user's token
token = Token.objects.get(user=request.user)
# manually set authorization header to user's token as it will be set to that of the admin's (assuming the admin has one, of course)
request.META['HTTP_AUTHORIZATION'] = 'Token {0}'.format(token.key)
i don't see how that is a security hole any more than using su - someuser as root on a a unix machine. root or an django-admin with root/admin access to the database can fake anything if he/she wants to. the risk is only in the django-admin account being cracked at which point the cracker could hide tracks by becoming another user and then faking actions as the user.
yes, it may be called a backdoor, but as ibz says, admins have access to the database anyways. being able to make changes to the database in that light is also a backdoor.
Set up so you have two different host names to the same server. If you are doing it locally, you can connect with 127.0.0.1, or localhost, for example. Your browser will see this as three different sites, and you can be logged in with different users. The same works for your site.
So in addition to www.mysite.com you can set up test.mysite.com, and log in with the user there. I often set up sites (with Plone) so I have both www.mysite.com and admin.mysite.com, and only allow access to the admin pages from there, meaning I can log in to the normal site with the username that has the problems.

Categories

Resources