Wagtail how to filter pages a user has view access to via their groups - wagtail

I am implementing a search function that returns pages the user has access to via their groups. Pages have these settings set via the Wagtail admin page privacy settings when editing.
For example, a page could only be visible to users in the Editors group. So when a user NOT in the Editors group searches for this page it should be filtered out.
How would one efficiently filter pages not accessible by the user this way? I could not find any clear way to do this.

To answer my own question for search engine optimization purposes.
After studying the Wagtail source code I discovered Wagtail uses a PageViewRestriction model internally.
I ended up using this snippet to solve my issue:
from wagtail.core.models import Page, PageViewRestriction
def filter_pages(user):
pages = Page.objects.live()
# Unauthenticated users can only see public pages
if not user.is_authenticated:
pages = pages.public()
# Superusers can implicitly view all pages. No further filtering required
elif not user.is_superuser:
# Get all page ids where the user's groups do NOT have access to
disallowed_ids = PageViewRestriction.objects.exclude(groups__id=user.groups.all()).values_list("page", flat=True)
# Exclude all pages with disallowed ids
pages = pages.exclude(id__in=disallowed_ids)
return pages

Related

Wagtail admin page for different clients

We are in the process of making a UberEat like app and will be using Django for the backend. I discovered wagtail not so long ago and was wondering if it would be possible to use it for our vendors, with each vendor having the possibility to log into Wagtail admin and having access to his/her own products, category, prices, etc. Rephrased, is there a possibility to have different admins in Wagtail that would have access to their own model instances ?
Thanks to you all
With Wagtail’s page permissions you could solve that via a "parent" page in combination with a custom "group" for each vendor. A clumsy workaround to be honest, it would require 3 steps, which could be automated. But this way you could use the full-featured Wagtail CMS in a way, in which each vendor could only see their "own" pages.
You could manage images and documents in the same way by assigning collections to vendors as well. But let’s start with the pages here.
The slug would look something like ubereatlike.app/vendorxyz/... with vendorxyz/ representing this "parent" page.
Groups can be added via the SETTINGS in the sidebar. Groups are a native part of the Django framework, see documentation. To add a new vendor, you would have to do three steps. (1) Create a parent page for this vendor. (2) Create a group for this vendor via SETTINGS --> GROUPS. Here you should check "Can access admin" and create a "native" new page permisson for the vendor’s page with all necessary permissions, like "Add", "Edit" and "Publish", for example. (3) Lastly you would have to add a new User for the vendor and choose its group as role.
To automate this I would create a custom user model, see documentation. With a post_signal for this custom user model, I would create both the parent page and the group and its permissions. This way you would add the User only and the page and the group would be generated programmatically.
# startapp vendors with models.py
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.models import Group, Permission
from django.dispatch import receiver
from wagtail.models import Page
from home.models import HomePage
class VendorPage(Page):
parent_page_types = ['home.HomePage']
...
class Vendor(AbstractUser):
company_name = models.CharField(max_length=255)
# ...other fields
#receiver(models.signals.post_save, sender=Vendor)
def vendor_created(sender, instance, created, **kwargs):
if created:
# create vendor page as child of home page
home_page = HomePage.objects.first()
vendor_page = VendorPage(title=instance.company_name)
home_page.add_child(instance=vendor_page)
vendor_page.save_revision().publish() # recommended
# create group with permissions
vendor_group = Group.objects.create(...)
permission = Permisson.objects.get(...) # please look into Wagtail’s page permissons, this is just a rough draft
vendor_group.permissions.add(permission)

Normal user (not admin) registration and publishing in Wagtail

I understand Wagtail is a CMS. Per my test so far, only the admin has permission to publish an article/content. I checked out "puput" and a few others as listed here. I wonder is there a way to allow normal user registration, login, publishing? Something similar to Medium, where the normal user, or say the community, can contribute to the content generation.
I thought there might be a toggle or switch to enable this. But I didn't find it. I'm looking for a way that is either a package or a plugin or similar. Not coding from scratch. Ideally within Wagtail CMS, but other frameworks based on Django should also be fine.
Thanks.
Wagtail provides two user groups:
Editors: user within this group can create page and submit it to moderation
Moderators: user within this group can publish pages that have been submitted to moderation.
To update groups for a given user, go the the django admin interface with admin credentails, usually the url is your-domain/admin
Then go to Users under Authentication and Authorization category
Then get into the user you want to allow posting pages,
Scroll down until Permissions category and moove groups Editors and Moderators from Available groups to Chosen groups as follow:
Then save new settings.

Create a post on facebook on users behalf using new Sharing Products feature

My scenario:
I have an application within which users keep their own journals. For some of the journal records, i want to enable them to post to their facebook timeline.
It was rather straightforward with an old api (obtaining token and posting) but with a new Sharing Product, it seems impossible because its intended to use ograph data and backlink from facebook post to the page within the app but since the journal post itself is for logged user only, i don't see a way how could it work.
So, the question is:
How to enable users to share (actually, "replicate" is more accurate word) content from their authorization protected area within my application to their facebook timeline?
PS.
I am aware of solutions like: Auto post (user behalf) on facebook but that's an old api.
You can not create new content like this any more in any automated way, you can only let your users share links.
But you can point the Share button to any URL you like (parameter href), it does not have to be that of the current page.
Facebook will follow whatever you have set as og:url or canonical, so that would have to be the version without authorization then.
That would also be the URL that users clicking on the link in that post would be redirected to.

How to show selective UI features?

I have a UI that needs to either show icons on a timeline view or not based on user profile. How can I show for some users and not for others? For example : the Sports Admin team needs to see the scores of all teams over time in the view (showing all years visually) but the players (when they login to the same web app) only see the timeline view with their team's performance over the years (not other details for a particular year). How can I achieve this? I am using Angular JS and javascript
I have looked into role based SSO login and show selectively and also cookies. My goal is faster performance - meaning the page needs to load fast.
I was able to find a solution for the problem above that we have been facing. After many design sessions, the best approach was to have a "User Settings" link that would save the preferences at a backend database per user id that's already captured via SSO login. The backend returns data based on the user settings as the queries to get data from backend are now made dynamic to take the selections from User Settings into account while querying the backend. As a result the front end shows data specific to user.
Tested this and seems to work perfectly without any affecting any page load performance whatsoever.

how to use wagtail admin page edit interface by normal user

I'm planning to create a website, and the pages contents will be created by both Admin and normal(logged in) users.
Is wagtail admin page supposed to be only for the admin users to create page contents ?
Is it a bad idea to give normal users the admin access with limited permissions to allow them to create their page contents?
If it is a bad idea, is it still possible to use the awesome admin page editor interface for the normal user?
I'm wondering how other people handles the page creation by the normal users in wagtail..
It depends how you're defining "admin user". By the most literal definition, as soon as you give a user access to the Wagtail admin, they're an admin user...
Wagtail is designed to support multiple user roles - through features like the permission system and the "submit for moderation" option, so that you can give people access to edit pages without giving them total control over the site. For example, the Royal College of Art - the site that Wagtail was originally built for - gives students limited-permission accounts on Wagtail so that they can create and submit pages about their work in the RCA Now section, without giving them edit access to the rest of the site.
If you want to give normal user to wagatil admin access than you have to give below permission as mentioned in photo.
You can see this in
wagtail admin > settings > groups > other permissions > check "can access wagtail admin"
And might be clear that you have'nt given Admin Access Role.

Resources