Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import urllib
- import urllib2
- import json
- import cherrypy
- import hashlib
- import socket
- import profile_db
- import messages_db
- import users_db
- import blacklist_db
- import time
- import sys
- import base64
- import threading
- from json import load
- from urllib2 import urlopen
- import atexit
- # Requires: CherryPy 3.2.2 (www.cherrypy.org)
- # Python (We use 2.7)
- # The address we listen for connections on
- listen_ip = "0.0.0.0"
- listen_port = 10001
- class MainApp(object):
- #CherryPy Configuration
- _cp_config = {'tools.encode.on': True,
- 'tools.encode.encoding': 'utf-8',
- 'tools.sessions.on' : 'True',
- }
- login_parameters = {'username' : None, 'password' : None , 'location' : None, 'ip' : None, 'port' : None}
- sessionValid = False
- # If they try somewhere we don't know, catch it here and send them to the right place.
- @cherrypy.expose
- def default(self, *args, **kwargs):
- """The default page, given when we don't recognise where the request is for."""
- Page = "The page that you are trying to access does not exist - 404 Error."
- cherrypy.response.status = 404
- return Page
- # HOME PAGE
- @cherrypy.expose
- def index(self):
- Page = "Welcome!<br/>"
- try:
- Page += '<form action="/showOnlineUsers" method="get" enctype="multipart/form-data">'
- Page += "Hello " + cherrypy.session['username'] + "!<br/>"
- Page += "You have successfully logged in!<br/>"
- Page += "Click here to view the online users"
- Page += '<input type="submit" value="Online Users"/></form>'
- Page += '<form action="/checkMessages" method="get" enctype="multipart/form-data">'
- Page += '<input type="submit" value="View Received Messages"/></form>'
- Page += '<form action="/sentMessages" method="get" enctype="multipart/form-data">'
- Page += '<input type="submit" value="View Sent Messages"/></form>'
- Page += '<form action="/viewProfile" method="get" enctype="multipart/form-data">'
- Page += '<input type="submit" value="View User Profile"/></form> </br>'
- Page += '</br> View a Profile: </br>'
- Page += '<form action="/getOtherProfile" method="get" enctype="multipart/form-data">'
- Page += 'User: <input type="text" name="targetUser" required/><br/>'
- Page += '<input type="submit" value="View"/></form></br>'
- Page += '<form action="/sendFile" method="post" enctype="multipart/form-data">'
- Page += 'Send a file: </br>'
- Page += 'To User: <input type="text" name="targetUser" required/><br/>'
- Page += '<input type="file" name ="fileToSend" value="Upload File" required/>'
- Page += '<input type="submit" value="Send"/></form></br>'
- Page += '<form action="/listUsers" method="get" enctype="multipart/form-data">'
- Page += '<input type="submit" value="View All Users"/></form></br>'
- Page += '<form action="/logoff" method="get" enctype="multipart/form-data">'
- Page += '<input type="submit" value="Logout"/></form>'
- except KeyError: #There is no username
- Page += "Click here to <a href='login'>login</a>."
- return Page
- @cherrypy.expose
- def login(self):
- Page = '<form action="/signin" method="post" enctype="multipart/form-data">'
- Page += 'Username: <input type="text" name="username" required/><br/>'
- Page += 'Password: <input type="password" name="password" required/></br>'
- Page += 'Location: <input type="text" name="userLocation"/>'
- Page += '</br> (Location: 0 - University Desktop; 1 - University Wireless; 2 - External)</br> '
- Page += '<input type="submit" value="Login"/></form>'
- return Page
- @cherrypy.expose
- def loginFailed(self):
- Page = '<form action="/signin" method="post" enctype="multipart/form-data">'
- Page += 'Username: <input type="text" name="username" required/><br/>'
- Page += 'Password: <input type= "password" name="password" required/></br>'
- Page += 'Location: <input type="text" name="userLocation"/>'
- Page += '</br> (Location: 0 - University Desktop; 1 - University Wireless; 2 - External)</br> '
- Page += '<input type="submit" value="Login"/></form></br>'
- Page += 'Failed to log in. Please try again.</br>'
- return Page
- # Exception Handling
- @cherrypy.expose
- def actionFailed(self):
- Page = "The action you are trying to do is not valid, or you are currently not logged in to the application or do not have a valid session.</br>"
- Page += "Click <a href = 'index'>here</a> to go back to the main menu."
- return Page
- @cherrypy.expose
- def userOffline(self):
- Page = "The user that you are trying to reach is currently offline or is currently unavailable</br>"
- Page += "Click <a href = 'index'>here</a> to go back to the main menu."
- return Page
- # Online Users
- @cherrypy.expose
- def showOnlineUsers(self):
- getList()
- Page = "<h1><b>List of People Online:</b></h1> </br>"
- Page += users_db.dispOnlineUsers()
- Page += '<meta http-equiv="refresh" content="10" >'
- Page += '<form action="/sendMessageToUser" method="get" enctype="multipart/form-data">'
- Page += '</br> Click this button to send a message to a user '
- Page += '<input type="submit" value="Send Message"/></form> </br>'
- Page += "Click <a href = 'index'>here</a> to go back to the main menu"
- return Page
- @cherrypy.expose
- def listAPI(self):
- Page = "Available APIs: "
- Page += "/ping "
- Page += "/listAPI "
- Page += "/receiveMessage [sender] [destination] [message] [stamp] "
- Page += "/getProfile [profile_username] [sender] "
- Page += "/receiveFile [sender] [destination] [file] [filename] [content_type] [stamp] "
- Page += "/getStatus [profile_username] "
- return Page
- # ------------- RECEIVING/SENDING MESSAGES ------------------ #
- @cherrypy.expose
- def checkMessages(self):
- Page = "<h1>These are your messages:</h1> </br>"
- Page += messages_db.displayMessages(cherrypy.session['username'],"RECEIVED")
- Page += '<meta http-equiv="refresh" content="5" >'
- Page += "<h3></br>Click <a href = 'index'>here</a> to return to the main menu</h3>"
- return Page
- @cherrypy.expose
- def sentMessages(self):
- Page = "<h1>Sent Messages:</h1> </br>"
- Page += messages_db.displayMessages(cherrypy.session['username'],"SENT")
- Page += '<meta http-equiv="refresh" content="5" >'
- Page += "<h3></br>Click <a href = 'index'>here</a> to return to the main menu</h3>"
- return Page
- @cherrypy.expose
- def sendMessageToUser(self):
- Page = "Type your message below"
- Page += '<form accept-charset="utf-8" action="/sendMessage" method="post" enctype="multipart/form-data">'
- Page += '<input type="text" size="100" name="message" required/><br/>'
- Page += 'Destination: <input type="text" size="20" name="destination" required/>'
- Page += '<input type="submit" value="Send"/></form>'
- return Page
- @cherrypy.expose
- @cherrypy.tools.json_in()
- def receiveMessage(self):
- try:
- message_dict = cherrypy.request.json
- if (blacklist_db.checkList(message_dict["sender"])):
- messages_db.storeMessage(message_dict)
- Page = '0' #If there are no errors
- print "MESSAGE RECEIVED"
- else:
- Page = '11'
- except:
- Page = '4'
- return Page
- @cherrypy.expose
- def sendMessage(self,message,destination):
- pingUser = ping(destination)
- if (pingUser == "0"):
- url = users_db.getURL(destination) + "/receiveMessage"
- time_stamp = time.time()
- payload = {'sender' : cherrypy.session['username'], 'destination' : destination, 'message' : message , 'stamp' : time_stamp }
- data = json.dumps(payload)
- req = urllib2.Request(url, data, {'Content-Type' : 'application/json'})
- try:
- response = urllib2.urlopen(req, timeout = 1)
- except urllib2.URLError, e:
- raise cherrypy.HTTPRedirect("/actionFailed")
- except urllib2.HTTPError:
- raise cherrypy.HTTPRedirect("/actionFailed")
- # TODO: Check for responses
- if (response.read() == "0"):
- messages_db.storeMessage(payload)
- raise cherrypy.HTTPRedirect("/showOnlineUsers")
- else:
- print "MESSAGE DID NOT SEND"
- raise cherrypy.HTTPRedirect("/actionFailed")
- @cherrypy.expose
- def ping(self,sender):
- return '0'
- # ----------------------END MESSAGES----------------------------------#
- #---------------------- PROFILE --------------------- #
- @cherrypy.expose
- def viewProfile(self):
- try:
- Page = profile_db.getProfile(cherrypy.session['username'],"view") + '</br>'
- Page += '<b>Status: </b>' + profile_db.getStatus(cherrypy.session['username'],"Profile")
- Page += '<form action="/updateProfilePrompt" method="get" enctype="multipart/form-data">'
- Page += '<input type="submit" value="Update Profile"/></form> </br>'
- Page += '<form action="/updateStatus" method="post" enctype="multipart/form-data">'
- Page += 'Update Status: <input type="text" name="status"/>'
- Page += ' Valid Status = ["Online", "Idle", "Away", "Do Not Disturb", "Offline"] </br>'
- Page += '<input type="submit" value="Update"/></form></br>'
- Page += '<form action="/index" method="get" enctype="multipart/form-data">'
- Page += '<input type="submit" value="Main Menu"/></form> </br>'
- except:
- raise cherrypy.HTTPRedirect('/actionFailed')
- return Page
- @cherrypy.expose
- def updateProfilePrompt(self):
- Page = '<form action="/updateProfile" method="post" enctype="multipart/form-data">'
- Page += '<embed type="application/x-vlc-plugin" pluginspage="http://www.videolan.org" />'
- Page += 'Full Name: <input type="text" name="FULLNAME" required/><br/>'
- Page += 'Position: <input type="text" name="POSITION"/></br>'
- Page += 'Description: <input type="text" name="DESCRIPTION"/></br>'
- Page += 'Location: <input type="text" name="LOCATION"/></br>'
- Page += 'New Profile Picture: <input type="text" name="IMAGE_URL"/> (please put a URL link)</br> '
- Page += '<input type="submit" value="Update"/></form>'
- return Page
- @cherrypy.expose
- def updateProfile(self,FULLNAME,POSITION,DESCRIPTION,LOCATION, IMAGE_URL):
- profile_db.updateProfileValues(cherrypy.session['username'],FULLNAME,POSITION,DESCRIPTION,LOCATION, IMAGE_URL)
- raise cherrypy.HTTPRedirect('/viewProfile')
- @cherrypy.expose
- @cherrypy.tools.json_in()
- def getProfile(self):
- input_data = cherrypy.request.json
- if (blacklist_db.checkList(input_data["sender"])):
- output_dict = profile_db.getProfile(input_data["profile_username"],"dictionary")
- else:
- output_dict = {'fullname' : 'BLOCKED', 'position' : 'BLOCKED' , 'description' : 'BLOCKED', 'location' : 'BLOCKED' , 'picture' : 'https://pbs.twimg.com/profile_images/600060188872155136/st4Sp6Aw.jpg'}
- data = json.dumps(output_dict)
- return data
- @cherrypy.expose
- def getOtherProfile(self, targetUser):
- url = users_db.getURL(targetUser) + "/getProfile"
- payload = {'profile_username' : targetUser, 'sender' : cherrypy.session['username']}
- data = json.dumps(payload)
- req = urllib2.Request(url, data, {'Content-Type' : 'application/json'})
- try:
- response = urllib2.urlopen(req, timeout = 1)
- except urllib2.URLError, e:
- #raise MyException("There was an error: %r" % e)
- raise cherrypy.HTTPRedirect('/actionFailed')
- input_dict = json.loads(response.read())
- profile_db.updateProfileValues(targetUser, input_dict["fullname"], input_dict["position"], input_dict["description"], input_dict["location"], input_dict["picture"])
- #TODO: Check for each parameter to
- Page = '<h1>User: ' + targetUser + '</h1></br>'
- Page += '<b>Full Name:</b> ' + input_dict["fullname"] + '</br>'
- Page += '<b>Position:</b> ' + input_dict["position"] + '</br>'
- Page += '<b>Description:</b> ' + input_dict["description"] + '</br>'
- Page += '<b>Location:</b> ' + input_dict["location"] + '</br>'
- Page += '<img src=' + "\"" + input_dict["picture"] + "\"" + "></br>"
- Page += '<b>Status:</b> : '+ self.getPeerStatus(targetUser)
- profile_db.updateStatus(targetUser,self.getPeerStatus(targetUser))
- Page += '<form action="/index" method="post" enctype="multipart/form-data">'
- Page += '<input type="submit" value="Main Menu"/></form>'
- return Page
- ### ---- STATUS --- ###
- @cherrypy.expose
- @cherrypy.tools.json_in()
- def getStatus(self):
- input_data = cherrypy.request.json
- if (blacklist_db.checkList(input_data["sender"])):
- output_dict = profile_db.getStatus(self.login_parameters['username'], "others")
- else:
- output_dict = {'status': 'Offline' }
- data = json.dumps(output_dict)
- return data
- @cherrypy.expose
- def getPeerStatus(self,targetUser):
- pingUser = ping(targetUser)
- payload = {'profile_username' : targetUser}
- url = users_db.getURL(targetUser) + "/getStatus"
- data = json.dumps(payload)
- req = urllib2.Request(url, data, {'Content-Type' : 'application/json'})
- try:
- response = urllib2.urlopen(req)
- output = json.loads(response.read())
- except:
- output = {'status' : 'Offline'}
- return output['status']
- @cherrypy.expose
- def updateStatus(self,status):
- validStatus = ["Online", "Idle", "Away", "Do Not Disturb", "Offline"]
- if status not in validStatus:
- raise cherrypy.HTTPRedirect('/actionFailed') #TODO: Must say invalid status
- else:
- profile_db.updateStatus(cherrypy.session['username'],status)
- raise cherrypy.HTTPRedirect('/viewProfile')
- return status
- # -----------------END PROFILE---------------------------#
- # ----------------- FILES -------------------------------#
- @cherrypy.expose
- def sendFile(self,fileToSend,targetUser):
- userPing = ping(targetUser)
- file_read = fileToSend.file.read()
- fileSize = len (file_read)
- if fileSize > 5000000:
- raise cherrypy.HTTPRedirect('/actionFailed')
- if (userPing == "0"):
- file_64_encode = base64.encodestring(file_read)
- url = users_db.getURL(targetUser) + "/receiveFile"
- filenameList = (fileToSend.filename).split(".")
- filename = fileToSend.filename
- content_type = "." + filenameList[1]
- payload = {'sender' : cherrypy.session['username'], 'destination' : targetUser, 'file' : file_64_encode, 'filename' : filename,
- 'content_type' : content_type, 'stamp' : time.time()}
- data = json.dumps(payload)
- req = urllib2.Request(url, data, {'Content-Type' : 'application/json'})
- try:
- response = urllib2.urlopen(req)
- raise cherrypy.HTTPRedirect('/index')
- except urllib2.URLError as err:
- raise cherrypy.HTTPRedirect('/actionFailed')
- @cherrypy.expose
- @cherrypy.tools.json_in()
- def receiveFile(self):
- input_data = cherrypy.request.json
- if (blacklist_db.checkList(input_data["sender"])):
- receivedFile = base64.decodestring(input_data["file"])
- fileSize = len(receivedFile)
- if (fileSize > 5000000):
- return "6" #
- else:
- fileName = input_data["filename"]
- file_result = open(fileName, 'wb')
- file_result.write(receivedFile)
- return "0"
- else:
- return "11"
- # ------------ END FILES --------------------------------#
- ### ------------ USERS -------------------------#
- # Viewing all the users in the login server
- @cherrypy.expose #TODO: Fix this database!
- def listUsers(self):
- ''' List all of the users currently registered in the login server.'''
- url = "http://cs302.pythonanywhere.com/listUsers"
- f = urllib.urlopen(url)
- Page = f.read() + '</br>'
- #TODO:Update list of users
- #store_registered_users(f)
- Page += '</br> Add a user to a black list:'
- Page += '<form action="/addToBlacklist" method="post" enctype="multipart/form-data">'
- Page += 'User: <input type="text" name="UPI" required/><br/>'
- Page += 'Reasoning: <input type="text" name="Reason" required/></br>'
- Page += '<input type="submit" value="Add"/></form>'
- Page += '<form action="/showBlacklist" method="get" enctype="multipart/form-data">'
- Page += '<input type="submit" value="View Blacklist"/></form></br>'
- Page += "Click <a href = 'index'>here</a> to go back to the main menu"
- return Page
- @cherrypy.expose
- def addToBlacklist(self,UPI,Reason):
- blacklist_db.addToList(UPI,Reason)
- raise cherrypy.HTTPRedirect('/listUsers')
- #Blackisting
- @cherrypy.expose
- def blockUser(self,UPI,Reason):
- blacklist_db.addToList(UPI,Reason)
- raise cherrypy.HTTPRedirect('/index')
- @cherrypy.expose
- def showBlacklist(self):
- blockedUsers = "<h1>Blocked Users</h1>"
- blockedUsers += blacklist_db.viewList() + '</br>'
- blockedUsers += "</br>Remove a user from the black list:</br>"
- blockedUsers += '<form action="/removeFromBlacklist" method="post" enctype="multipart/form-data">'
- blockedUsers += 'User: <input type="text" name="UPI" required/><br/>'
- blockedUsers += '<input type="submit" value="Delete"/></form>'
- blockedUsers += "Click <a href = 'index'>here</a> to return to the main menu."
- return blockedUsers
- @cherrypy.expose
- def removeFromBlacklist(self,UPI):
- blacklist_db.removeFromList(UPI)
- raise cherrypy.HTTPRedirect('/listUsers')
- # -----------------LOGGING IN AND OUT -------------------#
- @cherrypy.expose
- def signin(self, username=None, password=None, userLocation = None):
- """Check their name and password and send them either to the main page, or back to the main login screen."""
- saltedPW = str(password) + "COMPSYS302-2017"
- hashedPW = hashlib.sha256(saltedPW).hexdigest()
- if (userLocation == '0'):
- my_ip = socket.gethostbyname(socket.gethostname())
- else:
- my_ip = load(urlopen('http://jsonip.com'))['ip']
- # Checks whether the user incorrectly types in 2 instead of 0
- if (my_ip[0:3] == "130"):
- userLocation = '0'
- my_ip = socket.gethostbyname(socket.gethostname())
- self.login_parameters = {'username': username, 'password': hashedPW, 'location' : userLocation, 'ip' : my_ip , 'port' : listen_port }
- #print hex(id(login_parameters))
- url = "http://cs302.pythonanywhere.com/report"
- payload = urllib.urlencode({'username': username, 'password': hashedPW, 'location' : userLocation, 'ip' : my_ip , 'port' : listen_port })
- f = urllib.urlopen(url,payload)
- error = f.read()[0]
- if (error == '0'):
- cherrypy.session['username'] = username;
- cherrypy.session['password'] = hashlib.sha256(password + "COMPSYS302-2017").hexdigest()
- cherrypy.session['userLocation'] = userLocation
- profile_db.createProfile(cherrypy.session['username'])
- self.sessionValid = True
- self.report()
- raise cherrypy.HTTPRedirect('/')
- else:
- raise cherrypy.HTTPRedirect('/loginFailed')
- # Threading
- @cherrypy.expose
- def report(self):
- url = "http://cs302.pythonanywhere.com/report"
- if (self.sessionValid == True):
- f = urllib.urlopen(url,urllib.urlencode(self.login_parameters))
- #print self.login_parameters
- print f.read()
- print "REPORT"
- #MAKE SURE TO not have report() as it will be a recursive threading
- threading.Timer(30.0, self.report).start()
- @cherrypy.expose
- def logoff(self):
- """Logs the current user out, expires their session"""
- self.sessionValid = False
- print "GOES HERE"
- url = "http://cs302.pythonanywhere.com/logoff"
- try:
- payload = urllib.urlencode({'username': cherrypy.session['username'], 'password' : cherrypy.session['password']})
- except:
- raise cherrypy.HTTPRedirect('/actionFailed')
- try:
- f = urllib.urlopen(url,payload)
- if (f.read()[0] == "0"):
- print "Logged Off"
- raise cherrypy.HTTPRedirect('/logout')
- except:
- raise cherrypy.HTTPRedirect('/logout')
- @cherrypy.expose
- def logout(self):
- Page = "You have successfully logged out. "
- self.sessionValid = False
- cherrypy.lib.sessions.expire()
- return Page
- # ---------- HELPER FUNCTIONS ----------- #
- # Gets all the users who are currently online
- def getList():
- try:
- url = "http://cs302.pythonanywhere.com/getList"
- payload = urllib.urlencode({'username': cherrypy.session['username'], 'password' : cherrypy.session['password'], 'json' : '1'})
- f = urllib.urlopen(url,payload)
- online_users = f.read()
- users_db.update_online_users(json.loads(online_users))
- return online_users
- except:
- raise cherrypy.HTTPRedirect('/actionFailed')
- #PING to check if user is still available
- def ping(destination):
- ping_url = users_db.getURL(destination) + "/ping?" + "sender=" + cherrypy.session['username']
- req = urllib2.Request(ping_url)
- try:
- f = urllib2.urlopen(req, timeout = 1)
- except urllib2.URLError, err:
- print err
- raise cherrypy.HTTPRedirect('/userOffline')
- return f.read()
- def runMainApp():
- # Create an instance of MainApp and tell Cherrypy to send all requests under / to it. (ie all of them)
- cherrypy.tree.mount(MainApp(), "/")
- # Tell Cherrypy to listen for connections on the configured address and port.
- cherrypy.config.update({'server.socket_host': listen_ip,
- 'server.socket_port': listen_port,
- 'engine.autoreload.on': True,
- })
- print "========================="
- print "University of Auckland"
- print "COMPSYS302 - Software Design Application"
- print "========================================"
- # Start the web server
- cherrypy.engine.start()
- # And stop doing anything else. Let the web server take over.
- cherrypy.engine.block()
- #Run the function to start everything
- runMainApp()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement