Using the django admin's site authentication in a non-admin view - django

I am writing a simple django app to manage pages on a website.
The pages are created through the admin site and can be previewed using the 'view on site' function.
Each page has a 'published' boolean that determines whether the view that displays pages should show it on site.
Of course, once I change the view to respect 'published' the admin page's 'view on site' link will not show the page either.
But I want to be able to preview unpublished pages during the editing process.
So I decided to change the view to check whether there is an authenticated user associated with the request.
For example:
if request.user.is_authenticated() and request.user.is_staff:
manager=Pages.objects #returns all pages
else:
manager=Pages.live #only returns published pages
Then the appropriate manager is passed to get_object_or_404 along with the page_id captured from the URL
However, in the view, user is always Anonymous even when a user who is authenticated with the admin site clicks the 'view on site' link.
So the 'live' manager always gets used and I have the same result as before: 404 when unpublished pages are accessed from the admin site.
Is this the way its supposed to behave?
I really thought the session information would be inherited from the admin site's session.
I would appreciate any direction here because I may not be too clear on how this should work.
I don't need a login mechanism for the site so I was hoping to piggyback off the admin's login to get the ability to view unpublished pages in the admin.
Thanks

The problem is gone.
Now, if I am logged into admin I can view unpublished pages otherwise I get a 404 error.
Unfortunately, I'm not sure why it started working.
I ran some package updates (neither django nor Firefox was among them) and had to restart my (archlinux) machine.
When I restarted the django develpment server and tested the function again, all was well.
I suspect Firefox was the culprit but that's only a guess.
Anyway, thanks to anyone who gave the issue some thought.
I can stop pulling my hair out now.

Related

Oracle-Apex: Dynamically redirecting from login button

The scenario
I have implemented social authentication similarly to described by Dimitri Gielisin hist post "Facebook, Google and Custom Authentication in the same Oracle APEX 18.1 app" (http://dgielis.blogspot.com/2018/06/facebook-google-and-custom.html)
The pertinent point is that there is a button which has the request 'APEX_AUTHENICATION=FACEBOOK' which logs the user in and also hard codes the page that the user is taken to.
It works great. (However if I have a login menu item which directs back to the same page - the user name isn't updated on the page.)
The Issue
Default behaviour is for apex to redirect users to the login page when they attempt to access a page which is not publicly available.  After logging in the user is taken to the page hard coded page in the button (except for modal dialogues which just produce an invalid session error). 
I'd love it if they could sign in and then continue to the page they need to go to. Is there some not extremely cumbersome ways of doing that? I thought of trying to saving the page number I want the user to go to into an application item and then having the button redirecting based on the application item- but while I was saving the page number the dynamic redirect in the button is not working...and I feel like I'm fighting the apex framework...
Is there a better way? If not can a button reference an item for the page number? I was trying &APP_ITEM. but that didn't seem to work...
(I"m using Apex 20.1)

Django admin/frontend authentication issue

I am developing an application using Django 1.4. When I log into admin site in another tab in the browser, the application interface in which I am already logged in automatically logs out. Please help me in solving this issue. The browser I am using is Firefox. Thanks in advance.
Admin is also a user in django. So, you can't have more than one user logged in at the same time in the same browser, can you? Try the same scenario on facebook. This is what it is. You re fine, there's no problem.
On the side note, if you are just getting started with your project use Django 1.5.
Well you cannot log into the same website with different login ids simultaneously until and unless you dont use some plugins for this feature or you are opening different ids in the incognito window.
Since admin is a superuser(still a user), hence you cannot open a multiple django accounts in the same browser. One account will be logged out in order to open the other one. This is no issue. Happy coding.
The Django admin site is just another page of your Django main website. Say if you have foo.com, then foo.com/admin/ shows you the admin portal.
And we already know that two users cannot be simultaneously logged in to the same website from the same browser.
So, you can test on your foo.com site, being an admin user itself. Experience on the Django website for any user will be same, it doesn't change with user being a staff member or superuser. Only admin site has different permissions based on these factors.
In this case, you'll be able to use both the main site, as well as admin portal.
But if you really want to use different user accounts for admin site and main site, then you should either use different browsers or Private window in Firefox.

How to restrict users from going back to the previous page with the browser "back button" (redirect to a different page, instead)?

I am working on a site that would allow users to post some data. To successfully add a new post, the users need to go through three states: Form -> Preview -> Posted page. I want to restrict the users from going back to the Preview page with the browser "back button" once they have already reached the Posted page (instead, they should be redirected to the empty Form page). How can I implement this behaviour in Django?
I am not sure how you get this desired behavior from Django as you have limited control over the user's browser. However, in Javascript you can use:
window.location.replace(url);
which will remove history, thus preventing the back button from working.
See this stack overflow question about window location:
What's the difference between window.location= and window.location.replace()?
An idea: from your preview page, use AJAX to submit and if all is successful, window.location.replace to your posted page.
I can't speak for how to deal with this using browser technologies but with django you could just set a flag in the session.
# posted_page view
request.session['posted_page_visited'] = True
# preview_page view
if request.session.get('posted_page_visited'):
del request.session['posted_page_visited']
return http.HttpResponseRedirect("form_page")
Using js (window.location.replace(url)) doesn't fulfill this requirement because "replace url" will just replace the page with another one,Ex: if form flow goes from page1 to page2 then page3 then page4 and (window.location.replace(url)) is used in page2 (window.location.replace(page4);) then page3 will never be visited!! moreover user will still be able to go back in the same forward path meaning from page4 to page2...etc
the good thing, you can solve it by using Django session as shown below assuming users will be able to go back and forth as long as form not yet saved, and once its saved they can't go back anymore:
in page1/view function where first part of form is issued create session varaible:
in view1.py
def view1(request)
.
.
.
request.session['forward'] = True
return redirect(....)
in view2.py:
def view2(request):
if not request.session['forward']:
return redirect(..Select whatever page you want to redirect users to it..)
the same in rest of pages views..
in the last page/view where after saving the form, reset the variable:
request.session['forward'] = False
return redirect(..Select whatever page you want to redirect users to it..)
hopes its clear enough
django's form wizard should do what you want:
How it works
Here’s the basic workflow for how a user would use a wizard:
The user visits the first page of the wizard, fills in the form and submits it.
The server validates the data. If it’s invalid, the form is displayed again, with error messages. If it’s valid, the server saves
the current state of the wizard in the backend and redirects to the
next step.
Step 1 and 2 repeat, for every subsequent form in the wizard.
Once the user has submitted all the forms and all the data has been validated, the wizard processes the data – saving it to the
database, sending an email, or whatever the application needs to do.

Django user authentication: not redirecting after login

My website has a front page that has a link to a forum. Access to the forum requires that the user be logged in. I have therefore given the view show_forum the decorator: #login_required. When the user clicks the forum link, they are correctly redirected to the login page. Once the user has logged in they are, however, taken back to the front page, not to the forum page. If the user now (being logged in) clicks the forum link then he is taken directly to the forum page.
Via Firebug, I can see that the url is getting the correct 'next' parameter. Any hints or things that I should look for?
My most common issue with the login_required decorator is that I forget to redirect to the next parameter while having a custom login view in place. In other words, the page gets built up in segments, and after a while the login feature gets added. By default, this view redirects to a default index page (what you probably equals to your "front page").
What this boils down to is: do you have something like the following in your /accounts/login/ view?
return HttpResponseRedirect(request.GET.get('next', settings.LOGIN_REDIRECT_URL))

How do I best implement admin-only pages and admin-specific views on a primary read-only Django website?

I’m writing a Django website. It’s pretty much a read-only site, except for the administrator, who performs some update actions on it. I’d like the administrator to edit the site via its front end.
To support this, some URLs are displayed differently for the administrator, and some URLs should return 404 unless the request comes from the logged-in administrator.
I’d rather not make the existence of the administrator user particularly obvious to anonymous users, hence the 404s for admin-only pages if the user isn’t already logged in as the administrator.
My design for this at the moment is:
At the server level, have two hostnames as aliases for the same single Django site:
admin.example.com
www.example.com
At the Django app level, for every view that’s admin-only or is displayed differently for the administrator, check whether the request’s hostname is the admin one. If it is:
if the request comes from the logged-in administrator, return the page with the administrator-specific display
otherwise, return 404
Have a URL that the administrator can go to manually to log in.
Is this dumb? Am I missing a simpler/better way to do this?
At the simplest level you can use the user_passes_test decorator on your admin-specific views:
#user_passes_test(lambda u: u.is_superuser)
def only_admins_here(request):
#do stuff
Or you can simply branch in the view:
def some_view(request):
if request.user.is_superuser:
render_to_response('admin_template.html')
else:
render_to_response('template.html')
Creating a whole subdomain layer over this is going to get highly complicated quickly, since not all classes and functions in Django necessarily have access to the request object, and thus, which domain the request is coming from.
You can remove point one.
At the Django app level, for every view that’s admin-only or is displayed differently for the administrator, check whether the request comes from the logged-in administrator.
if the request comes from the logged-in administrator, return the page with the administrator-specific display
otherwise, return 404
Have a URL that the administrator can go to manually to log in.