CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-django-cms

Lean enterprise content management powered by Django.

Pending
Overview
Eval results
Files

permissions.mddocs/

User Management and Permissions

Django CMS provides a comprehensive permission system with granular control over pages, placeholders, and plugins, along with user management utilities that integrate seamlessly with Django's authentication system.

Capabilities

User Management

Create and manage CMS-specific users with appropriate permissions and group assignments.

def create_page_user(
    created_by,
    user,
    can_add_page=True,
    can_view_page=True,
    can_change_page=True,
    can_delete_page=True,
    can_publish_page=True,
    can_add_pageuser=True,
    can_change_pageuser=True,
    can_delete_pageuser=True,
    can_add_pagepermission=True,
    can_change_pagepermission=True,
    can_delete_pagepermission=True,
    grant_all=False
):
    """
    Create a page user for the provided user with specified permissions.
    
    Args:
        created_by (User): The user creating this page user
        user (User): The user to create the page user from
        can_add_page (bool): Permission to add pages
        can_view_page (bool): Permission to view pages
        can_change_page (bool): Permission to change pages
        can_delete_page (bool): Permission to delete pages
        can_publish_page (bool): Permission to publish pages
        can_add_pageuser (bool): Permission to add page users
        can_change_pageuser (bool): Permission to change page users
        can_delete_pageuser (bool): Permission to delete page users
        can_add_pagepermission (bool): Permission to add page permissions
        can_change_pagepermission (bool): Permission to change page permissions
        can_delete_pagepermission (bool): Permission to delete page permissions
        grant_all (bool): Grant all permissions
        
    Returns:
        PageUser: Created page user instance
    """

def assign_user_to_page(
    page,
    user,
    grant_on=ACCESS_PAGE_AND_DESCENDANTS,
    can_add=False,
    can_change=False,
    can_delete=False,
    can_change_advanced_settings=False,
    can_publish=None,
    can_change_permissions=False,
    can_move_page=False,
    can_recover_page=True,
    can_view=False,
    grant_all=False,
    global_permission=False
):
    """
    Assign user permissions to a specific page.
    
    Args:
        page (Page): Target page
        user (User): User to grant permissions
        grant_on (int): Permission scope (ACCESS_PAGE_AND_DESCENDANTS, etc.)
        can_add (bool): Permission to add child pages
        can_change (bool): Permission to edit page
        can_delete (bool): Permission to delete page
        can_change_advanced_settings (bool): Permission to change advanced settings
        can_publish (bool, optional): Permission to publish page
        can_change_permissions (bool): Permission to change page permissions
        can_move_page (bool): Permission to move page
        can_recover_page (bool): Permission to recover deleted page
        can_view (bool): Permission to view page
        grant_all (bool): Grant all permissions
        global_permission (bool): Apply as global permission
        
    Returns:
        PagePermission: Created permission instance
    """

Permission Checking

Comprehensive functions to check user permissions for various CMS operations.

def can_change_page(request):
    """
    Check if current user can change pages.
    
    Args:
        request (HttpRequest): Current request
        
    Returns:
        bool: Permission status
    """

def user_can_add_page(user, site=None):
    """
    Check if user can add pages.
    
    Args:
        user (User): User to check
        site (Site, optional): Target site
        
    Returns:
        bool: Permission granted
    """

def user_can_add_subpage(user, target, site=None):
    """
    Check if user can add subpages to target.
    
    Args:
        user (User): User to check
        target (Page): Parent page
        site (Site, optional): Target site
        
    Returns:
        bool: Permission granted
    """

def user_can_change_page(user, page, site=None):
    """
    Check if user can edit specific page.
    
    Args:
        user (User): User to check
        page (Page): Target page
        site (Site, optional): Target site
        
    Returns:
        bool: Permission granted
    """

def user_can_delete_page(user, page, site=None):
    """
    Check if user can delete specific page.
    
    Args:
        user (User): User to check
        page (Page): Target page  
        site (Site, optional): Target site
        
    Returns:
        bool: Permission granted
    """

def user_can_publish_page(user, page, site=None):
    """
    Check if user can publish specific page.
    
    Args:
        user (User): User to check
        page (Page): Target page
        site (Site, optional): Target site
        
    Returns:
        bool: Permission granted
    """

def user_can_view_page(user, page, site=None):
    """
    Check if user can view specific page.
    
    Args:
        user (User): User to check
        page (Page): Target page
        site (Site, optional): Target site
        
    Returns:
        bool: Permission granted
    """

Thread-Local User Management

Utilities for managing current user context in thread-local storage for permission checking.

def get_current_user():
    """
    Get current user from thread-local storage.
    
    Returns:
        User: Current user or None
    """

def set_current_user(user):
    """
    Set current user in thread-local storage.
    
    Args:
        user (User): User to set as current
    """

def current_user(user):
    """
    Context manager for temporary user switching.
    
    Args:
        user (User): User to temporarily set
        
    Returns:
        ContextManager: Context manager for user scope
    """

Plugin and Advanced Permissions

Permission checking for plugin operations and advanced CMS functionality.

def has_plugin_permission(user, plugin_type, permission_type):
    """
    Check if user has plugin-specific permissions.
    
    Args:
        user (User): User to check
        plugin_type (str): Plugin type identifier
        permission_type (str): Permission type ("add", "change", "delete")
        
    Returns:
        bool: Permission granted
    """

def get_user_permission_level(user, site=None):
    """
    Get user's permission hierarchy level.
    
    Args:
        user (User): User to check
        site (Site, optional): Target site
        
    Returns:
        int: Permission level (0=no access, 1=limited, 2=full)
    """

def get_subordinate_users(user, site=None):
    """
    Get users under current user's management.
    
    Args:
        user (User): Managing user
        site (Site, optional): Target site
        
    Returns:
        QuerySet: Subordinate users
    """

def get_subordinate_groups(user, site=None):
    """
    Get groups under current user's management.
    
    Args:
        user (User): Managing user
        site (Site, optional): Target site
        
    Returns:
        QuerySet: Subordinate groups
    """

Usage Examples

Creating Users and Assigning Permissions

from cms.api import create_page_user, assign_user_to_page, create_page
from cms.models import ACCESS_PAGE_AND_DESCENDANTS

# First create regular Django users
from django.contrib.auth import get_user_model
User = get_user_model()

editor_user = User.objects.create_user(
    username="editor",
    email="editor@example.com",
    password="secure_password"
)

manager_user = User.objects.create_user(
    username="manager", 
    email="manager@example.com",
    password="secure_password"
)

# Create page users from Django users
admin_user = User.objects.filter(is_superuser=True).first()

editor = create_page_user(
    created_by=admin_user,
    user=editor_user,
    can_add_page=True,
    can_change_page=True,
    can_view_page=True
)

manager = create_page_user(
    created_by=admin_user,
    user=manager_user,
    grant_all=True
)

# Create a page hierarchy
home_page = create_page(
    title="Home",
    template="homepage.html",
    language="en"
)

blog_section = create_page(
    title="Blog",
    template="page.html",
    language="en",
    parent=home_page
)

# Grant editor limited permissions on blog section
assign_user_to_page(
    page=blog_section,
    user=editor,
    grant_on=ACCESS_PAGE_AND_DESCENDANTS,
    can_add=True,
    can_change=True,
    can_view=True
)

# Grant manager full permissions on entire site
assign_user_to_page(
    page=home_page,
    user=manager,
    grant_all=True,
    grant_on=ACCESS_PAGE_AND_DESCENDANTS
)

Permission Checking in Views

from django.shortcuts import get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from cms.models import Page
from cms.utils.permissions import (
    user_can_change_page,
    user_can_publish_page,
    user_can_add_subpage
)

@login_required
def edit_page_view(request, page_id):
    page = get_object_or_404(Page, id=page_id)
    
    # Check if user can edit this page
    if not user_can_change_page(request.user, page):
        return redirect('permission_denied')
    
    # Process page editing
    return render(request, 'edit_page.html', {'page': page})

@login_required
def publish_page_view(request, page_id):
    page = get_object_or_404(Page, id=page_id)
    
    # Check publishing permissions
    if not user_can_publish_page(request.user, page):
        return redirect('permission_denied')
    
    # Note: Publishing has been removed from Django CMS core v4+
    # Use djangocms-versioning or similar packages for publishing
    
    return redirect('page_list')

def add_subpage_view(request, parent_id):
    parent_page = get_object_or_404(Page, id=parent_id)
    
    # Check if user can add subpages
    if not user_can_add_subpage(request.user, parent_page):
        return redirect('permission_denied')
    
    # Show add page form
    return render(request, 'add_page.html', {'parent': parent_page})

Thread-Local User Context

from cms.utils.permissions import current_user, get_current_user, set_current_user
from django.contrib.auth import get_user_model

User = get_user_model()

# Set current user for permission context
admin_user = User.objects.get(username='admin')
set_current_user(admin_user)

# Get current user
current = get_current_user()
print(f"Current user: {current.username}")

# Temporarily switch user context
editor_user = User.objects.get(username='editor')

with current_user(editor_user):
    # Operations here run with editor permissions
    current = get_current_user()
    print(f"Temporary user: {current.username}")
    
    # Check permissions as editor
    can_edit = user_can_change_page(current, some_page)

# Back to original user context
current = get_current_user()
print(f"Back to: {current.username}")

Plugin Permission Checking

from cms.utils.permissions import has_plugin_permission

# Check if user can add specific plugin types
can_add_text = has_plugin_permission(request.user, "TextPlugin", "add")
can_add_image = has_plugin_permission(request.user, "PicturePlugin", "add")
can_change_video = has_plugin_permission(request.user, "VideoPlugin", "change")

# Filter available plugins based on permissions
available_plugins = []
for plugin_type in ["TextPlugin", "PicturePlugin", "VideoPlugin"]:
    if has_plugin_permission(request.user, plugin_type, "add"):
        available_plugins.append(plugin_type)

Permission Management in Templates

{% load cms_tags %}

<!-- Check permissions in templates -->
{% if request.user.is_staff %}
    <div class="admin-toolbar">
        {% cms_toolbar %}
        
        <!-- Show edit links only if user can change page -->
        {% if page|can_change_page:request.user %}
            <a href="{% cms_admin_url 'admin:cms_page_change' page.id %}">
                Edit Page
            </a>
        {% endif %}
        
        <!-- Show publish link only if user can publish -->
        {% if page|can_publish_page:request.user %}
            <a href="{% url 'publish_page' page.id %}">
                Publish Page
            </a>
        {% endif %}
    </div>
{% endif %}

<!-- Render model editing only if user has permissions -->
{% if request.user.is_staff %}
    {% render_model article "title" %}
{% else %}
    <h1>{{ article.title }}</h1>
{% endif %}

Types

class PageUser:
    """
    CMS-specific user model extending Django's User.
    
    Attributes:
        language: User interface language preference
        created_by: User who created this account
        can_add_page: Global page addition permission
        can_change_page: Global page change permission
        can_delete_page: Global page deletion permission
    """

class PagePermission:
    """
    Page-specific user permissions.
    
    Attributes:
        user: Associated user
        group: Associated group (alternative to user)
        page: Target page
        grant_on: Permission scope (page only vs descendants)
        can_add: Can add child pages
        can_change: Can edit page content
        can_delete: Can delete page
        can_publish: Can publish page changes
        can_move: Can move page in tree
        can_view: Can view page (for restricted content)
    """

class GlobalPagePermission:
    """
    Site-wide user permissions.
    
    Attributes:
        user: Associated user
        group: Associated group
        can_add: Global page addition permission
        can_change: Global page change permission  
        can_delete: Global page deletion permission
        can_publish: Global page publishing permission
        can_move: Global page moving permission
        can_view: Global page viewing permission
        sites: Sites where permissions apply
    """

class PageUserGroup:
    """
    CMS-specific user groups.
    
    Attributes:
        name: Group name
        created_by: User who created group
        users: Group members
    """

# Permission constants
ACCESS_PAGE_AND_DESCENDANTS: int  # Apply permissions to page and all descendants
ACCESS_PAGE: int  # Apply permissions to page only
ACCESS_DESCENDANTS: int  # Apply permissions to descendants only

Install with Tessl CLI

npx tessl i tessl/pypi-django-cms

docs

index.md

menus.md

pages.md

permissions.md

plugins.md

templates.md

utilities.md

tile.json