Started port to Django 2.1, Python 3, Docker

This commit is a rough port to Django 2.1, Python 3 and a Docker based local
development setup. Tests fail/error but migrations and the web frontend are
already runnable. Task queue functionality is untested and translations seem to
have trouble.
This commit is contained in:
Jan Dittberner 2018-11-19 23:28:40 +01:00
parent adc57657dd
commit 6cebd80c89
48 changed files with 1081 additions and 576 deletions

View file

@ -5,7 +5,7 @@ This module defines operating system user related forms.
from __future__ import unicode_literals
from django import forms
from django.core.urlresolvers import reverse
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from crispy_forms.helper import FormHelper
@ -79,7 +79,7 @@ class AddSshPublicKeyForm(forms.ModelForm):
keytext = self.cleaned_data.get('publickeytext')
try:
SshPublicKey.objects.parse_keytext(keytext)
except:
except ValueError:
raise forms.ValidationError(INVALID_SSH_PUBLIC_KEY)
return keytext

View file

@ -1,13 +1,12 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
import django.utils.timezone
import model_utils.fields
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
]
@ -15,9 +14,15 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='AdditionalGroup',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)),
('id', models.AutoField(
verbose_name='ID', serialize=False, auto_created=True,
primary_key=True)),
('created', model_utils.fields.AutoCreatedField(
default=django.utils.timezone.now, verbose_name='created',
editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(
default=django.utils.timezone.now, verbose_name='modified',
editable=False)),
],
options={
'verbose_name': 'Additional group',
@ -28,9 +33,14 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='DeleteTaskResult',
fields=[
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)),
('task_uuid', models.CharField(max_length=64, serialize=False, primary_key=True)),
('created', model_utils.fields.AutoCreatedField(
default=django.utils.timezone.now, verbose_name='created',
editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(
default=django.utils.timezone.now, verbose_name='modified',
editable=False)),
('task_uuid', models.CharField(
max_length=64, serialize=False, primary_key=True)),
('task_name', models.CharField(max_length=255, db_index=True)),
('is_finished', models.BooleanField(default=False)),
('is_success', models.BooleanField(default=False)),
@ -47,12 +57,21 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='Group',
fields=[
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)),
('groupname', models.CharField(unique=True, max_length=16, verbose_name='Group name')),
('gid', models.PositiveSmallIntegerField(unique=True, serialize=False, verbose_name='Group ID', primary_key=True)),
('descr', models.TextField(verbose_name='Description', blank=True)),
('passwd', models.CharField(max_length=128, verbose_name='Group password', blank=True)),
('created', model_utils.fields.AutoCreatedField(
default=django.utils.timezone.now, verbose_name='created',
editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(
default=django.utils.timezone.now, verbose_name='modified',
editable=False)),
('groupname', models.CharField(
unique=True, max_length=16, verbose_name='Group name')),
('gid', models.PositiveSmallIntegerField(
unique=True, serialize=False, verbose_name='Group ID',
primary_key=True)),
('descr', models.TextField(
verbose_name='Description', blank=True)),
('passwd', models.CharField(
max_length=128, verbose_name='Group password', blank=True)),
],
options={
'verbose_name': 'Group',
@ -63,15 +82,21 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='GroupTaskResult',
fields=[
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)),
('task_uuid', models.CharField(max_length=64, serialize=False, primary_key=True)),
('created', model_utils.fields.AutoCreatedField(
default=django.utils.timezone.now, verbose_name='created',
editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(
default=django.utils.timezone.now, verbose_name='modified',
editable=False)),
('task_uuid', models.CharField(
max_length=64, serialize=False, primary_key=True)),
('task_name', models.CharField(max_length=255, db_index=True)),
('is_finished', models.BooleanField(default=False)),
('is_success', models.BooleanField(default=False)),
('state', models.CharField(max_length=10)),
('result_body', models.TextField(blank=True)),
('group', models.ForeignKey(to='osusers.Group')),
('group', models.ForeignKey(
to='osusers.Group', on_delete=models.CASCADE)),
],
options={
'abstract': False,
@ -81,13 +106,23 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='User',
fields=[
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)),
('username', models.CharField(unique=True, max_length=64, verbose_name='User name')),
('uid', models.PositiveSmallIntegerField(unique=True, serialize=False, verbose_name='User ID', primary_key=True)),
('gecos', models.CharField(max_length=128, verbose_name='Gecos field', blank=True)),
('homedir', models.CharField(max_length=256, verbose_name='Home directory')),
('shell', models.CharField(max_length=64, verbose_name='Login shell')),
('created', model_utils.fields.AutoCreatedField(
default=django.utils.timezone.now, verbose_name='created',
editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(
default=django.utils.timezone.now, verbose_name='modified',
editable=False)),
('username', models.CharField(
unique=True, max_length=64, verbose_name='User name')),
('uid', models.PositiveSmallIntegerField(
unique=True, serialize=False, verbose_name='User ID',
primary_key=True)),
('gecos', models.CharField(
max_length=128, verbose_name='Gecos field', blank=True)),
('homedir', models.CharField(
max_length=256, verbose_name='Home directory')),
('shell', models.CharField(
max_length=64, verbose_name='Login shell')),
],
options={
'verbose_name': 'Benutzer',
@ -98,16 +133,43 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='Shadow',
fields=[
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)),
('user', models.OneToOneField(primary_key=True, serialize=False, to='osusers.User', verbose_name='Benutzer')),
('passwd', models.CharField(max_length=128, verbose_name='Encrypted password')),
('changedays', models.PositiveSmallIntegerField(help_text='This is expressed in days since Jan 1, 1970', null=True, verbose_name='Date of last change', blank=True)),
('minage', models.PositiveSmallIntegerField(help_text='Minimum number of days before the password can be changed', null=True, verbose_name='Minimum age', blank=True)),
('maxage', models.PositiveSmallIntegerField(help_text='Maximum number of days after which the password has to be changed', null=True, verbose_name='Maximum age', blank=True)),
('gracedays', models.PositiveSmallIntegerField(help_text='The number of days before the password is going to expire', null=True, verbose_name='Grace period', blank=True)),
('inactdays', models.PositiveSmallIntegerField(help_text='The number of days after the password has expired during which the password should still be accepted', null=True, verbose_name='Inactivity period', blank=True)),
('expiredays', models.PositiveSmallIntegerField(default=None, help_text='The date of expiration of the account, expressed as number of days since Jan 1, 1970', null=True, verbose_name='Account expiration date', blank=True)),
('created', model_utils.fields.AutoCreatedField(
default=django.utils.timezone.now, verbose_name='created',
editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(
default=django.utils.timezone.now, verbose_name='modified',
editable=False)),
('user', models.OneToOneField(
primary_key=True, serialize=False, to='osusers.User',
verbose_name='Benutzer', on_delete=models.CASCADE)),
('passwd', models.CharField(
max_length=128, verbose_name='Encrypted password')),
('changedays', models.PositiveSmallIntegerField(
help_text='This is expressed in days since Jan 1, 1970',
null=True, verbose_name='Date of last change', blank=True)),
('minage', models.PositiveSmallIntegerField(
help_text='Minimum number of days before the password can '
'be changed',
null=True, verbose_name='Minimum age', blank=True)),
('maxage', models.PositiveSmallIntegerField(
help_text='Maximum number of days after which the '
'password has to be changed',
null=True, verbose_name='Maximum age', blank=True)),
('gracedays', models.PositiveSmallIntegerField(
help_text='The number of days before the password is '
'going to expire',
null=True, verbose_name='Grace period', blank=True)),
('inactdays', models.PositiveSmallIntegerField(
help_text='The number of days after the password has '
'expired during which the password should still '
'be accepted',
null=True, verbose_name='Inactivity period', blank=True)),
('expiredays', models.PositiveSmallIntegerField(
default=None,
help_text='The date of expiration of the account, '
'expressed as number of days since Jan 1, 1970',
null=True, verbose_name='Account expiration date',
blank=True)),
],
options={
'verbose_name': 'Shadow password',
@ -118,15 +180,21 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='UserTaskResult',
fields=[
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)),
('task_uuid', models.CharField(max_length=64, serialize=False, primary_key=True)),
('created', model_utils.fields.AutoCreatedField(
default=django.utils.timezone.now, verbose_name='created',
editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(
default=django.utils.timezone.now, verbose_name='modified',
editable=False)),
('task_uuid', models.CharField(
max_length=64, serialize=False, primary_key=True)),
('task_name', models.CharField(max_length=255, db_index=True)),
('is_finished', models.BooleanField(default=False)),
('is_success', models.BooleanField(default=False)),
('state', models.CharField(max_length=10)),
('result_body', models.TextField(blank=True)),
('user', models.ForeignKey(to='osusers.User')),
('user', models.ForeignKey(
to='osusers.User', on_delete=models.CASCADE)),
],
options={
'abstract': False,
@ -136,23 +204,27 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='user',
name='group',
field=models.ForeignKey(verbose_name='Group', to='osusers.Group'),
field=models.ForeignKey(
verbose_name='Group', to='osusers.Group',
on_delete=models.CASCADE),
preserve_default=True,
),
migrations.AddField(
model_name='additionalgroup',
name='group',
field=models.ForeignKey(to='osusers.Group'),
field=models.ForeignKey(
to='osusers.Group', on_delete=models.CASCADE),
preserve_default=True,
),
migrations.AddField(
model_name='additionalgroup',
name='user',
field=models.ForeignKey(to='osusers.User'),
field=models.ForeignKey(
to='osusers.User', on_delete=models.CASCADE),
preserve_default=True,
),
migrations.AlterUniqueTogether(
name='additionalgroup',
unique_together=set([('user', 'group')]),
unique_together={('user', 'group')},
),
]

View file

@ -6,7 +6,6 @@ from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('osusers', '0002_auto_20141226_1456'),
@ -16,7 +15,9 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='user',
name='customer',
field=models.ForeignKey(default=1, to=settings.AUTH_USER_MODEL),
field=models.ForeignKey(
default=1, to=settings.AUTH_USER_MODEL,
on_delete=models.CASCADE),
preserve_default=False,
),
]

View file

@ -1,11 +1,10 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('osusers', '0003_user_customer'),
]
@ -18,7 +17,9 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='shadow',
name='user',
field=models.OneToOneField(primary_key=True, serialize=False, to='osusers.User', verbose_name='User'),
field=models.OneToOneField(
primary_key=True, serialize=False, to='osusers.User',
verbose_name='User', on_delete=models.CASCADE),
preserve_default=True,
),
]

View file

@ -1,13 +1,12 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
import django.utils.timezone
import model_utils.fields
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('osusers', '0004_auto_20150104_1751'),
]
@ -16,13 +15,25 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='SshPublicKey',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)),
('algorithm', models.CharField(max_length=20, verbose_name='Algorithm')),
('data', models.TextField(help_text='Base64 encoded key bytes', verbose_name='Key bytes')),
('comment', models.TextField(verbose_name='Comment', blank=True)),
('user', models.ForeignKey(verbose_name='User', to='osusers.User')),
('id', models.AutoField(
verbose_name='ID', serialize=False, auto_created=True,
primary_key=True)),
('created', model_utils.fields.AutoCreatedField(
default=django.utils.timezone.now, verbose_name='created',
editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(
default=django.utils.timezone.now, verbose_name='modified',
editable=False)),
('algorithm', models.CharField(
max_length=20, verbose_name='Algorithm')),
('data', models.TextField(
help_text='Base64 encoded key bytes',
verbose_name='Key bytes')),
('comment', models.TextField(
verbose_name='Comment', blank=True)),
('user', models.ForeignKey(
verbose_name='User', to='osusers.User',
on_delete=models.CASCADE)),
],
options={
'verbose_name': 'SSH public key',
@ -32,6 +43,6 @@ class Migration(migrations.Migration):
),
migrations.AlterUniqueTogether(
name='sshpublickey',
unique_together=set([('user', 'algorithm', 'data')]),
unique_together={('user', 'algorithm', 'data')},
),
]

View file

@ -198,11 +198,13 @@ class User(TimeStampedModel, models.Model):
_('User name'), max_length=64, unique=True)
uid = models.PositiveSmallIntegerField(
_('User ID'), unique=True, primary_key=True)
group = models.ForeignKey(Group, verbose_name=_('Group'))
group = models.ForeignKey(
Group, verbose_name=_('Group'), on_delete=models.CASCADE)
gecos = models.CharField(_('Gecos field'), max_length=128, blank=True)
homedir = models.CharField(_('Home directory'), max_length=256)
shell = models.CharField(_('Login shell'), max_length=64)
customer = models.ForeignKey(settings.AUTH_USER_MODEL)
customer = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
objects = UserManager()
@ -307,7 +309,9 @@ class Shadow(TimeStampedModel, models.Model):
entry.
"""
user = models.OneToOneField(User, primary_key=True, verbose_name=_('User'))
user = models.OneToOneField(
User, primary_key=True, verbose_name=_('User'),
on_delete=models.CASCADE)
passwd = models.CharField(_('Encrypted password'), max_length=128)
changedays = models.PositiveSmallIntegerField(
_('Date of last change'),
@ -364,8 +368,8 @@ class AdditionalGroup(TimeStampedModel, models.Model):
:py:class:`operating system user <osusers.models.User>`.
"""
user = models.ForeignKey(User)
group = models.ForeignKey(Group)
user = models.ForeignKey(User, on_delete=models.CASCADE)
group = models.ForeignKey(Group, on_delete=models.CASCADE)
class Meta:
unique_together = ('user', 'group')
@ -498,7 +502,8 @@ class SshPublicKey(TimeStampedModel):
system user <osusers.models.User>`.
"""
user = models.ForeignKey(User, verbose_name=_('User'))
user = models.ForeignKey(
User, verbose_name=_('User'), on_delete=models.CASCADE)
algorithm = models.CharField(_('Algorithm'), max_length=20)
data = models.TextField(_('Key bytes'),
help_text=_('Base64 encoded key bytes'))

View file

@ -4,8 +4,8 @@ This module defines the views for gnuviechadmin operating system user handling.
"""
from __future__ import unicode_literals, absolute_import
from django.core.urlresolvers import reverse
from django.shortcuts import redirect
from django.urls import reverse
from django.views.generic import (
CreateView,
DeleteView,