Skip to content

Commit

Permalink
[fix] Fixed extensibility of openwisp-users and added sample_users te…
Browse files Browse the repository at this point in the history
…st app openwisp#377

Closes openwisp#377

Co-authored-by: Ajay Tripathi <ajay39in@gmail.com>
  • Loading branch information
devkapilbansal and atb00ker committed Apr 3, 2021
1 parent 9916774 commit 443679d
Show file tree
Hide file tree
Showing 41 changed files with 644 additions and 91 deletions.
12 changes: 10 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1253,6 +1253,12 @@ When in doubt, the code in the
will serve you as source of truth: just replicate and adapt that code
to get a basic derivative of *openwisp-controller* working.

If you want to add new users fields, please follow the `tutorial to extend the
openwisp-users <https://github.com/openwisp/openwisp-users/#extend-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
<https://github.com/openwisp/openwisp-controller/blob/master/tests/openwisp2/sample_users/models.py>`_.

**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.
Expand Down Expand Up @@ -1375,7 +1381,9 @@ Add ``openwisp_utils.staticfiles.DependencyFinder`` to
6. Add ``openwisp_utils.loaders.DependencyLoader``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Add ``openwisp_utils.loaders.DependencyLoader`` to ``TEMPLATES`` in your ``settings.py``:
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
Expand All @@ -1385,8 +1393,8 @@ Add ``openwisp_utils.loaders.DependencyLoader`` to ``TEMPLATES`` in your ``setti
'OPTIONS': {
'loaders': [
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
'openwisp_utils.loaders.DependencyLoader',
'django.template.loaders.app_directories.Loader',
],
'context_processors': [
'django.template.context_processors.debug',
Expand Down
4 changes: 2 additions & 2 deletions openwisp_controller/config/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
get_default_templates,
get_template_default_values,
)
from openwisp_users.models import Organization
from openwisp_users.multitenancy import (
MultitenantOrgFilter,
MultitenantRelatedOrgFilter,
Expand All @@ -50,6 +49,7 @@
Device = load_model('config', 'Device')
Template = load_model('config', 'Template')
Vpn = load_model('config', 'Vpn')
Organization = load_model('openwisp_users', 'Organization')
OrganizationConfigSettings = load_model('config', 'OrganizationConfigSettings')

if 'reversion' in settings.INSTALLED_APPS:
Expand Down Expand Up @@ -100,7 +100,7 @@ def get_extra_context(self, pk=None):
'value': text,
'title': '{0} (ALT+P)'.format(text),
}
],
]
}
# do not pass CONFIG_BACKEND_FIELD_SHOWN in VpnAdmin
# since we don't need to hide the VPN backend there
Expand Down
3 changes: 2 additions & 1 deletion openwisp_controller/config/base/multitenancy.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import swapper
from django.db import models
from django.utils.translation import ugettext_lazy as _

Expand All @@ -7,7 +8,7 @@
class AbstractOrganizationConfigSettings(UUIDModel):

organization = models.OneToOneField(
'openwisp_users.Organization',
swapper.get_model_name('openwisp_users', 'Organization'),
verbose_name=_('organization'),
related_name='config_settings',
on_delete=models.CASCADE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import model_utils.fields
import sortedm2m.fields
from django.db import migrations, models
from swapper import get_model_name

import openwisp_controller.config.base.template
import openwisp_utils.base
Expand Down Expand Up @@ -152,7 +153,7 @@ class Migration(migrations.Migration):
'organization',
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to='openwisp_users.Organization',
to=get_model_name('openwisp_users', 'Organization'),
verbose_name='organization',
),
),
Expand Down Expand Up @@ -212,7 +213,7 @@ class Migration(migrations.Migration):
models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
related_name='config_settings',
to='openwisp_users.Organization',
to=get_model_name('openwisp_users', 'Organization'),
verbose_name='organization',
),
),
Expand Down Expand Up @@ -323,7 +324,7 @@ class Migration(migrations.Migration):
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
to='openwisp_users.Organization',
to=get_model_name('openwisp_users', 'Organization'),
verbose_name='organization',
),
),
Expand Down Expand Up @@ -417,7 +418,7 @@ class Migration(migrations.Migration):
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
to='openwisp_users.Organization',
to=get_model_name('openwisp_users', 'Organization'),
verbose_name='organization',
),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import django.utils.timezone
import model_utils.fields
from django.db import migrations, models
from swapper import get_model_name

import openwisp_utils.base
import openwisp_utils.utils
Expand Down Expand Up @@ -111,7 +112,7 @@ class Migration(migrations.Migration):
'organization',
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to='openwisp_users.Organization',
to=get_model_name('openwisp_users', 'Organization'),
verbose_name='organization',
),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ class Migration(migrations.Migration):
field=models.CharField(db_index=True, max_length=64),
),
migrations.AlterUniqueTogether(
name='vpn', unique_together={('organization', 'name')},
name='vpn', unique_together={('organization', 'name')}
),
]
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@

class Migration(migrations.Migration):

dependencies = [
('config', '0033_name_unique_per_organization'),
]
dependencies = [('config', '0033_name_unique_per_organization')]

operations = [
migrations.AddField(
Expand Down
11 changes: 2 additions & 9 deletions openwisp_controller/config/migrations/__init__.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
import subprocess

import swapper
from django.contrib.auth.models import Permission

from ...migrations import create_default_permissions


def get_swapped_model(apps, app_name, model_name):
model_path = swapper.get_model_name(app_name, model_name)
app, model = swapper.split(model_path)
return apps.get_model(app, model)
from ...migrations import create_default_permissions, get_swapped_model


def update_vpn_dhparam_length(apps, schema_editor):
Expand All @@ -34,7 +27,7 @@ def assign_permissions_to_groups(apps, schema_editor):
operators_and_admins_can_change = ['device', 'config', 'template']
operators_read_only_admins_manage = ['vpn']
manage_operations = ['add', 'change', 'delete']
Group = apps.get_model('openwisp_users', 'Group')
Group = get_swapped_model(apps, 'openwisp_users', 'Group')

try:
admin = Group.objects.get(name='Administrator')
Expand Down
2 changes: 1 addition & 1 deletion openwisp_controller/config/tests/test_vpn.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ def test_vpn_name_unique_validation(self):
message_dict = context_manager.exception.message_dict
self.assertIn('name', message_dict)
self.assertIn(
'There is already another shared vpn', message_dict['name'][0],
'There is already another shared vpn', message_dict['name'][0]
)

with self.subTest('ensure object itself is excluded'):
Expand Down
3 changes: 1 addition & 2 deletions openwisp_controller/config/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@
from django.views.decorators.http import last_modified
from swapper import load_model

from openwisp_users.models import Organization

from .settings import BACKENDS, VPN_BACKENDS
from .utils import get_default_templates_queryset, get_object_or_404

Organization = load_model('openwisp_users', 'Organization')
Template = load_model('config', 'Template')


Expand Down
2 changes: 1 addition & 1 deletion openwisp_controller/connection/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class Migration(migrations.Migration):
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
to='openwisp_users.Organization',
to=swapper.get_model_name('openwisp_users', 'Organization'),
verbose_name='organization',
),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ class Migration(migrations.Migration):
field=models.CharField(db_index=True, max_length=64),
),
migrations.AlterUniqueTogether(
name='credentials', unique_together={('name', 'organization')},
name='credentials', unique_together={('name', 'organization')}
),
]
4 changes: 2 additions & 2 deletions openwisp_controller/connection/migrations/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
from django.contrib.auth.models import Permission

from ...migrations import create_default_permissions
from ...migrations import create_default_permissions, get_swapped_model


def assign_permissions_to_groups(apps, schema_editor):
create_default_permissions(apps, schema_editor)
operators_and_admins_can_change = ['deviceconnection']
only_admins_can_manage = ['credentials']
manage_operations = ['add', 'change', 'delete']
Group = apps.get_model('openwisp_users', 'Group')
Group = get_swapped_model(apps, 'openwisp_users', 'Group')

try:
admin = Group.objects.get(name='Administrator')
Expand Down
3 changes: 2 additions & 1 deletion openwisp_controller/connection/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from django.test import TestCase, TransactionTestCase
from swapper import load_model

from openwisp_users.models import Group, Organization
from openwisp_utils.tests import capture_any_output, catch_signal

from .. import settings as app_settings
Expand All @@ -20,6 +19,8 @@
Device = load_model('config', 'Device')
Credentials = load_model('connection', 'Credentials')
DeviceConnection = load_model('connection', 'DeviceConnection')
Group = load_model('openwisp_users', 'Group')
Organization = load_model('openwisp_users', 'Organization')

_connect_path = 'paramiko.SSHClient.connect'
_exec_command_path = 'paramiko.SSHClient.exec_command'
Expand Down
2 changes: 1 addition & 1 deletion openwisp_controller/geo/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ class Migration(migrations.Migration):
'organization',
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to='openwisp_users.Organization',
to=swapper.get_model_name('openwisp_users', 'Organization'),
verbose_name='organization',
),
),
Expand Down
4 changes: 2 additions & 2 deletions openwisp_controller/geo/migrations/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from django.contrib.auth.models import Permission

from ...migrations import create_default_permissions
from ...migrations import create_default_permissions, get_swapped_model


def assign_permissions_to_groups(apps, schema_editor):
create_default_permissions(apps, schema_editor)
operators_and_admins_can_change = ['location', 'floorplan', 'devicelocation']
manage_operations = ['add', 'change', 'delete']
Group = apps.get_model('openwisp_users', 'Group')
Group = get_swapped_model(apps, 'openwisp_users', 'Group')

try:
admin = Group.objects.get(name='Administrator')
Expand Down
2 changes: 1 addition & 1 deletion openwisp_controller/geo/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def setUp(self):
ou.is_admin = True
ou.save()
# create a superuser
self._create_admin(is_superuser=True,)
self._create_admin(is_superuser=True)

def _create_device_location(self, **kwargs):
options = dict()
Expand Down
3 changes: 2 additions & 1 deletion openwisp_controller/geo/tests/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from django.utils.text import slugify
from django_loci.tests import TestLociMixin
from swapper import load_model

from openwisp_users.models import Organization
Organization = load_model('openwisp_users', 'Organization')


class TestGeoMixin(TestLociMixin):
Expand Down
8 changes: 8 additions & 0 deletions openwisp_controller/migrations.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Used in migrations of apps
import swapper
from django.contrib.auth.management import create_permissions


Expand All @@ -6,3 +8,9 @@ def create_default_permissions(apps, schema_editor):
app_config.models_module = True
create_permissions(app_config, apps=apps, verbosity=0)
app_config.models_module = None


def get_swapped_model(apps, app_name, model_name):
model_path = swapper.get_model_name(app_name, model_name)
app, model = swapper.split(model_path)
return apps.get_model(app, model)
5 changes: 3 additions & 2 deletions openwisp_controller/pki/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import jsonfield.fields
import model_utils.fields
from django.db import migrations, models
from swapper import get_model_name


class Migration(migrations.Migration):
Expand Down Expand Up @@ -160,7 +161,7 @@ class Migration(migrations.Migration):
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
to='openwisp_users.Organization',
to=get_model_name('openwisp_users', 'Organization'),
verbose_name='organization',
),
),
Expand Down Expand Up @@ -328,7 +329,7 @@ class Migration(migrations.Migration):
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
to='openwisp_users.Organization',
to=get_model_name('openwisp_users', 'Organization'),
verbose_name='organization',
),
),
Expand Down
4 changes: 2 additions & 2 deletions openwisp_controller/pki/migrations/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from django.contrib.auth.models import Permission

from ...migrations import create_default_permissions
from ...migrations import create_default_permissions, get_swapped_model


def assign_permissions_to_groups(apps, schema_editor):
create_default_permissions(apps, schema_editor)
operators_read_only_admins_manage = ['ca', 'cert']
manage_operations = ['add', 'change', 'delete']
Group = apps.get_model('openwisp_users', 'Group')
Group = get_swapped_model(apps, 'openwisp_users', 'Group')

try:
admin = Group.objects.get(name='Administrator')
Expand Down
28 changes: 28 additions & 0 deletions openwisp_controller/tests/mixins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Mixins used for unit tests of openwisp_controller


class GetEditFormInlineMixin(object):
def _get_org_edit_form_inline_params(self, user, org):
params = super()._get_org_edit_form_inline_params(user, org)
params.update(
{
# config inline
'config_settings-TOTAL_FORMS': 0,
'config_settings-INITIAL_FORMS': 0,
'config_settings-MIN_NUM_FORMS': 0,
'config_settings-MAX_NUM_FORMS': 0,
}
)
return params

def _get_user_edit_form_inline_params(self, user, organization):
params = super()._get_user_edit_form_inline_params(user, organization)
params.update(
{
'notificationsetting_set-TOTAL_FORMS': 0,
'notificationsetting_set-INITIAL_FORMS': 0,
'notificationsetting_set-MIN_NUM_FORMS': 0,
'notificationsetting_set-MAX_NUM_FORMS': 0,
}
)
return params
Loading

0 comments on commit 443679d

Please sign in to comment.