api_return QueueApi::handleAddFileBundle(ApiRequest& aRequest) { const auto& reqJson = aRequest.getRequestBody(); string targetDirectory, targetFileName; TargetUtil::TargetType targetType; QueueItemBase::Priority prio; Deserializer::deserializeDownloadParams(aRequest.getRequestBody(), targetDirectory, targetFileName, targetType, prio); BundlePtr b = nullptr; try { b = QueueManager::getInstance()->createFileBundle( targetDirectory + targetFileName, JsonUtil::getField<int64_t>("size", reqJson, false), Deserializer::deserializeTTH(reqJson), Deserializer::deserializeHintedUser(reqJson), JsonUtil::getField<time_t>("time", reqJson, false), 0, prio ); } catch (const Exception& e) { aRequest.setResponseErrorStr(e.getError()); return websocketpp::http::status_code::internal_server_error; } if (b) { json retJson = { { "id", b->getToken() } }; aRequest.setResponseBody(retJson); } return websocketpp::http::status_code::ok; }
api_return SystemApi::handleSetAway(ApiRequest& aRequest) { auto away = JsonUtil::getField<bool>("away", aRequest.getRequestBody()); ActivityManager::getInstance()->setAway(away ? AWAY_MANUAL : AWAY_OFF); aRequest.setResponseBody(serializeAwayState()); return websocketpp::http::status_code::ok; }
api_return ShareApi::handleFindDupePaths(ApiRequest& aRequest) { const auto& reqJson = aRequest.getRequestBody(); json ret; StringList paths; auto path = JsonUtil::getOptionalField<string>("path", reqJson, false, false); if (path) { paths = ShareManager::getInstance()->getDirPaths(Util::toNmdcFile(*path)); } else { auto tth = Deserializer::deserializeTTH(reqJson); paths = ShareManager::getInstance()->getRealPaths(tth); } if (!paths.empty()) { for (const auto& p : paths) { ret.push_back(p); } } else { ret = json::array(); } aRequest.setResponseBody(ret); return websocketpp::http::status_code::ok; }
api_return QueueApi::handleAddFileBundle(ApiRequest& aRequest) { const auto& reqJson = aRequest.getRequestBody(); string targetDirectory, targetFileName; Priority prio; Deserializer::deserializeDownloadParams(aRequest.getRequestBody(), aRequest.getSession(), targetDirectory, targetFileName, prio); BundleAddInfo bundleAddInfo; try { bundleAddInfo = QueueManager::getInstance()->createFileBundle( targetDirectory + targetFileName, JsonUtil::getField<int64_t>("size", reqJson, false), Deserializer::deserializeTTH(reqJson), Deserializer::deserializeHintedUser(reqJson), JsonUtil::getField<time_t>("time", reqJson, false), 0, prio ); } catch (const Exception& e) { aRequest.setResponseErrorStr(e.getError()); return websocketpp::http::status_code::internal_server_error; } aRequest.setResponseBody(Serializer::serializeBundleAddInfo(bundleAddInfo)); return websocketpp::http::status_code::ok; }
websocketpp::http::status_code::value SessionApi::handleLogin(ApiRequest& aRequest, bool aIsSecure, const WebSocketPtr& aSocket, const string& aIP) { const auto& reqJson = aRequest.getRequestBody(); auto username = JsonUtil::getField<string>("username", reqJson, false); auto password = JsonUtil::getField<string>("password", reqJson, false); auto inactivityMinutes = JsonUtil::getOptionalFieldDefault<uint64_t>("max_inactivity", reqJson, WEBCFG(DEFAULT_SESSION_IDLE_TIMEOUT).uint64()); auto userSession = JsonUtil::getOptionalFieldDefault<bool>("user_session", reqJson, false); auto session = WebServerManager::getInstance()->getUserManager().authenticate(username, password, aIsSecure, inactivityMinutes, userSession, aIP); if (!session) { aRequest.setResponseErrorStr("Invalid username or password"); return websocketpp::http::status_code::unauthorized; } json retJson = { { "permissions", session->getUser()->getPermissions() }, { "token", session->getAuthToken() }, { "user", session->getUser()->getUserName() }, { "system", getSystemInfo(aIP) }, { "run_wizard", SETTING(WIZARD_RUN) }, { "cid", ClientManager::getInstance()->getMyCID().toBase32() }, }; if (aSocket) { session->onSocketConnected(aSocket); aSocket->setSession(session); } aRequest.setResponseBody(retJson); return websocketpp::http::status_code::ok; }
api_return QueueApi::handleRemoveFile(ApiRequest& aRequest) { if (QueueManager::getInstance()->removeFile(aRequest.getTokenParam(0), false)) { aRequest.setResponseErrorStr("File not found"); return websocketpp::http::status_code::bad_request; } return websocketpp::http::status_code::ok; }
api_return RecentHubApi::handleGetHubs(ApiRequest& aRequest) { auto hubs = FavoriteManager::getInstance()->getRecentHubs(); auto retJson = Serializer::serializeFromPosition(aRequest.getRangeParam(0), aRequest.getRangeParam(1), hubs, serializeHub); aRequest.setResponseBody(retJson); return websocketpp::http::status_code::ok; }
api_return FavoriteDirectoryApi::handleUpdateDirectory(ApiRequest& aRequest) { auto path = getPath(aRequest); auto info = updatePath(path, aRequest.getRequestBody()); aRequest.setResponseBody(serializeDirectory(info)); return websocketpp::http::status_code::ok; }
// BUNDLES api_return QueueApi::handleGetBundles(ApiRequest& aRequest) { int start = aRequest.getRangeParam(0); int count = aRequest.getRangeParam(1); auto j = Serializer::serializeItemList(start, count, bundlePropertyHandler, QueueUtils::getBundleList()); aRequest.setResponseBody(j); return websocketpp::http::status_code::ok; }
api_return ViewFileApi::handleRemoveFile(ApiRequest& aRequest) { auto success = ViewFileManager::getInstance()->removeFile(Deserializer::parseTTH(aRequest.getStringParam(0))); if (!success) { aRequest.setResponseErrorStr("File not found"); return websocketpp::http::status_code::not_found; } return websocketpp::http::status_code::ok; }
api_return LogApi::handleGetLog(ApiRequest& aRequest) { auto j = Serializer::serializeFromEnd( aRequest.getRangeParam(0), LogManager::getInstance()->getCache().getLogMessages(), Serializer::serializeLogMessage); aRequest.setResponseBody(j); return websocketpp::http::status_code::ok; }
api_return QueueApi::handleRemoveFile(ApiRequest& aRequest) { auto path = JsonUtil::getField<string>("target", aRequest.getRequestBody(), false); if (!QueueManager::getInstance()->removeFile(path, false)) { aRequest.setResponseErrorStr("File not found"); return websocketpp::http::status_code::bad_request; } return websocketpp::http::status_code::ok; }
api_return FilelistApi::handleDeleteList(ApiRequest& aRequest) { auto list = getSubModule(aRequest.getStringParam(0)); if (!list) { aRequest.setResponseErrorStr("List not found"); return websocketpp::http::status_code::not_found; } DirectoryListingManager::getInstance()->removeList(list->getList()->getUser()); return websocketpp::http::status_code::ok; }
api_return HashApi::handleOptimize(ApiRequest& aRequest) { if (HashManager::getInstance()->maintenanceRunning()) { aRequest.setResponseErrorStr("Database maintenance is running already"); return websocketpp::http::status_code::bad_request; } auto verify = JsonUtil::getField<bool>("verify", aRequest.getRequestBody()); HashManager::getInstance()->startMaintenance(verify); return websocketpp::http::status_code::ok; }
api_return SessionApi::handleLogout(ApiRequest& aRequest) { if (!aRequest.getSession()) { aRequest.setResponseErrorStr("Not authorized"); return websocketpp::http::status_code::unauthorized; } WebServerManager::getInstance()->logout(aRequest.getSession()->getId()); return websocketpp::http::status_code::ok; }
api_return QueueApi::handleRemoveSource(ApiRequest& aRequest) { auto user = Deserializer::deserializeUser(aRequest.getRequestBody()); auto removed = QueueManager::getInstance()->removeSource(user, QueueItem::Source::FLAG_REMOVED); aRequest.setResponseBody({ { "count", removed } }); return websocketpp::http::status_code::ok; }
api_return PrivateChatApi::handleDeleteChat(ApiRequest& aRequest) { auto chat = getSubModule(aRequest.getStringParam(0)); if (!chat) { aRequest.setResponseErrorStr("Chat session not found"); return websocketpp::http::status_code::not_found; } MessageManager::getInstance()->removeChat(chat->getChat()->getUser()); return websocketpp::http::status_code::ok; }
api_return ApiModule::handleRequest(ApiRequest& aRequest) { // Find section auto i = requestHandlers.find(aRequest.getStringParam(0)); if (i == requestHandlers.end()) { aRequest.setResponseErrorStr("Invalid API section"); return websocketpp::http::status_code::bad_request; } aRequest.popParam(); const auto& sectionHandlers = i->second; bool hasParamMatch = false; // for better error reporting // Match parameters auto handler = boost::find_if(sectionHandlers, [&](const RequestHandler& aHandler) { // Regular matching auto matchesParams = aHandler.matchParams(aRequest.getParameters()); if (!matchesParams) { return false; } if (aHandler.method == aRequest.getMethod() || aHandler.isModuleHandler()) { return true; } hasParamMatch = true; return false; }); if (handler == sectionHandlers.end()) { if (hasParamMatch) { aRequest.setResponseErrorStr("Method not supported for this command"); } else { aRequest.setResponseErrorStr("Invalid parameters for this API section"); } return websocketpp::http::status_code::bad_request; } // Check JSON payload if (handler->requireJson && !aRequest.hasRequestBody()) { aRequest.setResponseErrorStr("JSON body required"); return websocketpp::http::status_code::bad_request; } // Check permission if (!session->getUser()->hasPermission(handler->access)) { aRequest.setResponseErrorStr("Permission denied"); return websocketpp::http::status_code::forbidden; } // Exact params could be removed from the request... return handler->f(aRequest); }
api_return ApiRouter::handleRequest(ApiRequest& aRequest, bool aIsSecure, const WebSocketPtr& aSocket, const string& aIp) noexcept { int code; try { // Special case because we may not have the session yet if (aRequest.getApiModule() == "session") { return handleSessionRequest(aRequest, aIsSecure, aSocket, aIp); } // Require auth for all other modules if (!aRequest.getSession()) { aRequest.setResponseErrorStr("Not authorized"); return websocketpp::http::status_code::unauthorized; } // Require using the same protocol that was used for logging in if (aRequest.getSession()->isSecure() != aIsSecure) { aRequest.setResponseErrorStr("Protocol mismatch"); return websocketpp::http::status_code::not_acceptable; } aRequest.getSession()->updateActivity(); code = aRequest.getSession()->handleRequest(aRequest); } catch (const ArgumentException& e) { aRequest.setResponseErrorJson(e.getErrorJson()); code = CODE_UNPROCESSABLE_ENTITY; } catch (const std::exception& e) { aRequest.setResponseErrorStr(e.what()); code = websocketpp::http::status_code::bad_request; } return static_cast<api_return>(code); }
api_return SettingApi::handleGetSettingValues(ApiRequest& aRequest) { const auto& requestJson = aRequest.getRequestBody(); json retJson; parseSettingKeys(requestJson, [&](const ApiSettingItem* aItem) { retJson[aItem->name] = aItem->valueToJson().first; }); aRequest.setResponseBody(retJson); return websocketpp::http::status_code::ok; }
api_return QueueApi::handleShareBundle(ApiRequest& aRequest) { auto b = getBundle(aRequest); if (!b->isFinished()) { aRequest.setResponseErrorStr("This action can only be performed for finished bundles"); return websocketpp::http::status_code::bad_request; } auto skipScan = JsonUtil::getOptionalFieldDefault<bool>("skip_scan", aRequest.getRequestBody(), false); QueueManager::getInstance()->shareBundle(b, skipScan); return websocketpp::http::status_code::ok; }
api_return QueueApi::handleRemoveBundleSource(ApiRequest& aRequest) { auto b = getBundle(aRequest); auto user = Deserializer::getUser(aRequest.getStringParam(2), false); auto removed = QueueManager::getInstance()->removeBundleSource(b, user, QueueItem::Source::FLAG_REMOVED); aRequest.setResponseBody({ { "count", removed }, }); return websocketpp::http::status_code::ok; }
api_return ShareProfileApi::handleDefaultProfile(ApiRequest& aRequest) { auto token = aRequest.getTokenParam(0); auto profile = ShareManager::getInstance()->getShareProfile(token); if (!profile) { aRequest.setResponseErrorStr("Profile not found"); return websocketpp::http::status_code::not_found; } ShareManager::getInstance()->setDefaultProfile(token); return websocketpp::http::status_code::ok; }
api_return FavoriteDirectoryApi::handleAddDirectory(ApiRequest& aRequest) { const auto& reqJson = aRequest.getRequestBody(); auto path = Util::validatePath(JsonUtil::getField<string>("path", reqJson, false), true); if (FavoriteManager::getInstance()->hasFavoriteDir(path)) { JsonUtil::throwError("path", JsonUtil::ERROR_EXISTS, "Path exists already"); } auto info = updatePath(path, reqJson); aRequest.setResponseBody(serializeDirectory(info)); return websocketpp::http::status_code::no_content; }
api_return ShareRootApi::handleRemoveRoot(ApiRequest& aRequest) { const auto& reqJson = aRequest.getRequestBody(); auto path = JsonUtil::getField<string>("path", reqJson, false); if (!ShareManager::getInstance()->removeRootDirectory(path)) { aRequest.setResponseErrorStr("Path not found"); return websocketpp::http::status_code::not_found; } return websocketpp::http::status_code::ok; }
api_return SettingApi::handleGetSettingInfos(ApiRequest& aRequest) { const auto& requestJson = aRequest.getRequestBody(); auto forceAutoValues = JsonUtil::getOptionalFieldDefault<bool>("force_auto_values", requestJson, false); json retJson; parseSettingKeys(requestJson, [&](const ApiSettingItem* aItem) { retJson[aItem->name] = aItem->infoToJson(forceAutoValues); }); aRequest.setResponseBody(retJson); return websocketpp::http::status_code::ok; }
websocketpp::http::status_code::value Session::handleRequest(ApiRequest& aRequest) { auto h = apiHandlers.find(aRequest.getApiModule()); if (h != apiHandlers.end()) { if (aRequest.getApiVersion() != h->second->getVersion()) { aRequest.setResponseErrorStr("Invalid API version"); return websocketpp::http::status_code::precondition_failed; } return h->second->handleRequest(aRequest); } aRequest.setResponseErrorStr("Section not found"); return websocketpp::http::status_code::not_found; }
int main(){ ApiRequest request; Stream console; request.setStream(&console); request.initialize(); int id = request.getInstanceId(); char * key = request.getKey(); printf("Key: (%s) <br>\n", key); printf("Instance id: (%d) <br>\n", id); printf("...\n"); }
api_return ApiModule::handleSubscribe(ApiRequest& aRequest) { if (!socket) { aRequest.setResponseErrorStr("Socket required"); return websocketpp::http::status_code::precondition_required; } const auto& subscription = aRequest.getStringParam(0); if (!subscriptionExists(subscription)) { aRequest.setResponseErrorStr("No such subscription: " + subscription); return websocketpp::http::status_code::not_found; } setSubscriptionState(subscription, true); return websocketpp::http::status_code::ok; }
api_return SessionApi::handleActivity(ApiRequest& aRequest) { auto s = aRequest.getSession(); if (!s) { aRequest.setResponseErrorStr("Not authorized"); return websocketpp::http::status_code::unauthorized; } if (!s->isUserSession()) { aRequest.setResponseErrorStr("Activity can only be updated for user sessions"); return websocketpp::http::status_code::bad_request; } ActivityManager::getInstance()->updateActivity(); return websocketpp::http::status_code::ok; }