Loading src/admin.cpp +5 −123 Original line number Diff line number Diff line Loading @@ -147,9 +147,7 @@ namespace authdb { _DomainCacheEvictor = std::move(evictor); } void setAdminKey(const std::string &key) { _AdminKey = key; } /* ---- JSON API: List Users ---- */ void apiListUsers(libhttppp::HttpRequest &curreq, const char *cdid) { Loading Loading @@ -512,8 +510,10 @@ namespace authdb { /* ---- Helper: Check if session user has full admin rights (all authdb GPOs granted) ---- */ bool isSuperAdmin(const SessionData *sdat) { if (!sdat) return false; // SuperAdmin = user has all default GPOs granted // SuperAdmin = user has all restrictive GPOs (default=false) granted for (size_t i = 0; gpo_default[i][0] != nullptr; ++i) { bool defval = (strcmp(gpo_default[i][3], "true") == 0); if (defval) continue; // default=true GPOs are granted to everyone anyway if (!sdat->checkGPO(uuid::uuid(gpo_default[i][0]))) return false; } Loading Loading @@ -1988,26 +1988,8 @@ namespace authdb { libhttppp::HttpCookie cookie; const SessionData *sdat = nullptr; uuid::uuid ssid; bool apiKeyAuth = false; // Check for API key authentication (Bearer token) if (!_AdminKey.empty()) { libhttppp::HttpHeader::HeaderData *authHeader = curreq.getHeaderData("authorization"); if (authHeader && authHeader->getfirstValue()) { std::string authVal = authHeader->getfirstValue()->getvalue(); std::string key; if (authVal.size() > 7 && authVal.substr(0, 7) == "Bearer ") key = authVal.substr(7); else if (authVal.size() > 7 && authVal.substr(0, 7) == "ApiKey ") key = authVal.substr(7); if (!key.empty() && key == _AdminKey) { apiKeyAuth = true; } } } try { if (!apiKeyAuth) { cookie.parse(curreq); for (libhttppp::HttpCookie::CookieData *cur = cookie.getfirstCookieData(); cur; cur = cur->nextCookieData()) { std::cerr << "[CTRL] cookie: key='" << cur->getKey() << "' val='" << cur->getValue() << "'" << std::endl; Loading Loading @@ -2104,7 +2086,6 @@ namespace authdb { if (!sdat) { throw AuthBackendError("No Session found!"); } } // end if (!apiKeyAuth) } catch (...) { // If cluster is critical (< k nodes), show warning page with auto-refresh if (g_Cluster && g_Cluster->isCritical()) { Loading Loading @@ -2188,102 +2169,6 @@ namespace authdb { // Check for /settings/{domain}/api/{action}[/{param}] if (sscanf(url.c_str(), "/settings/%[^/]/api/%[^/]/%s", domain, apiurl, param) >= 2) { try { // API key auth bypasses all permission checks (SuperAdmin) if (apiKeyAuth) { // Route API key requests without permission checks if (strcmp(apiurl, "listusers") == 0) { apiListUsers(curreq, domain); } else if (strcmp(apiurl, "getuser") == 0 && param[0]) { apiGetUser(curreq, domain, param); } else if (strcmp(apiurl, "createuser") == 0) { apiCreateUser(curreq, domain); } else if (strcmp(apiurl, "removeuser") == 0 && param[0]) { apiRemoveUser(curreq, domain, param); } else if (strcmp(apiurl, "edituser") == 0 && param[0]) { apiEditUser(curreq, domain, param); } else if (strcmp(apiurl, "listdomains") == 0) { apiListDomains(curreq); } else if (strcmp(apiurl, "checkpermissions") == 0) { // Return SuperAdmin permissions for API key json_object *jobj = json_object_new_object(); json_object_object_add(jobj, "superadmin", json_object_new_boolean(true)); json_object_object_add(jobj, "sessiondomain", json_object_new_string("admin")); json_object *jgpo = json_object_new_object(); for (size_t i = 0; gpo_default[i][0] != nullptr; ++i) json_object_object_add(jgpo, gpo_default[i][0], json_object_new_boolean(true)); json_object_object_add(jobj, "gpo", jgpo); json_object_object_add(jobj, "backendtype", json_object_new_int(_AdminBackend.getType())); json_object_object_add(jobj, "cluster", json_object_new_boolean(g_Cluster && g_Cluster->isRunning())); sendJson(curreq, jobj); json_object_put(jobj); } else if (strcmp(apiurl, "createdomain") == 0) { apiCreateDomain(curreq, nullptr); } else if (strcmp(apiurl, "removedomain") == 0 && param[0]) { apiRemoveDomain(curreq, param, nullptr); } else if (strcmp(apiurl, "listgroups") == 0) { apiListGroups(curreq, domain); } else if (strcmp(apiurl, "getgroup") == 0 && param[0]) { apiGetGroup(curreq, domain, param); } else if (strcmp(apiurl, "creategroup") == 0) { apiCreateGroup(curreq, domain); } else if (strcmp(apiurl, "removegroup") == 0 && param[0]) { apiRemoveGroup(curreq, domain, param); } else if (strcmp(apiurl, "editgroup") == 0 && param[0]) { apiEditGroup(curreq, domain, param); } else if (strcmp(apiurl, "listsessions") == 0) { apiListSessions(curreq, domain); } else if (strcmp(apiurl, "removesession") == 0 && param[0]) { apiRemoveSession(curreq, param); } else if (strcmp(apiurl, "reloadsession") == 0 && param[0]) { apiReloadSession(curreq, domain, param); } else if (strcmp(apiurl, "listgpos") == 0) { apiListGpos(curreq, domain); } else if (strcmp(apiurl, "getgpo") == 0 && param[0]) { apiGetGpo(curreq, domain, param); } else if (strcmp(apiurl, "creategpo") == 0) { apiCreateGpo(curreq, domain); } else if (strcmp(apiurl, "removegpo") == 0 && param[0]) { apiRemoveGpo(curreq, domain, param); } else if (strcmp(apiurl, "editgpo") == 0 && param[0]) { apiEditGpo(curreq, domain, param); } else if (strcmp(apiurl, "listclients") == 0) { apiListClients(curreq, domain); } else if (strcmp(apiurl, "getclient") == 0 && param[0]) { apiGetClient(curreq, domain, param); } else if (strcmp(apiurl, "createclient") == 0) { apiCreateClient(curreq, domain); } else if (strcmp(apiurl, "removeclient") == 0 && param[0]) { apiRemoveClient(curreq, domain, param); } else if (strcmp(apiurl, "editclient") == 0 && param[0]) { apiEditClient(curreq, domain, param); } else if (strcmp(apiurl, "listservices") == 0) { apiListServices(curreq, domain); } else if (strcmp(apiurl, "getservice") == 0 && param[0]) { apiGetService(curreq, domain, param); } else if (strcmp(apiurl, "createservice") == 0) { apiCreateService(curreq, domain); } else if (strcmp(apiurl, "removeservice") == 0 && param[0]) { apiRemoveService(curreq, domain, param); } else if (strcmp(apiurl, "editservice") == 0 && param[0]) { apiEditService(curreq, domain, param); } else if (strcmp(apiurl, "export") == 0) { apiExportDb(curreq, domain); } else if (strcmp(apiurl, "import") == 0) { apiImportDb(curreq, domain); } else if (strcmp(apiurl, "vacuum") == 0) { apiVacuum(curreq, domain); } else if (strcmp(apiurl, "clusterstatus") == 0) { apiClusterStatus(curreq); } else if (strcmp(apiurl, "clusterscrub") == 0) { apiClusterScrub(curreq); } else if (strcmp(apiurl, "clusterrebalance") == 0) { apiClusterRebalance(curreq); } else { sendJsonError(curreq, "Unknown API endpoint", 404); } return; } if (strcmp(apiurl, "listusers") == 0) { checkDomainAccess(sdat, domain); checkGPO(sdat, "a1b2c3d4-452e-11f0-b1cc-1a2b3c4d5e02"); Loading Loading @@ -2446,7 +2331,6 @@ namespace authdb { std::vector<char> _AdminHtml; std::function<AuthBackend*(const char*)> _DomainResolver; std::function<void(const char*)> _DomainCacheEvictor; std::string _AdminKey; }; AdminInterface::AdminInterface(AuthBackend &bck, std::vector<netplus::socket*> ssock) : _bck(bck) { Loading @@ -2465,9 +2349,7 @@ namespace authdb { _ctl->setDomainCacheEvictor(std::move(evictor)); } void AdminInterface::setAdminKey(const std::string &key) { _ctl->setAdminKey(key); } void AdminInterface::Request(libhttppp::HttpRequest &curreq, const int tid, ULONG_PTR args) { if (curreq.getRequestURL().compare(0, 9, "/settings", 9) == 0) { Loading src/admin.h +1 −1 Original line number Diff line number Diff line Loading @@ -43,7 +43,7 @@ namespace authdb { void Request(libhttppp::HttpRequest &curreq, const int tid, ULONG_PTR args); void setDomainResolver(std::function<AuthBackend*(const char*)> resolver); void setDomainCacheEvictor(std::function<void(const char*)> evictor); void setAdminKey(const std::string &key); public: AdminController * _ctl; AuthBackend &_bck; Loading src/authdb.cpp +0 −14 Original line number Diff line number Diff line Loading @@ -126,10 +126,6 @@ namespace authdb { }); }; void setAdminKey(const std::string &key) { _AdminInterface.setAdminKey(key); } void WizzardEvent(libhttppp::HttpRequest &curreq, const int tid, ULONG_PTR args){ std::lock_guard<std::mutex> wlock(g_wizzard); Loading Loading @@ -896,16 +892,6 @@ int main(int argc,char *argv[]){ authdb::AuthDB authdb(backend,httpd.getServerSockets()); // Set admin API key if configured auto *adminKeyNode = config.getKey("/AUTHDB/ADMIN_KEY"); if (adminKeyNode) { std::string adminKey = config.getValue(adminKeyNode, 0); if (!adminKey.empty()) { authdb.setAdminKey(adminKey); std::cerr << "[AUTHDB] Admin API key authentication enabled" << std::endl; } } // Pre-load all domain backends into cache so API requests // don't need to lock the admin backend for domain resolution. if (backend.end() > sizeof(authdb::AuthHeader)) Loading Loading
src/admin.cpp +5 −123 Original line number Diff line number Diff line Loading @@ -147,9 +147,7 @@ namespace authdb { _DomainCacheEvictor = std::move(evictor); } void setAdminKey(const std::string &key) { _AdminKey = key; } /* ---- JSON API: List Users ---- */ void apiListUsers(libhttppp::HttpRequest &curreq, const char *cdid) { Loading Loading @@ -512,8 +510,10 @@ namespace authdb { /* ---- Helper: Check if session user has full admin rights (all authdb GPOs granted) ---- */ bool isSuperAdmin(const SessionData *sdat) { if (!sdat) return false; // SuperAdmin = user has all default GPOs granted // SuperAdmin = user has all restrictive GPOs (default=false) granted for (size_t i = 0; gpo_default[i][0] != nullptr; ++i) { bool defval = (strcmp(gpo_default[i][3], "true") == 0); if (defval) continue; // default=true GPOs are granted to everyone anyway if (!sdat->checkGPO(uuid::uuid(gpo_default[i][0]))) return false; } Loading Loading @@ -1988,26 +1988,8 @@ namespace authdb { libhttppp::HttpCookie cookie; const SessionData *sdat = nullptr; uuid::uuid ssid; bool apiKeyAuth = false; // Check for API key authentication (Bearer token) if (!_AdminKey.empty()) { libhttppp::HttpHeader::HeaderData *authHeader = curreq.getHeaderData("authorization"); if (authHeader && authHeader->getfirstValue()) { std::string authVal = authHeader->getfirstValue()->getvalue(); std::string key; if (authVal.size() > 7 && authVal.substr(0, 7) == "Bearer ") key = authVal.substr(7); else if (authVal.size() > 7 && authVal.substr(0, 7) == "ApiKey ") key = authVal.substr(7); if (!key.empty() && key == _AdminKey) { apiKeyAuth = true; } } } try { if (!apiKeyAuth) { cookie.parse(curreq); for (libhttppp::HttpCookie::CookieData *cur = cookie.getfirstCookieData(); cur; cur = cur->nextCookieData()) { std::cerr << "[CTRL] cookie: key='" << cur->getKey() << "' val='" << cur->getValue() << "'" << std::endl; Loading Loading @@ -2104,7 +2086,6 @@ namespace authdb { if (!sdat) { throw AuthBackendError("No Session found!"); } } // end if (!apiKeyAuth) } catch (...) { // If cluster is critical (< k nodes), show warning page with auto-refresh if (g_Cluster && g_Cluster->isCritical()) { Loading Loading @@ -2188,102 +2169,6 @@ namespace authdb { // Check for /settings/{domain}/api/{action}[/{param}] if (sscanf(url.c_str(), "/settings/%[^/]/api/%[^/]/%s", domain, apiurl, param) >= 2) { try { // API key auth bypasses all permission checks (SuperAdmin) if (apiKeyAuth) { // Route API key requests without permission checks if (strcmp(apiurl, "listusers") == 0) { apiListUsers(curreq, domain); } else if (strcmp(apiurl, "getuser") == 0 && param[0]) { apiGetUser(curreq, domain, param); } else if (strcmp(apiurl, "createuser") == 0) { apiCreateUser(curreq, domain); } else if (strcmp(apiurl, "removeuser") == 0 && param[0]) { apiRemoveUser(curreq, domain, param); } else if (strcmp(apiurl, "edituser") == 0 && param[0]) { apiEditUser(curreq, domain, param); } else if (strcmp(apiurl, "listdomains") == 0) { apiListDomains(curreq); } else if (strcmp(apiurl, "checkpermissions") == 0) { // Return SuperAdmin permissions for API key json_object *jobj = json_object_new_object(); json_object_object_add(jobj, "superadmin", json_object_new_boolean(true)); json_object_object_add(jobj, "sessiondomain", json_object_new_string("admin")); json_object *jgpo = json_object_new_object(); for (size_t i = 0; gpo_default[i][0] != nullptr; ++i) json_object_object_add(jgpo, gpo_default[i][0], json_object_new_boolean(true)); json_object_object_add(jobj, "gpo", jgpo); json_object_object_add(jobj, "backendtype", json_object_new_int(_AdminBackend.getType())); json_object_object_add(jobj, "cluster", json_object_new_boolean(g_Cluster && g_Cluster->isRunning())); sendJson(curreq, jobj); json_object_put(jobj); } else if (strcmp(apiurl, "createdomain") == 0) { apiCreateDomain(curreq, nullptr); } else if (strcmp(apiurl, "removedomain") == 0 && param[0]) { apiRemoveDomain(curreq, param, nullptr); } else if (strcmp(apiurl, "listgroups") == 0) { apiListGroups(curreq, domain); } else if (strcmp(apiurl, "getgroup") == 0 && param[0]) { apiGetGroup(curreq, domain, param); } else if (strcmp(apiurl, "creategroup") == 0) { apiCreateGroup(curreq, domain); } else if (strcmp(apiurl, "removegroup") == 0 && param[0]) { apiRemoveGroup(curreq, domain, param); } else if (strcmp(apiurl, "editgroup") == 0 && param[0]) { apiEditGroup(curreq, domain, param); } else if (strcmp(apiurl, "listsessions") == 0) { apiListSessions(curreq, domain); } else if (strcmp(apiurl, "removesession") == 0 && param[0]) { apiRemoveSession(curreq, param); } else if (strcmp(apiurl, "reloadsession") == 0 && param[0]) { apiReloadSession(curreq, domain, param); } else if (strcmp(apiurl, "listgpos") == 0) { apiListGpos(curreq, domain); } else if (strcmp(apiurl, "getgpo") == 0 && param[0]) { apiGetGpo(curreq, domain, param); } else if (strcmp(apiurl, "creategpo") == 0) { apiCreateGpo(curreq, domain); } else if (strcmp(apiurl, "removegpo") == 0 && param[0]) { apiRemoveGpo(curreq, domain, param); } else if (strcmp(apiurl, "editgpo") == 0 && param[0]) { apiEditGpo(curreq, domain, param); } else if (strcmp(apiurl, "listclients") == 0) { apiListClients(curreq, domain); } else if (strcmp(apiurl, "getclient") == 0 && param[0]) { apiGetClient(curreq, domain, param); } else if (strcmp(apiurl, "createclient") == 0) { apiCreateClient(curreq, domain); } else if (strcmp(apiurl, "removeclient") == 0 && param[0]) { apiRemoveClient(curreq, domain, param); } else if (strcmp(apiurl, "editclient") == 0 && param[0]) { apiEditClient(curreq, domain, param); } else if (strcmp(apiurl, "listservices") == 0) { apiListServices(curreq, domain); } else if (strcmp(apiurl, "getservice") == 0 && param[0]) { apiGetService(curreq, domain, param); } else if (strcmp(apiurl, "createservice") == 0) { apiCreateService(curreq, domain); } else if (strcmp(apiurl, "removeservice") == 0 && param[0]) { apiRemoveService(curreq, domain, param); } else if (strcmp(apiurl, "editservice") == 0 && param[0]) { apiEditService(curreq, domain, param); } else if (strcmp(apiurl, "export") == 0) { apiExportDb(curreq, domain); } else if (strcmp(apiurl, "import") == 0) { apiImportDb(curreq, domain); } else if (strcmp(apiurl, "vacuum") == 0) { apiVacuum(curreq, domain); } else if (strcmp(apiurl, "clusterstatus") == 0) { apiClusterStatus(curreq); } else if (strcmp(apiurl, "clusterscrub") == 0) { apiClusterScrub(curreq); } else if (strcmp(apiurl, "clusterrebalance") == 0) { apiClusterRebalance(curreq); } else { sendJsonError(curreq, "Unknown API endpoint", 404); } return; } if (strcmp(apiurl, "listusers") == 0) { checkDomainAccess(sdat, domain); checkGPO(sdat, "a1b2c3d4-452e-11f0-b1cc-1a2b3c4d5e02"); Loading Loading @@ -2446,7 +2331,6 @@ namespace authdb { std::vector<char> _AdminHtml; std::function<AuthBackend*(const char*)> _DomainResolver; std::function<void(const char*)> _DomainCacheEvictor; std::string _AdminKey; }; AdminInterface::AdminInterface(AuthBackend &bck, std::vector<netplus::socket*> ssock) : _bck(bck) { Loading @@ -2465,9 +2349,7 @@ namespace authdb { _ctl->setDomainCacheEvictor(std::move(evictor)); } void AdminInterface::setAdminKey(const std::string &key) { _ctl->setAdminKey(key); } void AdminInterface::Request(libhttppp::HttpRequest &curreq, const int tid, ULONG_PTR args) { if (curreq.getRequestURL().compare(0, 9, "/settings", 9) == 0) { Loading
src/admin.h +1 −1 Original line number Diff line number Diff line Loading @@ -43,7 +43,7 @@ namespace authdb { void Request(libhttppp::HttpRequest &curreq, const int tid, ULONG_PTR args); void setDomainResolver(std::function<AuthBackend*(const char*)> resolver); void setDomainCacheEvictor(std::function<void(const char*)> evictor); void setAdminKey(const std::string &key); public: AdminController * _ctl; AuthBackend &_bck; Loading
src/authdb.cpp +0 −14 Original line number Diff line number Diff line Loading @@ -126,10 +126,6 @@ namespace authdb { }); }; void setAdminKey(const std::string &key) { _AdminInterface.setAdminKey(key); } void WizzardEvent(libhttppp::HttpRequest &curreq, const int tid, ULONG_PTR args){ std::lock_guard<std::mutex> wlock(g_wizzard); Loading Loading @@ -896,16 +892,6 @@ int main(int argc,char *argv[]){ authdb::AuthDB authdb(backend,httpd.getServerSockets()); // Set admin API key if configured auto *adminKeyNode = config.getKey("/AUTHDB/ADMIN_KEY"); if (adminKeyNode) { std::string adminKey = config.getValue(adminKeyNode, 0); if (!adminKey.empty()) { authdb.setAdminKey(adminKey); std::cerr << "[AUTHDB] Admin API key authentication enabled" << std::endl; } } // Pre-load all domain backends into cache so API requests // don't need to lock the admin backend for domain resolution. if (backend.end() > sizeof(authdb::AuthHeader)) Loading