From dde3385ee0320d3009320d2668c17bbfe2217299 Mon Sep 17 00:00:00 2001 From: Federico Capoano Date: Thu, 1 Aug 2024 16:35:59 -0400 Subject: [PATCH] [qa/ci/misc] Maintenance - Reformatted code & docs - Updated CI settings - Updated setup.py --- .coveragerc | 7 - .github/workflows/ci.yml | 12 +- CHANGES.rst | 205 ++--- CONTRIBUTING.rst | 3 +- docs/source/developer/captive_portal_mock.rst | 22 +- docs/source/developer/contributing.rst | 31 +- docs/source/developer/freeradius.rst | 315 ++++---- .../developer/freeradius_wpa_enterprise.rst | 89 +- docs/source/developer/how_to_extend.rst | 441 ++++++---- docs/source/developer/setup.rst | 192 +++-- docs/source/developer/signals.rst | 5 +- docs/source/general/goals.rst | 77 +- docs/source/general/support.rst | 6 +- docs/source/index.rst | 90 ++- docs/source/user/api.rst | 757 +++++++++--------- docs/source/user/change_of_authorization.rst | 78 +- docs/source/user/enforcing_limits.rst | 168 ++-- docs/source/user/generating_users.rst | 73 +- docs/source/user/importing_users.rst | 73 +- docs/source/user/management_commands.rst | 105 ++- docs/source/user/registration.rst | 18 +- docs/source/user/saml.rst | 129 +-- docs/source/user/settings.rst | 736 ++++++++--------- docs/source/user/social_login.rst | 103 +-- .../migrations/0005_radiustoken.py | 1 - .../migrations/0006_add_radactt_fields.py | 1 - openwisp_radius/migrations/0008_sms_sender.py | 1 - .../0009_radbatch_user_credentials_field.py | 1 - .../migrations/0010_csv_private_storage.py | 1 - .../migrations/0011_add_null_uuid_field.py | 1 - .../migrations/0012_populate_uuid_field.py | 1 - .../migrations/0013_remove_null_uuid_field.py | 1 - .../0014_radiustoken_freeradius_auth.py | 1 - .../0015_freeradius_allowed_hosts.py | 1 - .../0016_allowed_mobile_prefixes.py | 1 - .../0017_phonetoken_phone_number.py | 1 - .../0018_populate_phonetoken_phone_number.py | 1 - ...9_made_phonetoken_phone_number_required.py | 1 - ...0020_added_optional_registration_fields.py | 1 - .../0021_radius_user_group_unique_together.py | 1 - ...tionradiussettings_registration_enabled.py | 1 - .../0024_registereduser_modified.py | 1 - .../migrations/0025_sms_verification.py | 1 - .../0026_login_status_url_org_settings.py | 1 - .../0027_password_reset_url_org_settings.py | 1 - ...ttings_saml_social_registration_enabled.py | 1 - .../0029_remove_check_customizations.py | 1 - .../0030_remove_radiuscheck_notes.py | 1 - .../0031_added_fallback_model_fields.py | 1 - ..._organizationradiussettings_sms_message.py | 1 - ...zationradiussettings_password_reset_url.py | 1 - ..._organizationradiussettings_coa_enabled.py | 1 - ...organizationradiussettings_sms_cooldown.py | 1 - ...radiussettings_mac_addr_roaming_enabled.py | 1 - openwisp_radius/tests/test_admin.py | 1 - pyproject.toml | 22 + setup.cfg | 10 - setup.py | 2 +- .../migrations/0002_initial_openwisp_app.py | 1 - .../0004_allowed_mobile_prefixes.py | 1 - .../0005_phonetoken_phone_number.py | 1 - ...0020_added_optional_registration_fields.py | 1 - ...tionradiussettings_registration_enabled.py | 1 - .../migrations/0022_registered_user.py | 1 - .../0023_registereduser_modified.py | 1 - .../migrations/0024_sms_verification.py | 1 - .../0025_login_status_url_org_settings.py | 1 - .../0026_password_reset_url_org_settings.py | 1 - .../0027_remove_check_customizations.py | 1 - ...ttings_allowed_mobile_prefixes_and_more.py | 1 - .../sample_users/migrations/0001_initial.py | 1 - .../migrations/0004_default_groups.py | 1 - 72 files changed, 2023 insertions(+), 1791 deletions(-) delete mode 100644 .coveragerc create mode 100644 pyproject.toml diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index ac42c385..00000000 --- a/.coveragerc +++ /dev/null @@ -1,7 +0,0 @@ -[run] -omit = - /*/test* - /tests - /*/__init__.py - /setup.py - /*/migrations/* diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 93a42243..a20a1d18 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,11 +31,6 @@ jobs: with: ref: ${{ github.event.pull_request.head.sha }} - - name: Install system libraries - run: | - sudo apt update - sudo apt-get -qq -y install xmlsec1 gettext - - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: @@ -44,6 +39,8 @@ jobs: - name: Install Dependencies id: deps run: | + sudo apt update -qq + sudo apt-get -qq -y install xmlsec1 gettext pip install -U pip wheel setuptools pip install -U -r requirements-test.txt pip install -e .[saml,openvpn_status] @@ -57,9 +54,10 @@ jobs: - name: Tests if: ${{ !cancelled() && steps.deps.conclusion == 'success' }} run: | - coverage run --source=openwisp_radius runtests.py + coverage run runtests.py --parallel # SAMPLE tests do not influence coverage, so we can speed up tests with --parallel - SAMPLE_APP=1 ./runtests.py --parallel --keepdb > /dev/null 2>&1 || SAMPLE_APP=1 ./runtests.py --keepdb + SAMPLE_APP=1 coverage run ./runtests.py --parallel > /dev/null 2>&1 || SAMPLE_APP=1 ./runtests.py + coverage combine coverage xml - name: Upload Coverage diff --git a/CHANGES.rst b/CHANGES.rst index 8a3d366c..97706ee5 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -13,25 +13,25 @@ Bugfixes ~~~~~~~~ - Made private storage backend configurable -- Updated API views to use ``filterset_class`` instead of ``filter_class`` +- Updated API views to use ``filterset_class`` instead of ``filter_class`` (required by ``django-filter==22.1``) -- Fixed organization cache bug in SAML ACS view: A forceful update of - the user's organization cache is done before performing post-login +- Fixed organization cache bug in SAML ACS view: A forceful update of the + user's organization cache is done before performing post-login operations to avoid issues occurring due to outdated cache. - Added missing Furlan translation for sesame link validity -- Use storage backend method for deleting ``RadiusBatch.csvfile``: - The previous implementation used the "os" module for deleting resisdual - csv files. This causes issues when the project uses a file storage backend +- Use storage backend method for deleting ``RadiusBatch.csvfile``: The + previous implementation used the "os" module for deleting resisdual csv + files. This causes issues when the project uses a file storage backend other than based on file system. -- Added error handling in RadiusBatch admin change view: Accessing admin change - view of a non-existent RadiusBatch object resulted in Server Error 500 - because the ``DoesNotExist`` conditioned was not handled. +- Added error handling in RadiusBatch admin change view: Accessing admin + change view of a non-existent RadiusBatch object resulted in Server + Error 500 because the ``DoesNotExist`` conditioned was not handled. - Load image using ``static()`` in RegisteredUserInline.get_is_verified - Use ``path`` URL kwarg in "serve_private_file" URL pattern -- Honor DISPOSABLE_RADIUS_USER_TOKEN in accounting stop API view: - The accounting stop REST API operation was not taking into - account the OPENWISP_RADIUS_DISPOSABLE_RADIUS_USER_TOKEN - setting when disabling the auth capability of the radius token. +- Honor DISPOSABLE_RADIUS_USER_TOKEN in accounting stop API view: The + accounting stop REST API operation was not taking into account the + OPENWISP_RADIUS_DISPOSABLE_RADIUS_USER_TOKEN setting when disabling the + auth capability of the radius token. Version 1.0.1 [2022-05-10] -------------------------- @@ -39,15 +39,15 @@ Version 1.0.1 [2022-05-10] Bugfixes ~~~~~~~~ -- Fixed a bug in the organization radius settings form which was causing it - to not display some default values correctly -- Fixed a bug in allowed mobile prefix implementation: - the implementation was joining the globally allowed prefixes - and the prefixes allowed at org level, with the result - that disabling a prefix at org level was not possible -- Called-station-ID command: log with warning instead of ``warn`` or ``error``: - - warn > warning (warn is deprecated) - - use warning instead of errors for more temporary connection issues cases +- Fixed a bug in the organization radius settings form which was causing + it to not display some default values correctly +- Fixed a bug in allowed mobile prefix implementation: the implementation + was joining the globally allowed prefixes and the prefixes allowed at + org level, with the result that disabling a prefix at org level was not + possible +- Called-station-ID command: log with warning instead of ``warn`` or + ``error``: - warn > warning (warn is deprecated) - use warning instead + of errors for more temporary connection issues cases Version 1.0.0 [2022-04-18] -------------------------- @@ -57,15 +57,16 @@ Features - Allowed to login via API with email or phone number - Allowed freeradius authorize with email or phone number -- Allowed the usage of subnets in `OPENWISP_RADIUS_FREERADIUS_ALLOWED_HOSTS +- Allowed the usage of subnets in + `OPENWISP_RADIUS_FREERADIUS_ALLOWED_HOSTS `_ -- Made the fields containing personal data of users which are exposed in the registration API - configurable (allowed, mandatory, disabled) via the - `OPENWISP_RADIUS_OPTIONAL_REGISTRATION_FIELDS setting or the admin interface +- Made the fields containing personal data of users which are exposed in + the registration API configurable (allowed, mandatory, disabled) via the + `OPENWISP_RADIUS_OPTIONAL_REGISTRATION_FIELDS setting or the admin + interface `_ - Allow to disable registration API via the - `OPENWISP_RADIUS_REGISTRATION_API_ENABLED setting - or the admin interface + `OPENWISP_RADIUS_REGISTRATION_API_ENABLED setting or the admin interface `_ - Added `throttling of API requests `_ @@ -74,34 +75,37 @@ Features - Add identity verification feature, configurable via the `OPENWISP_RADIUS_NEEDS_IDENTITY_VERIFICATION or via admin interface `_ -- Added utilities for implementing - `new registration and identity verification methods +- Added utilities for implementing `new registration and identity + verification methods `_ - Added `captive portal mock views `_ to ease development and debugging -- Add possibility to filter users by registration method in the admin interface -- Added SAML registration method to implement `captive portal authentication - via Single Sign On (SSO) `_ -- Added management command and celery task to - `delete unverified users +- Add possibility to filter users by registration method in the admin + interface +- Added SAML registration method to implement `captive portal + authentication via Single Sign On (SSO) + `_ +- Added management command and celery task to `delete unverified users `_ -- Added translations of user facing API responses in Italian, German, Slovenian and Furlan +- Added translations of user facing API responses in Italian, German, + Slovenian and Furlan - Added `Convert RADIUS accounting CALLED-STATION-ID feature `_, - celery task and management command, - with the possibility of triggering it on accounting creation - (see `OPENWISP_RADIUS_CONVERT_CALLED_STATION_ON_CREATE + celery task and management command, with the possibility of triggering + it on accounting creation (see + `OPENWISP_RADIUS_CONVERT_CALLED_STATION_ON_CREATE `_) -- Added an `equivalent of the FreeRADIUS sqlcounter feature to the REST API +- Added an `equivalent of the FreeRADIUS sqlcounter feature to the REST + API `_ - Added emission of django signal to FreeRADIUS accounting view: `radius_accounting_success `_ -- Added possibility to send email to the user an they start - a new radius accounting session -- Added organization level settings and related admin interface functionality - to enable/disable SAML and social login: +- Added possibility to send email to the user an they start a new radius + accounting session +- Added organization level settings and related admin interface + functionality to enable/disable SAML and social login: - `OPENWISP_RADIUS_SAML_REGISTRATION_ENABLED `_ @@ -116,24 +120,25 @@ Changes ~~~~~~~ Backward incompatible changes -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ++++++++++++++++++++++++++++++ - Updated prefixes of REST API URLs: - - API endpoints dedicated to FreeRADIUS have moved to ``/api/v1/freeradius/`` + - API endpoints dedicated to FreeRADIUS have moved to + ``/api/v1/freeradius/`` - the rest of the API endpoints have moved to ``/api/v1/radius/`` -- Allowed ``username`` and ``phone_number`` in password reset API, - the endpoint now accepts the "input" parameter instead of "email" -- Removed customizations for checks and password hashing because - they are unmaintained, any user needing these customizations is - advised to implement them as a third party app -- Improved REST API to change password: - inherited ``PasswordChangeView`` of openwisp-users to add support for - the current-password field in password change view +- Allowed ``username`` and ``phone_number`` in password reset API, the + endpoint now accepts the "input" parameter instead of "email" +- Removed customizations for checks and password hashing because they are + unmaintained, any user needing these customizations is advised to + implement them as a third party app +- Improved REST API to change password: inherited ``PasswordChangeView`` + of openwisp-users to add support for the current-password field in + password change view Dependencies -^^^^^^^^^^^^ +++++++++++++ - Added support for Django 3.2 and 4.0 - Dropped support for Django 2.2 @@ -143,24 +148,26 @@ Dependencies - Removed support for Python 3.6 Other changes -^^^^^^^^^^^^^ ++++++++++++++ - Moved AccountingView to freeradius endpoints -- Relaxed default values for the - `SMS token settings `_ +- Relaxed default values for the `SMS token settings + `_ - Switched to new navigation menu and new OpenWISP theme - Allowed users to sign up to multiple organizations -- Update username when phone number is changed if username is equal to the phone number -- Update stop time and termination to ``None`` if ``status_type`` is ``Interim-Update`` -- Send password reset emails using HTML theme: - leverage the new `openwisp-utils send_email function +- Update username when phone number is changed if username is equal to the + phone number +- Update stop time and termination to ``None`` if ``status_type`` is + ``Interim-Update`` +- Send password reset emails using HTML theme: leverage the new + `openwisp-utils send_email function `_ - to send an HTML version - of the reset password email based on the configurable email HTML theme of OpenWISP + to send an HTML version of the reset password email based on the + configurable email HTML theme of OpenWISP - Save the user preferred language in obtain and validate token views -- Added validation check to prevent invalid username in batch user creation -- Allowed to set the - `Password Reset URL setting +- Added validation check to prevent invalid username in batch user + creation +- Allowed to set the `Password Reset URL setting `_ via the admin interface - Added soft limits to celery tasks for background operations @@ -175,27 +182,28 @@ Bugfixes - Ensured each user can be member of a group only once - Radius check and reply should check for organization membership - ``ValidateAuthTokenView``: show ``phone_number`` as ``null`` if ``None`` -- Freeradius API: properly handle interaction between multiple orgs: - an user trying to authorize using the authorization data of an - org for which they are not member of must be rejected +- Freeradius API: properly handle interaction between multiple orgs: an + user trying to authorize using the authorization data of an org for + which they are not member of must be rejected - Fixed radius user group creation with multiple orgs - Added validation of phone number uniqueness in the registration API - Fixed issues with translatable strings: - - we don't translate log lines anymore because these won't be shown - to end users - - ``gettext`` does not work with fstrings, - therefore the use of ``str.format()`` has been restored + - we don't translate log lines anymore because these won't be shown to + end users + - ``gettext`` does not work with fstrings, therefore the use of + ``str.format()`` has been restored - improved some user facing strings -- Fixed Accounting-On and Accounting-Of accounting requests with blank usernames +- Fixed Accounting-On and Accounting-Of accounting requests with blank + usernames - Delete any cached radius token key on phone number change -- Fixed handling of interim-updates for closed sessions: - added handling of "Interim-Updates" for RadiusAccounting sessions - that are closed by OpenWISP when user logs into another organization +- Fixed handling of interim-updates for closed sessions: added handling of + "Interim-Updates" for RadiusAccounting sessions that are closed by + OpenWISP when user logs into another organization - Flag user as verified in batch user creation -- Added validation which prevents the creation of duplicated - check/reply attributes +- Added validation which prevents the creation of duplicated check/reply + attributes Version 0.2.1 [2020-12-14] -------------------------- @@ -203,8 +211,8 @@ Version 0.2.1 [2020-12-14] Changes ~~~~~~~ -- Increased openwisp-users and openwisp-utils versions to be - consistent with the `OpenWISP 2020-12 release +- Increased openwisp-users and openwisp-utils versions to be consistent + with the `OpenWISP 2020-12 release `_ - Increased dj-rest-auth to 2.1.2 and weasyprint to 52 @@ -214,23 +222,24 @@ Version 0.2.0 [2020-12-11] Features ~~~~~~~~ -- Changing the phone number via the API now keeps track of previous phone numbers - used by the user to comply with ISP legal requirements +- Changing the phone number via the API now keeps track of previous phone + numbers used by the user to comply with ISP legal requirements Changes ~~~~~~~ -- Obtain Auth Token View API endpoint: added ``is_active`` attribute to response -- Obtain Auth Token View API endpoint: if the user attempting to authenticate - is inactive, the API will return HTTP status code 401 along with the auth token - and ``is_active`` attribute -- Validate Auth Token View API endpoint: added ``is_active``, ``phone_number`` - and ``email`` to response data -- When changing phone number, user is flagged as inactive only after - the phone token is created and sent successfully +- Obtain Auth Token View API endpoint: added ``is_active`` attribute to + response +- Obtain Auth Token View API endpoint: if the user attempting to + authenticate is inactive, the API will return HTTP status code 401 along + with the auth token and ``is_active`` attribute +- Validate Auth Token View API endpoint: added ``is_active``, + ``phone_number`` and ``email`` to response data +- When changing phone number, user is flagged as inactive only after the + phone token is created and sent successfully - All API endpoints related to phone token and SMS sending are now - disabled (return 403 HTTP response) if SMS verification not enabled - at organization level + disabled (return 403 HTTP response) if SMS verification not enabled at + organization level Bugfixes ~~~~~~~~ @@ -253,7 +262,7 @@ Version 0.1.0 [2020-09-10] - mobile phone verification via SMS tokens - possibility to import users from CSV files - possibility to generate users for events -- management commands and/or celery tasks to perform - clean up operations and periodic tasks -- possibility to extend the base classes and swap models - to add custom functionality without changing the core code +- management commands and/or celery tasks to perform clean up operations + and periodic tasks +- possibility to extend the base classes and swap models to add custom + functionality without changing the core code diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 82049609..e1b58e46 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -1 +1,2 @@ -Please refer to the `OpenWISP Contribution Guidelines `_. +Please refer to the `OpenWISP Contribution Guidelines +`_. diff --git a/docs/source/developer/captive_portal_mock.rst b/docs/source/developer/captive_portal_mock.rst index d7206642..fb372711 100644 --- a/docs/source/developer/captive_portal_mock.rst +++ b/docs/source/developer/captive_portal_mock.rst @@ -1,15 +1,15 @@ -========================= Captive portal mock views ========================= The development environment of openwisp-radius provides two URLs that mock the behavior of a captive portal, these URLs can be used when testing -frontend applications like -`openwisp-wifi-login-pages `_ -during development. +frontend applications like `openwisp-wifi-login-pages +`_ during +development. .. note:: - These views are meant to be used just for development and testing. + + These views are meant to be used just for development and testing. Captive Portal Login Mock View ------------------------------ @@ -17,12 +17,12 @@ Captive Portal Login Mock View - **URL**: ``http://localhost:8000/captive-portal-mock/login/``. - **POST fields**: ``auth_pass`` or ``password``. -This view looks for ``auth_pass`` or ``password`` in the POST request data, -and if it finds anything will try to look for any ``RadiusToken`` instance -having its key equal to this value, and if it does find one, it makes a -``POST`` request to accouting view to create the radius session related to -the user to which the radius token belongs, provided there's no other open -session for the same user. +This view looks for ``auth_pass`` or ``password`` in the POST request +data, and if it finds anything will try to look for any ``RadiusToken`` +instance having its key equal to this value, and if it does find one, it +makes a ``POST`` request to accouting view to create the radius session +related to the user to which the radius token belongs, provided there's no +other open session for the same user. Captive Portal Logout Mock View ------------------------------- diff --git a/docs/source/developer/contributing.rst b/docs/source/developer/contributing.rst index 868fad8e..4803bfd8 100644 --- a/docs/source/developer/contributing.rst +++ b/docs/source/developer/contributing.rst @@ -1,24 +1,28 @@ -============ Contributing ============ -Thank you for taking the time to contribute to openwisp-radius, please read the -`guide for contributing to openwisp repositories `_. +Thank you for taking the time to contribute to openwisp-radius, please +read the `guide for contributing to openwisp repositories +`_. Follow these guidelines to speed up the process. .. contents:: **Table of Contents**: - :backlinks: none - :depth: 3 + :backlinks: none + :depth: 3 .. note:: - **In order to have your contribution accepted faster**, please read the - `OpenWISP contributing guidelines `_ and make sure to follow its guidelines. + + **In order to have your contribution accepted faster**, please read + the `OpenWISP contributing guidelines + `_ and make sure + to follow its guidelines. Setup ----- -Once you have chosen an issue to work on, :ref:`setup your machine for development `. +Once you have chosen an issue to work on, :ref:`setup your machine for +development `. Ensure test coverage does not decrease -------------------------------------- @@ -47,8 +51,9 @@ First of all, install the test requirements: pip install --no-cache-dir -U -r requirements-test.txt npm install -g jslint -Before committing your work check that your changes are not breaking -our `coding style conventions `_: +Before committing your work check that your changes are not breaking our +`coding style conventions +`_: .. code-block:: shell @@ -59,7 +64,8 @@ our `coding style conventions `_ +- `OpenWISP Coding Style Conventions + `_ Update the documentation ------------------------ @@ -67,8 +73,7 @@ Update the documentation If you introduce new features or change existing documented behavior, please remember to update the documentation! -The documentation is located in the ``/docs`` directory -of the repository. +The documentation is located in the ``/docs`` directory of the repository. To do work on the docs, proceed with the following steps: diff --git a/docs/source/developer/freeradius.rst b/docs/source/developer/freeradius.rst index 4a03934a..86cada66 100644 --- a/docs/source/developer/freeradius.rst +++ b/docs/source/developer/freeradius.rst @@ -1,34 +1,31 @@ .. _freeradius_setup_for_captive_portal: -================================================== Freeradius Setup for Captive Portal authentication ================================================== -This guide explains how to install and configure -`freeradius 3 `_ -in order to make it work with -`OpenWISP RADIUS `_ -for Captive Portal authentication. +This guide explains how to install and configure `freeradius 3 +`_ in order to make it work with `OpenWISP RADIUS +`_ for Captive Portal +authentication. -The guide is written for debian based systems, other linux -distributions can work as well but the name of packages and -files may be different. +The guide is written for debian based systems, other linux distributions +can work as well but the name of packages and files may be different. Widely used solutions used with OpenWISP RADIUS are PfSense and Coova-Chilli, but other solutions can be used as well. .. note:: - Before users can authenticate through a captive portal, - they will most likely need to sign up through a web page, - or alternatively, they will need to perform social login or - some other kind of Single Sign On (SSO). + + Before users can authenticate through a captive portal, they will most + likely need to sign up through a web page, or alternatively, they will + need to perform social login or some other kind of Single Sign On + (SSO). The `openwisp-wifi-login-pages - `_ web app - is an open source solution which integrates with - OpenWISP RADIUS to provide features like self user registration, - social login, SSO/SAML login, SMS verification, - simple username & password login using the + `_ web app is + an open source solution which integrates with OpenWISP RADIUS to + provide features like self user registration, social login, SSO/SAML + login, SMS verification, simple username & password login using the :ref:`radius_user_token` method. For more information see: `openwisp-wifi-login-pages @@ -43,12 +40,12 @@ First of all, become root: sudo -s -In order to **install a recent version of FreeRADIUS**, we recommend -using the `freeradius packages provided by NetworkRADIUS +In order to **install a recent version of FreeRADIUS**, we recommend using +the `freeradius packages provided by NetworkRADIUS `_. -After having updated the APT sources list to pull the NetworkRADIUS packages, -let's proceed to update the list of available packages: +After having updated the APT sources list to pull the NetworkRADIUS +packages, let's proceed to update the list of available packages: .. code-block:: shell @@ -74,13 +71,13 @@ If you use PostgreSQL: .. warning:: - You have to install and configure an SQL database like - PostgreSQL, MySQL (SQLite can also work, but we won't treat it here) - and make sure both OpenWISP RADIUS and Freeradius point to it. + You have to install and configure an SQL database like PostgreSQL, + MySQL (SQLite can also work, but we won't treat it here) and make sure + both OpenWISP RADIUS and Freeradius point to it. - The steps outlined above may not be sufficient to get the DB - of your choice to run, please consult the documentation of your - database of choice for more information on how to get it to run properly. + The steps outlined above may not be sufficient to get the DB of your + choice to run, please consult the documentation of your database of + choice for more information on how to get it to run properly. In the rest of this document we will mention PostgreSQL often because that is the database generally preferred by the Django community. @@ -89,19 +86,22 @@ Configuring Freeradius 3 ------------------------ For a complete reference on how to configure freeradius please read the -`Freeradius wiki, configuration files `_ -and their `configuration tutorial `_. +`Freeradius wiki, configuration files +`_ and their +`configuration tutorial `_. .. note:: - The path to freeradius configuration could be different on your system. - This article use the ``/etc/freeradius/`` directory that ships with recent - debian distributions and its derivatives -Refer to the `mods-available documentation `_ + The path to freeradius configuration could be different on your + system. This article use the ``/etc/freeradius/`` directory that ships + with recent debian distributions and its derivatives + +Refer to the `mods-available documentation +`_ for the available configuration values. Enable the configured modules -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ First of all enable the ``rest`` and optionally the ``sql`` module: @@ -114,20 +114,24 @@ First of all enable the ``rest`` and optionally the ``sql`` module: .. _configure-rest-module: Configure the REST module -^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~ -Configure the rest module by editing the file ``/etc/freeradius/mods-enabled/rest``, -substituting ```` with your django project's URL, (for example, if you are -testing a development environment, the URL could be ``http://127.0.0.1:8000``, -otherwise in production could be something like ``https://openwisp2.mydomain.org``)- +Configure the rest module by editing the file +``/etc/freeradius/mods-enabled/rest``, substituting ```` with your +django project's URL, (for example, if you are testing a development +environment, the URL could be ``http://127.0.0.1:8000``, otherwise in +production could be something like ``https://openwisp2.mydomain.org``)- .. warning:: - Remember you need to add your freeradius server IP address in `openwisp freeradius - allowed hosts settings <../user/settings.html#openwisp-radius-freeradius-allowed-hosts>`_. - If the freeradius server IP is not in allowed hosts, all requests to openwisp - radius API will return ``403``. -Refer to the `rest module documentation `_ + Remember you need to add your freeradius server IP address in + `openwisp freeradius allowed hosts settings + <../user/settings.html#openwisp-radius-freeradius-allowed-hosts>`_. If + the freeradius server IP is not in allowed hosts, all requests to + openwisp radius API will return ``403``. + +Refer to the `rest module documentation +`_ for the available configuration values. .. code-block:: ini @@ -164,25 +168,27 @@ for the available configuration values. } Configure the SQL module -^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~ .. note:: The ``sql`` module is not extremely needed but we treat it here since - it can be useful to implement custom behavior, moreover we treat it - in this document also to show that OpenWISP RADIUS can integrate itself + it can be useful to implement custom behavior, moreover we treat it in + this document also to show that OpenWISP RADIUS can integrate itself with other widely used FreeRADIUS modules. -Once you have configured properly an SQL server, e.g. PostgreSQL:, and you can -connect with a username and password edit the file ``/etc/freeradius/mods-available/sql`` -to configure Freeradius to use the relational database. +Once you have configured properly an SQL server, e.g. PostgreSQL:, and you +can connect with a username and password edit the file +``/etc/freeradius/mods-available/sql`` to configure Freeradius to use the +relational database. -Change the configuration for ``driver``, ``dialect``, ``server``, ``port``, -``login``, ``password``, ``radius_db`` as you need to fit your SQL server configuration. +Change the configuration for ``driver``, ``dialect``, ``server``, +``port``, ``login``, ``password``, ``radius_db`` as you need to fit your +SQL server configuration. -Refer to the -`sql module documentation `_ -for the available configuration values. +Refer to the `sql module documentation +`_ for +the available configuration values. Example configuration using the PostgreSQL database: @@ -203,7 +209,7 @@ Example configuration using the PostgreSQL database: .. _freeradius_site: Configure the site -^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~ This section explains how to configure the FreeRADIUS site. @@ -218,14 +224,13 @@ you have to do the following: - create one FreeRADIUS site for each organization - uncomment the line which starts with ``# api_token_header`` - substitute the occurrences of ```` and - ```` with the UUID & RADIUS API token of - each organization, refer to the section - :ref:`organization_uuid_token` for finding these values. + ```` with the UUID & RADIUS API token of each + organization, refer to the section :ref:`organization_uuid_token` for + finding these values. -If you are deploying a captive portal setup and can use -the RADIUS User Token method, you can get away with having -only one freeradius site for all the organizations and can simply copy -the configuration shown below. +If you are deploying a captive portal setup and can use the RADIUS User +Token method, you can get away with having only one freeradius site for +all the organizations and can simply copy the configuration shown below. .. code-block:: ini @@ -265,7 +270,8 @@ the configuration shown below. } } -Please also ensure that ``acct_unique`` is present in the ``pre-accounting`` section: +Please also ensure that ``acct_unique`` is present in the +``pre-accounting`` section: .. code-block:: ini @@ -278,7 +284,7 @@ Please also ensure that ``acct_unique`` is present in the ``pre-accounting`` sec .. _restart_freeradius: Restart freeradius to make the configuration effective -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Restart freeradius to load the new configuration: @@ -289,42 +295,44 @@ Restart freeradius to load the new configuration: systemctl restart freeradius In case of errors you can run `freeradius in debug mode -`_ by running -``freeradius -X`` in order to find out the reason of the failure. +`_ by running ``freeradius +-X`` in order to find out the reason of the failure. **A common problem, especially during development and testing, is that the -openwisp-radius application may not be running**, in that case you can find -out how to run the django development server in the -:ref:`Install for development ` section. +openwisp-radius application may not be running**, in that case you can +find out how to run the django development server in the :ref:`Install for +development ` section. Also make sure that this server runs on the port specified in ``/etc/freeradius/mods-enabled/rest``. You may also want to take a look at the `Freeradius documentation -`_ for further information that is freeradius specific. +`_ for further information that is +freeradius specific. Reconfigure the development environment using PostgreSQL -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You'll have to reconfigure the development environment as well before being able -to use openwisp-radius for managing the freeradius databases. +You'll have to reconfigure the development environment as well before +being able to use openwisp-radius for managing the freeradius databases. -If you have installed for development, create a file ``tests/local_settings.py`` -and add the following code to configure the database: +If you have installed for development, create a file +``tests/local_settings.py`` and add the following code to configure the +database: .. code-block:: python - # openwisp-radius/tests/local_settings.py - DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': '', - 'USER': '', - 'PASSWORD': '', - 'HOST': '127.0.0.1', - 'PORT': '5432' + # openwisp-radius/tests/local_settings.py + DATABASES = { + "default": { + "ENGINE": "django.db.backends.postgresql_psycopg2", + "NAME": "", + "USER": "", + "PASSWORD": "", + "HOST": "127.0.0.1", + "PORT": "5432", }, - } + } Make sure the database by the name ```` is created and also the role ```` with ```` as password. @@ -332,35 +340,38 @@ role ```` with ```` as password. Using Radius Checks for Authorization Information ------------------------------------------------- -Traditionally, when using an SQL backend with Freeradius, -user authorization information such as User-Name and -`"known good" `_ -password can be stored using the *radcheck* -table provided by Freeradius' default SQL schema. +Traditionally, when using an SQL backend with Freeradius, user +authorization information such as User-Name and `"known good" +`_ password can be stored +using the *radcheck* table provided by Freeradius' default SQL schema. -OpenWISP RADIUS instead uses the FreeRADIUS -`rlm_rest `_ +OpenWISP RADIUS instead uses the FreeRADIUS `rlm_rest +`_ module in order to take advantage of the built in user management and -authentication capabilities of Django -(for more information about these topics see :ref:`configure-rest-module` -and `User authentication in Django `_). +authentication capabilities of Django (for more information about these +topics see :ref:`configure-rest-module` and `User authentication in Django +`_). When migrating from existing FreeRADIUS deployments or in cases where it is preferred to use the FreeRADIUS *radcheck* table for storing user -credentials it is possible to utilize `rlm_sql `_ -in parallel with (or instead of) `rlm_rest `_ +credentials it is possible to utilize `rlm_sql +`_ in parallel with (or +instead of) `rlm_rest +`_ for authorization. .. note:: - Bypassing the REST API of openwisp-radius means that you - will have to manually create the radius check entries for each user - you want to authenticate with FreeRADIUS. + + Bypassing the REST API of openwisp-radius means that you will have to + manually create the radius check entries for each user you want to + authenticate with FreeRADIUS. Configuration -^^^^^^^^^^^^^ +~~~~~~~~~~~~~ -To configure support for accessing user credentials with Radius Checks ensure -the ``authorize`` section of your site as follows contains the ``sql`` module: +To configure support for accessing user credentials with Radius Checks +ensure the ``authorize`` section of your site as follows contains the +``sql`` module: .. code-block:: ini @@ -380,9 +391,10 @@ Debugging In this section we will explain how to debug your freeradius instance. Start freeradius in debug mode -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When debugging we suggest you to open up a dedicated terminal window to run freeradius in debug mode: +When debugging we suggest you to open up a dedicated terminal window to +run freeradius in debug mode: .. code-block:: shell @@ -394,7 +406,7 @@ When debugging we suggest you to open up a dedicated terminal window to run free freeradius -X Testing authentication and authorization -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can do this with ``radtest``: @@ -403,32 +415,36 @@ You can do this with ``radtest``: # radtest 10 radtest admin admin localhost 10 testing123 -A successful authentication will return similar output:: +A successful authentication will return similar output: + +:: Sent Access-Request Id 215 from 0.0.0.0:34869 to 127.0.0.1:1812 length 75 - User-Name = "admin" - User-Password = "admin" - NAS-IP-Address = 127.0.0.1 - NAS-Port = 10 - Message-Authenticator = 0x00 - Cleartext-Password = "admin" + User-Name = "admin" + User-Password = "admin" + NAS-IP-Address = 127.0.0.1 + NAS-Port = 10 + Message-Authenticator = 0x00 + Cleartext-Password = "admin" Received Access-Accept Id 215 from 127.0.0.1:1812 to 0.0.0.0:0 length 20 -While an unsuccessful one will look like the following:: +While an unsuccessful one will look like the following: + +:: Sent Access-Request Id 85 from 0.0.0.0:51665 to 127.0.0.1:1812 length 73 - User-Name = "foo" - User-Password = "bar" - NAS-IP-Address = 127.0.0.1 - NAS-Port = 10 - Message-Authenticator = 0x00 - Cleartext-Password = "bar" + User-Name = "foo" + User-Password = "bar" + NAS-IP-Address = 127.0.0.1 + NAS-Port = 10 + Message-Authenticator = 0x00 + Cleartext-Password = "bar" Received Access-Reject Id 85 from 127.0.0.1:1812 to 0.0.0.0:0 length 20 (0) -: Expected Access-Accept got Access-Reject -Alternatively, you can use ``radclient`` which allows more complex tests; in the following -example we show how to test an authentication request which includes ``Called-Station-ID`` -and ``Calling-Station-ID``: +Alternatively, you can use ``radclient`` which allows more complex tests; +in the following example we show how to test an authentication request +which includes ``Called-Station-ID`` and ``Calling-Station-ID``: .. code-block:: shell @@ -440,10 +456,12 @@ and ``Calling-Station-ID``: echo $request | radclient localhost auth testing123 Testing accounting -^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~ -You can do this with ``radclient``, but first of all you will have to create a text file -like the following one:: +You can do this with ``radclient``, but first of all you will have to +create a text file like the following one: + +:: # /tmp/accounting.txt @@ -470,29 +488,32 @@ Then you can call ``radclient``: radclient -f /tmp/accounting.txt -x 127.0.0.1 acct testing123 -You should get the following output:: +You should get the following output: + +:: Sent Accounting-Request Id 83 from 0.0.0.0:51698 to 127.0.0.1:1813 length 154 - Acct-Session-Id = "35000006" - User-Name = "jim" - NAS-IP-Address = 172.16.64.91 - NAS-Port = 1 - NAS-Port-Type = Async - Acct-Status-Type = Interim-Update - Acct-Authentic = RADIUS - Service-Type = Login-User - Login-Service = Telnet - Login-IP-Host = 172.16.64.25 - Acct-Delay-Time = 0 - Acct-Session-Time = 261 - Acct-Input-Octets = 9900909 - Acct-Output-Octets = 1511075509 - Called-Station-Id = "00-27-22-F3-FA-F1:hostname" - Calling-Station-Id = "5c:7d:c1:72:a7:3b" + Acct-Session-Id = "35000006" + User-Name = "jim" + NAS-IP-Address = 172.16.64.91 + NAS-Port = 1 + NAS-Port-Type = Async + Acct-Status-Type = Interim-Update + Acct-Authentic = RADIUS + Service-Type = Login-User + Login-Service = Telnet + Login-IP-Host = 172.16.64.25 + Acct-Delay-Time = 0 + Acct-Session-Time = 261 + Acct-Input-Octets = 9900909 + Acct-Output-Octets = 1511075509 + Called-Station-Id = "00-27-22-F3-FA-F1:hostname" + Calling-Station-Id = "5c:7d:c1:72:a7:3b" Received Accounting-Response Id 83 from 127.0.0.1:1813 to 0.0.0.0:0 length 20 Customizing your configuration ------------------------------ -You can further customize your freeradius configuration and exploit the many features of freeradius but -you will need to test how your configuration plays with *openwisp-radius*. +You can further customize your freeradius configuration and exploit the +many features of freeradius but you will need to test how your +configuration plays with *openwisp-radius*. diff --git a/docs/source/developer/freeradius_wpa_enterprise.rst b/docs/source/developer/freeradius_wpa_enterprise.rst index 5d63e8be..879f0acb 100644 --- a/docs/source/developer/freeradius_wpa_enterprise.rst +++ b/docs/source/developer/freeradius_wpa_enterprise.rst @@ -1,33 +1,30 @@ -================================================================= Freeradius Setup for WPA Enterprise (EAP-TTLS-PAP) authentication ================================================================= -This guide explains how to install and configure -`freeradius 3 `_ -in order to make it work with -`OpenWISP RADIUS `_ -for WPA Enterprise EAP-TTLS-PAP authentication. - -The setup will allow users to authenticate via WiFi WPA Enterprise networks -using their personal username and password of their django user accounts. -Users can either be created manually via the admin interface, -:ref:`generated `, -:ref:`imported from CSV `, -or can self register through a web page which makes use of the -:ref:`registration REST API ` -(like `openwisp-wifi-login-pages +This guide explains how to install and configure `freeradius 3 +`_ in order to make it work with `OpenWISP RADIUS +`_ for WPA Enterprise +EAP-TTLS-PAP authentication. + +The setup will allow users to authenticate via WiFi WPA Enterprise +networks using their personal username and password of their django user +accounts. Users can either be created manually via the admin interface, +:ref:`generated `, :ref:`imported from CSV +`, or can self register through a web page which makes +use of the :ref:`registration REST API ` (like +`openwisp-wifi-login-pages `_). Prerequisites ------------- -Execute the steps explained in the following sections -of the :ref:`freeradius guide for captive portal authentication +Execute the steps explained in the following sections of the +:ref:`freeradius guide for captive portal authentication `: - * How to install freeradius 3 - * Enable the configured modules - * Configure the REST module + - How to install freeradius 3 + - Enable the configured modules + - Configure the REST module Then proceed with the rest of the document. @@ -37,10 +34,10 @@ Freeradius configuration .. _freeradius_site_wpa_enterprise: Configure the sites -^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~ Main sites -~~~~~~~~~~ +++++++++++ In this scenario it is necessary to set up one FreeRADIUS site for each organization you want to support, each FreeRADIUS instance will therefore @@ -49,10 +46,10 @@ and a related inner tunnel configuration. Let's create the site for an hypotethical organization called org-A. -Don't forget to substitute the occurrences of -```` and ```` with -the UUID & Radius API token of each organization, refer to the section -:ref:`organization_uuid_token` for finding these values. +Don't forget to substitute the occurrences of ```` and +```` with the UUID & Radius API token of each +organization, refer to the section :ref:`organization_uuid_token` for +finding these values. .. code-block:: ini @@ -119,7 +116,8 @@ the UUID & Radius API token of each organization, refer to the section } } -Please also ensure that ``acct_unique`` is present in the ``pre-accounting`` section: +Please also ensure that ``acct_unique`` is present in the +``pre-accounting`` section: .. code-block:: ini @@ -130,7 +128,7 @@ Please also ensure that ``acct_unique`` is present in the ``pre-accounting`` sec } Inner tunnels -~~~~~~~~~~~~~ ++++++++++++++ You will need to set up one inner tunnel for each organization too. @@ -192,11 +190,13 @@ Following the example for a hypotetical organization named org-A: } Configure the EAP modules -^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~ .. note:: + Keep in mind these are basic sample configurations, once you get it - working feel free to tweak it to make it more secure and fully featured. + working feel free to tweak it to make it more secure and fully + featured. You will need to set up one EAP module instance for each organization too. @@ -246,10 +246,10 @@ Following the example for a hypotetical organization named org-A: Repeating the steps for more organizations ------------------------------------------ -Let's say you don't have only the hypotetical org-A in your system -but more organizations, in that case you simply have to repeat -the steps explained in the previous sections, substituting the occurrences -of org-A with the names of the other organizations. +Let's say you don't have only the hypotetical org-A in your system but +more organizations, in that case you simply have to repeat the steps +explained in the previous sections, substituting the occurrences of org-A +with the names of the other organizations. So if you have an organization named ACME Systems, copy the files and substitute the occurrences ``org_a`` with ``acme_systems``. @@ -257,9 +257,9 @@ substitute the occurrences ``org_a`` with ``acme_systems``. Final steps ----------- -Once the configurations are ready, you should -:ref:`restart freeradius ` -and :ref:`then test/troubleshoot/debug your setup `. +Once the configurations are ready, you should :ref:`restart freeradius +` and :ref:`then test/troubleshoot/debug your setup +`. Implementing other EAP scenarios -------------------------------- @@ -268,11 +268,10 @@ Implementing other setups like EAP-TLS requires additional development effort. `OpenWISP Controller `_ -already supports x509 certificates, so it would be -a matter of integrating the -`django-x509 `_ -module into OpenWISP RADIUS and then implement mechanisms for the users -to securely download their certificates. - -If you're interested in this feature, let us know via the -:ref:`support channels `. +already supports x509 certificates, so it would be a matter of integrating +the `django-x509 `_ module into +OpenWISP RADIUS and then implement mechanisms for the users to securely +download their certificates. + +If you're interested in this feature, let us know via the :ref:`support +channels `. diff --git a/docs/source/developer/how_to_extend.rst b/docs/source/developer/how_to_extend.rst index 50b74d79..60ed4757 100644 --- a/docs/source/developer/how_to_extend.rst +++ b/docs/source/developer/how_to_extend.rst @@ -1,30 +1,34 @@ -========================= Extending openwisp-radius ========================= -One of the core values of the OpenWISP project is `Software Reusability `_, -for this reason *openwisp-radius* provides a set of base classes -which can be imported, extended and reused to create derivative apps. - -In order to implement your custom version of *openwisp-radius*, -you need to perform the steps described in this section. - -When in doubt, the code in the `test project `_ and -the `sample app `_ -will serve you as source of truth: -just replicate and adapt that code to get a basic derivative of -*openwisp-radius* working. - -If you want to add new users fields, please follow the `tutorial to extend the -openwisp-users `_. -As an example, we have extended *openwisp-users* to *sample_users* app and +One of the core values of the OpenWISP project is `Software Reusability +`_, +for this reason *openwisp-radius* provides a set of base classes which can +be imported, extended and reused to create derivative apps. + +In order to implement your custom version of *openwisp-radius*, you need +to perform the steps described in this section. + +When in doubt, the code in the `test project +`_ +and the `sample app +`_ +will serve you as source of truth: just replicate and adapt that code to +get a basic derivative of *openwisp-radius* working. + +If you want to add new users fields, please follow the `tutorial to extend +the openwisp-users +`_. As +an example, we have extended *openwisp-users* to *sample_users* app and added a field ``social_security_number`` in the `sample_users/models.py `_. .. note:: + **Premise**: if you plan on using a customized version of this module, - we suggest to start with it since the beginning, because migrating your data - from the default module to your extended version may be time consuming. + we suggest to start with it since the beginning, because migrating + your data from the default module to your extended version may be time + consuming. 1. Initialize your custom module -------------------------------- @@ -32,19 +36,22 @@ added a field ``social_security_number`` in the `sample_users/models.py The first thing you need to do is to create a new django app which will contain your custom version of *openwisp-radius*. -A django app is nothing more than a -`python package `_ -(a directory of python scripts), in the following examples we'll call this django app -``myradius``, but you can name it how you want:: +A django app is nothing more than a `python package +`_ (a directory +of python scripts), in the following examples we'll call this django app +``myradius``, but you can name it how you want: + +:: django-admin startapp myradius -Keep in mind that the command mentioned above must be called from a directory -which is available in your `PYTHON_PATH `_ -so that you can then import the result into your project. +Keep in mind that the command mentioned above must be called from a +directory which is available in your `PYTHON_PATH +`_ so that +you can then import the result into your project. -Now you need to add ``myradius`` to ``INSTALLED_APPS`` in your ``settings.py``, -ensuring also that ``openwisp_radius`` has been removed: +Now you need to add ``myradius`` to ``INSTALLED_APPS`` in your +``settings.py``, ensuring also that ``openwisp_radius`` has been removed: .. code-block:: python @@ -53,57 +60,63 @@ ensuring also that ``openwisp_radius`` has been removed: INSTALLED_APPS = [ # ... other apps ... # openwisp admin theme - 'openwisp_utils.admin_theme', + "openwisp_utils.admin_theme", # all-auth - 'django.contrib.sites', - 'allauth', - 'allauth.account', - 'allauth.socialaccount', + "django.contrib.sites", + "allauth", + "allauth.account", + "allauth.socialaccount", # admin - 'django.contrib.admin', + "django.contrib.admin", # rest framework - 'rest_framework', - 'django_filters', + "rest_framework", + "django_filters", # registration - 'rest_framework.authtoken', - 'dj_rest_auth', - 'dj_rest_auth.registration', + "rest_framework.authtoken", + "dj_rest_auth", + "dj_rest_auth.registration", # social login - 'allauth.socialaccount.providers.facebook', # optional, can be removed if social login is not needed - 'allauth.socialaccount.providers.google', # optional, can be removed if social login is not needed + "allauth.socialaccount.providers.facebook", # optional, can be removed if social login is not needed + "allauth.socialaccount.providers.google", # optional, can be removed if social login is not needed # SAML login - 'djangosaml2', # optional, can be removed if SAML login is not needed + "djangosaml2", # optional, can be removed if SAML login is not needed # openwisp # 'myradius', <-- replace with your app-name here - 'openwisp_users', - 'private_storage', - 'drf_yasg' + "openwisp_users", + "private_storage", + "drf_yasg", ] SITE_ID = 1 - MEDIA_ROOT = os.path.join(BASE_DIR, 'media') - PRIVATE_STORAGE_ROOT = os.path.join(MEDIA_ROOT, 'private') + MEDIA_ROOT = os.path.join(BASE_DIR, "media") + PRIVATE_STORAGE_ROOT = os.path.join(MEDIA_ROOT, "private") AUTHENTICATION_BACKENDS = ( - 'openwisp_users.backends.UsersAuthenticationBackend', - 'openwisp_radius.saml.backends.OpenwispRadiusSaml2Backend', # optional, can be removed if SAML login is not needed + "openwisp_users.backends.UsersAuthenticationBackend", + "openwisp_radius.saml.backends.OpenwispRadiusSaml2Backend", # optional, can be removed if SAML login is not needed ) .. important:: + Remember to include your radius app's name before proceeding. .. note:: - For more information about how to work with django projects and django apps, please refer - to the `django documentation `_. + + For more information about how to work with django projects and django + apps, please refer to the `django documentation + `_. 2. Install ``openwisp-radius`` ------------------------------ -Install (and add to the requirement of your project) openwisp-radius:: +Install (and add to the requirement of your project) openwisp-radius: + +:: pip install openwisp-radius .. note:: + Use ``pip install openwisp-radius[saml]`` if you intend to use :ref:`Single Sign-On (SAML) ` feature. @@ -114,7 +127,7 @@ Add the following to your ``settings.py``: .. code-block:: python - EXTENDED_APPS = ('openwisp_radius',) + EXTENDED_APPS = ("openwisp_radius",) 4. Add ``openwisp_utils.staticfiles.DependencyFinder`` ------------------------------------------------------ @@ -125,34 +138,34 @@ Add ``openwisp_utils.staticfiles.DependencyFinder`` to .. code-block:: python STATICFILES_FINDERS = [ - 'django.contrib.staticfiles.finders.FileSystemFinder', - 'django.contrib.staticfiles.finders.AppDirectoriesFinder', - 'openwisp_utils.staticfiles.DependencyFinder', + "django.contrib.staticfiles.finders.FileSystemFinder", + "django.contrib.staticfiles.finders.AppDirectoriesFinder", + "openwisp_utils.staticfiles.DependencyFinder", ] 5. Add ``openwisp_utils.loaders.DependencyLoader`` -------------------------------------------------- -Add ``openwisp_utils.loaders.DependencyLoader`` to ``TEMPLATES`` -in your ``settings.py``, but ensure it comes before +Add ``openwisp_utils.loaders.DependencyLoader`` to ``TEMPLATES`` in your +``settings.py``, but ensure it comes before ``django.template.loaders.app_directories.Loader``: .. code-block:: 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', + "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', + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", ], }, } @@ -163,90 +176,114 @@ in your ``settings.py``, but ensure it comes before Please refer to the following files in the sample app of the test project: -- `sample_radius/__init__.py `_ -- `sample_radius/apps.py `_ +- `sample_radius/__init__.py + `_ +- `sample_radius/apps.py + `_ You have to replicate and adapt that code in your project. .. note:: - For more information regarding the concept of ``AppConfig`` please refer to - the `"Applications" section in the django documentation `_. + + For more information regarding the concept of ``AppConfig`` please + refer to the `"Applications" section in the django documentation + `_. 7. Create your custom models ---------------------------- -For the purpose of showing an example, we added a simple ``details`` field to the -`models of the sample app in the test project `_. +For the purpose of showing an example, we added a simple ``details`` field +to the `models of the sample app in the test project +`_. You can add fields in a similar way in your ``models.py`` file. .. note:: - For doubts regarding how to use, extend or develop models please refer to the - `"Models" section in the django documentation `_. + + For doubts regarding how to use, extend or develop models please refer + to the `"Models" section in the django documentation + `_. 8. Add swapper configurations ----------------------------- -Once you have created the models, add the following to your ``settings.py``: +Once you have created the models, add the following to your +``settings.py``: .. code-block:: python # Setting models for swapper module - OPENWISP_RADIUS_RADIUSREPLY_MODEL = 'myradius.RadiusReply' - OPENWISP_RADIUS_RADIUSGROUPREPLY_MODEL = 'myradius.RadiusGroupReply' - OPENWISP_RADIUS_RADIUSCHECK_MODEL = 'myradius.RadiusCheck' - OPENWISP_RADIUS_RADIUSGROUPCHECK_MODEL = 'myradius.RadiusGroupCheck' - OPENWISP_RADIUS_RADIUSACCOUNTING_MODEL = 'myradius.RadiusAccounting' - OPENWISP_RADIUS_NAS_MODEL = 'myradius.Nas' - OPENWISP_RADIUS_RADIUSUSERGROUP_MODEL = 'myradius.RadiusUserGroup' - OPENWISP_RADIUS_RADIUSPOSTAUTH_MODEL = 'myradius.RadiusPostAuth' - OPENWISP_RADIUS_RADIUSBATCH_MODEL = 'myradius.RadiusBatch' - OPENWISP_RADIUS_RADIUSGROUP_MODEL = 'myradius.RadiusGroup' - OPENWISP_RADIUS_RADIUSTOKEN_MODEL = 'myradius.RadiusToken' - OPENWISP_RADIUS_PHONETOKEN_MODEL = 'myradius.PhoneToken' - OPENWISP_RADIUS_ORGANIZATIONRADIUSSETTINGS_MODEL = 'myradius.OrganizationRadiusSettings' - OPENWISP_RADIUS_REGISTEREDUSER_MODEL = 'myradius.RegisteredUser' + OPENWISP_RADIUS_RADIUSREPLY_MODEL = "myradius.RadiusReply" + OPENWISP_RADIUS_RADIUSGROUPREPLY_MODEL = "myradius.RadiusGroupReply" + OPENWISP_RADIUS_RADIUSCHECK_MODEL = "myradius.RadiusCheck" + OPENWISP_RADIUS_RADIUSGROUPCHECK_MODEL = "myradius.RadiusGroupCheck" + OPENWISP_RADIUS_RADIUSACCOUNTING_MODEL = "myradius.RadiusAccounting" + OPENWISP_RADIUS_NAS_MODEL = "myradius.Nas" + OPENWISP_RADIUS_RADIUSUSERGROUP_MODEL = "myradius.RadiusUserGroup" + OPENWISP_RADIUS_RADIUSPOSTAUTH_MODEL = "myradius.RadiusPostAuth" + OPENWISP_RADIUS_RADIUSBATCH_MODEL = "myradius.RadiusBatch" + OPENWISP_RADIUS_RADIUSGROUP_MODEL = "myradius.RadiusGroup" + OPENWISP_RADIUS_RADIUSTOKEN_MODEL = "myradius.RadiusToken" + OPENWISP_RADIUS_PHONETOKEN_MODEL = "myradius.PhoneToken" + OPENWISP_RADIUS_ORGANIZATIONRADIUSSETTINGS_MODEL = ( + "myradius.OrganizationRadiusSettings" + ) + OPENWISP_RADIUS_REGISTEREDUSER_MODEL = "myradius.RegisteredUser" # You will need to change AUTH_USER_MODEL if you are extending openwisp_users - AUTH_USER_MODEL = 'openwisp_users.User' + AUTH_USER_MODEL = "openwisp_users.User" Substitute ``myradius`` with the name you chose in step 1. 9. Create database migrations ----------------------------- -Copy the `migration files from the sample_radius's migration folder `_. +Copy the `migration files from the sample_radius's migration folder +`_. +Now, create database migrations as per your custom application's +requirements: -Now, create database migrations as per your custom application's requirements:: +:: ./manage.py makemigrations -If you are starting with a fresh database, you can apply the migrations:: +If you are starting with a fresh database, you can apply the migrations: + +:: ./manage.py migrate -However, if you want :ref:`migrate an existing freeradius database please read the guide in the setup `. +However, if you want :ref:`migrate an existing freeradius database please +read the guide in the setup `. .. note:: - For more information, refer to the - `"Migrations" section in the django documentation `_. + + For more information, refer to the `"Migrations" section in the django + documentation + `_. 10. Create the admin -------------------- -Refer to the `admin.py file of the sample app `_. +Refer to the `admin.py file of the sample app +`_. -To introduce changes to the admin, you can do it in two main ways which are described below. +To introduce changes to the admin, you can do it in two main ways which +are described below. .. note:: - For more information regarding how the django admin works, or how it can be customized, please refer to - `"The django admin site" section in the django documentation `_. + + For more information regarding how the django admin works, or how it + can be customized, please refer to `"The django admin site" section in + the django documentation + `_. 1. Monkey patching -^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~ -If the changes you need to add are relatively small, you can resort to monkey patching. +If the changes you need to add are relatively small, you can resort to +monkey patching. For example: @@ -264,13 +301,14 @@ For example: RadiusPostAuthAdmin, RadiusBatchAdmin, ) + # NasAdmin.fields += ['example_field'] <-- Monkey patching changes example 2. Inheriting admin classes -^^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If you need to introduce significant changes and/or you don't want to resort to -monkey patching, you can proceed as follows: +If you need to introduce significant changes and/or you don't want to +resort to monkey patching, you can proceed as follows: .. code-block:: python @@ -288,18 +326,21 @@ monkey patching, you can proceed as follows: RadiusBatchAdmin as BaseRadiusBatchAdmin, ) from swapper import load_model - Nas = load_model('openwisp_radius', 'Nas') - RadiusAccounting = load_model('openwisp_radius', 'RadiusAccounting') - RadiusBatch = load_model('openwisp_radius', 'RadiusBatch') - RadiusCheck = load_model('openwisp_radius', 'RadiusCheck') - RadiusGroup = load_model('openwisp_radius', 'RadiusGroup') - RadiusPostAuth = load_model('openwisp_radius', 'RadiusPostAuth') - RadiusReply = load_model('openwisp_radius', 'RadiusReply') - PhoneToken = load_model('openwisp_radius', 'PhoneToken') - RadiusGroupCheck = load_model('openwisp_radius', 'RadiusGroupCheck') - RadiusGroupReply = load_model('openwisp_radius', 'RadiusGroupReply') - RadiusUserGroup = load_model('openwisp_radius', 'RadiusUserGroup') - OrganizationRadiusSettings = load_model('openwisp_radius', 'OrganizationRadiusSettings') + + Nas = load_model("openwisp_radius", "Nas") + RadiusAccounting = load_model("openwisp_radius", "RadiusAccounting") + RadiusBatch = load_model("openwisp_radius", "RadiusBatch") + RadiusCheck = load_model("openwisp_radius", "RadiusCheck") + RadiusGroup = load_model("openwisp_radius", "RadiusGroup") + RadiusPostAuth = load_model("openwisp_radius", "RadiusPostAuth") + RadiusReply = load_model("openwisp_radius", "RadiusReply") + PhoneToken = load_model("openwisp_radius", "PhoneToken") + RadiusGroupCheck = load_model("openwisp_radius", "RadiusGroupCheck") + RadiusGroupReply = load_model("openwisp_radius", "RadiusGroupReply") + RadiusUserGroup = load_model("openwisp_radius", "RadiusUserGroup") + OrganizationRadiusSettings = load_model( + "openwisp_radius", "OrganizationRadiusSettings" + ) User = get_user_model() admin.site.unregister(RadiusCheck) @@ -313,89 +354,120 @@ monkey patching, you can proceed as follows: admin.site.unregister(RadiusPostAuth) admin.site.unregister(RadiusBatch) + @admin.register(RadiusCheck) class RadiusCheckAdmin(BaseRadiusCheckAdmin): + pass # add your changes here + @admin.register(RadiusReply) class RadiusReplyAdmin(BaseRadiusReplyAdmin): + pass # add your changes here + @admin.register(RadiusAccounting) class RadiusAccountingAdmin(BaseRadiusAccountingAdmin): + pass # add your changes here + @admin.register(Nas) class NasAdmin(BaseNasAdmin): + pass # add your changes here + @admin.register(RadiusGroup) class RadiusGroupAdmin(BaseRadiusGroupAdmin): + pass # add your changes here + @admin.register(RadiusUserGroup) class RadiusUserGroupAdmin(BaseRadiusUserGroupAdmin): + pass # add your changes here + @admin.register(RadiusGroupCheck) class RadiusGroupCheckAdmin(BaseRadiusGroupCheckAdmin): + pass # add your changes here + @admin.register(RadiusGroupReply) class RadiusGroupReplyAdmin(BaseRadiusGroupReplyAdmin): + pass # add your changes here + @admin.register(RadiusPostAuth) class RadiusPostAuthAdmin(BaseRadiusPostAuthAdmin): + pass # add your changes here + @admin.register(RadiusBatch) class RadiusBatchAdmin(BaseRadiusBatchAdmin): + pass # add your changes here 11. Setup Freeradius API Allowed Hosts -------------------------------------- -Add allowed freeradius hosts in ``settings.py``: +Add allowed freeradius hosts in ``settings.py``: .. code-block:: python - OPENWISP_RADIUS_FREERADIUS_ALLOWED_HOSTS = ['127.0.0.1'] + OPENWISP_RADIUS_FREERADIUS_ALLOWED_HOSTS = ["127.0.0.1"] .. note:: + Read more about :ref:`freeradius allowed hosts in settings page `. 12. Setup Periodic tasks ------------------------ -Some periodic commands are required in production environments to enable certain -features and facilitate database cleanup: +Some periodic commands are required in production environments to enable +certain features and facilitate database cleanup: + +1. You need to create a `celery configuration file as it's created in + example file + `_. -1. You need to create a `celery configuration file as it's created in example file `_. +2. In the settings.py, `configure the CELERY_BEAT_SCHEDULE +`_. +Some celery tasks take an argument, for instance ``365`` is given here for +``delete_old_radacct`` in the example settings. These arguments are passed +to their respective management commands. More information about these +parameters can be found at the :ref:`management commands page +`. -2. In the settings.py, `configure the CELERY_BEAT_SCHEDULE `_. Some celery tasks take an argument, for instance -``365`` is given here for ``delete_old_radacct`` in the example settings. -These arguments are passed to their respective management commands. More information about these parameters can be -found at the :ref:`management commands page `. +3. Add the following in your settings.py file: -3. Add the following in your settings.py file:: + :: - CELERY_IMPORTS = ('openwisp_monitoring.device.tasks',) + CELERY_IMPORTS = ('openwisp_monitoring.device.tasks',) .. note:: - Celery tasks do not start with django server and need to be - started seperately, please read about running :ref:`celery and - celery-beat ` tasks. + + Celery tasks do not start with django server and need to be started + seperately, please read about running :ref:`celery and celery-beat + ` tasks. 13. Create root URL configuration --------------------------------- -The root ``url.py`` file should have the following paths (please read the comments): +The root ``url.py`` file should have the following paths (please read the +comments): .. code-block:: python from openwisp_radius.urls import get_urls + # Only imported when views are extended. # from myradius.api.views import views as api_views # from myradius.social.views import views as social_views @@ -403,32 +475,41 @@ The root ``url.py`` file should have the following paths (please read the commen urlpatterns = [ # ... other urls in your project ... - path('admin/', admin.site.urls), + path("admin/", admin.site.urls), # openwisp-radius urls - path('accounts/', include('openwisp_users.accounts.urls')), - path('api/v1/', include('openwisp_utils.api.urls')), + path("accounts/", include("openwisp_users.accounts.urls")), + path("api/v1/", include("openwisp_utils.api.urls")), # Use only when extending views (dicussed below) # path('', include((get_urls(api_views, social_views, saml_views), 'radius'), namespace='radius')), - path('', include('openwisp_radius.urls', namespace='radius')), # Remove when extending views + path( + "", include("openwisp_radius.urls", namespace="radius") + ), # Remove when extending views ] + .. note:: - For more information about URL configuration in django, please refer to the - `"URL dispatcher" section in the django documentation `_. + + For more information about URL configuration in django, please refer + to the `"URL dispatcher" section in the django documentation + `_. 14. Import the automated tests ------------------------------ When developing a custom application based on this module, it's a good -idea to import and run the base tests too, so that you can be sure the changes -you're introducing are not breaking some of the existing features of *openwisp-radius*. +idea to import and run the base tests too, so that you can be sure the +changes you're introducing are not breaking some of the existing features +of *openwisp-radius*. -In case you need to add breaking changes, you can overwrite the tests defined -in the base classes to test your own behavior. +In case you need to add breaking changes, you can overwrite the tests +defined in the base classes to test your own behavior. -See the `tests of the sample app `_ +See the `tests of the sample app +`_ to find out how to do this. -You can then run tests with:: +You can then run tests with: + +:: # the --parallel flag is optional ./manage.py test --parallel myradius @@ -438,51 +519,63 @@ Substitute ``myradius`` with the name you chose in step 1. Other base classes that can be inherited and extended ----------------------------------------------------- -The following steps are not required and are intended for more advanced customization. +The following steps are not required and are intended for more advanced +customization. 1. Extending the API Views -^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~ -The API view classes can be extended into other django applications as well. Note -that it is not required for extending *openwisp-radius* to your app and this change -is required only if you plan to make changes to the API views. +The API view classes can be extended into other django applications as +well. Note that it is not required for extending *openwisp-radius* to your +app and this change is required only if you plan to make changes to the +API views. -Create a view file as done in `API views.py `_. +Create a view file as done in `API views.py +`_. -Remember to use these views in root URL configurations in point 11. -If you want only extend the API views and not social views, you can use +Remember to use these views in root URL configurations in point 11. If you +want only extend the API views and not social views, you can use ``get_urls(api_views, None)`` to get social_views from *openwisp_radius*. .. note:: - For more information about django views, please refer to the - `views section in the django documentation `_. + + For more information about django views, please refer to the `views + section in the django documentation + `_. 2. Extending the Social Views -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The social view classes can be extended into other django applications as well. Note -that it is not required for extending *openwisp-radius* to your app and this change -is required only if you plan to make changes to the social views. +The social view classes can be extended into other django applications as +well. Note that it is not required for extending *openwisp-radius* to your +app and this change is required only if you plan to make changes to the +social views. -Create a view file as done in `social views.py `_. +Create a view file as done in `social views.py +`_. -Remember to use these views in root URL configurations in point 11. -If you want only extend the API views and not social views, you can use +Remember to use these views in root URL configurations in point 11. If you +want only extend the API views and not social views, you can use ``get_urls(api_views, None)`` to get social_views from *openwisp_radius*. 3. Extending the SAML Views -^^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The SAML view classes can be extended into other django applications as well. Note -that it is not required for extending *openwisp-radius* to your app and this change -is required only if you plan to make changes to the SAML views. +The SAML view classes can be extended into other django applications as +well. Note that it is not required for extending *openwisp-radius* to your +app and this change is required only if you plan to make changes to the +SAML views. -Create a view file as done in `saml views.py `_. +Create a view file as done in `saml views.py +`_. -Remember to use these views in root URL configurations in point 11. -If you want only extend the API views and social view but not SAML views, you can use -``get_urls(api_views, social_views, None)`` to get saml_views from *openwisp_radius*. +Remember to use these views in root URL configurations in point 11. If you +want only extend the API views and social view but not SAML views, you can +use ``get_urls(api_views, social_views, None)`` to get saml_views from +*openwisp_radius*. .. note:: - For more information about django views, please refer to the - `views section in the django documentation `_. + + For more information about django views, please refer to the `views + section in the django documentation + `_. diff --git a/docs/source/developer/setup.rst b/docs/source/developer/setup.rst index b07aedf6..986ecde1 100644 --- a/docs/source/developer/setup.rst +++ b/docs/source/developer/setup.rst @@ -1,25 +1,29 @@ -===== Setup ===== Try the demo ------------ -**Need a quick overview?** `Try the OpenWISP Demo `_. +**Need a quick overview?** `Try the OpenWISP Demo +`_. Deploy it in production ----------------------- -An automated installer is available at -`ansible-openwisp2 `_. +An automated installer is available at `ansible-openwisp2 +`_. Create a virtual environment ---------------------------- -Please use a `python virtual environment `_. -It keeps everybody on the same page, helps reproducing bugs and resolving problems. +Please use a `python virtual environment +`_. It keeps everybody on the +same page, helps reproducing bugs and resolving problems. -We highly suggest to use **virtualenvwrapper**, please refer to the official `virtualenvwrapper installation page `_ and come back here when ready to proceed. +We highly suggest to use **virtualenvwrapper**, please refer to the +official `virtualenvwrapper installation page +`_ and +come back here when ready to proceed. .. code-block:: shell @@ -27,17 +31,22 @@ We highly suggest to use **virtualenvwrapper**, please refer to the official `vi mkvirtualenv radius .. note:: - If you encounter an error like ``Python could not import the module virtualenvwrapper``, - add ``VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3`` and run ``source virtualenvwrapper.sh`` again :) + + If you encounter an error like ``Python could not import the module + virtualenvwrapper``, add ``VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3`` + and run ``source virtualenvwrapper.sh`` again :) Install required system packages -------------------------------- Install packages required by Weasyprint for your OS: - - `Linux `_ - - `MacOS `_ - - `Windows `_ + - `Linux + `_ + - `MacOS + `_ + - `Windows + `_ Install stable version from pypi -------------------------------- @@ -86,78 +95,80 @@ If you want to contribute, install your cloned fork: Setup (integrate in an existing django project) ----------------------------------------------- -The ``settings.py`` file of your project should have at least the following -modules listed ``INSTALLED_APPS``: +The ``settings.py`` file of your project should have at least the +following modules listed ``INSTALLED_APPS``: .. code-block:: python INSTALLED_APPS = [ - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'django.contrib.humanize', + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", + "django.contrib.humanize", # openwisp admin theme - 'openwisp_utils.admin_theme', + "openwisp_utils.admin_theme", # all-auth - 'django.contrib.sites', - 'allauth', - 'allauth.account', + "django.contrib.sites", + "allauth", + "allauth.account", # admin - 'django.contrib.admin', + "django.contrib.admin", # rest framework - 'rest_framework', - 'django_filters', + "rest_framework", + "django_filters", # registration - 'rest_framework.authtoken', - 'dj_rest_auth', - 'dj_rest_auth.registration', + "rest_framework.authtoken", + "dj_rest_auth", + "dj_rest_auth.registration", # openwisp radius - 'openwisp_radius', - 'openwisp_users', - 'private_storage', - 'drf_yasg', + "openwisp_radius", + "openwisp_users", + "private_storage", + "drf_yasg", ] -These modules are optional, add them only if you need the -:ref:`social login ` feature: +These modules are optional, add them only if you need the :ref:`social +login ` feature: .. code-block:: python INSTALLED_APPS += [ # social login - 'allauth.socialaccount', - 'allauth.socialaccount.providers.facebook', - 'allauth.socialaccount.providers.google', + "allauth.socialaccount", + "allauth.socialaccount.providers.facebook", + "allauth.socialaccount.providers.google", ] Add media locations in ``settings.py``: .. code-block:: python - MEDIA_ROOT = os.path.join(BASE_DIR, 'media') - PRIVATE_STORAGE_ROOT = os.path.join(MEDIA_ROOT, 'private') + MEDIA_ROOT = os.path.join(BASE_DIR, "media") + PRIVATE_STORAGE_ROOT = os.path.join(MEDIA_ROOT, "private") -Also, add ``AUTH_USER_MODEL``, ``AUTHENTICATION_BACKENDS`` and ``SITE_ID`` to -your ``settings.py``: +Also, add ``AUTH_USER_MODEL``, ``AUTHENTICATION_BACKENDS`` and ``SITE_ID`` +to your ``settings.py``: .. code-block:: python - AUTH_USER_MODEL = 'openwisp_users.User' + AUTH_USER_MODEL = "openwisp_users.User" SITE_ID = 1 AUTHENTICATION_BACKENDS = ( - 'openwisp_users.backends.UsersAuthenticationBackend', + "openwisp_users.backends.UsersAuthenticationBackend", ) -Add allowed freeradius hosts in ``settings.py``: +Add allowed freeradius hosts in ``settings.py``: .. code-block:: python - OPENWISP_RADIUS_FREERADIUS_ALLOWED_HOSTS = ['127.0.0.1'] + OPENWISP_RADIUS_FREERADIUS_ALLOWED_HOSTS = ["127.0.0.1"] .. note:: - Read more about :ref:`freeradius allowed hosts in settings page `. + + Read more about :ref:`freeradius allowed hosts in settings page + `. Add the URLs to your main ``urls.py``: @@ -167,14 +178,13 @@ Add the URLs to your main ``urls.py``: urlpatterns = [ # ... other urls in your project ... - # django admin interface urls - path('admin/', admin.site.urls), + path("admin/", admin.site.urls), # openwisp-radius urls - path('api/v1/', include('openwisp_utils.api.urls')), - path('api/v1/', include('openwisp_users.api.urls')), - path('accounts/', include('openwisp_users.accounts.urls')), - path('', include('openwisp_radius.urls')) + path("api/v1/", include("openwisp_utils.api.urls")), + path("api/v1/", include("openwisp_users.api.urls")), + path("accounts/", include("openwisp_users.accounts.urls")), + path("", include("openwisp_radius.urls")), ] Then run: @@ -188,14 +198,14 @@ Then run: Migrating an existing freeradius database ----------------------------------------- -If you already have a freeradius 3 database with the default schema, you should -be able to use it with openwisp-radius (and extended apps) easily: +If you already have a freeradius 3 database with the default schema, you +should be able to use it with openwisp-radius (and extended apps) easily: 1. first of all, back up your existing database; 2. configure django to connect to your existing database; -3. fake the first migration (which only replicates the default freeradius schema) - and then launch the rest of migrations normally, see the examples below to - see how to do this. +3. fake the first migration (which only replicates the default freeradius + schema) and then launch the rest of migrations normally, see the + examples below to see how to do this. .. code-block:: shell @@ -205,35 +215,40 @@ be able to use it with openwisp-radius (and extended apps) easily: Automated periodic tasks ------------------------ -Some periodic commands are required in production environments to enable certain -features and facilitate database cleanup. -There are two ways to automate these tasks: +Some periodic commands are required in production environments to enable +certain features and facilitate database cleanup. There are two ways to +automate these tasks: 1. Celery-beat (Recommended Method) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -1. You need to create a `celery configuration file as it's created in example file `_. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +1. You need to create a `celery configuration file as it's created in + example file + `_. 2. Add celery to ``__init__.py`` of your project: .. code-block:: python from .celery import app as celery_app - __all__ = ['celery_app'] + __all__ = ["celery_app"] -3. In the settings.py, `configure the CELERY_BEAT_SCHEDULE `_. Some celery tasks take an argument, for instance -``365`` is given here for ``delete_old_radacct`` in the example settings. -These arguments are passed to their respective management commands. More information about these parameters can be -found at the `management commands page <../user/management_commands.html>`_. +3. In the settings.py, `configure the CELERY_BEAT_SCHEDULE +`_. +Some celery tasks take an argument, for instance ``365`` is given here for +``delete_old_radacct`` in the example settings. These arguments are passed +to their respective management commands. More information about these +parameters can be found at the `management commands page +<../user/management_commands.html>`_. .. note:: - Celery tasks do not start with django server and need to be - started seperately, please read about running `celery and - celery-beat <./setup.html#celery-usage>`_ tasks. + + Celery tasks do not start with django server and need to be started + seperately, please read about running `celery and celery-beat + <./setup.html#celery-usage>`_ tasks. 2. Crontab (Legacy Method) -^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~ Edit the crontab with: @@ -263,14 +278,14 @@ Add and modify the following lines accordingly: # 18 months (which is the default duration) 30 04 * * * /bin/python /manage.py delete_old_radiusbatch_users -Be sure to replace ```` with the absolute path to the Python -virtual environment. +Be sure to replace ```` with the absolute path to the +Python virtual environment. Also, change ```` to the directory where ``manage.py`` is. To get the absolute path to ``manage.py`` when openwisp-radius is -installed for development, navigate to the base directory of -the cloned fork. Then, run: +installed for development, navigate to the base directory of the cloned +fork. Then, run: .. code-block:: shell @@ -278,8 +293,9 @@ the cloned fork. Then, run: pwd .. note:: - More information can be found at the - :ref:`management commands page `. + + More information can be found at the :ref:`management commands page + `. .. _installing_for_development: @@ -305,7 +321,9 @@ Install mysqlclient: sudo apt install libmysqlclient-dev libssl-dev .. note:: - If you are on Debian 10 or 9 you may need to install ``default-libmysqlclient-dev`` instead + + If you are on Debian 10 or 9 you may need to install + ``default-libmysqlclient-dev`` instead Install xmlsec1: @@ -317,7 +335,7 @@ Install your forked repo: .. code-block:: shell -   git clone git://github.com//openwisp-radius + git clone git://github.com//openwisp-radius cd openwisp-radius/ pip install -e .[saml,openvpn_status] @@ -354,15 +372,17 @@ Run tests with: Celery Usage ------------ -To run celery, you need to start redis-server. You can `install redis on your machine -`_ or `install docker `_ -and run redis inside docker container: +To run celery, you need to start redis-server. You can `install redis on +your machine `_ or `install docker +`_ and run redis inside docker +container: .. code-block:: shell docker run -p 6379:6379 --name openwisp-redis -d redis:alpine -Run celery (it is recommended to use a tool like supervisord in production): +Run celery (it is recommended to use a tool like supervisord in +production): .. code-block:: shell diff --git a/docs/source/developer/signals.rst b/docs/source/developer/signals.rst index 23faea27..0b19244d 100644 --- a/docs/source/developer/signals.rst +++ b/docs/source/developer/signals.rst @@ -1,4 +1,3 @@ -======= Signals ======= @@ -16,5 +15,5 @@ Signals This signal is emitted every time the accounting REST API endpoint completes successfully, just before the response is returned. -The ``view`` argument can also be used to access the ``request`` -object i.e. ``view.request``. +The ``view`` argument can also be used to access the ``request`` object +i.e. ``view.request``. diff --git a/docs/source/general/goals.rst b/docs/source/general/goals.rst index b57b73ad..6525061a 100644 --- a/docs/source/general/goals.rst +++ b/docs/source/general/goals.rst @@ -1,15 +1,14 @@ -===================== Motivations and Goals ===================== -In this page we explain the goals of this project and the motivations -that led us on this path. +In this page we explain the goals of this project and the motivations that +led us on this path. Motivations ----------- -The old version of OpenWISP (which we call OpenWISP 1) had a freeradius module -which provided several interesting features: +The old version of OpenWISP (which we call OpenWISP 1) had a freeradius +module which provided several interesting features: - user registration - account verification with several methods @@ -20,45 +19,53 @@ which provided several interesting features: But it also had important problems: -- it was not written with automated testing in mind, so there was a lot of code which - the maintainers didn't want to touch because of fear of breaking existing features -- it was not written with an international user-base in mind, it contained a great - deal of code which was specific to a single country (Italy) -- it was hard to extend, even small changes required changing its core code +- it was not written with automated testing in mind, so there was a lot of + code which the maintainers didn't want to touch because of fear of + breaking existing features +- it was not written with an international user-base in mind, it contained + a great deal of code which was specific to a single country (Italy) +- it was hard to extend, even small changes required changing its core + code - the user management code was implemented in a different way compared to other openwisp1 modules, which added a lot of maintenance overhead -- it used outdated dependencies which over time became vulnerable and were hard to replace +- it used outdated dependencies which over time became vulnerable and were + hard to replace - **it did not perform hashing of user passwords** -- the documentation did not explain how to properly install and configure the software +- the documentation did not explain how to properly install and configure + the software Similar problems were affecting other modules of OpenWISP 1, that's why -over time we got convinced the best thing was to start fresh using best practices -since the start. +over time we got convinced the best thing was to start fresh using best +practices since the start. Project goals ------------- -The main aim of this project is to offer a web application and documentation -that helps people from all over the world to implement a wifi network -that can use freeradius to authenticate its users, either via captive portal -authentication or WPA2 enterprise, **BUT** this doesn't mean we want to -lock the software to this use case: we want to keep the software generic enough -so it can be useful to implement other use cases that are related to -networking connectivity and network management; **Just keep in mind our main -aim if you plan to contribute to openwisp-radius please**. +The main aim of this project is to offer a web application and +documentation that helps people from all over the world to implement a +wifi network that can use freeradius to authenticate its users, either via +captive portal authentication or WPA2 enterprise, **BUT** this doesn't +mean we want to lock the software to this use case: we want to keep the +software generic enough so it can be useful to implement other use cases +that are related to networking connectivity and network management; **Just +keep in mind our main aim if you plan to contribute to openwisp-radius +please**. Other goals are listed below: -* replace the user management system of OpenWISP 1 by providing a similar feature set -* provide a web interface to manage a freeradius database -* provide abstract models and admin classes that can be imported, extended and reused in third party apps -* provide ways to extend the logic of openwisp-radius without changing its core -* ensure the code is written with an international audience in mind -* maintain a very good automated test suite -* reuse the django user management logic which is very robust and stable -* ensure passwords are hashed with strong algorithms and freeradius can - authorize/authenticate using these hashes (that's why we recommend using the - ``rlm_rest`` freeradius module with the REST API of openwisp-radius) -* integrate openwisp-radius with the rest of the openwisp2 ecosystem -* provide good documentation on how to install the project, configure it with - freeradius and use its most important features +- replace the user management system of OpenWISP 1 by providing a similar + feature set +- provide a web interface to manage a freeradius database +- provide abstract models and admin classes that can be imported, extended + and reused in third party apps +- provide ways to extend the logic of openwisp-radius without changing its + core +- ensure the code is written with an international audience in mind +- maintain a very good automated test suite +- reuse the django user management logic which is very robust and stable +- ensure passwords are hashed with strong algorithms and freeradius can + authorize/authenticate using these hashes (that's why we recommend using + the ``rlm_rest`` freeradius module with the REST API of openwisp-radius) +- integrate openwisp-radius with the rest of the openwisp2 ecosystem +- provide good documentation on how to install the project, configure it + with freeradius and use its most important features diff --git a/docs/source/general/support.rst b/docs/source/general/support.rst index 840cbb8b..0e1c9880 100644 --- a/docs/source/general/support.rst +++ b/docs/source/general/support.rst @@ -1,11 +1,11 @@ .. _support: -======= Support ======= -The OpenWISP community is very active and offers best effort support through the official -`OpenWISP Support Channels `_. +The OpenWISP community is very active and offers best effort support +through the official `OpenWISP Support Channels +`_. .. raw:: html diff --git a/docs/source/index.rst b/docs/source/index.rst index 48170879..80fd17bf 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,69 +1,71 @@ -=============== openwisp-radius =============== .. image:: https://travis-ci.org/openwisp/openwisp-radius.svg?branch=master - :target: https://travis-ci.org/openwisp/openwisp-radius - :alt: CI build status + :target: https://travis-ci.org/openwisp/openwisp-radius + :alt: CI build status .. image:: https://coveralls.io/repos/github/openwisp/openwisp-radius/badge.svg?branch=master - :target: https://coveralls.io/github/openwisp/openwisp-radius?branch=master - :alt: Test Coverage + :target: https://coveralls.io/github/openwisp/openwisp-radius?branch=master + :alt: Test Coverage .. image:: https://img.shields.io/librariesio/release/github/openwisp/openwisp-radius - :target: https://libraries.io/github/openwisp/openwisp-radius#repository_dependencies - :alt: Dependency monitoring + :target: https://libraries.io/github/openwisp/openwisp-radius#repository_dependencies + :alt: Dependency monitoring .. image:: https://img.shields.io/gitter/room/nwjs/nw.js.svg - :target: https://gitter.im/openwisp/general - :alt: Chat + :target: https://gitter.im/openwisp/general + :alt: Chat .. image:: https://badge.fury.io/py/openwisp-radius.svg - :target: http://badge.fury.io/py/openwisp-radius - :alt: Pypi Version + :target: http://badge.fury.io/py/openwisp-radius + :alt: Pypi Version .. image:: https://pepy.tech/badge/openwisp-radius - :target: https://pepy.tech/project/openwisp-radius - :alt: Downloads + :target: https://pepy.tech/project/openwisp-radius + :alt: Downloads .. image:: https://img.shields.io/badge/code%20style-black-000000.svg - :target: https://pypi.org/project/black/ - :alt: code style: black + :target: https://pypi.org/project/black/ + :alt: code style: black -**OpenWISP-RADIUS** provides an admin interface to a -`freeradius `_ database and offers features -that are common in WiFi and ISP deployments. +**OpenWISP-RADIUS** provides an admin interface to a `freeradius +`_ database and offers features that are common +in WiFi and ISP deployments. -**Need a quick overview?** `Try the OpenWISP Demo `_. +**Need a quick overview?** `Try the OpenWISP Demo +`_. .. note:: - If you're building a public wifi service, we suggest - to take a look at `openwisp-wifi-login-pages `_, - which is built to work with openwisp-radius. + + If you're building a public wifi service, we suggest to take a look at + `openwisp-wifi-login-pages + `_, which is + built to work with openwisp-radius. .. image:: https://raw.githubusercontent.com/openwisp/openwisp2-docs/master/assets/design/openwisp-logo-black.svg - :target: http://openwisp.org + :target: http://openwisp.org .. toctree:: - :maxdepth: 2 + :maxdepth: 2 - /developer/setup - /developer/freeradius - /developer/freeradius_wpa_enterprise - /user/settings - /user/management_commands - /user/importing_users - /user/generating_users - /user/enforcing_limits - /user/registration - /user/social_login - /user/saml - /user/change_of_authorization - /user/api - /developer/signals - /developer/how_to_extend - /developer/captive_portal_mock.rst - /general/support - /developer/contributing - /general/goals - /general/changelog.rst + /developer/setup + /developer/freeradius + /developer/freeradius_wpa_enterprise + /user/settings + /user/management_commands + /user/importing_users + /user/generating_users + /user/enforcing_limits + /user/registration + /user/social_login + /user/saml + /user/change_of_authorization + /user/api + /developer/signals + /developer/how_to_extend + /developer/captive_portal_mock.rst + /general/support + /developer/contributing + /general/goals + /general/changelog.rst diff --git a/docs/source/user/api.rst b/docs/source/user/api.rst index 8286b3ae..40e53481 100644 --- a/docs/source/user/api.rst +++ b/docs/source/user/api.rst @@ -1,217 +1,231 @@ -================= API Documentation ================= .. contents:: **Table of Contents**: - :backlinks: none - :depth: 4 + :backlinks: none + :depth: 4 .. important:: - The REST API of openwisp-radius is enabled by default and may be turned off by - setting :ref:`OPENWISP_RADIUS_API ` to ``False``. + + The REST API of openwisp-radius is enabled by default and may be + turned off by setting :ref:`OPENWISP_RADIUS_API ` + to ``False``. Live documentation -****************** +------------------ .. image:: /images/swagger_api.png - :alt: Swagger API Documentation + :alt: Swagger API Documentation -A general live API documentation (following the OpenAPI specification) at ``/api/v1/docs/``. +A general live API documentation (following the OpenAPI specification) at +``/api/v1/docs/``. Browsable web interface -*********************** +----------------------- + .. image:: /images/drf_api_interface.png - :alt: API Interface + :alt: API Interface -Additionally, opening any of the endpoints :ref:`listed below ` -directly in the browser will show the `browsable API interface of Django-REST-Framework -`_, -which makes it even easier to find out the details of each endpoint. +Additionally, opening any of the endpoints :ref:`listed below +` directly in the browser will show the `browsable API +interface of Django-REST-Framework +`_, which +makes it even easier to find out the details of each endpoint. FreeRADIUS API Endpoints -************************ +------------------------ -The following section is dedicated to API endpoints that are designed -to be consumed by FreeRADIUS (:ref:`Authorize `, :ref:`Post Auth `, :ref:`Accounting `). +The following section is dedicated to API endpoints that are designed to +be consumed by FreeRADIUS (:ref:`Authorize `, :ref:`Post Auth +`, :ref:`Accounting `). .. important:: - These endpoints can be consumed only by hosts which have - been added to the :ref:`freeradius allowed hosts list + + These endpoints can be consumed only by hosts which have been added to + the :ref:`freeradius allowed hosts list `. .. _freeradius_api_authentication: FreeRADIUS API Authentication -============================= +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -There are 3 different methods with which the FreeRADIUS API endpoints -can authenticate incoming requests and understand to which organization -these requests belong. +There are 3 different methods with which the FreeRADIUS API endpoints can +authenticate incoming requests and understand to which organization these +requests belong. .. _radius_user_token: Radius User Token ------------------ ++++++++++++++++++ This method relies on the presence of a special token which was obtained -by the user when authenticating via the -:ref:`Obtain Auth Token View `, this means -the user would have to log in through something like a web form first. +by the user when authenticating via the :ref:`Obtain Auth Token View +`, this means the user would have to log in +through something like a web form first. The flow works as follows: -1. the user enters credentials in a login form belonging to a specific organization - and submits, the credentials are then sent to the :ref:`Obtain Auth Token View `; -2. if credentials are correct, a **radius user token** associated to the user - and organization is created and returned in the response; -3. the login page or app must then initiate the HTTP request to the web server - of the captive portal, - (the URL of the form action of the default captive login page) - using the radius user token as password, example: +1. the user enters credentials in a login form belonging to a specific + organization and submits, the credentials are then sent to the + :ref:`Obtain Auth Token View `; +2. if credentials are correct, a **radius user token** associated to the + user and organization is created and returned in the response; +3. the login page or app must then initiate the HTTP request to the web + server of the captive portal, (the URL of the form action of the + default captive login page) using the radius user token as password, + example: .. code-block:: text curl -X POST http://captive.projcect.com:8005/index.php?zone=myorg \ -d "auth_user=&auth_pass=" -This method is recommended if you are using multiple organizations -in the same OpenWISP instance. +This method is recommended if you are using multiple organizations in the +same OpenWISP instance. .. note:: + By default, ```` is valid for authentication for one request only and a new ```` needs to be `obtained for - each request <#login-obtain-user-auth-token>`_. - However, if `OPENWISP_RADIUS_DISPOSABLE_RADIUS_USER_TOKEN - <./settings.html#openwisp-radius-disposable-radius-user-token>`_ - is set to ``False``, the ```` is valid for authentication - as long as freeradius accounting ``Stop`` request is not sent - or the token is not deleted. + each request <#login-obtain-user-auth-token>`_. However, if + `OPENWISP_RADIUS_DISPOSABLE_RADIUS_USER_TOKEN + <./settings.html#openwisp-radius-disposable-radius-user-token>`_ is + set to ``False``, the ```` is valid for authentication + as long as freeradius accounting ``Stop`` request is not sent or the + token is not deleted. .. warning:: - If you are using Radius User token method, keep in mind that one - user account can only authenticate with one organization - at a time, i.e a single user account cannot consume - services from multiple organizations simultaneously. + + If you are using Radius User token method, keep in mind that one user + account can only authenticate with one organization at a time, i.e a + single user account cannot consume services from multiple + organizations simultaneously. .. _bearer_token: Bearer token ------------- +++++++++++++ -This other method allows to use the system without the need for a user -to obtain a token first, the drawback is that one FreeRADIUS site has to -be configured for each organization, the authorization credentials for -the specific organization is sent in each request, -see :ref:`freeradius_site` for more information on -the FreeRADIUS site configuration. +This other method allows to use the system without the need for a user to +obtain a token first, the drawback is that one FreeRADIUS site has to be +configured for each organization, the authorization credentials for the +specific organization is sent in each request, see :ref:`freeradius_site` +for more information on the FreeRADIUS site configuration. The (:ref:`Organization UUID and Organization RADIUS token -`) are sent in the authorization header of -the HTTP request in the form of a Bearer token, eg: +`) are sent in the authorization header of the +HTTP request in the form of a Bearer token, eg: .. code-block:: text - curl -X POST http://localhost:8000/api/v1/freeradius/authorize/ \ - -H "Authorization: Bearer " \ - -d "username=&password=" + curl -X POST http://localhost:8000/api/v1/freeradius/authorize/ \ + -H "Authorization: Bearer " \ + -d "username=&password=" -This method is recommended if you are using only one organization -and you have no need nor intention of adding more organizations in the future. +This method is recommended if you are using only one organization and you +have no need nor intention of adding more organizations in the future. .. _querystring: Querystring ------------ ++++++++++++ -This method is identical to the previous one, but the credentials -are sent in querystring parameters, eg: +This method is identical to the previous one, but the credentials are sent +in querystring parameters, eg: .. code-block:: text - curl -X POST http://localhost:8000/api/v1/freeradius/authorize/?uuid=&token= \ - -d "username=&password=" + curl -X POST http://localhost:8000/api/v1/freeradius/authorize/?uuid=&token= \ + -d "username=&password=" -This method is not recommended for production usage, it should be -used for testing and debugging only -(because webservers can include the querystring parameters in their logs). +This method is not recommended for production usage, it should be used for +testing and debugging only (because webservers can include the querystring +parameters in their logs). .. _organization_uuid_token: Organization UUID & RADIUS API Token ------------------------------------- +++++++++++++++++++++++++++++++++++++ You can get (and set) the value of the OpenWISP RADIUS API token in the -organization configuration page on the OpenWISP dashboard -(select your organization in ``/admin/openwisp_users/organization/``): +organization configuration page on the OpenWISP dashboard (select your +organization in ``/admin/openwisp_users/organization/``): .. image:: /images/token.png - :alt: Organization Radius Token + :alt: Organization Radius Token .. note:: - It is highly recommended that you use a hard to guess value, longer than - 15 characters containing both letters and numbers. - Eg: ``165f9a790787fc38e5cc12c1640db2300648d9a2``. -You will also need the UUID of your organization from the organization change page -(select your organization in ``/admin/openwisp_users/organization/``): + It is highly recommended that you use a hard to guess value, longer + than 15 characters containing both letters and numbers. Eg: + ``165f9a790787fc38e5cc12c1640db2300648d9a2``. + +You will also need the UUID of your organization from the organization +change page (select your organization in +``/admin/openwisp_users/organization/``): .. image:: /images/org_uuid.png - :alt: Organization UUID + :alt: Organization UUID -Requests authorizing with :ref:`bearer-token ` or :ref:`querystring -` method **must** contain organization UUID & token. If the -tokens are missing or invalid, the request will receive a ``403`` HTTP error. +Requests authorizing with :ref:`bearer-token ` or +:ref:`querystring ` method **must** contain organization UUID +& token. If the tokens are missing or invalid, the request will receive a +``403`` HTTP error. -For information on how to configure FreeRADIUS to send the bearer tokens, see -:ref:`freeradius_site`. +For information on how to configure FreeRADIUS to send the bearer tokens, +see :ref:`freeradius_site`. API Throttling -============== +~~~~~~~~~~~~~~ -To override the default API throttling settings, add the following to your ``settings.py`` file: +To override the default API throttling settings, add the following to your +``settings.py`` file: .. code-block:: python REST_FRAMEWORK = { - 'DEFAULT_THROTTLE_CLASSES': [ - 'rest_framework.throttling.ScopedRateThrottle', + "DEFAULT_THROTTLE_CLASSES": [ + "rest_framework.throttling.ScopedRateThrottle", ], - 'DEFAULT_THROTTLE_RATES': { + "DEFAULT_THROTTLE_RATES": { # None by default - 'authorize': None, - 'postauth': None, - 'accounting': None, - 'obtain_auth_token': None, - 'validate_auth_token': None, - 'create_phone_token': None, - 'phone_token_status': None, - 'validate_phone_token': None, + "authorize": None, + "postauth": None, + "accounting": None, + "obtain_auth_token": None, + "validate_auth_token": None, + "create_phone_token": None, + "phone_token_status": None, + "validate_phone_token": None, # Relaxed throttling Policy - 'others': '400/hour', + "others": "400/hour", }, } The rate descriptions used in ``DEFAULT_THROTTLE_RATES`` may include -``second``, ``minute``, ``hour`` or ``day`` as the throttle period, setting it to ``None`` will result in no throttling. +``second``, ``minute``, ``hour`` or ``day`` as the throttle period, +setting it to ``None`` will result in no throttling. .. _list_of_endpoints: List of Endpoints -================= +~~~~~~~~~~~~~~~~~ .. _authorize: Authorize ---------- ++++++++++ Use by FreeRADIUS to perform the ``authorization`` phase. -It's triggered when a user submits the form to login into the captive portal. -The captive portal has to be configured to send the password to freeradius in clear text -(will be encrypted with the freeradius shared secret, can be tunneled -via TLS for increased security if needed). +It's triggered when a user submits the form to login into the captive +portal. The captive portal has to be configured to send the password to +freeradius in clear text (will be encrypted with the freeradius shared +secret, can be tunneled via TLS for increased security if needed). -FreeRADIUS in turn will send the username and password via HTTPs to this endpoint. +FreeRADIUS in turn will send the username and password via HTTPs to this +endpoint. Responds to only **POST**. @@ -225,25 +239,25 @@ Example: POST /api/v1/freeradius/authorize/ HTTP/1.1 username=testuser&password=testpassword -======== =========================== -Param Description -======== =========================== -username Username for the given user -password Password for the given user -======== =========================== +======== =========================== +Param Description +======== =========================== +username Username for the given user +password Password for the given user +======== =========================== If the authorization is successful, the API will return all group replies related to the group with highest priority assigned to the user. -If the authorization is unsuccessful, the response body can either be empty -or it can contain an explicit rejection, depending on how the -:ref:`OPENWISP_RADIUS_API_AUTHORIZE_REJECT ` -setting is configured. +If the authorization is unsuccessful, the response body can either be +empty or it can contain an explicit rejection, depending on how the +:ref:`OPENWISP_RADIUS_API_AUTHORIZE_REJECT +` setting is configured. .. _post_auth: Post Auth ---------- ++++++++++ API endpoint designed to be used by FreeRADIUS ``postauth``. @@ -253,32 +267,32 @@ Responds only to **POST**. /api/v1/freeradius/postauth/ -================== =================================== -Param Description -================== =================================== -username Username -password Password (*) -reply Radius reply received by freeradius -called_station_id Called Station ID -calling_station_id Calling Station ID -================== =================================== +================== =================================== +Param Description +================== =================================== +username Username +password Password (*) +reply Radius reply received by freeradius +called_station_id Called Station ID +calling_station_id Calling Station ID +================== =================================== (*): the ``password`` is stored only on unsuccessful authorizations. -Returns an empty response body in order to instruct -FreeRADIUS to avoid processing the response body. +Returns an empty response body in order to instruct FreeRADIUS to avoid +processing the response body. .. _accounting: Accounting ----------- +++++++++++ .. code-block:: text /api/v1/freeradius/accounting/ GET -~~~ +... Returns a list of accounting objects @@ -319,46 +333,47 @@ Returns a list of accounting objects ] POST -~~~~ - -Add or update accounting information (start, interim-update, stop); -does not return any JSON response so that freeradius will avoid -processing the response without generating warnings - -===================== ====================== -Param Description -===================== ====================== -session_id Session ID -unique_id Accounting unique ID -username Username -groupname Group name -realm Realm -nas_ip_address NAS IP address -nas_port_id NAS port ID -nas_port_type NAS port type -start_time Start time -update_time Update time -stop_time Stop time -interval Interval -session_time Session Time -authentication Authentication -connection_info_start Connection Info Start -connection_info_stop Connection Info Stop -input_octets Input Octets -output_octets Output Octets -called_station_id Called station ID -calling_station_id Calling station ID -terminate_cause Termination Cause -service_type Service Type -framed_protocol Framed protocol -framed_ip_address framed IP address -===================== ====================== +.... + +Add or update accounting information (start, interim-update, stop); does +not return any JSON response so that freeradius will avoid processing the +response without generating warnings + +===================== ===================== +Param Description +===================== ===================== +session_id Session ID +unique_id Accounting unique ID +username Username +groupname Group name +realm Realm +nas_ip_address NAS IP address +nas_port_id NAS port ID +nas_port_type NAS port type +start_time Start time +update_time Update time +stop_time Stop time +interval Interval +session_time Session Time +authentication Authentication +connection_info_start Connection Info Start +connection_info_stop Connection Info Stop +input_octets Input Octets +output_octets Output Octets +called_station_id Called station ID +calling_station_id Calling station ID +terminate_cause Termination Cause +service_type Service Type +framed_protocol Framed protocol +framed_ip_address framed IP address +===================== ===================== Pagination -++++++++++ +'''''''''' -Pagination is provided using a Link header pagination. Check `here for more information about -traversing with pagination `_. +Pagination is provided using a Link header pagination. Check `here for +more information about traversing with pagination +`_. .. code-block:: text @@ -372,39 +387,42 @@ traversing with pagination ` - described in the beginning of this document. -Some endpoints require the sending of the user API access -token sent in the form of a "Bearer Token", example: + The API endpoints described below do not require the + :ref:`Organization API Token ` described in + the beginning of this document. + +Some endpoints require the sending of the user API access token sent in +the form of a "Bearer Token", example: .. code-block:: shell @@ -412,68 +430,69 @@ token sent in the form of a "Bearer Token", example: 'http://localhost:8000/api/v1/radius/organization/default/account/session/' List of Endpoints -================= +~~~~~~~~~~~~~~~~~ .. _user_registration: User Registration ------------------ ++++++++++++++++++ .. important:: - This endpoint is enabled by default but can be disabled either - via a :ref:`global setting or from the admin interface + This endpoint is enabled by default but can be disabled either via a + :ref:`global setting or from the admin interface `. .. code-block:: text - /api/v1/radius/organization//account/ + /api/v1/radius/organization//account/ Responds only to **POST**. Parameters: -=============== =============================== -Param Description -=============== =============================== -username string -phone_number string (\*) -email string -password1 string -password2 string -first_name string (\*\*) -last_name string (\*\*) -birth_date string (\*\*) -location string (\*\*) -method string (\*\*\*) -=============== =============================== +============ =============== +Param Description +============ =============== +username string +phone_number string (\*) +email string +password1 string +password2 string +first_name string (\*\*) +last_name string (\*\*) +birth_date string (\*\*) +location string (\*\*) +method string (\*\*\*) +============ =============== (\*) ``phone_number`` is required only when the organization has enabled :ref:`SMS verification in its "Organization RADIUS Settings" `. -(\*\*) ``first_name``, ``last_name``, ``birth_date`` and ``location`` -are optional fields which are disabled by default to make the registration -simple, but can be :ref:`enabled through configuration `. +(\*\*) ``first_name``, ``last_name``, ``birth_date`` and ``location`` are +optional fields which are disabled by default to make the registration +simple, but can be :ref:`enabled through configuration +`. (\*\*) ``method`` must be one of the available -:ref:`registration/verification methods `; -if identity verification is disabled for a particular org, an empty string -will be acceptable. +:ref:`registration/verification methods +`; if identity verification +is disabled for a particular org, an empty string will be acceptable. .. _registering_to_multiple_organizations: Registering to Multiple Organizations -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +..................................... -An **HTTP 409** response will be returned if an existing user tries to register -on a URL of a different organization (because the account already exists). -The response will contain a list of organizations with which the user has already -registered to the system which may be shown to the user in the UI. E.g.: +An **HTTP 409** response will be returned if an existing user tries to +register on a URL of a different organization (because the account already +exists). The response will contain a list of organizations with which the +user has already registered to the system which may be shown to the user +in the UI. E.g.: .. code-block:: json - { "details": "A user like the one being registered already exists.", "organizations":[ @@ -482,17 +501,18 @@ registered to the system which may be shown to the user in the UI. E.g.: } The existing user can register with a new organization using the -:ref:`login endpoint `. The user will also get -membership of the new organization only if the organization has -:ref:`user registration enabled `. +:ref:`login endpoint `. The user will also +get membership of the new organization only if the organization has +:ref:`user registration enabled +`. .. _reset_password: Reset password --------------- +++++++++++++++ -This is the classic "password forgotten recovery feature" which -sends a reset password token to the email of the user. +This is the classic "password forgotten recovery feature" which sends a +reset password token to the email of the user. .. code-block:: text @@ -502,17 +522,17 @@ Responds only to **POST**. Parameters: -=============== ====================================================== -Param Description -=============== ====================================================== -input string that can be an email, phone_number or username. -=============== ====================================================== +===== ====================================================== +Param Description +===== ====================================================== +input string that can be an email, phone_number or username. +===== ====================================================== Confirm reset password ----------------------- +++++++++++++++++++++++ -Allows users to confirm their reset password after having it requested -via the :ref:`Reset password ` endpoint. +Allows users to confirm their reset password after having it requested via +the :ref:`Reset password ` endpoint. .. code-block:: text @@ -522,22 +542,22 @@ Responds only to **POST**. Parameters: -=============== =============================== -Param Description -=============== =============================== -new_password1 string -new_password2 string -uid string -token string -=============== =============================== +============= =========== +Param Description +============= =========== +new_password1 string +new_password2 string +uid string +token string +============= =========== Change password ---------------- ++++++++++++++++ **Requires the user auth token (Bearer Token)**. -Allows users to change their password after using the -:ref:`Reset password ` endpoint. +Allows users to change their password after using the :ref:`Reset password +` endpoint. .. code-block:: text @@ -547,18 +567,18 @@ Responds only to **POST**. Parameters: -================ =============================== -Param Description -================ =============================== -current_password string -new_password string -confirm_password string -================ =============================== +================ =========== +Param Description +================ =========== +current_password string +new_password string +confirm_password string +================ =========== .. _login_obtain_user_auth_token: Login (Obtain User Auth Token) ------------------------------- +++++++++++++++++++++++++++++++ .. code-block:: text @@ -568,19 +588,19 @@ Responds only to **POST**. Returns: -- ``radius_user_token``: the user radius token, which can be used to authenticate - the user in the captive portal by sending it in place of the user password - (it will be passed to freeradius which in turn will send it to the - :ref:`authorize API endpoint ` which will recognize the token as - the user passsword) -- ``key``: the user API access token, which will be needed to authenticate the user to - eventual subsequent API requests (eg: change password) +- ``radius_user_token``: the user radius token, which can be used to + authenticate the user in the captive portal by sending it in place of + the user password (it will be passed to freeradius which in turn will + send it to the :ref:`authorize API endpoint ` which will + recognize the token as the user passsword) +- ``key``: the user API access token, which will be needed to authenticate + the user to eventual subsequent API requests (eg: change password) - ``is_active`` if it's ``false`` it means the user has been banned - ``is_verified`` when identity verification is enabled, it indicates - whether the user has completed an indirect identity verification - process like confirming their mobile phone number -- ``method`` registration/verification method used by the user to register, - eg: ``mobile_phone``, ``social_login``, etc. + whether the user has completed an indirect identity verification process + like confirming their mobile phone number +- ``method`` registration/verification method used by the user to + register, eg: ``mobile_phone``, ``social_login``, etc. - ``username`` - ``email`` - ``phone_number`` @@ -589,30 +609,31 @@ Returns: - ``birth_date`` - ``location`` -If the user account is inactive or unverified the endpoint will send the data -anyway but using the HTTP status code 401, this way consumers can recognize -these users and trigger the appropriate response needed (eg: reject them -or initiate account verification). +If the user account is inactive or unverified the endpoint will send the +data anyway but using the HTTP status code 401, this way consumers can +recognize these users and trigger the appropriate response needed (eg: +reject them or initiate account verification). -If an existing user account tries to authenticate to an organization of which -they're not member of, then they would be automatically added as members -(if registration is enabled for that org). Please refer to -:ref:`"Registering to Multiple Organizations" `. +If an existing user account tries to authenticate to an organization of +which they're not member of, then they would be automatically added as +members (if registration is enabled for that org). Please refer to +:ref:`"Registering to Multiple Organizations" +`. -This endpoint updates the user language preference field according -to the ``Accept-Language`` HTTP header. +This endpoint updates the user language preference field according to the +``Accept-Language`` HTTP header. Parameters: -=============== =============================== -Param Description -=============== =============================== -username string -password string -=============== =============================== +======== =========== +Param Description +======== =========== +username string +password string +======== =========== Validate user auth token ------------------------- +++++++++++++++++++++++++ Used to check whether the auth token of a user is valid or not. @@ -626,29 +647,29 @@ Responds only to **POST**. Parameters: -================= =============================== -Param Description -================= =============================== -token the rest auth token to validate -================= =============================== +===== =============================== +Param Description +===== =============================== +token the rest auth token to validate +===== =============================== The user information is returned in the response (similarly to -:ref:`Obtain User Auth Token `), -along with the following additional parameter: +:ref:`Obtain User Auth Token `), along with +the following additional parameter: -- ``response_code``: string indicating whether the result is successful or not, - to be used for translation. +- ``response_code``: string indicating whether the result is successful or + not, to be used for translation. -This endpoint updates the user language preference field according -to the ``Accept-Language`` HTTP header. +This endpoint updates the user language preference field according to the +``Accept-Language`` HTTP header. User Radius Sessions --------------------- +++++++++++++++++++++ **Requires the user auth token (Bearer Token)**. -Returns the radius sessions of the logged-in user and the organization specified -in the URL. +Returns the radius sessions of the logged-in user and the organization +specified in the URL. .. code-block:: text @@ -659,12 +680,12 @@ Responds only to **GET**. .. _radius_usage_api_view: User Radius Usage ------------------ ++++++++++++++++++ **Requires the user auth token (Bearer Token)**. -Returns the radius usage of the logged-in user and the organization specified -in the URL. +Returns the radius usage of the logged-in user and the organization +specified in the URL. It executes the relevant RADIUS counters and returns information that shows how much time and/or traffic the user has consumed. @@ -676,15 +697,17 @@ shows how much time and/or traffic the user has consumed. Responds only to **GET**. Create SMS token ----------------- +++++++++++++++++ .. note:: - This API endpoint will work only if the organization has enabled - :ref:`SMS verification `. + + This API endpoint will work only if the organization has enabled + :ref:`SMS verification `. **Requires the user auth token (Bearer Token)**. -Used for SMS verification, sends a code via SMS to the phone number of the user. +Used for SMS verification, sends a code via SMS to the phone number of the +user. .. code-block:: text @@ -695,11 +718,12 @@ Responds only to **POST**. No parameters required. Get active SMS token status ---------------------------- ++++++++++++++++++++++++++++ .. note:: - This API endpoint will work only if the organization has enabled - :ref:`SMS verification `. + + This API endpoint will work only if the organization has enabled + :ref:`SMS verification `. **Requires the user auth token (Bearer Token)**. @@ -717,15 +741,17 @@ No parameters required. .. _verify_validate_sms_token: Verify/Validate SMS token -------------------------- ++++++++++++++++++++++++++ .. note:: - This API endpoint will work only if the organization has enabled - :ref:`SMS verification `. + + This API endpoint will work only if the organization has enabled + :ref:`SMS verification `. **Requires the user auth token (Bearer Token)**. -Used for SMS verification, allows users to validate the code they receive via SMS. +Used for SMS verification, allows users to validate the code they receive +via SMS. .. code-block:: text @@ -735,25 +761,26 @@ Responds only to **POST**. Parameters: -=============== =============================== -Param Description -=============== =============================== -code string -=============== =============================== +===== =========== +Param Description +===== =========== +code string +===== =========== Change phone number -------------------- ++++++++++++++++++++ .. note:: - This API endpoint will work only if the organization has enabled - :ref:`SMS verification `. + + This API endpoint will work only if the organization has enabled + :ref:`SMS verification `. **Requires the user auth token (Bearer Token)**. -Allows users to change their phone number, -will flag the user as inactive and send them a verification code via SMS. -The phone number of the user is updated only after this verification code -has been :ref:`validated `. +Allows users to change their phone number, will flag the user as inactive +and send them a verification code via SMS. The phone number of the user is +updated only after this verification code has been :ref:`validated +`. .. code-block:: text @@ -763,16 +790,16 @@ Responds only to **POST**. Parameters: -=============== =============================== -Param Description -=============== =============================== -phone_number string -=============== =============================== +============ =========== +Param Description +============ =========== +phone_number string +============ =========== .. _batch_user_creation: Batch user creation -------------------- ++++++++++++++++++++ This API endpoint allows to use the features described in :doc:`/user/importing_users` and :doc:`/user/generating_users`. @@ -782,46 +809,48 @@ This API endpoint allows to use the features described in /api/v1/radius/batch/ .. note:: - This API endpoint allows to use the features described in :doc:`/user/importing_users` - and :doc:`/user/generating_users`. + + This API endpoint allows to use the features described in + :doc:`/user/importing_users` and :doc:`/user/generating_users`. Responds only to **POST**, used to save a ``RadiusBatch`` instance. -It is possible to generate the users of the ``RadiusBatch`` with two different strategies: csv or prefix. +It is possible to generate the users of the ``RadiusBatch`` with two +different strategies: csv or prefix. The csv method needs the following parameters: -================= ================================= -Param Description -================= ================================= -name Name of the operation -strategy csv -csvfile file with the users -expiration_date date of expiration of the users -organization_slug slug of organization of the users -================= ================================= +================= ================================= +Param Description +================= ================================= +name Name of the operation +strategy csv +csvfile file with the users +expiration_date date of expiration of the users +organization_slug slug of organization of the users +================= ================================= These others are for the prefix method: -================= ================================== -Param Description -================= ================================== -name name of the operation -strategy prefix -prefix prefix for the generation of users -number_of_users number of users -expiration_date date of expiration of the users -organization_slug slug of organization of the users -================= ================================== +================= ================================== +Param Description +================= ================================== +name name of the operation +strategy prefix +prefix prefix for the generation of users +number_of_users number of users +expiration_date date of expiration of the users +organization_slug slug of organization of the users +================= ================================== When using this strategy, in the response you can find the field -``user_credentials`` containing the list of users created -(example: ``[['username', 'password'], ['sample_user', 'BBuOb5sN']]``) -and the field ``pdf_link`` which can be used to download a PDF file -containing the user credentials. +``user_credentials`` containing the list of users created (example: +``[['username', 'password'], ['sample_user', 'BBuOb5sN']]``) and the field +``pdf_link`` which can be used to download a PDF file containing the user +credentials. Batch CSV Download -------------------- +++++++++++++++++++ .. code-block:: text @@ -831,10 +860,10 @@ Responds only to **GET**. Parameters: -=============== =============================== -Param Description -=============== =============================== -slug string -id string -filename string -=============== =============================== +======== =========== +Param Description +======== =========== +slug string +id string +filename string +======== =========== diff --git a/docs/source/user/change_of_authorization.rst b/docs/source/user/change_of_authorization.rst index ba78f82c..2101033b 100644 --- a/docs/source/user/change_of_authorization.rst +++ b/docs/source/user/change_of_authorization.rst @@ -1,6 +1,5 @@ .. _change_of_authorization: -============================= Change of Authorization (CoA) ============================= @@ -8,53 +7,50 @@ Change of Authorization (CoA) The *Change of Authorization (CoA)* is disabled by default. - In order to enable this feature you have it enable it via - :ref:`global setting or from the admin interface - `. + In order to enable this feature you have it enable it via :ref:`global + setting or from the admin interface `. The openwisp-radius module supports the Change of Authorization (CoA) -specification of the RADIUS protocol described in -`RFC 5176 `_. +specification of the RADIUS protocol described in `RFC 5176 +`_. -Whenever the *RADIUS Group* of a user is changed, openwisp-radius -updates the NAS with the user's latest RADIUS Attributes. This is achieved -by sending CoA RADIUS packet to NAS for all open RADIUS sessions of -the user. This allows enforcing RADIUS limits without requiring -the user to re-authenticate with the NAS. +Whenever the *RADIUS Group* of a user is changed, openwisp-radius updates +the NAS with the user's latest RADIUS Attributes. This is achieved by +sending CoA RADIUS packet to NAS for all open RADIUS sessions of the user. +This allows enforcing RADIUS limits without requiring the user to +re-authenticate with the NAS. -The CoA RADIUS packet contains the RADIUS Attributes defined in the -new *RADIUS Group* of the user. If the new *RADIUS Group* does -not specify any attributes, the CoA RADIUS packet will unset the -attributes set by the previous *RADIUS Group*. +The CoA RADIUS packet contains the RADIUS Attributes defined in the new +*RADIUS Group* of the user. If the new *RADIUS Group* does not specify any +attributes, the CoA RADIUS packet will unset the attributes set by the +previous *RADIUS Group*. Consider the following example with two *RADIUS Groups*: -+-----------------------+------------------------------------------------------+ -| **RADIUS Group Name** | **RADIUS Group Checks** | -+-----------------------+------------------------------------------------------+ -| **users** | +-------------------------------+------------------+ | -| | | **Attribute** | **Value** | | -| | +-------------------------------+------------------+ | -| | | ``Max-Daily-Session-Traffic`` | ``:=3000000000`` | | -| | +-------------------------------+------------------+ | -| | | ``Max-Daily-Session`` | ``:=10800`` | | -| | +-------------------------------+------------------+ | -+-----------------------+------------------------------------------------------+ -| **power-users** | *Note: This group intentionally does not define any | -| | limits.* | -+-----------------------+------------------------------------------------------+ - -A user, Jane is assigned ``users`` *RADIUS Group* and is currently using the -network, i.e. has an open RADIUS session. The administrator of the system -decided to upgrade the *RADIUS Group* of Jane to ``power-users``, allowing -Jane to use the network without any limits. Without CoA, Jane will have to -logout of the captive portal (NAS) and log-in again to browse the network -without any limits. But when CoA is enabled in openwisp-radius, openwisp-radius -will update the NAS with the limits defined in Jane's new RADIUS Group. In this -case, openwisp-radius will tell the NAS to unset the limits that were configured -by the previous RADIUS Group. +===================== =================================================== +**RADIUS Group Name** **RADIUS Group Checks** +**users** ============================= ================ + **Attribute** **Value** + ``Max-Daily-Session-Traffic`` ``:=3000000000`` + ``Max-Daily-Session`` ``:=10800`` + ============================= ================ +**power-users** *Note: This group intentionally does not define any + limits.* +===================== =================================================== + +A user, Jane is assigned ``users`` *RADIUS Group* and is currently using +the network, i.e. has an open RADIUS session. The administrator of the +system decided to upgrade the *RADIUS Group* of Jane to ``power-users``, +allowing Jane to use the network without any limits. Without CoA, Jane +will have to logout of the captive portal (NAS) and log-in again to browse +the network without any limits. But when CoA is enabled in +openwisp-radius, openwisp-radius will update the NAS with the limits +defined in Jane's new RADIUS Group. In this case, openwisp-radius will +tell the NAS to unset the limits that were configured by the previous +RADIUS Group. If the system administrators later decided to downgrade the *RADIUS Group* of Jane to ``users``, hence enforcing limits to the usage of the network, -openwisp-radius will update the NAS with the limits defined for the ``users`` -group for all active RADIUS sessions if CoA is enabled in openwisp-radius. +openwisp-radius will update the NAS with the limits defined for the +``users`` group for all active RADIUS sessions if CoA is enabled in +openwisp-radius. diff --git a/docs/source/user/enforcing_limits.rst b/docs/source/user/enforcing_limits.rst index f0aeefdc..d5bd9f11 100644 --- a/docs/source/user/enforcing_limits.rst +++ b/docs/source/user/enforcing_limits.rst @@ -1,43 +1,45 @@ -======================== Enforcing session limits ======================== -The default freeradius schema does not include a table where groups are stored, -but openwisp-radius adds a model called ``RadiusGroup`` and alters the default -freeradius schema to add some optional foreign-keys from other tables like: +The default freeradius schema does not include a table where groups are +stored, but openwisp-radius adds a model called ``RadiusGroup`` and alters +the default freeradius schema to add some optional foreign-keys from other +tables like: - ``radgroupcheck`` - ``radgroupreply`` - ``radusergroup`` -These foreign keys make it easier to automate many synchronization and integrity -checks between the ``RadiusGroup`` table and its related tables but they are -not strictly mandatory from the database point of view: -their value can be ``NULL`` and their presence and validation is handled at -application level, this makes it easy to use existing freeradius databases. +These foreign keys make it easier to automate many synchronization and +integrity checks between the ``RadiusGroup`` table and its related tables +but they are not strictly mandatory from the database point of view: their +value can be ``NULL`` and their presence and validation is handled at +application level, this makes it easy to use existing freeradius +databases. -For each group, checks and replies can be specified directly in the edit page -of a Radius Group (``admin`` > ``groups`` > ``add group`` or ``change group``). +For each group, checks and replies can be specified directly in the edit +page of a Radius Group (``admin`` > ``groups`` > ``add group`` or ``change +group``). Default groups -------------- -Some groups are created automatically by **openwisp-radius** during the initial -migrations: +Some groups are created automatically by **openwisp-radius** during the +initial migrations: -- ``users``: this is the default group which limits users sessions - to 3 hours and 300 MB (daily) +- ``users``: this is the default group which limits users sessions to 3 + hours and 300 MB (daily) - ``power-users``: this group does not have any check, therefore users who are members of this group won't be limited in any way -You can customize the checks and the replies of these groups, as well as create -new groups according to your needs and preferences. +You can customize the checks and the replies of these groups, as well as +create new groups according to your needs and preferences. **Note on the default group**: keep in mind that the group flagged as -default will by automatically assigned to new users, it cannot be deleted nor -it can be flagged as non-default: to set another group as default simply check -that group as the default one, save and **openwisp-radius** will remove the -default flag from the old default group. +default will by automatically assigned to new users, it cannot be deleted +nor it can be flagged as non-default: to set another group as default +simply check that group as the default one, save and **openwisp-radius** +will remove the default flag from the old default group. .. _counters: @@ -47,60 +49,60 @@ How limits are enforced: counters In Freeradius, this kind of feature is implemented with the `rml_sqlcounter `_. -The problem with this FreeRADIUS module is that it doesn't know about OpenWISP, -so it does not support multi-tenancy. -This means that if multiple organizations are using the OpenWISP instance, -it's possible that a user may be an end user of multiple organizations and -hence have one radius group assigned for each, but the sqlcounter module will -not understand the right group to choose when enforcing limits, with the +The problem with this FreeRADIUS module is that it doesn't know about +OpenWISP, so it does not support multi-tenancy. This means that if +multiple organizations are using the OpenWISP instance, it's possible that +a user may be an end user of multiple organizations and hence have one +radius group assigned for each, but the sqlcounter module will not +understand the right group to choose when enforcing limits, with the result that the enforcing of limits will not work as expected, unless one FreeRADIUS site with different sqlcounter configurations is created for -each organization using the system, which is doable but cumbersome to maintain. +each organization using the system, which is doable but cumbersome to +maintain. -For the reasons explained above, an alternative counter feature -has been implemented in the authorize API endpoint of OpenWISP RADIUS. +For the reasons explained above, an alternative counter feature has been +implemented in the authorize API endpoint of OpenWISP RADIUS. The default counters available are described below. ``DailyCounter`` ~~~~~~~~~~~~~~~~ -This counter is used to limit the amount of time users can use -the network every day. It works by checking whether the total -session time of a user during a specific day is below the value indicated in -the ``Max-Daily-Session`` group check attribute, sending the remaining -session time with a ``Session-Timeout`` reply message or rejecting -the authorization if the limit has been passed. +This counter is used to limit the amount of time users can use the network +every day. It works by checking whether the total session time of a user +during a specific day is below the value indicated in the +``Max-Daily-Session`` group check attribute, sending the remaining session +time with a ``Session-Timeout`` reply message or rejecting the +authorization if the limit has been passed. .. _daily_traffic_counter: ``DailyTrafficCounter`` ~~~~~~~~~~~~~~~~~~~~~~~ -This counter is used to limit the amount of traffic -users can consume every day. It works by checking whether the total amount -of download plus upload octets (bytes consumed) is below the value indicated -in the ``Max-Daily-Session-Traffic`` group check attribute, sending the -remaining octets with a reply message or rejecting -the authorization if the limit has been passed. +This counter is used to limit the amount of traffic users can consume +every day. It works by checking whether the total amount of download plus +upload octets (bytes consumed) is below the value indicated in the +``Max-Daily-Session-Traffic`` group check attribute, sending the remaining +octets with a reply message or rejecting the authorization if the limit +has been passed. -The attributes used for the check and or the reply message are configurable -because it can differ from NAS to NAS, see :ref:`traffic_counter_check_name` -:ref:`traffic_counter_reply_name` for more information. +The attributes used for the check and or the reply message are +configurable because it can differ from NAS to NAS, see +:ref:`traffic_counter_check_name` :ref:`traffic_counter_reply_name` for +more information. ``MonthlyTrafficCounter`` ~~~~~~~~~~~~~~~~~~~~~~~~~ -This counter is used to limit the amount of traffic -users can consume every solar month. -It works by checking whether the total amount -of download plus upload octets (bytes consumed) is below the value indicated +This counter is used to limit the amount of traffic users can consume +every solar month. It works by checking whether the total amount of +download plus upload octets (bytes consumed) is below the value indicated in the ``Max-Monthly-Session-Traffic`` group check attribute, sending the -remaining octets with a reply message or rejecting -the authorization if the limit has been passed. +remaining octets with a reply message or rejecting the authorization if +the limit has been passed. -The reply message is configurable -because it can differ from NAS to NAS, +The reply message is configurable because it can differ from NAS to NAS, :ref:`traffic_counter_reply_name` for more information. ``MonthlySubscriptionTrafficCounter`` @@ -108,14 +110,14 @@ because it can differ from NAS to NAS, .. important:: - This counter is not enabled by default. - It can be enabled via the :ref:`counter_related_settings`. + This counter is not enabled by default. It can be enabled via the + :ref:`counter_related_settings`. -Same as ``MonthlyTrafficCounter``, but with the difference that -the reset period depends on the day in which the user subscribed -to the service: if the user signed up (or their account was created by -an admin) on a date like November 15 2022, the reset period will -start on the 15th day of every month. +Same as ``MonthlyTrafficCounter``, but with the difference that the reset +period depends on the day in which the user subscribed to the service: if +the user signed up (or their account was created by an admin) on a date +like November 15 2022, the reset period will start on the 15th day of +every month. Database support ~~~~~~~~~~~~~~~~ @@ -123,40 +125,44 @@ Database support The counters described above are available for PostgreSQL, MySQL, SQLite and are enabled by default. -There's a different class of each counter for each database, because -the query is executed with raw SQL defined on each class, instead of -the classic django-ORM approach which is database agnostic. +There's a different class of each counter for each database, because the +query is executed with raw SQL defined on each class, instead of the +classic django-ORM approach which is database agnostic. -It was implemented this way to ensure maximum flexibility and adherence -to the FreeRADIUS sqlcounter implementation. +It was implemented this way to ensure maximum flexibility and adherence to +the FreeRADIUS sqlcounter implementation. Django Settings ~~~~~~~~~~~~~~~ -The settings available to control the behavior of counters are -described in :ref:`counter_related_settings`. +The settings available to control the behavior of counters are described +in :ref:`counter_related_settings`. Writing custom counter classes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It is possible to write custom counter classes to satisfy any need. -The easiest way is to subclass ``openwisp_radius.counters.base.BaseCounter``, -then implement at least the following attributes: +The easiest way is to subclass +``openwisp_radius.counters.base.BaseCounter``, then implement at least the +following attributes: - ``counter_name``: name of the counter, used internally for debugging; -- ``check_name``: attribute name used in the database lookup to the group check table; +- ``check_name``: attribute name used in the database lookup to the group + check table; - ``reply_name``: attribute name sent in the reply message; - ``reset``: reset period, either ``daily``, ``weekly``, ``monthly``, ``monthly_subscription`` or ``never``; - ``sql``: the raw SQL query to execute; -- ``get_sql_params``: a method which returns a list of the arguments passed - to the interpolation of the raw sql query. +- ``get_sql_params``: a method which returns a list of the arguments + passed to the interpolation of the raw sql query. Please look at the source code of OpenWISP RADIUS to find out more. -- `openwisp_radius.counters.base `_ -- `openwisp_radius.counters.postgresql `_ +- `openwisp_radius.counters.base + `_ +- `openwisp_radius.counters.postgresql + `_ Once the new class is ready, you will need to add it to :ref:`counters_setting`. @@ -165,10 +171,10 @@ It is also possible to implement a check class in a completely custom fashion (that is, not inheriting from ``BaseCounter``), the only requirements are: -- the class must have a constructor (``__init__`` method) identical to - the one used in the ``BaseCounter`` class; -- the class must have a ``check`` method which doesn't need any required argument - and returns the remaining counter value or raises ``MaxQuotaReached`` if - the limit has been reached and the authorization should be rejected; - This method may return ``None`` if no additional RADIUS attribute - needs to be added to the response. +- the class must have a constructor (``__init__`` method) identical to the + one used in the ``BaseCounter`` class; +- the class must have a ``check`` method which doesn't need any required + argument and returns the remaining counter value or raises + ``MaxQuotaReached`` if the limit has been reached and the authorization + should be rejected; This method may return ``None`` if no additional + RADIUS attribute needs to be added to the response. diff --git a/docs/source/user/generating_users.rst b/docs/source/user/generating_users.rst index d23d84d8..411779fd 100644 --- a/docs/source/user/generating_users.rst +++ b/docs/source/user/generating_users.rst @@ -1,62 +1,68 @@ .. _generating_users: -================ Generating users ================ -Many a times, a network admin might need to generate temporary users (eg: events). +Many a times, a network admin might need to generate temporary users (eg: +events). -This feature can be used for generating users by specifying a prefix and the number -of users to be generated. +This feature can be used for generating users by specifying a prefix and +the number of users to be generated. There are many features included in it such as: -* **Generating users in batches**: all of the users of a particular **prefix** would be - stored in batches and can be retrieved/deleted easily using the batch functions. -* **Download user credentials in PDF format**: get the usernames and passwords - generated outputted into a PDF. -* **Set an expiration date**: an expiration date can be set for a batch after which - the users would not able to authenticate to the RADIUS Server. +- **Generating users in batches**: all of the users of a particular + **prefix** would be stored in batches and can be retrieved/deleted + easily using the batch functions. +- **Download user credentials in PDF format**: get the usernames and + passwords generated outputted into a PDF. +- **Set an expiration date**: an expiration date can be set for a batch + after which the users would not able to authenticate to the RADIUS + Server. -This operation can be performed via the admin interface, -with a management command or via the REST API. +This operation can be performed via the admin interface, with a management +command or via the REST API. .. note:: - Users imported or generated through this form will be flagged as verified if the - organization requires identity verification, otherwise the generated users would - not be able to log in. If this organization requires identity verification, make - sure the identity of the users is verified before giving out the credentials. + + Users imported or generated through this form will be flagged as + verified if the organization requires identity verification, otherwise + the generated users would not be able to log in. If this organization + requires identity verification, make sure the identity of the users is + verified before giving out the credentials. Using the admin interface ------------------------- -To generate users from the admin interface, go to -``Home > Batch user creation operations > Add`` -(URL: ``/admin/openwisp_radius/radiusbatch/add``), -set ``Strategy`` to ``Generate from prefix``, fill in the remaining fields -that are shown after the selection of the strategy and save. +To generate users from the admin interface, go to ``Home > Batch user +creation operations > Add`` (URL: +``/admin/openwisp_radius/radiusbatch/add``), set ``Strategy`` to +``Generate from prefix``, fill in the remaining fields that are shown +after the selection of the strategy and save. -Once the batch object has been created, a PDF containing the user credentials can -be downloaded by using the "Download user credentials" button in the upper right -corner of the page: +Once the batch object has been created, a PDF containing the user +credentials can be downloaded by using the "Download user credentials" +button in the upper right corner of the page: .. image:: /images/download_user_credentials_button.png - :alt: Downlaod user credentials button in admin interface + :alt: Downlaod user credentials button in admin interface -The contents of the PDF is in format of a table of users & their passwords: +The contents of the PDF is in format of a table of users & their +passwords: .. image:: /images/pdf_of_user_list.png - :alt: Sample contents of the user credentials PDF file + :alt: Sample contents of the user credentials PDF file Usage Demonstration: .. image:: /images/add_users_prefix.gif - :alt: Demo: adding users from prefix + :alt: Demo: adding users from prefix Management command: ``prefix_add_users`` ---------------------------------------- -This command generates users whose usernames start with a particular prefix. Usage is as shown below. +This command generates users whose usernames start with a particular +prefix. Usage is as shown below. .. code-block:: shell @@ -69,10 +75,11 @@ This command generates users whose usernames start with a particular prefix. Usa --output .. note:: - The expiration, password-length and output are optional parameters. - The options expiration and password-length default to never and 8 respectively. - If output parameter is not provided, pdf file is not created on the server - and can be accessed from the admin interface. + + The expiration, password-length and output are optional parameters. + The options expiration and password-length default to never and 8 + respectively. If output parameter is not provided, pdf file is not + created on the server and can be accessed from the admin interface. REST API: Batch user creation ----------------------------- diff --git a/docs/source/user/importing_users.rst b/docs/source/user/importing_users.rst index 7395f8d2..21fcc756 100644 --- a/docs/source/user/importing_users.rst +++ b/docs/source/user/importing_users.rst @@ -1,44 +1,54 @@ .. _importing_users: -=============== Importing users =============== -This feature can be used for importing users from a csv file. There are many features included in it such as: +This feature can be used for importing users from a csv file. There are +many features included in it such as: -* Importing users in batches: all of the users of a particular csv file would - be stored in batches and can be retrieved/ deleted easily using the batch functions. -* Set an expiration date: Expiration date can be set for a batch after which the users - would not able to authenticate to the RADIUS Server. -* Autogenerate usernames and passwords: The usernames and passwords are +- Importing users in batches: all of the users of a particular csv file + would be stored in batches and can be retrieved/ deleted easily using + the batch functions. +- Set an expiration date: Expiration date can be set for a batch after + which the users would not able to authenticate to the RADIUS Server. +- Autogenerate usernames and passwords: The usernames and passwords are automatically generated if they aren't provided in the csv file. Usernames are generated from the email address whereas passwords are generated randomly and their lengths can be customized. -* Passwords are accepted in both cleartext and hash formats from the CSV. -* Send mails to users whose passwords have been generated automatically. +- Passwords are accepted in both cleartext and hash formats from the CSV. +- Send mails to users whose passwords have been generated automatically. -This operation can be performed via the admin interface, -with a management command or via the REST API. +This operation can be performed via the admin interface, with a management +command or via the REST API. .. _csv_format: CSV Format ---------- -The CSV shall be of the format:: +The CSV shall be of the format: + +:: username,password,email,firstname,lastname Imported users with hashed passwords ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The hashes are directly stored in the database if they are of the `django hash format `_. +The hashes are directly stored in the database if they are of the `django +hash format +`_. -For example, a password myPassword123, hashed using salted SHA1 algorithm, will look like:: +For example, a password myPassword123, hashed using salted SHA1 algorithm, +will look like: + +:: pbkdf2_sha256$100000$cKdP39chT3pW$2EtVk4Hhm1V65GNfYAA5AHj0uyD60f2CmqumqiB/gRk= -So a full CSV line containing that password would be:: +So a full CSV line containing that password would be: + +:: username,pbkdf2_sha256$100000$cKdP39chT3pW$2EtVk4Hhm1V65GNfYAA5AHj0uyD60f2CmqumqiB/gRk=,email@email.com,firstname,lastname @@ -47,8 +57,8 @@ Importing users with clear-text passwords Clear-text passwords must be flagged with the prefix ``cleartext$``. -For example, if we want to use the password ``qwerty``, -we must use: ``cleartext$qwerty``. +For example, if we want to use the password ``qwerty``, we must use: +``cleartext$qwerty``. Auto-generation of usernames and passwords ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -62,24 +72,28 @@ auto-generated and contents of these emails can be customized too. Here are some defined settings for doing that: - * :ref:`OPENWISP_RADIUS_BATCH_MAIL_SUBJECT ` - * :ref:`OPENWISP_RADIUS_BATCH_MAIL_MESSAGE ` - * :ref:`OPENWISP_RADIUS_BATCH_MAIL_SENDER ` + - :ref:`OPENWISP_RADIUS_BATCH_MAIL_SUBJECT + ` + - :ref:`OPENWISP_RADIUS_BATCH_MAIL_MESSAGE + ` + - :ref:`OPENWISP_RADIUS_BATCH_MAIL_SENDER + ` Using the admin interface ------------------------- .. note:: - The CSV uploaded must follow the :ref:`CSV format described above `. -To generate users from the admin interface, go to -``Home > Batch user creation operations > Add`` -(URL: ``/admin/openwisp_radius/radiusbatch/add``), -set ``Strategy`` to ``Import from CSV``, -choose the CSV file to upload and save. + The CSV uploaded must follow the :ref:`CSV format described above + `. + +To generate users from the admin interface, go to ``Home > Batch user +creation operations > Add`` (URL: +``/admin/openwisp_radius/radiusbatch/add``), set ``Strategy`` to ``Import +from CSV``, choose the CSV file to upload and save. .. image:: /images/add_users_csv.gif - :alt: Demo: adding users from CSV + :alt: Demo: adding users from CSV Management command: ``batch_add_users`` --------------------------------------- @@ -93,8 +107,11 @@ This command imports users from a csv file. Usage is as shown below. --file \ --expiration \ --password-length + .. note:: - The expiration and password-length are optional parameters which default to never and 8 respectively. + + The expiration and password-length are optional parameters which + default to never and 8 respectively. REST API: Batch user creation ----------------------------- diff --git a/docs/source/user/management_commands.rst b/docs/source/user/management_commands.rst index e3ac28a7..aa2df790 100644 --- a/docs/source/user/management_commands.rst +++ b/docs/source/user/management_commands.rst @@ -1,6 +1,5 @@ .. _management_commands: -=================== Management commands =================== @@ -14,7 +13,8 @@ Example usage: cd tests/ ./manage.py -In this page we list the management commands currently available in **openwisp-radius**. +In this page we list the management commands currently available in +**openwisp-radius**. ``delete_old_radacct`` ---------------------- @@ -49,8 +49,8 @@ For example: ``cleanup_stale_radacct`` ------------------------- -This command closes stale RADIUS sessions that have remained open for -the number of specified ````. +This command closes stale RADIUS sessions that have remained open for the +number of specified ````. .. code-block:: shell @@ -66,10 +66,12 @@ For example: ---------------------------- .. note:: - :ref:`Find out more about this feature in its dedicated page ` -This command deactivates expired user accounts which were created temporarily -(eg: for en event) and have an expiration date set. + :ref:`Find out more about this feature in its dedicated page + ` + +This command deactivates expired user accounts which were created +temporarily (eg: for en event) and have an expiration date set. .. code-block:: shell @@ -78,8 +80,9 @@ This command deactivates expired user accounts which were created temporarily ``delete_old_radiusbatch_users`` -------------------------------- -This command deletes users that have expired (and should have been deactivated by -``deactivate_expired_users``) for more than the specified ````. +This command deletes users that have expired (and should have been +deactivated by ``deactivate_expired_users``) for more than the specified +````. .. code-block:: shell @@ -90,11 +93,11 @@ Note that the default duration is set to 18 months. ``delete_unverified_users`` --------------------------- -This command deletes unverified users that have been registered for -more than specified duration and have no associated radius session. -This feature is needed to delete users who have registered but never -completed the verification process. -**Staff users will not be deleted by this management command.** +This command deletes unverified users that have been registered for more +than specified duration and have no associated radius session. This +feature is needed to delete users who have registered but never completed +the verification process. **Staff users will not be deleted by this +management command.** .. code-block:: shell @@ -102,8 +105,9 @@ completed the verification process. Note that the default duration is set to 1 day. -It is also possible to exclude users that have registered using specified methods. -You can specify multiple methods separated by comma(`,`). Following is an example: +It is also possible to exclude users that have registered using specified +methods. You can specify multiple methods separated by comma(`,`). +Following is an example: .. code-block:: shell @@ -112,59 +116,77 @@ You can specify multiple methods separated by comma(`,`). Following is an exampl ``upgrade_from_django_freeradius`` ---------------------------------- -If you are upgrading from `django-freeradius `_ -to openwisp-radius, there is an easy migration script that will import your freeradius -database, sites, social website account users, users & groups to openwisp-radius instance:: +If you are upgrading from `django-freeradius +`_ to openwisp-radius, +there is an easy migration script that will import your freeradius +database, sites, social website account users, users & groups to +openwisp-radius instance: + +:: ./manage.py upgrade_from_django_freeradius The management command accepts an argument ``--backup``, that you can pass -to give the location of the backup files, by default it looks in the ``tests/`` -directory, eg:: +to give the location of the backup files, by default it looks in the +``tests/`` directory, eg: + +:: ./manage.py upgrade_from_django_freeradius --backup /home/user/django_freeradius/ -The management command accepts another argument ``--organization``, if you want to -import data to a specific organization, you can give its UUID for the same, -by default the data is added to the first found organization, eg:: +The management command accepts another argument ``--organization``, if you +want to import data to a specific organization, you can give its UUID for +the same, by default the data is added to the first found organization, +eg: + +:: ./manage.py upgrade_from_django_freeradius --organization 900856da-c89a-412d-8fee-45a9c763ca0b .. note:: - You can follow the `tutorial to migrate database from django-freeradius `_. + + You can follow the `tutorial to migrate database from + django-freeradius + `_. .. warning:: - It is not possible to export user credential data for radiusbatch created using prefix, please manually preserve the PDF files if you want to access the data in the future. + + It is not possible to export user credential data for radiusbatch + created using prefix, please manually preserve the PDF files if you + want to access the data in the future. .. _convert_called_station_id: ``convert_called_station_id`` ----------------------------- -If an installation uses a centralized captive portal, the value of "Called Station ID" of -RADIUS Sessions will always show the MAC address of the captive portal instead of the access points. +If an installation uses a centralized captive portal, the value of "Called +Station ID" of RADIUS Sessions will always show the MAC address of the +captive portal instead of the access points. -This command will update the "Called Station ID" to reflect the MAC address of the access points -using information from OpenVPN. It requires installing ``openvpn_status``, -which can be installed using the following command +This command will update the "Called Station ID" to reflect the MAC +address of the access points using information from OpenVPN. It requires +installing ``openvpn_status``, which can be installed using the following +command .. code-block:: shell pip install openwisp-radius[openvpn_status] In order to work, this command requires to be configured via the -:ref:`OPENWISP_RADIUS_CALLED_STATION_IDS ` setting. +:ref:`OPENWISP_RADIUS_CALLED_STATION_IDS +` setting. Use the following command if you want to perform this operation for all -RADIUS sessions that meet criteria of ``OPENWISP_RADIUS_CALLED_STATION_IDS`` -setting. +RADIUS sessions that meet criteria of +``OPENWISP_RADIUS_CALLED_STATION_IDS`` setting. .. code-block:: shell ./manage.py convert_called_station_id -You can also convert the "Called Station ID" of a particular RADIUS session by -replacing session's ``unique_id`` in the following command: +You can also convert the "Called Station ID" of a particular RADIUS +session by replacing session's ``unique_id`` in the following command: .. code-block:: shell @@ -172,14 +194,15 @@ replacing session's ``unique_id`` in the following command: .. note:: - If you encounter ``ParseError`` for datetime data, you can set the datetime format - of the parser using :ref:`OPENWISP_RADIUS_OPENVPN_DATETIME_FORMAT ` - setting. + If you encounter ``ParseError`` for datetime data, you can set the + datetime format of the parser using + :ref:`OPENWISP_RADIUS_OPENVPN_DATETIME_FORMAT + ` setting. .. note:: - ``convert_called_station_id`` command will only operate on open RADIUS sessions, - i.e. the "stop_time" field is None. + ``convert_called_station_id`` command will only operate on open RADIUS + sessions, i.e. the "stop_time" field is None. But if you are converting a single RADIUS session, it will operate on it even if the session is closed. diff --git a/docs/source/user/registration.rst b/docs/source/user/registration.rst index bb7b1073..452121d4 100644 --- a/docs/source/user/registration.rst +++ b/docs/source/user/registration.rst @@ -1,13 +1,15 @@ -========================= Registration of new users ========================= -openwisp-radius uses `django-rest-auth `_ -which provides registration of new users via REST API so you can implement -registration and password reset directly from your captive page. +openwisp-radius uses `django-rest-auth +`_ which provides registration +of new users via REST API so you can implement registration and password +reset directly from your captive page. -The registration API endpoint is described in :ref:`API: User Registration `. +The registration API endpoint is described in :ref:`API: User Registration +`. -If you need users to self-register to a public wifi service, we suggest -to take a look at `openwisp-wifi-login-pages `_, -which is built to work with openwisp-radius. +If you need users to self-register to a public wifi service, we suggest to +take a look at `openwisp-wifi-login-pages +`_, which is built +to work with openwisp-radius. diff --git a/docs/source/user/saml.rst b/docs/source/user/saml.rst index be5ac61e..1bee17b3 100644 --- a/docs/source/user/saml.rst +++ b/docs/source/user/saml.rst @@ -1,6 +1,5 @@ .. _saml_: -===================== Single Sign-On (SAML) ===================== @@ -8,52 +7,57 @@ Single Sign-On (SAML) The SAML registration method is disabled by default. - In order to enable this feature you have to follow - the :ref:`SAML setup instructions ` below - and then activate it via :ref:`global setting or from the admin interface + In order to enable this feature you have to follow the :ref:`SAML + setup instructions ` below and then activate it via + :ref:`global setting or from the admin interface `. -`SAML `_ is supported by generating -an additional temporary token right after users authenticates via SSO, -the user is then redirected to the captive page with 3 querystring -parameters: +`SAML `_ is supported by generating an +additional temporary token right after users authenticates via SSO, the +user is then redirected to the captive page with 3 querystring parameters: - ``username`` - ``token`` (REST auth token) - ``login_method=saml`` The captive page must recognize these two parameters, validate the token -and automatically perform the submit action of the captive portal login form: -``username`` should obviously used for the username field, -while ``token`` should be used for the password field. +and automatically perform the submit action of the captive portal login +form: ``username`` should obviously used for the username field, while +``token`` should be used for the password field. The third parameter, ``login_method=saml``, is needed because it allows -the captive page to remember that the user logged in via SAML, -because it will need to perform the :ref:`SAML logout ` later on. +the captive page to remember that the user logged in via SAML, because it +will need to perform the :ref:`SAML logout ` later on. -The internal REST API of openwisp-radius will recognize the token and authorize -the user. +The internal REST API of openwisp-radius will recognize the token and +authorize the user. -This kind of implementation allows to support SAML with any captive -portal which already supports the RADIUS protocol because it's totally transparent -for it, that is, the captive portal doesn't even know the user is signing-in with -a SSO. +This kind of implementation allows to support SAML with any captive portal +which already supports the RADIUS protocol because it's totally +transparent for it, that is, the captive portal doesn't even know the user +is signing-in with a SSO. .. note:: - If you're building a public wifi service, we suggest - to take a look at `openwisp-wifi-login-pages `_, - which is built to work with openwisp-radius. + + If you're building a public wifi service, we suggest to take a look at + `openwisp-wifi-login-pages + `_, which is + built to work with openwisp-radius. .. _setup_saml: Setup ----- -Install required system dependencies:: +Install required system dependencies: + +:: sudo apt install xmlsec1 -Install Python dependencies:: +Install Python dependencies: + +:: pip install openwisp-radius[saml] @@ -64,34 +68,35 @@ Ensure your ``settings.py`` looks like the following: INSTALLED_APPS = [ # ... other apps .. # apps needed for SAML login - 'rest_framework.authtoken', - 'django.contrib.sites', - 'allauth', - 'allauth.account', - 'djangosaml2' + "rest_framework.authtoken", + "django.contrib.sites", + "allauth", + "allauth.account", + "djangosaml2", ] SITE_ID = 1 # Update AUTHENTICATION_BACKENDS AUTHENTICATION_BACKENDS = ( - 'openwisp_users.backends.UsersAuthenticationBackend', - 'openwisp_radius.saml.backends.OpenwispRadiusSaml2Backend', # <- add for SAML login + "openwisp_users.backends.UsersAuthenticationBackend", + "openwisp_radius.saml.backends.OpenwispRadiusSaml2Backend", # <- add for SAML login ) # Update MIDDLEWARE MIDDLEWARE = [ # ... other middlewares ... - 'djangosaml2.middleware.SamlSessionMiddleware', + "djangosaml2.middleware.SamlSessionMiddleware", ] -Ensure your main ``urls.py`` contains the ``openwisp_users.accounts.urls``: +Ensure your main ``urls.py`` contains the +``openwisp_users.accounts.urls``: .. code-block:: python urlpatterns = [ # .. other urls ... - path('accounts/', include('openwisp_users.accounts.urls')), + path("accounts/", include("openwisp_users.accounts.urls")), ] Configure the djangosaml2 settings @@ -117,25 +122,28 @@ the right organization: Log in with SSO -Substitute ``openwisp2.mywifiproject.com``, ``https://captivepage.mywifiproject.com`` -and ``default`` with the hostname of your openwisp-radius instance, your captive -page and the organization slug respectively. +Substitute ``openwisp2.mywifiproject.com``, +``https://captivepage.mywifiproject.com`` and ``default`` with the +hostname of your openwisp-radius instance, your captive page and the +organization slug respectively. -Alternatively, you can take a look at -`openwisp-wifi-login-pages `_, -which provides buttons for Single Sign-On (SAML) by default. +Alternatively, you can take a look at `openwisp-wifi-login-pages +`_, which provides +buttons for Single Sign-On (SAML) by default. .. _logout: Logout ------ -When logging out a user which logged in via SAML, the captive page -should also call the SAML logout URL: ``/radius/saml2/logout/``. +When logging out a user which logged in via SAML, the captive page should +also call the SAML logout URL: ``/radius/saml2/logout/``. -The `openwisp-wifi-login-pages `_ -app supports this with minimal configuration, refer to the -`"Configuring SAML Login & Logout" `_ +The `openwisp-wifi-login-pages +`_ app supports +this with minimal configuration, refer to the `"Configuring SAML Login & +Logout" +`_ section. Settings @@ -151,18 +159,19 @@ FAQs Preventing change in username of a registered user ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The ``djangosaml2`` library requires configuring ``SAML_DJANGO_USER_MAIN_ATTRIBUTE`` -setting which serves as the primary lookup value for User objects. -Whenever a user logs in or registers through the SAML method, -a database query is made to check whether such a user already exists. -This lookup is done using the value of ``SAML_DJANGO_USER_MAIN_ATTRIBUTE`` setting. -If a match is found, the details of the user are updated with the -information received from SAML Identity Provider. - -If a user (who has registered on OpenWISP with a different method from SAML) -logs into OpenWISP with SAML, then the default behaviour of OpenWISP RADIUS -prevents updating username of this user. Because, this operation could -render the user's old credentials useless. If you want to update the username -in such scenarios with details received from Identity Provider, set -:ref:`OPENWISP_RADIUS_SAML_UPDATES_PRE_EXISTING_USERNAME ` -to ``True``. +The ``djangosaml2`` library requires configuring +``SAML_DJANGO_USER_MAIN_ATTRIBUTE`` setting which serves as the primary +lookup value for User objects. Whenever a user logs in or registers +through the SAML method, a database query is made to check whether such a +user already exists. This lookup is done using the value of +``SAML_DJANGO_USER_MAIN_ATTRIBUTE`` setting. If a match is found, the +details of the user are updated with the information received from SAML +Identity Provider. + +If a user (who has registered on OpenWISP with a different method from +SAML) logs into OpenWISP with SAML, then the default behaviour of OpenWISP +RADIUS prevents updating username of this user. Because, this operation +could render the user's old credentials useless. If you want to update the +username in such scenarios with details received from Identity Provider, +set :ref:`OPENWISP_RADIUS_SAML_UPDATES_PRE_EXISTING_USERNAME +` to ``True``. diff --git a/docs/source/user/settings.rst b/docs/source/user/settings.rst index e2d8c233..8632b268 100644 --- a/docs/source/user/settings.rst +++ b/docs/source/user/settings.rst @@ -1,15 +1,16 @@ Available settings ------------------- +================== Admin related settings -====================== +---------------------- -These settings control details of the administration interface of openwisp-radius. +These settings control details of the administration interface of +openwisp-radius. .. note:: - The values of overridden settings fields do not change even when - the global defaults are changed. + The values of overridden settings fields do not change even when the + global defaults are changed. ``OPENWISP_RADIUS_EDITABLE_ACCOUNTING`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -30,39 +31,39 @@ Whether ``postauth`` logs are editable from the django admin or not. **Default**: ``False`` -Direct editing of group checks items is disabled by default because -these can be edited through inline items in the Radius Group -admin (Freeradius > Groups). +Direct editing of group checks items is disabled by default because these +can be edited through inline items in the Radius Group admin (Freeradius > +Groups). *This is done with the aim of simplifying the admin interface and avoid overwhelming users with too many options*. -If for some reason you need to enable direct editing of group checks -you can do so by setting this to ``True``. +If for some reason you need to enable direct editing of group checks you +can do so by setting this to ``True``. ``OPENWISP_RADIUS_GROUPREPLY_ADMIN`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **Default**: ``False`` -Direct editing of group reply items is disabled by default because -these can be edited through inline items in the Radius Group -admin (Freeradius > Groups). +Direct editing of group reply items is disabled by default because these +can be edited through inline items in the Radius Group admin (Freeradius > +Groups). *This is done with the aim of simplifying the admin interface and avoid overwhelming users with too many options*. -If for some reason you need to enable direct editing of group replies -you can do so by setting this to ``True``. +If for some reason you need to enable direct editing of group replies you +can do so by setting this to ``True``. ``OPENWISP_RADIUS_USERGROUP_ADMIN`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **Default**: ``False`` -Direct editing of user group items (``radusergroup``) is disabled by default -because these can be edited through inline items in the User -admin (Users and Organizations > Users). +Direct editing of user group items (``radusergroup``) is disabled by +default because these can be edited through inline items in the User admin +(Users and Organizations > Users). *This is done with the aim of simplifying the admin interface and avoid overwhelming users with too many options*. @@ -75,17 +76,17 @@ you can do so by setting this to ``True``. **Default**: ``False`` -The functionality of editing a user's ``RadiusToken`` directly -through an inline from the user admin page is disabled by default. +The functionality of editing a user's ``RadiusToken`` directly through an +inline from the user admin page is disabled by default. *This is done with the aim of simplifying the admin interface and avoid overwhelming users with too many options*. -If for some reason you need to enable editing user's ``RadiusToken`` -from the user admin page, you can do so by setting this to ``True``. +If for some reason you need to enable editing user's ``RadiusToken`` from +the user admin page, you can do so by setting this to ``True``. Model related settings -====================== +---------------------- These settings control details of the openwisp-radius model classes. @@ -101,16 +102,16 @@ The default encryption format for storing radius check values. **Default**: ``[]`` -A list of disabled encryption formats, by default all formats are -enabled in order to keep backward compatibility with legacy systems. +A list of disabled encryption formats, by default all formats are enabled +in order to keep backward compatibility with legacy systems. ``OPENWISP_RADIUS_BATCH_DEFAULT_PASSWORD_LENGTH`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **Default**: ``8`` -The default password length of the auto generated passwords while -batch addition of users from the csv. +The default password length of the auto generated passwords while batch +addition of users from the csv. ``OPENWISP_RADIUS_BATCH_DELETE_EXPIRED`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -122,7 +123,8 @@ It is the number of months after which the expired users are deleted. ``OPENWISP_RADIUS_BATCH_PDF_TEMPLATE`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -It is the template used to generate the pdf when users are being generated using the batch add users feature using the prefix. +It is the template used to generate the pdf when users are being generated +using the batch add users feature using the prefix. The value should be the absolute path to the template of the pdf. @@ -139,9 +141,7 @@ the following to your project ``settings.py``: .. code-block:: python - OPENWISP_RADIUS_EXTRA_NAS_TYPES = ( - ('cisco', 'Cisco Router'), - ) + OPENWISP_RADIUS_EXTRA_NAS_TYPES = (("cisco", "Cisco Router"),) .. _openwisp_radius_freeradius_allowed_hosts: @@ -150,35 +150,37 @@ the following to your project ``settings.py``: **Default**: ``[]`` -List of host IP addresses or subnets allowed to consume the freeradius -API endpoints (Authorize, Accounting and Postauth), i.e the value -of this option should be the IP address of your freeradius -instance. Example: If your freeradius instance is running on -the same host machine as OpenWISP, the value should be ``127.0.0.1``. -Similarly, if your freeradius instance is on a different host in -the private network, the value should be the private IP of freeradius -host like ``192.0.2.50``. If your freeradius is on a public network, -please use the public IP of your freeradius instance. +List of host IP addresses or subnets allowed to consume the freeradius API +endpoints (Authorize, Accounting and Postauth), i.e the value of this +option should be the IP address of your freeradius instance. Example: If +your freeradius instance is running on the same host machine as OpenWISP, +the value should be ``127.0.0.1``. Similarly, if your freeradius instance +is on a different host in the private network, the value should be the +private IP of freeradius host like ``192.0.2.50``. If your freeradius is +on a public network, please use the public IP of your freeradius instance. You can use subnets when freeradius is hosted on a variable IP, eg: - ``198.168.0.0/24`` to allow the entire LAN. - ``0.0.0.0/0`` to allow any address (useful for development / testing). -This value can be overridden per organization in the organization -change page. You can skip setting this option if you intend to set -it from organization change page for each organization. +This value can be overridden per organization in the organization change +page. You can skip setting this option if you intend to set it from +organization change page for each organization. .. image:: /images/freeradius_allowed_hosts.png - :alt: Organization change page freeradius settings + :alt: Organization change page freeradius settings .. code-block:: python - OPENWISP_RADIUS_FREERADIUS_ALLOWED_HOSTS = ['127.0.0.1', '192.0.2.10', '192.168.0.0/24'] + OPENWISP_RADIUS_FREERADIUS_ALLOWED_HOSTS = [ + "127.0.0.1", + "192.0.2.10", + "192.168.0.0/24", + ] -If this option and organization change page option are both -empty, then all freeradius API requests for the organization -will return ``403``. +If this option and organization change page option are both empty, then +all freeradius API requests for the organization will return ``403``. .. _coa_enabled_setting: @@ -187,47 +189,47 @@ will return ``403``. **Default**: ``False``` -If set to ``True``, openwisp-radius will update the NAS with the -user's current RADIUS attributes whenever the ``RadiusGroup`` of -user is changed. This allow enforcing of rate limits on active -RADIUS sessions without requiring users to re-authenticate. For -more details, :ref:`read the dedicated section for configuring -openwisp-radius and NAS for using CoA `. +If set to ``True``, openwisp-radius will update the NAS with the user's +current RADIUS attributes whenever the ``RadiusGroup`` of user is changed. +This allow enforcing of rate limits on active RADIUS sessions without +requiring users to re-authenticate. For more details, :ref:`read the +dedicated section for configuring openwisp-radius and NAS for using CoA +`. -This can be overridden for each organization separately -via the organization radius settings section of the admin interface. +This can be overridden for each organization separately via the +organization radius settings section of the admin interface. .. image:: /images/organization_coa_enabled.png - :alt: CoA enabled + :alt: CoA enabled ```RADCLIENT_ATTRIBUTE_DICTIONARIES``` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -+--------------+----------+ -| **type**: | ``list`` | -+--------------+----------+ -| **default**: | ``[]`` | -+--------------+----------+ +============ ======== +**type**: ``list`` +**default**: ``[]`` +============ ======== -List of absolute file paths of additional RADIUS dictionaries used -for RADIUS attribute mapping. +List of absolute file paths of additional RADIUS dictionaries used for +RADIUS attribute mapping. .. note:: - A `default dictionary `_ - is shipped with openwisp-radius. Any dictionary added using this setting - will be used alongside the default dictionary. + A `default dictionary + `_ + is shipped with openwisp-radius. Any dictionary added using this + setting will be used alongside the default dictionary. ``OPENWISP_RADIUS_MAX_CSV_FILE_SIZE`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -+--------------+----------------------------+ -| **type**: | ``int`` | -+--------------+----------------------------+ -| **default**: | `5 * 1024 * 1024` (5 MB) | -+--------------+----------------------------+ +============ ======================== +**type**: ``int`` +**default**: `5 * 1024 * 1024` (5 MB) +============ ======================== -This setting can be used to set the maximum size limit for firmware images, eg: +This setting can be used to set the maximum size limit for firmware +images, eg: .. code-block:: python @@ -235,23 +237,24 @@ This setting can be used to set the maximum size limit for firmware images, eg: .. note:: - The numeric value represents the size of files in bytes. - Setting this to ``None`` will mean there's no max size. + The numeric value represents the size of files in bytes. Setting this + to ``None`` will mean there's no max size. ``OPENWISP_RADIUS_PRIVATE_STORAGE_INSTANCE`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -+--------------+-------------------------------------------------------------------------------------+ -| **type**: | ``str`` | -+--------------+-------------------------------------------------------------------------------------+ -| **default**: | ``openwisp_radius.private_storage.storage.private_file_system_storage`` | -+--------------+-------------------------------------------------------------------------------------+ + +============ ======================================================================= +**type**: ``str`` +**default**: ``openwisp_radius.private_storage.storage.private_file_system_storage`` +============ ======================================================================= Dotted path to an instance of any one of the storage classes in -`private_storage `_. +`private_storage +`_. This instance is used for storing csv files of batch imports of users. -By default, an instance of ``private_storage.storage.files.PrivateFileSystemStorage`` -is used. +By default, an instance of +``private_storage.storage.files.PrivateFileSystemStorage`` is used. .. _openwisp_radius_called_station_ids: @@ -261,8 +264,9 @@ is used. **Default**: ``{}`` This setting allows to specify the parameters to connect to the different -OpenVPN management interfaces available for an organization. This setting is used by the -:ref:`convert_called_station_id ` command. +OpenVPN management interfaces available for an organization. This setting +is used by the :ref:`convert_called_station_id +` command. It should contain configuration in following format: @@ -271,20 +275,20 @@ It should contain configuration in following format: OPENWISP_RADIUS_CALLED_STATION_IDS = { # UUID of the organization for which settings are being specified # In this example 'default' - '': { - 'openvpn_config': [ + "": { + "openvpn_config": [ { # Host address of OpenVPN management - 'host': '', + "host": "", # Port of OpenVPN management interface. Defaults to 7505 (integer) - 'port': 7506, + "port": 7506, # Password of OpenVPN management interface (optional) - 'password': '', + "password": "", } ], # List of CALLED STATION IDs that has to be converted, # These look like: 00:27:22:F3:FA:F1:gw1.openwisp.org - 'unconverted_ids': [''], + "unconverted_ids": [""], } } @@ -294,8 +298,10 @@ It should contain configuration in following format: **Default**: ``False`` If set to ``True``, "Called Station ID" of a RADIUS session will be -converted (as per configuration defined in :ref:`OPENWISP_RADIUS_CALLED_STATION_IDS `) -just after the RADIUS session is created. +converted (as per configuration defined in +:ref:`OPENWISP_RADIUS_CALLED_STATION_IDS +`) just after the RADIUS session is +created. .. _openwisp_radius_openvpn_datetime_format: @@ -304,56 +310,55 @@ just after the RADIUS session is created. **Default**: ``u'%a %b %d %H:%M:%S %Y'`` -Specifies the datetime format of OpenVPN management status parser used by the -:ref:`convert_called_station_id ` -command. +Specifies the datetime format of OpenVPN management status parser used by +the :ref:`convert_called_station_id ` command. ``OPENWISP_RADIUS_UNVERIFY_INACTIVE_USERS`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **Default**: ``0`` (disabled) -Number of days from user's ``last_login`` after which the -user will be flagged as *unverified*. +Number of days from user's ``last_login`` after which the user will be +flagged as *unverified*. -When set to ``0``, the feature would be disabled and the user will -not be flagged as *unverified*. +When set to ``0``, the feature would be disabled and the user will not be +flagged as *unverified*. ``OPENWISP_RADIUS_DELETE_INACTIVE_USERS`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **Default**: ``0`` (disabled) -Number of days from user's ``last_login`` after which the -user will be deleted. - -When set to ``0``, the feature would be disabled and the user will -not be deleted. +Number of days from user's ``last_login`` after which the user will be +deleted. +When set to ``0``, the feature would be disabled and the user will not be +deleted. API and user token related settings -=================================== +----------------------------------- -These settings control details related to the API and the radius user token. +These settings control details related to the API and the radius user +token. ``OPENWISP_RADIUS_API_URLCONF`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **Default**: ``None`` -Changes the urlconf option of django urls to point the RADIUS API -urls to another installed module, example, ``myapp.urls`` -(useful when you have a seperate API instance.) +Changes the urlconf option of django urls to point the RADIUS API urls to +another installed module, example, ``myapp.urls`` (useful when you have a +seperate API instance.) ``OPENWISP_RADIUS_API_BASEURL`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **Default**: ``/`` (points to same server) -If you have a seperate instance of openwisp-radius API on a -different domain, you can use this option to change the base of the image -download URL, this will enable you to point to your API server's domain, -example value: ``https://myradius.myapp.com``. +If you have a seperate instance of openwisp-radius API on a different +domain, you can use this option to change the base of the image download +URL, this will enable you to point to your API server's domain, example +value: ``https://myradius.myapp.com``. .. _openwisp_radius_api: @@ -371,9 +376,10 @@ Indicates whether the REST API of openwisp-radius is enabled or not. Radius user tokens are used for authorizing users. -When this setting is ``True`` radius user tokens are deleted right after a successful -authorization is performed. This reduces the possibility of attackers reusing -the access tokens and posing as other users if they manage to intercept it somehow. +When this setting is ``True`` radius user tokens are deleted right after a +successful authorization is performed. This reduces the possibility of +attackers reusing the access tokens and posing as other users if they +manage to intercept it somehow. .. _openwisp_radius_api_authorize_reject: @@ -386,27 +392,29 @@ Indicates wether the :ref:`Authorize API view ` will return ``{"control:Auth-Type": "Reject"}`` or not. Rejecting an authorization request explicitly will prevent freeradius from -attempting to perform authorization with other mechanisms (eg: radius checks, LDAP, etc.). +attempting to perform authorization with other mechanisms (eg: radius +checks, LDAP, etc.). -When set to ``False``, if an authorization request fails, the API will respond with -``None``, which will allow freeradius to keep attempting to authorize the request -with other freeradius modules. +When set to ``False``, if an authorization request fails, the API will +respond with ``None``, which will allow freeradius to keep attempting to +authorize the request with other freeradius modules. -Set this to ``True`` if you are performing authorization exclusively through the REST API. +Set this to ``True`` if you are performing authorization exclusively +through the REST API. ``OPENWISP_RADIUS_API_ACCOUNTING_AUTO_GROUP`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **Default**: ``True`` -When this setting is enabled, every accounting instance saved from the API will have -its ``groupname`` attribute automatically filled in. -The value filled in will be the ``groupname`` of the ``RadiusUserGroup`` of the highest -priority among the RadiusUserGroups related to the user with the ``username`` as in the -accounting instance. -In the event there is no user in the database corresponding to the ``username`` in the -accounting instance, the failure will be logged with ``warning`` level but the accounting -will be saved as usual. +When this setting is enabled, every accounting instance saved from the API +will have its ``groupname`` attribute automatically filled in. The value +filled in will be the ``groupname`` of the ``RadiusUserGroup`` of the +highest priority among the RadiusUserGroups related to the user with the +``username`` as in the accounting instance. In the event there is no user +in the database corresponding to the ``username`` in the accounting +instance, the failure will be logged with ``warning`` level but the +accounting will be saved as usual. .. _openwisp_radius_allowed_mobile_prefixes: @@ -415,28 +423,30 @@ will be saved as usual. **Default**: ``[]`` -This setting is used to specify a list of international mobile prefixes which should -be allowed to register into the system via the :ref:`user registration API `. +This setting is used to specify a list of international mobile prefixes +which should be allowed to register into the system via the :ref:`user +registration API `. -That is, only users with phone numbers using the specified international prefixes will -be allowed to register. +That is, only users with phone numbers using the specified international +prefixes will be allowed to register. -Leaving this unset or setting it to an empty list (``[]``) will effectively allow -any international mobile prefix to register (which is the default setting). +Leaving this unset or setting it to an empty list (``[]``) will +effectively allow any international mobile prefix to register (which is +the default setting). For example: .. code-block:: python - OPENWISP_RADIUS_ALLOWED_MOBILE_PREFIXES = ['+44', '+237'] + OPENWISP_RADIUS_ALLOWED_MOBILE_PREFIXES = ["+44", "+237"] -Using the setting above will only allow phone numbers from the UK (``+44``) -or Cameroon (``+237``). +Using the setting above will only allow phone numbers from the UK +(``+44``) or Cameroon (``+237``). .. note:: - This setting is applicable only for organizations - which have :ref:`enabled the SMS verification option + This setting is applicable only for organizations which have + :ref:`enabled the SMS verification option `. ``OPENWISP_RADIUS_ALLOW_FIXED_LINE_OR_MOBILE`` @@ -444,10 +454,10 @@ or Cameroon (``+237``). **Default**: ``False`` -OpenWISP RADIUS only allow using mobile phone numbers for user registration. -This can cause issues in regions where fixed line and mobile phone numbers - uses the same pattern (e.g. USA). Setting the value to ``True`` -would make phone number type checking less strict. +OpenWISP RADIUS only allow using mobile phone numbers for user +registration. This can cause issues in regions where fixed line and mobile +phone numbers uses the same pattern (e.g. USA). Setting the value to +``True`` would make phone number type checking less strict. .. _openwisp_radius_optional_registration_fields: @@ -459,16 +469,16 @@ would make phone number type checking less strict. .. code-block:: python { - 'first_name': 'disabled', - 'last_name': 'disabled', - 'birth_date': 'disabled', - 'location': 'disabled', + "first_name": "disabled", + "last_name": "disabled", + "birth_date": "disabled", + "location": "disabled", } This global setting is used to specify if the optional user fields -(``first_name``, ``last_name``, ``location`` and ``birth_date``) -shall be disabled (hence ignored), allowed or required in the -:ref:`User Registration API `. +(``first_name``, ``last_name``, ``location`` and ``birth_date``) shall be +disabled (hence ignored), allowed or required in the :ref:`User +Registration API `. The allowed values are: @@ -481,32 +491,31 @@ For example: .. code-block:: python OPENWISP_RADIUS_OPTIONAL_REGISTRATION_FIELDS = { - 'first_name': 'disabled', - 'last_name': 'disabled', - 'birth_date': 'mandatory', - 'location': 'allowed', + "first_name": "disabled", + "last_name": "disabled", + "birth_date": "mandatory", + "location": "allowed", } Means: -- ``first_name`` and ``last_name`` fields are not required and their values - if provided are ignored. -- ``location`` field is not required but its value will - be saved to the database if provided. -- ``birth_date`` field is required and a ``ValidationError`` - exception is raised if its value is not provided. +- ``first_name`` and ``last_name`` fields are not required and their + values if provided are ignored. +- ``location`` field is not required but its value will be saved to the + database if provided. +- ``birth_date`` field is required and a ``ValidationError`` exception is + raised if its value is not provided. -The setting for each field can also be overridden at organization level -if needed, by going to -``Home › Users and Organizations › Organizations > Edit organization`` and -then scrolling down to ``ORGANIZATION RADIUS SETTINGS``. +The setting for each field can also be overridden at organization level if +needed, by going to ``Home › Users and Organizations › Organizations > +Edit organization`` and then scrolling down to ``ORGANIZATION RADIUS +SETTINGS``. .. image:: /images/optional_fields.png :alt: optional field setting -By default the fields at organization level hold a ``NULL`` value, -which means that the global setting specified in ``settings.py`` will -be used. +By default the fields at organization level hold a ``NULL`` value, which +means that the global setting specified in ``settings.py`` will be used. ``OPENWISP_RADIUS_PASSWORD_RESET_URLS`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -514,47 +523,52 @@ be used. .. note:: This setting can be overridden for each organization in the - organization admin page, the setting implementation is left - for backward compatibility but may be deprecated in the future. + organization admin page, the setting implementation is left for + backward compatibility but may be deprecated in the future. **Default**: .. code-block:: python { - '__all__': 'https://{site}/{organization}/password/reset/confirm/{uid}/{token}' + "__all__": "https://{site}/{organization}/password/reset/confirm/{uid}/{token}" } -A dictionary representing the frontend URLs through which end users can complete -the password reset operation. +A dictionary representing the frontend URLs through which end users can +complete the password reset operation. -The frontend could be `openwisp-wifi-login-pages `_ -or another in-house captive page solution. +The frontend could be `openwisp-wifi-login-pages +`_ or another +in-house captive page solution. -Keys of the dictionary must be either UUID of organizations or ``__all__``, which is the fallback URL -that will be used in case there's no customized URL for a specific organization. +Keys of the dictionary must be either UUID of organizations or +``__all__``, which is the fallback URL that will be used in case there's +no customized URL for a specific organization. -The password reset URL must contain the "{token}" and "{uid}" placeholders. +The password reset URL must contain the "{token}" and "{uid}" +placeholders. The meaning of the variables in the string is the following: -- ``{site}``: site domain as defined in the - `django site framework `_ - (defaults to example.com and an be changed through the django admin) +- ``{site}``: site domain as defined in the `django site framework + `_ (defaults + to example.com and an be changed through the django admin) - ``{organization}``: organization slug - ``{uid}``: uid of the password reset request - ``{token}``: token of the password reset request -If you're using `openwisp-wifi-login-pages `_, -the configuration is fairly simple, in case the nodejs app is installed in the same domain -of openwisp-radius, you only have to ensure the domain field in the main Site object is correct, -if instead the nodejs app is deployed on a different domain, say ``login.wifiservice.com``, -the configuration should be simply changed to: +If you're using `openwisp-wifi-login-pages +`_, the +configuration is fairly simple, in case the nodejs app is installed in the +same domain of openwisp-radius, you only have to ensure the domain field +in the main Site object is correct, if instead the nodejs app is deployed +on a different domain, say ``login.wifiservice.com``, the configuration +should be simply changed to: .. code-block:: python { - '__all__': 'https://login.wifiservice.com/{organization}/password/reset/confirm/{uid}/{token}' + "__all__": "https://login.wifiservice.com/{organization}/password/reset/confirm/{uid}/{token}" } .. _openwisp_radius_registration_api_enabled: @@ -564,23 +578,24 @@ the configuration should be simply changed to: **Default**: ``True`` -Indicates whether the API registration view is enabled or not. -When this setting is disabled (i.e. ``False``), the registration API view is disabled. +Indicates whether the API registration view is enabled or not. When this +setting is disabled (i.e. ``False``), the registration API view is +disabled. -**This setting can be overridden in individual organizations -via the admin interface**, by going to *Organizations* -then edit a specific organization and scroll down to -*"Organization RADIUS settings"*, as shown in the screenshot below. +**This setting can be overridden in individual organizations via the admin +interface**, by going to *Organizations* then edit a specific organization +and scroll down to *"Organization RADIUS settings"*, as shown in the +screenshot below. .. image:: /images/organization_registration_setting.png - :alt: Organization RADIUS settings + :alt: Organization RADIUS settings .. note:: - We recommend using the override via the admin interface only when there - are special organizations which need a different configuration, otherwise, - if all the organization use the same configuration, we recommend - changing the global setting. + We recommend using the override via the admin interface only when + there are special organizations which need a different configuration, + otherwise, if all the organization use the same configuration, we + recommend changing the global setting. .. _openwisp_radius_sms_verification_enabled: @@ -594,15 +609,16 @@ then edit a specific organization and scroll down to If you're looking for instructions on how to configure SMS sending, see :ref:`SMS Token Related Settings `. -If :ref:`Identity verification is required `, -this setting indicates whether users who sign up should be required to -verify their mobile phone number via SMS. +If :ref:`Identity verification is required +`, this setting indicates +whether users who sign up should be required to verify their mobile phone +number via SMS. -This can be overridden for each organization separately -via the organization radius settings section of the admin interface. +This can be overridden for each organization separately via the +organization radius settings section of the admin interface. .. image:: /images/organization_sms_verification_setting.png - :alt: SMS verification enabled + :alt: SMS verification enabled .. _openwisp_radius_needs_identity_verification: @@ -611,68 +627,69 @@ via the organization radius settings section of the admin interface. **Default**: ``False`` -Indicates whether MAC address roaming is supported. -When this setting is enabled (i.e. ``True``), -MAC address roaming is enabled for all organizations. +Indicates whether MAC address roaming is supported. When this setting is +enabled (i.e. ``True``), MAC address roaming is enabled for all +organizations. -**This setting can be overridden in individual organizations -via the admin interface**, by going to *Organizations* -then edit a specific organization and scroll down to -*"Organization RADIUS settings"*, as shown in the screenshot below. +**This setting can be overridden in individual organizations via the admin +interface**, by going to *Organizations* then edit a specific organization +and scroll down to *"Organization RADIUS settings"*, as shown in the +screenshot below. .. image:: /images/mac-address-roaming.png - :alt: Organization MAC Address Roaming settings + :alt: Organization MAC Address Roaming settings .. note:: - We recommend using the override via the admin interface only when there - are special organizations which need a different configuration, otherwise, - if all the organization use the same configuration, we recommend - changing the global setting. + We recommend using the override via the admin interface only when + there are special organizations which need a different configuration, + otherwise, if all the organization use the same configuration, we + recommend changing the global setting. ``OPENWISP_RADIUS_NEEDS_IDENTITY_VERIFICATION`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **Default**: ``False`` -Indicates whether organizations require a user to be verified in order to login. -This can be overridden globally or for each organization separately via the admin -interface. +Indicates whether organizations require a user to be verified in order to +login. This can be overridden globally or for each organization separately +via the admin interface. -If this is enabled, each registered user should be verified using a verification method. -The following choices are available by default: +If this is enabled, each registered user should be verified using a +verification method. The following choices are available by default: - ``''`` (empty string): unspecified - ``manual``: manually created - ``email``: Email (No Identity Verification) -- ``mobile_phone``: Mobile phone number - :ref:`verification via SMS ` +- ``mobile_phone``: Mobile phone number :ref:`verification via SMS + ` - ``social_login``: :ref:`social login feature ` .. note:: - Of the methods listed above, ``mobile_phone`` is generally - accepted as a legal and valid form of indirect identity verification - in those countries who require to provide - a valid ID document before buying a SIM card. + Of the methods listed above, ``mobile_phone`` is generally accepted as + a legal and valid form of indirect identity verification in those + countries who require to provide a valid ID document before buying a + SIM card. - Organizations which are required by law to identify their users - before allowing them to access the network (eg: ISPs) can restrict - users to register only through this method and can configure the system - to only :ref:`allow international mobile prefixes ` - of countries which require a valid ID document to buy a SIM card. + Organizations which are required by law to identify their users before + allowing them to access the network (eg: ISPs) can restrict users to + register only through this method and can configure the system to only + :ref:`allow international mobile prefixes + ` of countries which require + a valid ID document to buy a SIM card. **Disclaimer:** these are just suggestions on possible configurations of OpenWISP RADIUS and must not be considered as legal advice. Adding support for more registration/verification methods -######################################################### ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ For those who need to implement additional registration and identity verification methods, such as supporting a National ID card, new methods -can be added or an existing method can be removed using -the ``register_registration_method`` -and ``unregister_registration_method`` functions respectively. +can be added or an existing method can be removed using the +``register_registration_method`` and ``unregister_registration_method`` +functions respectively. For example: @@ -684,49 +701,49 @@ For example: ) # Enable registering via national digital ID - register_registration_method('national_id', 'National Digital ID') + register_registration_method("national_id", "National Digital ID") # Remove mobile verification method - unregister_registration_method('mobile_phone') + unregister_registration_method("mobile_phone") .. note:: - Both functions will fail if a specific registration method - is already registered or unregistered, unless the keyword argument - ``fail_loud`` is passed as ``False`` (this useful when working with - additional registration methods which are supported by multiple - custom modules). + Both functions will fail if a specific registration method is already + registered or unregistered, unless the keyword argument ``fail_loud`` + is passed as ``False`` (this useful when working with additional + registration methods which are supported by multiple custom modules). Pass ``strong_identity`` as ``True`` to to indicate that users who register using that method have indirectly verified their identity - (eg: :ref:`SMS verification - `, - credit card, national ID card, etc). + (eg: :ref:`SMS verification + `, credit card, national ID + card, etc). .. warning:: - If you need to implement a registration method that needs to grant limited - internet access to unverified users so they can complete their - verification process online on other websites which cannot be predicted - and hence cannot be added to the walled garden, you can pass + If you need to implement a registration method that needs to grant + limited internet access to unverified users so they can complete their + verification process online on other websites which cannot be + predicted and hence cannot be added to the walled garden, you can pass ``authorize_unverified=True`` to the ``register_registration_method`` function. - This is needed to implement payment flows in which users insert - a specific 3D secure code in the website of their bank. - Keep in mind that you should create a specific limited radius group - for these unverified users. + This is needed to implement payment flows in which users insert a + specific 3D secure code in the website of their bank. Keep in mind + that you should create a specific limited radius group for these + unverified users. Payment flows and credit/debit card verification are fully implemented in **OpenWISP Subscriptions**, a premium module available only to - customers of the - :ref:`commercial support offering of OpenWISP `. + customers of the :ref:`commercial support offering of OpenWISP + `. Email related settings -====================== +---------------------- -Emails can be sent to users whose usernames or passwords have been auto-generated. -The content of these emails can be customized with the settings explained below. +Emails can be sent to users whose usernames or passwords have been +auto-generated. The content of these emails can be customized with the +settings explained below. .. _openwisp_radius_batch_mail_subject: @@ -735,7 +752,8 @@ The content of these emails can be customized with the settings explained below. **Default**: ``Credentials`` -It is the subject of the mail to be sent to the users. Eg: ``Login Credentials``. +It is the subject of the mail to be sent to the users. Eg: ``Login +Credentials``. .. _openwisp_radius_batch_mail_message: @@ -744,10 +762,11 @@ It is the subject of the mail to be sent to the users. Eg: ``Login Credentials`` **Default**: ``username: {}, password: {}`` -The message should be a string in the format ``Your username is {} and password is {}``. +The message should be a string in the format ``Your username is {} and +password is {}``. -The text could be anything but should have the format string operator ``{}`` for -``.format`` operations to work. +The text could be anything but should have the format string operator +``{}`` for ``.format`` operations to work. .. _openwisp_radius_batch_mail_sender: @@ -756,28 +775,31 @@ The text could be anything but should have the format string operator ``{}`` for **Default**: ``settings.DEFAULT_FROM_EMAIL`` -It is the sender email which is also to be configured in the SMTP settings. -The default sender email is a common setting from the -`Django core settings `_ -under ``DEFAULT_FROM_EMAIL``. -Currently, ``DEFAULT_FROM_EMAIL`` is set to to ``webmaster@localhost``. +It is the sender email which is also to be configured in the SMTP +settings. The default sender email is a common setting from the `Django +core settings +`_ +under ``DEFAULT_FROM_EMAIL``. Currently, ``DEFAULT_FROM_EMAIL`` is set to +to ``webmaster@localhost``. .. _counter_related_settings: Counter related settings -======================== +------------------------ .. _counters_setting: ``OPENWISP_RADIUS_COUNTERS`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -**Default**: depends on the database backend in use, -see :ref:`counters` to find out what are the default counters enabled. +**Default**: depends on the database backend in use, see :ref:`counters` +to find out what are the default counters enabled. -It's a list of strings, each representing the python path to a counter class. +It's a list of strings, each representing the python path to a counter +class. -It may be set to an empty list or tuple to disable the counter feature, eg: +It may be set to an empty list or tuple to disable the counter feature, +eg: .. code-block:: python @@ -790,11 +812,11 @@ to include the new classes, eg: OPENWISP_RADIUS_COUNTERS = [ # default counters for PostgreSQL, may be removed if not needed - 'openwisp_radius.counters.postgresql.daily_counter.DailyCounter', - 'openwisp_radius.counters.postgresql.daily_traffic_counter.DailyTrafficCounter', + "openwisp_radius.counters.postgresql.daily_counter.DailyCounter", + "openwisp_radius.counters.postgresql.daily_traffic_counter.DailyTrafficCounter", # custom counters - 'myproject.counters.CustomCounter1', - 'myproject.counters.CustomCounter2', + "myproject.counters.CustomCounter1", + "myproject.counters.CustomCounter2", ] .. _traffic_counter_check_name: @@ -804,10 +826,10 @@ to include the new classes, eg: **Default**: ``Max-Daily-Session-Traffic`` -Used by :ref:`daily_traffic_counter`, -it indicates the check attribute which is looked for -in the database to find the maximum amount of daily traffic -which users having the default ``users`` radius group assigned can consume. +Used by :ref:`daily_traffic_counter`, it indicates the check attribute +which is looked for in the database to find the maximum amount of daily +traffic which users having the default ``users`` radius group assigned can +consume. .. _traffic_counter_reply_name: @@ -816,24 +838,23 @@ which users having the default ``users`` radius group assigned can consume. **Default**: ``CoovaChilli-Max-Total-Octets`` -Used by :ref:`daily_traffic_counter`, -it indicates the reply attribute which is returned to the NAS -to indicate how much remaining traffic users -which users having the default ``users`` radius group assigned -can consume. +Used by :ref:`daily_traffic_counter`, it indicates the reply attribute +which is returned to the NAS to indicate how much remaining traffic users +which users having the default ``users`` radius group assigned can +consume. -It should be changed according to the NAS software in use, for example, -if using PfSense, this setting should be set to ``pfSense-Max-Total-Octets``. +It should be changed according to the NAS software in use, for example, if +using PfSense, this setting should be set to ``pfSense-Max-Total-Octets``. ``OPENWISP_RADIUS_RADIUS_ATTRIBUTES_TYPE_MAP`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **Default**: ``{}`` -Used by :ref:`User Radius Usage API `, -it stores mapping of RADIUS attributes to the unit of value -enforced by the attribute, e.g. ``bytes`` for traffic counters and -``seconds`` for session time counters. +Used by :ref:`User Radius Usage API `, it stores +mapping of RADIUS attributes to the unit of value enforced by the +attribute, e.g. ``bytes`` for traffic counters and ``seconds`` for session +time counters. In the following example, the setting is configured to return ``bytes`` type in the API response for ``ChilliSpot-Max-Input-Octets`` attribute: @@ -841,15 +862,16 @@ type in the API response for ``ChilliSpot-Max-Input-Octets`` attribute: .. code-block:: python OPENWISP_RADIUS_RADIUS_ATTRIBUTES_TYPE_MAP = { - 'ChilliSpot-Max-Input-Octets': 'bytes' + "ChilliSpot-Max-Input-Octets": "bytes" } .. _social_login_settings: Social Login related settings -============================= +----------------------------- -The following settings are related to the :ref:`social login feature `. +The following settings are related to the :ref:`social login feature +`. .. _openwisp_radius_social_registration_enabled: @@ -858,29 +880,29 @@ The following settings are related to the :ref:`social login feature `. @@ -891,24 +913,24 @@ The following settings are related to the :ref:`SAML feature `. **Default**: ``False`` -Indicates whether registration using SAML is enabled or not. -When this setting is enabled (i.e. ``True``), -authentication using SAML is enabled for all organizations. +Indicates whether registration using SAML is enabled or not. When this +setting is enabled (i.e. ``True``), authentication using SAML is enabled +for all organizations. -**This setting can be overridden in individual organizations -via the admin interface**, by going to *Organizations* -then edit a specific organization and scroll down to -*"Organization RADIUS settings"*, as shown in the screenshot below. +**This setting can be overridden in individual organizations via the admin +interface**, by going to *Organizations* then edit a specific organization +and scroll down to *"Organization RADIUS settings"*, as shown in the +screenshot below. .. image:: /images/organization_saml_setting.png - :alt: Organization SAML settings + :alt: Organization SAML settings .. note:: - We recommend using the override via the admin interface only when there - are special organizations which need a different configuration, otherwise, - if all the organization use the same configuration, we recommend - changing the global setting. + We recommend using the override via the admin interface only when + there are special organizations which need a different configuration, + otherwise, if all the organization use the same configuration, we + recommend changing the global setting. ``OPENWISP_RADIUS_SAML_REGISTRATION_METHOD_LABEL`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -922,11 +944,12 @@ Sets the verbose name of SAML registration method. **Default**: ``False`` -Setting this to ``True`` will automatically flag user accounts -created during SAML sign-in as verified users (``RegisteredUser.is_verified=True``). +Setting this to ``True`` will automatically flag user accounts created +during SAML sign-in as verified users +(``RegisteredUser.is_verified=True``). -This is useful when SAML identity providers can be trusted -to be legally valid identity verifiers. +This is useful when SAML identity providers can be trusted to be legally +valid identity verifiers. .. _openwisp_radius_saml_updates_pre_existing_username: @@ -935,41 +958,40 @@ to be legally valid identity verifiers. **Default**: ``False`` -Allows updating username of a registered user with the value -received from SAML Identity Provider. Read the -:ref:`FAQs in SAML integration documentation ` -for details. +Allows updating username of a registered user with the value received from +SAML Identity Provider. Read the :ref:`FAQs in SAML integration +documentation ` for +details. .. _sms_token_related_settings: SMS token related settings -========================== +-------------------------- These settings allow to control aspects and limitations of the SMS tokens -which are sent to users for the purpose of -:ref:`verifying their mobile phone number -`. +which are sent to users for the purpose of :ref:`verifying their mobile +phone number `. -These settings are applicable only when -:ref:`SMS verification is enabled `. +These settings are applicable only when :ref:`SMS verification is enabled +`. ``SENDSMS_BACKEND`` ~~~~~~~~~~~~~~~~~~~ This setting takes a python path which points to the `django-sendsms -`__ -backend which will be used by the system to send SMS messages. +`__ backend which will be +used by the system to send SMS messages. -The list of supported SMS services can be seen in the source code of -`the django-sendsms backends +The list of supported SMS services can be seen in the source code of `the +django-sendsms backends `__. -Adding support for other SMS services can be done by subclassing -the ``BaseSmsBackend`` and implement the logic needed to talk to the -SMS service. +Adding support for other SMS services can be done by subclassing the +``BaseSmsBackend`` and implement the logic needed to talk to the SMS +service. -The value of this setting can point to any class on the python path, -so the backend doesn't have to be necessarily shipped in django-sendsms -but can be deployed in any other location. +The value of this setting can point to any class on the python path, so +the backend doesn't have to be necessarily shipped in django-sendsms but +can be deployed in any other location. ``OPENWISP_RADIUS_SMS_TOKEN_DEFAULT_VALIDITY`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1004,9 +1026,9 @@ Seconds users needs to wait before being able to request a new SMS token. **Default**: ``5`` -The max number of mistakes tolerated during verification, -after this amount of mistaken attempts, it won't be possible to -verify the token anymore and it will be necessary to request a new one. +The max number of mistakes tolerated during verification, after this +amount of mistaken attempts, it won't be possible to verify the token +anymore and it will be necessary to request a new one. ``OPENWISP_RADIUS_SMS_TOKEN_MAX_USER_DAILY`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1032,13 +1054,13 @@ The template used for sending verification code to users via SMS. .. note:: - The template should always contain ``{code}`` placeholder. - Otherwise, the sent SMS will not contain the verification code. + The template should always contain ``{code}`` placeholder. Otherwise, + the sent SMS will not contain the verification code. -This value can be overridden per organization in the organization -change page. You can skip setting this option if you intend to set -it from organization change page for each organization. Keep in mind that -the default value is translated in other languages. If the value is -customized the translations will not work, so if you need this message -to be translated in different languages you should either not change the -default value or prepare the additional translations. +This value can be overridden per organization in the organization change +page. You can skip setting this option if you intend to set it from +organization change page for each organization. Keep in mind that the +default value is translated in other languages. If the value is customized +the translations will not work, so if you need this message to be +translated in different languages you should either not change the default +value or prepare the additional translations. diff --git a/docs/source/user/social_login.rst b/docs/source/user/social_login.rst index 6b14bf15..66bcb66e 100644 --- a/docs/source/user/social_login.rst +++ b/docs/source/user/social_login.rst @@ -1,6 +1,5 @@ .. _social_login: -============ Social Login ============ @@ -8,38 +7,44 @@ Social Login The social login feature is disabled by default. - In order to enable this feature you have to follow - the :ref:`setup instructions ` below - and then activate it via :ref:`global setting or from the admin interface + In order to enable this feature you have to follow the :ref:`setup + instructions ` below and then activate it via + :ref:`global setting or from the admin interface `. -Social login is supported by generating an additional temporary token right -after users perform the social sign-in, the user is then redirected to the -captive page with two querystring parameters: ``username`` and ``token``. +Social login is supported by generating an additional temporary token +right after users perform the social sign-in, the user is then redirected +to the captive page with two querystring parameters: ``username`` and +``token``. -The captive page must recognize these two parameters and automatically perform -the submit action of the login form: ``username`` should obviously used for the -username field, while ``token`` should be used for the password field. +The captive page must recognize these two parameters and automatically +perform the submit action of the login form: ``username`` should obviously +used for the username field, while ``token`` should be used for the +password field. -The internal REST API of openwisp-radius will recognize the token and authorize -the user. +The internal REST API of openwisp-radius will recognize the token and +authorize the user. -This kind of implementation allows to implement the social login with any captive -portal which already supports the RADIUS protocol because it's totally transparent -for it, that is, the captive portal doesn't even know the user is signing-in with -a social network. +This kind of implementation allows to implement the social login with any +captive portal which already supports the RADIUS protocol because it's +totally transparent for it, that is, the captive portal doesn't even know +the user is signing-in with a social network. .. note:: - If you're building a public wifi service, we suggest - to take a look at `openwisp-wifi-login-pages `_, - which is built to work with openwisp-radius. + + If you're building a public wifi service, we suggest to take a look at + `openwisp-wifi-login-pages + `_, which is + built to work with openwisp-radius. .. _setup_social_login: Setup ----- -Install ``django-allauth``:: +Install ``django-allauth``: + +:: pip install django-allauth @@ -51,15 +56,15 @@ configure of the facebook social provider): INSTALLED_APPS = [ # ... other apps .. # apps needed for social login - 'rest_framework.authtoken', - 'django.contrib.sites', - 'allauth', - 'allauth.account', - 'allauth.socialaccount', + "rest_framework.authtoken", + "django.contrib.sites", + "allauth", + "allauth.account", + "allauth.socialaccount", # showing facebook as an example # to configure social login with other social networks # refer to the django-allauth documentation - 'allauth.socialaccount.providers.facebook', + "allauth.socialaccount.providers.facebook", ] SITE_ID = 1 @@ -68,20 +73,20 @@ configure of the facebook social provider): # to configure social login with other social networks # refer to the django-allauth documentation SOCIALACCOUNT_PROVIDERS = { - 'facebook': { - 'METHOD': 'oauth2', - 'SCOPE': ['email', 'public_profile'], - 'AUTH_PARAMS': {'auth_type': 'reauthenticate'}, - 'INIT_PARAMS': {'cookie': True}, - 'FIELDS': [ - 'id', - 'email', - 'name', - 'first_name', - 'last_name', - 'verified', + "facebook": { + "METHOD": "oauth2", + "SCOPE": ["email", "public_profile"], + "AUTH_PARAMS": {"auth_type": "reauthenticate"}, + "INIT_PARAMS": {"cookie": True}, + "FIELDS": [ + "id", + "email", + "name", + "first_name", + "last_name", + "verified", ], - 'VERIFIED_EMAIL': True, + "VERIFIED_EMAIL": True, } } @@ -91,7 +96,7 @@ Ensure your main ``urls.py`` contains the ``allauth.urls``: urlpatterns = [ # .. other urls ... - path('accounts/', include('allauth.urls')), + path("accounts/", include("allauth.urls")), ] Configure the social account application @@ -104,8 +109,9 @@ configuration of a sample facebook login app Captive page button example --------------------------- -Following the previous example configuration with facebook, in your captive page -you will need an HTML button similar to the ones in the following examples. +Following the previous example configuration with facebook, in your +captive page you will need an HTML button similar to the ones in the +following examples. This example needs the slug of the organization to assign the new user to the right organization: @@ -116,13 +122,14 @@ the right organization: class="button">Log in with Facebook -Substitute ``openwisp2.mywifiproject.com``, ``captivepage.mywifiproject.com`` -and ``default`` with the hostname of your openwisp-radius instance, your captive -page and the organization slug respectively. +Substitute ``openwisp2.mywifiproject.com``, +``captivepage.mywifiproject.com`` and ``default`` with the hostname of +your openwisp-radius instance, your captive page and the organization slug +respectively. -Alternatively, you can take a look at -`openwisp-wifi-login-pages `_, -which provides buttons for Facebook, Google and Twitter by default. +Alternatively, you can take a look at `openwisp-wifi-login-pages +`_, which provides +buttons for Facebook, Google and Twitter by default. Settings -------- diff --git a/openwisp_radius/migrations/0005_radiustoken.py b/openwisp_radius/migrations/0005_radiustoken.py index 19f03f13..d1cf0735 100644 --- a/openwisp_radius/migrations/0005_radiustoken.py +++ b/openwisp_radius/migrations/0005_radiustoken.py @@ -8,7 +8,6 @@ class Migration(migrations.Migration): - dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('openwisp_radius', '0004_default_permissions'), diff --git a/openwisp_radius/migrations/0006_add_radactt_fields.py b/openwisp_radius/migrations/0006_add_radactt_fields.py index 57d733c6..12192b30 100644 --- a/openwisp_radius/migrations/0006_add_radactt_fields.py +++ b/openwisp_radius/migrations/0006_add_radactt_fields.py @@ -6,7 +6,6 @@ class Migration(migrations.Migration): - dependencies = [('openwisp_radius', '0005_radiustoken')] operations = [ diff --git a/openwisp_radius/migrations/0008_sms_sender.py b/openwisp_radius/migrations/0008_sms_sender.py index 3f3de372..c6ba4d9c 100644 --- a/openwisp_radius/migrations/0008_sms_sender.py +++ b/openwisp_radius/migrations/0008_sms_sender.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0007_sms_verification'), ] diff --git a/openwisp_radius/migrations/0009_radbatch_user_credentials_field.py b/openwisp_radius/migrations/0009_radbatch_user_credentials_field.py index d25a2b0d..715c6373 100644 --- a/openwisp_radius/migrations/0009_radbatch_user_credentials_field.py +++ b/openwisp_radius/migrations/0009_radbatch_user_credentials_field.py @@ -5,7 +5,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0008_sms_sender'), ] diff --git a/openwisp_radius/migrations/0010_csv_private_storage.py b/openwisp_radius/migrations/0010_csv_private_storage.py index dedad843..ff38b1dc 100644 --- a/openwisp_radius/migrations/0010_csv_private_storage.py +++ b/openwisp_radius/migrations/0010_csv_private_storage.py @@ -13,7 +13,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0009_radbatch_user_credentials_field'), ] diff --git a/openwisp_radius/migrations/0011_add_null_uuid_field.py b/openwisp_radius/migrations/0011_add_null_uuid_field.py index 96cab6bc..0afbb95e 100644 --- a/openwisp_radius/migrations/0011_add_null_uuid_field.py +++ b/openwisp_radius/migrations/0011_add_null_uuid_field.py @@ -6,7 +6,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0010_csv_private_storage'), ] diff --git a/openwisp_radius/migrations/0012_populate_uuid_field.py b/openwisp_radius/migrations/0012_populate_uuid_field.py index 76bbb9c0..02d1d249 100644 --- a/openwisp_radius/migrations/0012_populate_uuid_field.py +++ b/openwisp_radius/migrations/0012_populate_uuid_field.py @@ -6,7 +6,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0011_add_null_uuid_field'), ] diff --git a/openwisp_radius/migrations/0013_remove_null_uuid_field.py b/openwisp_radius/migrations/0013_remove_null_uuid_field.py index 1e823b21..b676c21b 100644 --- a/openwisp_radius/migrations/0013_remove_null_uuid_field.py +++ b/openwisp_radius/migrations/0013_remove_null_uuid_field.py @@ -6,7 +6,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0012_populate_uuid_field'), ] diff --git a/openwisp_radius/migrations/0014_radiustoken_freeradius_auth.py b/openwisp_radius/migrations/0014_radiustoken_freeradius_auth.py index 479358a3..66767429 100644 --- a/openwisp_radius/migrations/0014_radiustoken_freeradius_auth.py +++ b/openwisp_radius/migrations/0014_radiustoken_freeradius_auth.py @@ -8,7 +8,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0013_remove_null_uuid_field'), ] diff --git a/openwisp_radius/migrations/0015_freeradius_allowed_hosts.py b/openwisp_radius/migrations/0015_freeradius_allowed_hosts.py index dcdd986f..f64c8567 100644 --- a/openwisp_radius/migrations/0015_freeradius_allowed_hosts.py +++ b/openwisp_radius/migrations/0015_freeradius_allowed_hosts.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0014_radiustoken_freeradius_auth'), ] diff --git a/openwisp_radius/migrations/0016_allowed_mobile_prefixes.py b/openwisp_radius/migrations/0016_allowed_mobile_prefixes.py index 8598d0a1..fb50dc9b 100644 --- a/openwisp_radius/migrations/0016_allowed_mobile_prefixes.py +++ b/openwisp_radius/migrations/0016_allowed_mobile_prefixes.py @@ -6,7 +6,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0015_freeradius_allowed_hosts'), ] diff --git a/openwisp_radius/migrations/0017_phonetoken_phone_number.py b/openwisp_radius/migrations/0017_phonetoken_phone_number.py index 02a7846e..535f8792 100644 --- a/openwisp_radius/migrations/0017_phonetoken_phone_number.py +++ b/openwisp_radius/migrations/0017_phonetoken_phone_number.py @@ -5,7 +5,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0016_allowed_mobile_prefixes'), ] diff --git a/openwisp_radius/migrations/0018_populate_phonetoken_phone_number.py b/openwisp_radius/migrations/0018_populate_phonetoken_phone_number.py index 0a32d2a6..3f599406 100644 --- a/openwisp_radius/migrations/0018_populate_phonetoken_phone_number.py +++ b/openwisp_radius/migrations/0018_populate_phonetoken_phone_number.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0017_phonetoken_phone_number'), ] diff --git a/openwisp_radius/migrations/0019_made_phonetoken_phone_number_required.py b/openwisp_radius/migrations/0019_made_phonetoken_phone_number_required.py index 9e619bc9..380e8059 100644 --- a/openwisp_radius/migrations/0019_made_phonetoken_phone_number_required.py +++ b/openwisp_radius/migrations/0019_made_phonetoken_phone_number_required.py @@ -5,7 +5,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0018_populate_phonetoken_phone_number'), ] diff --git a/openwisp_radius/migrations/0020_added_optional_registration_fields.py b/openwisp_radius/migrations/0020_added_optional_registration_fields.py index 62df15c6..ff4deb25 100644 --- a/openwisp_radius/migrations/0020_added_optional_registration_fields.py +++ b/openwisp_radius/migrations/0020_added_optional_registration_fields.py @@ -6,7 +6,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0019_made_phonetoken_phone_number_required'), ] diff --git a/openwisp_radius/migrations/0021_radius_user_group_unique_together.py b/openwisp_radius/migrations/0021_radius_user_group_unique_together.py index 3894c853..188b1578 100644 --- a/openwisp_radius/migrations/0021_radius_user_group_unique_together.py +++ b/openwisp_radius/migrations/0021_radius_user_group_unique_together.py @@ -5,7 +5,6 @@ class Migration(migrations.Migration): - dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('openwisp_radius', '0020_added_optional_registration_fields'), diff --git a/openwisp_radius/migrations/0022_organizationradiussettings_registration_enabled.py b/openwisp_radius/migrations/0022_organizationradiussettings_registration_enabled.py index a597fe7a..2368b751 100644 --- a/openwisp_radius/migrations/0022_organizationradiussettings_registration_enabled.py +++ b/openwisp_radius/migrations/0022_organizationradiussettings_registration_enabled.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0021_radius_user_group_unique_together'), ] diff --git a/openwisp_radius/migrations/0024_registereduser_modified.py b/openwisp_radius/migrations/0024_registereduser_modified.py index 3aebf8be..1ad2a9a3 100644 --- a/openwisp_radius/migrations/0024_registereduser_modified.py +++ b/openwisp_radius/migrations/0024_registereduser_modified.py @@ -6,7 +6,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0023_registered_user'), ] diff --git a/openwisp_radius/migrations/0025_sms_verification.py b/openwisp_radius/migrations/0025_sms_verification.py index 030d650e..27b4a411 100644 --- a/openwisp_radius/migrations/0025_sms_verification.py +++ b/openwisp_radius/migrations/0025_sms_verification.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0024_registereduser_modified'), ] diff --git a/openwisp_radius/migrations/0026_login_status_url_org_settings.py b/openwisp_radius/migrations/0026_login_status_url_org_settings.py index b9a7a176..7bda3ecd 100644 --- a/openwisp_radius/migrations/0026_login_status_url_org_settings.py +++ b/openwisp_radius/migrations/0026_login_status_url_org_settings.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0025_sms_verification'), ] diff --git a/openwisp_radius/migrations/0027_password_reset_url_org_settings.py b/openwisp_radius/migrations/0027_password_reset_url_org_settings.py index 9ddf171c..6d4f688b 100644 --- a/openwisp_radius/migrations/0027_password_reset_url_org_settings.py +++ b/openwisp_radius/migrations/0027_password_reset_url_org_settings.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0026_login_status_url_org_settings'), ] diff --git a/openwisp_radius/migrations/0028_organizationradiussettings_saml_social_registration_enabled.py b/openwisp_radius/migrations/0028_organizationradiussettings_saml_social_registration_enabled.py index 332d5872..3b2e6f06 100644 --- a/openwisp_radius/migrations/0028_organizationradiussettings_saml_social_registration_enabled.py +++ b/openwisp_radius/migrations/0028_organizationradiussettings_saml_social_registration_enabled.py @@ -5,7 +5,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0027_password_reset_url_org_settings'), ] diff --git a/openwisp_radius/migrations/0029_remove_check_customizations.py b/openwisp_radius/migrations/0029_remove_check_customizations.py index 67133839..5b678640 100644 --- a/openwisp_radius/migrations/0029_remove_check_customizations.py +++ b/openwisp_radius/migrations/0029_remove_check_customizations.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ( 'openwisp_radius', diff --git a/openwisp_radius/migrations/0030_remove_radiuscheck_notes.py b/openwisp_radius/migrations/0030_remove_radiuscheck_notes.py index 7f7883d3..541f0196 100644 --- a/openwisp_radius/migrations/0030_remove_radiuscheck_notes.py +++ b/openwisp_radius/migrations/0030_remove_radiuscheck_notes.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0029_remove_check_customizations'), ] diff --git a/openwisp_radius/migrations/0031_added_fallback_model_fields.py b/openwisp_radius/migrations/0031_added_fallback_model_fields.py index 9ac796ae..de88cf40 100644 --- a/openwisp_radius/migrations/0031_added_fallback_model_fields.py +++ b/openwisp_radius/migrations/0031_added_fallback_model_fields.py @@ -8,7 +8,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0030_remove_radiuscheck_notes'), ] diff --git a/openwisp_radius/migrations/0032_organizationradiussettings_sms_message.py b/openwisp_radius/migrations/0032_organizationradiussettings_sms_message.py index 868c68fd..399e4a91 100644 --- a/openwisp_radius/migrations/0032_organizationradiussettings_sms_message.py +++ b/openwisp_radius/migrations/0032_organizationradiussettings_sms_message.py @@ -7,7 +7,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0031_added_fallback_model_fields'), ] diff --git a/openwisp_radius/migrations/0033_alter_organizationradiussettings_password_reset_url.py b/openwisp_radius/migrations/0033_alter_organizationradiussettings_password_reset_url.py index b9532bc1..342e340f 100644 --- a/openwisp_radius/migrations/0033_alter_organizationradiussettings_password_reset_url.py +++ b/openwisp_radius/migrations/0033_alter_organizationradiussettings_password_reset_url.py @@ -8,7 +8,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0032_organizationradiussettings_sms_message'), ] diff --git a/openwisp_radius/migrations/0034_organizationradiussettings_coa_enabled.py b/openwisp_radius/migrations/0034_organizationradiussettings_coa_enabled.py index 2af8dcfe..454c5171 100644 --- a/openwisp_radius/migrations/0034_organizationradiussettings_coa_enabled.py +++ b/openwisp_radius/migrations/0034_organizationradiussettings_coa_enabled.py @@ -7,7 +7,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0033_alter_organizationradiussettings_password_reset_url'), ] diff --git a/openwisp_radius/migrations/0035_organizationradiussettings_sms_cooldown.py b/openwisp_radius/migrations/0035_organizationradiussettings_sms_cooldown.py index e36c9f72..03b4b6bc 100644 --- a/openwisp_radius/migrations/0035_organizationradiussettings_sms_cooldown.py +++ b/openwisp_radius/migrations/0035_organizationradiussettings_sms_cooldown.py @@ -6,7 +6,6 @@ class Migration(migrations.Migration): - dependencies = [ ("openwisp_radius", "0034_organizationradiussettings_coa_enabled"), ] diff --git a/openwisp_radius/migrations/0036_organizationradiussettings_mac_addr_roaming_enabled.py b/openwisp_radius/migrations/0036_organizationradiussettings_mac_addr_roaming_enabled.py index 16c4c1f6..18e68b8e 100644 --- a/openwisp_radius/migrations/0036_organizationradiussettings_mac_addr_roaming_enabled.py +++ b/openwisp_radius/migrations/0036_organizationradiussettings_mac_addr_roaming_enabled.py @@ -6,7 +6,6 @@ class Migration(migrations.Migration): - dependencies = [ ('openwisp_radius', '0035_organizationradiussettings_sms_cooldown'), ] diff --git a/openwisp_radius/tests/test_admin.py b/openwisp_radius/tests/test_admin.py index cebca12f..461e158c 100644 --- a/openwisp_radius/tests/test_admin.py +++ b/openwisp_radius/tests/test_admin.py @@ -53,7 +53,6 @@ class TestAdmin( PostParamsMixin, TestMultitenantAdminMixin, ): - app_label = 'openwisp_radius' app_label_users = 'openwisp_users' diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..6c773df5 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,22 @@ +[tool.coverage.run] +source = ["openwisp_radius"] +parallel = true +concurrency = ["multiprocessing"] +omit = [ + "openwisp_radius/__init__.py", + "*/tests/*", + "*/migrations/*", +] + +[tool.docstrfmt] +extend_exclude = ["**/*.py", "README.rst"] + +[tool.isort] +known_third_party = ["django"] +known_first_party = ["openwisp_users", "openwisp_utils", "openwisp_radius"] +default_section = "THIRDPARTY" +line_length = 88 +multi_line_output = 3 +use_parentheses = true +include_trailing_comma = true +force_grid_wrap = 0 diff --git a/setup.cfg b/setup.cfg index fca2b3c6..17920818 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,16 +1,6 @@ [bdist_wheel] universal=1 -[isort] -known_third_party = django -known_first_party = openwisp_users, openwisp_utils, openwisp_radius -default_section = THIRDPARTY -line_length=88 -multi_line_output=3 -use_parentheses=True -include_trailing_comma=True -force_grid_wrap=0 - [flake8] # W503: line break before or after operator # W504: line break after or after operator diff --git a/setup.py b/setup.py index f72e6faa..24b6f034 100644 --- a/setup.py +++ b/setup.py @@ -59,7 +59,7 @@ 'openvpn_status': ['openvpn-status~=0.2.1'], }, classifiers=[ - 'Development Status :: 3 - Alpha', + 'Development Status :: 5 - Production/Stable ', 'Environment :: Web Environment', 'Topic :: Internet :: WWW/HTTP', 'Topic :: System :: Networking', diff --git a/tests/openwisp2/sample_radius/migrations/0002_initial_openwisp_app.py b/tests/openwisp2/sample_radius/migrations/0002_initial_openwisp_app.py index 43acab03..2f22602c 100644 --- a/tests/openwisp2/sample_radius/migrations/0002_initial_openwisp_app.py +++ b/tests/openwisp2/sample_radius/migrations/0002_initial_openwisp_app.py @@ -25,7 +25,6 @@ class Migration(migrations.Migration): - nas_model = swapper.get_model_name('openwisp_radius', 'Nas') model_app_label = swapper.split(nas_model)[0] dependencies = [ diff --git a/tests/openwisp2/sample_radius/migrations/0004_allowed_mobile_prefixes.py b/tests/openwisp2/sample_radius/migrations/0004_allowed_mobile_prefixes.py index f6529aa4..3a71aba9 100644 --- a/tests/openwisp2/sample_radius/migrations/0004_allowed_mobile_prefixes.py +++ b/tests/openwisp2/sample_radius/migrations/0004_allowed_mobile_prefixes.py @@ -6,7 +6,6 @@ class Migration(migrations.Migration): - dependencies = [ ('sample_radius', '0003_default_groups_and_permissions'), ] diff --git a/tests/openwisp2/sample_radius/migrations/0005_phonetoken_phone_number.py b/tests/openwisp2/sample_radius/migrations/0005_phonetoken_phone_number.py index d14e2f47..04c03f3a 100644 --- a/tests/openwisp2/sample_radius/migrations/0005_phonetoken_phone_number.py +++ b/tests/openwisp2/sample_radius/migrations/0005_phonetoken_phone_number.py @@ -5,7 +5,6 @@ class Migration(migrations.Migration): - dependencies = [ ('sample_radius', '0004_allowed_mobile_prefixes'), ] diff --git a/tests/openwisp2/sample_radius/migrations/0020_added_optional_registration_fields.py b/tests/openwisp2/sample_radius/migrations/0020_added_optional_registration_fields.py index 545dc2f5..cc925259 100644 --- a/tests/openwisp2/sample_radius/migrations/0020_added_optional_registration_fields.py +++ b/tests/openwisp2/sample_radius/migrations/0020_added_optional_registration_fields.py @@ -6,7 +6,6 @@ class Migration(migrations.Migration): - dependencies = [ ('sample_radius', '0005_phonetoken_phone_number'), ] diff --git a/tests/openwisp2/sample_radius/migrations/0021_organizationradiussettings_registration_enabled.py b/tests/openwisp2/sample_radius/migrations/0021_organizationradiussettings_registration_enabled.py index 03a9ec2f..68b24e81 100644 --- a/tests/openwisp2/sample_radius/migrations/0021_organizationradiussettings_registration_enabled.py +++ b/tests/openwisp2/sample_radius/migrations/0021_organizationradiussettings_registration_enabled.py @@ -5,7 +5,6 @@ class Migration(migrations.Migration): - dependencies = [ ('sample_radius', '0020_added_optional_registration_fields'), ] diff --git a/tests/openwisp2/sample_radius/migrations/0022_registered_user.py b/tests/openwisp2/sample_radius/migrations/0022_registered_user.py index 9c319aa5..fcc0b299 100644 --- a/tests/openwisp2/sample_radius/migrations/0022_registered_user.py +++ b/tests/openwisp2/sample_radius/migrations/0022_registered_user.py @@ -7,7 +7,6 @@ class Migration(migrations.Migration): - dependencies = [ ('sample_radius', '0021_organizationradiussettings_registration_enabled'), ] diff --git a/tests/openwisp2/sample_radius/migrations/0023_registereduser_modified.py b/tests/openwisp2/sample_radius/migrations/0023_registereduser_modified.py index 6a80f74d..d42488e4 100644 --- a/tests/openwisp2/sample_radius/migrations/0023_registereduser_modified.py +++ b/tests/openwisp2/sample_radius/migrations/0023_registereduser_modified.py @@ -6,7 +6,6 @@ class Migration(migrations.Migration): - dependencies = [ ('sample_radius', '0022_registered_user'), ] diff --git a/tests/openwisp2/sample_radius/migrations/0024_sms_verification.py b/tests/openwisp2/sample_radius/migrations/0024_sms_verification.py index 92386108..53e6db86 100644 --- a/tests/openwisp2/sample_radius/migrations/0024_sms_verification.py +++ b/tests/openwisp2/sample_radius/migrations/0024_sms_verification.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ('sample_radius', '0023_registereduser_modified'), ] diff --git a/tests/openwisp2/sample_radius/migrations/0025_login_status_url_org_settings.py b/tests/openwisp2/sample_radius/migrations/0025_login_status_url_org_settings.py index 05f594b0..835a0189 100644 --- a/tests/openwisp2/sample_radius/migrations/0025_login_status_url_org_settings.py +++ b/tests/openwisp2/sample_radius/migrations/0025_login_status_url_org_settings.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ('sample_radius', '0024_sms_verification'), ] diff --git a/tests/openwisp2/sample_radius/migrations/0026_password_reset_url_org_settings.py b/tests/openwisp2/sample_radius/migrations/0026_password_reset_url_org_settings.py index 7a987824..441cdbe5 100644 --- a/tests/openwisp2/sample_radius/migrations/0026_password_reset_url_org_settings.py +++ b/tests/openwisp2/sample_radius/migrations/0026_password_reset_url_org_settings.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ('sample_radius', '0025_login_status_url_org_settings'), ] diff --git a/tests/openwisp2/sample_radius/migrations/0027_remove_check_customizations.py b/tests/openwisp2/sample_radius/migrations/0027_remove_check_customizations.py index 84ee61b7..d24abfb0 100644 --- a/tests/openwisp2/sample_radius/migrations/0027_remove_check_customizations.py +++ b/tests/openwisp2/sample_radius/migrations/0027_remove_check_customizations.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ('sample_radius', '0026_password_reset_url_org_settings'), ] diff --git a/tests/openwisp2/sample_radius/migrations/0028_alter_organizationradiussettings_allowed_mobile_prefixes_and_more.py b/tests/openwisp2/sample_radius/migrations/0028_alter_organizationradiussettings_allowed_mobile_prefixes_and_more.py index d276630c..1a45326d 100644 --- a/tests/openwisp2/sample_radius/migrations/0028_alter_organizationradiussettings_allowed_mobile_prefixes_and_more.py +++ b/tests/openwisp2/sample_radius/migrations/0028_alter_organizationradiussettings_allowed_mobile_prefixes_and_more.py @@ -8,7 +8,6 @@ class Migration(migrations.Migration): - dependencies = [ ('sample_radius', '0027_remove_check_customizations'), ] diff --git a/tests/openwisp2/sample_users/migrations/0001_initial.py b/tests/openwisp2/sample_users/migrations/0001_initial.py index 6431d6e8..f80bd1f1 100644 --- a/tests/openwisp2/sample_users/migrations/0001_initial.py +++ b/tests/openwisp2/sample_users/migrations/0001_initial.py @@ -17,7 +17,6 @@ class Migration(migrations.Migration): - initial = True dependencies = [ diff --git a/tests/openwisp2/sample_users/migrations/0004_default_groups.py b/tests/openwisp2/sample_users/migrations/0004_default_groups.py index 209c0ef0..4a8f29be 100644 --- a/tests/openwisp2/sample_users/migrations/0004_default_groups.py +++ b/tests/openwisp2/sample_users/migrations/0004_default_groups.py @@ -12,7 +12,6 @@ class Migration(migrations.Migration): - org_model = swapper.get_model_name('openwisp_users', 'organization') dependencies = [ swapper.dependency(*swapper.split(org_model), version='0001_initial')