commit
871474ab6d
|
@ -4,10 +4,11 @@ _Being an adminstrative and user-signup tool for [https://tilde.town]_.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
(None of these are actually implemented yet)
|
* User signup form (✓)
|
||||||
|
* with client-side key generation (only server-side key **validation** at this point)
|
||||||
* User signup form with client-side key generation
|
* Guestbook (✓)
|
||||||
* User account management
|
* Helpdesk (✓)
|
||||||
|
* User account management (admin only)
|
||||||
* Start/stop services
|
* Start/stop services
|
||||||
* Cost reporting using AWS
|
* Cost reporting using AWS
|
||||||
* Status monitoring
|
* Status monitoring
|
||||||
|
|
|
@ -1,6 +1,16 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from .models import Townie
|
from django.contrib.auth.models import User
|
||||||
|
from django.contrib.auth.models import Group
|
||||||
|
|
||||||
|
from .models import Townie, Pubkey
|
||||||
|
|
||||||
|
admin.site.unregister(User)
|
||||||
|
admin.site.unregister(Group)
|
||||||
|
|
||||||
|
class PubkeyInline(admin.TabularInline):
|
||||||
|
model = Pubkey
|
||||||
|
|
||||||
@admin.register(Townie)
|
@admin.register(Townie)
|
||||||
class TownieAdmin(admin.ModelAdmin):
|
class TownieAdmin(admin.ModelAdmin):
|
||||||
|
inlines = [PubkeyInline]
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.2 on 2017-01-13 21:26
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('users', '0006_townie_reasons'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='townie',
|
||||||
|
options={'verbose_name': 'Townie', 'verbose_name_plural': 'Townies'},
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='townie',
|
||||||
|
name='pubkey_type',
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,33 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.2 on 2017-01-13 21:28
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('users', '0007_auto_20170113_2126'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Pubkey',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('key_type', models.CharField(choices=[('ssh-rsa', 'ssh-rsa'), ('ssh-dss', 'ssh-dss')], max_length=15)),
|
||||||
|
('key', models.TextField()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='townie',
|
||||||
|
name='pubkey',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='pubkey',
|
||||||
|
name='townie',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.Townie'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,9 +1,10 @@
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from django.db.models import Model
|
||||||
from django.db.models.signals import post_save
|
from django.db.models.signals import post_save
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.db.models import TextField, BooleanField, CharField
|
from django.db.models import TextField, BooleanField, CharField, ForeignKey
|
||||||
|
|
||||||
|
|
||||||
SSH_TYPE_CHOICES = (
|
SSH_TYPE_CHOICES = (
|
||||||
|
@ -15,24 +16,13 @@ SSH_TYPE_CHOICES = (
|
||||||
class Townie(User):
|
class Townie(User):
|
||||||
"""Both an almost normal Django User as well as an abstraction over a
|
"""Both an almost normal Django User as well as an abstraction over a
|
||||||
system user."""
|
system user."""
|
||||||
pubkey = TextField(blank=False, null=False)
|
class Meta:
|
||||||
|
verbose_name = 'Townie'
|
||||||
|
verbose_name_plural = 'Townies'
|
||||||
shell = CharField(max_length=50, default="/bin/bash")
|
shell = CharField(max_length=50, default="/bin/bash")
|
||||||
reviewed = BooleanField(default=False)
|
reviewed = BooleanField(default=False)
|
||||||
reasons = TextField(blank=True, null=False, default='')
|
reasons = TextField(blank=True, null=False, default='')
|
||||||
displayname = CharField(max_length=100, blank=False, null=False)
|
displayname = CharField(max_length=100, blank=False, null=False)
|
||||||
pubkey_type = CharField(max_length=15,
|
|
||||||
blank=False,
|
|
||||||
null=False,
|
|
||||||
choices=SSH_TYPE_CHOICES)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def home_path(self):
|
|
||||||
return "/home/{}".format(self.username)
|
|
||||||
|
|
||||||
def accept(self):
|
|
||||||
"""Sets self.pending to False. Indicates the user has been signed up
|
|
||||||
after review."""
|
|
||||||
self.pending = False
|
|
||||||
|
|
||||||
# TODO consider a generic ensure method that syncs this model with the
|
# TODO consider a generic ensure method that syncs this model with the
|
||||||
# system. there will likely be things besides shell that we want to keep
|
# system. there will likely be things besides shell that we want to keep
|
||||||
|
@ -42,6 +32,17 @@ class Townie(User):
|
||||||
is."""
|
is."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
|
class Pubkey(Model):
|
||||||
|
key_type = CharField(max_length=15,
|
||||||
|
blank=False,
|
||||||
|
null=False,
|
||||||
|
choices=SSH_TYPE_CHOICES,
|
||||||
|
)
|
||||||
|
key = TextField(blank=False, null=False)
|
||||||
|
townie = ForeignKey(Townie)
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_save, sender=Townie)
|
@receiver(post_save, sender=Townie)
|
||||||
def sync_system_state(sender, instance, created, **kwargs):
|
def sync_system_state(sender, instance, created, **kwargs):
|
||||||
if created:
|
if created:
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.db import transaction
|
||||||
from django.forms import Form, CharField, EmailField, Textarea, ChoiceField, BooleanField
|
from django.forms import Form, CharField, EmailField, Textarea, ChoiceField, BooleanField
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.shortcuts import redirect
|
from django.shortcuts import redirect
|
||||||
|
@ -8,21 +9,24 @@ from django.views.generic import TemplateView
|
||||||
from django.views.generic.edit import FormView
|
from django.views.generic.edit import FormView
|
||||||
|
|
||||||
from .forms import TownieForm
|
from .forms import TownieForm
|
||||||
from .models import Townie
|
from .models import Townie, Pubkey
|
||||||
|
|
||||||
class SignupView(FormView):
|
class SignupView(FormView):
|
||||||
form_class = TownieForm
|
form_class = TownieForm
|
||||||
template_name = 'users/signup.html'
|
template_name = 'users/signup.html'
|
||||||
|
|
||||||
|
@transaction.atomic
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
|
|
||||||
del form.cleaned_data['captcha']
|
del form.cleaned_data['captcha']
|
||||||
del form.cleaned_data['aup']
|
del form.cleaned_data['aup']
|
||||||
|
pubkey = Pubkey(key=form.cleaned_data.pop('pubkey'),
|
||||||
|
key_type=form.cleaned_data.pop('pubkey_type'))
|
||||||
|
|
||||||
t = Townie(**form.cleaned_data)
|
t = Townie(**form.cleaned_data)
|
||||||
|
|
||||||
t.set_unusable_password()
|
t.set_unusable_password()
|
||||||
t.save()
|
t.save()
|
||||||
|
pubkey.townie = t
|
||||||
|
pubkey.save()
|
||||||
return redirect('users:thanks')
|
return redirect('users:thanks')
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue