Skip to main content

django-pucas

Build status Code Coverage CodeFactor PyPI - Python Version PyPI - Django Version

django-pucas is a reusable Django application to simplify logging into a Django application with CAS using django-cas-ng. Login and creation of user accounts is handled by django-cas-ng; pucas adds support for prepopulating user account data based on an LDAP search.

pucas should be pronounced like pookas for the Celtic spirit creature.

django-pucas is tested against:

  • Django 3.2-4.2
  • Python 3.10-3.14

django-pucas requires django-cas-ng 3.6 or greater.

Installation

Use pip to install:

pip install pucas

You can also install from Github. Use @main or @0.11 to install a specific branch or tagged release:

pip install git+https://github.com/Princeton-CDH/django-pucas.git@main#egg=pucas

Configuration

Add both django-cas-ng and pucas to installed apps; enable authentication middleware and django-cas-ng authentication backend:

INSTALLED_APPS = (
    ...
    'django_cas_ng',
    'pucas',
    ...
)

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    ...
)

AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend',
    'django_cas_ng.backends.CASBackend',
)

Include the default django-cas-ng login and logout urls provided with pucas, or configure them as needed based on the documentation:

urlpatterns = [
    ...
    path('accounts/', include('pucas.cas_urls')),
    ...
]

Add required configurations to settings.py:

  • CAS_SERVER_URL - Base URL of your CAS source

  • Configure LDAP settings as needed to populate user attributes:

PUCAS_LDAP = {
    'SERVERS': ['ldap1', 'ldap2'],
    'SEARCH_BASE': 'ou=users,dc=example,dc=com',
    'SEARCH_FILTER': "(uid=%(user)s)",
    # attributes to request from the LDAP server
    'ATTRIBUTES': ['givenName', 'sn', 'mail'],
    # mapping of User attributes to LDAP attributes
    # if passed list for the value, the first attribute to return a
    # value will be used
    'ATTRIBUTE_MAP': {
        'first_name': 'givenName',
        'last_name': 'sn',
        'email': ['mail', 'eduPersonPrincipalName']
    },
    # Optional local method to do additional user initialization
    # not handled by attribute map.  Method should take a user
    # object and ldap search result.
    'EXTRA_USER_INIT': 'myproj.myapp.models.init_profile_from_ldap'
    'BIND_DN': 'uid=username,o=your org,c=country_code',
    'BIND_PASSWORD': 'secreupasswordforyourldap',
}
  • Note: BIND_DN and BIND_PASSWORD are optional if you want to bind anonymously. Add them if they are required by your LDAP. This supports user/pass authentication.

Run migrations to create database tables required by django-cas-ng:

python manage.py migrate

To make CAS login available on the Django admin login form, extend the default admin login form and include or adapt the provided CAS login template snippet. An example admin login form is included at pucas/templates/pucas/sample-admin-login.html; copy this to admin/login.html within a valid template directory and modify as needed.

An example of a login template with local branding is provided at pucas/templates/pucas/sample-pu-login.html using re-usable template snippets that can be adapted or re-used as appropriate.

Usage

Users can login with CAS and have a Django user account automatically created and populated with LDAP data based on the settings.

Two manage commands are provided, for convenience.

  • Use python manage.py ldapsearch netid1 netid2 netid3 for testing your LDAP configuration and attributes.
  • Use python manage.py createcasuser netid1 netid2 netid3 to initialize one or more CAS accounts and populate data from LDAP without requiring the user to login first, as an aid to managing accounts and permissions. The optional flag --admin will give the new account superuser permissions (bypasses all permission checks); --staff will give staff permissions, which allow the account to log into the Django admin, but requires additional permissions to be assigned separately.

Admin interface for CAS user initialization

Register CasUserAdmin with your User model to add an Add CAS Users button to the user changelist in the Django admin. The form accepts one or more netids at a time.

from django.contrib import admin
from django.contrib.auth import get_user_model
from pucas.admin import CasUserAdmin

admin.site.register(get_user_model(), CasUserAdmin)

To use it alongside a custom UserAdmin, subclass CasUserAdmin:

from pucas.admin import CasUserAdmin

class MyUserAdmin(CasUserAdmin):
    pass

CasUserAdmin uses a custom changelist template (admin/pucas/user_change_list.html) to add the Add CAS Users button. If you are already customizing the changelist template in your project, extend CasUserAdmin's template instead of admin/change_list.html directly.

Make sure pucas is in INSTALLED_APPS so Django's app template loader can find the templates:

INSTALLED_APPS = [
    ...
    "pucas",
]

Development instructions

This git repository uses git flow branching conventions, with main as the current production release branch.

For development, we assume the usage of uv. uv is compatible with the use of pip for python package management and a tool of your choice for creating python virtual environments (e.g., mamba, venv).

Initial setup and installation:

  • Install uv if it's not installed. It can be installed via PyPI, Homebrew, or a standalone installer. See uv's installation documentation for more details.

  • To explicitly sync the project's dependencies, including optional dependencies for development and testing, to your local environment run:

    uv sync
    
  • Note that uv performs syncing and locking automatically (e.g., any time uv run is invoked). By default, syncing will remove any packages not specifically specified in the pyproject.toml.

Unit Testing

Unit tests are written with py.test but use some Django test classes for compatibility with django test suites. Running the tests requires a minimal settings file for Django required configurations.

  • Copy sample test settings and add a secret key:

    cp ci/testsettings.py testsettings.py
    
  • Run the tests with pytest:

    uv run pytest
    

License

django-pucas is distributed under the Apache 2.0 License.

©2016 Trustees of Princeton University. Permission granted via Princeton Docket #18-3398-1 for distribution online under a standard Open Source license. Ownership rights transferred to Rebecca Koeser provided software is distributed online via open source.

Metadata

Release files for pucas 0.11

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pucas 0.11
File Size Uploaded
pucas-0.11.tar.gz 23.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pucas 0.11
File Interpreter ABI Platform
pucas-0.11-py3-none-any.whl Python 3 none any Details

Total release size: 47.0 kB

Release files / pucas-0.11.tar.gz

Download URL pucas-0.11.tar.gz
Size 23.2 kB
Tags Source
SHA-256 checksum
How to use checksums
3568a4af3d8e7e5facf8ad137b0a22d5207909e8d92f0e010554a5758f8e617a
BLAKE2b-256 checksum
How to use checksums
6c7df017ad4bb51c0419a84af81a25a05d3d81cdb03ff6226e751838fb869a90
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 27, 2026.

Transparency log

Release files / pucas-0.11-py3-none-any.whl

Download URL pucas-0.11-py3-none-any.whl
Size 23.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
239857b910d0944cd841966b23c7d18523d2f23fa1be6d2e12f54ddaa3803967
BLAKE2b-256 checksum
How to use checksums
231bd77afca137abbf8c15e01f07dcb5761d35852419c0343048bdaf3e4206a6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 27, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.11 This release

2 release files

0.9.1

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.2

2 release files

0.5.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page