Guest User

Untitled

a guest
Mar 29th, 2019
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 18.15 KB | None | 0 0
  1. import socket
  2. # allows network connections - enables connections to clients
  3.  
  4. import sqlite3
  5. # allows database communication - used to manage database
  6.  
  7. import threading
  8. # used to create multi-threaded processes
  9. # enables multiple clients to request data concurrently
  10.  
  11. import json
  12. # python module to use JSON language
  13. # used to assist in sending data between client and server
  14.  
  15. import hashlib
  16. # used to hash passwords when storing them in the database
  17.  
  18. import random
  19. # used to generate random numbers
  20. # used to generate a salt for the passwords, and create randomised passwords
  21.  
  22. import datetime
  23. # used to retrieve current date and time
  24.  
  25. import string
  26. # used to get list of ASCII characters
  27.  
  28.  
  29. class Client:
  30.     def __init__(self,clientsock,addr):
  31.         self.clientsock = clientsock    # client socket is socket object provided in arguments
  32.         self.addr = addr    # ip address of client
  33.         self.ulvl = 0
  34.         self.user = None    # will be changed when client logs in
  35.         self.dbconn = sqlite3.connect("./resources/cadets.db")  # establish a connection to the database
  36.         self.dbcursor = self.dbconn.cursor()    # create a cursor object to interact with the database
  37.         self.clientsock.sendall("Handshake started, authenticate".encode()) # send message to auhenticate
  38.         data = self.clientsock.recv(1024) # receive reply from client
  39.         if data.decode() == "Handshake accepted":   # confirms client is same program
  40.             self.clientsock.send("1987".encode())   #
  41.             clientkey = self.clientsock.recv(1024)
  42.             print("Client Key received")
  43.             print(clientkey.decode())
  44.             self.connected = True
  45.         else:
  46.             print(data)
  47.             print("Handshake failed")
  48.         while self.connected:
  49.             try:
  50.                 print("tried")
  51.                 encodeddata = self.clientsock.recv(1024)
  52.                 print("tried1")
  53.                 data = encodeddata.decode()
  54.                 print("tryingdata",data)
  55.                 char = data[0]
  56.                 data = data[1:]
  57.             except:
  58.                 print("excepted")
  59.                 self.clientsock.close()
  60.                 self.connected = False
  61.                 break
  62.            
  63.             if char == "s": #send data
  64.                 self.newdata(self.ulvl,data)
  65.                 print(1)
  66.             elif char == "r": #retrieve
  67.                 self.fetchdata(self.ulvl,data)
  68.             elif char == "u": # update data
  69.                 self.updatedata(self.ulvl,data)
  70.             elif char == "l": #login
  71.                 data = json.loads(data)
  72.                 uname = data[0]
  73.                 print(uname)
  74.                 passw = data[1]
  75.                 print(passw)
  76.                 self.login(uname,passw)
  77.             elif char == "e": #exit
  78.                 self.logout()
  79.             elif char == "d": # return user details
  80.                 self.userdata()
  81.             elif char == "z": # get username
  82.                 self.retrievelogin(data)
  83.             elif char == "p":   # change details
  84.                 self.changedetails(data)
  85.     def newdata(self,ulvl, data):
  86.         strings = data.split("+")
  87.         print("datreceived:",data)
  88.         for i in strings:
  89.             if i[0] == "u":
  90.                 data = i[1:]
  91.                 print(data)
  92.                 udata = json.loads(data)
  93.                 print("2873",udata)
  94.                 print(3)
  95.                 if udata[3] == "S": # staff userlevel
  96.                     userlevel = 3
  97.                 elif udata[2] == "Cdt": # cadet userlevel
  98.                     userlevel = 1
  99.                 else:
  100.                     userlevel = 2   # nco userlevel
  101.                 password = hashlib.sha512(udata[7].encode()).hexdigest()
  102.                 salt = random.randint(1000,9999)
  103.                 print(password)
  104.                 finpassword = hashlib.sha512((password+str(salt)).encode()).hexdigest()
  105.                 self.dbcursor.execute("""SELECT * FROM TblBasic WHERE username = ?;""",(udata[6]))
  106.                 result = self.dbcursor.fetchall()
  107.                 if len(result) != 0:
  108.                     self.clientsock.send("UAE".encode()) #username already exists
  109.                 else:
  110.                     self.dbcursor.execute("""INSERT INTO TblBasic(id,forename,surname,rank,flight,gender,dob,username,password,salt,userlevel)
  111.                    VALUES(NULL,?,?,?,?,?,?,?,?,?,?);""",(udata[0],udata[1],udata[2],udata[3],udata[4],udata[5],udata[6],finpassword,salt,userlevel))
  112.                     self.dbconn.commit()
  113.                     self.clientsock.send("UAS".encode()) # user added successfully
  114.             elif i[0] == "r":
  115.                 data = i[1:]
  116.                 print(data)
  117.                 rdata = json.loads(data)
  118.                 self.dbcursor.execute("""INSERT INTO TblRequest(request_id,cadet_id,urgency,message,response)
  119. VALUES(NULL,"{cid}","{urgency}","{message}","{response}");""".format(cid=self.user,urgency=rdata[0],message=rdata[1],response="NULL"))
  120.                 self.dbconn.commit()
  121.                 print("green")
  122.             elif i[0] == "s":
  123.                 data = i[1:]
  124.                 print(data)
  125.                 rdata = json.loads(data)
  126.                 self.dbcursor.execute("""UPDATE TblRequest SET response = "{reply}" WHERE request_id = "{rid}";""".format(reply=rdata[0],rid=rdata[1]))
  127.                 self.dbconn.commit()
  128.                 print("response done")
  129.             elif i[0] == "a":   #uniform scores
  130.                 self.dbcursor.execute("""SELECT rank,forename,surname,id FROM TblBasic WHERE userlevel = 1;""")
  131.                 result = self.dbcursor.fetchall()
  132.                 data = json.dumps(result)
  133.                 sendingdata = "<{dat}>".format(dat=data)
  134.                 self.clientsock.send(sendingdata.encode())
  135.                 # adding the <> signs allows the client to know when the
  136.                 # data has been fully received, so all of the data is definitely
  137.                 # there. This section of data may be larger than usual, so
  138.                 # the correct sending of the data must be ensured.
  139.                 endofdata = False
  140.                 data = ""
  141.                 while not endofdata:
  142.                     received = self.clientsock.recv(1024)
  143.                     print(received)
  144.                     decoded = received.decode()
  145.                     data = data.join(decoded)
  146.                     if data[-1] == ">":
  147.                         endofdata = True
  148.                 print(data)
  149.                 jsondata = data[1:-1]
  150.                 data = json.loads(jsondata)
  151.                 today = datetime.datetime.today().strftime('%Y-%m-%d')
  152.                 self.dbcursor.execute("""SELECT MAX(date) FROM TblEvent;""")
  153.                 latestdate = self.dbcursor.fetchall()
  154.                 if today == latestdate[0][0]:
  155.                     self.clientsock.send("DAR".encode())
  156.                     break
  157.                 else:
  158.                     for i in data:
  159.                         print(i)
  160.                         self.dbcursor.execute("""INSERT INTO TblEvent(event_id,cadet_id,date,attendance,uniform,tips)
  161. VALUES(NULL,"{cid}","{date}","{attend}",{unif},"{tip}");""".format(cid=i[0],date=i[1],attend=i[2],unif=i[3],tip=i[4]))
  162.                         self.dbconn.commit()
  163.                     self.clientsock.send("DSU".encode())
  164.                
  165.     def fetchdata(self,ulvl, datadict):
  166.         if datadict[0] == "a":
  167.             self.dbcursor.execute("""SELECT * FROM TblEvent WHERE cadet_id = "{cid}" """.format(cid=self.user))
  168.             print(self.user)
  169.             result = self.dbcursor.fetchall()
  170.             print(result)
  171.             data = json.dumps(result)
  172.             self.clientsock.send(data.encode())
  173.         elif datadict[0] == "u":
  174.             self.dbcursor.execute("""SELECT rank, forename, surname, id FROM TblBasic WHERE userlevel <> 3;""")
  175.             result = self.dbcursor.fetchall()
  176.             print(result)
  177.             jsondata = json.dumps(result)
  178.             print("JASON",jsondata)
  179.             self.clientsock.send(jsondata.encode())
  180.         elif datadict[0] == "z":
  181.             data = datadict[1:]
  182.             print("CID:",data)
  183.             self.dbcursor.execute("""SELECT date,uniform FROM TblEvent WHERE cadet_id = {cid} ORDER BY date ASC;""".format(cid=data))
  184.             result = self.dbcursor.fetchall()
  185.             print(result)
  186.             jsondata = json.dumps(result)
  187.             self.clientsock.send(jsondata.encode())
  188.         elif datadict[0] == "s":
  189.             data = datadict[1:]
  190.             self.dbcursor.execute("""SELECT date,AVG(uniform) FROM TblEvent GROUP BY date ORDER BY date;""")
  191.             result = self.dbcursor.fetchall()
  192.             jsondata = json.dumps(result)
  193.             self.clientsock.send(jsondata.encode())
  194.         elif datadict[0] == "c":
  195.             datenow = datetime.datetime.today().strftime("%Y-%m")
  196.             date = []
  197.             year = datenow[:-3]
  198.             month = datenow[-2:]
  199.             if datenow[-2:] == "01":
  200.                 year = str(int(year)-1)
  201.                 month = str(int(month)+11)
  202.             else:
  203.                 month = str(int(month)+1)
  204.             date = "".join([year+"-"+month])
  205.             self.dbcursor.execute("""SELECT cadet_id,AVG(uniform) FROM TblEvent GROUP BY cadet_id;""")
  206.             result = self.dbcursor.fetchall()
  207.             sending = json.dumps(result)
  208.             print(sending)
  209.             self.clientsock.send(sending.encode())
  210.         elif datadict[0] == "n":
  211.             data = datadict[1:]
  212.             self.dbcursor.execute("""SELECT rank,forename,surname FROM TblBasic WHERE id={cid};""".format(cid=data))
  213.             result = self.dbcursor.fetchall()
  214.             sendingdata = json.dumps(result[0])
  215.             self.clientsock.send(sendingdata.encode())
  216.         elif datadict[0] == "x" :
  217.             data = datadict[1:]
  218.             if data == "0":
  219.                 self.dbcursor.execute("""SELECT tips from TblEvent WHERE attendance ="/";""")
  220.             else:
  221.                 self.dbcursor.execute("""SELECT tips from TblEvent WHERE cadet_id={cid} AND attendance = "/";""".format(cid=data))
  222.             result = self.dbcursor.fetchall()
  223.             jsondata = json.dumps(result)
  224.             self.clientsock.send(jsondata.encode())
  225.         elif datadict[0] == "h":
  226.             self.dbcursor.execute("""SELECT * FROM TblBasic LEFT JOIN TblRequest ON id = cadet_id WHERE response NOT NULL;""")
  227.             result = self.dbcursor.fetchall()
  228.             print(result)
  229.             jsondata = json.dumps(result)
  230.             self.clientsock.send(jsondata.encode())
  231.         elif datadict[0] == "r":
  232.             self.dbcursor.execute("""SELECT rank FROM TblBasic;""")
  233.             result = self.dbcursor.fetchall()
  234.             print(result)
  235.             jsondata = json.dumps(result)
  236.             self.clientsock.send(jsondata.encode())
  237.            
  238.     def retrievelogin(self,surname):
  239.         if self.ulvl == "3":
  240.             uname = self.dbcursor.execute(("""SELECT username FROM TblBasic WHERE b.surname = "{data}";""".format(data=surname)))
  241.             result = self.dbcursor.fetchall()
  242.             print(result)
  243.        
  244.        
  245.     def generateuname(self,fname,sname):
  246.         uname = sname+fname[0]
  247.         return uname
  248.     def login(self,uname,pword):
  249.         self.dbcursor.execute("""SELECT * FROM TblBasic WHERE username="{uname}";""".format(uname=uname))
  250.         result = self.dbcursor.fetchall()
  251.         print(result)
  252.         try:
  253.             userid = result[0][0]
  254.             forename = result[0][1]
  255.             surname = result[0][2]
  256.             password = result[0][8]
  257.             print("PASSWORD",password,"hello")
  258.             salt = result[0][9]
  259.             userlvl = str(result[0][10])
  260.             print("USERLVL",userlvl)
  261.             pword = hashlib.sha512((hashlib.sha512(pword.encode()).hexdigest()+str(salt)).encode()).hexdigest()
  262.             print("PWORD",pword,"hello")
  263.             if pword == password:
  264.                 self.clientsock.send("a{ulvl},{uid},{fname} {sname}".format(ulvl = userlvl,uid = userid,fname=forename,sname=surname).encode())
  265.                 self.user = result[0][0]
  266.                 print("RESULT",result)
  267.                 print("USER",self.user)
  268.                 self.ulvl = userlvl
  269.                 print(userlvl)
  270.                 self.dbcursor.execute("""SELECT message,response FROM TblRequest WHERE cadet_id = ? AND response IS NOT NULL;""",(userid,))
  271.                 result = self.dbcursor.fetchall()
  272.                 self.dbcursor.execute("""DELETE FROM TblRequest WHERE cadet_id = ? AND response IS NOT NULL;""",(userid,))
  273.                 jsondata = json.dumps(result)
  274.                 self.clientsock.send(jsondata.encode())
  275.             else:
  276.                 self.clientsock.send("p".encode())
  277.                 print('no')
  278.         except IndexError:
  279.             if len(result) == 0:
  280.                 self.clientsock.send("u".encode())
  281.                 print("uno")
  282.             print("SOMETHING FAILED",result)
  283.  
  284.            
  285.     def logout(self):
  286.         self.ulvl = 0
  287.         self.uname = None
  288.  
  289.        
  290.     def userdata(self):
  291.         self.dbcursor.execute("""SELECT rank,forename,surname,id FROM TblBasic;""")
  292.         result = self.dbcursor.fetchall()
  293.         data = json.dumps(result)
  294.         sendingdata = "<{dat}>".format(dat=data)
  295.         self.clientsock.send(sendingdata.encode())
  296.  
  297.        
  298.     def changedetails(self,data):
  299.         print("hello1")
  300.         print(data)
  301.        
  302.         if data[0] == "x":
  303.             userid = data[1:]
  304.             self.dbcursor.execute("""DELETE FROM TblBasic WHERE id = {uid};""".format(uid=userid))
  305.             self.dbcursor.execute("""DELETE FROM TblEvent WHERE cadet_id = {uid};""".format(uid=userid))
  306.             self.dbcursor.execute("""DELETE FROM TblRequest WHERE cadet_id = {uid};""".format(uid=userid))
  307.             self.dbcursor.execute("""DELETE FROM TblPoints WHERE cadet_id = {uid};""".format(uid=userid))
  308.             self.clientsock.send("UFD".encode())
  309.         elif data[0] == "p":
  310.             cadet_id = data[1:]
  311.             print("hello")
  312.             newpassword = ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits + string.ascii_lowercase) for i in range(8))
  313.             print(newpassword)
  314.             self.clientsock.send("npw{pw}".format(pw=newpassword).encode())
  315.             password = hashlib.sha512(newpassword.encode()).hexdigest()
  316.             salt = random.randint(1000,9999)
  317.             print(password)
  318.             finpassword = hashlib.sha512((password+str(salt)).encode()).hexdigest()
  319.             self.dbcursor.execute("""UPDATE TblBasic SET password = "{pword}", salt = "{psalt}", userlevel = "{ulvl}" WHERE id = "{cid}";
  320.                    """.format(cid=cadet_id,pword=finpassword,psalt=salt,ulvl="1"))
  321.             self.dbconn.commit()
  322.         elif data[0] == "d":
  323.             tandd = data[1:]
  324.             dattuple = tandd.split("+")
  325.             attribute = dattuple[1]
  326.             value = dattuple[2]
  327.             cadetid = dattuple[0]
  328.             if attribute == "Rank":
  329.                 if value in ["CWO","CI","SI","Sgt (ATC)","FS (ATC)","WO (ATC)","Plt Off","Fg Off","Flt Lt","Sqn Ldr","Wg Cdr","Gp Capt"]:
  330.                     self.dbcursor.execute("""UPDATE TblBasic SET rank = "{rnk}",flight = "S", userlevel = 3 WHERE id = {cid};""".format(rnk = value,cid=cadetid))
  331.                     self.dbcursor.execute("""DELETE FROM TblEvent WHERE cadet_id = {cid};""".format(cid = cadetid))
  332.                 elif value in ["Cpl","Sgt","FS"]:
  333.                     self.dbcursor.execute("""UPDATE TblBasic SET rank = "{rnk}", userlevel = 2 WHERE id = {cid};""".format(rnk = value,cid=cadetid))
  334.                     self.dbcursor.execute("""DELETE FROM TblEvent WHERE cadet_id = {cid};""".format(cid = cadetid))
  335.                 else:
  336.                     self.dbcursor.execute("""UPDATE TblBasic SET rank = "{rnk}", userlevel = 1 WHERE id = {cid};""".format(rnk = value,cid=cadetid))
  337.                 self.clientsock.send("DCS".encode())
  338.             elif attribute == "Username":
  339.                 self.dbcursor.execute("""SELECT * FROM TblBasic WHERE username = ?;""",(value))
  340.                 result = self.dbcursor.fetchall()
  341.                 if len(result) != 0:
  342.                     self.clientsock.send("UAE".encode())
  343.                 else:
  344.                     self.dbcursor.execute("""UPDATE TblBasic SET username = "{value}" WHERE id = {cid};""".format(value=dattuple[2],cid=dattuple[0]))
  345.                     self.clientsock.send("DCS".encode())
  346.  
  347.             else:
  348.                 self.dbcursor.execute("""UPDATE TblBasic SET {attr} = "{value}" WHERE id = {cid};""".format(attr=dattuple[1],value=dattuple[2],cid=dattuple[0]))
  349.                 self.clientsock.send("DCS".encode())
  350.         elif data[0] == "c":
  351.             pword=data[1:]
  352.             data = pword.split("+")
  353.             userid = data[0]
  354.             print("uid:",userid)
  355.             pword = data[1]
  356.             print("pword",pword)
  357.             self.dbcursor.execute("""SELECT salt FROM TblBasic WHERE id={uid};""".format(uid=userid))
  358.             salt = int(self.dbcursor.fetchall()[0][0])
  359.             print("salt:",salt)
  360.             pword = hashlib.sha512((pword+str(salt)).encode()).hexdigest()
  361.             self.dbcursor.execute("""UPDATE TblBasic SET password = "{pwordhash}" WHERE id = {cid};""".format(pwordhash=pword,cid=userid))
  362.         self.dbconn.commit()
  363.    
  364. def client(clientsock,addr):
  365.     newclient = Client(clientsock,addr)
  366.  
  367. #def getdata()
  368. s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  369. host = socket.gethostname()
  370. port = 8881
  371. print("Server started!")
  372. print("Waiting for connection..")
  373. s.bind((host,port))
  374. s.listen(5)
  375. while True:
  376.     c,addr = s.accept()
  377.     print("Connection from",addr)
  378.     print(c)
  379.     print(addr)
  380.     print(c,addr)
  381.     thread = threading.Thread(target=client,args=(c,addr))
  382.     thread.start()
  383.     print(threading.active_count())
  384.    
  385. s.close()
  386.  
  387. #   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
  388. #   The function will then read next char to decide what kind of data it is
  389. #   function will then act on data
  390. #   e.g. data = "su["joe","bloggs","cdt","a","m","2000-01-01"]"
Add Comment
Please, Sign In to add comment