progress on form
parent
f1fc5f4cb8
commit
2d8abd3577
|
@ -0,0 +1,98 @@
|
|||
from random import shuffle
|
||||
import re
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.forms import Form, CharField, EmailField, Textarea, ChoiceField, BooleanField
|
||||
import sshpubkeys as ssh
|
||||
|
||||
from .models import SSH_TYPE_CHOICES
|
||||
|
||||
USERNAME_RE = re.compile(r'[a-z][a-z0-9_]+')
|
||||
USERNAME_MIN_LENGTH = 4
|
||||
DISPLAY_NAME_RE = re.compile(r"[a-zA-Z0-9_\-']+")
|
||||
DISPLAY_MIN_LENGTH = 2
|
||||
|
||||
# >_>
|
||||
CAPTCHA_CHOICES = [('two', 'zorp borp'),
|
||||
('three', 'quop bop'),
|
||||
('four', 'NO, I AM NOT A ROBOT'),
|
||||
('five', 'crackle zop'),
|
||||
('six', '*rusty screech*'),
|
||||
('seven', 'mother, give me legs')]
|
||||
shuffle(CAPTCHA_CHOICES)
|
||||
CAPTCHA_CHOICES.insert(0, ('one', 'beep boop'),)
|
||||
NOT_A_ROBOT = 'four'
|
||||
# <_<
|
||||
|
||||
def validate_username(username):
|
||||
if len(username) < USERNAME_MIN_LENGTH:
|
||||
raise ValidationError('Username too short.')
|
||||
if not USERNAME_RE.match(username):
|
||||
raise ValidationError('Username must be all lowercase, start with a letter, and only use the _ special charcter')
|
||||
|
||||
def validate_displayname(display_name):
|
||||
if len(display_name) < DISPLAY_MIN_LENGTH:
|
||||
raise ValidationError('Display name too short.')
|
||||
if not DISPLAY_NAME_RE.match(display_name):
|
||||
raise ValidationError("Valid characters: a-z, A-Z, 0-9, -, _, and '.")
|
||||
|
||||
def validate_pubkey(pubkey):
|
||||
key = ssh.SSHKey(pubkey, strict_mode=False, skip_option_parsing=True)
|
||||
try:
|
||||
key.parse()
|
||||
except ssh.InvalidKeyException as e:
|
||||
raise ValidationError('Could not validate key: {}'.format(e))
|
||||
except NotImplementedError as e:
|
||||
raise ValidationError('Invalid key type')
|
||||
except Exception as e:
|
||||
raise ValidationError('unknown error: {}'.format(e))
|
||||
|
||||
def validate_captcha(captcha):
|
||||
if captcha != NOT_A_ROBOT:
|
||||
raise ValidationError('Are you sure you are not a robot?')
|
||||
|
||||
|
||||
class TownieForm(Form):
|
||||
username = CharField(
|
||||
validators=(validate_username,),
|
||||
help_text='lowercase and no spaces. underscore ok',
|
||||
label='username')
|
||||
email = EmailField(
|
||||
help_text='only used to message you about your account and nothing else.',
|
||||
label='e-mail')
|
||||
displayname = CharField(
|
||||
validators=(validate_displayname,),
|
||||
help_text='100% optional. pseudonyms welcome.',
|
||||
label='display name',
|
||||
required=False)
|
||||
reasons = CharField(
|
||||
widget=Textarea,
|
||||
required=False,
|
||||
label='what interests you about tilde.town?',
|
||||
help_text='This is a totally optional place for you to tell us what excites you about getting a ~ account. This is mainly just so we can all feel warm fuzzies.')
|
||||
captcha = ChoiceField(
|
||||
choices=CAPTCHA_CHOICES,
|
||||
label='are you a robot?',
|
||||
help_text='pick the response that indicates whether or not you are a robot.',
|
||||
validators=(validate_captcha,)
|
||||
)
|
||||
pubkey = CharField(
|
||||
widget=Textarea,
|
||||
validators=(validate_pubkey,),
|
||||
label='SSH public key',
|
||||
help_text='if this is not a thing you are familiar with, that\'s okay! check out <a href="https://tilde.town/~wiki/ssh.html">our guide</a> to learn how to get one of these.')
|
||||
pubkey_type = ChoiceField(
|
||||
choices=SSH_TYPE_CHOICES,
|
||||
label='SSH public key type',
|
||||
help_text="unless you know what you're doing you can leave this be.")
|
||||
aup = BooleanField(
|
||||
label='i super agree to our acceptable use policy',
|
||||
help_text='please read our <a href="https://tilde.town/~wiki/conduct.html">code of conduct</a> and click this box if you agree.')
|
||||
|
||||
def clean(self):
|
||||
result = super().clean()
|
||||
if self.errors:
|
||||
raise ValidationError('oops, looks like there were some problems below.')
|
||||
return result
|
||||
|
||||
|
|
@ -1,19 +1,24 @@
|
|||
import re
|
||||
|
||||
from django.db.models.signals import post_save
|
||||
from django.dispatch import receiver
|
||||
from django.contrib.auth.models import User
|
||||
from django.db.models import TextField, BooleanField, CharField
|
||||
|
||||
|
||||
SSH_TYPE_CHOICES = (
|
||||
('ssh-rsa', 'ssh-rsa',),
|
||||
('ssh-dss', 'ssh-dss',),
|
||||
)
|
||||
|
||||
|
||||
class Townie(User):
|
||||
"""Both an almost normal Django User as well as an abstraction over a
|
||||
system user."""
|
||||
pubkey = TextField(blank=False, null=False)
|
||||
shell = CharField(max_length=50, default="/bin/bash")
|
||||
reviewed = BooleanField(default=False)
|
||||
reasons = TextField(blank=True, null=False, default='')
|
||||
displayname = CharField(max_length=100, blank=False, null=False)
|
||||
pubkey_type = CharField(max_length=15,
|
||||
blank=False,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from django.conf.urls import url
|
||||
|
||||
from .views import UserSignupView
|
||||
from .views import SignupView, ThanksView
|
||||
|
||||
app_name = 'users'
|
||||
urlpatterns = [
|
||||
url(r'^signup/?$', UserSignupView.as_view(), name='signup'),
|
||||
|
||||
url(r'^signup/?$', SignupView.as_view(), name='signup'),
|
||||
url(r'^thanks/?$', ThanksView.as_view(), name='thanks'),
|
||||
]
|
||||
|
|
|
@ -1,48 +1,37 @@
|
|||
import re
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.forms import Form, CharField, EmailField, Textarea, ChoiceField, BooleanField
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import redirect
|
||||
from django.views.generic import TemplateView
|
||||
from django.views.generic.edit import FormView
|
||||
from django.urls import reverse
|
||||
|
||||
from .models import Townie, SSH_TYPE_CHOICES
|
||||
from .forms import TownieForm
|
||||
from .models import Townie
|
||||
|
||||
# TODO validation functions for final request validation and live js validation
|
||||
# I refuse to duplicate the logic for validation on the front-end and am going
|
||||
# to accept round-trip validation costs with long-term caching.
|
||||
class SignupView(FormView):
|
||||
form_class = TownieForm
|
||||
template_name = 'users/signup.html'
|
||||
# TODO reverse
|
||||
success_url = '/thanks'
|
||||
|
||||
class UserSignupView(TemplateView):
|
||||
template_name = 'ttadmin/signup.html'
|
||||
def form_valid(self, form):
|
||||
|
||||
def get_context_data(self):
|
||||
ctx = super().get_context_data()
|
||||
ctx['ssh_type_choices'] = SSH_TYPE_CHOICES
|
||||
return ctx
|
||||
#t = Townie(
|
||||
# username=username,
|
||||
# displayname=displayname,
|
||||
# pubkey=pubkey,
|
||||
# email=email,
|
||||
#)
|
||||
|
||||
def post(self, request):
|
||||
print(request.POST)
|
||||
# TODO validate
|
||||
username = request.POST.get('username')
|
||||
#t.set_unusable_password()
|
||||
#t.save()
|
||||
|
||||
displayname = request.POST.get('displayname')
|
||||
|
||||
if displayname is None:
|
||||
displayname = username
|
||||
else:
|
||||
# TODO validate
|
||||
pass
|
||||
|
||||
# TODO validate
|
||||
pubkey = request.POST.get('pubkey')
|
||||
|
||||
# TODO validate
|
||||
email = request.POST.get('email')
|
||||
|
||||
t = Townie(
|
||||
username=username,
|
||||
displayname=displayname,
|
||||
pubkey=pubkey,
|
||||
email=email,
|
||||
)
|
||||
|
||||
t.set_unusable_password()
|
||||
t.save()
|
||||
return super().form_valid(form)
|
||||
|
||||
|
||||
return HttpResponse('LOLOLOLOL')
|
||||
# TODO add template for this once i've fixed template directories
|
||||
class ThanksView(TemplateView):
|
||||
template_name = 'users/thanks.html'
|
||||
|
|
Loading…
Reference in New Issue