async def login_post(req): """ post endpoint for logging in a user """ user = User(req.app.mongo) user = await user.fetch_by_name(req.json["username"]) if user: if await user.check_password(req.app.password_hasher, str(req.json["password"]), req.app.pepper): sess_id = await user.login() resp = json_res({ "success": "logged in successfully", "data": { "sessionId": sess_id } }) return resp return json_res( { "error": "Wrong Credentials", "status": 401, "description": "either username or password are wrong" }, status=401)
async def add_addon(req, i): if not await req.ctx.server.supports(req.json["addonType"]): return json_res( { "error": "Invalid Addon Type", "description": "this server doesn't support " + req.json["addonType"], "status": 400 }, status=400) addon = await req.ctx.server.add_addon(req.json["addonId"], req.json["addonType"], req.json["addonVersion"]) if addon: return json_res({"success": "Addon added", "data": {"addon": addon}}) else: return json_res( { "error": "Error while creating Addon", "description": "maybe the addon id is wrong, the file couldn't be downloaded or this server doesn't support addons yet", "status": 400 }, status=400)
async def update_server(req, i): out = {} for k, v in req.json.items(): if k not in MinecraftServer.CHANGEABLE_FIELDS.keys(): return json_res( { "error": "Invalid Key", "description": f"Server has no editable attribute: {k}", "status": 400, "key": k }, status=400) if not MinecraftServer.CHANGEABLE_FIELDS[k](v): return json_res( { "error": "ValueError", "description": f"the value you specified is not valid for {k}", "status": 400, "key": k }, status=400) out[k] = v await req.ctx.server.update(out) await req.ctx.server.refetch() return json_res({ "success": "Updated Server", "update": { "server": req.ctx.server.json() } })
async def remove_addon(req, i, addon_id): if await req.ctx.server.remove_addon(addon_id): return json_res({"success": "Addon Removed"}) else: return json_res( { "error": "Addon Not Found", "description": "addon couldn't be found on the server", "status": 400 }, status=400)
async def open_ticket(req): user = req.ctx.user type_ = req.json["type"].lower() data = req.json["data"] if type_ == "server.console": if "serverId" not in data.keys(): return json_res( { "error": "Missing Server Id", "description": "you have to specify the server id for the type server.console", "status": 400 }, status=400) # Check if serverId is valid bson ObjectId and if a server with that id exists if (not ObjectId.is_valid( data["serverId"])) | (ObjectId(data["serverId"]) not in await req.app.server_manager.get_ids()): return json_res( { "error": "Invalid Server Id", "description": "the server id you entered is either no valid bson ObjectId or does not match a server", "status": 400 }, status=400) # save ObjectId string from request as ObjectId in mongo data["serverId"] = ObjectId(data["serverId"]) rec = await req.app.mongo["wsticket"].find_one({ "userId": user.id, "endpoint": { "type": type_, "data": data } }) if rec and rec["expiration"] >= time.time(): del rec["_id"] return json_res(rec) elif rec: await req.app.mongo["wsticket"].delete_one({"_id": rec["_id"]}) ticket = await get_new_ticket(req.app.mongo) doc = { "ticket": ticket, "userId": user.id, "endpoint": { "type": type_, "data": data }, "expiration": int(time.time() + Config.SESSION_EXPIRATION) } await req.app.mongo["wsticket"].insert_one(doc) del doc["_id"] return json_res(doc)
async def get_minor_versions(req, software, major_version): prov = await req.app.server_manager.versions.provider_by_name(software) if not prov: return json_res( { "error": "Invalid Software", "description": "there is no server software with that name: " + str(software), "status": 400 }, status=400) return json_res(await prov.get_minor_versions(major_version))
async def login_get(req): """ endpoint to redirect on wrong login """ if not req.ctx.session: return json_res( { "error": "Not Logged In", "status": 401, "description": "please login using POST to /account/login" }, status=401) else: return json_res({"info": "you are already logged in", "status": 200})
async def execute_console_command(req, i): """ endpoints for sending console commands to the server """ command = req.json["command"] req.ctx.server.output.append( f"[{strftime('%H:%M:%S')} MCWEB CONSOLE COMMAND]: " + command) await req.ctx.server.send_command(command) return json_res({"success": "command sent", "update": {}})
async def get_all_servers(req): """ endpoints for getting a list of all servers """ o = [ s.light_json() if req.args.get("idonly") else s.json() for s in req.app.server_manager.servers ] return json_res(o)
async def restart(req, i): """ endpoints for restarting the specified server """ stop_event = await req.ctx.server.stop() if not stop_event: raise ValueError("impossible") await stop_event.wait() await req.ctx.server.start() return json_res({"success": "Server Restarted"})
async def fetch_me(req): """ sends information about the current user to the client """ return json_res({ "username": req.ctx.user.name, "permissions": req.ctx.user.perms, "lastServer": str(req.ctx.user.last_server) if req.ctx.user.last_server else None })
async def start_server(req, i): """ endpoints for starting the specified server """ if await req.app.server_manager.server_running_on(port=req.ctx.server.port ): return json_res( { "error": "Port Unavailable", "description": "there is already a server running on that port", "status": 423 }, status=423) await req.ctx.server.start() return json_res({ "success": "server started", "update": { "server": { "online_status": 1 } } })
async def stop_server(req, i): """ endpoint for stopping the specified server """ block = req.args.get("blockuntilstopped") stop_event = await req.ctx.server.stop() if stop_event is None: return json_res( { "error": "Error stopping server", "description": "", "status": 500 }, status=500) if block: await stop_event.wait() return json_res({ "success": "server stopped", "update": { "server": { "online_status": 0 if block else 3 } } })
async def set_session_middleware(self, req) -> None: """ middleware that fetches and sets the session on the request object """ sid = req.token if sid: session = Session(self.mongo) await session.fetch_by_sid(sid) if not await session.is_expired(): await session.refresh() user = User(self.mongo) req.ctx.user = await user.fetch_by_sid(sid) req.ctx.session = session else: await session.logout() req.ctx.user = None req.ctx.session = None return json_res({"error": "session id not existing", "status": 401}, status=401) else: req.ctx.user = None req.ctx.session = None
async def delete_server(req, i): await req.ctx.server.delete() return json_res({"success": "Removed Server Successfully"})
async def logout(req): """ get endpoint for logging out a user """ await req.ctx.session.logout() return json_res({"success": "logged out successfully", "data": {}})
async def get_all_versions(req): return json_res( await req.app.server_manager.versions.get_all_major_versions_json())
async def get_config(req): return json_res(Config.public_json())
async def get_server(req, i): """ endpoint for getting server information for a single server """ await req.ctx.user.set_last_server(req.ctx.server) return json_res(req.ctx.server.json())