Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import socket
- # allows network connections - enables connections to clients
- import sqlite3
- # allows database communication - used to manage database
- import threading
- # used to create multi-threaded processes
- # enables multiple clients to request data concurrently
- import json
- # python module to use JSON language
- # used to assist in sending data between client and server
- import hashlib
- # used to hash passwords when storing them in the database
- import random
- # used to generate random numbers
- # used to generate a salt for the passwords, and create randomised passwords
- import datetime
- # used to retrieve current date and time
- import string
- # used to get list of ASCII characters
- class Client:
- def __init__(self,clientsock,addr):
- self.clientsock = clientsock # client socket is socket object provided in arguments
- self.addr = addr # ip address of client
- self.ulvl = 0
- self.user = None # will be changed when client logs in
- self.dbconn = sqlite3.connect("./resources/cadets.db") # establish a connection to the database
- self.dbcursor = self.dbconn.cursor() # create a cursor object to interact with the database
- self.clientsock.sendall("Handshake started, authenticate".encode()) # send message to auhenticate
- data = self.clientsock.recv(1024) # receive reply from client
- if data.decode() == "Handshake accepted": # confirms client is same program
- self.clientsock.send("1987".encode()) #
- clientkey = self.clientsock.recv(1024)
- print("Client Key received")
- print(clientkey.decode())
- self.connected = True
- else:
- print(data)
- print("Handshake failed")
- while self.connected:
- try:
- print("tried")
- encodeddata = self.clientsock.recv(1024)
- print("tried1")
- data = encodeddata.decode()
- print("tryingdata",data)
- char = data[0]
- data = data[1:]
- except:
- print("excepted")
- self.clientsock.close()
- self.connected = False
- break
- if char == "s": #send data
- self.newdata(self.ulvl,data)
- print(1)
- elif char == "r": #retrieve
- self.fetchdata(self.ulvl,data)
- elif char == "u": # update data
- self.updatedata(self.ulvl,data)
- elif char == "l": #login
- data = json.loads(data)
- uname = data[0]
- print(uname)
- passw = data[1]
- print(passw)
- self.login(uname,passw)
- elif char == "e": #exit
- self.logout()
- elif char == "d": # return user details
- self.userdata()
- elif char == "z": # get username
- self.retrievelogin(data)
- elif char == "p": # change details
- self.changedetails(data)
- def newdata(self,ulvl, data):
- strings = data.split("+")
- print("datreceived:",data)
- for i in strings:
- if i[0] == "u":
- data = i[1:]
- print(data)
- udata = json.loads(data)
- print("2873",udata)
- print(3)
- if udata[3] == "S": # staff userlevel
- userlevel = 3
- elif udata[2] == "Cdt": # cadet userlevel
- userlevel = 1
- else:
- userlevel = 2 # nco userlevel
- password = hashlib.sha512(udata[7].encode()).hexdigest()
- salt = random.randint(1000,9999)
- print(password)
- finpassword = hashlib.sha512((password+str(salt)).encode()).hexdigest()
- self.dbcursor.execute("""SELECT * FROM TblBasic WHERE username = ?;""",(udata[6]))
- result = self.dbcursor.fetchall()
- if len(result) != 0:
- self.clientsock.send("UAE".encode()) #username already exists
- else:
- self.dbcursor.execute("""INSERT INTO TblBasic(id,forename,surname,rank,flight,gender,dob,username,password,salt,userlevel)
- VALUES(NULL,?,?,?,?,?,?,?,?,?,?);""",(udata[0],udata[1],udata[2],udata[3],udata[4],udata[5],udata[6],finpassword,salt,userlevel))
- self.dbconn.commit()
- self.clientsock.send("UAS".encode()) # user added successfully
- elif i[0] == "r":
- data = i[1:]
- print(data)
- rdata = json.loads(data)
- self.dbcursor.execute("""INSERT INTO TblRequest(request_id,cadet_id,urgency,message,response)
- VALUES(NULL,"{cid}","{urgency}","{message}","{response}");""".format(cid=self.user,urgency=rdata[0],message=rdata[1],response="NULL"))
- self.dbconn.commit()
- print("green")
- elif i[0] == "s":
- data = i[1:]
- print(data)
- rdata = json.loads(data)
- self.dbcursor.execute("""UPDATE TblRequest SET response = "{reply}" WHERE request_id = "{rid}";""".format(reply=rdata[0],rid=rdata[1]))
- self.dbconn.commit()
- print("response done")
- elif i[0] == "a": #uniform scores
- self.dbcursor.execute("""SELECT rank,forename,surname,id FROM TblBasic WHERE userlevel = 1;""")
- result = self.dbcursor.fetchall()
- data = json.dumps(result)
- sendingdata = "<{dat}>".format(dat=data)
- self.clientsock.send(sendingdata.encode())
- # adding the <> signs allows the client to know when the
- # data has been fully received, so all of the data is definitely
- # there. This section of data may be larger than usual, so
- # the correct sending of the data must be ensured.
- endofdata = False
- data = ""
- while not endofdata:
- received = self.clientsock.recv(1024)
- print(received)
- decoded = received.decode()
- data = data.join(decoded)
- if data[-1] == ">":
- endofdata = True
- print(data)
- jsondata = data[1:-1]
- data = json.loads(jsondata)
- today = datetime.datetime.today().strftime('%Y-%m-%d')
- self.dbcursor.execute("""SELECT MAX(date) FROM TblEvent;""")
- latestdate = self.dbcursor.fetchall()
- if today == latestdate[0][0]:
- self.clientsock.send("DAR".encode())
- break
- else:
- for i in data:
- print(i)
- self.dbcursor.execute("""INSERT INTO TblEvent(event_id,cadet_id,date,attendance,uniform,tips)
- VALUES(NULL,"{cid}","{date}","{attend}",{unif},"{tip}");""".format(cid=i[0],date=i[1],attend=i[2],unif=i[3],tip=i[4]))
- self.dbconn.commit()
- self.clientsock.send("DSU".encode())
- def fetchdata(self,ulvl, datadict):
- if datadict[0] == "a":
- self.dbcursor.execute("""SELECT * FROM TblEvent WHERE cadet_id = "{cid}" """.format(cid=self.user))
- print(self.user)
- result = self.dbcursor.fetchall()
- print(result)
- data = json.dumps(result)
- self.clientsock.send(data.encode())
- elif datadict[0] == "u":
- self.dbcursor.execute("""SELECT rank, forename, surname, id FROM TblBasic WHERE userlevel <> 3;""")
- result = self.dbcursor.fetchall()
- print(result)
- jsondata = json.dumps(result)
- print("JASON",jsondata)
- self.clientsock.send(jsondata.encode())
- elif datadict[0] == "z":
- data = datadict[1:]
- print("CID:",data)
- self.dbcursor.execute("""SELECT date,uniform FROM TblEvent WHERE cadet_id = {cid} ORDER BY date ASC;""".format(cid=data))
- result = self.dbcursor.fetchall()
- print(result)
- jsondata = json.dumps(result)
- self.clientsock.send(jsondata.encode())
- elif datadict[0] == "s":
- data = datadict[1:]
- self.dbcursor.execute("""SELECT date,AVG(uniform) FROM TblEvent GROUP BY date ORDER BY date;""")
- result = self.dbcursor.fetchall()
- jsondata = json.dumps(result)
- self.clientsock.send(jsondata.encode())
- elif datadict[0] == "c":
- datenow = datetime.datetime.today().strftime("%Y-%m")
- date = []
- year = datenow[:-3]
- month = datenow[-2:]
- if datenow[-2:] == "01":
- year = str(int(year)-1)
- month = str(int(month)+11)
- else:
- month = str(int(month)+1)
- date = "".join([year+"-"+month])
- self.dbcursor.execute("""SELECT cadet_id,AVG(uniform) FROM TblEvent GROUP BY cadet_id;""")
- result = self.dbcursor.fetchall()
- sending = json.dumps(result)
- print(sending)
- self.clientsock.send(sending.encode())
- elif datadict[0] == "n":
- data = datadict[1:]
- self.dbcursor.execute("""SELECT rank,forename,surname FROM TblBasic WHERE id={cid};""".format(cid=data))
- result = self.dbcursor.fetchall()
- sendingdata = json.dumps(result[0])
- self.clientsock.send(sendingdata.encode())
- elif datadict[0] == "x" :
- data = datadict[1:]
- if data == "0":
- self.dbcursor.execute("""SELECT tips from TblEvent WHERE attendance ="/";""")
- else:
- self.dbcursor.execute("""SELECT tips from TblEvent WHERE cadet_id={cid} AND attendance = "/";""".format(cid=data))
- result = self.dbcursor.fetchall()
- jsondata = json.dumps(result)
- self.clientsock.send(jsondata.encode())
- elif datadict[0] == "h":
- self.dbcursor.execute("""SELECT * FROM TblBasic LEFT JOIN TblRequest ON id = cadet_id WHERE response NOT NULL;""")
- result = self.dbcursor.fetchall()
- print(result)
- jsondata = json.dumps(result)
- self.clientsock.send(jsondata.encode())
- elif datadict[0] == "r":
- self.dbcursor.execute("""SELECT rank FROM TblBasic;""")
- result = self.dbcursor.fetchall()
- print(result)
- jsondata = json.dumps(result)
- self.clientsock.send(jsondata.encode())
- def retrievelogin(self,surname):
- if self.ulvl == "3":
- uname = self.dbcursor.execute(("""SELECT username FROM TblBasic WHERE b.surname = "{data}";""".format(data=surname)))
- result = self.dbcursor.fetchall()
- print(result)
- def generateuname(self,fname,sname):
- uname = sname+fname[0]
- return uname
- def login(self,uname,pword):
- self.dbcursor.execute("""SELECT * FROM TblBasic WHERE username="{uname}";""".format(uname=uname))
- result = self.dbcursor.fetchall()
- print(result)
- try:
- userid = result[0][0]
- forename = result[0][1]
- surname = result[0][2]
- password = result[0][8]
- print("PASSWORD",password,"hello")
- salt = result[0][9]
- userlvl = str(result[0][10])
- print("USERLVL",userlvl)
- pword = hashlib.sha512((hashlib.sha512(pword.encode()).hexdigest()+str(salt)).encode()).hexdigest()
- print("PWORD",pword,"hello")
- if pword == password:
- self.clientsock.send("a{ulvl},{uid},{fname} {sname}".format(ulvl = userlvl,uid = userid,fname=forename,sname=surname).encode())
- self.user = result[0][0]
- print("RESULT",result)
- print("USER",self.user)
- self.ulvl = userlvl
- print(userlvl)
- self.dbcursor.execute("""SELECT message,response FROM TblRequest WHERE cadet_id = ? AND response IS NOT NULL;""",(userid,))
- result = self.dbcursor.fetchall()
- self.dbcursor.execute("""DELETE FROM TblRequest WHERE cadet_id = ? AND response IS NOT NULL;""",(userid,))
- jsondata = json.dumps(result)
- self.clientsock.send(jsondata.encode())
- else:
- self.clientsock.send("p".encode())
- print('no')
- except IndexError:
- if len(result) == 0:
- self.clientsock.send("u".encode())
- print("uno")
- print("SOMETHING FAILED",result)
- def logout(self):
- self.ulvl = 0
- self.uname = None
- def userdata(self):
- self.dbcursor.execute("""SELECT rank,forename,surname,id FROM TblBasic;""")
- result = self.dbcursor.fetchall()
- data = json.dumps(result)
- sendingdata = "<{dat}>".format(dat=data)
- self.clientsock.send(sendingdata.encode())
- def changedetails(self,data):
- print("hello1")
- print(data)
- if data[0] == "x":
- userid = data[1:]
- self.dbcursor.execute("""DELETE FROM TblBasic WHERE id = {uid};""".format(uid=userid))
- self.dbcursor.execute("""DELETE FROM TblEvent WHERE cadet_id = {uid};""".format(uid=userid))
- self.dbcursor.execute("""DELETE FROM TblRequest WHERE cadet_id = {uid};""".format(uid=userid))
- self.dbcursor.execute("""DELETE FROM TblPoints WHERE cadet_id = {uid};""".format(uid=userid))
- self.clientsock.send("UFD".encode())
- elif data[0] == "p":
- cadet_id = data[1:]
- print("hello")
- newpassword = ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits + string.ascii_lowercase) for i in range(8))
- print(newpassword)
- self.clientsock.send("npw{pw}".format(pw=newpassword).encode())
- password = hashlib.sha512(newpassword.encode()).hexdigest()
- salt = random.randint(1000,9999)
- print(password)
- finpassword = hashlib.sha512((password+str(salt)).encode()).hexdigest()
- self.dbcursor.execute("""UPDATE TblBasic SET password = "{pword}", salt = "{psalt}", userlevel = "{ulvl}" WHERE id = "{cid}";
- """.format(cid=cadet_id,pword=finpassword,psalt=salt,ulvl="1"))
- self.dbconn.commit()
- elif data[0] == "d":
- tandd = data[1:]
- dattuple = tandd.split("+")
- attribute = dattuple[1]
- value = dattuple[2]
- cadetid = dattuple[0]
- if attribute == "Rank":
- if value in ["CWO","CI","SI","Sgt (ATC)","FS (ATC)","WO (ATC)","Plt Off","Fg Off","Flt Lt","Sqn Ldr","Wg Cdr","Gp Capt"]:
- self.dbcursor.execute("""UPDATE TblBasic SET rank = "{rnk}",flight = "S", userlevel = 3 WHERE id = {cid};""".format(rnk = value,cid=cadetid))
- self.dbcursor.execute("""DELETE FROM TblEvent WHERE cadet_id = {cid};""".format(cid = cadetid))
- elif value in ["Cpl","Sgt","FS"]:
- self.dbcursor.execute("""UPDATE TblBasic SET rank = "{rnk}", userlevel = 2 WHERE id = {cid};""".format(rnk = value,cid=cadetid))
- self.dbcursor.execute("""DELETE FROM TblEvent WHERE cadet_id = {cid};""".format(cid = cadetid))
- else:
- self.dbcursor.execute("""UPDATE TblBasic SET rank = "{rnk}", userlevel = 1 WHERE id = {cid};""".format(rnk = value,cid=cadetid))
- self.clientsock.send("DCS".encode())
- elif attribute == "Username":
- self.dbcursor.execute("""SELECT * FROM TblBasic WHERE username = ?;""",(value))
- result = self.dbcursor.fetchall()
- if len(result) != 0:
- self.clientsock.send("UAE".encode())
- else:
- self.dbcursor.execute("""UPDATE TblBasic SET username = "{value}" WHERE id = {cid};""".format(value=dattuple[2],cid=dattuple[0]))
- self.clientsock.send("DCS".encode())
- else:
- self.dbcursor.execute("""UPDATE TblBasic SET {attr} = "{value}" WHERE id = {cid};""".format(attr=dattuple[1],value=dattuple[2],cid=dattuple[0]))
- self.clientsock.send("DCS".encode())
- elif data[0] == "c":
- pword=data[1:]
- data = pword.split("+")
- userid = data[0]
- print("uid:",userid)
- pword = data[1]
- print("pword",pword)
- self.dbcursor.execute("""SELECT salt FROM TblBasic WHERE id={uid};""".format(uid=userid))
- salt = int(self.dbcursor.fetchall()[0][0])
- print("salt:",salt)
- pword = hashlib.sha512((pword+str(salt)).encode()).hexdigest()
- self.dbcursor.execute("""UPDATE TblBasic SET password = "{pwordhash}" WHERE id = {cid};""".format(pwordhash=pword,cid=userid))
- self.dbconn.commit()
- def client(clientsock,addr):
- newclient = Client(clientsock,addr)
- #def getdata()
- s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
- host = socket.gethostname()
- port = 8881
- print("Server started!")
- print("Waiting for connection..")
- s.bind((host,port))
- s.listen(5)
- while True:
- c,addr = s.accept()
- print("Connection from",addr)
- print(c)
- print(addr)
- print(c,addr)
- thread = threading.Thread(target=client,args=(c,addr))
- thread.start()
- print(threading.active_count())
- s.close()
- # The format of data received from the client will be a prefacing letter indicating what to do with the data, such as s for send or r for retrieve
- # The function will then read next char to decide what kind of data it is
- # function will then act on data
- # e.g. data = "su["joe","bloggs","cdt","a","m","2000-01-01"]"
Add Comment
Please, Sign In to add comment