def login_handler(data): logger.debug("Login %s", data) data['type'] = 'login' sid = request.sid user = db.getUserByName(conn, data.get('doubleName').lower()) if user: logger.debug("User found %s", user[0]) update_sql = "UPDATE users SET sid=? WHERE double_name=?;" db.update_user(conn, update_sql, sid, user[0]) if data.get('firstTime') == False and data.get('mobile') == False: user = db.getUserByName(conn, data.get('doubleName').lower()) push_service.notify_single_device( registration_id=user[4], message_title='Finish login', message_body='Tap to finish login', data_message=data, click_action='FLUTTER_NOTIFICATION_CLICK', tag='testLogin', collapse_key='testLogin') insert_auth_sql = "INSERT INTO auth (double_name,state_hash,timestamp,scanned,data) VALUES (?,?,?,?,?);" db.insert_auth(conn, insert_auth_sql, data.get('doubleName').lower(), data.get('state'), datetime.now(), 0, json.dumps(data)) print('')
def add_user(): # Fetch form data userDetails = request.get_json() name = userDetails.get('name') password = userDetails.get('password') # Check if all data is supplied if name is None: return jsonify({"error": "Username not specified"}), 400 if password is None: return jsonify({"error": "Password not specified"}), 400 # Strip leading and trailing spaces name = name.strip() # Check is username and password comply to the requirements username_message = function.check_username(name) password_message = function.check_password(password) if (username_message is not "ok"): return jsonify({"error": username_message}), 400 elif (password_message is not "ok"): return jsonify({"error": password_message}), 400 # Check if the user already exists user = database.getUserByName(name) if user is not None: return "Username already exists", 400 # Hash the userpassword for secure storage hashedpass = function.hash_password(password) # Add user to the database and return newly created userID user = database.addUser(name, hashedpass) return jsonify(user), 201
def printProfilePage(dbCursor, uname): name = db.getUserByName(dbCursor, uname) page = db.getProfilePage(dbCursor, uname) jobs = db.getProfileJobs(dbCursor, uname) education = db.getProfileEducation(dbCursor, uname) print(f"{name[2]} {name[3]}'s Profile Page" ) # name[2] = user first name; name[3] = user last name print(f"Major: {page[1]}") # page[1] = user major print(f"University: {page[2]}") # page[2] = user university print(f"About: \n{page[3]}") # page[3] = user about if jobs is None: print("Experience:") else: print("Experience:") for job in jobs: print(job[2]) # job[2] = job title print(f"\tEmployer: {job[3]}") # job[3] = job employer print(f"\tDate: {job[4]} - {job[5]}" ) # job[4] = job start date; job[5] = job end date print(f"\tLocation: {job[6]}") # job[6] = job location print(f"\tDescription: \n\t{job[7]}") # job[7] = job description if education is None: print("Education:") else: print("Education:") for i in education: print(f"University: {i[2]}") # i[2] = university name print(f"\tDegree: {i[3]}") # i[3] = degree print(f"\tYear: {i[4]} - {i[5]}" ) # i[4] = start year; i[5] = end year return page[1], page[2], page[3]
def postJob(dbCursor, dbConnection): if db.getNumJobs(dbCursor) >= constants.MAX_POSTED_JOBS: # checks if number of jobs in database is at max limit print("All permitted jobs have been created, please come back later.") settings.currentState = states.jobMenu return # Take input from user and create job in DB User = namedtuple('User', 'uname pword firstname lastname plusMember date_created') currentUser = User._make(db.getUserByName(dbCursor, settings.signedInUname)) first = currentUser.firstname last = currentUser.lastname author = first + " " + last title = input("Enter job title: ") desc = input("Enter job description: ") emp = input("Enter employer name: ") loc = input("Enter job location: ") sal = input("Enter salary: ") db.insertJob(dbCursor, title, desc, emp, loc, sal, author) # add notification to let other users know a job has been posted other_users = db.getAllOtherUsers(dbCursor, settings.signedInUname) if len(other_users) > 0: for user in other_users: db.insertNotification(dbCursor, "new_job", title, user[0]) dbConnection.commit() # call API functions to modify output files API.outputJobs(dbCursor) API.outputAppliedJobs(dbCursor) print("Job has been posted.") settings.currentState = states.jobMenu # returns to main() w/ currentState = jobMenu
def verify_handler(): body = request.get_json() logger.debug("Verify %s", body) user = db.getUserByName(conn, body.get('username')) login_attempt = db.getAuthByStateHash(conn, body.get('hash')) try: if user and login_attempt: requested_datetime = datetime.strptime(login_attempt[2], '%Y-%m-%d %H:%M:%S.%f') max_datetime = requested_datetime + timedelta(minutes=10) if requested_datetime < max_datetime: public_key = base64.b64decode(user[3]) signed_hash = base64.b64decode(login_attempt[4]) original_hash = login_attempt[1] try: bytes_signed_hash = bytes(signed_hash) bytes_original_hash = bytes(original_hash, encoding='utf8') verify_key = nacl.signing.VerifyKey( public_key.hex(), encoder=nacl.encoding.HexEncoder) verify_key.verify(bytes_original_hash, bytes_signed_hash) return Response("Ok") except: return Response("Sinature invalid", status=400) else: return Response("You are too late", status=400) else: return Response("Oops.. user or login attempt not found", status=404) except Exception as e: logger.log("Something went wrong while trying to verify the header %e", e)
def set_email_verified_handler(doublename): logger.debug("Verified email from user %s", doublename.lower()) user = db.getUserByName(conn, doublename.lower()) logger.debug(user) logger.debug(user[4]) data = {'type': 'email_verification'} emitOrQueue('login', data, room=user[0]) return Response('Ok')
def testCreateUser(): # todo: potentially change this test to utilize createUser function from main program instead connection = sqlite3.connect("incollege_test.db") cursor = connection.cursor() # Initialize database and run insert function db.initTables(cursor) db.insertUser(cursor, "username", "password", "first", "last", 0, "01/01/2020") assert db.getUserByName(cursor, "username") # Check successful insert connection.close()
def registration_handler(data): logger.debug("Registration %s", data) doublename = data.get('doubleName').lower() email = data.get('email') sid = request.sid publickey = data.get('publicKey') user = db.getUserByName(conn, doublename) if (user is None): update_sql = "INSERT into users (double_name, sid, email, public_key) VALUES(?,?,?,?);" db.insert_user(conn, update_sql, doublename, sid, email, publickey)
def checkname_handler(data): logger.debug("Checking name %s", data) user = db.getUserByName(conn, data.get('doubleName').lower()) if user: logger.debug("user %s", user[0]) emit('nameknown') else: logger.debug("user %s was not found", data.get('doubleName').lower()) emit('namenotknown')
def printUserFriends(dbCursor, uname): friends = db.getUserFriendsByName(dbCursor, uname) if friends: count = 1 for f in friends: name = db.getUserByName(dbCursor, f[0]) print(f"{count}. {name[2]} {name[3]}") count += 1 return friends else: return None
def login_handler(data): logger.debug("Login %s", data) double_name = data.get('doubleName').lower() state = data.get('state') data['type'] = 'login' sid = request.sid user = db.getUserByName(conn, double_name) if user: logger.debug("User found %s", user[0]) update_sql = "UPDATE users SET sid=? WHERE double_name=?;" db.update_user(conn, update_sql, sid, user[0]) user = db.getUserByName(conn, double_name) emitOrQueue('login', data, room=user[0]) insert_auth_sql = "INSERT INTO auth (double_name,state_hash,timestamp,scanned,data) VALUES (?,?,?,?,?);" db.insert_auth(conn, insert_auth_sql, double_name, state, datetime.now(), 0, json.dumps(data)) print('')
def signRegisterHandler(): print('inside signRegister...') body = request.get_json() user = db.getUserByName(conn, body.get('doubleName')) print(user) if user: sio.emit('signed', { 'data': body.get('data'), }, room=user[1]) return Response('Ok') else: return Response('User not found', status=404)
def set_email_verified_handler(doublename): logger.debug("Verified email from user %s", doublename.lower()) user = db.getUserByName(conn, doublename.lower()) logger.debug(user) logger.debug(user[4]) push_service.notify_single_device( registration_id=user[4], message_title='Email verified', message_body='Thanks for verifying your email', data_message={'type': 'email_verification'}, click_action='EMAIL_VERIFIED') return Response('Ok')
def get_user_handler(doublename): doublename = doublename.lower() logger.debug("Getting user %s", doublename) user = db.getUserByName(conn, doublename) if (user is not None): data = {"doublename": doublename, "publicKey": user[3]} response = app.response_class(response=json.dumps(data), mimetype='application/json') logger.debug("User found") return response else: logger.debug("User not found") return Response('User not found', status=404)
def resend_handler(data): logger.debug("Resend %s", data) db.delete_auth_for_user(conn, data.get('doubleName').lower()) insert_auth_sql = "INSERT INTO auth (double_name,state_hash,timestamp,scanned,data) VALUES (?,?,?,?,?);" db.insert_auth(conn, insert_auth_sql, data.get('doubleName').lower( ), data.get('state'), datetime.now(), 0, json.dumps(data)) user = db.getUserByName(conn, data.get('doubleName').lower()) data['type'] = 'login' emitOrQueue('login', data, room=user[0])
def flag_handler(): body = request.get_json() logger.debug("Flag %s", body) login_attempt = None user = db.getUserByName(conn, body.get('doubleName')) try: login_attempt = db.getAuthByStateHash(conn, body.get('hash')) except Exception as e: pass if user: print("user found") try: public_key = base64.b64decode(user[3]) signed_device_id = base64.b64decode(body.get('deviceId')) bytes_signed_device_id = bytes(signed_device_id) verify_key = nacl.signing.VerifyKey( public_key.hex(), encoder=nacl.encoding.HexEncoder) verified_device_id = verify_key.verify(bytes_signed_device_id) if verified_device_id: verified_device_id = verified_device_id.decode("utf-8") update_sql = "UPDATE users SET device_id=? WHERE device_id=?;" db.update_user(conn, update_sql, '', verified_device_id) sio.emit('scannedFlag', {'scanned': True}, room=user[1]) return Response("Ok") except Exception as e: logger.debug("Exception: %s", e) return Response("Sinature invalid", status=400) if login_attempt: print("login attempt found") if verified_device_id: verified_device_id = verified_device_id.decode("utf-8") update_sql = "UPDATE users SET device_id=? WHERE device_id=?;" db.update_user(conn, update_sql, '', verified_device_id) update_sql = "UPDATE auth SET scanned=?, data=? WHERE double_name=?;" db.update_auth(conn, update_sql, 1, '', login_attempt[0]) update_sql = "UPDATE users SET device_id =? WHERE double_name=?;" db.update_user(conn, update_sql, verified_device_id, login_attempt[0]) return Response("Ok") else: print("user not found") return Response('User not found', status=404)
def printUsersFoundParameter(dbCursor, param, param_type): # Search by University or Major if param_type == 0: # Search by University param_string = "UPPER(university)= '" + param.upper() + "'" elif param_type == 1: # Search by Major param_string = "UPPER(major)= '" + param.upper() + "'" users = db.getUsersByParameter(dbCursor, param_string) if users: count = 1 for u in users: name = db.getUserByName(dbCursor, u[0]) print(f"{count}. {name[2]} {name[3]}") count += 1 return users else: return None
def mobile_registration_handler(): body = request.get_json() double_name = body.get('doubleName').lower() sid = body.get('sid') email = body.get('email') public_key = body.get('public_key') if double_name == None or email == None or public_key == None or sid == None: return Response("Missing data", status=400) else: user = db.getUserByName(conn, double_name) if user is None: update_sql = "INSERT into users (double_name, sid, email, public_key) VALUES(?,?,?,?);" db.insert_user(conn, update_sql, double_name, sid, email, public_key) return Response("Succes", status=200)
def sign_handler(): body = request.get_json() logger.debug("Sign: %s", body) login_attempt = db.getAuthByStateHash(conn, body.get('hash')) if login_attempt != None: user = db.getUserByName(conn, login_attempt[0]) update_sql = "UPDATE auth SET singed_statehash =?, data=? WHERE state_hash=?;" db.update_auth(conn, update_sql, body.get('signedHash'), json.dumps(body.get('data')), body.get('hash')) sio.emit('signed', { 'signedHash': body.get('signedHash'), 'data': body.get('data'), 'selectedImageId': body.get('selectedImageId') }, room=user[1]) return Response("Ok") else: return Response("Something went wrong", status=500)
def resend_handler(data): logger.debug("Resend %s", data) db.delete_auth_for_user(conn, data.get('doubleName').lower()) insert_auth_sql = "INSERT INTO auth (double_name,state_hash,timestamp,scanned,data) VALUES (?,?,?,?,?);" db.insert_auth(conn, insert_auth_sql, data.get('doubleName').lower(), data.get('state'), datetime.now(), 0, json.dumps(data)) user = db.getUserByName(conn, data.get('doubleName').lower()) data['type'] = 'login' push_service.notify_single_device( registration_id=user[4], message_title='Finish login', message_body='Tap to finish login', data_message=data, click_action='FLUTTER_NOTIFICATION_CLICK', collapse_key='testLogin') print('')
def verify_signed_data(double_name, data): # print('/n### --- data verification --- ###') # print("Verifying data: ", data) decoded_data = base64.b64decode(data) # print("Decoding data: ", decoded_data) bytes_data = bytes(decoded_data) public_key = base64.b64decode(db.getUserByName(conn, double_name)[3]) # print('Retrieving public key from: ', double_name) verify_key = nacl.signing.VerifyKey(public_key.hex(), encoder=nacl.encoding.HexEncoder) # print('verify_key: ', verify_key) verified_signed_data = verify_key.verify(bytes_data) # print('verified_signed_data: ', verified_signed_data) # print('### --- END data verification --- ###/n') return verified_signed_data
def login(): # Get user details from request body userDetails = request.get_json() name = userDetails.get('name') password = userDetails.get('password') # Check if the user details are set if name is None: return jsonify({"error": "Vul een gebruikersnaam in"}), 400 if password is None: return jsonify({"error": "Vul een wachtwoord in"}), 400 # Check if the user exists user = database.getUserByName(name) if user is None: return jsonify( {"error": "Gebruiker met naam " + name + " bestaat niet"}), 400 # Check the hashed password against the one provided if function.verify_hashed_password(user['userPass'], password): jwt_token = create_access_token(identity=user['userID']) return jsonify({"id": user['userID'], "jwt_token": jwt_token}), 200 else: return jsonify({"error": "Incorrect wachtwoord"}), 401
def createUser(dbCursor, connection): if db.getNumUsers( dbCursor ) >= constants.MAX_USER_ACCOUNTS: # checks if number of accounts in database is at max limit print( "All permitted accounts have been created, please come back later") settings.currentState = states.loggedOut # returns to main() w/ currentState = loggedOut return print( "Enter desired account credentials, or only press enter at any time to cancel account creation." ) uname = input("Enter your desired username: "******"": print("Account creation canceled.") settings.currentState = states.loggedOut return while db.getUserByName(dbCursor, uname): print("Sorry, that username has already been taken.") uname = input("Enter your desired username: "******"": print("Account creation canceled.") settings.currentState = states.loggedOut return pword = input("Enter your desired password: "******"": print("Account creation canceled.") settings.currentState = states.loggedOut return while not utils.validatePassword(pword): print( "Invalid password. Must be length 8-12 characters, contain one digit, one uppercase character, and one non-alphanumeric." ) pword = input("Enter your desired password: "******"": print("Account creation canceled.") settings.currentState = states.loggedOut return fname = input("Enter your first name: ") if fname == "": print("Account creation canceled.") settings.currentState = states.loggedOut return lname = input("Enter your last name: ") if lname == "": print("Account creation canceled.") settings.currentState = states.loggedOut return plusMember = input( "Sign up for InCollege-Plus membership? (Enter Y for Plus, N for Standard): " ) while True: if plusMember.upper() == "Y": plusMember = 1 break elif plusMember.upper() == "N": plusMember = 0 break else: print(constants.INVALID_INPUT) plusMember = input( "Sign up for InCollege-Plus membership? (Enter Y for Plus, N for Standard): " ) today = date.today() # Get today's date date_format = "%m/%d/%Y" todayDate = today.strftime(date_format) # Format date mm/dd/yyyy currentDate = datetime.strptime(todayDate, date_format) # Today's date as a string db.insertUser(dbCursor, uname, pword, fname, lname, plusMember, currentDate) db.insertUserSettings(dbCursor, uname, settings.emailNotif, settings.smsNotif, settings.targetAdvert, settings.language) db.insertProfilePage(dbCursor, uname, "", "", "") # add notification to let other users know a new student has joined other_users = db.getAllOtherUsers(dbCursor, uname) if len(other_users) > 0: for user in other_users: db.insertNotification(dbCursor, "new_student", fname + " " + lname, user[0]) connection.commit( ) # commits the new account and settings to the database (ensures account and settings are saved) API.outputUsers(dbCursor) API.outputProfiles(dbCursor) settings.currentState = states.loggedOut # returns to main() w/ currentState = loggedOut print("Account has been created.")
def findUser(dbCursor, connection): result = None while settings.currentState == states.userSearch: # Added the user prompt for searched person within this function print("\nWhich search term do you want to find users by?") print("A. By Full Name") print("B. By Last Name") print("C. By University") print("D. By Major") print("Z. Return to Previous Menu") response = input("Enter how you wish to search for a user: "******"Enter the name of a person you know: ").split(" ") # If the user enters an extra spaces at the end of first or last name they will be removed while "" in name: name.remove("") while len(name) != 2: print("Name must be in the form (firstname lastname)") name = input("Enter the name of a person you know: ").split( " ") first = name[0] last = name[1] result = db.getUserByFullName( dbCursor, first, last) # Find receiver for friend request break elif response.upper() == 'B': name = input("Enter the last name of the person you might know: ") users_found = utils.printUsersFoundLastName(dbCursor, name) if users_found is None: result = None else: while settings.currentState == states.userSearch: response = input("Choose a person you might know: ") if response.isdigit( ) and int(response) <= len(users_found): first_name = (users_found[int(response) - 1] )[2] # parse first name from user object last_name = (users_found[int(response) - 1] )[3] # parse last name from user object result = db.getUserByFullName(dbCursor, first_name, last_name) break else: print(constants.INVALID_INPUT) break elif response.upper() == 'C': university = input( "Enter the University of the person you might know goes to: ") users_found = utils.printUsersFoundParameter( dbCursor, university, 0) if users_found is None: result = None else: while settings.currentState == states.userSearch: response = input("Choose a person you might know: ") if response.isdigit( ) and int(response) <= len(users_found): name = db.getUserByName(dbCursor, ( users_found[int(response) - 1] )[0]) # parses first and last name from user object result = db.getUserByFullName(dbCursor, name[2], name[3]) break else: print(constants.INVALID_INPUT) break elif response.upper() == 'D': major = input("Enter the major of the person you might know has: ") users_found = utils.printUsersFoundParameter(dbCursor, major, 1) if users_found is None: result = None else: while settings.currentState == states.userSearch: response = input("Choose a person you might know: ") if response.isdigit( ) and int(response) <= len(users_found): name = db.getUserByName(dbCursor, ( users_found[int(response) - 1] )[0]) # parses first and last name from user object result = db.getUserByFullName(dbCursor, name[2], name[3]) break else: print(constants.INVALID_INPUT) break elif response.upper() == 'Z': if settings.signedIn: settings.currentState = states.mainMenu else: settings.currentState = states.loggedOut # returns to main() w/ currentState = loggedOut return False # Didn't find user else: print(constants.INVALID_INPUT) # If the desired user is found successfully, return their data and jump to appropriate menu if result is not None: User = namedtuple( 'User', 'uname pword firstname lastname plus_member date_created') receiver = User._make(result) if settings.signedIn: friend_exists = db.checkUserFriendRelation(dbCursor, settings.signedInUname, receiver.uname) # If this person is already your friend,return if friend_exists: print(receiver.uname + " is already your friend!") settings.currentState = states.userSearch # returns to main() w/ currentState = userSearch return True print("They are a part of the InCollege system!") if settings.signedIn: # if a user is signed in if settings.signedInUname != receiver.uname: # Person you are requesting is not yourself response = input( "Would you like to add them as a friend? Enter 'Y' for yes: " ) request_exists = utils.checkExistingFriendRequest( dbCursor, settings.signedInUname, receiver.uname) if response.upper() == "Y": # Send request if there is no pending request if not request_exists: print( "Sending friend request! They will need to accept before they appear in your friends list!\n" ) db.insertFriendRequest(dbCursor, settings.signedInUname, receiver.uname) connection.commit() else: print( receiver.uname + " has already been sent a request! They will show up in your friends list once they accept!" ) settings.currentState = states.userSearch # returns to main() w/ currentState = userSearch return True else: # else a user is not signed in print("You must be logged in to connect with other users!") settings.currentState = states.userSearch # returns to main() w/ currentState = userSearch return True else: print( "No users found; they are not a part of the InCollege system yet.") while settings.currentState == states.userSearch: print("\nOptions:") print("A. Search for another user") print("Z. Return to previous menu") response = input("Input: ") if response.upper() == "A": break elif response.upper() == "Z": if settings.signedIn: settings.currentState = states.mainMenu else: settings.currentState = states.loggedOut # returns to main() w/ currentState = loggedOut return False # Didn't find user else: print(constants.INVALID_INPUT)
def cancel_login_attempt(doublename): user = db.getUserByName(conn, doublename.lower()) db.delete_auth_for_user(conn, doublename.lower()) sio.emit('cancelLogin', {'scanned': True}, room=user[1]) return Response('Canceled by User')