def push_message(ip_address, message): """ Connects to a client app and sends a message request """ message = message + "\n" s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # get local machine name host = ip_address port = 5677 print("connecting to socket: {}:{}".format(host, port)) try: # connect to client s.connect((host, port)) # prepare message message = message.encode("utf-8") sent = s.send(message) response_code = s.recv(1) s.close() except Error as e: return JSONResponse(False, "Socket error: {}".format(e)) print("sent {} bytes. response: {}".format(sent, response_code)) return JSONResponse(True)
def post(self, *args) -> dict: serializer = AccountSerializer(data=self.request.data) if serializer.is_valid(): serializer.save() else: return JSONResponse.badrequest(serializer.errors) return JSONResponse.success()
def post(self, request) -> dict: serializer = FileSerializer(data=request.data, context=dict(request=request)) if serializer.is_valid(): serializer.save() else: return JSONResponse.badrequest(serializer.errors) return JSONResponse.success(serializer.data)
def post(self, request, *args, **kwargs) -> dict: serializer = self.get_serializer(data=request.data) if serializer.is_valid(): user = serializer.object.get('user') or request.user token = serializer.object.get('token') data = jwt_response_payload_handler(token, user, request) return JSONResponse.success(data) else: return JSONResponse.noauth(serializer.errors)
def logout(session): """ Logs a user out by destroying all session info. """ if "username" not in session: return JSONResponse(False, "Not logged in") for k in session: del session[k] return JSONResponse(True)
def put_action(self, url_params, form_data): service_row = self._get_service_row(form_data) if service_row is not None: result = self._model.update_row(url_params, service_row) if result: return JSONResponse(json_mes='row success updated') else: return JSONResponse(json_status='error', json_mes='error with updating row') else: logger.error(f'Not valid {form_data}') return BadResponse(400, 'Bad Request')
def post_action(self, form_data): service_row = self._get_service_row(form_data) if service_row is not None: result = self._model.add_row(service_row) if result: return JSONResponse(json_mes='row success added') else: return JSONResponse(json_status='error', json_mes='error with adding row') else: logger.error(f'Not valid {form_data}') return BadResponse(400, 'Bad Request')
def process_exception(request, exception): logger = logging.getLogger("api") info = traceback.format_exc() logger.error(info) if not settings.RETURN_ERR_INFO: info = "系统报错" return JSONResponse.servererr(info)
def get_message_route(requester_user, target_user): """ Looks up routing information for the given user. On a successful lookup, the following info should be returned: public_key: public key of the targeted user device_ip: last known IP of the targeted user """ # Lookup public key and device ip of target try: cursor.execute( ("SELECT users.public_key, directory.device_ip FROM directory " "INNER JOIN users ON users.id = directory.user_id " "WHERE users.username=%s"), (target_user, )) except mariadb.Error as error: return JSONResponse(False, "Database error: {}".format(error)) rows = cursor.fetchall() if len(rows) != 1: return JSONResponse(False, "No directory entry found for given username") target_key, target_ip = rows[0] # Lookup public key and device ip of requester try: cursor.execute( ("SELECT users.public_key, directory.device_ip FROM directory " "INNER JOIN users ON users.id = directory.user_id " "WHERE users.username=%s"), (requester_user, )) except mariadb.Error as error: return JSONResponse(False, "Database error: {}".format(error)) rows = cursor.fetchall() if len(rows) != 1: return JSONResponse(False, "No directory entry found for given username") requester_key, requester_ip = rows[0] # Send requester ip and key to target (via socket to target) message = {} message["sender_ip"] = requester_ip message["sender_public_key"] = requester_key response = push_message(target_ip, json.dumps(message)) if not response.success: return response # Return target ip and key to requester (via original http response) response = JSONResponse(True) response.target_ip = target_ip response.target_public_key = target_key return response
def get(self, request, **kwargs) -> Union[dict, FileResponse]: file_id = kwargs.get("id") try: file = FileModel.objects.get(id=file_id) except FileModel.DoesNotExist: return JSONResponse.notfound("{}不指向任何文件".format(file_id)) path = file.file.path name = file.name data = FileModel.read_iter_file(path) response = FileResponse(data) response['Content-Type'] = 'application/octet-stream' response['Content-Disposition'] = 'attachment;filename="{}"'.format(name).encode("utf-8") return response
def upload_action(self, form_data): if not form_data['filename']: logger.error(f'Not valid {form_data} for file') return BadResponse(400, 'Bad Request') elif not form_data['filename'].endswith('.csv'): logger.error(f'Not valid {form_data["filename"]}') return BadResponse(400, 'Bad Request') path_to_file = self._save_file(form_data) if path_to_file is None: return JSONResponse(json_status='error', json_mes='error with saving file') result = self._model.upload_data(path_to_file) os.remove(path_to_file) if result: return JSONResponse(json_mes='table success updated from file') else: return JSONResponse(json_status='error', json_mes='error with updating table from file')
def create_account_post(): """ Creates a new account. """ response = JSONResponse() # Check login status and privileges if "username" not in session: session["create_account_error"] = "You must be logged in" return redirect("/cryptic/admin/console") if "is_admin" in session: if session["is_admin"] < accounts.ADMIN: session[ "create_account_error"] = "Insufficient privileges for account creation" return redirect("/cryptic/admin/console") else: session[ "create_account_error"] = "Insufficient privileges for account creation" return redirect("/cryptic/admin/console") # Form validation if "username" not in request.form: session[ "create_account_error"] = "No username provided for account creation" return redirect("/cryptic/admin/console") username = request.form["username"] if len(username) > 255 or len(username) < 3: session[ "create_account_error"] = "Username must be between 3 and 255 characters" return redirect("/cryptic/admin/console") response = accounts.create_account(session, username) if response.success: session["create_account_success"] = True else: session["create_account_error"] = response.message return redirect("/cryptic/admin/console")
def create_account(session, username): """ Attempts to create the given user account. The user calling this method must have admin privileges to create a new user account. Returns: a tuple (success, message) detailing the result of the login attempt """ # Ensure username is not taken try: cursor.execute("SELECT username FROM users WHERE username=%s", (username, )) except mariadb.Error as error: return JSONResponse(False, "Database error: {}".format(error)) rows = cursor.fetchall() if len(rows) > 0: return JSONResponse(False, "Username is already taken") # Generate a random password. This must be sent to the account creator gen_password = generate_password() gen_password = gen_password.encode("UTF-8") hashed_password = bcrypt.hashpw(gen_password, bcrypt.gensalt()) session["generated_password"] = gen_password # Personal key generation for message storage personal_key = generate_personal_key() # Insert new account into database try: cursor.execute( "INSERT INTO users (username, password, personal_key) VALUES (%s, %s, %s)", (username, hashed_password, personal_key)) except mariadb.Error as error: return JSONResponse(False, "Database error: {}".format(error)) # Commit transaction db_conn.commit() # Successful insert. Prepare response for client response = JSONResponse(True) response.password = gen_password return response
def login_post(): """ Handles login requests. """ if "login_error" in session: del session["login_error"] response = JSONResponse() if "medium" in request.form and request.form["medium"] == "admin_web": # request is from web # Form validation if "username" not in request.form: session["login_error"] = "No username provided for login" return redirect("/cryptic/admin/login") if "password" not in request.form: rsession["login_error"] = "No password provided for login" return redirect("/cryptic/admin/login") username = request.form["username"] password = request.form["password"] if len(username) > 255: session["login_error"] = "Username may not exceed 255 characters" return redirect("/cryptic/admin/login") if len(password) > 255: session["login_error"] = "Password may not exceed 255 characters" return redirect("/cryptic/admin/login") # Check for active sessions if "username" in session: print("username in session found: ", session["username"]) # Client is already logged in as someone if session["username"] == username: # Already logged in as person who they are trying to login as return redirect("/cryptic/admin/console") else: session.clear() #session["login_error"] = "You are already logged in as someone else" #return redirect("/cryptic/admin/login") # Perform login response = accounts.login(session, username, password, None, None) if response.success: return redirect("/cryptic/admin/console") session["login_error"] = response.message return redirect("/cryptic/admin/login") else: # assume request is from app # Form validation if "username" not in request.form: response.success = False response.message = "No username provided for login" return response.to_json(), 200 if "password" not in request.form: response.success = False response.message = "No password provided for login" return response.to_json(), 200 username = request.form["username"] password = request.form["password"] device_ip = request.form[ "device_ip"] if "device_ip" in request.form else "" if "public_key" in request.form: public_key = request.form["public_key"] if public_key == "PLACEHOLDER_KEY_IGNORE": public_key = None else: public_key = None if len(username) > 255: response.success = False response.message = "Username field may not exceed 255 characters" return response.to_json(), 200 if len(password) > 255: response.success = False response.message = "Password field may not exceed 255 characters" return response.to_json(), 200 # Check for active sessions if "username" in session: print("username in session found: ", session["username"]) # Client is already logged in as someone if session["username"] == username: # Already logged in as person who they are trying to login as response.success = True else: response.success = False response.message = "You are already logged in as someone else" return response.to_json(), 200 # Perform login response = accounts.login(session, username, password, device_ip, public_key) return response.to_json(), 200
def delete_action(self, url_params): result = self._model.delete_row(url_params) if result: return JSONResponse(json_mes='row success deleted') else: return JSONResponse(json_status='error', json_mes='error with deleting row')
def get_action(self): result = self._model.get_all() return JSONResponse(data=result)
def post(self, request, **kwargs): user_ids = request.data.get("user_ids") data = {'text': 'websocket成功'} mass_message(user_ids, data) return JSONResponse.success()
def get(self, request: Request, **kwargs) -> dict: user_id = request.user.id data = {'text': 'websocket成功'} send_message.delay(user_id, data) return JSONResponse.success()
def delete(self, request, **kwargs) -> dict: file_id = kwargs.get("id") FileModel.objects.filter(id=file_id).delete() return JSONResponse.success()
def message_route(): """ Mediate peer-to-peer connections. Expected request parameters: target: the user that we are requesting a route to Returns: JSONResponse detailing the request result """ response = JSONResponse() # Check login status if "username" not in session: response.success = False response.message = "You must be logged in to request a route" return response.to_json(), 200 requester = session["username"] # Form validation if "target" not in request.form: response.success = False response.message = "No target provided for routing" return response.to_json(), 200 target = request.form["target"] if len(target) > 255: response.success = False response.message = "Target user field may not exceed 255 characters" return response.to_json(), 200 response = routing.get_message_route(requester, target) return response.to_json(), 200
def login(session, username, password, device_ip, public_key): """ Attempts to login the given user with the given password. Returns: a JSONResponse object detailing the result of the login request """ # Find user in DB try: cursor.execute( "SELECT id, username, password, is_admin, personal_key FROM users WHERE username=%s", (username, )) except mariadb.Error as error: return JSONResponse(False, "Database error: {}".format(error)) rows = cursor.fetchall() if len(rows) != 1: return JSONResponse(False, "Invalid username or password") user_id, fetched_username, hashed_password, is_admin, personal_key = rows[ 0] # Encode passwords for use in bcrypt password = password.encode("UTF-8") hashed_password = hashed_password.encode("UTF-8") if bcrypt.checkpw(password, hashed_password): # Login was successful session["username"] = fetched_username session["is_admin"] = is_admin else: # Invalid password return JSONResponse(False, "Invalid username or password") # If we are here, login was succesful # save device ip if given if device_ip: # check for existing directory entry try: cursor.execute( "SELECT device_ip FROM directory INNER JOIN users ON users.id = directory.user_id WHERE username=%s", (username, )) except mariadb.Error as error: return JSONResponse(False, "Database error: {}".format(error)) rows = cursor.fetchall() if len(rows) == 1: # run update if different fetched_ip = rows[0] if fetched_ip != device_ip: try: cursor.execute( "UPDATE directory INNER JOIN users ON users.id = directory.user_id SET device_ip=%s WHERE username=%s", (device_ip, username)) except mariadb.Error as error: return JSONResponse(False, "Database error: {}".format(error)) db_conn.commit() else: # run insert try: cursor.execute( "INSERT INTO directory (user_id, device_ip) VALUES (%s, %s)", (user_id, device_ip)) except mariadb.Error as error: return JSONResponse(False, "Database error: {}".format(error)) db_conn.commit() # save public key if given if public_key: try: cursor.execute("UPDATE users SET public_key=%s WHERE username=%s", (public_key, username)) except mariadb.Error as error: return JSONResponse(False, "Database error: {}".format(error)) db_conn.commit() response = JSONResponse(True) if personal_key: response.personal_key = personal_key return response