def delete_puzzle_timeline(puzzle_id): "" cur = db.cursor() result = cur.execute( fetch_query_string("select-internal-puzzle-details-for-puzzle_id.sql"), { "puzzle_id": puzzle_id }, ).fetchall() if not result: err_msg = {"msg": "No puzzle found", "status_code": 400} cur.close() return err_msg (result, col_names) = rowify(result, cur.description) puzzle_data = result[0] puzzle = puzzle_data["id"] result = cur.execute(fetch_query_string("delete_puzzle_timeline.sql"), {"puzzle": puzzle}) cur.close() db.commit() redis_connection.delete("timeline:{puzzle}".format(puzzle=puzzle)) redis_connection.delete("score:{puzzle}".format(puzzle=puzzle)) msg = {"rowcount": result.rowcount, "msg": "Deleted", "status_code": 200} return msg
def post(self): args = {} if request.form: args.update(request.form.to_dict(flat=True)) # Verify args action = args.get("action") if action not in SLOT_ACTIONS: abort(400) player = args.get("player") if not player: abort(400) cur = db.cursor() if action == "add": cur.execute(fetch_query_string("add-new-user-puzzle-slot.sql"), {"player": player}) elif action == "delete": cur.execute(fetch_query_string("delete-user-puzzle-slot.sql"), {"player": player}) cur.close() db.commit() return redirect( "/chill/site/admin/player/details/{player}/".format(player=player))
def user_id_from_ip(ip, skip_generate=True): cur = db.cursor() shareduser = current_app.secure_cookie.get(u"shareduser") if shareduser != None: # Check if this shareduser is still valid and another user hasn't chosen # a bit icon. result = cur.execute( fetch_query_string("select-user-by-id-and-no-password.sql"), { "id": shareduser }, ).fetchall() if result: cur.close() return int(shareduser) # Handle players that had a cookie in their browser, but then deleted it. # Or new players that are from the same ip that existing players are on. # These players are shown the new-player page. result = cur.execute( fetch_query_string("select-user-id-by-ip-and-no-password.sql"), { "ip": ip }).fetchall() user_id = ANONYMOUS_USER_ID # No ip in db so create it except if the skip_generate flag is set if not result: if skip_generate: cur.close() return None login = generate_user_login() cur.execute( fetch_query_string("add-new-user-for-ip.sql"), { "ip": ip, "login": login, "points": current_app.config["NEW_USER_STARTING_POINTS"], }, ) db.commit() result = cur.execute( fetch_query_string("select-user-id-by-ip-and-login.sql"), { "ip": ip, "login": login }, ).fetchall() (result, col_names) = rowify(result, cur.description) user_id = result[0]["id"] else: (result, col_names) = rowify(result, cur.description) user_id = result[0]["id"] cur.close() return user_id
def delete_puzzle_file(puzzle_id, file_name): "" cur = db.cursor() result = cur.execute( fetch_query_string("select-internal-puzzle-details-for-puzzle_id.sql"), { "puzzle_id": puzzle_id }, ).fetchall() if not result: err_msg = {"msg": "No puzzle found", "status_code": 400} cur.close() return err_msg (result, col_names) = rowify(result, cur.description) puzzle_data = result[0] puzzle = puzzle_data["id"] result = cur.execute( fetch_query_string("select_puzzle_file_with_attribution.sql"), { "puzzle": puzzle, "name": file_name }, ).fetchall() if result: (result, col_names) = rowify(result, cur.description) puzzle_file_with_attribution_data = result[0] # Delete previous attribution if it exists if puzzle_file_with_attribution_data["attribution_id"]: result = cur.execute( fetch_query_string("delete_attribution_from_puzzle_file.sql"), {"id": puzzle_file_with_attribution_data["puzzle_file_id"]}, ) result = cur.execute( fetch_query_string("delete_attribution.sql"), { "attribution": puzzle_file_with_attribution_data["attribution_id"] }, ) result = cur.execute( fetch_query_string("delete_puzzle_file_with_name_for_puzzle.sql"), { "puzzle": puzzle, "name": file_name }, ) db.commit() cur.close() msg = {"rowcount": result.rowcount, "msg": "Deleted", "status_code": 200} return msg
def add_to_timeline(puzzle_id, player, points=0, timestamp=None, message=""): "" if timestamp is None: _timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime()) else: # TODO: Should verify timestamp is in ISO format. _timestamp = timestamp if not isinstance(points, int): err_msg = {"msg": "points needs to be an integer", "status_code": 400} return err_msg cur = db.cursor() result = cur.execute( fetch_query_string("select-internal-puzzle-details-for-puzzle_id.sql"), { "puzzle_id": puzzle_id }, ).fetchall() if not result: err_msg = {"msg": "No puzzle found", "status_code": 400} cur.close() return err_msg (result, col_names) = rowify(result, cur.description) puzzle_data = result[0] puzzle = puzzle_data["id"] # TODO: The message is not added to the Timeline DB table for now since that # information is not currently being used. try: result = cur.execute( fetch_query_string("insert_batchpoints_to_timeline.sql"), { "puzzle": puzzle, "player": player, "points": points, "timestamp": _timestamp, }, ) except sqlite3.IntegrityError: err_msg = { "msg": "Database integrity error. Does the player ({}) exist?".format( player), "status_code": 400, } cur.close() return err_msg cur.close() db.commit() msg = {"rowcount": result.rowcount, "msg": "Inserted", "status_code": 200} return msg
def post(self): """Update shareduser to user""" # Prevent creating a new user if no support for cookies. Player should # have 'ot' already set by viewing the page. uses_cookies = current_app.secure_cookie.get(u"ot") if not uses_cookies: abort(400) cur = db.cursor() response = make_response("", 200) user = user_id_from_ip(request.headers.get("X-Real-IP")) if user == None: abort(400) user = int(user) # Only set new user if enough dots result = cur.execute( fetch_query_string("select-minimum-points-for-user.sql"), { "user": user, "points": current_app.config["NEW_USER_STARTING_POINTS"] + current_app.config["POINT_COST_FOR_CHANGING_BIT"], }, ).fetchone() if result: self.register_new_user(user) # Save as a cookie current_app.secure_cookie.set(u"user", str(user), response, expires_days=365) # Remove shareduser expires = datetime.datetime.utcnow() - datetime.timedelta(days=365) current_app.secure_cookie.set(u"shareduser", "", response, expires=expires) cur.execute( fetch_query_string("decrease-user-points.sql"), { "user": user, "points": current_app.config["POINT_COST_FOR_CHANGING_BIT"], }, ) cur.close() db.commit() return response
def get(self, puzzle_id): "" ip = request.headers.get("X-Real-IP") user = int( current_app.secure_cookie.get(u"user") or user_id_from_ip(ip)) cur = db.cursor() result = cur.execute( fetch_query_string("select_viewable_puzzle_id.sql"), { "puzzle_id": puzzle_id }, ).fetchall() if not result: # 404 if puzzle does not exist abort(404) (result, col_names) = rowify(result, cur.description) puzzle = result[0].get("puzzle") status = result[0].get("status") now = int(time.time()) count = (redis_connection.zcount( "timeline:{puzzle}".format(puzzle=puzzle), now - 5 * 60, "+inf") or 0) player_active_count = {"now": now, "count": count} cur.close() return json.jsonify(player_active_count)
def get(self): url_match = request.args.get("url_match", "/resources/%") cur = db.cursor() result = cur.execute( fetch_query_string( "select_rendered_puzzle_files_with_url_like.sql"), { "url_match": url_match }, ).fetchall() if not result: puzzle_files = [] else: (result, col_names) = rowify(result, cur.description) puzzle_files = result response = { "puzzle_files": puzzle_files, } cur.close() return make_response(json.jsonify(response), 200)
def get(self, puzzle_id): "" cur = db.cursor() result = cur.execute( fetch_query_string("select_viewable_puzzle_id.sql"), { "puzzle_id": puzzle_id }, ).fetchall() if not result: # 404 if puzzle does not exist abort(404) (result, col_names) = rowify(result, cur.description) puzzle = result[0].get("puzzle") status = result[0].get("status") now = int(time.time()) count = (redis_connection.zcount( "timeline:{puzzle}".format(puzzle=puzzle), now - 5 * 60, "+inf") or 0) player_active_count = {"now": now, "count": count} cur.close() return make_response(json.jsonify(player_active_count), 200)
def reward_player_for_score_threshold(player): cur = db.cursor() try: result = cur.execute( fetch_query_string( "reward_player_for_score_threshold--puzzle-instance-slot.sql"), { "player": player, "score_threshold": int( current_app.config.get( "REWARD_INSTANCE_SLOT_SCORE_THRESHOLD", '0')) }, ) except sqlite3.IntegrityError: err_msg = { "msg": "Database integrity error. Does the player ({}) exist?".format( player), "status_code": 400, } cur.close() return err_msg cur.close() db.commit() msg = {"rowcount": result.rowcount, "msg": "Executed", "status_code": 200} return msg
def update_user_points_and_m_date(player, points, score): cur = db.cursor() try: result = cur.execute( fetch_query_string("update_user_points_and_m_date.sql"), { "id": player, "points": points, "score": score, "POINTS_CAP": current_app.config["POINTS_CAP"], }, ) except sqlite3.IntegrityError: err_msg = { "msg": "Database integrity error. Does the player ({}) exist?".format( player), "status_code": 400, } cur.close() return err_msg cur.close() db.commit() msg = {"rowcount": result.rowcount, "msg": "Executed", "status_code": 200} return msg
def post(self, puzzle_id): "Ping and record the time in milliseconds for this player." now_ms = int(time.time() * 1000) response = {"message": "", "name": ""} user = current_app.secure_cookie.get(u"user") or user_id_from_ip( request.headers.get("X-Real-IP"), skip_generate=True) if user == None: response["message"] = "Player not currently logged in." response["name"] = "error" return make_response(json.jsonify(response), 400) user = int(user) cur = db.cursor() # Validate the puzzle_id result = cur.execute( fetch_query_string("select_viewable_puzzle_id.sql"), { "puzzle_id": puzzle_id }, ).fetchall() if not result: response["message"] = "Invalid puzzle id." response["name"] = "error" cur.close() db.commit() return make_response(json.jsonify(response), 400) else: (result, col_names) = rowify(result, cur.description) puzzle = result[0].get("puzzle") status = result[0].get("status") if status != ACTIVE: response["message"] = "Puzzle not active" response["name"] = "invalid" cur.close() db.commit() return make_response(json.jsonify(response), 200) # publish to the puzzle channel the ping with the user id. This will # allow that player to determine their latency. token = uuid.uuid4().hex[:4] pingtoken_key = get_pingtoken_key(puzzle, user, token) redis_connection.setex(pingtoken_key, 60, now_ms) current_app.logger.debug( "publish ping {puzzle_id}".format(puzzle_id=puzzle_id)) sse.publish( "{user}:{token}".format(user=user, token=token), type="ping", channel="puzzle:{puzzle_id}".format(puzzle_id=puzzle_id), ) response["message"] = "ping accepted" response["name"] = "accepted" response = make_response(json.jsonify(response), 202) cur.close() db.commit() return response
def get(self): cur = db.cursor() response = make_response(redirect("/chill/site/admin/puzzle/")) # Delete the shareduser cookie if it exists expires = datetime.datetime.utcnow() - datetime.timedelta(days=365) current_app.secure_cookie.set("shareduser", "", response, expires=expires) current_app.secure_cookie.set("user", str(ADMIN_USER_ID), response, expires_days=365) cur.execute( fetch_query_string("extend-cookie_expires-for-user.sql"), {"id": ADMIN_USER_ID}, ) db.commit() cur.close() return response
def post(self): args = {} xhr_data = request.get_json() if xhr_data: args.update(xhr_data) args.update(request.form.to_dict(flat=True)) args.update(request.args.to_dict(flat=True)) if len(args.keys()) == 0: abort(400) # Start db operations cur = db.cursor() llamas = 0 result = cur.execute(fetch_query_string("get-llama-count.sql")).fetchall() if result: (result, col_names) = rowify(result, cur.description) llamas = result[0]["llamas"] # TODO: Process args for llamaness processed = {"llama-check": True, "count": llamas} db.commit() cur.close() return json.jsonify(processed)
def test_updates_puzzle_details_with_values(self): "Should update the puzzle details with the values that were sent" with self.app.app_context(): with self.app.test_client() as c: new_data = {"status": 1, "queue": 1, "pieces": 1234} rv = c.patch( "/internal/puzzle/{puzzle_id}/details/".format( puzzle_id=self.puzzle_id ), json=new_data, ) self.assertEqual(200, rv.status_code) self.assertEqual( {"msg": "Updated", "rowcount": 1, "status_code": 200}, rv.json ) self.puzzle_data.update(new_data) cur = self.db.cursor() result = cur.execute( fetch_query_string( "select-internal-puzzle-details-for-puzzle_id.sql" ), {"puzzle_id": self.puzzle_id,}, ).fetchall() (result, col_names) = rowify(result, cur.description) self.assertEqual(result[0], self.puzzle_data)
def build_select_available_puzzle_sql(query_file, status, type): """ The sqlite bind params don't support expanding lists, so doing this manually. Careful here to avoid sql injection attacks. """ recent_status = set() # include false values for is_recent active_status = { 0, } # include false values for is_active status_ids = set() for name in status: if name == STATUS_RECENT: recent_status.add(1) status_ids.add(ACTIVE) elif name == STATUS_ACTIVE: recent_status.add(0) recent_status.add(1) active_status.add(1) status_ids.add(ACTIVE) elif name == STATUS_IN_QUEUE: recent_status.add(0) status_ids.add(IN_QUEUE) elif name == STATUS_COMPLETE: recent_status.add(0) status_ids.add(COMPLETED) elif name == STATUS_FROZEN: recent_status.add(0) status_ids.add(FROZEN) elif name == STATUS_UNAVAILABLE: recent_status.add(0) status_ids.add(REBUILD) status_ids.add(IN_RENDER_QUEUE) status_ids.add(RENDERING) status_ids.add(RENDERING_FAILED) original_type = set() for name in type: if name == TYPE_ORIGINAL: original_type.add(1) elif name == TYPE_INSTANCE: original_type.add(0) query = fetch_query_string(query_file) query = query.format( status="({})".format(", ".join(map(str, status_ids))), recent_status="({})".format(", ".join(map(str, recent_status))), active_status="({})".format(", ".join(map(str, active_status))), original_type="({})".format(", ".join(map(str, original_type))), ) # current_app.logger.debug(query) return query
def get(self, puzzle_id): """ deletePenalty: number; canFreeze: boolean; canDelete: boolean; canReset: boolean; hasActions: boolean; deleteDisabledMessage: string; //Not enough dots to delete this puzzle isFrozen: boolean; status: number; """ ip = request.headers.get("X-Real-IP") user = int(current_app.secure_cookie.get("user") or user_id_from_ip(ip)) cur = db.cursor() # validate the puzzle_id result = cur.execute( fetch_query_string("select-puzzle-details-for-puzzle_id.sql"), {"puzzle_id": puzzle_id}, ).fetchall() if not result: # 400 if puzzle does not exist err_msg = { "msg": "No puzzle found", } cur.close() return make_response(json.jsonify(err_msg), 400) (result, col_names) = rowify(result, cur.description) puzzleData = result[0] (delete_penalty, can_delete, delete_disabled_message) = self.get_delete_prereq( puzzleData ) response = { "canDelete": can_delete, "canFreeze": puzzleData.get("status") in (FROZEN, BUGGY_UNLISTED, ACTIVE), "canReset": puzzleData.get("permission") == PRIVATE and not puzzleData.get("is_original") and puzzleData.get("status") in (FROZEN, BUGGY_UNLISTED, ACTIVE, COMPLETED), "hasActions": puzzleData.get("status") in ( FROZEN, ACTIVE, COMPLETED, BUGGY_UNLISTED, RENDERING_FAILED, REBUILD, IN_RENDER_QUEUE, MAINTENANCE, ), "deleteDisabledMessage": delete_disabled_message, "deletePenalty": delete_penalty, "isFrozen": puzzleData.get("status") == FROZEN, "status": puzzleData.get("status", -99), } cur.close() return make_response(json.jsonify(response), 200)
def get(self, anonymous_login): "Set the user cookie if correct anon bit link." login = anonymous_login[:-13] password = anonymous_login[-13:] cur = db.cursor() response = make_response(redirect("/")) result = cur.execute(fetch_query_string("select-user-by-login.sql"), { "login": login }).fetchall() if not result: cur.close() return make_response("no user", 404) (result, col_names) = rowify(result, cur.description) user_data = result[0] expires = datetime.datetime.utcnow() - datetime.timedelta(days=365) if crypt.crypt(password, user_data["password"]) == user_data["password"]: current_app.secure_cookie.set("shareduser", "", response, expires=expires) current_app.secure_cookie.set("user", str(user_data["id"]), response, expires_days=365) cur.execute( fetch_query_string("extend-cookie_expires-for-user.sql"), {"id": user_data["id"]}, ) db.commit() else: # Invalid anon login; delete cookie just in case it's there current_app.secure_cookie.set("user", "", response, expires=expires) cur.close() return response
def get(self): "Return an object to be used by the generateBitLink js call" user = current_app.secure_cookie.get("user") if user is None: return make_response("no user", 403) user = int(user) (p_string, password) = generate_password() # Store encrypted password in db cur = db.cursor() try: result = cur.execute( fetch_query_string("select-login-from-user.sql"), { "id": user }).fetchall() except IndexError: # user may have been added after a db rollback cur.close() return make_response("no user", 404) if not result: cur.close() return make_response("no user", 404) (result, col_names) = rowify(result, cur.description) user_data = result[0] cur.execute( fetch_query_string("update-password-for-user.sql"), { "id": user, "password": password }, ) db.commit() cur.close() data = { "bit": "".join(["", "/puzzle-api/bit/", user_data["login"], p_string]) } return make_response(json.jsonify(data), 200)
def add_puzzle_file(puzzle_id, file_name, url, attribution=None): cur = db.cursor() result = cur.execute( fetch_query_string("select-internal-puzzle-details-for-puzzle_id.sql"), { "puzzle_id": puzzle_id }, ).fetchall() if not result: err_msg = {"msg": "No puzzle found", "status_code": 400} cur.close() return err_msg (result, col_names) = rowify(result, cur.description) puzzle_data = result[0] puzzle = puzzle_data["id"] if attribution: attribution_result = cur.execute( fetch_query_string("insert_attribution.sql"), attribution) attribution_id = attribution_result.lastrowid result = cur.execute( fetch_query_string("add-puzzle-file-with-attribution.sql"), { "puzzle": puzzle, "name": file_name, "url": url, "attribution": attribution_id, }, ) else: result = cur.execute( fetch_query_string("add-puzzle-file.sql"), { "puzzle": puzzle, "name": file_name, "url": url }, ) db.commit() cur.close() msg = {"rowcount": result.rowcount, "msg": "Inserted", "status_code": 200} return msg
def reset_puzzle_pieces_and_handle_errors(puzzle): cur = db.cursor() result = cur.execute( fetch_query_string("select_all_from_puzzle_for_id.sql"), { "id": puzzle }, ).fetchall() if not result: cur.close() raise DataError("No puzzle found with that id.") (result, col_names) = rowify(result, cur.description) puzzle_data = result[0] cur.close() try: reset_puzzle_pieces(puzzle) # TODO: Fix handling of errors on puzzle reset pieces except Error as err: # Update puzzle status to RENDERING_FAILED r = requests.patch( "http://{HOSTAPI}:{PORTAPI}/internal/puzzle/{puzzle_id}/details/". format( HOSTAPI=current_app.config["HOSTAPI"], PORTAPI=current_app.config["PORTAPI"], puzzle_id=puzzle_data["puzzle_id"], ), json={"status": RENDERING_FAILED}, ) sse.publish( "status:{}".format(RENDERING_FAILED), channel="puzzle:{puzzle_id}".format( puzzle_id=puzzle_data["puzzle_id"]), ) if r.status_code != 200: raise Exception("Puzzle details api error") # Update puzzle status to ACTIVE and sse publish r = requests.patch( "http://{HOSTAPI}:{PORTAPI}/internal/puzzle/{puzzle_id}/details/". format( HOSTAPI=current_app.config["HOSTAPI"], PORTAPI=current_app.config["PORTAPI"], puzzle_id=puzzle_data["puzzle_id"], ), json={"status": ACTIVE}, ) sse.publish( "status:{}".format(ACTIVE), channel="puzzle:{puzzle_id}".format( puzzle_id=puzzle_data["puzzle_id"]), ) if r.status_code != 200: raise Exception("Puzzle details api error")
def post(self): "Route is protected by basic auth in nginx" args = {} if request.form: args.update(request.form.to_dict(flat=True)) # Verify args action = args.get("action") if action not in ACTIONS: abort(400) name_register_ids = request.form.getlist("name_register_id") if len(name_register_ids) == 0: abort(400) if not isinstance(name_register_ids, list): name_register_ids = [name_register_ids] name_register_users = request.form.getlist("name_register_user") if len(name_register_users) == 0: abort(400) if not isinstance(name_register_users, list): name_register_users = [name_register_users] cur = db.cursor() if action == "reject": def each(name_register_ids): for id in name_register_ids: yield {"id": id} cur.executemany( fetch_query_string("reject-name-on-name-register-for-id.sql"), each(name_register_ids), ) db.commit() cur.close() routes_to_purge = [] for user in name_register_users: routes_to_purge.append( "/chill/site/internal/player-bit/{}/".format(user)) purge_route_from_nginx_cache( "\n".join(routes_to_purge), current_app.config.get("PURGEURLLIST"), ) return redirect("/chill/site/admin/name-register-review/")
def get(self, user): cur = db.cursor() result = cur.execute( fetch_query_string("select-user-details-by-id.sql"), { "id": user, }, ).fetchall() if not result: err_msg = { "msg": "No user found", } cur.close() return make_response(json.jsonify(err_msg), 404) (result, col_names) = rowify(result, cur.description) user_details = result[0] return make_response(json.jsonify(user_details), 200)
def get_puzzle_details(puzzle_id): "" cur = db.cursor() # validate the puzzle_id result = cur.execute( fetch_query_string("select-internal-puzzle-details-for-puzzle_id.sql"), {"puzzle_id": puzzle_id}, ).fetchall() if not result: # 404 if puzzle does not exist err_msg = {"msg": "No puzzle found", "status_code": 404} cur.close() return err_msg (result, col_names) = rowify(result, cur.description) puzzle_details = result[0] cur.close() msg = {"result": puzzle_details, "msg": "Success", "status_code": 200} return msg
def get_bid_amount(self, cur, puzzleData): "compute the winning bid amount" bid_amount = 0 low, high = next( filter( lambda x: x[0] <= puzzleData["pieces"] and x[1] > puzzleData["pieces"], current_app.config["SKILL_LEVEL_RANGES"], ) ) queue_count_result = cur.execute( fetch_query_string("get-queue-count-for-skill-level.sql"), {"low": low, "high": high}, ).fetchone() if queue_count_result and len(queue_count_result): bid_amount = (queue_count_result[0] + 1) * current_app.config[ "BID_COST_PER_PUZZLE" ] return bid_amount
def update_user_name_approved_for_approved_date_due(): cur = db.cursor() try: result = cur.execute( fetch_query_string( "update-user-name-approved-for-approved_date-due.sql"), ) except sqlite3.IntegrityError: err_msg = { "msg": "Database integrity error. update_user_name_approved_for_approved_date_due", "status_code": 400, } cur.close() return err_msg cur.close() db.commit() msg = {"rowcount": result.rowcount, "msg": "Executed", "status_code": 200} return msg
def get(self, puzzle_id): "" cur = db.cursor() result = cur.execute( fetch_query_string("_select-puzzle-by-puzzle_id.sql"), {"puzzle_id": puzzle_id}, ).fetchall() if not result: # 404 if puzzle does not exist abort(404) (result, col_names) = rowify(result, cur.description) puzzle = result[0].get("id") now = int(time.time()) timeline = redis_connection.zrevrange( "timeline:{puzzle}".format(puzzle=puzzle), 0, -1, withscores=True ) score_puzzle = redis_connection.zrange( "score:{puzzle}".format(puzzle=puzzle), 0, -1, withscores=True ) user_score = dict(score_puzzle) user_rank = {} for index, item in enumerate(score_puzzle): user_rank[int(item[0])] = index + 1 players = [] for index, item in enumerate(timeline): (user, timestamp) = item players.append( { "id": int(user), "score": int(user_score.get(user, 0)), "rank": user_rank.get( int(user), 0 ), # a 0 value means the player hasn't joined any pieces "seconds_from_now": int(now - timestamp), } ) puzzle_stats = {"now": now, "players": players} cur.close() return encoder.encode(puzzle_stats)
def test_get_puzzle_details(self): "Should get the puzzle details" with self.app.app_context(): with self.app.test_client() as c: rv = c.get("/internal/puzzle/{puzzle_id}/details/".format( puzzle_id=self.puzzle_id)) self.assertEqual(200, rv.status_code) self.assertEqual(self.puzzle_data, rv.json) cur = self.db.cursor() result = cur.execute( fetch_query_string( "select-internal-puzzle-details-for-puzzle_id.sql"), { "puzzle_id": self.puzzle_id, }, ).fetchall() (result, col_names) = rowify(result, cur.description) self.assertEqual(result[0], self.puzzle_data)
def update_points_to_minimum_for_all_users(minimum): cur = db.cursor() try: result = cur.execute( fetch_query_string("update_points_to_minimum_for_all_users.sql"), {"minimum": minimum}, ) except sqlite3.IntegrityError: err_msg = { "msg": "Database integrity error. update_points_to_minimum_for_all_users", "status_code": 400, } cur.close() return err_msg cur.close() db.commit() msg = {"rowcount": result.rowcount, "msg": "Executed", "status_code": 200} return msg
def register_new_user(self, user_id): """Update initial ip tracked user to now be cookie tracked with a password.""" cur = db.cursor() login = generate_user_login() (p_string, password) = generate_password() cur.execute( fetch_query_string("set-initial-password-for-user.sql"), { "id": user_id, "password": password, "ip": request.headers.get("X-Real-IP"), }, ) # Other players on the same network that are tracked by shareduser # cookie will have it updated to a new value. db.commit() cur.close()