commit bea4c7eaad26783ced20a355fd284b75116f4db6 Author: Daniel Knüttel Date: Sun Jul 15 10:23:36 2018 +0200 initial diff --git a/create_databases.py b/create_databases.py new file mode 100644 index 0000000..48485e6 --- /dev/null +++ b/create_databases.py @@ -0,0 +1,116 @@ +import docopt, os, sqlite3 + +usage = \ +''' +Usage: + create_databases.py PATH + + +''' + + +args = docopt.docopt(usage) + + +path = args["PATH"] + +def create_private_db(path): + private_path = os.path.join(path, "private") + os.makedirs(private_path) + + private_db_file = os.path.join(private_path, "users.db") + db = sqlite3.connect(private_db_file) + + cursor = db.cursor() + + cursor.execute("CREATE TABLE users(" \ + "uid integer PRIMARY KEY AUTOINCREMENT, "\ + "username text UNIQUE, "\ + "passwd_hash text, "\ + "email text, "\ + "first_name text, "\ + "last_name text, " \ + "is_confirmed bool)") + db.commit() + + cursor.execute("CREATE TABLE globals(" \ + "confirmation_id_offset integer " \ + ")") + db.commit() + + cursor.execute("CREATE TABLE email_queue(" \ + "email_id integer PRIMARY KEY AUTOINCREMENT, " \ + "sender text, " \ + "recipient text, " \ + "message text, " \ + "in_transaction bool)") + db.commit() + + cursor.execute("CREATE TABLE confirmations_awaiting(" \ + "user_id integer, " \ + "convirmation_id integer PRIMARY KEY AUTOINCREMENT"); + db.commit() + + cursor.execute("CREATE INDEX username ON users(username)") + db.commit() + + db.close() + +def create_public_db(path): + public_path = os.path.join(path, "pulic") + os.makedirs(public_path) + + public_db_file = os.path.join(public_path, "data") + db = sqlite3.connect(public_db_file) + + cursor = db.cursor() + + cursor.execute("CREATE TABLE location_settings("\ + "username text PRIMARY KEY, "\ + "radius decimal, "\ + "use_gps bool, "\ + "country text)") + db.commit() + + cursor.execute("CREATE TABLE specimen_settings("\ + "username text PRIMARY KEY, "\ + "author text, "\ + "location_uri text) ") + + db.commit() + + cursor.execute("CREATE TABLE locations("\ + "username text, "\ + "latitude decimal, "\ + "longitude decimal, "\ + "name text, "\ + "radius decimal, "\ + "description text, "\ + "country text, "\ + "identifier text, "\ + "address text, "\ + "image_uri text)") + db.commit() + + cursor.execute("CREATE TABLE specimen("\ + "username text, "\ + "genus text, "\ + "species text, "\ + "subspecies text, "\ + "sex text, "\ + "nickname text, "\ + "author text, "\ + "image_uri text, "\ + "location_uri text, "\ + "identifier text, "\ + "latitude decimal, "\ + "longitude decimal)") + db.commit() + + cursor.execute("CREATE INDEX username_loc on locations(username)") + cursor.execute("CREATE INDEX username_spec on specimen(username)") + db.commit() + + +create_private_db(path) +create_public_db(path) diff --git a/data.cfg b/data.cfg new file mode 100644 index 0000000..045d532 --- /dev/null +++ b/data.cfg @@ -0,0 +1,10 @@ +[register] +index = "client/static/register.html" +enabled = true + +[database] +users = "server/data/private/users.db" +public = "server/data/public/data" +public_path = "server/data/public" +pulic_databases = data + diff --git a/server/data/databases/private/users.db b/server/data/databases/private/users.db new file mode 100644 index 0000000..a73458a Binary files /dev/null and b/server/data/databases/private/users.db differ diff --git a/server/data/databases/pulic/data b/server/data/databases/pulic/data new file mode 100644 index 0000000..6e53abd Binary files /dev/null and b/server/data/databases/pulic/data differ diff --git a/server/requirements.tx b/server/requirements.tx new file mode 100644 index 0000000..dffc084 --- /dev/null +++ b/server/requirements.tx @@ -0,0 +1,3 @@ +webdb +cherrypy + diff --git a/server/server/__init__.py b/server/server/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/server/server/registration.py b/server/server/registration.py new file mode 100644 index 0000000..b10f6fa --- /dev/null +++ b/server/server/registration.py @@ -0,0 +1,69 @@ +import cherrypy, sqlite3 +from cherrypy import HTTPError + +required_for_register = ["email", "username", "password", "first_name", "last_name"] + +class RegistrationServer(object): + def __init__(self, conf, mkhash): + self.conf = conf + self.mkhash = mkhash + + @cherrypy.expose + def index(self): + return open(self.conf["register"]["index"]) + + @cherrypy.expose + @cherrypy.tools.json_in + def do_register(self): + + if(not self.conf["register"]["enabled"]): + raise HTTPError(404, "registration is disabled") + data = cherrypy.request.json + + for required in required_for_register: + if not required in data: + raise HTTPError(400, "missing {}".format(required)) + + username = data["username"] + self.check_username_validity(username) + + passwd_hash = self.mkhash(data["password"]) + db = sqlite3.connect(self.conf["database"]["users"]) + + cursor = db.cursor() + + cursor.execute("INSERT INTO users("\ + "username, passwd_hash, "\ + "email, first_name, last_name) "\ + "VALUES(?, ?, ?, ?, ?)", + [username, passwd_hash, data["email"], + data["first_name"], data["last_name"]) + + db.commit() + db.close() + return "registration successful" + + + @cherrypy.expose + def check_username_validity(self, username): + for i in string.whitespace: + if i in username: + raise HTTPError(400, "username contains whitespace") + for i in "\\\"\b\n\r/": + if i in username: + raise HTTPError(400, "username contains forbidden character") + + db = sqlite3.connect(self.conf["database"]["users"]) + cursor = db.cursor() + cursor.execute("SELECT uid FROM users WHERE username = ?", [(username)]) + if(cursor.fetchone()): + db.close() + raise HTTPError(404, "username already in use") + db.close() + return "username is valid" + + + + + + diff --git a/server/test/test_registration.py b/server/test/test_registration.py new file mode 100644 index 0000000..4a5a724 --- /dev/null +++ b/server/test/test_registration.py @@ -0,0 +1,129 @@ +from hashlib import sha256 + + +from server.registration import RegistrationServer + +mkhash = lambda s: sha256(s).hexdigest() + +def build_dir(directory): + def create_private_db(path): + private_path = os.path.join(path, "private") + os.makedirs(private_path) + + private_db_file = os.path.join(private_path, "users.db") + db = sqlite3.connect(private_db_file) + + cursor = db.cursor() + + cursor.execute("CREATE TABLE users(" \ + "uid integer PRIMARY KEY AUTOINCREMENT, "\ + "username text UNIQUE, "\ + "passwd_hash text, "\ + "email text, "\ + "first_name text, "\ + "last_name text, " \ + "is_confirmed bool)") + db.commit() + + cursor.execute("CREATE TABLE globals(" \ + "confirmation_id_offset integer " \ + ")") + db.commit() + + cursor.execute("CREATE TABLE email_queue(" \ + "email_id integer PRIMARY KEY AUTOINCREMENT, " \ + "sender text, " \ + "recipient text, " \ + "message text, " \ + "in_transaction bool)") + db.commit() + + cursor.execute("CREATE TABLE confirmations_awaiting(" \ + "user_id integer, " \ + "convirmation_id integer PRIMARY KEY AUTOINCREMENT"); + db.commit() + + cursor.execute("CREATE INDEX username ON users(username)") + db.commit() + + db.close() + + def create_public_db(path): + public_path = os.path.join(path, "pulic") + os.makedirs(public_path) + + public_db_file = os.path.join(public_path, "data") + db = sqlite3.connect(public_db_file) + + cursor = db.cursor() + + cursor.execute("CREATE TABLE location_settings("\ + "username text PRIMARY KEY, "\ + "radius decimal, "\ + "use_gps bool, "\ + "country text)") + db.commit() + + cursor.execute("CREATE TABLE specimen_settings("\ + "username text PRIMARY KEY, "\ + "author text, "\ + "location_uri text) ") + + db.commit() + + cursor.execute("CREATE TABLE locations("\ + "username text, "\ + "latitude decimal, "\ + "longitude decimal, "\ + "name text, "\ + "radius decimal, "\ + "description text, "\ + "country text, "\ + "identifier text, "\ + "address text, "\ + "image_uri text)") + db.commit() + + cursor.execute("CREATE TABLE specimen("\ + "username text, "\ + "genus text, "\ + "species text, "\ + "subspecies text, "\ + "sex text, "\ + "nickname text, "\ + "author text, "\ + "image_uri text, "\ + "location_uri text, "\ + "identifier text, "\ + "latitude decimal, "\ + "longitude decimal)") + db.commit() + + cursor.execute("CREATE INDEX username_loc on locations(username)") + cursor.execute("CREATE INDEX username_spec on specimen(username)") + db.commit() + + + create_private_db(directory) + create_public_db(directory) + + with open("index.html", "w") as index: + index.write("INDEX") + + return {"database": {"users": directory + "private"}, + "register": {"index": directory + "index.html", + "enabled": True} + } + + + + + + +def test_registration(tmpdir): + conf = build_dir(str(tmpdir)) + + server = RegistrationServer(conf, mkhash) + + assert server.index() == "INDEX" +