def update_admins_permissions(apps, schema_editor): org_model = swapper.get_model_name('openwisp_users', 'organization') model_app_label = swapper.split(org_model)[0] group = apps.get_model(model_app_label, 'group') email_model = swapper.get_model_name('account', 'EmailAddress') email_app_label = swapper.split(email_model)[0] try: admin = group.objects.get(name='Administrator') permissions = [ Permission.objects.get( content_type__app_label=email_app_label, codename='view_emailaddress' ).pk, Permission.objects.get( content_type__app_label=email_app_label, codename='delete_emailaddress' ).pk, Permission.objects.get( content_type__app_label=email_app_label, codename='change_emailaddress' ).pk, Permission.objects.get( content_type__app_label=model_app_label, codename='delete_user' ).pk, ] admin.permissions.add(*permissions) except ObjectDoesNotExist: pass
def update_config(device_id): """ Launches the ``update_config()`` operation of a specific device in the background """ Device = swapper.load_model( *swapper.split(app_settings.UPDATE_CONFIG_MODEL)) # wait for the saving operations of this device to complete # (there may be multiple ones happening at the same time) time.sleep(2) try: device = Device.objects.select_related('config').get(pk=device_id) # abort operation if device shouldn't be updated if not device.can_be_updated(): logger.info( f'{device} (pk: {device_id}) is not going to be updated') return except ObjectDoesNotExist as e: logger.warning(f'update_config("{device_id}") failed: {e}') return qs = device.deviceconnection_set.filter(device_id=device_id, enabled=True) conn = qs.first() if conn: logger.info(f'Updating {device} (pk: {device_id})') conn.update_config()
def __str__(self): concrete_fqdn = swapper.get_model_name("survey", "Question") app_name, concrete_name = swapper.split(concrete_fqdn) msg = concrete_name + f" '{self.text}'" if self.required: msg += "(*) " msg += "{}".format(self.get_clean_choices()) return msg
def load_model_patched(app_label, model, require_ready=True): """ TODO: remove if https://github.com/wq/django-swappable-models/pull/23 gets merged """ swapped = is_swapped(app_label, model) if swapped: app_label, model = split(swapped) return apps.get_model(app_label, model, require_ready=require_ready)
class Migration(migrations.Migration): dependencies = [ dependency(*split(settings.AUTH_USER_MODEL), version='0004_default_groups'), ('topology', '0004_fixed_target_link_set'), ] operations = [ migrations.RunPython(assign_permissions_to_groups, reverse_code=migrations.RunPython.noop) ]
def create_default_groups(apps, schema_editor): org_model = swapper.get_model_name('openwisp_users', 'organization') model_app_label = swapper.split(org_model)[0] group = apps.get_model(model_app_label, 'group') # To populate all the permissions for app_config in apps.get_app_configs(): app_config.models_module = True create_permissions(app_config, apps=apps, verbosity=0) app_config.models_module = None operator = group.objects.filter(name='Operator') if operator.count() == 0: operator = group.objects.create(name='Operator') admin = group.objects.filter(name='Administrator') if admin.count() == 0: admin = group.objects.create(name='Administrator') permissions = [ Permission.objects.get( content_type__app_label=model_app_label, codename='add_user' ).pk, Permission.objects.get( content_type__app_label=model_app_label, codename='change_user' ).pk, Permission.objects.get( content_type__app_label=model_app_label, codename='change_organizationuser', ).pk, Permission.objects.get( content_type__app_label=model_app_label, codename='delete_organizationuser', ).pk, Permission.objects.get( content_type__app_label=model_app_label, codename='add_organizationuser', ).pk, ] try: permissions += [ Permission.objects.get( content_type__app_label=model_app_label, codename='view_user' ).pk, Permission.objects.get( content_type__app_label=model_app_label, codename='view_group' ).pk, Permission.objects.get( content_type__app_label=model_app_label, codename='view_organizationuser', ).pk, ] except Permission.DoesNotExist: pass admin.permissions.set(permissions)
class Migration(migrations.Migration): org_model = swapper.get_model_name('openwisp_users', 'organization') model_app_label = swapper.split(org_model)[0] dependencies = [ (model_app_label, '0001_initial'), ] operations = [ migrations.RunPython(set_default_organization_uuid, reverse_code=migrations.RunPython.noop), migrations.RunPython(create_default_groups, reverse_code=migrations.RunPython.noop), ]
class Migration(migrations.Migration): """ Set default group and move existing users to the default group """ org_model = swapper.get_model_name('openwisp_radius', 'Nas') model_app_label = swapper.split(org_model)[0] dependencies = [ (model_app_label, '0001_initial'), ] operations = [ migrations.RunPython(add_default_organization, reverse_code=migrations.RunPython.noop), migrations.RunPython(add_default_groups, reverse_code=migrations.RunPython.noop), migrations.RunPython(add_default_group_to_existing_users, reverse_code=migrations.RunPython.noop), migrations.RunPython(assign_permissions_to_groups, reverse_code=migrations.RunPython.noop), ]
def set_default_organization_uuid(apps, schema_editor): """ Get or create a default organization then set settings._OPENWISP_DEFAULT_ORG_UUID """ org_model = swapper.get_model_name('openwisp_users', 'organization') model_app_label = swapper.split(org_model)[0] organization = apps.get_model(model_app_label, 'organization') default_organization = organization.objects.first() if default_organization is None: default_organization = organization( name='default', slug='default', description='This is the default organization. ' 'It was created automatically during installation. ' 'You can simply rename it to your organization name.', ) default_organization.full_clean() default_organization.save() # settings._OPENWISP_DEFAULT_ORG_UUID is used in # openwisp-radius.migrations, it helps to enable # users to migrate from freeradius 3 settings._OPENWISP_DEFAULT_ORG_UUID = default_organization.pk
def get_model(apps, name): model_name = swapper.get_model_name('openwisp_users', name) model_label = swapper.split(model_name)[0] return apps.get_model(model_label, name)
class Migration(migrations.Migration): dependencies = [ swapper.dependency(*swapper.split(settings.AUTH_USER_MODEL), version='0004_default_groups'), swapper.dependency('config', 'Device'), ('device_monitoring', '0003_update_template'), ] operations = [ migrations.CreateModel( name='WifiClient', fields=[ ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'mac_address', models.CharField( db_index=True, help_text='MAC address', max_length=17, primary_key=True, serialize=False, validators=[ django.core.validators.RegexValidator( re.compile( '^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$' ), code='invalid', message='Must be a valid mac address.', ) ], ), ), ('vendor', models.CharField(blank=True, max_length=200, null=True)), ('ht', models.BooleanField(default=False, verbose_name='HT')), ('vht', models.BooleanField(default=False, verbose_name='VHT')), ('wmm', models.BooleanField(default=False, verbose_name='WMM')), ('wds', models.BooleanField(default=False, verbose_name='WDS')), ('wps', models.BooleanField(default=False, verbose_name='WPS')), ], options={ 'verbose_name': 'WiFi Client', 'abstract': False, 'swappable': 'DEVICE_MONITORING_WIFICLIENT_MODEL', }, ), migrations.CreateModel( name='WifiSession', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'ssid', models.CharField(blank=True, max_length=32, null=True, verbose_name='SSID'), ), ('interface_name', models.CharField(max_length=15)), ( 'start_time', models.DateTimeField(auto_now=True, db_index=True, verbose_name='start time'), ), ( 'stop_time', models.DateTimeField(blank=True, db_index=True, null=True, verbose_name='stop time'), ), ( 'device', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('config', 'Device'), ), ), ( 'wifi_client', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('device_monitoring', 'WifiClient'), ), ), ], options={ 'verbose_name': 'WiFi Session', 'ordering': ('-start_time', ), 'abstract': False, 'swappable': 'DEVICE_MONITORING_WIFISESSION_MODEL', }, ), ]
class Migration(migrations.Migration): initial = True dependencies = [ swapper.dependency( *split(settings.AUTH_USER_MODEL), version='0004_default_groups' ), ('contenttypes', '0002_remove_content_type_name'), swapper.dependency('openwisp_notifications', 'Notifications'), ] operations = [ migrations.CreateModel( name='Metric', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ('name', models.CharField(max_length=64)), ( 'configuration', models.CharField( choices=METRIC_CONFIGURATION_CHOICES, max_length=16, null=True ), ), ( 'key', models.SlugField( blank=True, help_text='leave blank to determine automatically', max_length=64, ), ), ('field_name', models.CharField(default='value', max_length=16)), ( 'object_id', models.CharField(blank=True, db_index=True, max_length=36), ), ( 'content_type', models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype', ), ), ( 'is_healthy', models.BooleanField( blank=True, db_index=True, default=None, null=True ), ), ], options={ 'abstract': False, 'swappable': swapper.swappable_setting('monitoring', 'Metric'), 'unique_together': {('key', 'field_name', 'content_type', 'object_id')}, }, ), migrations.CreateModel( name='Chart', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'configuration', models.CharField( choices=CHART_CONFIGURATION_CHOICES, max_length=16, null=True ), ), ( 'metric', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('monitoring', 'Metric'), ), ), ], options={ 'abstract': False, 'swappable': swapper.swappable_setting('monitoring', 'Chart'), }, ), migrations.CreateModel( name='AlertSettings', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'custom_operator', models.CharField( blank=True, choices=[('<', 'less than'), ('>', 'greater than')], max_length=1, null=True, verbose_name='operator', ), ), ( 'custom_threshold', models.FloatField( blank=True, help_text='threshold value', null=True, verbose_name='threshold value', ), ), ( 'custom_tolerance', models.PositiveIntegerField( blank=True, help_text='for how many minutes should the threshold value be crossed before' ' an alert is sent? A value of zero means the alert is sent immediately', null=True, validators=[django.core.validators.MaxValueValidator(10080)], verbose_name='threshold tolerance', ), ), ( 'metric', models.OneToOneField( on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('monitoring', 'Metric'), ), ), ( 'is_active', models.BooleanField( default=True, help_text='whether alerts are enabled for this metric, uncheck to disable' ' this alert for this object and all users', verbose_name='Alerts enabled', ), ), ], options={ 'verbose_name': 'Alert settings', 'verbose_name_plural': 'Alert settings', 'abstract': False, 'swappable': swapper.swappable_setting('monitoring', 'AlertSettings'), }, ), ]
def test_non_contrib_app_split(self): self.assertEqual(swapper.split('alt_app.Type'), ('alt_app', 'Type'))
class Migration(migrations.Migration): initial = True dependencies = [ swapper.dependency(*swapper.split(settings.AUTH_USER_MODEL), version='0004_default_groups'), swapper.dependency('config', 'Device'), ] operations = [ migrations.CreateModel( name='DeviceLocation', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'indoor', models.CharField( blank=True, max_length=64, null=True, verbose_name='indoor position', ), ), ( 'content_object', models.OneToOneField( on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('config', 'Device'), ), ), ], options={'abstract': False}, bases=(openwisp_users.mixins.ValidateOrgMixin, models.Model), ), migrations.CreateModel( name='FloorPlan', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ('floor', models.SmallIntegerField(verbose_name='floor')), ( 'image', models.ImageField( help_text='floor plan image', storage=django_loci.storage.OverwriteStorage(), upload_to=django_loci.storage.OverwriteStorage. upload_to, verbose_name='image', ), ), ], options={'abstract': False}, bases=(openwisp_users.mixins.ValidateOrgMixin, models.Model), ), migrations.CreateModel( name='Location', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'name', models.CharField( help_text=('A descriptive name of the location ' '(building name, company name, etc.)'), max_length=75, verbose_name='name', ), ), ( 'type', models.CharField( choices=[ ( 'outdoor', ('Outdoor environment (eg: street, square, garden, ' 'land)'), ), ( 'indoor', ('Indoor environment (eg: building, roofs, subway, ' 'large vehicles)'), ), ], db_index=True, help_text= ('indoor locations can have floorplans associated to them' ), max_length=8, ), ), ( 'is_mobile', models.BooleanField( db_index=True, default=False, help_text='is this location a moving object?', verbose_name='is mobile?', ), ), ( 'address', models.CharField( blank=True, db_index=True, max_length=256, verbose_name='address', ), ), ( 'geometry', django.contrib.gis.db.models.fields.GeometryField( blank=True, null=True, srid=4326, verbose_name='geometry'), ), ( 'organization', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ], options={'abstract': False}, bases=(openwisp_users.mixins.ValidateOrgMixin, models.Model), ), migrations.AddField( model_name='floorplan', name='location', field=models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to='geo.Location'), ), migrations.AddField( model_name='floorplan', name='organization', field=models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), migrations.AddField( model_name='devicelocation', name='floorplan', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='geo.FloorPlan', ), ), migrations.AddField( model_name='devicelocation', name='location', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='geo.Location', ), ), migrations.AlterUniqueTogether(name='floorplan', unique_together=set([('location', 'floor')])), ]
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)
class Migration(migrations.Migration): initial = True dependencies = [ ('contenttypes', '0002_remove_content_type_name'), ('sample_pki', '0002_default_group_permissions'), swapper.dependency( *swapper.split(settings.AUTH_USER_MODEL), version='0004_default_groups' ), ] operations = [ migrations.CreateModel( name='Config', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'backend', models.CharField( choices=[ ('netjsonconfig.OpenWrt', 'OpenWRT'), ('netjsonconfig.OpenWisp', 'OpenWISP Firmware 1.x'), ], help_text=( 'Select <a href="http://netjsonconfig.openwisp.org/en/' 'stable/" target="_blank">netjsonconfig</a> backend' ), max_length=128, verbose_name='backend', ), ), ( 'config', jsonfield.fields.JSONField( blank=True, default=dict, dump_kwargs={'ensure_ascii': False, 'indent': 4}, help_text='configuration in NetJSON DeviceConfiguration format', load_kwargs={'object_pairs_hook': collections.OrderedDict}, verbose_name='configuration', ), ), ( 'status', model_utils.fields.StatusField( choices=[ ('modified', 'modified'), ('applied', 'applied'), ('error', 'error'), ], default='modified', help_text=( '"modified" means the configuration is not applied yet; \n' '"applied" means the configuration is applied successfully;' ' \n' '"error" means the configuration caused issues ' 'and it was rolled back;' ), max_length=100, no_check_for_status=True, verbose_name='configuration status', ), ), ( 'error_reason', models.CharField( blank=True, help_text='Error reason reported by the device', max_length=1024, verbose_name='error reason', ), ), ( 'context', jsonfield.fields.JSONField( blank=True, default=dict, dump_kwargs={'ensure_ascii': False, 'indent': 4}, help_text=( 'Additional <a href="http://netjsonconfig.openwisp.org' '/en/stable/general/basics.html#context" target="_blank">' 'context (configuration variables)</a> in JSON format' ), load_kwargs={'object_pairs_hook': collections.OrderedDict}, ), ), ('details', models.CharField(blank=True, max_length=64, null=True)), ], options={ 'verbose_name': 'configuration', 'verbose_name_plural': 'configurations', 'abstract': False, }, ), migrations.CreateModel( name='TaggedTemplate', fields=[ ( 'id', models.AutoField( auto_created=True, primary_key=True, serialize=False, verbose_name='ID', ), ), ( 'object_id', models.UUIDField(db_index=True, verbose_name='object ID'), ), ('details', models.CharField(blank=True, max_length=64, null=True)), ( 'content_type', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, related_name='%(app_label)s_%(class)s_tagged_items', to='contenttypes.ContentType', verbose_name='content type', ), ), ], options={ 'verbose_name': 'Tagged item', 'verbose_name_plural': 'Tags', 'abstract': False, }, ), migrations.CreateModel( name='TemplateTag', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'name', models.CharField(max_length=100, unique=True, verbose_name='name'), ), ( 'slug', models.SlugField(max_length=100, unique=True, verbose_name='slug'), ), ('details', models.CharField(blank=True, max_length=64, null=True)), ], options={ 'verbose_name': 'Tag', 'verbose_name_plural': 'Tags', 'abstract': False, }, ), migrations.CreateModel( name='Vpn', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ('name', models.CharField(db_index=True, max_length=64, unique=True)), ( 'config', jsonfield.fields.JSONField( default=dict, dump_kwargs={'ensure_ascii': False, 'indent': 4}, help_text='configuration in NetJSON DeviceConfiguration format', load_kwargs={'object_pairs_hook': collections.OrderedDict}, verbose_name='configuration', ), ), ( 'host', models.CharField( help_text='VPN server hostname or ip address', max_length=64 ), ), ( 'key', openwisp_utils.base.KeyField( db_index=True, default=openwisp_utils.utils.get_random_key, help_text=None, max_length=64, validators=[ django.core.validators.RegexValidator( re.compile('^[^\\s/\\.]+$'), code='invalid', message=( 'This value must not contain spaces, ' 'dots or slashes.' ), ) ], ), ), ( 'backend', models.CharField( choices=[ ('openwisp_controller.vpn_backends.OpenVpn', 'OpenVPN'), ('openwisp_controller.vpn_backends.Wireguard', 'WireGuard'), ( 'openwisp_controller.vpn_backends.VxlanWireguard', 'VXLAN over WireGuard', ), ], help_text='Select VPN configuration backend', max_length=128, verbose_name='VPN backend', ), ), ('notes', models.TextField(blank=True)), ('dh', models.TextField(blank=True)), ('public_key', models.CharField(blank=True, max_length=44)), ('private_key', models.CharField(blank=True, max_length=44)), ('details', models.CharField(blank=True, max_length=64, null=True)), ( 'ca', models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='sample_pki.ca', verbose_name='Certification Authority', ), ), ( 'cert', models.ForeignKey( blank=True, help_text='leave blank to create automatically', null=True, on_delete=django.db.models.deletion.CASCADE, to='sample_pki.cert', verbose_name='x509 Certificate', ), ), ( 'ip', models.ForeignKey( blank=True, help_text=( 'Internal IP address of the VPN ' 'server interface, if applicable' ), null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.OPENWISP_IPAM_IPADDRESS_MODEL, verbose_name='Internal IP', ), ), ( 'organization', models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ( 'subnet', models.ForeignKey( blank=True, help_text=( 'Subnet IP addresses used by VPN clients, if applicable' ), null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.OPENWISP_IPAM_SUBNET_MODEL, verbose_name='Subnet', ), ), ( 'auth_token', models.CharField( blank=True, help_text=( 'Authentication token for triggering "Webhook Endpoint"' ), max_length=128, null=True, verbose_name='Webhook AuthToken', ), ), ( 'webhook_endpoint', models.CharField( blank=True, help_text=( 'Webhook to trigger for updating server configuration ' '(e.g. https://openwisp2.mydomain.com:8081/trigger-update)' ), max_length=128, null=True, verbose_name='Webhook Endpoint', ), ), ], options={ 'verbose_name': 'VPN server', 'verbose_name_plural': 'VPN servers', 'abstract': False, }, bases=(openwisp_users.mixins.ValidateOrgMixin, models.Model), ), migrations.CreateModel( name='VpnClient', fields=[ ( 'id', models.AutoField( auto_created=True, primary_key=True, serialize=False, verbose_name='ID', ), ), ('auto_cert', models.BooleanField(default=False)), ( 'public_key', models.CharField(blank=True, max_length=44), ), ( 'private_key', models.CharField(blank=True, max_length=44), ), ( 'vni', models.PositiveIntegerField( blank=True, db_index=True, null=True, validators=[ django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(16777216), ], ), ), ('details', models.CharField(blank=True, max_length=64, null=True)), ( 'cert', models.OneToOneField( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='sample_pki.cert', ), ), ( 'config', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to='sample_config.config', ), ), ( 'ip', models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='openwisp_ipam.ipaddress', ), ), ( 'vpn', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to='sample_config.vpn', ), ), ], options={ 'verbose_name': 'VPN client', 'verbose_name_plural': 'VPN clients', 'abstract': False, 'unique_together': {('vpn', 'vni'), ('config', 'vpn')}, }, ), migrations.CreateModel( name='Template', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ('name', models.CharField(db_index=True, max_length=64, unique=True)), ( 'backend', models.CharField( choices=[ ('netjsonconfig.OpenWrt', 'OpenWRT'), ('netjsonconfig.OpenWisp', 'OpenWISP Firmware 1.x'), ], help_text=( 'Select <a href="http://netjsonconfig.openwisp.org/en/' 'stable/" target="_blank">netjsonconfig</a> backend' ), max_length=128, verbose_name='backend', ), ), ( 'config', jsonfield.fields.JSONField( blank=True, default=dict, dump_kwargs={'ensure_ascii': False, 'indent': 4}, help_text='configuration in NetJSON DeviceConfiguration format', load_kwargs={'object_pairs_hook': collections.OrderedDict}, verbose_name='configuration', ), ), ( 'type', models.CharField( choices=[('generic', 'Generic'), ('vpn', 'VPN-client')], db_index=True, default='generic', help_text=( 'template type, determines which features are available' ), max_length=16, verbose_name='type', ), ), ( 'default', models.BooleanField( db_index=True, default=False, help_text=( 'whether new configurations will have this ' 'template enabled by default' ), verbose_name='enabled by default', ), ), ( 'required', models.BooleanField( db_index=True, default=False, help_text=( 'if checked, will force the assignment of this template to ' 'all the devices of the organization (if no organization ' 'is selected, it will be required for every device ' 'in the system)' ), verbose_name='required', ), ), ( 'auto_cert', models.BooleanField( db_index=True, default=default_auto_cert, help_text=( 'whether tunnel specific configuration (cryptographic ' 'keys, ip addresses, etc) should be automatically ' 'generated and managed behind the scenes for each ' 'configuration using this template, valid only for ' 'the VPN type' ), verbose_name='automatic tunnel provisioning', ), ), ( 'default_values', jsonfield.fields.JSONField( blank=True, default=dict, dump_kwargs={'ensure_ascii': False, 'indent': 4}, help_text=( 'A dictionary containing the default values for the ' 'variables used by this template; these default variables ' 'will be used during schema validation.' ), load_kwargs={'object_pairs_hook': collections.OrderedDict}, verbose_name='Default Values', ), ), ('details', models.CharField(blank=True, max_length=64, null=True)), ( 'organization', models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ( 'tags', taggit.managers.TaggableManager( blank=True, help_text=( 'A comma-separated list of template tags, may be used ' 'to ease auto configuration with specific settings ' '(eg: 4G, mesh, WDS, VPN, ecc.)' ), through='sample_config.TaggedTemplate', to='sample_config.TemplateTag', verbose_name='Tags', ), ), ( 'vpn', models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='sample_config.vpn', verbose_name='VPN', ), ), ], options={ 'verbose_name': 'template', 'verbose_name_plural': 'templates', 'abstract': False, 'unique_together': {('organization', 'name')}, }, bases=(openwisp_users.mixins.ValidateOrgMixin, models.Model), ), migrations.AddField( model_name='taggedtemplate', name='tag', field=models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, related_name='%(app_label)s_%(class)s_items', to='sample_config.TemplateTag', ), ), migrations.CreateModel( name='OrganizationConfigSettings', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'registration_enabled', models.BooleanField( default=True, help_text=( 'Whether automatic registration of ' 'devices is enabled or not' ), verbose_name='auto-registration enabled', ), ), ( 'shared_secret', openwisp_utils.base.KeyField( db_index=True, default=openwisp_utils.utils.get_random_key, help_text='used for automatic registration of devices', max_length=32, unique=True, validators=[ django.core.validators.RegexValidator( re.compile('^[^\\s/\\.]+$'), code='invalid', message=( 'This value must not contain spaces, ' 'dots or slashes.' ), ) ], verbose_name='shared secret', ), ), ('details', models.CharField(blank=True, max_length=64, null=True)), ( 'organization', models.OneToOneField( on_delete=django.db.models.deletion.CASCADE, related_name='config_settings', to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ], options={ 'verbose_name': 'Configuration management settings', 'verbose_name_plural': 'Configuration management settings', 'abstract': False, }, ), migrations.CreateModel( name='DeviceGroup', fields=[ ('details', models.CharField(blank=True, max_length=64, null=True)), ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ('name', models.CharField(max_length=60)), ( 'description', models.TextField(blank=True, help_text='internal notes'), ), ( 'meta_data', jsonfield.fields.JSONField( blank=True, default=dict, dump_kwargs={'ensure_ascii': False, 'indent': 4}, load_kwargs={'object_pairs_hook': collections.OrderedDict}, ), ), ( 'organization', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ], options={ 'verbose_name': 'Device Group', 'verbose_name_plural': 'Device Groups', 'abstract': False, 'swappable': 'CONFIG_DEVICEGROUP_MODEL', }, bases=(openwisp_users.mixins.ValidateOrgMixin, models.Model), ), migrations.AlterUniqueTogether( name='devicegroup', unique_together={('organization', 'name')}, ), migrations.CreateModel( name='Device', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'name', models.CharField( db_index=True, max_length=64, validators=[ django.core.validators.RegexValidator( re.compile( '^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}' '[a-zA-Z0-9])(\\.([a-zA-Z0-9]|[a-zA-Z0-9]' '[a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9]))*$|^' '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$' ), code='invalid', message=( 'Must be either a valid hostname or mac address.' ), ) ], help_text=('must be either a valid hostname or mac address'), ), ), ( 'mac_address', models.CharField( db_index=True, help_text='primary mac address', max_length=17, validators=[ django.core.validators.RegexValidator( re.compile('^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$'), code='invalid', message='Must be a valid mac address.', ) ], ), ), ( 'group', models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=swapper.get_model_name('config', 'DeviceGroup'), verbose_name='group', ), ), ( 'key', openwisp_utils.base.KeyField( blank=True, db_index=True, default=None, help_text='unique device key', max_length=64, unique=True, validators=[ django.core.validators.RegexValidator( re.compile('^[^\\s/\\.]+$'), code='invalid', message=( 'This value must not contain spaces, ' 'dots or slashes.' ), ) ], ), ), ( 'model', models.CharField( blank=True, db_index=True, help_text='device model and manufacturer', max_length=64, ), ), ( 'os', models.CharField( blank=True, db_index=True, help_text='operating system identifier', max_length=128, verbose_name='operating system', ), ), ( 'system', models.CharField( blank=True, db_index=True, help_text='system on chip or CPU info', max_length=128, verbose_name='SOC / CPU', ), ), ('notes', models.TextField(blank=True, help_text='internal notes')), ( 'last_ip', models.GenericIPAddressField( blank=True, db_index=True, help_text=( 'indicates the IP address logged from the last ' 'request coming from the device' ), null=True, ), ), ( 'management_ip', models.GenericIPAddressField( blank=True, db_index=True, help_text=( 'IP address used by OpenWISP to reach the device when ' 'performing any type of push operation or active check. ' 'The value of this field is generally sent by the device ' 'and hence does not need to be changed, but can be ' 'changed or cleared manually if needed.' ), null=True, ), ), ( 'hardware_id', models.CharField( blank=True, help_text='Serial number of this device', max_length=32, null=True, verbose_name='Serial number', ), ), ('details', models.CharField(blank=True, max_length=64, null=True)), ( 'organization', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ], options={ 'abstract': False, 'unique_together': { ('mac_address', 'organization'), ('hardware_id', 'organization'), }, 'verbose_name': app_settings.DEVICE_VERBOSE_NAME[0], 'verbose_name_plural': app_settings.DEVICE_VERBOSE_NAME[1], }, bases=(openwisp_users.mixins.ValidateOrgMixin, models.Model), ), migrations.AddField( model_name='config', name='device', field=models.OneToOneField( on_delete=django.db.models.deletion.CASCADE, to='sample_config.device' ), ), migrations.AddField( model_name='config', name='templates', field=openwisp_controller.config.sortedm2m.fields.SortedManyToManyField( blank=True, help_text='configuration templates, applied from first to last', related_name='config_relations', to='sample_config.Template', verbose_name='templates', ), ), migrations.AddField( model_name='config', name='vpn', field=models.ManyToManyField( blank=True, related_name='vpn_relations', through='sample_config.VpnClient', to='sample_config.Vpn', ), ), ]
class BaseUpdateFromDjangoFreeradius(BaseCommand): help = 'Upgrade from django-freeradius' app_label_users = split(get_model_name('openwisp_users', 'Organization'))[0] app_label = split(get_model_name('openwisp_radius', 'Nas'))[0] def add_arguments(self, parser): parser.add_argument( '--backup', action='store', default=settings.BASE_DIR, help='(Optional) Path to the backup files', ) parser.add_argument( '--organization', action='store', default=None, help=( '(Optional) organization UUID of the organization in ' 'which you want to import the data.' ), ) def int_to_uuid(self, pk): return "00000000-0000-0000-0000-{:012}".format(pk) def _get_updated_permission_list( self, permission_data, permissions_list, contenttype_data ): permit_list = [] for permit_pk in permissions_list: for item in permission_data: if item['pk'] == permit_pk: for content in contenttype_data: if item['fields']['content_type'] == content['pk']: permit_app_label = content['fields']['app_label'] if permit_app_label == 'django_freeradius': permit_app_label = self.app_label elif ( content['fields']['model'] in ['user', 'group'] and permit_app_label == 'auth' ): permit_app_label = self.app_label_users try: permit_list.append( Permission.objects.get( content_type__app_label=permit_app_label, codename=item['fields']['codename'], ).pk ) except Permission.DoesNotExist: # pragma: nocover pass return permit_list def handle(self, *args, **options): if options['organization']: org = Organization.objects.get(pk=options['organization']) else: org = Organization.objects.first() # Group Model with open(f'{options["backup"]}/contenttype.json') as contenttype: contenttype_data = json.load(contenttype) with open(f'{options["backup"]}/permission.json') as permission: permission_data = json.load(permission) with open(f'{options["backup"]}/group.json') as group: group_data = json.load(group) load_group_data = [] for data in group_data: if not Group.objects.filter(name=data['fields']['name']).exists(): load_group_data.append( { 'model': f'{self.app_label_users}.group', 'pk': data['pk'] + Group.objects.count(), 'fields': { 'name': data['fields']['name'], 'permissions': self._get_updated_permission_list( permission_data, data['fields']['permissions'], contenttype_data, ), }, } ) if load_group_data: # Save in anotherfile with open(f'{options["backup"]}/group_loaded.json', 'w') as outfile: json.dump(load_group_data, outfile) # Load to database call_command( 'loaddata', f'{options["backup"]}/group_loaded.json', verbosity=0 ) # User Model with open(f'{options["backup"]}/user.json') as users: users_data = json.load(users) # Make changes org_users_data = [] load_users_data = [] for data in users_data: data['model'] = f'{self.app_label_users}.user' data['pk'] = self.int_to_uuid(data['pk']) # If the user doesn't have an email, give them a # @example.com email but in openwisp-network-topology # email is UNIQUE. if not data['fields']['email']: data['fields']['email'] = f'{data["fields"]["username"]}@example.com' group_list = [] for group_pk in data['fields']['groups']: for item in group_data: if item['pk'] == group_pk: group_list.append( Group.objects.filter(name=item['fields']['name']).first().pk ) data['fields']['groups'] = group_list data['fields']['user_permissions'] = self._get_updated_permission_list( permission_data, data['fields']['user_permissions'], contenttype_data, ) if not User.objects.filter(email=data['fields']['email']): load_users_data.append(data) if not data['fields']['is_superuser']: org_users_data.append( { 'model': f'{self.app_label_users}.organizationuser', 'pk': str(uuid.uuid4()), 'fields': { 'created': data['fields']['date_joined'], 'modified': data['fields']['date_joined'], 'is_admin': False, 'user': data['pk'], 'organization': str(org.pk), }, } ) load_users_data.extend(org_users_data) if load_users_data: # Save in anotherfile with open(f'{options["backup"]}/user_loaded.json', 'w') as outfile: json.dump(load_users_data, outfile) # Load to database call_command( 'loaddata', f'{options["backup"]}/user_loaded.json', verbosity=0 ) # Radius Models with open(f'{options["backup"]}/freeradius.json') as freeradius: freeradius_data = json.load(freeradius) # Make changes for data in freeradius_data: table_name = data["model"].split(".")[1] data['model'] = f'{self.app_label}.{table_name}' if table_name in [ 'radiuscheck', 'radiusreply', 'radiusgroup', 'radiusbatch', 'organizationradiussettings', 'nas', ]: data['fields']['organization'] = str(org.pk) if table_name in ['radiusbatch']: del data['fields']['pdf'] user_list = [] for user in data['fields']['users']: user_list.append(self.int_to_uuid(user)) data['fields']['users'] = user_list if table_name in ['radiusreply', 'radiususergroup']: data['fields']['user'] = self.int_to_uuid(data['fields']['user']) if table_name in ['radiustoken']: data['fields']['user'] = self.int_to_uuid(data['fields']['user']) data['fields']['organization'] = str(org.pk) # Save in anotherfile with open(f'{options["backup"]}/freeradius_loaded.json', 'w') as outfile: json.dump(freeradius_data, outfile) # Load to database call_command( 'loaddata', f'{options["backup"]}/freeradius_loaded.json', verbosity=0 ) # Load site.json & social.json call_command('loaddata', f'{options["backup"]}/site.json', verbosity=0) call_command('loaddata', f'{options["backup"]}/social.json', verbosity=0) self.stdout.write(self.style.SUCCESS('Migration Process Complete!'))
class Migration(migrations.Migration): initial = True dependencies = [ dependency(*split(settings.AUTH_USER_MODEL), version='0004_default_groups'), ] operations = [ migrations.CreateModel( name='Link', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ('cost', models.FloatField()), ('cost_text', models.CharField(blank=True, max_length=24)), ( 'status', model_utils.fields.StatusField( choices=[('up', 'up'), ('down', 'down')], default='up', max_length=100, no_check_for_status=True, ), ), ( 'properties', jsonfield.fields.JSONField( blank=True, default=dict, dump_kwargs={'indent': 4}, load_kwargs={ 'object_pairs_hook': collections.OrderedDict }, ), ), ( 'organization', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ], options={'abstract': False}, ), migrations.CreateModel( name='Node', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ('label', models.CharField(blank=True, max_length=64)), ('addresses', models.CharField(db_index=True, max_length=510)), ( 'properties', jsonfield.fields.JSONField( blank=True, default=dict, dump_kwargs={'indent': 4}, load_kwargs={ 'object_pairs_hook': collections.OrderedDict }, ), ), ( 'organization', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ], options={'abstract': False}, ), migrations.CreateModel( name='Topology', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ('label', models.CharField(max_length=64, verbose_name='label')), ( 'parser', models.CharField( choices=[ ('netdiff.OlsrParser', 'OLSRd (txtinfo/jsoninfo)'), ( 'netdiff.BatmanParser', 'batman-advanced (jsondoc/txtinfo)', ), ('netdiff.BmxParser', 'BMX6 (q6m)'), ('netdiff.NetJsonParser', 'NetJSON NetworkGraph'), ('netdiff.CnmlParser', 'CNML 1.0'), ], help_text='Select topology format', max_length=128, verbose_name='format', ), ), ( 'strategy', models.CharField( choices=[('fetch', 'FETCH'), ('receive', 'RECEIVE')], db_index=True, default='fetch', max_length=16, verbose_name='strategy', ), ), ( 'url', models.URLField( blank=True, help_text= 'Topology data will be fetched from this URL (FETCH strategy)', verbose_name='url', ), ), ( 'key', openwisp_utils.base.KeyField( blank=True, default=openwisp_utils.utils.get_random_key, help_text='key needed to update topology from nodes ', max_length=64, validators=[ django.core.validators.RegexValidator( re.compile('^[^\\s/\\.]+$'), code='invalid', message= 'This value must not contain spaces, dots or slashes.', ) ], verbose_name='key', ), ), ( 'expiration_time', models.PositiveIntegerField( default=0, help_text= ('"Expiration Time" in seconds: setting this to 0 will ' 'immediately mark missing links as down; a value higher ' 'than 0 will delay marking missing links as down until ' 'the "modified" field of a link is older than "Expiration Time"' ), verbose_name='expiration time', ), ), ( 'published', models.BooleanField( default=True, help_text= "Unpublished topologies won't be updated or shown in the visualizer", verbose_name='published', ), ), ( 'protocol', models.CharField(blank=True, max_length=64, verbose_name='protocol'), ), ( 'version', models.CharField(blank=True, max_length=24, verbose_name='version'), ), ( 'revision', models.CharField(blank=True, max_length=64, verbose_name='revision'), ), ( 'metric', models.CharField(blank=True, max_length=24, verbose_name='metric'), ), ( 'organization', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ], options={ 'verbose_name_plural': 'topologies', 'abstract': False }, ), migrations.AddField( model_name='node', name='topology', field=models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to='topology.Topology'), ), migrations.AddField( model_name='link', name='source', field=models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, related_name='source_link_set', to='topology.Node', ), ), migrations.AddField( model_name='link', name='target', field=models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, related_name='source_target_set', to='topology.Node', ), ), migrations.AddField( model_name='link', name='topology', field=models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to='topology.Topology'), ), ]
class Migration(migrations.Migration): initial = True dependencies = [ swapper.dependency(*swapper.split(settings.AUTH_USER_MODEL), version='0004_default_groups'), swapper.dependency('config', 'Device'), ] operations = [ migrations.CreateModel( name='Credentials', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ('name', models.CharField(db_index=True, max_length=64, unique=True)), ( 'connector', models.CharField( choices=app_settings.CONNECTORS, db_index=True, max_length=128, verbose_name='connection type', ), ), ( 'params', jsonfield.fields.JSONField( default=dict, dump_kwargs={'indent': 4}, help_text='global connection parameters', load_kwargs={ 'object_pairs_hook': collections.OrderedDict }, verbose_name='parameters', ), ), ( 'organization', models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ], options={ 'verbose_name_plural': 'Access credentials', 'verbose_name': 'Access credentials', }, bases=(openwisp_users.mixins.ValidateOrgMixin, models.Model), ), migrations.CreateModel( name='DeviceConnection', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'update_strategy', models.CharField( blank=True, choices=app_settings.UPDATE_STRATEGIES, db_index=True, help_text='leave blank to determine automatically', max_length=128, verbose_name='update strategy', ), ), ('enabled', models.BooleanField(db_index=True, default=True)), ( 'params', jsonfield.fields.JSONField( blank=True, default=dict, dump_kwargs={'indent': 4}, help_text=( 'local connection parameters (will override ' 'the global parameters if specified)'), load_kwargs={ 'object_pairs_hook': collections.OrderedDict }, verbose_name='parameters', ), ), ('is_working', models.NullBooleanField(default=None)), ('last_attempt', models.DateTimeField(blank=True, null=True)), ( 'failure_reason', models.CharField(blank=True, max_length=128, verbose_name='reason of failure'), ), ( 'credentials', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('connection', 'Credentials'), ), ), ( 'device', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('config', 'Device'), ), ), ], options={ 'verbose_name_plural': 'Device connections', 'verbose_name': 'Device connection', }, ), ]
class Migration(migrations.Migration): """ Set default group and move existing users to the default group """ rad_model = swapper.get_model_name('openwisp_radius', 'RadiusToken') users_model = swapper.get_model_name('openwisp_users', 'Organization') model_app_label = swapper.split(rad_model)[0] users_model_app_label = swapper.split(users_model)[0] dependencies = [ swapper.dependency('openwisp_radius', 'RadiusToken'), (model_app_label, '0002_initial_openwisp_app'), (users_model_app_label, '0002_default_groups_and_permissions'), ] operations = [ migrations.RunPython( add_default_organization, reverse_code=migrations.RunPython.noop ), migrations.RunPython( add_default_groups, reverse_code=migrations.RunPython.noop ), migrations.RunPython( add_default_group_to_existing_users, reverse_code=migrations.RunPython.noop ), migrations.RunPython( assign_permissions_to_groups, reverse_code=migrations.RunPython.noop ), migrations.AlterField( model_name='nas', name='organization', field=models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), migrations.AlterField( model_name='radiusaccounting', name='organization', field=models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), migrations.AlterField( model_name='radiuscheck', name='organization', field=models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), migrations.AlterField( model_name='radiuspostauth', name='organization', field=models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), migrations.AlterField( model_name='radiusreply', name='organization', field=models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ]
class Migration(migrations.Migration): """ Default schema of freeradius 3. radius app's model schema begins from next migration, this helps to enable users to migrate from freeradius 3 """ initial = True nas_model = swapper.get_model_name('openwisp_radius', 'Nas') model_app_label = swapper.split(nas_model)[0] dependencies = [(model_app_label, '__first__')] operations = [ migrations.CreateModel( name='Nas', fields=[ ( 'id', models.AutoField( auto_created=True, primary_key=True, serialize=False, verbose_name='ID', ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'name', models.CharField( db_column='nasname', db_index=True, help_text='NAS Name (or IP address)', max_length=128, verbose_name='name', ), ), ( 'short_name', models.CharField(db_column='shortname', max_length=32, verbose_name='short name'), ), ( 'type', models.CharField( default='other', max_length=30, verbose_name='type', choices=RAD_NAS_TYPES, ), ), ( 'secret', models.CharField(help_text='Shared Secret', max_length=60, verbose_name='secret'), ), ( 'ports', models.PositiveIntegerField(blank=True, null=True, verbose_name='ports'), ), ( 'community', models.CharField(blank=True, max_length=50, null=True, verbose_name='community'), ), ( 'description', models.CharField( blank=True, max_length=200, null=True, verbose_name='description', ), ), ( 'server', models.CharField(blank=True, max_length=64, null=True, verbose_name='server'), ), ], options={ 'swappable': 'OPENWISP_RADIUS_NAS_MODEL', 'db_table': 'nas', 'verbose_name_plural': 'NAS', 'abstract': False, 'verbose_name': 'NAS', }, bases=(openwisp_users.mixins.ValidateOrgMixin, models.Model), ), migrations.CreateModel( name='RadiusAccounting', fields=[ ( 'id', models.BigAutoField(db_column='radacctid', primary_key=True, serialize=False), ), ( 'session_id', models.CharField( db_column='acctsessionid', db_index=True, max_length=64, verbose_name='session ID', ), ), ( 'unique_id', models.CharField( db_column='acctuniqueid', max_length=32, unique=True, verbose_name='accounting unique ID', ), ), ( 'username', models.CharField( blank=True, db_index=True, max_length=64, null=True, verbose_name='username', ), ), ( 'groupname', models.CharField(blank=True, max_length=64, null=True, verbose_name='group name'), ), ( 'realm', models.CharField(blank=True, max_length=64, null=True, verbose_name='realm'), ), ( 'nas_ip_address', models.GenericIPAddressField( db_column='nasipaddress', db_index=True, verbose_name='NAS IP address', ), ), ( 'nas_port_id', models.CharField( blank=True, db_column='nasportid', max_length=15, null=True, verbose_name='NAS port ID', ), ), ( 'nas_port_type', models.CharField( blank=True, db_column='nasporttype', max_length=32, null=True, verbose_name='NAS port type', ), ), ( 'start_time', models.DateTimeField( blank=True, db_column='acctstarttime', db_index=True, null=True, verbose_name='start time', ), ), ( 'stop_time', models.DateTimeField( blank=True, db_column='acctstoptime', db_index=True, null=True, verbose_name='stop time', ), ), ( 'session_time', models.PositiveIntegerField( blank=True, db_column='acctsessiontime', null=True, verbose_name='session time', ), ), ( 'authentication', models.CharField( blank=True, db_column='acctauthentic', max_length=32, null=True, verbose_name='authentication', ), ), ( 'connection_info_start', models.CharField( blank=True, db_column='connectinfo_start', max_length=50, null=True, verbose_name='connection info start', ), ), ( 'connection_info_stop', models.CharField( blank=True, db_column='connectinfo_stop', max_length=50, null=True, verbose_name='connection info stop', ), ), ( 'input_octets', models.BigIntegerField( blank=True, db_column='acctinputoctets', null=True, verbose_name='input octets', ), ), ( 'output_octets', models.BigIntegerField( blank=True, db_column='acctoutputoctets', null=True, verbose_name='output octets', ), ), ( 'calling_station_id', models.CharField( blank=True, db_column='callingstationid', max_length=50, null=True, verbose_name='calling station ID', ), ), ( 'called_station_id', models.CharField( blank=True, db_column='calledstationid', max_length=50, null=True, verbose_name='called station ID', ), ), ( 'terminate_cause', models.CharField( blank=True, db_column='acctterminatecause', max_length=32, null=True, verbose_name='termination cause', ), ), ( 'service_type', models.CharField( blank=True, db_column='servicetype', max_length=32, null=True, verbose_name='service type', ), ), ( 'framed_protocol', models.CharField( blank=True, db_column='framedprotocol', max_length=32, null=True, verbose_name='framed protocol', ), ), ( 'framed_ip_address', models.GenericIPAddressField( blank=True, db_column='framedipaddress', db_index=True, null=True, verbose_name='framed IP address', ), ), ( 'update_time', models.DateTimeField( blank=True, db_column='acctupdatetime', null=True, verbose_name='update time', ), ), ( 'interval', models.IntegerField( blank=True, db_column='acctinterval', null=True, verbose_name='interval', ), ), ], options={ 'swappable': 'OPENWISP_RADIUS_RADIUSACCOUNTING_MODEL', 'db_table': 'radacct', 'verbose_name_plural': 'accountings', 'abstract': False, 'verbose_name': 'accounting', }, bases=(openwisp_users.mixins.ValidateOrgMixin, models.Model), ), migrations.CreateModel( name='RadiusCheck', fields=[ ( 'id', models.AutoField( auto_created=True, primary_key=True, serialize=False, verbose_name='ID', ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'username', models.CharField(db_index=True, max_length=64, verbose_name='username'), ), ('value', models.CharField(max_length=253, verbose_name='value')), ( 'op', models.CharField( choices=[ ('=', '='), (':=', ':='), ('==', '=='), ('+=', '+='), ('!=', '!='), ('>', '>'), ('>=', '>='), ('<', '<'), ('<=', '<='), ('=~', '=~'), ('!~', '!~'), ('=*', '=*'), ('!*', '!*'), ], default=':=', max_length=2, verbose_name='operator', ), ), ( 'attribute', models.CharField( choices=[ ('Max-Daily-Session', 'Max-Daily-Session'), ('Max-All-Session', 'Max-All-Session'), ('Max-Daily-Session-Traffic', 'Max-Daily-Session-Traffic'), ('Cleartext-Password', 'Cleartext-Password'), ('NT-Password', 'NT-Password'), ('LM-Password', 'LM-Password'), ('MD5-Password', 'MD5-Password'), ('SMD5-Password', 'SMD5-Password'), ('SHA-Password', 'SHA-Password'), ('SSHA-Password', 'SSHA-Password'), ('Crypt-Password', 'Crypt-Password'), ], default='NT-Password', max_length=64, verbose_name='attribute', ), ), ], options={ 'swappable': 'OPENWISP_RADIUS_RADIUSCHECK_MODEL', 'db_table': 'radcheck', 'verbose_name_plural': 'checks', 'abstract': False, 'verbose_name': 'check', }, bases=( openwisp_users.mixins.ValidateOrgMixin, openwisp_radius.base.models.AutoUsernameMixin, models.Model, ), ), migrations.CreateModel( name='RadiusGroupCheck', fields=[ ( 'id', models.AutoField( auto_created=True, primary_key=True, serialize=False, verbose_name='ID', ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'groupname', models.CharField(db_index=True, max_length=64, verbose_name='group name'), ), ( 'attribute', models.CharField(max_length=64, verbose_name='attribute'), ), ( 'op', models.CharField( choices=[ ('=', '='), (':=', ':='), ('==', '=='), ('+=', '+='), ('!=', '!='), ('>', '>'), ('>=', '>='), ('<', '<'), ('<=', '<='), ('=~', '=~'), ('!~', '!~'), ('=*', '=*'), ('!*', '!*'), ], default=':=', max_length=2, verbose_name='operator', ), ), ('value', models.CharField(max_length=253, verbose_name='value')), ], options={ 'swappable': 'OPENWISP_RADIUS_RADIUSGROUPCHECK_MODEL', 'db_table': 'radgroupcheck', 'verbose_name_plural': 'group checks', 'abstract': False, 'verbose_name': 'group check', }, bases=(openwisp_radius.base.models.AutoGroupnameMixin, models.Model), ), migrations.CreateModel( name='RadiusGroupReply', fields=[ ( 'id', models.AutoField( auto_created=True, primary_key=True, serialize=False, verbose_name='ID', ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'groupname', models.CharField(db_index=True, max_length=64, verbose_name='group name'), ), ( 'attribute', models.CharField(max_length=64, verbose_name='attribute'), ), ( 'op', models.CharField( choices=[('=', '='), (':=', ':='), ('+=', '+=')], default='=', max_length=2, verbose_name='operator', ), ), ('value', models.CharField(max_length=253, verbose_name='value')), ], options={ 'swappable': 'OPENWISP_RADIUS_RADIUSGROUPREPLY_MODEL', 'db_table': 'radgroupreply', 'verbose_name_plural': 'group replies', 'abstract': False, 'verbose_name': 'group reply', }, bases=(openwisp_radius.base.models.AutoGroupnameMixin, models.Model), ), migrations.CreateModel( name='RadiusPostAuth', fields=[ ( 'id', models.AutoField( auto_created=True, primary_key=True, serialize=False, verbose_name='ID', ), ), ('username', models.CharField(max_length=64, verbose_name='username')), ( 'password', models.CharField( blank=True, db_column='pass', max_length=64, verbose_name='password', ), ), ('reply', models.CharField(max_length=32, verbose_name='reply')), ( 'date', models.DateTimeField(auto_now_add=True, db_column='authdate', verbose_name='date'), ), ( 'called_station_id', models.CharField( blank=True, db_column='calledstationid', max_length=50, null=True, verbose_name='called station ID', ), ), ( 'calling_station_id', models.CharField( blank=True, db_column='callingstationid', max_length=50, null=True, verbose_name='calling station ID', ), ), ], options={ 'swappable': 'OPENWISP_RADIUS_RADIUSPOSTAUTH_MODEL', 'db_table': 'radpostauth', 'verbose_name_plural': 'post auth log', 'abstract': False, 'verbose_name': 'post auth', }, bases=(openwisp_users.mixins.ValidateOrgMixin, models.Model), ), migrations.CreateModel( name='RadiusReply', fields=[ ( 'id', models.AutoField( auto_created=True, primary_key=True, serialize=False, verbose_name='ID', ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'username', models.CharField(db_index=True, max_length=64, verbose_name='username'), ), ('value', models.CharField(max_length=253, verbose_name='value')), ( 'op', models.CharField( choices=[('=', '='), (':=', ':='), ('+=', '+=')], default='=', max_length=2, verbose_name='operator', ), ), ( 'attribute', models.CharField(max_length=64, verbose_name='attribute'), ), ], options={ 'swappable': 'OPENWISP_RADIUS_RADIUSREPLY_MODEL', 'db_table': 'radreply', 'verbose_name_plural': 'replies', 'abstract': False, 'verbose_name': 'reply', }, bases=( openwisp_users.mixins.ValidateOrgMixin, openwisp_radius.base.models.AutoUsernameMixin, models.Model, ), ), migrations.CreateModel( name='RadiusUserGroup', fields=[ ( 'id', models.AutoField( auto_created=True, primary_key=True, serialize=False, verbose_name='ID', ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'username', models.CharField(db_index=True, max_length=64, verbose_name='username'), ), ( 'groupname', models.CharField(max_length=64, verbose_name='group name'), ), ('priority', models.IntegerField(default=1, verbose_name='priority')), ], options={ 'swappable': 'OPENWISP_RADIUS_RADIUSUSERGROUP_MODEL', 'db_table': 'radusergroup', 'verbose_name_plural': 'user groups', 'abstract': False, 'verbose_name': 'user group', }, bases=( openwisp_radius.base.models.AutoGroupnameMixin, openwisp_radius.base.models.AutoUsernameMixin, models.Model, ), ), ]
class Migration(migrations.Migration): initial = True dependencies = [ ('sample_config', '0001_initial'), swapper.dependency( *swapper.split(settings.AUTH_USER_MODEL), version='0004_default_groups' ), swapper.dependency('config', 'Device'), ] operations = [ migrations.CreateModel( name='Credentials', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ('name', models.CharField(db_index=True, max_length=64, unique=True)), ( 'connector', models.CharField( choices=connection_settings.CONNECTORS, db_index=True, max_length=128, verbose_name='connection type', ), ), ( 'params', jsonfield.fields.JSONField( default=dict, dump_kwargs={'indent': 4}, help_text='global connection parameters', load_kwargs={'object_pairs_hook': collections.OrderedDict}, verbose_name='parameters', ), ), ( 'auto_add', models.BooleanField( default=False, help_text=( 'automatically add these credentials to the ' 'devices of this organization; if no organization is ' 'specified will be added to all the new devices' ), verbose_name='auto add', ), ), ('details', models.CharField(blank=True, max_length=64, null=True)), ( 'organization', models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ], options={ 'verbose_name': 'Access credentials', 'verbose_name_plural': 'Access credentials', 'abstract': False, }, bases=( openwisp_controller.connection.base.models.ConnectorMixin, openwisp_users.mixins.ValidateOrgMixin, models.Model, ), ), migrations.CreateModel( name='DeviceConnection', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'update_strategy', models.CharField( blank=True, choices=connection_settings.UPDATE_STRATEGIES, db_index=True, help_text='leave blank to determine automatically', max_length=128, verbose_name='update strategy', ), ), ('enabled', models.BooleanField(db_index=True, default=True)), ( 'params', jsonfield.fields.JSONField( blank=True, default=dict, dump_kwargs={'indent': 4}, help_text=( 'local connection parameters (will override the ' 'global parameters if specified)' ), load_kwargs={'object_pairs_hook': collections.OrderedDict}, verbose_name='parameters', ), ), ( 'is_working', models.BooleanField(blank=True, default=None, null=True), ), ( 'failure_reason', models.TextField(blank=True, verbose_name='reason of failure'), ), ('last_attempt', models.DateTimeField(blank=True, null=True)), ('details', models.CharField(blank=True, max_length=64, null=True)), ( 'credentials', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to='sample_connection.Credentials', ), ), ( 'device', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to='sample_config.Device', ), ), ], options={ 'verbose_name': 'Device connection', 'verbose_name_plural': 'Device connections', 'abstract': False, }, bases=( openwisp_controller.connection.base.models.ConnectorMixin, models.Model, ), ), migrations.CreateModel( name='Command', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'status', models.CharField( choices=[ ('in-progress', 'in progress'), ('success', 'success'), ('failed', 'failed'), ], default='in-progress', max_length=12, ), ), ( 'type', models.CharField( choices=COMMAND_CHOICES, max_length=16, ), ), ( 'input', jsonfield.fields.JSONField( blank=True, dump_kwargs={'indent': 4}, load_kwargs={'object_pairs_hook': collections.OrderedDict}, null=True, ), ), ('output', models.TextField(blank=True)), ( 'connection', models.ForeignKey( null=True, on_delete=django.db.models.deletion.SET_NULL, to=swapper.get_model_name('connection', 'DeviceConnection'), ), ), ( 'device', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('config', 'Device'), ), ), ], options={ 'verbose_name': 'Command', 'verbose_name_plural': 'Commands', 'ordering': ('created',), 'abstract': False, 'swappable': swapper.swappable_setting('connection', 'Command'), }, ), ]
def test_contrib_app_split(self): self.assertEqual( swapper.split('alt_app.contrib.named_things.NamedThing'), ('alt_app.contrib.named_things', 'NamedThing'))
def get_model(apps, name): model_tuple = swapper.split(swapper.get_model_name('cities', name)) return apps.get_model(*model_tuple)
class Migration(migrations.Migration): nas_model = swapper.get_model_name('openwisp_radius', 'Nas') model_app_label = swapper.split(nas_model)[0] dependencies = [ swapper.dependency('openwisp_users', 'Organization'), migrations.swappable_dependency(settings.AUTH_USER_MODEL), (model_app_label, '0001_initial_freeradius'), ] operations = [ migrations.RemoveField( model_name='radiusaccounting', name='id', ), migrations.AddField( model_name='nas', name='details', field=models.CharField(blank=True, max_length=64, null=True), ), migrations.AddField( model_name='nas', name='organization', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), preserve_default=False, ), migrations.AddField( model_name='radiusaccounting', name='delegated_ipv6_prefix', field=models.CharField( blank=True, db_column='delegatedipv6prefix', max_length=44, null=True, validators=[ openwisp_radius.base.validators.ipv6_network_validator ], verbose_name='delegated IPv6 prefix', ), ), migrations.AddField( model_name='radiusaccounting', name='details', field=models.CharField(blank=True, max_length=64, null=True), ), migrations.AddField( model_name='radiusaccounting', name='framed_interface_id', field=models.CharField( blank=True, db_column='framedinterfaceid', max_length=19, null=True, verbose_name='framed interface ID', ), ), migrations.AddField( model_name='radiusaccounting', name='framed_ipv6_address', field=models.GenericIPAddressField( blank=True, db_column='framedipv6address', null=True, protocol='IPv6', verbose_name='framed IPv6 address', ), ), migrations.AddField( model_name='radiusaccounting', name='framed_ipv6_prefix', field=models.CharField( blank=True, db_column='framedipv6prefix', max_length=44, null=True, validators=[ openwisp_radius.base.validators.ipv6_network_validator ], verbose_name='framed IPv6 prefix', ), ), migrations.AddField( model_name='radiusaccounting', name='organization', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), preserve_default=False, ), migrations.AddField( model_name='radiuscheck', name='details', field=models.CharField(blank=True, max_length=64, null=True), ), migrations.AddField( model_name='radiuscheck', name='is_active', field=models.BooleanField(default=True), ), migrations.AddField( model_name='radiuscheck', name='notes', field=models.TextField(blank=True, null=True), ), migrations.AddField( model_name='radiuscheck', name='organization', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), preserve_default=False, ), migrations.AddField( model_name='radiuscheck', name='user', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, ), ), migrations.AddField( model_name='radiuscheck', name='valid_until', field=models.DateTimeField(blank=True, null=True), ), migrations.AddField( model_name='radiusgroupcheck', name='details', field=models.CharField(blank=True, max_length=64, null=True), ), migrations.AddField( model_name='radiusgroupreply', name='details', field=models.CharField(blank=True, max_length=64, null=True), ), migrations.AddField( model_name='radiuspostauth', name='details', field=models.CharField(blank=True, max_length=64, null=True), ), migrations.AddField( model_name='radiuspostauth', name='organization', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), preserve_default=False, ), migrations.AddField( model_name='radiusreply', name='details', field=models.CharField(blank=True, max_length=64, null=True), ), migrations.AddField( model_name='radiusreply', name='organization', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), preserve_default=False, ), migrations.AddField( model_name='radiusreply', name='user', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, ), ), migrations.AddField( model_name='radiususergroup', name='details', field=models.CharField(blank=True, max_length=64, null=True), ), migrations.AddField( model_name='radiususergroup', name='user', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, ), ), migrations.AlterField( model_name='nas', name='id', field=models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False), ), migrations.AlterField( model_name='radiusaccounting', name='called_station_id', field=models.CharField( blank=True, db_column='calledstationid', db_index=True, max_length=50, null=True, verbose_name='called station ID', ), ), migrations.AlterField( model_name='radiusaccounting', name='calling_station_id', field=models.CharField( blank=True, db_column='callingstationid', db_index=True, max_length=50, null=True, verbose_name='calling station ID', ), ), migrations.AlterField( model_name='radiusaccounting', name='framed_ip_address', field=models.GenericIPAddressField( blank=True, db_column='framedipaddress', null=True, verbose_name='framed IP address', ), ), migrations.AlterField( model_name='radiusaccounting', name='unique_id', field=models.CharField( db_column='acctuniqueid', max_length=32, primary_key=True, serialize=False, unique=True, verbose_name='accounting unique ID', ), ), migrations.AlterField( model_name='radiuscheck', name='id', field=models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False), ), migrations.AlterField( model_name='radiuscheck', name='username', field=models.CharField(blank=True, db_index=True, max_length=64, verbose_name='username'), ), migrations.AlterField( model_name='radiusgroupcheck', name='groupname', field=models.CharField(blank=True, db_index=True, max_length=64, verbose_name='group name'), ), migrations.AlterField( model_name='radiusgroupcheck', name='id', field=models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False), ), migrations.AlterField( model_name='radiusgroupreply', name='groupname', field=models.CharField(blank=True, db_index=True, max_length=64, verbose_name='group name'), ), migrations.AlterField( model_name='radiusgroupreply', name='id', field=models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False), ), migrations.AlterField( model_name='radiuspostauth', name='id', field=models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False), ), migrations.AlterField( model_name='radiusreply', name='id', field=models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False), ), migrations.AlterField( model_name='radiusreply', name='username', field=models.CharField(blank=True, db_index=True, max_length=64, verbose_name='username'), ), migrations.AlterField( model_name='radiususergroup', name='groupname', field=models.CharField(blank=True, max_length=64, verbose_name='group name'), ), migrations.AlterField( model_name='radiususergroup', name='id', field=models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False), ), migrations.AlterField( model_name='radiususergroup', name='username', field=models.CharField(blank=True, db_index=True, max_length=64, verbose_name='username'), ), migrations.CreateModel( name='RadiusToken', fields=[ ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'key', models.CharField( max_length=40, primary_key=True, serialize=False, verbose_name='Key', ), ), ( 'can_auth', models.BooleanField( default=False, help_text=('Enable the radius token to be used for ' 'freeradius authorization request'), ), ), ('details', models.CharField(blank=True, max_length=64, null=True)), ( 'organization', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ( 'user', models.OneToOneField( on_delete=django.db.models.deletion.CASCADE, related_name='radius_token', to=settings.AUTH_USER_MODEL, ), ), ], options={ 'verbose_name': 'radius token', 'verbose_name_plural': 'radius token', 'db_table': 'radiustoken', 'abstract': False, }, bases=(openwisp_users.mixins.ValidateOrgMixin, models.Model), ), migrations.CreateModel( name='RadiusGroup', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'name', models.CharField( db_index=True, max_length=255, unique=True, verbose_name='group name', ), ), ( 'description', models.CharField(blank=True, max_length=64, null=True, verbose_name='description'), ), ( 'default', models.BooleanField( default=False, help_text=( 'The default group is automatically assigned ' 'to new users; changing the default group has ' 'only effect on new users (existing users will ' 'keep being members of their current group)'), verbose_name='is default?', ), ), ('details', models.CharField(blank=True, max_length=64, null=True)), ( 'organization', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ], options={ 'verbose_name': 'group', 'verbose_name_plural': 'groups', 'abstract': False, }, bases=(openwisp_users.mixins.ValidateOrgMixin, models.Model), ), migrations.CreateModel( name='OrganizationRadiusSettings', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'token', openwisp_utils.base.KeyField( default=openwisp_utils.utils.get_random_key, help_text=None, max_length=32, validators=[ django.core.validators.RegexValidator( re.compile('^[^\\s/\\.]+$'), code='invalid', message=('This value must not contain spaces, ' 'dots or slashes.'), ) ], ), ), ( 'sms_verification', models.BooleanField( default=False, help_text=('whether users who sign up should be ' 'required to verify their mobile ' 'phone number via SMS'), ), ), ( 'sms_sender', models.CharField( blank=True, help_text=( 'alpha numeric identifier used as sender for ' 'SMS sent by this organization'), max_length=128, null=True, verbose_name='Sender', ), ), ( 'sms_meta_data', jsonfield.fields.JSONField( blank=True, help_text=('Additional configuration for SMS backend ' 'in JSON format (optional)'), null=True, ), ), ( 'freeradius_allowed_hosts', models.TextField( blank=True, help_text=( 'Comma separated list of IP addresses allowed ' 'to access freeradius API'), null=True, ), ), ('details', models.CharField(blank=True, max_length=64, null=True)), ( 'organization', models.OneToOneField( on_delete=django.db.models.deletion.CASCADE, related_name='radius_settings', to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ], options={ 'verbose_name': 'Organization radius settings', 'verbose_name_plural': 'Organization radius settings', 'abstract': False, }, ), migrations.AddField( model_name='radiusgroupcheck', name='group', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_radius', 'RadiusGroup'), ), ), migrations.AddField( model_name='radiusgroupreply', name='group', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_radius', 'RadiusGroup'), ), ), migrations.AddField( model_name='radiususergroup', name='group', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_radius', 'RadiusGroup'), ), ), migrations.AlterUniqueTogether( name='radiususergroup', unique_together={('user', 'group')}, ), migrations.CreateModel( name='RadiusBatch', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'strategy', models.CharField( choices=[ ('prefix', 'Generate from prefix'), ('csv', 'Import from CSV'), ], db_index=True, help_text= 'Import users from a CSV or generate using a prefix', max_length=16, verbose_name='strategy', ), ), ( 'name', models.CharField( db_index=True, help_text='A unique batch name', max_length=128, verbose_name='name', ), ), ( 'csvfile', private_storage.fields.PrivateFileField( blank=True, help_text= ('The csv file containing the user details to be uploaded' ), null=True, storage=private_storage.storage.files. PrivateFileSystemStorage( base_url=urljoin(RADIUS_API_BASEURL, CSV_URL_PATH), location=settings.PRIVATE_STORAGE_ROOT, ), upload_to=openwisp_radius.base.models. _get_csv_file_location, verbose_name='CSV', ), ), ( 'prefix', models.CharField( blank=True, help_text= ('Usernames generated will be of the format [prefix][number]' ), max_length=20, null=True, verbose_name='prefix', ), ), ( 'user_credentials', jsonfield.fields.JSONField(blank=True, null=True, verbose_name='PDF'), ), ( 'expiration_date', models.DateField( blank=True, help_text='If left blank users will never expire', null=True, verbose_name='expiration date', ), ), ('details', models.CharField(blank=True, max_length=64, null=True)), ( 'organization', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ( 'users', models.ManyToManyField( blank=True, help_text='List of users uploaded in this batch', related_name='radius_batch', to=settings.AUTH_USER_MODEL, ), ), ], options={ 'verbose_name': 'batch user creation', 'verbose_name_plural': 'batch user creation operations', 'db_table': 'radbatch', 'abstract': False, 'unique_together': {('name', 'organization')}, }, bases=(openwisp_users.mixins.ValidateOrgMixin, models.Model), ), migrations.CreateModel( name='PhoneToken', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'valid_until', models.DateTimeField(default=openwisp_radius.utils. get_sms_default_valid_until), ), ('attempts', models.PositiveIntegerField(default=0)), ('verified', models.BooleanField(default=False)), ( 'token', models.CharField( default=openwisp_radius.utils.generate_sms_token, editable=False, max_length=8, ), ), ('ip', models.GenericIPAddressField()), ('details', models.CharField(blank=True, max_length=64, null=True)), ( 'user', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, ), ), ], options={ 'verbose_name': 'Phone verification token', 'verbose_name_plural': 'Phone verification tokens', 'ordering': ('-created', ), 'abstract': False, 'index_together': {('user', 'created'), ('user', 'created', 'ip')}, }, ), ]
def test_non_contrib_app_split(self): self.assertEqual(swapper.split('alt_app.Type'), ('alt_app', 'Type'))
class Migration(migrations.Migration): """ Initial migration for openwisp-radius models Note (It's Manually Edited): - settings._OPENWISP_DEFAULT_ORG_UUID must be set before running; as done in 'openwisp_users'->'0003_default_organization' - Custom logic for setting default organization in all existing relevent records (read comments) """ dependencies = [ swapper.dependency(*swapper.split(settings.AUTH_USER_MODEL), version='0004_default_groups'), ('openwisp_radius', '0001_initial_freeradius'), ] operations = [ migrations.CreateModel( name='RadiusBatch', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'strategy', models.CharField( choices=[ ('prefix', 'Generate from prefix'), ('csv', 'Import from CSV'), ], db_index=True, help_text= 'Import users from a CSV or generate using a prefix', max_length=16, verbose_name='strategy', ), ), ( 'csvfile', models.FileField( blank=True, help_text= ('The csv file containing the user details to be uploaded' ), null=True, upload_to="", verbose_name='CSV', ), ), ( 'prefix', models.CharField( blank=True, help_text= ('Usernames generated will be of the format [prefix][number]' ), max_length=20, null=True, verbose_name='prefix', ), ), ( 'pdf', models.FileField( blank=True, help_text= ('The pdf file containing list of usernames and passwords' ), null=True, upload_to="", verbose_name='PDF', ), ), ( 'expiration_date', models.DateField( blank=True, help_text='If left blank users will never expire', null=True, verbose_name='expiration date', ), ), ( 'name', models.CharField( db_index=True, help_text='A unique batch name', max_length=128, verbose_name='name', ), ), ( 'organization', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ( 'users', models.ManyToManyField( blank=True, help_text='List of users uploaded in this batch', related_name='radius_batch', to=settings.AUTH_USER_MODEL, ), ), ], options={ 'verbose_name': 'batch user creation', 'verbose_name_plural': 'batch user creation operations', 'db_table': 'radbatch', 'abstract': False, 'swappable': 'OPENWISP_RADIUS_RADIUSBATCH_MODEL', }, bases=(openwisp_users.mixins.ValidateOrgMixin, models.Model), ), migrations.CreateModel( name='RadiusGroup', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'name', models.CharField( db_index=True, max_length=255, unique=True, verbose_name='group name', ), ), ( 'description', models.CharField(blank=True, max_length=64, null=True, verbose_name='description'), ), ( 'default', models.BooleanField( default=False, help_text=( 'The default group is automatically assigned ' 'to new users; changing the default group has only ' 'effect on new users (existing users will keep ' 'being members of their current group)'), verbose_name='is default?', ), ), ( 'organization', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ], options={ 'verbose_name': 'group', 'verbose_name_plural': 'groups', 'abstract': False, 'swappable': 'OPENWISP_RADIUS_RADIUSGROUP_MODEL', }, bases=(openwisp_users.mixins.ValidateOrgMixin, models.Model), ), migrations.CreateModel( name='OrganizationRadiusSettings', fields=[ ( 'id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False), ), ( 'token', openwisp_utils.base.KeyField( default=openwisp_utils.utils.get_random_key, help_text=None, max_length=32, validators=[ django.core.validators.RegexValidator( re.compile('^[^\\s/\\.]+$'), code='invalid', message=('This value must not contain spaces, ' 'dots or slashes.'), ) ], ), ), ( 'organization', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ], options={'abstract': False}, bases=(openwisp_users.mixins.ValidateOrgMixin, models.Model), ), migrations.AddField( model_name='radiuscheck', name='is_active', field=models.BooleanField(default=True), ), migrations.AddField( model_name='radiuscheck', name='notes', field=models.TextField(blank=True, null=True), ), migrations.AddField( model_name='radiuscheck', name='user', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, ), ), migrations.AddField( model_name='radiuscheck', name='valid_until', field=models.DateTimeField(blank=True, null=True), ), migrations.AddField( model_name='radiusgroupcheck', name='group', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.OPENWISP_RADIUS_RADIUSGROUP_MODEL, ), ), migrations.AddField( model_name='radiusgroupreply', name='group', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.OPENWISP_RADIUS_RADIUSGROUP_MODEL, ), ), migrations.AddField( model_name='radiusreply', name='user', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, ), ), migrations.AddField( model_name='radiususergroup', name='group', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.OPENWISP_RADIUS_RADIUSGROUP_MODEL, ), ), migrations.AddField( model_name='radiususergroup', name='user', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, ), ), migrations.AlterField( model_name='radiusaccounting', name='called_station_id', field=models.CharField( blank=True, db_column='calledstationid', db_index=True, max_length=50, null=True, verbose_name='called station ID', ), ), migrations.AlterField( model_name='radiusaccounting', name='calling_station_id', field=models.CharField( blank=True, db_column='callingstationid', db_index=True, max_length=50, null=True, verbose_name='calling station ID', ), ), migrations.AlterField( model_name='radiuscheck', name='username', field=models.CharField(blank=True, db_index=True, max_length=64, verbose_name='username'), ), migrations.AlterField( model_name='radiusgroupcheck', name='groupname', field=models.CharField(blank=True, db_index=True, max_length=64, verbose_name='group name'), ), migrations.AlterField( model_name='radiusgroupreply', name='groupname', field=models.CharField(blank=True, db_index=True, max_length=64, verbose_name='group name'), ), migrations.AlterField( model_name='radiusreply', name='username', field=models.CharField(blank=True, db_index=True, max_length=64, verbose_name='username'), ), migrations.AlterField( model_name='radiususergroup', name='groupname', field=models.CharField(blank=True, max_length=64, verbose_name='group name'), ), migrations.AlterField( model_name='radiususergroup', name='username', field=models.CharField(blank=True, db_index=True, max_length=64, verbose_name='username'), ), migrations.AlterUniqueTogether(name='radiusbatch', unique_together={('name', 'organization')}), migrations.AlterModelOptions( name='organizationradiussettings', options={ 'verbose_name': 'Organization radius settings', 'verbose_name_plural': 'Organization radius settings', }, ), migrations.AlterField( model_name='organizationradiussettings', name='id', field=models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False), ), migrations.AlterField( model_name='organizationradiussettings', name='organization', field=models.OneToOneField( on_delete=django.db.models.deletion.CASCADE, related_name='radius_settings', to=get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), # Set null=True for organization field to allow # creation without giving a default value migrations.AddField( model_name='nas', name='organization', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.CASCADE, to=get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), migrations.AddField( model_name='radiusaccounting', name='organization', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.CASCADE, to=get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), migrations.AddField( model_name='radiuscheck', name='organization', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.CASCADE, to=get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), migrations.AddField( model_name='radiuspostauth', name='organization', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.CASCADE, to=get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), migrations.AddField( model_name='radiusreply', name='organization', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.CASCADE, to=get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), # Set default organization for all the existing records migrations.RunPython(add_default_organization, reverse_code=migrations.RunPython.noop), # Set null=False for all organization fields that need # NOT NULL condition as per the openwisp-radius model migrations.AlterField( model_name='nas', name='organization', field=models.ForeignKey( null=False, blank=False, on_delete=django.db.models.deletion.CASCADE, to=get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), migrations.AlterField( model_name='radiusaccounting', name='organization', field=models.ForeignKey( null=False, blank=False, on_delete=django.db.models.deletion.CASCADE, to=get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), migrations.AlterField( model_name='radiuscheck', name='organization', field=models.ForeignKey( null=False, blank=False, on_delete=django.db.models.deletion.CASCADE, to=get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), migrations.AlterField( model_name='radiuspostauth', name='organization', field=models.ForeignKey( null=False, blank=False, on_delete=django.db.models.deletion.CASCADE, to=get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), migrations.AlterField( model_name='radiusreply', name='organization', field=models.ForeignKey( null=False, blank=False, on_delete=django.db.models.deletion.CASCADE, to=get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ]
def test_contrib_app_split(self): self.assertEqual( swapper.split('alt_app.contrib.named_things.NamedThing'), ('alt_app.contrib.named_things', 'NamedThing'))
def get_model(apps, app_name, model): model_name = swapper.get_model_name(app_name, model) model_label = swapper.split(model_name)[0] return apps.get_model(model_label, model)
class Migration(migrations.Migration): initial = True dependencies = [ ('pki', '0001_initial'), dependency(*split(settings.AUTH_USER_MODEL), version='0004_default_groups'), ] operations = [ migrations.CreateModel( name='Config', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ('name', models.CharField(max_length=64, unique=True)), ( 'backend', models.CharField( choices=[ ('netjsonconfig.OpenWrt', 'OpenWRT'), ('netjsonconfig.OpenWisp', 'OpenWISP Firmware 1.x'), ], help_text=( 'Select <a href="http://netjsonconfig.openwisp.org' '/en/stable/" target="_blank">netjsonconfig</a> ' 'backend'), max_length=128, verbose_name='backend', ), ), ( 'config', jsonfield.fields.JSONField( blank=True, default=dict, dump_kwargs={ 'ensure_ascii': False, 'indent': 4 }, help_text= 'configuration in NetJSON DeviceConfiguration format', load_kwargs={ 'object_pairs_hook': collections.OrderedDict }, verbose_name='configuration', ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'status', model_utils.fields.StatusField( choices=[ ('modified', 'modified'), ('running', 'running'), ('error', 'error'), ], default='modified', help_text= ('modified means the configuration is not applied ' 'yet; running means applied and running; error means the ' 'configuration caused issues and it was rolledback'), max_length=100, no_check_for_status=True, ), ), ( 'key', models.CharField( db_index=True, default=openwisp_utils.utils.get_random_key, help_text= ('unique key that can be used to download the configuration' ), max_length=64, unique=True, validators=[ django.core.validators.RegexValidator( re.compile('^[^\\s/\\.]+$', 32), code='invalid', message= 'Key must not contain spaces, dots or slashes.', ) ], ), ), ( 'mac_address', models.CharField( help_text='primary mac address', max_length=17, unique=True, validators=[ django.core.validators.RegexValidator( re.compile( '^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})', 32), code='invalid', message='Must be a valid mac address.', ) ], ), ), ( 'last_ip', models.GenericIPAddressField( blank=True, help_text=('indicates the last ip from which the ' 'configuration was downloaded from (except ' 'downloads from this page)'), null=True, ), ), ( 'organization', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ], options={ 'verbose_name': 'configuration', 'verbose_name_plural': 'configurations', 'abstract': False, }, ), migrations.CreateModel( name='OrganizationConfigSettings', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ( 'registration_enabled', models.BooleanField( default=True, help_text=( 'Whether automatic registration of devices is ' 'enabled or not'), verbose_name='auto-registration enabled', ), ), ( 'shared_secret', openwisp_utils.base.KeyField( db_index=True, default=openwisp_utils.utils.get_random_key, help_text='used for automatic registration of devices', max_length=32, unique=True, validators=[ django.core.validators.RegexValidator( re.compile('^[^\\s/\\.]+$'), code='invalid', message=( 'This value must not contain spaces, dots ' 'or slashes.'), ) ], verbose_name='shared secret', ), ), ( 'organization', models.OneToOneField( on_delete=django.db.models.deletion.CASCADE, related_name='config_settings', to=get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ], options={ 'verbose_name': 'Configuration management settings', 'verbose_name_plural': 'Configuration management settings', }, ), migrations.CreateModel( name='Template', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ('name', models.CharField(max_length=64, unique=True)), ( 'backend', models.CharField( choices=[ ('netjsonconfig.OpenWrt', 'OpenWRT'), ('netjsonconfig.OpenWisp', 'OpenWISP Firmware 1.x'), ], help_text= ('Select <a href="http://netjsonconfig.openwisp.org' '/en/stable/" target="_blank">netjsonconfig</a> backend' ), max_length=128, verbose_name='backend', ), ), ( 'config', jsonfield.fields.JSONField( blank=True, default=dict, dump_kwargs={ 'ensure_ascii': False, 'indent': 4 }, help_text= 'configuration in NetJSON DeviceConfiguration format', load_kwargs={ 'object_pairs_hook': collections.OrderedDict }, verbose_name='configuration', ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'type', models.CharField( choices=[('generic', 'Generic'), ('vpn', 'VPN-client')], db_index=True, default='generic', help_text= ('template type, determines which features are available' ), max_length=16, verbose_name='type', ), ), ( 'default', models.BooleanField( db_index=True, default=False, help_text=('whether new configurations will have this ' 'template enabled by default'), verbose_name='enabled by default', ), ), ( 'auto_cert', models.BooleanField( db_index=True, default=(openwisp_controller.config.base.template. default_auto_cert), help_text= ('whether x509 client certificates should be automatically ' 'managed behind the scenes for each configuration ' 'using this template, valid only for the VPN type'), verbose_name='auto certificate', ), ), ( 'organization', models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ], options={ 'verbose_name': 'template', 'verbose_name_plural': 'templates', 'abstract': False, }, ), migrations.CreateModel( name='Vpn', fields=[ ( 'id', models.UUIDField( default=uuid.uuid4, editable=False, primary_key=True, serialize=False, ), ), ('name', models.CharField(max_length=64, unique=True)), ( 'config', jsonfield.fields.JSONField( default=dict, dump_kwargs={ 'ensure_ascii': False, 'indent': 4 }, help_text= 'configuration in NetJSON DeviceConfiguration format', load_kwargs={ 'object_pairs_hook': collections.OrderedDict }, verbose_name='configuration', ), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'host', models.CharField( help_text='VPN server hostname or ip address', max_length=64), ), ( 'backend', models.CharField( choices=app_settings.VPN_BACKENDS, help_text='Select VPN configuration backend', max_length=128, verbose_name='VPN backend', ), ), ('notes', models.TextField(blank=True)), ('dh', models.TextField(blank=True)), ( 'ca', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to='pki.Ca', verbose_name='Certification Authority', ), ), ( 'cert', models.ForeignKey( blank=True, help_text='leave blank to create automatically', null=True, on_delete=django.db.models.deletion.CASCADE, to='pki.Cert', verbose_name='x509 Certificate', ), ), ( 'organization', models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ], options={ 'verbose_name': 'VPN server', 'verbose_name_plural': 'VPN servers', 'abstract': False, }, ), migrations.CreateModel( name='VpnClient', fields=[ ( 'id', models.AutoField( auto_created=True, primary_key=True, serialize=False, verbose_name='ID', ), ), ('auto_cert', models.BooleanField(default=False)), ( 'cert', models.OneToOneField( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='pki.Cert', ), ), ( 'config', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to='config.Config'), ), ( 'vpn', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to='config.Vpn'), ), ], options={ 'verbose_name': 'VPN client', 'verbose_name_plural': 'VPN clients', 'abstract': False, }, ), migrations.AddField( model_name='template', name='vpn', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='config.Vpn', verbose_name='VPN', ), ), migrations.AddField( model_name='config', name='templates', field=SortedManyToManyField( blank=True, help_text='configuration templates, applied from first to last', related_name='config_relations', to='config.Template', verbose_name='templates', ), ), migrations.AddField( model_name='config', name='vpn', field=models.ManyToManyField( blank=True, related_name='vpn_relations', through='config.VpnClient', to='config.Vpn', ), ), migrations.AlterUniqueTogether(name='vpnclient', unique_together=set([('config', 'vpn') ])), ]
class Migration(migrations.Migration): initial = True dependencies = [ swapper.dependency(*swapper.split(settings.AUTH_USER_MODEL), version='0004_default_groups'), ] operations = [ migrations.CreateModel( name='Ca', fields=[ ( 'id', models.AutoField( auto_created=True, primary_key=True, serialize=False, verbose_name='ID', ), ), ('name', models.CharField(max_length=64)), ('notes', models.TextField(blank=True)), ( 'key_length', models.CharField( blank=True, choices=[ ('', ''), ('512', '512'), ('1024', '1024'), ('2048', '2048'), ('4096', '4096'), ], default=django_x509.base.models.default_key_length, help_text='bits', max_length=6, verbose_name='key length', ), ), ( 'digest', models.CharField( blank=True, choices=[ ('', ''), ('sha1', 'SHA1'), ('sha224', 'SHA224'), ('sha256', 'SHA256'), ('sha384', 'SHA384'), ('sha512', 'SHA512'), ], default=django_x509.base.models. default_digest_algorithm, help_text='bits', max_length=8, verbose_name='digest algorithm', ), ), ( 'validity_start', models.DateTimeField( blank=True, default=django_x509.base.models.default_validity_start, null=True, ), ), ( 'validity_end', models.DateTimeField( blank=True, default=django_x509.base.models. default_ca_validity_end, null=True, ), ), ('country_code', models.CharField(blank=True, max_length=2)), ( 'state', models.CharField(blank=True, max_length=64, verbose_name='state or province'), ), ( 'city', models.CharField(blank=True, max_length=64, verbose_name='city'), ), ( 'organization_name', models.CharField(blank=True, max_length=64, verbose_name='organization'), ), ( 'organizational_unit_name', models.CharField( blank=True, max_length=64, verbose_name='organizational unit name', ), ), ( 'email', models.EmailField(blank=True, max_length=254, verbose_name='email address'), ), ( 'common_name', models.CharField(blank=True, max_length=64, verbose_name='common name'), ), ( 'extensions', jsonfield.fields.JSONField( blank=True, default=list, dump_kwargs={'indent': 4}, help_text='additional x509 certificate extensions', load_kwargs={ 'object_pairs_hook': collections.OrderedDict }, verbose_name='extensions', ), ), ( 'serial_number', models.CharField( blank=True, help_text='leave blank to determine automatically', max_length=48, null=True, verbose_name='serial number', ), ), ( 'certificate', models.TextField( blank=True, help_text='certificate in X.509 PEM format'), ), ( 'private_key', models.TextField( blank=True, help_text='private key in X.509 PEM format'), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'passphrase', models.CharField( blank=True, help_text='Passphrase for the private key, if present', max_length=64, ), ), ('details', models.CharField(blank=True, max_length=64, null=True)), ( 'organization', models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ], options={ 'verbose_name': 'CA', 'verbose_name_plural': 'CAs', 'abstract': False, }, bases=(openwisp_users.mixins.ValidateOrgMixin, models.Model), ), migrations.CreateModel( name='Cert', fields=[ ( 'id', models.AutoField( auto_created=True, primary_key=True, serialize=False, verbose_name='ID', ), ), ('name', models.CharField(max_length=64)), ('notes', models.TextField(blank=True)), ( 'key_length', models.CharField( blank=True, choices=[ ('', ''), ('512', '512'), ('1024', '1024'), ('2048', '2048'), ('4096', '4096'), ], default=django_x509.base.models.default_key_length, help_text='bits', max_length=6, verbose_name='key length', ), ), ( 'digest', models.CharField( blank=True, choices=[ ('', ''), ('sha1', 'SHA1'), ('sha224', 'SHA224'), ('sha256', 'SHA256'), ('sha384', 'SHA384'), ('sha512', 'SHA512'), ], default=django_x509.base.models. default_digest_algorithm, help_text='bits', max_length=8, verbose_name='digest algorithm', ), ), ( 'validity_start', models.DateTimeField( blank=True, default=django_x509.base.models.default_validity_start, null=True, ), ), ( 'validity_end', models.DateTimeField( blank=True, default=django_x509.base.models. default_cert_validity_end, null=True, ), ), ('country_code', models.CharField(blank=True, max_length=2)), ( 'state', models.CharField(blank=True, max_length=64, verbose_name='state or province'), ), ( 'city', models.CharField(blank=True, max_length=64, verbose_name='city'), ), ( 'organization_name', models.CharField(blank=True, max_length=64, verbose_name='organization'), ), ( 'organizational_unit_name', models.CharField( blank=True, max_length=64, verbose_name='organizational unit name', ), ), ( 'email', models.EmailField(blank=True, max_length=254, verbose_name='email address'), ), ( 'common_name', models.CharField(blank=True, max_length=64, verbose_name='common name'), ), ( 'extensions', jsonfield.fields.JSONField( blank=True, default=list, dump_kwargs={'indent': 4}, help_text='additional x509 certificate extensions', load_kwargs={ 'object_pairs_hook': collections.OrderedDict }, verbose_name='extensions', ), ), ( 'serial_number', models.CharField( blank=True, help_text='leave blank to determine automatically', max_length=48, null=True, verbose_name='serial number', ), ), ( 'certificate', models.TextField( blank=True, help_text='certificate in X.509 PEM format'), ), ( 'private_key', models.TextField( blank=True, help_text='private key in X.509 PEM format'), ), ( 'created', model_utils.fields.AutoCreatedField( default=django.utils.timezone.now, editable=False, verbose_name='created', ), ), ( 'modified', model_utils.fields.AutoLastModifiedField( default=django.utils.timezone.now, editable=False, verbose_name='modified', ), ), ( 'passphrase', models.CharField( blank=True, help_text='Passphrase for the private key, if present', max_length=64, ), ), ('revoked', models.BooleanField(default=False, verbose_name='revoked')), ( 'revoked_at', models.DateTimeField(blank=True, default=None, null=True, verbose_name='revoked at'), ), ('details', models.CharField(blank=True, max_length=64, null=True)), ( 'ca', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to='sample_pki.Ca', verbose_name='CA', ), ), ( 'organization', models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ], options={ 'verbose_name': 'certificate', 'verbose_name_plural': 'certificates', 'abstract': False, 'unique_together': {('ca', 'serial_number')}, }, bases=(openwisp_users.mixins.ValidateOrgMixin, models.Model), ), migrations.AddConstraint( model_name='ca', constraint=models.UniqueConstraint( fields=('common_name', 'organization'), name='sample_pki_ca_comman_name_and_organization_is_unique', ), ), migrations.AddConstraint( model_name='cert', constraint=models.UniqueConstraint( fields=('common_name', 'organization'), name='sample_pki_cert_comman_name_and_organization_is_unique', ), ), ]
def __str__(self): _, concrete_name = swapper.split( swapper.get_model_name("survey", "Response")) msg = "{} to {} by {}".format(concrete_name, self.survey, self.user) msg += " on {}".format(self.created) return msg