Răsfoiți Sursa

implement login and register

Eren Yilmaz 6 ani în urmă
părinte
comite
62d7e0a07f
8 a modificat fișierele cu 224 adăugiri și 56 ștergeri
  1. 2 1
      .gitignore
  2. 10 6
      client.py
  3. 65 0
      controller.py
  4. 0 41
      db.py
  5. 0 1
      login.py
  6. 131 0
      model.py
  7. 16 6
      server.py
  8. 0 1
      util.py

+ 2 - 1
.gitignore

@@ -1,3 +1,4 @@
 .idea
 *.db
-venv
+venv
+*.db-journal

+ 10 - 6
client.py

@@ -1,8 +1,12 @@
-import http.client as httplib
-import subprocess
+import json
+import requests
 import connection
 
-c = httplib.HTTPConnection('localhost', connection.port)
-c.request('POST', '/login', '{}')
-doc = c.getresponse().read()
-print(doc)
+host = 'http://127.0.0.1:' + str(connection.port)
+
+headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
+r = requests.post(host + '/register', data=json.dumps({"username": "user1", "password": "qwertz"}), headers=headers)
+print(r.content)
+
+r = requests.post(host + '/login', data=json.dumps({"username": "user1", "password": "qwertz"}), headers=headers)
+print(r.content)

+ 65 - 0
controller.py

@@ -0,0 +1,65 @@
+import json
+
+from bottle import request, response
+
+import model
+
+
+def missing_attributes(attrs):
+    for attr in attrs:
+        if attr not in request.json:
+            return attr
+        else:
+            return False
+
+
+def login():
+    missing = missing_attributes(['username', 'password'])
+    if missing:
+        return bad_request('Missing value for attribute ' + str(missing))
+    username = request.json['username']
+    password = request.json['password']
+    session_id = model.login(username, password)
+    if session_id:
+        return {'session_id': session_id}
+    else:
+        return forbidden('Invalid login data')
+
+
+def register():
+    missing = missing_attributes(['username', 'password'])
+    if missing:
+        return bad_request('Missing value for attribute ' + str(missing))
+    username = request.json['username']
+    password = request.json['password']
+    if model.user_exists(username):
+        return forbidden('User already exists.')
+    model.register(username, password)
+    return {'message': "successfully registered user"}
+
+
+def not_found(msg=None):
+    response.status = 404
+    response.content_type = 'application/json'
+    if msg is None:
+        return json.dumps({"error": "404: Page not found"})
+    else:
+        return json.dumps({"error": "404: Page not found: " + msg})
+
+
+def forbidden(msg=None):
+    response.status = 403
+    response.content_type = 'application/json'
+    if msg is None:
+        return json.dumps({"error": "403: Forbidden"})
+    else:
+        return json.dumps({"error": "403: Forbidden: " + msg})
+
+
+def bad_request(msg=None):
+    response.status = 400
+    response.content_type = 'application/json'
+    if msg is None:
+        return json.dumps({"error": "400: Bad request"})
+    else:
+        return json.dumps({"error": "400: Bad request: " + msg})

+ 0 - 41
db.py

@@ -1,41 +0,0 @@
-import sqlite3 as db
-import sys
-
-
-def setup():
-    con = None
-    try:
-        con = db.connect('boerse.db')
-
-        cur = con.cursor()
-
-        # Database setup
-        print('Database setup...')
-        cur.execute('''
-                    CREATE TABLE IF NOT EXISTS users(
-                        username VARCHAR(10) UNIQUE NOT NULL, 
-                        password VARCHAR(6) NOT NULL)
-                    '''
-                    )
-        cur.execute('''
-                    CREATE TABLE IF NOT EXISTS stocks(
-                        name VARCHAR(10) UNIQUE NOT NULL, 
-                        total_available INTEGER NOT NULL)
-                    '''
-                    )
-        cur.execute('''
-                    CREATE TABLE IF NOT EXISTS ownership(
-                        user_id INTEGER NOT NULL,
-                        amount INTEGER NOT NULL DEFAULT 0,
-                        FOREIGN KEY (user_id) REFERENCES users(rowid)
-                    )
-                    '''
-                    )
-
-    except db.Error as e:
-        print("Database error %s:" % e.args[0])
-        sys.exit(1)
-
-    finally:
-        if con is not None:
-            con.close()

+ 0 - 1
login.py

@@ -1 +0,0 @@
-print('login successful')

+ 131 - 0
model.py

@@ -0,0 +1,131 @@
+import sqlite3 as db
+import sys
+import uuid
+
+connection = None
+cursor = None
+
+
+def connect():
+    global connection
+    global cursor
+    if connection is None or cursor is None:
+        try:
+            connection = db.connect('boerse.db')
+
+            cursor = connection.cursor()
+
+        except db.Error as e:
+            print("Database error %s:" % e.args[0])
+            sys.exit(1)
+
+        # finally:
+        #     if con is not None:
+        #         con.close()
+
+
+def setup():
+    connect()
+
+    print('Database setup...')
+
+    replace = True
+    if replace:
+        cursor.execute("DROP TABLE users")
+        cursor.execute("DROP TABLE stocks")
+        cursor.execute("DROP TABLE ownership")
+        cursor.execute("DROP TABLE sessions")
+
+    cursor.execute('''
+                CREATE TABLE IF NOT EXISTS users(
+                    username VARCHAR(10) UNIQUE NOT NULL, 
+                    password VARCHAR(6) NOT NULL)
+                ''')
+    cursor.execute('''
+                CREATE TABLE IF NOT EXISTS stocks(
+                    name VARCHAR(10) UNIQUE NOT NULL, 
+                    total_available INTEGER NOT NULL)
+                ''')
+    cursor.execute('''
+                CREATE TABLE IF NOT EXISTS ownership(
+                    user_id INTEGER NOT NULL,
+                    stock_id INTEGER NOT NULL,
+                    amount INTEGER NOT NULL DEFAULT 0,
+                    FOREIGN KEY (user_id) REFERENCES users(rowid),
+                    FOREIGN KEY (stock_id) REFERENCES stocks(rowid),
+                    UNIQUE (user_id, stock_id)
+                )
+                ''')
+    cursor.execute('''
+                CREATE TABLE IF NOT EXISTS sessions(
+                    user_id INTEGER NOT NULL,
+                    session_id STRING NOT NULL,
+                    FOREIGN KEY (user_id) REFERENCES users(rowid)
+                )
+                ''')
+
+
+def login(username, password):
+    connect()
+
+    cursor.execute('''
+                SELECT rowid
+                FROM users
+                WHERE username = ?
+                AND password = ?
+                ''', (username, password))
+    user_id = cursor.fetchone()
+    if user_id:
+        return new_session(user_id)
+    else:
+        return None
+
+
+def register(username, password):
+    connect()
+
+    cursor.execute('''
+                INSERT INTO users 
+                (username, password)
+                VALUES (? , ?)
+                ''', (username, password))
+
+
+def new_session(user_id):
+    connect()
+
+    session_id = str(uuid.uuid4())
+
+    cursor.execute('''
+                INSERT INTO SESSIONS 
+                (user_id, session_id)
+                VALUES (? , ?)
+                ''', (user_id[0], session_id))
+
+    return session_id
+
+
+def drop_old_sessions():
+    connect()
+    # TODO: test
+    cursor.execute('''
+                DELETE FROM sessions s1
+                WHERE 
+                    (SELECT COUNT(*) as newer
+                     FROM sessions s2
+                     WHERE s1.user_id = s2.user_id
+                     AND s1.rowid < s2.rowid) >= 10
+                ''')
+
+
+def user_exists(username):
+    cursor.execute('''
+                SELECT rowid
+                FROM users
+                WHERE username = ?
+                ''', (username,))
+
+    if cursor.fetchone():
+        return True
+    else:
+        return False

+ 16 - 6
server.py

@@ -1,15 +1,25 @@
 import connection
-import db
-import subprocess
-from bottle import run, post, request, response, get, route
+import controller
+import model
+from bottle import run, request, response, route
+
+from controller import not_found
 
 if __name__ == '__main__':
-    print('sqlite3.version', db.db.version)
+    print('sqlite3.version', model.db.version)
+
+    model.setup()
+
+    valid_routes = ['login', 'register']
 
-    db.setup()
 
     @route('/<path>', method='POST')
     def process(path):
-        return subprocess.check_output(['python', path + '.py'], shell=True)
+        if path not in valid_routes:
+            return not_found()
+        response.content_type = 'application/json'
+        method_to_call = getattr(controller, path)
+        return method_to_call()
+
 
     run(host='localhost', port=connection.port, debug=True)

+ 0 - 1
util.py

@@ -1 +0,0 @@
-def print_variable