def add_admin(params, _id, conn, logger, config, session): try: # NOTE: make the new admin admin = Admin(username=params["username"], password_hash=params["password_hash"]) with conn: # NOTE: get a lock on the database conn.execute("BEGIN EXCLUSIVE") # CHECK: is the admin-name free? if __is_adminname_taken(conn, params["username"]): return rpc.make_error_resp(const.USERNAME_TAKEN_CODE, const.USERNAME_TAKEN, _id) # NOTE: save the new admin db.save_new_admin(conn, admin, _id) return rpc.make_success_resp( { "type": "admin", "user_id": admin.user_id }, _id) except WrappedErrorResponse as e: file_logger.log_error({ "method": "add_admin " + str(e.methods), "params": params, "error": str(e.exception) }) return e.response_obj except Exception as e: file_logger.log_error({ "method": "add_admin", "params": params, "error": str(e) }) return rpc.make_error_resp(const.INTERNAL_ERROR_CODE, const.INTERNAL_ERROR, _id)
def get_table_names(params, _id, conn, logger, config): try: schemes = t.typize_config(config) if not t.check_params_against_scheme_set(schemes["get_table_names"], params): return rpc.make_error_resp( const.INVALID_PARAMS_CODE, const.INVALID_PARAMS, _id ) resp = __helper(params, _id, conn, logger, config) if resp is not True: return resp c = conn.cursor() c.execute("SELECT name FROM sqlite_master WHERE type='table';") resp = c.fetchall() ret = list() for table_tuple in resp: ret.append(table_tuple[0]) return rpc.make_success_resp(ret, _id) except Exception as e: file_logger.log_error({ "method": "backup_database", "params": params, "error": str(e) }) return rpc.make_error_resp( const.INTERNAL_ERROR_CODE, const.INTERNAL_ERROR, _id)
def get_sister_items(params, _id, conn, logger, config, session): try: # NOTE: find user_id user_id = params.get("user_id", session.get("user_id", None)) # CHECK: was a user_id found? if user_id is None: return rpc.make_error_resp(0, "PROBLEM: There was no `user_id` argument provided and no user_id could be " "located in the session.\n" "SUGGESTION: Either either try again with a `user_id` argument, call " "login() then try again, or use put_sess() to manually add your user_id to " "your session then try again.", _id) with conn: # NOTE: get a lock on the database conn.execute("BEGIN EXCLUSIVE") # NOTE: load the target location target = db.load_item(conn, params["item_uuid"], _id) # NOTE: load the target's items items = [db.load_item(conn, uuid, _id) for uuid in target.sister_items] return rpc.make_success_resp([i.one_hot_jsonify() for i in items], _id) except WrappedErrorResponse as e: file_logger.log_error({ "method": "get_sister_items" + str(e.methods), "params": params, "error": str(e.exception) }) return e.response_obj except Exception as e: file_logger.log_error({ "method": "get_sister_items", "params": params, "error": str(e), }) return rpc.make_error_resp(const.INTERNAL_ERROR_CODE, const.INTERNAL_ERROR, _id)
def get_sess(params, _id, conn, logger, config, session): try: # NOTE: find user_id user_id = params.get("user_id", session.get("user_id", None)) # CHECK: was a user_id found? if user_id is None: return rpc.make_error_resp( 0, "PROBLEM: There was no `user_id` argument provided and no user_id could be " "located in the session.\n" "SUGGESTION: Either either try again with a `user_id` argument, call " "login() then try again, or use put_sess() to manually add your user_id to " "your session then try again.", _id) # NOTE: dictize session for response return rpc.make_success_resp(apihandler.dictize_session(session), _id) except WrappedErrorResponse as e: file_logger.log_error({ "method": "get_sess" + str(e.methods), "params": params, "error": str(e.exception) }) return e.response_obj except Exception as e: file_logger.log_error({ "method": "get_sess", "params": params, "error": str(e) }) return rpc.make_error_resp(const.INTERNAL_ERROR_CODE, const.INTERNAL_ERROR, _id)
def add_ints(params, _id, conn, logger, config): # the entire method gets wrapped in a try except to ensure any uncaught errors return a JSON-RPC error object # rather than an http 5xx. try: # get the typized version of config schemes = t.typize_config(config) # does the params object match any of your the param schemes specified in config.json ? if not t.check_params_against_scheme_set(schemes["add_ints"], params): # if not then throw a JSON-RPC error return rpc.make_error_resp(const.INVALID_PARAMS_CODE, const.INVALID_PARAMS, _id) # do our calculation _sum = 0 for i in params.values(): _sum += i # lets log to stdout saying what we're doing (assuming debugging is on) logger.info( "We just calculated the sum, {}. Now time to format and return the response!" .format(_sum)) # make and return our JSON-RPC response object return rpc.make_success_resp(_sum, _id) # catch everything! except Exception as e: # something went really wrong to be here. So, we write an error object to error.log for later review log.log_error({ "method": "add_ints", "params": params, "error": str(e) }) # finally, we return a JSON-RPC error saying something we messed up. Sorry 😢 return rpc.make_error_resp(const.INTERNAL_ERROR_CODE, const.INTERNAL_ERROR, _id)
def backup_database(params, _id, conn, logger, config): try: schemes = t.typize_config(config) if not t.check_params_against_scheme_set(schemes["backup_database"], params): return rpc.make_error_resp( const.INVALID_PARAMS_CODE, const.INVALID_PARAMS, _id ) resp = __helper(params, _id, conn, logger, config) if resp is not True: return resp with open(config["database_path"] + ".backup", "w+") as f: for line in conn.iterdump(): f.write('%s\n' % line) file_logger.log_general({ # database backups are probably worth writing to a general log file "method": "backup_database", "params": params, }) return rpc.make_success_resp({"success": True}, _id) except Exception as e: file_logger.log_error({ "method": "backup_database", "params": params, "error": str(e) }) return rpc.make_error_resp( const.INTERNAL_ERROR_CODE, const.INTERNAL_ERROR, _id)
def add_location(params, _id, conn, logger, config, session): try: # NOTE: find user_id user_id = params.get("user_id", session.get("user_id", None)) # CHECK: was a user_id found? if user_id is None: return rpc.make_error_resp( 0, "PROBLEM: There was no `user_id` argument provided and no user_id could be " "located in the session.\n" "SUGGESTION: Either either try again with a `user_id` argument, call " "login() then try again, or use put_sess() to manually add your user_id to " "your session then try again.", _id) # CHECK: is the location type valid? if params["type"] not in lconst.LOCATION_TYPES: return rpc.make_error_resp( 0, "PROBLEM: The provided location type is not valid.\n" "SUGGESTION: Try again with a valid location type.", _id) # CHECK: is the representative's title valid? if params["representative"]["title"] not in lconst.TITLES: return rpc.make_error_resp( 0, "PROBLEM: The provided representative title is not valid.\n" "SUGGESTION: Try again with a valid representative title.", _id) location = Location(_type=params["type"], name=params["name"], address=params["address"], details=params["details"], latitude=params["latitude"], longitude=params["longitude"], representative=params["representative"]) with conn: # NOTE: get a lock on the database conn.execute("BEGIN EXCLUSIVE") # NOTE: load the user user = db.load_user_w_user_id(conn, user_id, _id) # NOTE: add the location to the user's location_uuids list user.location_uuids.add(location.uuid) # NOTE: add the user to the location's user_uuids list location.user_uuids.add(user.uuid) # NOTE: save everything db.save_existing_user(conn, user, _id) db.save_new_location(conn, location, _id) return rpc.make_success_resp(location.one_hot_jsonify(), _id) except WrappedErrorResponse as e: file_logger.log_error({ "method": "add_location" + str(e.methods), "params": params, "error": str(e.exception) }) return e.response_obj except Exception as e: file_logger.log_error({ "method": "add_location", "params": params, "error": str(e), }) return rpc.make_error_resp(const.INTERNAL_ERROR_CODE, const.INTERNAL_ERROR, _id)
def method_call(method_name, params, _id, conn, logger, config, session): logger.info("[calling] {} with {}".format(method_name, params)) schemes = t.typize_config(config) if not t.check_params_against_scheme_set(schemes.get(method_name, None), params): return rpc.make_error_resp(const.INVALID_PARAMS_CODE, const.INVALID_PARAMS, _id) return methods.get( method_name, lambda v, w, x, y, z: rpc.make_error_resp(const.NO_METHOD_CODE, const.NO_METHOD, _id) )(params, _id, conn, logger, config, session)
def get_user_locations(params, _id, conn, logger, config, session): try: # NOTE: find user_id user_id = params.get("user_id", session.get("user_id", None)) # CHECK: was a user_id found? if user_id is None: return rpc.make_error_resp(0, "PROBLEM: There was no `user_id` argument provided and no user_id could be " "located in the session.\n" "SUGGESTION: Either either try again with a `user_id` argument, call " "login() then try again, or use put_sess() to manually add your user_id to " "your session then try again.", _id) if "username" in params: with conn: # NOTE: get a lock on the database conn.execute("BEGIN EXCLUSIVE") # CHECK: is there a user associated with the given username? if not __is_username_taken(_id, conn, params["username"]): return rpc.make_error_resp(0, "PROBLEM: No user in the system exists with the designated username.\n" "SUGGESTION: Try a different username.", _id) # NOTE: load the target user target = db.load_user_w_uuid(conn, conn .execute("""SELECT uuid FROM users WHERE username = ?""", (params["username"],)) .fetchone()[0], _id) # NOTE: load the target's locations locations = [db.load_location(conn, uuid, _id) for uuid in target.location_uuids] else: with conn: # NOTE: get a lock on the database conn.execute("BEGIN EXCLUSIVE") # NOTE: load the caller's user caller = db.load_user_w_user_id(conn, user_id, _id) # NOTE: load the caller's locations locations = [db.load_location(conn, uuid, _id) for uuid in caller.location_uuids] return rpc.make_success_resp([i.one_hot_jsonify() for i in locations], _id) except WrappedErrorResponse as e: file_logger.log_error({ "method": "get_user_locations" + str(e.methods), "params": params, "error": str(e.exception) }) return e.response_obj except Exception as e: file_logger.log_error({ "method": "get_user_locations", "params": params, "error": str(e), }) return rpc.make_error_resp(const.INTERNAL_ERROR_CODE, const.INTERNAL_ERROR, _id)
def drop_location(params, _id, conn, logger, config, session): try: # NOTE: find user_id user_id = params.get("user_id", session.get("user_id", None)) # CHECK: was a user_id found? if user_id is None: return rpc.make_error_resp( 0, "PROBLEM: There was no `user_id` argument provided and no user_id could be " "located in the session.\n" "SUGGESTION: Either either try again with a `user_id` argument, call " "login() then try again, or use put_sess() to manually add your user_id to " "your session then try again.", _id) with conn: # NOTE: get a lock on the database conn.execute("BEGIN EXCLUSIVE") # NOTE: load the user user = db.load_user_w_user_id(conn, user_id, _id) # CHECK: is the location attached to the user? if params["location_uuid"] not in user.location_uuids: return rpc.make_error_resp( 0, "PROBLEM: The designated location uuid doesn't correspond to a location " "owned by the user.\n" "SUGGESTIONS: Try again with a valid location uuid.", _id) # NOTE: load the location location = db.load_location(conn, params["location_uuid"], _id) # CHECK: is the location empty of items? if len(location.item_uuids | location.incoming_item_uuids | location.outgoing_item_uuids) != 0: return rpc.make_error_resp( 0, "PROBLEM: The designated location has incoming, outgoing, or inventory items.\n" "SUGGESTION: Try transferring all items then trying again.", _id) # NOTE: remove the location from the user's location_uuids list user.location_uuids.discard(location.uuid) # NOTE: save everything db.save_existing_user(conn, user, _id) return rpc.make_success_resp(location.one_hot_jsonify(), _id) except WrappedErrorResponse as e: file_logger.log_error({ "method": "drop_location" + str(e.methods), "params": params, "error": str(e.exception) }) return e.response_obj except Exception as e: file_logger.log_error({ "method": "drop_location", "params": params, "error": str(e), }) return rpc.make_error_resp(const.INTERNAL_ERROR_CODE, const.INTERNAL_ERROR, _id)
def change_username(params, _id, conn, logger, config, session): try: # CHECK: is the username valid? length = len(params["new_username"]) if length < lconst.MIN_USERNAME_LEN or length > lconst.MAX_USERNAME_LEN: return rpc.make_error_resp(const.INVALID_USER_USERNAME_CODE, const.INVALID_USER_USERNAME, _id) # NOTE: find user_id user_id = params.get("user_id", session.get("user_id", None)) # CHECK: was a user_id found? if user_id is None: return rpc.make_error_resp(0, "PROBLEM: There was no `user_id` argument provided and no user_id could be " "located in the session.\n" "SUGGESTION: Either either try again with a `user_id` argument, call " "login() then try again, or use put_sess() to manually add your user_id to " "your session then try again.", _id) with conn: # NOTE: get a lock on the database conn.execute("BEGIN EXCLUSIVE") # CHECK: is the username available? if len(conn.execute("""SELECT * FROM users WHERE username = ?""", (params["new_username"],)).fetchall()) != 0: return rpc.make_error_resp(0, "PROBLEM: The requested username is taken.\n" "SUGGESTION: Try again with a different username.", _id) # NOTE: load the caller's user caller = db.load_user_w_user_id(conn, user_id, _id) # NOTE: update the caller's username caller.username = params["new_username"] # NOTE: recalculate the caller's user_id caller.recalculate_user_id() # NOTE: save the caller db.save_existing_user(conn, caller, _id) # NOTE: update the user_id in the session session["user_id"] = caller.user_id return rpc.make_success_resp(caller.one_hot_jsonify(), _id) except WrappedErrorResponse as e: file_logger.log_error({ "method": "change_username" + str(e.methods), "params": params, "error": str(e.exception) }) return e.response_obj except Exception as e: file_logger.log_error({ "method": "change_username", "params": params, "error": str(e) }) return rpc.make_error_resp(const.INTERNAL_ERROR_CODE, const.INTERNAL_ERROR, _id)
def drop_user(params, _id, conn, logger, config, session): try: # NOTE: find user_id user_id = params.get("user_id", session.get("user_id", None)) # CHECK: was a user_id found? if user_id is None: return rpc.make_error_resp( 0, "PROBLEM: There was no `user_id` argument provided and no user_id could be " "located in the session.\n" "SUGGESTION: Either either try again with a `user_id` argument, call " "login() then try again, or use put_sess() to manually add your user_id to " "your session then try again.", _id) with conn: # NOTE: get a lock on the database conn.execute("BEGIN EXCLUSIVE") # NOTE: load the user user = db.load_user_w_user_id(conn, user_id, _id) # CHECK: does the user have no items? if len(user.item_uuids | user.incoming_item_uuids | user.outgoing_item_uuids) != 0: return rpc.make_error_resp( 0, "PROBLEM: The designated user has at least 1 item under their ownership or " "currently incoming.\n" "SUGGESTION: Try transferring/dropping/reject all items then trying again.", _id) # CHECK: does the user have no locations? if len(user.location_uuids) != 0: return rpc.make_error_resp( 0, "PROBLEM: The designated user has at least 1 location attached to their " "account.\n" "SUGGESTION: Try dropping all locations then trying again.", _id) # NOTE: delete the user conn.execute("""DELETE FROM users WHERE uuid = ?""", (user.uuid, )) return rpc.make_success_resp(True, _id) except WrappedErrorResponse as e: file_logger.log_error({ "method": "drop_user" + str(e.methods), "params": params, "error": str(e.exception) }) return e.response_obj except Exception as e: file_logger.log_error({ "method": "drop_user", "params": params, "error": str(e), }) return rpc.make_error_resp(const.INTERNAL_ERROR_CODE, const.INTERNAL_ERROR, _id)
def get_user_items(params, _id, conn, logger, config, session): try: # NOTE: find user_id user_id = params.get("user_id", session.get("user_id", None)) # CHECK: was a user_id found? if user_id is None: return rpc.make_error_resp(0, "PROBLEM: There was no `user_id` argument provided and no user_id could be " "located in the session.\n" "SUGGESTION: Either either try again with a `user_id` argument, call " "login() then try again, or use put_sess() to manually add your user_id to " "your session then try again.", _id) with conn: # NOTE: get a lock on the database conn.execute("BEGIN EXCLUSIVE") # NOTE: load the target user if "uuid" in params: target = db.load_user_w_uuid(conn, params["uuid"], _id) else: target = db.load_user_w_user_id(conn, user_id, _id) # NOTE: load the target's items items = [db.load_item(conn, uuid, _id) for uuid in (target.item_uuids | target.incoming_item_uuids | target.outgoing_item_uuids)] # NOTE: form the predicate function for the filter stages = [target.incoming_item_uuids, target.item_uuids, target.outgoing_item_uuids] p = lambda item: ( ("status_filter" not in params or item.status == params.get("status_filter")) and ("ownership_filter" not in params or (item.uuid in target.incoming_item_uuids) == params["ownership_filter"]) and ("location_uuid_filter" not in params or item.location_uuids[-1] == params["location_uuid_filter"]) and ("stage_filter" not in params or item.uuid in stages[params["stage_filter"]])) return rpc.make_success_resp([i.one_hot_jsonify() for i in items if p(i)], _id) except WrappedErrorResponse as e: file_logger.log_error({ "method": "get_user_items" + str(e.methods), "params": params, "error": str(e.exception) }) return e.response_obj except Exception as e: file_logger.log_error({ "method": "get_user_items", "params": params, "error": str(e), }) return rpc.make_error_resp(const.INTERNAL_ERROR_CODE, const.INTERNAL_ERROR, _id)
def save_new_location(c, loc_obj: Location, _id): try: c.execute( """INSERT INTO locations VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", ( loc_obj.uuid, loc_obj.type, json.dumps(list(loc_obj.user_uuids)), json.dumps(list(loc_obj.item_uuids)), json.dumps(list(loc_obj.incoming_item_uuids)), json.dumps(list(loc_obj.outgoing_item_uuids)), loc_obj.name, loc_obj.address, loc_obj.latitude, loc_obj.longitude, loc_obj.details, loc_obj.photo, json.dumps(loc_obj.representative), )) except WrappedErrorResponse as e: e.methods.append("database_helpers.save_new_location") raise e except Exception as e: raise WrappedErrorResponse( rpc.make_error_resp(const.DATABASE_FAILURE_CODE, const.DATABASE_FAILURE, _id), e, "database_helpers.save_new_location")
def login_user(params, _id, conn, logger, config, session): try: # NOTE: calculate user_id user_id = params.get( "user_id", ludeim.generate_user_user_id(params["username"], params["password_hash"])) with conn: # NOTE: get a lock on the database conn.execute("BEGIN EXCLUSIVE") # NOTE: get the user's type user = db.load_user_w_user_id(conn, user_id, _id) # NOTE: add the user's user_id to the session session["user_id"] = user.user_id # NOTE: add the user's type to the session session["type"] = user.type # NOTE: add user uuid to the session session["uuid"] = user.uuid return rpc.make_success_resp(user.one_hot_jsonify(), _id) except WrappedErrorResponse as e: file_logger.log_error({ "method": "login_user" + str(e.methods), "params": params, "error": str(e.exception) }) return e.response_obj except Exception as e: file_logger.log_error({ "method": "login_user", "params": params, "error": str(e) }) return rpc.make_error_resp(const.INTERNAL_ERROR_CODE, const.INTERNAL_ERROR, _id)
def save_existing_user(c, user_obj: User, _id): try: c.execute( """UPDATE users SET uuid = ?, user_id = ?, type_ = ?, username = ?, password_hash = ?, avatar = ?, location_uuids = ?, item_uuids = ?, incoming_item_uuids = ?, outgoing_item_uuids = ? WHERE uuid = ?""", ( user_obj.uuid, user_obj.user_id, user_obj.type, user_obj.username, user_obj.password_hash, user_obj.avatar, json.dumps(list(user_obj.location_uuids)), json.dumps(list(user_obj.item_uuids)), json.dumps(list(user_obj.incoming_item_uuids)), json.dumps(list(user_obj.outgoing_item_uuids)), user_obj.uuid, )) except WrappedErrorResponse as e: e.methods.append("database_helpers.save_existing_user") raise e except Exception as e: raise WrappedErrorResponse( rpc.make_error_resp(const.DATABASE_FAILURE_CODE, const.DATABASE_FAILURE, _id), e, "database_helpers.save_existing_user")
def save_existing_location(c, loc_obj: Location, _id): try: c.execute( """UPDATE locations SET uuid = ?, type = ?, user_uuids = ?, item_uuids = ?, incoming_item_uuids = ?, outgoing_item_uuids = ?, name = ?, address = ?, latitude = ?, longitude = ?, details = ?, photo = ?, representative = ? WHERE uuid = ?""", ( loc_obj.uuid, loc_obj.type, json.dumps(list(loc_obj.user_uuids)), json.dumps(list(loc_obj.item_uuids)), json.dumps(list(loc_obj.incoming_item_uuids)), json.dumps(list(loc_obj.outgoing_item_uuids)), loc_obj.name, loc_obj.address, loc_obj.latitude, loc_obj.longitude, loc_obj.details, loc_obj.photo, json.dumps(loc_obj.representative), loc_obj.uuid, )) except WrappedErrorResponse as e: e.methods.append("database_helpers.save_existing_location") raise e except Exception as e: raise WrappedErrorResponse( rpc.make_error_resp(const.DATABASE_FAILURE_CODE, const.DATABASE_FAILURE, _id), e, "database_helpers.save_existing_location")
def add_user(params, _id, conn, logger, config, session): try: user = User(_type=params["type"], username=params["username"], password_hash=params["password_hash"]) if user.type not in lconst.USER_TYPES: return rpc.make_error_resp(const.INVALID_USER_TYPE_CODE, const.INVALID_USER_TYPE, _id) if len(user.username) < lconst.MIN_USERNAME_LEN or len( user.username) > lconst.MAX_USERNAME_LEN: return rpc.make_error_resp(const.INVALID_USER_USERNAME_CODE, const.INVALID_USER_USERNAME, _id) if len(user.password_hash) < lconst.MIN_PASSWORD_HASH_LEN or len( user.password_hash) > lconst.MAX_PASSWORD_HASH_LEN: return rpc.make_error_resp(const.INVALID_USER_PASSWORD_HASH_CODE, const.INVALID_USER_PASSWORD_HASH, _id) with conn: conn.execute("BEGIN EXCLUSIVE") if __is_username_taken(conn, params["username"]): return rpc.make_error_resp(const.USERNAME_TAKEN_CODE, const.USERNAME_TAKEN, _id) db.save_new_user(conn, user, _id) return rpc.make_success_resp( { "type": user.type, "user_id": user.user_id }, _id) except WrappedErrorResponse as e: file_logger.log_error({ "method": "add_user " + str(e.methods), "params": params, "error": str(e.exception) }) return e.response_obj except Exception as e: exc_type, exc_value, exc_traceback = sys.exc_info() file_logger.log_error({ "method": "add_user", "params": params, "error": str(e), "trace": str(traceback.extract_tb(exc_traceback)) }) return rpc.make_error_resp(const.INTERNAL_ERROR_CODE, const.INTERNAL_ERROR, _id)
def __get_user_username(_id, conn, user_id): try: user = db.load_user_w_user_id(conn, user_id, _id) return user.username except WrappedErrorResponse as e: e.methods.append("__get_user_username") raise e except Exception as e: raise WrappedErrorResponse( rpc.make_error_resp(const.GET_USER_USERNAME_UNKNOWN_CODE, const.GET_USER_USERNAME_UNKNOWN, _id), e, "__get_user_username")
def __helper(params, _id, conn, logger, config): resp = get_user_type(params, _id, conn, logger, config) if "result" not in resp: return resp user_type = resp["result"]["type"] if user_type != "database_general_io_user": return rpc.make_error_resp( const.INSUFFICIENT_PERMISSIONS_CODE, const.INSUFFICIENT_PERMISSIONS, _id ) return True
def put_sess(params, _id, conn, logger, config, session): try: # NOTE: find user_id user_id = params.get("user_id", session.get("user_id", None)) # CHECK: was a user_id found? if user_id is None: return rpc.make_error_resp( 0, "PROBLEM: There was no `user_id` argument provided and no user_id could be " "located in the session.\n" "SUGGESTION: Either either try again with a `user_id` argument, call " "login() then try again, or use put_sess() to manually add your user_id to " "your session then try again.", _id) # CHECK: type key isn't not being updated? if params["key"] == "type": return rpc.make_error_resp( 0, "PROBLEM: Updating the `type` key is not allowed since it could present " "a permission escalation attack vector.\n" "SUGGESTION: Just login and your type will automatically be added to your " "session.", _id) # NOTE: update the session session[params["key"]] = params["value"] # NOTE: dictize session for response return rpc.make_success_resp(apihandler.dictize_session(session), _id) except WrappedErrorResponse as e: file_logger.log_error({ "method": "put_sess" + str(e.methods), "params": params, "error": str(e.exception) }) return e.response_obj except Exception as e: file_logger.log_error({ "method": "put_sess", "params": params, "error": str(e) }) return rpc.make_error_resp(const.INTERNAL_ERROR_CODE, const.INTERNAL_ERROR, _id)
def save_new_admin(c, admin_obj: Admin, _id): try: c.execute("""INSERT INTO admins VALUES (?, ?, ?, ?)""", (admin_obj.user_id, admin_obj.username, admin_obj.password_hash, admin_obj.avatar)) except WrappedErrorResponse as e: e.methods.append("database_helpers.save_new_admin") raise e except Exception as e: raise WrappedErrorResponse( rpc.make_error_resp(const.DATABASE_FAILURE_CODE, const.DATABASE_FAILURE, _id), e, "database_helpers.save_new_admin")
def load_admin(c, user_id, _id): try: line = c.execute("""SELECT * FROM admins WHERE user_id = ?""", (user_id, )).fetchone() return User(line[0], line[1], line[2], line[3]) except WrappedErrorResponse as e: e.methods.append("database_helpers.load_admin") raise e except Exception as e: raise WrappedErrorResponse( rpc.make_error_resp(const.NONEXISTENT_USER_CODE, const.NONEXISTENT_USER, _id), e, "database_helpers.load_admin")
def get_all_users(params, _id, conn, logger, config, session): try: # NOTE: find user_id user_id = params.get("user_id", session.get("user_id", None)) # CHECK: was a user_id found? if user_id is None: return rpc.make_error_resp(0, "PROBLEM: There was no `user_id` argument provided and no user_id could be " "located in the session.\n" "SUGGESTION: Either either try again with a `user_id` argument, call " "login() then try again, or use put_sess() to manually add your user_id to " "your session then try again.", _id) with conn: # NOTE: get a lock on the database conn.execute("BEGIN EXCLUSIVE") # NOTE: load partial users db_resp = conn.execute("""SELECT uuid, type_, username, avatar, location_uuids, item_uuids FROM users""").fetchall() return rpc.make_success_resp([{ "uuid": line[0], "type": line[1], "username": line[2], "avatar": line[3], "location_uuids": line[4], "item_uuids": line[5]} for line in db_resp], _id) except WrappedErrorResponse as e: file_logger.log_error({ "method": "get_all_users" + str(e.methods), "params": params, "error": str(e.exception) }) return e.response_obj except Exception as e: file_logger.log_error({ "method": "get_all_users", "params": params, "error": str(e) }) return rpc.make_error_resp(const.INTERNAL_ERROR_CODE, const.INTERNAL_ERROR, _id)
def change_avatar(params, _id, conn, logger, config, session): try: # NOTE: find user_id user_id = params.get("user_id", session.get("user_id", None)) # CHECK: was a user_id found? if user_id is None: return rpc.make_error_resp(0, "PROBLEM: There was no `user_id` argument provided and no user_id could be " "located in the session.\n" "SUGGESTION: Either either try again with a `user_id` argument, call " "login() then try again, or use put_sess() to manually add your user_id to " "your session then try again.", _id) with conn: # NOTE: get a lock on the database conn.execute("BEGIN EXCLUSIVE") # NOTE: load the caller's user caller = db.load_user_w_user_id(conn, user_id, _id) # NOTE: update the caller's username caller.avatar = params["new_avatar"] # NOTE: save the caller db.save_existing_user(conn, caller, _id) return rpc.make_success_resp(caller.one_hot_jsonify(), _id) except WrappedErrorResponse as e: file_logger.log_error({ "method": "change_avatar" + str(e.methods), "params": params, "error": str(e.exception) }) return e.response_obj except Exception as e: file_logger.log_error({ "method": "change_avatar", "params": params, "error": str(e) }) return rpc.make_error_resp(const.INTERNAL_ERROR_CODE, const.INTERNAL_ERROR, _id)
def load_item(c, item_uuid, _id): try: line = c.execute("""SELECT * FROM items WHERE uuid = ?""", (item_uuid, )).fetchone() return Item(line[0], line[1], json.loads(line[2]), json.loads(line[3]), line[4], json.loads(line[5]), json.loads(line[6])) except WrappedErrorResponse as e: e.methods.append("database_helpers.load_item") raise e except Exception as e: raise WrappedErrorResponse( rpc.make_error_resp(const.NONEXISTENT_USER_CODE, const.NONEXISTENT_USER, _id), e, "database_helpers.load_item")
def drop_admin(params, _id, conn, logger, config, session): try: # NOTE: find user_id user_id = params.get("user_id", session.get("user_id", None)) # CHECK: was a user_id found? if user_id is None: return rpc.make_error_resp( 0, "PROBLEM: There was no `user_id` argument provided and no user_id could be " "located in the session.\n" "SUGGESTION: Either either try again with a `user_id` argument, call " "login() then try again, or use put_sess() to manually add your user_id to " "your session then try again.", _id) with conn: # NOTE: get a lock on the database conn.execute("BEGIN EXCLUSIVE") # NOTE: load the admin admin = db.load_admin(conn, user_id, _id) # NOTE: delete the user conn.execute("""DELETE FROM admins WHERE user_id = ?""", (admin.user_id, )) return rpc.make_success_resp(True, _id) except WrappedErrorResponse as e: file_logger.log_error({ "method": "drop_admin" + str(e.methods), "params": params, "error": str(e.exception) }) return e.response_obj except Exception as e: file_logger.log_error({ "method": "drop_admin", "params": params, "error": str(e), }) return rpc.make_error_resp(const.INTERNAL_ERROR_CODE, const.INTERNAL_ERROR, _id)
def save_new_item(c, item_obj: Item, _id): try: c.execute( """INSERT INTO items VALUES (?, ?, ?, ?, ?, ?, ?)""", (item_obj.uuid, item_obj.type, json.dumps(item_obj.location_uuids), json.dumps(item_obj.user_uuids), item_obj.status, json.dumps(item_obj.sister_items), json.dumps(item_obj.details))) except WrappedErrorResponse as e: e.methods.append("database_helpers.save_new_item") raise e except Exception as e: raise WrappedErrorResponse( rpc.make_error_resp(const.DATABASE_FAILURE_CODE, const.DATABASE_FAILURE, _id), e, "database_helpers.save_new_item")
def load_user_w_user_id(c, user_id, _id): try: line = c.execute("""SELECT * FROM users WHERE user_id = ?""", (user_id, )).fetchone() return User(line[0], line[1], line[2], line[3], line[4], line[5], set(json.loads(line[6])), set(json.loads(line[7])), set(json.loads(line[8])), set(json.loads(line[9]))) except WrappedErrorResponse as e: e.methods.append("database_helpers.load_user_w_user_id") raise e except Exception as e: print(traceback.format_exc()) raise WrappedErrorResponse( rpc.make_error_resp(const.NONEXISTENT_USER_CODE, const.NONEXISTENT_USER, _id), e, "database_helpers.load_user_w_user_id")
def load_location(c, loc_uuid, _id): try: line = c.execute("""SELECT * FROM locations WHERE uuid = ?""", (loc_uuid, )).fetchone() return Location(line[0], line[1], set(json.loads(line[2])), set(json.loads(line[3])), set(json.loads(line[4])), set(json.loads(line[5])), line[6], line[7], line[8], line[9], line[10], line[11], json.loads(line[12])) except WrappedErrorResponse as e: e.methods.append("database_helpers.load_location") raise e except Exception as e: raise WrappedErrorResponse( rpc.make_error_resp(const.NONEXISTENT_LOC_CODE, const.NONEXISTENT_LOC, _id), e, "database_helpers.load_location")