Wagtail admin page for different clients - wagtail

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)

Related

Publish and "Save Drafts" feature in Django

I am working on a Django Rest Framework B2B application with a React Frontend. The data is fed from a csv and then Analytics dashboards are rendered in React. Each Account ("User") is a company - and within a company, the app is used by the entire marketing team (say). Each company account has data unique to that co. and dashboard preferences unique to that company. An administrator is a human user who is some Manager / employee of a company (let's say, for example, Boeing, Nike etc) who has edit / administrator rights on behalf of the company. That "admin" makes some changes to the dashboard preferences and wants to "Publish" the changes so that rest of the employees (the rest of the Marketing team) of the company Account can view the updated dashboard. But maybe not yet, hence a "Save Drafts" feature.
I'm not sure how to get these two features in the most industry-standard way in Django (DRF) - When I hit "Publish", the entire marketing team should be able to see the changes. (It's a B2B app). But when I save drafts, I should be able to view the changes (as admin) but not the rest of the marketing team. I'd be grateful for any help. Thank you!
You can use a choices field to manage the status of a a model (Dashboard in your case)
Example code follow
models.py
class Dasboard(models.Model):
STATUS_CHOICES = (('draft', 'Save Draft'), ('published', 'Published'))
status = models.Charfield(max_length=20, choices=STATUS_CHOICES)
# Others models fields
views.py
def dashboard(request):
objects = None
if request.user.is_admin:
# The admin users can see draft and saved (all Dashboard objects)
objects = Dashboard.objects.all()
else:
# Others users are seeing only published
objects = Dashboard.objects.filter(status='published')
return render(request, 'app_name/dashboard.html', {'objects': objects})
NB : Here i used only Django filter features to retrives some data according to the type of users.
But you can also use Django permissions too for more advanced handling.

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.

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

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

MVC2 Authorize Roles from SQL

I have a table in my SQL2008 DB for Users and one for Roles and then the UserRoles bridging table. I am at the point where I have to RoleProvider to work and have decorated some of my Actions with [Authorize(Roles = "Administrator,Developer")]
I actually build the navigation on my site per user so the RoleProvider is just to prevent a lower level user from getting the URL from his Admin buddy and going to a page that he is not supposed to.
We build the site navigation on a per user base and have a mapping between the user, his role and the pages that the role he is in is allowed to see. I just want to know if there is any way to change the [Authorize(Roles = "")] to get the list of roles with permission to that action dynamically from my database? That way I do not have to go decorate all actions that I have, it will just be pulled from the DB as if by magic.
A simple example will be appreciated, thank you.
Jack
I basically wrote my own CustomAuthorize class that inherits from AuthorizeAttribute and in the OnAuthorization I did the look-up for access. If the user does not have access I basically do:
filterContext.Result = new HttpUnauthorizedResult();
filterContext.Result = new RedirectResult("/accessDenied");
Works, and I decorate my methods with: [CustomAuthorize]

CakePHP ACL use case(s)

I have got a simple web app in development, i want to establish a couple of user groups; Admin, Doctors & Patients.
Each group would have their access restricted to particular controller actions rather than individual content. So for example, Doctors can view patient records (index & view actions), but cannot delete them.
Usually i would create a groups model, and assign the various users to a group. And filter in the beforeFilter() method to determine if the user has access. But if ACL can do the job, why right the code, right?
Thanks
You do not need to filter in the beforeFilter() method to determine if the user has access but you need to provide configuration to Auth component there. Follow Simple Acl controlled Application from tutorial (Setting up permissions).

Resources