tildetown-admin/ttadmin/users/forms.py

88 lines
3.4 KiB
Python
Raw Normal View History

2016-11-30 07:48:02 +00:00
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
2016-12-01 06:49:06 +00:00
from .models import Townie, SSH_TYPE_CHOICES
from common.forms import CaptchaField, throttler
submission_throttle = {}
throttle_submission = throttler(submission_throttle)
2016-12-19 05:28:16 +00:00
2016-11-30 07:48:02 +00:00
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
2016-12-19 23:22:06 +00:00
2016-11-30 07:48:02 +00:00
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')
2016-12-01 06:49:06 +00:00
duplicate = Townie.objects.filter(username=username).count()
if duplicate > 0:
raise ValidationError('Username already in use :(')
2016-11-30 07:48:02 +00:00
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):
2016-11-30 08:32:53 +00:00
# TODO see if I can get the type out
2016-11-30 07:48:02 +00:00
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))
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.')
2016-12-19 05:28:16 +00:00
captcha = CaptchaField()
2016-11-30 07:48:02 +00:00
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.')
throttle_submission(self.cleaned_data['email'])
2016-11-30 07:48:02 +00:00
return result