Skip to main content

Base ‘users’ application for Django projects. It provides following endpoints:

  • Registration

  • Background registration

  • Login

  • Change password

  • Change email

  • Remind password

  • Delete account

  • Google authentication

  • Facebook authentication

… and following template views:

  • Verify account

  • Confirm password remind

Setup

1. Install using pip:

pip install ngits-users

2. Change your settings file:

import os

...

INSTALLED_APPS = [
    ...
    "rest_framework",
    "rest_framework.authtoken",
    "users"
]

...

AUTH_USER_MODEL = "users.User"

CELERY_BROKER_URL = "<redis_url>"
CELERY_RESULT_BACKEND = "<redis_url>"

DEFAULT_FROM_EMAIL = os.environ.get("DEFAULT_FROM_EMAIL", "<your_email>")

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": [
        "rest_framework.authentication.TokenAuthentication",
    ],
    # Optional
    "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
}

REGISTRATION_EMAIL_SUBJECT = "<email subject>"
REMIND_EMAIL_SUBJECT = "<email subject>"

# debugging
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"

3. Add paths to your urls.py file:

from django.urls import path, include

urlpatterns = [
    ...
    path("users/", include("users.urls"))
]

4. Run migrations:

py manage.py migrate

5. Add following variables to your .env file:

# smpt config
DEFAULT_FROM_EMAIL=no-reply@ngits.dev

EMAIL_HOST=
EMAIL_HOST_PASSWORD=
EMAIL_HOST_USER=
EMAIL_PORT=

# celery
CELERY_BROKER_URL=
CELERY_RESULT_BACKEND=

6. Celery configuration:

../<django_project>/<proj_name>/celery.py

import os

from celery import Celery

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "<proj_name>.settings")

app = Celery("<proj_name>")
app.config_from_object("django.conf:settings", namespace="CELERY")
app.autodiscover_tasks()

../<django_project>/<proj_name>/__init__.py

from .celery import app as celery_app

__all__ = ("celery_app",)

7. Optional redoc configuration:

pip install drf-spectacular==0.23.*

settings.py:

INSTALLED_APPS = [
    ...
    "drf_spectacular"
]

SPECTACULAR_SETTINGS = {
    "TITLE": "<proj_name> API",
    "VERSION": "1.0.0",
}

TEMPLATES = [
    ...
    'DIRS': [ BASE_DIR / "templates"],
    ...
]

urls.py:

from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView

...

urlpatterns = [
    ...
    path(
        "docs/schema/",
        SpectacularAPIView.as_view(),
        name="schema"
    ),
    path(
        "docs/redoc/",
        SpectacularRedocView.as_view(url_name="schema"),
        name="redoc",
    ),
]

../<django_project>/templates/redoc.html:

<!DOCTYPE html>
<html>
    <head>
        <title>ReDoc</title>
        <!-- needed for adaptive design -->
        <meta charset="utf-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
        <!-- ReDoc doesn't change outer page styles -->
        <style>
            body {
                margin: 0;
                padding: 0;
            }
        </style>
    </head>
    <body>
        <redoc spec-url='{% url schema_url %}'></redoc>
        <script src="https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js"> </script>
    </body>
</html>

Finally generate YAML schema of documentation:

py manage.py spectacular --file schema.yml

8. Optional templates override:

In order to override the default templates you have to create new files in your configured templates directory named:
  • Email templates: these should contain {{ url|safe }}
    • change_password_email.html

    • change_password_email.txt

    • registration_email.html

    • registration_email.txt

  • View templates:
    • change_password.html - this have to contain {{ form }} !

    • verify_ok.html

    • verify_error.html

There’s also additional {{ email }} context param you can use in your email templates.

e.g.:

/repo
    /manage.py
    /templates
        /change_password_email.html
        /change_password_email.txt
        /change_password.html

For fore details check out library default templates

9. Optional TokenSerializer override:

You can override TokenSerializer - the default response serializer on LoginView (/login).

In order to use your own serializer, you need to follow these steps:

  1. Create your custom serializer:

e.g.:

from rest_framework import serializers
from rest_framework.authtoken.models import Token

...

class TestSerializer(serializers.ModelSerializer):
    foo = serializers.SerializerMethodField()

    class Meta:
        model = Token
        fields = ("key", "user_id", "foo")

    def get_foo(self, obj):
        return "bar"

Warning! Your custom serializer must handle incoming DRF Token object!

  1. Set serializer path in your settings file

e.g.:

LOGIN_RESPONSE_SERIALIZER_PATH = "app.serializers.TestSerializer"
  1. Take it for a spin!

HTTP 200 OK
Allow: POST, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "key": "a5851e7359d1d04cd99a26014e47fcbedaa0beea",
    "user_id": 1,
    "foo": "bar"
}

10. Optional AvatarDownloadView access checker:

You can override access verification for AvatarDownloadView (/<user_id>/avatar/).

By default, every authenticated user can download another user’s avatar. If you need custom rules (e.g. tenant isolation, organization membership, ownership), define your own checker and point to it from settings.

In the checker:

  • request.user is the authenticated user making the request

  • target_user is the user selected by <user_id> in the URL, whose avatar is being downloaded

  1. Create your custom checker:

e.g.:

def check_same_tenant(request, target_user):
    return request.user.tenant_id == target_user.tenant_id

The checker must accept (request, target_user) and return True when access should be allowed.

  1. Set checker path in your settings file

e.g.:

AVATAR_ACCESS_CHECKER_PATH = "app.permissions.check_same_tenant"
  1. Take it for a spin!

GET /users/12/avatar/
Authorization: Token <your_token>

If the checker returns False, the endpoint responds with:

HTTP 403 Forbidden
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "detail": "Access denied."
}

11. Optional DeleteAccountView verifier:

You can add a custom verifier for DeleteAccountView (/delete/).

By default, no additional verification is performed — the endpoint deletes the account for any authenticated user. If you need extra verification (e.g. password confirmation, two-factor check, admin approval), define your own verifier and point to it from settings.

The verifier callable receives the DRF request object and must return a tuple (is_verified: bool, error_message: str | None).

  1. Create your custom verifier:

e.g.:

def check_password_verifier(request):
    password = request.data.get("password", "")
    if not request.user.check_password(password):
        return False, "User authorization failed!"
    return True, None
  1. Set verifier path in your settings file

e.g.:

DELETE_ACCOUNT_VERIFIER_PATH = "app.verifiers.check_password_verifier"
  1. Take it for a spin!

POST /users/delete/
Authorization: Token <your_token>
Content-Type: application/json

{
    "password": "your_current_password"
}

If the verifier returns False, the endpoint responds with:

HTTP 400 Bad Request
Content-Type: application/json

{
    "detail": "User authorization failed!"
}

Login response codes

400 response:

error_code

error_msg

00

Login failed

01

User not found

02

User not active

Additional information

This package also support django tranlations.

Metadata

Release files for ngits-users 2.2.0

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

Source distribution (sdist)

Source distribution for ngits-users 2.2.0
File Size Uploaded Provenance
ngits_users-2.2.0.tar.gz 29.2 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for ngits-users 2.2.0
File Interpreter ABI Platform
ngits_users-2.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 62.7 kB

Release files / ngits_users-2.2.0.tar.gz

Download URL ngits_users-2.2.0.tar.gz
Size 29.2 kB
Tags Source
SHA-256 checksum
How to use checksums
1a270db013a3399fb8bf8f4886e85e9bb84bc5c54006e1ffd13488ac350c29f3
BLAKE2b-256 checksum
How to use checksums
d643c3eec398b566ba822b22667bed48f46168c2c375d0e07320accff338e404
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.2

Release files / ngits_users-2.2.0-py3-none-any.whl

Download URL ngits_users-2.2.0-py3-none-any.whl
Size 33.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e1f80541b7aae7892713b11f64eddfca2a65ec6249c76bf3da3418cf7eb2760d
BLAKE2b-256 checksum
How to use checksums
7f84f7cc17036df444325876d6f6c09c759b94a1fade64842b76016a9e9a53e6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.2

Security for ngits-users 2.2.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

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