Browse Source
Add a database schema, admin page, db commands, code creation form
Add a database schema, admin page, db commands, code creation form
* Added a simple database schema that is created at start * Added database methods to CRUD registration codes and read registered users * Added a table to the admin page with registration codes * Added a form to create registration codes * Added embedded forms to expire and delete registration codes * Added endpoints to facilitate expiring and deleting registration codes * Added models and helpers to facilitate storing and retrieving data * Added a password safety validator on registrationmaster
Drew Short
6 years ago
9 changed files with 315 additions and 26 deletions
-
2.gitignore
-
84app.py
-
112db.py
-
34forms.py
-
43models.py
-
1requirements.txt
-
12schema.sql
-
42templates/admin.html
-
1templates/register.html
@ -1 +1,3 @@ |
|||
.idea |
|||
|
|||
*.db |
@ -1,14 +1,40 @@ |
|||
from flask_wtf import FlaskForm |
|||
from wtforms import StringField, PasswordField |
|||
from wtforms.validators import DataRequired |
|||
from wtforms import StringField, PasswordField, DateField, IntegerField, SubmitField |
|||
from wtforms.validators import DataRequired, Length, EqualTo, InputRequired, \ |
|||
ValidationError, NumberRange, Optional |
|||
import safe |
|||
|
|||
|
|||
def safe_password_validator(form: FlaskForm, field): |
|||
strength = safe.check(field.data, level=safe.MEDIUM) |
|||
if not strength.valid: |
|||
raise ValidationError("Password is not secure enough: %s" % strength.message) |
|||
|
|||
|
|||
class RegistrationForm(FlaskForm): |
|||
username = StringField('Username', validators=[DataRequired()]) |
|||
password = PasswordField('Password', validators=[DataRequired()]) |
|||
username = StringField('Username', validators=[DataRequired(), Length(min=3, max=30)]) |
|||
password = PasswordField( |
|||
'Password', |
|||
validators=[ |
|||
InputRequired(), |
|||
EqualTo('confirm', message='Passwords must match'), |
|||
safe_password_validator |
|||
]) |
|||
confirm = PasswordField('Repeat Password') |
|||
registration_code = StringField('Registration Code', validators=[DataRequired()]) |
|||
|
|||
|
|||
class LoginForm(FlaskForm): |
|||
username = StringField('Username', validators=[DataRequired()]) |
|||
token = PasswordField('Token', validators=[DataRequired()]) |
|||
|
|||
|
|||
class RegistrationCodeForm(FlaskForm): |
|||
expiration_time = DateField('Expiration Time', validators=[Optional()]) |
|||
max_usages = IntegerField('Max Usages', validators=[NumberRange(min=1)]) |
|||
|
|||
|
|||
class ExpireRegistrationCodeForm(FlaskForm): |
|||
registration_code = StringField('Registration Code') |
|||
expire = SubmitField(label='Expire') |
|||
delete = SubmitField(label='Delete') |
@ -0,0 +1,43 @@ |
|||
from datetime import datetime |
|||
from typing import Tuple |
|||
|
|||
|
|||
class RegistrationCode: |
|||
def __init__(self, |
|||
code: str, |
|||
creation_time: datetime = datetime.now(), |
|||
expiration_time: datetime = None, |
|||
usages: int = 0, |
|||
max_usages: int = 1): |
|||
self.code = code |
|||
self.creation_time = creation_time |
|||
self.expiration_time = expiration_time |
|||
self.usages = usages |
|||
self.max_usages = max_usages |
|||
|
|||
@staticmethod |
|||
def from_db(db_registration_code: Tuple) -> 'RegistrationCode': |
|||
expiration_time = None if db_registration_code[2] is None else datetime.fromisoformat(db_registration_code[2]) |
|||
return RegistrationCode( |
|||
db_registration_code[0], |
|||
datetime.fromisoformat(db_registration_code[1]), |
|||
expiration_time, |
|||
db_registration_code[3], |
|||
db_registration_code[4] |
|||
) |
|||
|
|||
def is_expired(self): |
|||
return self.expiration_time is not None and self.expiration_time < datetime.now() |
|||
|
|||
|
|||
class RegisteredUser: |
|||
def __init__(self, username: str, registered_time: datetime = datetime.now()): |
|||
self.username = username |
|||
self.registered_time = registered_time |
|||
|
|||
@staticmethod |
|||
def from_db(db_registered_user: Tuple) -> 'RegisteredUser': |
|||
return RegisteredUser( |
|||
db_registered_user[0], |
|||
datetime.fromisoformat(db_registered_user[1]) |
|||
) |
@ -0,0 +1,12 @@ |
|||
CREATE TABLE IF NOT EXISTS registration_codes ( |
|||
code VARCHAR(60) NOT NULL UNIQUE, |
|||
creationTime TIMESTAMP NOT NULL, |
|||
expirationTime TIMESTAMP, |
|||
usages INTEGER NOT NULL DEFAULT 0, |
|||
maxUsages Integer NOT NULL DEFAULT 1 |
|||
); |
|||
|
|||
CREATE TABLE IF NOT EXISTS registered_users ( |
|||
username VARCHAR(30) NOT NULL UNIQUE , |
|||
registeredTime TIMESTAMP NOT NULL |
|||
); |
Write
Preview
Loading…
Cancel
Save
Reference in new issue