### Launch Development Server Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/installation.rst Starts the Django development server, making the project accessible locally. The admin interface is typically available at http://127.0.0.1:8000/admin/. ```shell ./manage.py runserver ``` -------------------------------- ### Start Redis with Docker Compose Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/installation.rst Starts the Redis service in detached mode using Docker Compose. Redis is a required backend for certain project functionalities, such as caching or message queuing. ```shell docker compose up -d ``` -------------------------------- ### Install from PyPI Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/installation.rst Installs the latest stable version of the openwisp-users package directly from the Python Package Index (PyPI). This is the standard method for production or general use. ```shell pip install openwisp-users ``` -------------------------------- ### Clone and Install OpenWISP Users Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/installation.rst Clones the OpenWISP Users repository from a specified fork and installs it in editable mode with REST API dependencies. This command sets up the project locally for development. ```shell git clone git://github.com//openwisp-users cd openwisp-users/ pip install -e .[rest] ``` -------------------------------- ### Install from GitHub Tarball Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/installation.rst Installs the latest development version of openwisp-users by downloading a tarball directly from its GitHub repository. This is useful for testing the most recent code. ```shell pip install https://github.com/openwisp/openwisp-users/tarball/master ``` -------------------------------- ### Install from GitHub Git URL Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/installation.rst Installs the openwisp-users package in editable mode directly from its GitHub repository using the git protocol. This allows for direct development and testing against the repository's HEAD. ```shell pip install -e git+git://github.com/openwisp/openwisp-users#egg=openwisp_users ``` -------------------------------- ### Run Celery Worker and Beat Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/installation.rst Starts the Celery worker and Celery Beat scheduler in separate terminal windows. These are essential for handling asynchronous tasks and scheduled jobs within the project. ```shell cd tests/ celery -A openwisp2 worker -l info celery -A openwisp2 beat -l info ``` -------------------------------- ### Create Database and Superuser Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/installation.rst Applies database migrations to set up the project's database schema and creates an administrative superuser account. These commands are executed within the project's test directory. ```shell cd tests/ ./manage.py migrate ./manage.py createsuperuser ``` -------------------------------- ### Install SQLite Dependencies Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/installation.rst Installs SQLite3 and its development libraries, along with OpenSSL, required for building and running the project on Debian/Ubuntu-based systems. These are essential system-level dependencies. ```shell sudo apt-get install sqlite3 libsqlite3-dev openssl libssl-dev ``` -------------------------------- ### Install Test Requirements Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/installation.rst Installs all Python packages necessary for running the project's test suite. This ensures that all testing dependencies are met before executing tests. ```shell pip install -r requirements-test.txt ``` -------------------------------- ### Install openwisp-users Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/extending.rst Install the openwisp-users package using pip and add it to your project's requirements. This ensures the necessary components are available for your project. ```shell pip install openwisp-users ``` -------------------------------- ### Run Project Tests Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/installation.rst Executes the project's test suite using a custom run script. The `--parallel` and `--keepdb` flags are optional but recommended for faster test execution. ```shell # --parallel and --keepdb are optional but help to speed up the operation ./runtests.py --parallel --keepdb ``` -------------------------------- ### Authentication Usage Example Source: https://github.com/openwisp/openwisp-users/blob/master/docs/user/rest-api.rst Demonstrates how to authenticate API requests using a Bearer token obtained from the token endpoint. It shows how to include the token in the Authorization header for subsequent requests. ```shell # Get the bearer token TOKEN=$(curl -X POST http://localhost:8000/api/v1/users/token/ -d "username=openwisp" -d "password=1234" | jq -r .token) # Get user list, send bearer token in authorization header curl http://localhost:8000/api/v1/users/user/ -H "Authorization: Bearer $TOKEN" ``` -------------------------------- ### Start a new Django app Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/extending.rst This command initializes a new Django application directory. This app will house your custom OpenWISP Users implementation. Ensure you run this command in a directory accessible via your Python path. ```shell django-admin startapp myusers ``` -------------------------------- ### DRF Permission Classes Documentation Example Fix Source: https://github.com/openwisp/openwisp-users/blob/master/CHANGES.rst Corrects a broken example in the documentation related to Django REST Framework permission classes. This ensures developers can correctly implement and understand permission logic. ```APIDOC Documentation Fix: DRF Permission Classes Example Description: Corrected a broken code example in the DRF Permission Classes section of the documentation. Purpose: - Ensure accuracy and usability of documentation examples. - Help developers correctly implement permission logic. Related: - DRF Permission Classes - Documentation ``` -------------------------------- ### ProtectedAPIMixin Usage Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/django-rest-framework-utils.rst Illustrates how to use the ProtectedAPIMixin, which provides common authentication and permission classes for API views. This example shows how to extend it and set a specific throttle scope. ```python # Used in openwisp-ipam from openwisp_users.api.mixins import ( ProtectedAPIMixin as BaseProtectedAPIMixin, ) class ProtectedAPIMixin(BaseProtectedAPIMixin): throttle_scope = "ipam" ``` -------------------------------- ### Usage of IsOrganizationManager Permission Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/django-rest-framework-utils.rst Example showing how to apply the IsOrganizationManager permission class to a Django REST Framework API view. This ensures that only users who are organization managers can access the view. ```python from openwisp_users.api.permissions import IsOrganizationManager from rest_framework import generics class MyApiView(generics.APIView): permission_classes = (IsOrganizationManager,) ``` -------------------------------- ### Python Package Dependencies Source: https://github.com/openwisp/openwisp-users/blob/master/requirements.txt This snippet details the Python packages and their version requirements for the OpenWISP Users project. It includes standard package names with version specifiers and a package installed directly from a Git tarball. ```python django-organizations~=2.5.0 django-extensions>=3.2,<4.2 django-allauth[socialaccount]~=65.8.1 django-phonenumber-field~=8.1.0 phonenumbers~=9.0.8 openwisp-utils[rest,celery] @ https://github.com/openwisp/openwisp-utils/tarball/1.2 packaging django-sesame~=3.2.3 ``` -------------------------------- ### Usage of Extended DjangoModelPermissions Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/django-rest-framework-utils.rst Example demonstrating the use of an extended DjangoModelPermissions class for a list-create API view. This custom permission checks for 'view' or 'change' permissions for GET requests, addressing limitations in the default DRF implementation. ```python from openwisp_users.api.permissions import DjangoModelPermissions from rest_framework.generics import ListCreateAPIView class TemplateListCreateView(ListCreateAPIView): serializer_class = TemplateSerializer permission_classes = (DjangoModelPermissions,) queryset = Template.objects.all() ``` -------------------------------- ### OPENWISP_USERS_AUTH_BACKEND_AUTO_PREFIXES Setting Source: https://github.com/openwisp/openwisp-users/blob/master/docs/user/settings.rst A tuple or list of international prefixes automatically tested by the authentication backend when parsing phone numbers for login. It is a tuple setting. ```python OPENWISP_USERS_AUTH_BACKEND_AUTO_PREFIXES = tuple() ``` -------------------------------- ### OpenWISP Users Sign In Template Source: https://github.com/openwisp/openwisp-users/blob/master/openwisp_users/accounts/templates/account/login.html The Django template for the user sign-in page. It extends a base template, loads internationalization, defines head title and extra styles, and renders the sign-in form using CSRF token and form-as-p rendering. Includes a link to the password reset page. ```django {% extends "account/base_entrance.html" %} {% load i18n %} {% block head_title %}{% trans "Sign In" %}{% endblock %} {% block extrastyle %} {{ block.super }} #content p label { margin-right: 5px; } #id_password + span { display: none; } {% endblock extrastyle %} {% block content %} {% trans "Sign In" %} ===================== {% csrf_token %} {{ form.as_p }} {% if redirect_field_value %} {% endif %} [{% trans "Forgot Password?" %}]({% url 'account_reset_password' %}) {% endblock %} ``` -------------------------------- ### Configure STATICFILES_FINDERS Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/extending.rst Add 'openwisp_utils.staticfiles.DependencyFinder' to the STATICFILES_FINDERS list in settings.py. This allows OpenWISP utilities to find static files from extended applications. ```python STATICFILES_FINDERS = [ "django.contrib.staticfiles.finders.FileSystemFinder", "django.contrib.staticfiles.finders.AppDirectoriesFinder", "openwisp_utils.staticfiles.DependencyFinder", ] ``` -------------------------------- ### Authentication REST API Endpoints Enabled by Default Source: https://github.com/openwisp/openwisp-users/blob/master/CHANGES.rst Notes that the REST API endpoints for authentication (login, logout, token management) are now enabled by default in the project configuration. This simplifies the setup for API-driven authentication. ```APIDOC Configuration: Authentication API Endpoints Description: Authentication-related REST API endpoints are enabled by default. Impact: - Users can immediately leverage API authentication features without explicit configuration. Related: - REST API - User authentication ``` -------------------------------- ### OPENWISP_USERS_EXPORT_USERS_COMMAND_CONFIG Setting Source: https://github.com/openwisp/openwisp-users/blob/master/docs/user/settings.rst Configures the fields exported by the export_users command, including fields to select and related models for optimization. It is a dictionary setting. ```python OPENWISP_USERS_EXPORT_USERS_COMMAND_CONFIG = { "fields": [ "id", "username", "email", "password", "first_name", "last_name", "is_staff", "is_active", "date_joined", "phone_number", "birth_date", "location", "notes", "language", "organizations", ], "select_related": [] } ``` -------------------------------- ### OpenwispUsersConfig Class Methods Source: https://github.com/openwisp/openwisp-users/blob/master/CHANGES.rst Addresses a bug where the `@classmethod` decorator was missing from specific methods within the `OpenwispUsersConfig` class. This fix ensures these methods function correctly as class methods. ```python from django.apps import AppConfig class OpenwispUsersConfig(AppConfig): name = 'openwisp_users' # ... other methods ... @classmethod def update_organizations_dict(cls, ...): # ... implementation ... pass @classmethod def create_organization_owner(cls, ...): # ... implementation ... pass # ... other methods ... ``` -------------------------------- ### User API Endpoints Source: https://github.com/openwisp/openwisp-users/blob/master/docs/user/rest-api.rst Comprehensive endpoints for managing users, including listing, creating, retrieving, updating, patching, and deleting user accounts. Supports email verification status during creation. ```APIDOC GET /api/v1/users/user/ Description: List Users POST /api/v1/users/user/ Description: Create User Note: Passing `true` to the optional `is_verified` field allows creating users with their email address flagged as verified, skipping the verification email. GET /api/v1/users/user/{id}/ Description: Get User Detail PUT /api/v1/users/user/{id}/ Description: Change User Detail PATCH /api/v1/users/user/{id}/ Description: Patch User Detail DELETE /api/v1/users/user/{id}/ Description: Delete User ``` -------------------------------- ### Django Admin Registrations for OpenWISP Users Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/extending.rst Registers various OpenWISP Users models with the Django admin site, extending base admin classes. This setup allows for management of Groups, Organizations, Organization Owners, Organization Users, and standard Users through the Django admin interface. ```python from openwisp_users.admin import ( UserAdmin as BaseUserAdmin, GroupAdmin as BaseGroupAdmin, OrganizationAdmin as BaseOrganizationAdmin, OrganizationOwnerAdmin as BaseOrganizationOwnerAdmin, OrganizationUserAdmin as BaseOrganizationUserAdmin, ) from swapper import load_model from django.contrib.auth import get_user_model Group = load_model("openwisp_users", "Group") Organization = load_model("openwisp_users", "Organization") OrganizationOwner = load_model("openwisp_users", "OrganizationOwner") OrganizationUser = load_model("openwisp_users", "OrganizationUser") User = get_user_model() admin.site.unregister(Group) admin.site.unregister(Organization) admin.site.unregister(OrganizationOwner) admin.site.unregister(OrganizationUser) admin.site.unregister(User) @admin.register(Group) class GroupAdmin(BaseGroupAdmin): pass @admin.register(Organization) class OrganizationAdmin(BaseOrganizationAdmin): pass @admin.register(OrganizationOwner) class OrganizationOwnerAdmin(BaseOrganizationOwnerAdmin): pass @admin.register(OrganizationUser) class OrganizationUserAdmin(BaseOrganizationUserAdmin): pass @admin.register(User) class UserAdmin(BaseUserAdmin): pass ``` -------------------------------- ### Filter Django by Organization (Default Fields) Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/django-rest-framework-utils.rst This example shows how to use `OrganizationManagedFilter` from `openwisp_users.api.filters`. This base filter class includes `organization` and `organization_slug` filter fields by default, simplifying the process of creating organization-aware filters. It demonstrates inheriting from `OrganizationManagedFilter` and configuring the `Meta` class to apply organization filtering to a specific model like `FloorPlan`. ```python from django_filters import rest_framework as filters from openwisp_users.api.filters import OrganizationManagedFilter from ..models import FloorPlan class FloorPlanFilter(OrganizationManagedFilter): class Meta(OrganizationManagedFilter.Meta): model = FloorPlan class FloorPlanListCreateView(ProtectedAPIMixin, generics.ListCreateAPIView): serializer_class = FloorPlanSerializer queryset = FloorPlan.objects.select_related().order_by("-created") pagination_class = ListViewPagination filter_backends = [filters.DjangoFilterBackend] filterset_class = FloorPlanFilter ``` -------------------------------- ### Programmatic User Authentication with OpenWisp Users Backend Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/misc-utils.rst Demonstrates programmatic authentication using the `UsersAuthenticationBackend` class. It requires a Django request object, user identifier, and password to authenticate a user. ```python from openwisp_users.backends import UsersAuthenticationBackend backend = UsersAuthenticationBackend() backend.authenticate(request, identifier, password) ``` -------------------------------- ### User Permission Helpers Source: https://github.com/openwisp/openwisp-users/blob/master/CHANGES.rst Offers utility functions for managing user permissions, particularly within the context of organizations. These helpers streamline permission checks and assignments. ```Python # Example usage of user permission helpers (conceptual) from openwisp_users.models import User # Assuming user object is retrieved # user = User.objects.get(pk=1) # Check if user has a specific permission # has_perm = user.has_org_permission('can_view_organization', organization_id=1) # Assign a permission to a user for an organization # user.assign_org_permission('can_edit_users', organization_id=1) ``` -------------------------------- ### Filter Django by Organization Membership (Managed) Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/django-rest-framework-utils.rst This example demonstrates using `FilterDjangoByOrgManaged` to filter Django model instances based on the user's organization membership. It integrates with Django REST Framework's `FilterSet` and `filter_backend` to automatically apply organization-based filtering, solving multi-tenancy issues where default filters might expose data across organizations. The `organization_slug` field is added for explicit filtering by organization slug. ```python from django_filters import rest_framework as filters from openwisp_users.api.mixins import FilterDjangoByOrgManaged from ..models import FloorPlan class FloorPlanOrganizationFilter(FilterDjangoByOrgManaged): organization_slug = filters.CharFilter(field_name="organization__slug") class Meta: model = FloorPlan fields = ["organization", "organization_slug"] class FloorPlanListCreateView(ProtectedAPIMixin, generics.ListCreateAPIView): serializer_class = FloorPlanSerializer queryset = FloorPlan.objects.select_related().order_by("-created") pagination_class = ListViewPagination filter_backends = [filters.DjangoFilterBackend] filterset_class = FloorPlanOrganizationFilter ``` -------------------------------- ### Apply Django Database Migrations Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/extending.rst Applies pending database migrations to your project's database. This command executes the SQL generated by makemigrations, updating your database schema to match your models. ```shell ./manage.py migrate ``` -------------------------------- ### Run OpenWISP Users Automated Tests Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/extending.rst Command to execute the automated tests for the OpenWISP Users module. It allows for parallel execution and specifies the test suite to run, typically named after the application. ```bash # the --parallel flag is optional ./manage.py test --parallel myusers ``` -------------------------------- ### Django Email Confirmation Template Source: https://github.com/openwisp/openwisp-users/blob/master/openwisp_users/accounts/templates/account/email/email_confirmation_message.txt This Django template generates the content for user registration confirmation emails. It uses template tags to dynamically insert site information, user details, and the activation URL. Dependencies include Django's templating engine and context variables like `current_site`, `user`, and `activate_url`. ```Django {% extends "account/email/base_message.txt" %} {% load account %} {% load i18n %} {% block content %}{% autoescape off %}{% user_display user as user_display %}{% blocktrans with site_name=current_site.name site_domain=current_site.name %}You're receiving this e-mail because user {{ user_display }} registered this e-mail address to create an account on {{ site_domain }}. To confirm this is correct, go to {{ activate_url }}{% endblocktrans %}{% endautoescape %}{% endblock %} ``` -------------------------------- ### Configure INSTALLED_APPS Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/extending.rst Update your Django project's settings.py to include your new custom app ('myusers') and remove or comment out the default 'openwisp_users' app. This tells Django to use your custom app instead. ```python INSTALLED_APPS = [ # ... other apps ... # 'openwisp_users' <-- comment out or delete this line "myusers" ] ``` -------------------------------- ### Create Django Database Migrations Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/extending.rst Generates migration files for your Django models based on changes detected in your models.py files. This command creates the necessary SQL statements to update your database schema. ```shell ./manage.py makemigrations ``` -------------------------------- ### export-users Command Line Utility Source: https://github.com/openwisp/openwisp-users/blob/master/CHANGES.rst Provides a command-line utility for exporting user data from the system. This is useful for data backup, migration, or analysis purposes. ```APIDOC Command: export-users Description: A Django management command to export user data from the system. Purpose: - Facilitates data backup, migration, and external analysis. Usage: - Run via `python manage.py export-users`. - May accept arguments for output format (e.g., CSV) or specific user selection. Output: - Typically generates a file containing user information. Related: - User management - Data export ``` -------------------------------- ### UsersAuthenticationBackend Source: https://github.com/openwisp/openwisp-users/blob/master/CHANGES.rst Introduces `UsersAuthenticationBackend`, an authentication backend that allows users to log in using multiple identifiers such as email, phone number, or username. This provides flexibility in user authentication. ```APIDOC Authentication Backend: UsersAuthenticationBackend Description: Allows users to authenticate using their email, phone number, or username. Purpose: - Provides flexible login options for users. Configuration: - Add 'openwisp_users.backends.UsersAuthenticationBackend' to AUTHENTICATION_BACKENDS in Django settings. Example (settings.py): AUTHENTICATION_BACKENDS = [ 'openwisp_users.backends.UsersAuthenticationBackend', 'django.contrib.auth.backends.ModelBackend', ] Related: - User authentication - Login methods ``` -------------------------------- ### Organization Membership Helpers Source: https://github.com/openwisp/openwisp-users/blob/master/CHANGES.rst Provides helper functions for managing organization memberships and user roles within OpenWisp. These utilities simplify common operations related to user-organization relationships. ```Python # Example usage of organization membership helpers (conceptual) from openwisp_users.models import Organization, User # Assuming user and organization objects are retrieved # user = User.objects.get(pk=1) # organization = Organization.objects.get(pk=1) # Add user to organization # organization.add_user(user, role='member') # Check if user is in organization # is_member = organization.has_user(user) # Get users of an organization # org_users = organization.get_users() ``` -------------------------------- ### Sign In Page CSS Styling Source: https://github.com/openwisp/openwisp-users/blob/master/openwisp_users/accounts/templates/account/login.html Custom CSS rules applied to the sign-in page. It inherits parent styles and applies specific styling to labels within paragraphs and hides a span element immediately following the password input field. ```css #content p label { margin-right: 5px; } #id_password + span { display: none; } ``` -------------------------------- ### Include Email Confirmation Template - Django Source: https://github.com/openwisp/openwisp-users/blob/master/openwisp_users/accounts/templates/account/email/email_confirmation_signup_message.html This Django template tag is used to include the content of another template file. It promotes modularity by allowing reusable template fragments. In this case, it incorporates the email confirmation message defined in 'account/email/email_confirmation_message.html'. ```Django {% include "account/email/email_confirmation_message.html" %} ``` -------------------------------- ### MultitenantAdminMixin Source: https://github.com/openwisp/openwisp-users/blob/master/CHANGES.rst A mixin class extracted from openwisp-utils to facilitate multi-tenant administration in Django. It helps in scoping admin interfaces to specific organizations. ```Python from django.contrib import admin from openwisp_users.mixins import MultitenantAdminMixin # Example of using the mixin in an admin class # class OrganizationUserAdmin(MultitenantAdminMixin, admin.ModelAdmin): # list_display = ('user', 'organization', 'role') # # ... other admin configurations ``` -------------------------------- ### Organization Membership Helpers Source: https://github.com/openwisp/openwisp-users/blob/master/CHANGES.rst Helper functions for managing organization memberships have been updated to accept string or UUID identifiers for greater flexibility. This simplifies the process of associating users with organizations. ```Python # Organization membership helpers now accept string or UUID # Example: organizations_managed(user, organization_id_or_uuid) # Example: organizations_owned(user, organization_id_or_uuid) ``` -------------------------------- ### User Organization Role Properties Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/misc-utils.rst Illustrates the properties available on the User model to retrieve organization-related information. These properties cache data to optimize performance and provide direct access to management and ownership status. ```python >>> user.organizations_dict {'20135c30-d486-4d68-993f-322b8acb51c4': {'is_admin': True, 'is_owner': False}} >>> user.organizations_dict.keys() dict_keys(['20135c30-d486-4d68-993f-322b8acb51c4']) >>> user.organizations_managed ['20135c30-d486-4d68-993f-322b8acb51c4'] >>> user.organizations_owned ['20135c30-d486-4d68-993f-322b8acb51c4'] ``` -------------------------------- ### User and Group Management Endpoints Source: https://github.com/openwisp/openwisp-users/blob/master/docs/user/rest-api.rst Provides endpoints for managing user and group resources within the OpenWISP Users system. Includes operations for listing, creating, retrieving, updating, and deleting groups, as well as managing user-specific data like email addresses. ```APIDOC User Password Management: PUT /api/v1/users/user/{id}/password/ Description: Changes the password for a specific user. Parameters: id (integer): The ID of the user whose password needs to be changed. List Groups: GET /api/v1/users/group/ Description: Retrieves a list of all available groups. Create New Group: POST /api/v1/users/group/ Description: Creates a new group. Get Group Detail: GET /api/v1/users/group/{id}/ Description: Retrieves details for a specific group. Parameters: id (integer): The ID of the group to retrieve. Change Group Detail: PUT /api/v1/users/group/{id}/ Description: Updates all details of a specific group. Parameters: id (integer): The ID of the group to update. Patch Group Detail: PATCH /api/v1/users/group/{id}/ Description: Partially updates details of a specific group. Parameters: id (integer): The ID of the group to update. Delete Group: DELETE /api/v1/users/group/{id}/ Description: Deletes a specific group. Parameters: id (integer): The ID of the group to delete. List Email Addresses: GET /api/v1/users/user/{id}/email/ Description: Retrieves a list of email addresses associated with a user. Parameters: id (integer): The ID of the user. Add Email Address: POST /api/v1/users/user/{id}/email/ Description: Adds a new email address for a user. Parameters: id (integer): The ID of the user. Get Email Address: GET /api/v1/users/user/{id}/email/{id}/ Description: Retrieves details of a specific email address for a user. Parameters: id (integer): The ID of the user. id (integer): The ID of the email address. Change Email Address: PUT /api/v1/users/user/{id}/email/{id}/ Description: Updates a specific email address for a user. Parameters: id (integer): The ID of the user. id (integer): The ID of the email address. Patch Email Address: PATCH /api/v1/users/user/{id}/email/{id}/ Description: Partially updates a specific email address for a user. Parameters: id (integer): The ID of the user. id (integer): The ID of the email address. Make/Unmake Email Address Primary: PATCH /api/v1/users/user/{id}/email/{id}/ Description: Marks or unmarks an email address as primary for a user. Parameters: id (integer): The ID of the user. id (integer): The ID of the email address. Mark/Unmark Email Address as Verified: PATCH /api/v1/users/user/{id}/email/{id}/ Description: Marks or unmarks an email address as verified for a user. Parameters: id (integer): The ID of the user. id (integer): The ID of the email address. Remove Email Address: DELETE /api/v1/users/user/{id}/email/{id}/ Description: Removes a specific email address from a user. Parameters: id (integer): The ID of the user. id (integer): The ID of the email address. ``` -------------------------------- ### Configure TEMPLATES loaders Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/extending.rst Modify the TEMPLATES setting in settings.py to include 'openwisp_utils.loaders.DependencyLoader' before 'django.template.loaders.app_directories.Loader'. This enables the dependency loading for templates. ```python TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", "OPTIONS": { "loaders": [ "django.template.loaders.filesystem.Loader", "openwisp_utils.loaders.DependencyLoader", "django.template.loaders.app_directories.Loader", ], "context_processors": [ "django.template.context_processors.debug", "django.template.context_processors.request", "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", ], }, } ] ``` -------------------------------- ### OrganizationInvitation Model Source: https://github.com/openwisp/openwisp-users/blob/master/CHANGES.rst Details the `OrganizationInvitation` model, which is used to manage invitations for users to join organizations. This model likely stores invitation tokens, expiry dates, and the status of invitations. ```APIDOC Model: OrganizationInvitation Description: Manages invitations for users to join organizations. Fields: - organization: ForeignKey to the Organization model. - invited_by: ForeignKey to the User who sent the invitation. - email: Email address of the invited user. - token: Unique token for the invitation. - expires_at: Timestamp when the invitation expires. - status: Current status of the invitation (e.g., pending, accepted, expired). Purpose: - Facilitates controlled onboarding of users into organizations. Related: - Organization management - User management ``` -------------------------------- ### UsersAuthenticationBackend API Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/misc-utils.rst Details the UsersAuthenticationBackend, which allows authentication via username, email, or phone number. It prioritizes email over username and phone numbers, handling international formats with the 'phonenumbers' library. ```APIDOC UsersAuthenticationBackend: __init__() Initializes the authentication backend. authenticate(request, username=None, password=None, **kwargs) Authenticates the user based on provided credentials. - Supports username, email, or phone number as the primary identifier. - Email authentication takes precedence over username. - Phone number authentication takes precedence if the identifier is a valid phone number. - Phone numbers are parsed using the 'phonenumbers' library, allowing for flexible input formats (e.g., with spaces, dots, dashes). - The OPENWISP_USERS_AUTH_BACKEND_AUTO_PREFIXES setting can be used to specify international prefixes for automatic parsing. - Returns the User object if authentication is successful, otherwise None. get_user(user_id) Retrieves a user by their primary key. - Parameters: - user_id: The primary key of the user. - Returns: The User object if found, otherwise None. Configuration: OPENWISP_USERS_AUTH_BACKEND_AUTO_PREFIXES - Type: list of strings - Description: A list of international prefixes (e.g., '+1', '+44') that can be automatically prepended to phone numbers during authentication. - Example: ['+1', '+44', '+39'] ``` -------------------------------- ### Configure EXTENDED_APPS Source: https://github.com/openwisp/openwisp-users/blob/master/docs/developer/extending.rst Add 'openwisp_users' to the EXTENDED_APPS setting in your settings.py. This setting is crucial for the dependency loading mechanism of OpenWISP utilities. ```python EXTENDED_APPS = ("openwisp_users",) ```