diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 6b6dc51..992ed49 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -1,6 +1,6 @@ Contributing ============ -Thanks for your interest! Pllease read `our contributing guideliness +Thanks for your interest! Please read `our contributing guideliness `_ and submit a PR. diff --git a/django_freeradius/base/admin.py b/django_freeradius/base/admin.py index 3b6a26e..f12a3b8 100644 --- a/django_freeradius/base/admin.py +++ b/django_freeradius/base/admin.py @@ -1,6 +1,11 @@ from django.contrib.admin import ModelAdmin +from django.contrib.admin.actions import delete_selected from .. import settings as app_settings +from .admin_actions import disable_accounts, enable_accounts +from .admin_filters import DuplicateListFilter, ExpiredListFilter +from .forms import AbstractRadiusCheckAdminForm +from .models import _encode_secret class TimeStampedEditableAdmin(ModelAdmin): @@ -59,10 +64,22 @@ class AbstractRadiusGroupUsersAdmin(TimeStampedEditableAdmin): class AbstractRadiusCheckAdmin(TimeStampedEditableAdmin): - list_display = ('username', 'attribute', 'value', 'is_active', - 'created', 'modified') - search_fields = ('username',) - list_filter = ('created', 'modified') + list_display = ('username', 'attribute', 'is_active', + 'created', 'valid_until') + search_fields = ('username', 'value') + list_filter = (DuplicateListFilter, ExpiredListFilter, 'created', + 'modified', 'valid_until') + readonly_fields = ('value',) + form = AbstractRadiusCheckAdminForm + fields = ('username', 'value', 'op', 'attribute', 'new_value', + 'is_active', 'valid_until', 'note', 'created', 'modified') + actions = [disable_accounts, enable_accounts, delete_selected] + + def save_model(self, request, obj, form, change): + if form.data.get('new_value'): + obj.value = _encode_secret(form.data['attribute'], + form.data.get('new_value')) + obj.save() class AbstractRadiusReplyAdmin(TimeStampedEditableAdmin): diff --git a/django_freeradius/base/admin_actions.py b/django_freeradius/base/admin_actions.py new file mode 100644 index 0000000..b204fae --- /dev/null +++ b/django_freeradius/base/admin_actions.py @@ -0,0 +1,36 @@ +from django.contrib import messages +from django.contrib.admin.models import CHANGE, LogEntry +from django.contrib.contenttypes.models import ContentType +from django.utils.translation import ugettext_lazy as _ + + +def disable_accounts(modeladmin, request, queryset): + queryset.update(is_active=False) + ct = ContentType.objects.get_for_model(queryset.model) + for entry in queryset: + LogEntry.objects.log_action(user_id=request.user.id, + content_type_id=ct.pk, + object_id=entry.pk, + object_repr=entry.username, + action_flag=CHANGE, + change_message=_("Disabled")) + messages.add_message(request, messages.INFO, '%d modifiche' % queryset.count()) + + +disable_accounts.short_description = _('Disable') + + +def enable_accounts(modeladmin, request, queryset): + queryset.update(is_active=True) + ct = ContentType.objects.get_for_model(queryset.model) + for entry in queryset: + LogEntry.objects.log_action(user_id=request.user.id, + content_type_id=ct.pk, + object_id=entry.pk, + object_repr=entry.username, + action_flag=CHANGE, + change_message=_("Enabled")) + messages.add_message(request, messages.INFO, '%d modifiche' % queryset.count()) + + +enable_accounts.short_description = _('Enable') diff --git a/django_freeradius/base/admin_filters.py b/django_freeradius/base/admin_filters.py new file mode 100644 index 0000000..3f80f63 --- /dev/null +++ b/django_freeradius/base/admin_filters.py @@ -0,0 +1,30 @@ +from django.contrib.admin import SimpleListFilter +from django.utils.translation import ugettext_lazy as _ + + +class DuplicateListFilter(SimpleListFilter): + title = _('find duplicates') + parameter_name = 'duplicates' + + def lookups(self, request, model_admin): + return (('username', _('username')), ('value', _('value'))) + + def queryset(self, request, queryset): + if self.value() == 'value': + return queryset.filter_duplicate_value() + elif self.value() == 'username': + return queryset.filter_duplicate_username() + + +class ExpiredListFilter(SimpleListFilter): + title = _('find expired') + parameter_name = 'expired' + + def lookups(self, request, model_admin): + return (('expired', _('expired')), ('not_expired', _('not expired'))) + + def queryset(self, request, queryset): + if self.value() == 'expired': + return queryset.filter_expired() + elif self.value() == 'not_expired': + return queryset.filter_not_expired() diff --git a/django_freeradius/base/forms.py b/django_freeradius/base/forms.py new file mode 100644 index 0000000..1395595 --- /dev/null +++ b/django_freeradius/base/forms.py @@ -0,0 +1,37 @@ +import re + +from django import forms +from django.core.exceptions import ValidationError +from django.utils.translation import ugettext_lazy as _ + +from .. import settings as app_settings +from .models import AbstractRadiusCheck + + +class AbstractRadiusCheckAdminForm(forms.ModelForm): + _secret_help_text = _('The secret must contains lowercase' + ' and uppercase characters, ' + ' number and at least one of these symbols:' + '! % - _ + = [ ] { } : , . ? < > ( ) ; ') + # custom field not backed by database + new_value = forms.CharField(label=_('Value'), required=False, + min_length=8, max_length=16, + widget=forms.PasswordInput(), + help_text=_secret_help_text) + + def clean_attribute(self): + if self.data['attribute'] not in app_settings.DISABLED_SECRET_FORMATS: + return self.cleaned_data["attribute"] + + def clean_new_value(self): + if not self.data['new_value']: + return None + for regexp in app_settings.RADCHECK_SECRET_VALIDATORS.values(): + found = re.findall(regexp, self.data['new_value']) + if not found: + raise ValidationError(self._secret_help_text) + return self.cleaned_data["new_value"] + + class Meta: + model = AbstractRadiusCheck + fields = '__all__' diff --git a/django_freeradius/base/models.py b/django_freeradius/base/models.py index a1fc643..c1e7f94 100644 --- a/django_freeradius/base/models.py +++ b/django_freeradius/base/models.py @@ -1,40 +1,38 @@ from django.db import models +from django.db.models import Count from django.utils.encoding import python_2_unicode_compatible from django.utils.timezone import now from django.utils.translation import ugettext_lazy as _ from model_utils.fields import AutoCreatedField, AutoLastModifiedField - -RADOP_CHECK_TYPES = ( - ('=', '='), - (':=', ':='), - ('==', '=='), - ('+=', '+='), - ('!=', '!='), - ('>', '>'), - ('>=', '>='), - ('<', '<'), - ('<=', '<='), - ('=~', '=~'), - ('!~', '!~'), - ('=*', '=*'), - ('!*', '!*'), -) - -RADOP_REPLY_TYPES = ( - ('=', '='), - (':=', ':='), - ('+=', '+='), -) - -RADCHECK_PASSWD_TYPE = ( - ('Cleartext-Password', 'Cleartext-Password'), - ('NT-Password', 'NT-Password'), - ('LM-Password', 'LM-Password'), - ('MD5-Password', 'MD5-Password'), - ('SMD5-Password', 'SMD5-Password'), - ('SSHA-Password', 'SSHA-Password'), - ('Crypt-Password', 'Crypt-Password'), -) +from passlib.hash import lmhash, nthash + +from .. import settings as app_settings + +RADOP_CHECK_TYPES = (('=', '='), + (':=', ':='), + ('==', '=='), + ('+=', '+='), + ('!=', '!='), + ('>', '>'), + ('>=', '>='), + ('<', '<'), + ('<=', '<='), + ('=~', '=~'), + ('!~', '!~'), + ('=*', '=*'), + ('!*', '!*')) + +RADOP_REPLY_TYPES = (('=', '='), + (':=', ':='), + ('+=', '+=')) + +RADCHECK_PASSWD_TYPE = ['Cleartext-Password', + 'NT-Password', + 'LM-Password', + 'MD5-Password', + 'SMD5-Password', + 'SSHA-Password', + 'Crypt-Password'] class TimeStampedEditableModel(models.Model): @@ -123,6 +121,48 @@ def __str__(self): return self.username +class AbstractRadiusCheckQueryset(models.query.QuerySet): + def filter_duplicate_username(self): + pks = [] + for i in self.values('username').annotate(Count('id')).order_by().filter(id__count__gt=1): + pks.extend([account.pk for account in self.filter(username=i['username'])]) + return self.filter(pk__in=pks) + + def filter_duplicate_value(self): + pks = [] + for i in self.values('value').annotate(Count('id')).order_by().filter(id__count__gt=1): + pks.extend([accounts.pk for accounts in self.filter(value=i['value'])]) + return self.filter(pk__in=pks) + + def filter_expired(self): + return self.filter(valid_until__lt=now()) + + def filter_not_expired(self): + return self.filter(valid_until__gte=now()) + + +def _encode_secret(attribute, new_value=None): + if attribute == 'Cleartext-Password': + password_renewed = new_value + elif attribute == 'NT-Password': + password_renewed = nthash.hash(new_value) + elif attribute == 'LM-Password': + password_renewed = lmhash.hash(new_value) + return password_renewed + + +class AbstractRadiusCheckManager(models.Manager): + def get_queryset(self): + return AbstractRadiusCheckQueryset(self.model, using=self._db) + + def create(self, *args, **kwargs): + if 'new_value' in kwargs: + kwargs['value'] = _encode_secret(kwargs['attribute'], + kwargs['new_value']) + del(kwargs['new_value']) + return super(AbstractRadiusCheckManager, self).create(*args, **kwargs) + + @python_2_unicode_compatible class AbstractRadiusCheck(TimeStampedEditableModel): username = models.CharField(verbose_name=_('username'), @@ -134,8 +174,16 @@ class AbstractRadiusCheck(TimeStampedEditableModel): choices=RADOP_CHECK_TYPES, default=':=') attribute = models.CharField(verbose_name=_('attribute'), - max_length=64, choices=RADCHECK_PASSWD_TYPE) + max_length=64, + choices=[(i, i) for i in RADCHECK_PASSWD_TYPE + if i not in + app_settings.DISABLED_SECRET_FORMATS], + blank=True, + default=app_settings.DEFAULT_SECRET_FORMAT) is_active = models.BooleanField(default=True) + valid_until = models.DateTimeField(null=True, blank=True) + note = models.TextField(null=True, blank=True) + objects = AbstractRadiusCheckManager() class Meta: db_table = 'radcheck' diff --git a/django_freeradius/migrations/0009_radiuscheck_expires.py b/django_freeradius/migrations/0009_radiuscheck_expires.py new file mode 100644 index 0000000..0ce0c44 --- /dev/null +++ b/django_freeradius/migrations/0009_radiuscheck_expires.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.6 on 2017-11-03 11:18 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('django_freeradius', '0008_auto_20171004_1003'), + ] + + operations = [ + migrations.AddField( + model_name='radiuscheck', + name='expires', + field=models.DateTimeField(blank=True, null=True), + ), + ] diff --git a/django_freeradius/migrations/0010_auto_20171107_1158.py b/django_freeradius/migrations/0010_auto_20171107_1158.py new file mode 100644 index 0000000..727cfbd --- /dev/null +++ b/django_freeradius/migrations/0010_auto_20171107_1158.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.6 on 2017-11-07 10:58 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('django_freeradius', '0009_radiuscheck_expires'), + ] + + operations = [ + migrations.RenameField( + model_name='radiuscheck', + old_name='expires', + new_name='valid_until', + ), + ] diff --git a/django_freeradius/migrations/0011_radiuscheck_note.py b/django_freeradius/migrations/0011_radiuscheck_note.py new file mode 100644 index 0000000..1c16a16 --- /dev/null +++ b/django_freeradius/migrations/0011_radiuscheck_note.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.6 on 2017-11-08 14:46 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('django_freeradius', '0010_auto_20171107_1158'), + ] + + operations = [ + migrations.AddField( + model_name='radiuscheck', + name='note', + field=models.TextField(blank=True, null=True), + ), + ] diff --git a/django_freeradius/migrations/0012_auto_20171206_1546.py b/django_freeradius/migrations/0012_auto_20171206_1546.py new file mode 100644 index 0000000..37c0bc0 --- /dev/null +++ b/django_freeradius/migrations/0012_auto_20171206_1546.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.7 on 2017-12-06 14:46 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('django_freeradius', '0011_radiuscheck_note'), + ] + + operations = [ + migrations.AlterField( + model_name='radiuscheck', + name='attribute', + field=models.CharField(blank=True, choices=[('Cleartext-Password', 'Cleartext-Password'), ('NT-Password', 'NT-Password'), ('LM-Password', 'LM-Password'), ('MD5-Password', 'MD5-Password'), ('SMD5-Password', 'SMD5-Password'), ('SSHA-Password', 'SSHA-Password'), ('Crypt-Password', 'Crypt-Password')], default='NT-Password', max_length=64, verbose_name='attribute'), + ), + migrations.AlterField( + model_name='radiuscheck', + name='is_active', + field=models.BooleanField(default=True), + ), + ] diff --git a/django_freeradius/migrations/0013_auto_20171211_1045.py b/django_freeradius/migrations/0013_auto_20171211_1045.py new file mode 100644 index 0000000..03804c6 --- /dev/null +++ b/django_freeradius/migrations/0013_auto_20171211_1045.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.7 on 2017-12-11 09:45 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('django_freeradius', '0012_auto_20171206_1546'), + ] + + operations = [ + migrations.AlterField( + model_name='radiuscheck', + name='attribute', + field=models.CharField(blank=True, choices=[('NT-Password', 'NT-Password')], default='NT-Password', max_length=64, verbose_name='attribute'), + ), + ] diff --git a/django_freeradius/settings.py b/django_freeradius/settings.py index de4523f..1bc336f 100644 --- a/django_freeradius/settings.py +++ b/django_freeradius/settings.py @@ -2,3 +2,24 @@ EDITABLE_ACCOUNTING = getattr(settings, 'DJANGO_FREERADIUS_EDITABLE_ACCOUNTING', False) EDITABLE_POSTAUTH = getattr(settings, 'DJANGO_FREERADIUS_EDITABLE_POSTAUTH', False) + +DEFAULT_SECRET_FORMAT = getattr(settings, + 'DJANGO_FREERADIUS_DEFAULT_SECRET_FORMAT', + 'NT-Password') + +DISABLED_SECRET_FORMATS = getattr(settings, + 'DISABLED_SECRET_FORMATS', + ['Cleartext-Password', + 'LM-Password', + 'MD5-Password', + 'SMD5-Password', + 'SSHA-Password', + 'Crypt-Password']) + +RADCHECK_SECRET_VALIDATORS = getattr(settings, + 'DJANGO_FREERADIUS_RADCHECK_SECRET_VALIDATORS', + {'regexp_lowercase': '[a-z]+', + 'regexp_uppercase': '[A-Z]+', + 'regexp_number': '[0-9]+', + 'regexp_special': '[\!\%\-_+=\[\]\ + {\}\:\,\.\?\<\>\(\)\;]+'}) diff --git a/docs/source/general/freeradius.rst b/docs/source/general/freeradius.rst index ee4ac5b..ad75511 100644 --- a/docs/source/general/freeradius.rst +++ b/docs/source/general/freeradius.rst @@ -9,6 +9,9 @@ in order to make it work with `django-freeradius =1.11,<1.12 django-model-utils swapper djangorestframework>=3.7,<3.8 +passlib diff --git a/tests/sample_radius/tests.py b/tests/sample_radius/tests.py index 9c3a43f..75ee75e 100644 --- a/tests/sample_radius/tests.py +++ b/tests/sample_radius/tests.py @@ -1,4 +1,5 @@ import os +from copy import copy from unittest import skipUnless import swapper @@ -17,6 +18,12 @@ RadiusAccounting = swapper.load_model("django_freeradius", "RadiusAccounting") RadiusGroup = swapper.load_model("django_freeradius", "RadiusGroup") +_SUPERUSER = {'username': 'gino', 'password': 'cic', 'email': 'giggi_vv@gmail.it'} +_RADCHECK_ENTRY = {'username': 'Monica', 'value': 'Cam0_liX', + 'attribute': 'NT-Password'} +_RADCHECK_ENTRY_PW_UPDATE = {'username': 'Monica', 'new_value': 'Cam0_liX', + 'attribute': 'NT-Password'} + @skipUnless(os.environ.get('SAMPLE_APP', False), 'Running tests on standard django_freeradius models') class TestNas(TestCase): @@ -95,29 +102,116 @@ def test_users_not_login(self): self.assertEqual(resp.status_code, 302) def test_users(self): - self.client.login(username='gino', password='ciao') + self.client.login(username=_SUPERUSER['username'], password=_SUPERUSER['password']) resp = self.client.get('/admin/login/?next=/admin/') self.assertEqual(resp.status_code, 200) def test_radius_nas_change(self): - User.objects.create_superuser(username='gino', password='cc', email='giggi_vv@gmail.it') + User.objects.create_superuser(**_SUPERUSER) obj = Nas.objects.create(name='fiore', short_name='ff', type='cisco', secret='d', ports='22', community='vmv', description='ciao', server='jsjs', details='nb') - self.client.login(username='gino', password='cc') + self.client.login(username=_SUPERUSER['username'], password=_SUPERUSER['password']) resp = self.client.get(reverse('admin:sample_radius_nas_change', args=[obj.pk])) self.assertContains(resp, 'ok') def test_radiuscheck_change(self): - User.objects.create_superuser(username='gino', password='cic', email='giggi_vv@gmail.it') - obj = RadiusCheck.objects.create(username='bob', attribute='Cleartext-Password', - op=':=', value='passbob', details='nb') - self.client.login(username='gino', password='cic') - resp = self.client.get(reverse('admin:sample_radius_radiuscheck_change', args=[obj.pk])) - self.assertContains(resp, 'ok') + User.objects.create_superuser(**_SUPERUSER) + self.client.login(username=_SUPERUSER['username'], password=_SUPERUSER['password']) + obj = RadiusCheck.objects.create(**_RADCHECK_ENTRY) + _RADCHECK = copy(_RADCHECK_ENTRY_PW_UPDATE) + _RADCHECK['attribute'] = 'Cleartext-Password' + RadiusCheck.objects.create(**_RADCHECK) + _RADCHECK['attribute'] = 'LM-Password' + RadiusCheck.objects.create(**_RADCHECK) + _RADCHECK['attribute'] = 'NT-Password' + RadiusCheck.objects.create(**_RADCHECK) + self.client.login(username=_SUPERUSER['username'], password=_SUPERUSER['password']) + response = self.client.post(reverse('admin:sample_radius_radiuscheck_change', args=[obj.pk]), + _RADCHECK_ENTRY_PW_UPDATE, follow=True) + self.assertContains(response, 'ok') + + def test_radiuscheck_create_weak_passwd(self): + User.objects.create_superuser(**_SUPERUSER) + self.client.login(username=_SUPERUSER['username'], password=_SUPERUSER['password']) + _RADCHECK = copy(_RADCHECK_ENTRY_PW_UPDATE) + _RADCHECK['new_value'] = '' + resp = self.client.post(reverse('admin:sample_radius_radiuscheck_add'), + _RADCHECK, follow=True) + self.assertEqual(resp.status_code, 200) + + def test_radiuscheck_create_disabled_hash(self): + User.objects.create_superuser(**_SUPERUSER) + self.client.login(username=_SUPERUSER['username'], password=_SUPERUSER['password']) + _RADCHECK = copy(_RADCHECK_ENTRY_PW_UPDATE) + _RADCHECK['attribute'] = 'Cleartext-Password' + response = self.client.post(reverse('admin:sample_radius_radiuscheck_add'), + _RADCHECK, follow=True) + self.assertEqual(response.status_code, 200) + + def test_radiuscheck_admin_save_model(self): + obj = RadiusCheck.objects.create(**_RADCHECK_ENTRY) + User.objects.create_superuser(**_SUPERUSER) + self.client.login(username=_SUPERUSER['username'], password=_SUPERUSER['password']) + change_url = reverse('admin:sample_radius_radiuscheck_change', args=[obj.pk]) + # test admin save_model method + data = _RADCHECK_ENTRY_PW_UPDATE + data['op'] = ':=' + response = self.client.post(change_url, data, follow=True) + # test also invalid password + data = _RADCHECK_ENTRY_PW_UPDATE + data['new_value'] = 'cionfrazZ' + response = self.client.post(change_url, data, follow=True) + self.assertEqual(response.status_code, 200) + + def test_radiuscheck_enable_disable_accounts(self): + User.objects.create_superuser(**_SUPERUSER) + self.client.login(username=_SUPERUSER['username'], password=_SUPERUSER['password']) + RadiusCheck.objects.create(**_RADCHECK_ENTRY) + accounts = RadiusCheck.objects.all().values_list('pk', flat=True) + change_url = reverse('admin:sample_radius_radiuscheck_changelist') + data = {'action': 'enable_accounts', + '_selected_action': accounts} + self.client.post(change_url, data, follow=True) + data = {'action': 'disable_accounts', + '_selected_action': accounts} + self.client.post(change_url, data, follow=True) + self.assertEqual(RadiusCheck.objects.filter(is_active=True).count(), 0) + + def test_radiuscheck_filter_duplicates_username(self): + User.objects.create_superuser(**_SUPERUSER) + self.client.login(username=_SUPERUSER['username'], password=_SUPERUSER['password']) + RadiusCheck.objects.create(**_RADCHECK_ENTRY) + RadiusCheck.objects.create(**_RADCHECK_ENTRY) + url = reverse('admin:sample_radius_radiuscheck_changelist')+'?duplicates=username' + resp = self.client.get(url, follow=True) + self.assertEqual(resp.status_code, 200) + + def test_radiuscheck_filter_duplicates_value(self): + User.objects.create_superuser(**_SUPERUSER) + self.client.login(username=_SUPERUSER['username'], password=_SUPERUSER['password']) + RadiusCheck.objects.create(**_RADCHECK_ENTRY) + RadiusCheck.objects.create(**_RADCHECK_ENTRY) + url = reverse('admin:sample_radius_radiuscheck_changelist')+'?duplicates=value' + resp = self.client.get(url, follow=True) + self.assertEqual(resp.status_code, 200) + + def test_radiuscheck_filter_expired(self): + User.objects.create_superuser(**_SUPERUSER) + self.client.login(username=_SUPERUSER['username'], password=_SUPERUSER['password']) + url = reverse('admin:sample_radius_radiuscheck_changelist')+'?expired=expired' + resp = self.client.get(url, follow=True) + self.assertEqual(resp.status_code, 200) + + def test_radiuscheck_filter_not_expired(self): + User.objects.create_superuser(**_SUPERUSER) + self.client.login(username=_SUPERUSER['username'], password=_SUPERUSER['password']) + url = reverse('admin:sample_radius_radiuscheck_changelist')+'?expired=not_expired' + resp = self.client.get(url, follow=True) + self.assertEqual(resp.status_code, 200) def test_radiusreply_change(self): - User.objects.create_superuser(username='gino', password='cic', email='giggi_vv@gmail.it') + User.objects.create_superuser(**_SUPERUSER) obj = RadiusReply.objects.create(username='bob', attribute='Cleartext-Password', op=':=', value='passbob', details='nb') self.client.login(username='gino', password='cic') @@ -125,40 +219,40 @@ def test_radiusreply_change(self): self.assertContains(resp, 'ok') def test_radiusgroupreply_change(self): - User.objects.create_superuser(username='gino', password='cic', email='giggi_vv@gmail.it') + User.objects.create_superuser(**_SUPERUSER) obj = RadiusGroupReply.objects.create(groupname='students', attribute='Cleartext-Password', op=':=', value='PPP', details='nb') - self.client.login(username='gino', password='cic') + self.client.login(username=_SUPERUSER['username'], password=_SUPERUSER['password']) resp = self.client.get(reverse('admin:sample_radius_radiusgroupreply_change', args=[obj.pk])) self.assertContains(resp, 'ok') def test_radiusgroupcheck_change(self): - User.objects.create_superuser(username='fiorella', password='ciao', email='giggi_fiore@gmail.it') + User.objects.create_superuser(**_SUPERUSER) obj = RadiusGroupCheck.objects.create(groupname='students', attribute='Cleartext-Password', op=':=', value='PPP', details='nb') - self.client.login(username='fiorella', password='ciao') + self.client.login(username=_SUPERUSER['username'], password=_SUPERUSER['password']) resp = self.client.get(reverse('admin:sample_radius_radiusgroupcheck_change', args=[obj.pk])) self.assertContains(resp, 'ok') def test_radiusgroup_change(self): - User.objects.create_superuser(username='gino', password='cic', email='giggi_vv@gmail.it') + User.objects.create_superuser(**_SUPERUSER) obj = RadiusGroup.objects.create(id='870df8e8-3107-4487-8316-81e089b8c2cf', groupname='students', priority='1', notes='hh', details='nb') - self.client.login(username='gino', password='cic') + self.client.login(username=_SUPERUSER['username'], password=_SUPERUSER['password']) resp = self.client.get(reverse('admin:sample_radius_radiusgroup_change', args=[obj.pk])) self.assertContains(resp, 'ok') def test_radiususergroup_change(self): - User.objects.create_superuser(username='gino', password='cic', email='giggi_vv@gmail.it') + User.objects.create_superuser(**_SUPERUSER) obj = RadiusUserGroup.objects.create(username='bob', groupname='students', priority='1', details='nb') - self.client.login(username='gino', password='cic') + self.client.login(username=_SUPERUSER['username'], password=_SUPERUSER['password']) resp = self.client.get(reverse('admin:sample_radius_radiususergroup_change', args=[obj.pk])) self.assertContains(resp, 'ok') def test_radiusgroupusers_change(self): - User.objects.create_superuser(username='gino', password='cic', email='giggi_vv@gmail.it') + User.objects.create_superuser(**_SUPERUSER) reply = RadiusReply.objects.create(username='bob', attribute='Cleartext-Password', op=':=', value='passbob') check = RadiusCheck.objects.create(username='bob', attribute='Cleartext-Password', @@ -167,12 +261,12 @@ def test_radiusgroupusers_change(self): username='bob', groupname='students') obj.radius_reply.add(reply) obj.radius_check.add(check) - self.client.login(username='gino', password='cic') + self.client.login(username=_SUPERUSER['username'], password=_SUPERUSER['password']) resp = self.client.get(reverse('admin:sample_radius_radiusgroupusers_change', args=[obj.pk])) self.assertContains(resp, 'ok') def test_radiusaccounting_change(self): - User.objects.create_superuser(username='gino', password='cic', email='giggi_vv@gmail.it') + User.objects.create_superuser(**_SUPERUSER) ola = RadiusAccounting.objects.create( unique_id='-2', username='bob', nas_ip_address='127.0.0.1', start_time='2012-09-04 06:00:00.000000-01:00', @@ -181,14 +275,14 @@ def test_radiusaccounting_change(self): input_octets='1', output_octets='4', details='nb', update_time='2012-09-06 11:50' ) - self.client.login(username='gino', password='cic') + self.client.login(username=_SUPERUSER['username'], password=_SUPERUSER['password']) resp = self.client.get(reverse('admin:sample_radius_radiusaccounting_change', args=[ola.pk])) self.assertContains(resp, 'ok') def test_radiuspostauth_change(self): - User.objects.create_superuser(username='gino', password='cic', email='giggi_vv@gmail.it') + User.objects.create_superuser(**_SUPERUSER) olu = RadiusPostAuth.objects.create(username='gino', password='ciao', reply='ghdhd', date='2017-09-02', details='nb') - self.client.login(username='gino', password='cic') + self.client.login(username=_SUPERUSER['username'], password=_SUPERUSER['password']) resp = self.client.get(reverse('admin:sample_radius_radiuspostauth_change', args=[olu.pk])) self.assertContains(resp, 'ok')