I have the django model called "create-chat" and there I write names of people I want to see in a group chat.
So. I created the model, but I don't know how to make a condition whether user is in django_db or no, if so then I want to show them the button "join chat"
And after clicking the button he will be transferred to the url sitename.com/lobby/1
Now I have the view that shows the page /lobby/any_number
First of all I'd to block these pages from users and only if the user is in django_db
He is able to visit the page Lobby/1
ONLY THE lobby/1 not lobby/2
I don't ask you to do it, I just want you to explain me how to do it, or maybe advice me some articles about my problem.
https://i.stack.imgur.com/FQw4Y.jpg
..1). How to block all users for visiting this url sitename.com/1234 <- here goes any number u d liked. ( 4 characters )
So now I blocked all the users for visiting this page, and how now make it visible for a certain users/user?
I am assuming you are storing the information in User object.
usr = User.objects.get(username = whateveristheusername)
if usr is not None:
#User Exist. Click to join chat
else:
#Create User or any other viable functionality
Related
I am hoping someone can help me with something, I am new to Django and am currently putting together a restaurant booking system application. I have a lot of what I want to do done already but what I now want is for all a users bookings to appear in a "My Bookings" page when they are logged into their accounts. I want to give people the option to edit or cancel bookings if needed.
Can anyone guide me in the right direction in terms of making just the users bookings appear when they log in?
Thanks
You can check if the user is authenticated in your view with if request.user.is_authenticated (docs here), then if so you retrieve all of their bookings and display the bookings page to them. If not, you can redirect to the login page for example, or just the home page or whathever.
I have created a Getting Started page to which I have to send the users if they are logging in for the first time after registration.
I also referred to this question but didn't understand anything
If not I have to redirect them to the Home page.
I have set the LOGIN_REDIRECT_URL to 'home' in settings.py
I have not tried anything yet because I have no idea about how I should do it. Please assume a simple html for both the pages with an <h1> tag containing their respective names
There are multiple ways to achieve this, and this are three that I usually do:
you can put additional field in user model, for example seen_getting_started that is boolean and during processing of home template in views.py you can check for this field and redirect accordingly to getting started page. I have an option that user needs to select his language and date formats, so if it not changed and stored in his profile than "select language and date format" page pops out
you could also check his creation time, if it is created in last 10 minutes it is safe to assume that the user is new, but there might be some issues with that if you use for example mail check during registration
if you are using mail check during registration, than you need to lend user on "email confirmed" page that could also lead to your getting started page.
Hope it helps. Sure that other options might work too.
Users that have been assigned to a group with 'add' permissions are able to access, copy, move and add pages created by other users via the admin search or by directly entering the correct path in the browser.
The goal is to prevent users from seeing anything the other users are doing. I had thought it was pretty much implemented.
My page tree looks like this:
Home > Persons > Person Profile > Person Story
Users sign up for an account and are automatically assigned to a custom 'Authors' group. This group has 'add' and 'publish' permissions on the Persons page. The user is responsible for any number of people on their team. With this setup they are able to add a Profile page for each member of their team. Then multiple stories may be added for each person with a profile. Now each Person has subpages of Stories linked to their profile.
I have the page explorer set so users only see their pages:
#hooks.register('construct_explorer_page_queryset')
def show_authors_only_their_articles(parent_page, pages, request):
user_group = request.user.groups.filter(name='Authors').exists()
if user_group:
pages = pages.filter(owner=request.user)
return pages
The image chooser also only displays images uploaded by the user:
#hooks.register('construct_image_chooser_queryset')
def filter_images_by_user(images, request):
images = images.filter(uploaded_by_user=request.user)
return images
And page summary items show only what belongs to the user using similar code.
But during what I thought was going to be final testing, I discovered that a search done using the admin search leads to a list of all available Person Profile and Person Story pages with those search terms. For example if they search for 'John', all Profile and Story page are returned for John. Users may then click on John's Profile page. Once arriving on John's profile page in the explorer they are able to add Stories to John's profile, copy, move or unpublish it! They can do the same with John's stories, minus adding a subpage.
This is a game changer and won't work for us.
I've looked around and see what might be several solutions:
1) Create a similar setup using ModelAdmin but I think I'm going to have the same problem. When searching users will still be able to find and manipulate forbidden content.
2) Create a unique user group for each user as recommended in this post: Wagtail per page user permission
In the second method, after the user is created I would need to programmatically:
1) Create a new user group just for them, maybe using their username.
2) Assign them to the new user group
3) Create a new 'Person' page specific to them and grant them 'add' and 'publish' permissions to it.
The last step because it seems that if I assign them all to the same Person page, they will still be able to add pages to other users Profiles regardless of being in a different user group, since all those different user groups will still have add access to the same Person page.
Ultimately I need to block each user off from what the other users are doing. Your thoughts are much appreciated. It's been years since I've done any programming and I'm still catching up. In the meantime I'm going to start seeing I can come up with.
I think we are pretty close. The system works and flows so well!
I finally figure this one out by searching for instances of GroupPagePermission and GroupCollectionPermission in the Wagtail core package. Was able to piece it together looking at how they did it.
In the models.py of an app I have called 'users' I implemented the django-allauth user_sign_up #receiver. As soon as the user is successfully signed up it runs the below code:
from django.contrib.auth.models import Group, Permission
from django.dispatch import receiver
from allauth.account.signals import user_signed_up
from wagtail.core.models import Page, GroupPagePermission, GroupCollectionPermission, Collection
from article.models import PersonIndexPage
#receiver(user_signed_up)
def create_user_group_and_pages(sender, **kwargs):
"""
When a new user signs up create a unique group and page for them.
Assign it the appropriate permission for admin, page and collection access.
"""
# Grab the new user
user = kwargs['user']
# Create a group object that matches their username
new_group, created = Group.objects.get_or_create(name=user.username)
# Add the new group to the database
user.groups.add(new_group)
# Create new permission to access the wagtail admin
access_admin = Permission.objects.get(codename='access_admin')
# Add the permission to the group
new_group.permissions.add(access_admin)
# Now start creating page access
# First find the homepage
home = Page.objects.get(slug='home').specific
# Create unique PersonIndexPage for the user
person_index_page = PersonIndexPage(title=user.username)
# Add PersonIndexPage to homepage as a child
home.add_child(instance=person_index_page)
# Save new page as first revision
person_index_page.save_revision()
# Create new add GroupPagePermission
GroupPagePermission.objects.create(
group=new_group,
page=person_index_page,
permission_type='add'
)
# Create new GroupCollectionPermission for Profile Images collection
GroupCollectionPermission.objects.create(
group=new_group,
collection=Collection.objects.get(name='Images'),
permission=Permission.objects.get(codename='add_image')
)
Now when a creates a new account a new Index page is created for them that has a unique group created that gives them access to only that Index page and it's child pages. Effectively blocking them from access to any other content on the site. They can still see results to other pages in the admin search but don't have permission to do anything with those results.
Users can log in, create profiles for each person and then as many stories as they want for each person.
I am working with a site which is already connected to single sign on system. Now I want to add terms of agreement page. Here is the flow that I am thinking of:
If I have a record of the user who is logging in that means the user has already seen it so we no longer need to show the agreement page. But if the record doesn't exist in the table I want to redirect to a view that has terms of agreement and user can go further on the sign in process only upon acceptance. If fail to accept we show the non-signed on version of the site.
Since its a single sign on system I have created a table on my end to just keep track of the users who login-to the site. And this is the table I should look up for record.
Here is how I create the record when they sign in:
This is in the my middleware class
shib_umnPersonType = shib_meta.get('uPersonType','')
shib_uRole = shib_umnPersonType.strip().split(';')[0]
#raise(shib_meta)
try:
shib_user = ShibUser.objects.get(shib_username=username)
user = shib_user.auth_user
user.backend = "django.contrib.auth.backends.RemoteUserBackend"
except ObjectDoesNotExist:
user = auth.authenticate(remote_user=username)
user.shibuser_set.create(shib_username=username, shib_user_role=shib_uRole)
What I am thinking at this point is I should interrupt the request in the except: But I am not really sure if thats that the way it should be done. I am also not a experience django developer.
If thats the way to do it then I guess I should be calling a view with a form from that location then check the response ...?
You can do it with view decorator.
If you detect in decorator, that user has not agreed to recent Terms, then redirect it to Terms page with extra parameter passed on to that view. Pick that parameter up in the Terms view and based on that paramter redirect user to previous view if user accepted the Terms.
I have a server which feeds several applications.
Please imagine that I'm a user registered in 2 or more of those applications and I use one different login info when accessing each one.
Now, as that user, I use the same browser with different tabs to access those applications...
Logging the first time (for the 1rst application) everything goes as intended, but when I access the 2nd application (as the second user), that request will access the same request.session object. When I invoke the login (from the auth framework) the current user will be compared with the user in the actual request.session (request.session[SESSION_KEY] != user.id) and request.session.flush() will be called.
This means that I will loose all of the request.session content for the user that accessed the 1st application, and that same user request.session will be "marked" to be the second user request.session from that point.
What I wanted, in this situation, was to have a function/method that permits to create a new request.session for the second user, leaving the original as it is.
Edited after the first answer:
First of all, thank you for the answer.
I was trying not to detail too much in order to avoid too oriented answers, but now I think I should do it:
Ok, I've called "it" applications before, but in truth, my project serves requests in order to offer the same final "product" (a game, for instance).
(I have several django applications inside my project. Each one with specific orientations and backend's depending of business considerations applied.)
It would be more detailed if I told that I have different entry points URL's, use the correct business backend in order to process the request and retrieve a game.
My main URL is the same (namespace) and my project has only one settings file.
There may be several answers to your question depending on whether you are ready to change the "use case" or not:
a) You can't change the use case: it's not possible because one Django session is bound to a browser session be it several browser windows instance or tabs.
b) You can change the use case: The user can still achieve this using several browsers (or profiles (or private browsing mode in chrome/chromium)) without any modification to your code.
c) You can implement an "user"-switch feature in your website that allow user to have several active profile in the same session in different windows, it's similar in purpose to github organization-switch feature or facebook page/organization-switch but you can have several user's profiles in several tabs which is not the case on github or facebook.
To achieve c) you need to have a "SubProfile" model instances attached to your "User" model, and activate the right SubProfile on each incoming request based on query string parameters and persist subprofile information across requests.
1) I guess you already have something like that Subprofile a model with a foreign key to django.contrib.auth.models.User, you may also have a view that allow an user to change its subprofile. In order to make subprofile-switch work, it needs to persist the information in the current tab session which subprofile it is using, for that it needs to add a parameter in the query string because it's the only place bound the tab and not the user-session. For instance "subprofile=123". You need to properly validate the subprofile with a form et al., the view looks like this:
def select_subprofile(request):
if request.method == 'POST':
form = SubProfileSelectForm(request)
if form.is_valid():
subprofile = form.cleaned_data['subprofile']
url = '%s?subprofile' % (reverse('homepage'), subprofile)
return redirect(url) # the redirect is something like '/homepage?subprofile=123'
else:
form = SubProfileSelectForm()
return render(request, 'myapp/subprofile_select.html', {'form':form})
This view can be the first page of each game.
2) After that, you need to retrieve the subprofile of the user for the current tab.
For this matter we will use the query string in a middleware (look for howtos on SO and example middlewares bundled with Django if you don't know what it is) can be used to attach current SubProfile instance to request.user. The middleware will for each incoming request attach the SubProfile instance corresponding to the current subprofile information found in query string to current user object, the middleware looks like this:
class SubProfileMiddleware(object):
def process_request(self, request):
subprofile = request.GET.get('subprofile', None)
if subprofile:
# it's important to check for user here or malicious users will be
# able to use Subprofiles of other users
subprofile = Subprofile.objects.filter(user=request.user, id=subprofile)
# This can also be written
# subprofile = request.user.subprofile_set.filter(id=subprofile)
if not subprofile:
# this is a malicious user
raise Http403
else:
request.user.subprofile = subprofile
else:
# set default subprofile
request.user.subprofile = self.user.default_subprofile
This way you have access in every view of your app to a SubProfile instance on subprofile attribute of request.user. If there is a valid query string subprofile=123 the user will have these subprofile active, if not it's the default subprofile.
Say your application is an application with Organization models each of which instances have walls, on which user's can post message using a subprofile, the function to post a message on a wall has the following signature post_on_organization_wall(subprofile, message, organization), the view that use this function will look like this:
def organization_wall_post(request, organization):
organization = Organization.objects.get_object_or_404(organization)
if request.method == 'POST':
form = MessageForm(request.POST)
if form.is_valid():
post_on_organization_wall(request.user.subprofile, message, organisation)
else:
form = MessageForm()
return render(request, 'organisation/wall_post.html', {'form': form})
3) Now you need to persist subprofile information across requests. Simplest way to do that is replace everycall to {% url %} to your own url template tag which checks for the request query string presence of subprofile key and add it to the requested url. You can reuse the code of Django's url template tag.
If I understand your problem correctly, the issue is that you're sharing sessions between applications even though the users are different. You should be able to solve this by setting either SESSION_COOKIE_DOMAIN, SESSION_COOKIE_PATH, or SESSION_COOKIE_NAME in settings.py to ensure that your applications don't clobber each others sessions.