From bea4c7eaad26783ced20a355fd284b75116f4db6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Kn=C3=BCttel?= Date: Sun, 15 Jul 2018 10:23:36 +0200 Subject: [PATCH] initial --- create_databases.py | 116 ++++++++++++++++++++++ data.cfg | 10 ++ server/data/databases/private/users.db | Bin 0 -> 20480 bytes server/data/databases/pulic/data | Bin 0 -> 36864 bytes server/requirements.tx | 3 + server/server/__init__.py | 0 server/server/registration.py | 69 +++++++++++++ server/test/test_registration.py | 129 +++++++++++++++++++++++++ 8 files changed, 327 insertions(+) create mode 100644 create_databases.py create mode 100644 data.cfg create mode 100644 server/data/databases/private/users.db create mode 100644 server/data/databases/pulic/data create mode 100644 server/requirements.tx create mode 100644 server/server/__init__.py create mode 100644 server/server/registration.py create mode 100644 server/test/test_registration.py 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 0000000000000000000000000000000000000000..a73458a60bc9c2d23604b67a6bbfbe89f6e4b9cb GIT binary patch literal 20480 zcmeI%O-sWt7{Kv#Zc_xEx1NMt1}hFhJPTIsVd%O!H*g0j)kQ7r#Wfvz)lc9T^W>ND zXcIPk0l&cf2bw%j+O)~9xs+asuO zE&eMkh~3iBM&&~kH(y1iT6x=i&jShq2q1s}0tg_000IagfWW^O@QY=4+jXvz@jyMz zv`WYENSRibjyr+h4P+xc2`=U0lx&4I*0n{C*Ip^RJ3CH4i?4@DPlx&UZKTz7rp7nF z)8hP|UH|ATkiV|2nMc?2k=}FFS#@34dGYK$?R0Ea_%Ysg)n>^+CgV)qsZ_Q*ji%q} z%hRAQ{a&}#2=f8WAnew^7Lci@O!mUYc`vBThgj>!L3AJMdudM8r5eS_a30?#sm>xZ zt$D{V{+@eYq3j;Gj<9(1)x@)GV)MvOFWR%sO1{z7%x2p#)t0F!2q1s}0tg_000Iag zfB*srAh4_g>tyw!q5Q z;nT4585lVSpNSJF6N~k?V#jy3@9z0M7fY6N(mzs(6c=GM@e=XK+OcfgdMbovS&m*e z^lFx@yk-je+n(G1+pc3hTt8@R|FG(}zgydPx4&*3Z+&Zg-2AfnSXZzhfB*srAbrd!hngUZ=5)0&gPS_(~45RZV2D@odoRp7zAytLMG9qI8M~17S{k zV2-r#1t$$G81w`YG!XVIEw<6_4t#amPtUS>T1 z?yD{4f{Q#~X`y0dzKn;Fy2?_Pw>S*bAc;Ph_!oood_R)0Q7!YdruEfYv(vGsPf9s- zW0@o>7{w-;Ma5bv%B92QXvOj1@MU*!CSLT;+M<*u<5Q%i)m?L%uRFFioAmMfv3|~V z^(En~Je&O4#4iTo?k{z|KD}fAisnrzN5wTorzX6WQZ!44Z;ECyFZ!3}j;>;H9)^1U z%;%)lUAZZ;rC#0rrK(kZlc{Gnnnt$S$u=wqAb zS2exFg#ZEwAbgSjU z5kLR|1Q0*~0R#|0009IL;Qc>y009ILKmY**5I_I{1Q0*~f$9tJ{9pYX6CnZ!Ab#i1$h3ievXL{0R#|0009ILKmY** I5I_KdpW6L{_5c6? literal 0 HcmV?d00001 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" +