125 lines
3.2 KiB
Python
125 lines
3.2 KiB
Python
|
import re
|
||
|
import sqlite3
|
||
|
import cherrypy
|
||
|
import uuid
|
||
|
import smtplib
|
||
|
|
||
|
def isinsecurepassword(password):
|
||
|
if(len(password) < 8):
|
||
|
return True
|
||
|
if(len(set(password)) < 4):
|
||
|
return True
|
||
|
return False
|
||
|
|
||
|
|
||
|
def simplehash(password):
|
||
|
"""
|
||
|
XXX: ONLY FOR DEMO PURPOSES!
|
||
|
"""
|
||
|
result = 0xff
|
||
|
for i in password:
|
||
|
result ^= ord(i)
|
||
|
return result
|
||
|
|
||
|
|
||
|
class InputValidationServer(object):
|
||
|
def __init__(self, db):
|
||
|
self._db_name = db
|
||
|
self._rzid_pattern = re.compile("[a-z]{3}[0-9]{5}")
|
||
|
self._email_password = "foobar"
|
||
|
self._email_user = "dummy@daknuett.eu"
|
||
|
|
||
|
@cherrypy.expose
|
||
|
def index(self):
|
||
|
return '''
|
||
|
<html>
|
||
|
<head>
|
||
|
<title>Input Validation Form</title>
|
||
|
</head>
|
||
|
<body>
|
||
|
<form action="submit">
|
||
|
<p>
|
||
|
password: <input type="password" name="password"/>
|
||
|
</p>
|
||
|
<p>
|
||
|
email: <input type="email" name="email"/>
|
||
|
</p>
|
||
|
<p>
|
||
|
RZ Kennung: <input type="text" name="rzid"/>
|
||
|
</p>
|
||
|
<input type=submit name="submit" value="Submit"/>
|
||
|
</form
|
||
|
</body>
|
||
|
</html>'''
|
||
|
|
||
|
|
||
|
@cherrypy.expose
|
||
|
def submit(self, password, email, rzid, submit):
|
||
|
|
||
|
if(not self._rzid_pattern.match(rzid)):
|
||
|
return '''<html><head><title>Error</title></head><body><h1>Error: invalid RZ Kennung.</h1></body></html>'''
|
||
|
|
||
|
confirmation_id = str(uuid.uuid4())
|
||
|
|
||
|
db = sqlite3.connect(self._db_name)
|
||
|
cursor = db.cursor()
|
||
|
cursor.execute("SELECT COUNT(rzid) FROM users WHERE rzid=?", (rzid,))
|
||
|
if(cursor.fetchone()[0]):
|
||
|
db.close()
|
||
|
return '''<html><head><title>Error</title></head><body><h1>Error: RZ Kennung in use.</h1></body></html>'''
|
||
|
|
||
|
cursor.execute("INSERT INTO users(rzid, email, password, confirmation_id) VALUES(?, ?, ?, ?)",
|
||
|
(rzid, email, simplehash(password), confirmation_id))
|
||
|
|
||
|
db.commit()
|
||
|
|
||
|
|
||
|
smtp = smtplib.SMTP("daknuett.eu", 587)
|
||
|
smtp.ehlo()
|
||
|
smtp.starttls()
|
||
|
smtp.login(self._email_user, self._email_password)
|
||
|
|
||
|
smtp.sendmail(self._email_user, [email],
|
||
|
'\r\n'.join(['To: %s' % email
|
||
|
, 'From: %s' % self._email_user
|
||
|
, 'Subject: %s' % "confirm your email address"
|
||
|
, "\n\r", "http://localhost:8080/confirm?confirmation_id={}".format(confirmation_id)]))
|
||
|
smtp.close()
|
||
|
|
||
|
db.close()
|
||
|
|
||
|
if(isinsecurepassword(password)):
|
||
|
return '''<html><head><title>OK</title></head><body><h1>Check your mailbox for the confirmation email</h1>
|
||
|
<p>Also your password is pretty unsecure</p></body></html>'''
|
||
|
return '''<html><head><title>OK</title></head><body><h1>Check your mailbox for the confirmation email</h1></body></html>'''
|
||
|
|
||
|
@cherrypy.expose
|
||
|
def confirm(self, confirmation_id):
|
||
|
db = sqlite3.connect(self._db_name)
|
||
|
cursor = db.cursor()
|
||
|
cursor.execute("SELECT rzid FROM users WHERE confirmation_id=?", (confirmation_id,))
|
||
|
|
||
|
try:
|
||
|
rzid = cursor.fetchone()[0]
|
||
|
except:
|
||
|
return '''<html><head><title>Error</title></head><body><h1>Error: unknown confirmation ID</h1></body></html>'''
|
||
|
|
||
|
cursor.execute("UPDATE users SET confirmation_id='' WHERE rzid=?", (rzid,))
|
||
|
return '''<html><head><title>OK</title></head><body><h1>Your account is activated.</h1></body></html>'''
|
||
|
|
||
|
with open("example.db", "w"):
|
||
|
pass
|
||
|
db = sqlite3.connect("example.db")
|
||
|
db.cursor().execute("CREATE TABLE users(rzid TEXT, email TEXT, password INT, confirmation_id TEXT)")
|
||
|
db.commit()
|
||
|
db.close()
|
||
|
|
||
|
app = InputValidationServer("example.db")
|
||
|
cherrypy.quickstart(app)
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|