Skip to content

ERROR ImportError: cannot import name 'ProtectedAPIMixin' from 'openwisp_users.api.mixins' #538

@SapeNeCo

Description

@SapeNeCo

Hello.
I'm new to OpenWISP, but would like to get the hang of it.
I installed the latest release of OpenWISP-controller on my machine with ubuntu 22.
For it I need to implement OpenWISP-wifi-login-pages.
In fact, the controller already has Radius, but when I launch it I get the following error:

$ ./browser-test/wait_for_url.sh http://0.0.0.0:8080 http://localhost:8000/admin && jest browser-test --runInBand
Build successful: http://0.0.0.0:8080 is reachable.
Build successful: http://localhost:8000/admin is reachable.
OpenWISP RADIUS is not installed or python virtual environment is not activated correctly

  ●  process.exit called with "1"

      18 |   }
      19 |   if (result.status !== 0) {
    > 20 |     process.exit(result.status);
         |             ^
      21 |   }
      22 | };
      23 |

      at executeCommand (browser-test/utils.js:20:13)
      at _callee4$ (browser-test/utils.js:53:9)
      at tryCatch (node_modules/@babel/runtime/helpers/regeneratorRuntime.js:45:16)
      at Generator.<anonymous> (node_modules/@babel/runtime/helpers/regeneratorRuntime.js:133:17)
      at Generator.next (node_modules/@babel/runtime/helpers/regeneratorRuntime.js:74:21)
      at asyncGeneratorStep (node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:24)
      at _next (node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:9)
      at node_modules/@babel/runtime/helpers/asyncToGenerator.js:27:7
      at apply (node_modules/@babel/runtime/helpers/asyncToGenerator.js:19:12)
      at initializeData (browser-test/utils.js:52:28)
      at _callee3$ (browser-test/mobile-phone-change.test.js:36:25)
      at tryCatch (node_modules/@babel/runtime/helpers/regeneratorRuntime.js:45:16)
      at Generator.<anonymous> (node_modules/@babel/runtime/helpers/regeneratorRuntime.js:133:17)
      at Generator.next (node_modules/@babel/runtime/helpers/regeneratorRuntime.js:74:21)
      at asyncGeneratorStep (node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:24)
      at _next (node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:9)
      at node_modules/@babel/runtime/helpers/asyncToGenerator.js:27:7
      at node_modules/@babel/runtime/helpers/asyncToGenerator.js:19:12

 RUNS  browser-test/mobile-phone-change.test.js
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

It requires OpenWISP-Radius, which is strange. But okay, I installed OpenWISP-Radius, figured out the dependencies and my setup.py file began to look like this:

import sys

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
DEBUG = True
TESTING = sys.argv[1:2] == ['test']
SELENIUM_HEADLESS = True if os.environ.get('SELENIUM_HEADLESS', False) else False
SHELL = 'shell' in sys.argv or 'shell_plus' in sys.argv
REDIS_URL = os.getenv('REDIS_URL', 'redis://localhost:6379')

ALLOWED_HOSTS = ['*']

SPATIALITE_LIBRARY_PATH = '/usr/local/lib/mod_spatialite.dylib'
DATABASES = {
    'default': {
        'ENGINE': 'django.contrib.gis.db.backends.spatialite',
        'NAME': os.path.join(BASE_DIR, 'openwisp-controller.db'),
    }
}


AUTH_USER_MODEL = 'openwisp_users.User'
SITE_ID = 1
AUTHENTICATION_BACKENDS = (
    'openwisp_users.backends.UsersAuthenticationBackend',
)

OPENWISP_RADIUS_FREERADIUS_ALLOWED_HOSTS = ['127.0.0.1']

SPATIALITE_LIBRARY_PATH = 'mod_spatialite.so'

SECRET_KEY = 'fn)t*+$)ugeyip6-#txyy$5wf2ervc0d2n#h)qb)y5@ly$t*@w'

INSTALLED_APPS = [
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.gis',
    # all-auth
    'django.contrib.sites',
    'openwisp_users.accounts',
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    'django_extensions',
    # openwisp2 modules
    'openwisp_users',
    'openwisp_controller.config',
    'openwisp_controller.pki',
    'openwisp_controller.geo',
    'openwisp_controller.connection',
    'openwisp_controller.subnet_division',
    'openwisp_notifications',
    'openwisp_ipam',
    # openwisp2 admin theme
    # (must be loaded here)
    'openwisp_utils.admin_theme',
    'admin_auto_filters',
    # admin
    'django.contrib.admin',
    'django.forms',
    # other dependencies
    'sortedm2m',
    'reversion',
    'leaflet',
    'flat_json_widget',
    # rest framework
    'rest_framework',
    'rest_framework.authtoken',
    'rest_framework_gis',
    'django_filters',
    'drf_yasg',
    # channels
    'channels',
    'import_export',
    # 'debug_toolbar',
    'django.contrib.humanize',
    # registration
    'dj_rest_auth',
    'dj_rest_auth.registration',
    # openwisp radius
    'openwisp_radius',
    'private_storage',
    'allauth.socialaccount.providers.facebook',
    'allauth.socialaccount.providers.google',
]
EXTENDED_APPS = ('django_x509', 'django_loci')

AUTH_USER_MODEL = 'openwisp_users.User'
SITE_ID = 1

STATICFILES_FINDERS = [
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    'openwisp_utils.staticfiles.DependencyFinder',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    # 'debug_toolbar.middleware.DebugToolbarMiddleware',
]

INTERNAL_IPS = ['127.0.0.1']

ROOT_URLCONF = 'openwisp2.urls'

ASGI_APPLICATION = 'openwisp2.asgi.application'
if not TESTING:
    CHANNEL_LAYERS = {
        'default': {
            'BACKEND': 'channels_redis.core.RedisChannelLayer',
            'CONFIG': {'hosts': [f'{REDIS_URL}/7']},
        }
    }
else:
    CHANNEL_LAYERS = {'default': {'BACKEND': 'channels.layers.InMemoryChannelLayer'}}

TIME_ZONE = 'Europe/Rome'
LANGUAGE_CODE = 'en-gb'
USE_TZ = True
USE_I18N = False
USE_L10N = False
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = f'{os.path.dirname(BASE_DIR)}/media/'
PRIVATE_STORAGE_ROOT = os.path.join(MEDIA_ROOT, 'private')

CORS_ORIGIN_ALLOW_ALL = True

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'OPTIONS': {
            'loaders': [
                'django.template.loaders.filesystem.Loader',
                'openwisp_utils.loaders.DependencyLoader',
                'django.template.loaders.app_directories.Loader',
            ],
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'openwisp_utils.admin_theme.context_processor.menu_groups',
                'openwisp_notifications.context_processors.notification_api_settings',
            ],
        },
    }
]

FORM_RENDERER = 'django.forms.renderers.TemplatesSetting'

EMAIL_PORT = '1025'  # for testing purposes
LOGIN_REDIRECT_URL = 'admin:index'
ACCOUNT_LOGOUT_REDIRECT_URL = LOGIN_REDIRECT_URL
OPENWISP_ORGANIZATION_USER_ADMIN = True  # tests will fail without this setting
OPENWISP_ADMIN_DASHBOARD_ENABLED = True
OPENWISP_CONTROLLER_GROUP_PIE_CHART = True
# during development only
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

if not TESTING:
    CACHES = {
        'default': {
            'BACKEND': 'django_redis.cache.RedisCache',
            'LOCATION': f'{REDIS_URL}/6',
            'OPTIONS': {
                'CLIENT_CLASS': 'django_redis.client.DefaultClient',
            },
        }
    }

if not TESTING:
    CELERY_BROKER_URL = f'{REDIS_URL}/1'
else:
    CELERY_TASK_ALWAYS_EAGER = True
    CELERY_TASK_EAGER_PROPAGATES = True
    CELERY_BROKER_URL = 'memory://'

LOGGING = {
    'version': 1,
    'filters': {'require_debug_true': {'()': 'django.utils.log.RequireDebugTrue'}},
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
        }
    },
}

if not TESTING and SHELL:
    LOGGING.update(
        {
            'loggers': {
                'django.db.backends': {
                    'level': 'DEBUG',
                    'handlers': ['console'],
                    'propagate': False,
                },
            }
        }
    )

DJANGO_LOCI_GEOCODE_STRICT_TEST = False
OPENWISP_CONTROLLER_CONTEXT = {'vpnserver1': 'vpn.testdomain.com'}
OPENWISP_USERS_AUTH_API = True

TEST_RUNNER = 'openwisp_utils.tests.TimeLoggingTestRunner'

if os.environ.get('SAMPLE_APP', False):
    # Replace Config
    config_index = INSTALLED_APPS.index('openwisp_controller.config')
    INSTALLED_APPS.remove('openwisp_controller.config')
    INSTALLED_APPS.insert(config_index, 'openwisp2.sample_config')
    # Replace Pki
    pki_index = INSTALLED_APPS.index('openwisp_controller.pki')
    INSTALLED_APPS.remove('openwisp_controller.pki')
    INSTALLED_APPS.insert(pki_index, 'openwisp2.sample_pki')
    # Replace Geo
    geo_index = INSTALLED_APPS.index('openwisp_controller.geo')
    INSTALLED_APPS.remove('openwisp_controller.geo')
    INSTALLED_APPS.insert(geo_index, 'openwisp2.sample_geo')
    # Replace Connection
    connection_index = INSTALLED_APPS.index('openwisp_controller.connection')
    INSTALLED_APPS.remove('openwisp_controller.connection')
    INSTALLED_APPS.insert(connection_index, 'openwisp2.sample_connection')
    # Replace Openwisp_Users
    users_index = INSTALLED_APPS.index('openwisp_users')
    INSTALLED_APPS.remove('openwisp_users')
    INSTALLED_APPS.insert(users_index, 'openwisp2.sample_users')
    # Replace Subnet Division
    subnet_division_index = INSTALLED_APPS.index('openwisp_controller.subnet_division')
    INSTALLED_APPS.remove('openwisp_controller.subnet_division')
    INSTALLED_APPS.insert(subnet_division_index, 'openwisp2.sample_subnet_division')
    # Extended apps
    EXTENDED_APPS = (
        'django_x509',
        'django_loci',
        'openwisp_controller.config',
        'openwisp_controller.pki',
        'openwisp_controller.geo',
        'openwisp_controller.connection',
        'openwisp_controller.subnet_division',
        'openwisp_users',
    )
    # Swapper
    AUTH_USER_MODEL = 'sample_users.User'
    OPENWISP_USERS_GROUP_MODEL = 'sample_users.Group'
    OPENWISP_USERS_ORGANIZATION_MODEL = 'sample_users.Organization'
    OPENWISP_USERS_ORGANIZATIONUSER_MODEL = 'sample_users.OrganizationUser'
    OPENWISP_USERS_ORGANIZATIONOWNER_MODEL = 'sample_users.OrganizationOwner'
    OPENWISP_USERS_ORGANIZATIONINVITATION_MODEL = 'sample_users.OrganizationInvitation'
    CONFIG_DEVICE_MODEL = 'sample_config.Device'
    CONFIG_DEVICEGROUP_MODEL = 'sample_config.DeviceGroup'
    CONFIG_CONFIG_MODEL = 'sample_config.Config'
    CONFIG_TEMPLATETAG_MODEL = 'sample_config.TemplateTag'
    CONFIG_TAGGEDTEMPLATE_MODEL = 'sample_config.TaggedTemplate'
    CONFIG_TEMPLATE_MODEL = 'sample_config.Template'
    CONFIG_VPN_MODEL = 'sample_config.Vpn'
    CONFIG_VPNCLIENT_MODEL = 'sample_config.VpnClient'
    CONFIG_ORGANIZATIONCONFIGSETTINGS_MODEL = 'sample_config.OrganizationConfigSettings'
    CONFIG_ORGANIZATIONLIMITS_MODEL = 'sample_config.OrganizationLimits'
    DJANGO_X509_CA_MODEL = 'sample_pki.Ca'
    DJANGO_X509_CERT_MODEL = 'sample_pki.Cert'
    GEO_LOCATION_MODEL = 'sample_geo.Location'
    GEO_FLOORPLAN_MODEL = 'sample_geo.FloorPlan'
    GEO_DEVICELOCATION_MODEL = 'sample_geo.DeviceLocation'
    CONNECTION_CREDENTIALS_MODEL = 'sample_connection.Credentials'
    CONNECTION_DEVICECONNECTION_MODEL = 'sample_connection.DeviceConnection'
    CONNECTION_COMMAND_MODEL = 'sample_connection.Command'
    SUBNET_DIVISION_SUBNETDIVISIONRULE_MODEL = (
        'sample_subnet_division.SubnetDivisionRule'
    )
    SUBNET_DIVISION_SUBNETDIVISIONINDEX_MODEL = (
        'sample_subnet_division.SubnetDivisionIndex'
    )
else:
    # not needed, these are the default values, left here only for example purposes
    # DJANGO_X509_CA_MODEL = 'pki.Ca'
    # DJANGO_X509_CERT_MODEL = 'pki.Cert'
    pass

if os.environ.get('SAMPLE_APP', False) and TESTING:
    # Required for openwisp-users tests
    OPENWISP_ORGANIZATION_USER_ADMIN = True
    OPENWISP_ORGANIZATION_OWNER_ADMIN = True
    OPENWISP_USERS_AUTH_API = True

# local settings must be imported before test runner otherwise they'll be ignored
try:
    from .local_settings import *
except ImportError:
    pass

But when I start it, I get this problem and I don’t understand why:

Traceback (most recent call last):
  File "/usr/lib/python3.10/threading.py", line 1016, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.10/threading.py", line 953, in run
    self._target(*self._args, **self._kwargs)
  File "/home/user/openwisp_controller/env/lib/python3.10/site-packages/django/utils/autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "/home/user/openwisp_controller/env/lib/python3.10/site-packages/django/core/management/commands/runserver.py", line 125, in inner_run
    autoreload.raise_last_exception()
  File "/home/user/openwisp_controller/env/lib/python3.10/site-packages/django/utils/autoreload.py", line 87, in raise_last_exception
    raise _exception[1]
  File "/home/user/openwisp_controller/env/lib/python3.10/site-packages/django/core/management/__init__.py", line 398, in execute
    autoreload.check_errors(django.setup)()
  File "/home/user/openwisp_controller/env/lib/python3.10/site-packages/django/utils/autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "/home/user/openwisp_controller/env/lib/python3.10/site-packages/django/__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/home/user/openwisp_controller/env/lib/python3.10/site-packages/django/apps/registry.py", line 124, in populate
    app_config.ready()
  File "/home/user/openwisp_controller/env/lib/python3.10/site-packages/django/contrib/admin/apps.py", line 27, in ready
    self.module.autodiscover()
  File "/home/user/openwisp_controller/env/lib/python3.10/site-packages/django/contrib/admin/__init__.py", line 50, in autodiscover
    autodiscover_modules("admin", register_to=site)
  File "/home/user/openwisp_controller/env/lib/python3.10/site-packages/django/utils/module_loading.py", line 58, in autodiscover_modules
    import_module("%s.%s" % (app_config.name, module_to_search))
  File "/usr/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/home/user/openwisp_controller/openwisp_controller/subnet_division/admin.py", line 5, in <module>
    from openwisp_ipam.admin import IpAddressAdmin as BaseIpAddressAdmin
  File "/home/user/openwisp_controller/env/lib/python3.10/site-packages/openwisp_ipam/admin.py", line 22, in <module>
    from .api.views import HostsSet
  File "/home/user/openwisp_controller/env/lib/python3.10/site-packages/openwisp_ipam/api/views.py", line 8, in <module>
    from openwisp_users.api.mixins import (
ImportError: cannot import name 'ProtectedAPIMixin' from 'openwisp_users.api.mixins' (/home/user/openwisp_controller/env/lib/python3.10/site-packages/openwisp_users/api/mixins.py)

I tried different versions of openwisp-users, openwisp-utils (because with ./manage.py migrate OpenWISP-Radius complained about them, supposedly the versions were incompatible), in the end nothing changed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions