Loading src/admin.cpp +30 −1 Changes for src/admin.cpp: 30 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include <iostream> #include <fstream> #include <cstring> #include <set> #include <json-c/json.h> #include <json-c/json_object.h> Loading Loading @@ -1079,15 +1080,20 @@ namespace authdb { json_object *jobj = json_object_new_object(); json_object *jarr = json_object_new_array(); std::set<std::string> seen_sids; // Local sessions for (const SessionData *curdat = AuthSession.firstData(); curdat; curdat = curdat->next()) { uuid::uuid sdid; curdat->getDid(sdid); if (strcmp(cdid, "admin") == 0 || if ((strcmp(cdid, "admin") == 0 && sdid.empty()) || (!did.empty() && did == sdid)) { uuid::uuid sid; curdat->getSid(sid); seen_sids.insert(std::string(sid.c_str())); json_object *jsess = json_object_new_object(); json_object_object_add(jsess, "sid", json_object_new_string(sid.c_str())); json_object_object_add(jsess, "did", json_object_new_string(sdid.c_str())); Loading @@ -1095,6 +1101,29 @@ namespace authdb { json_object_array_add(jarr, jsess); } } // Cluster sessions from all nodes if (g_Cluster && g_Cluster->isRunning()) { std::vector<Cluster::SessionInfo> csessions; g_Cluster->listAllSessions(csessions); for (const auto &cs : csessions) { std::string sidstr = cs.sid.c_str(); if (seen_sids.find(sidstr) != seen_sids.end()) continue; if ((strcmp(cdid, "admin") == 0 && cs.did.empty()) || (!did.empty() && did == cs.did)) { seen_sids.insert(sidstr); json_object *jsess = json_object_new_object(); json_object_object_add(jsess, "sid", json_object_new_string(cs.sid.c_str())); json_object_object_add(jsess, "did", json_object_new_string(cs.did.c_str())); json_object_object_add(jsess, "username", json_object_new_string(cs.username.c_str())); json_object_array_add(jarr, jsess); } } } json_object_object_add(jobj, "sessions", jarr); sendJson(curreq, jobj); json_object_put(jobj); Loading src/cluster.cpp +51 −0 Changes for src/cluster.cpp: 51 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ #include <cstring> #include <iostream> #include <algorithm> #include <set> #ifdef _WIN32 #include <winsock2.h> Loading Loading @@ -683,6 +684,56 @@ namespace authdb { } } void Cluster::listAllSessions(std::vector<SessionInfo> &out) { out.clear(); std::set<std::string> seen_sids; auto tryDeserialize = [&](const std::vector<uint8_t> &data) { SessionInfo info; if (SessionBlock::deserialize(data, info.sid, info.uid, info.did, info.members, info.username, info.gpo_results)) { std::string key = info.sid.c_str(); if (!info.sid.empty() && seen_sids.find(key) == seen_sids.end()) { seen_sids.insert(key); out.push_back(std::move(info)); } } }; // Enumerate local store auto groups = store_->list_groups(); for (uint64_t gid : groups) { std::vector<uint8_t> data; if (store_->fetch(gid, 0, data)) { tryDeserialize(data); } } // Enumerate each peer node if (pclient_) { for (size_t ni = 0; ni < cfg_.peers.size(); ni++) { try { std::vector<uint64_t> pgroups; { std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(5)); if (!lock.owns_lock()) continue; if (!pclient_->list_groups_on_node(ni, pgroups)) continue; } for (uint64_t gid : pgroups) { std::vector<uint8_t> data; std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(5)); if (!lock.owns_lock()) break; if (pclient_->fetch_from_peers(gid, 0, data) && !data.empty()) { tryDeserialize(data); } } } catch (...) { continue; } } } } }; src/cluster.h +10 −0 Changes for src/cluster.h: 10 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -156,6 +156,16 @@ namespace authdb { const uuid::uuid &uid, int dataType, const AuthData *records = nullptr); // List all sessions from local store and peer nodes. // Returns deserialized sessions (deduplicated by SID). struct SessionInfo { uuid::uuid sid, uid, did; std::vector<uuid::uuid> members; std::string username; std::vector<std::pair<uuid::uuid, bool>> gpo_results; }; void listAllSessions(std::vector<SessionInfo> &out); private: ClusterConfig cfg_; std::atomic<bool> running_{false}; Loading Loading
src/admin.cpp +30 −1 Changes for src/admin.cpp: 30 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include <iostream> #include <fstream> #include <cstring> #include <set> #include <json-c/json.h> #include <json-c/json_object.h> Loading Loading @@ -1079,15 +1080,20 @@ namespace authdb { json_object *jobj = json_object_new_object(); json_object *jarr = json_object_new_array(); std::set<std::string> seen_sids; // Local sessions for (const SessionData *curdat = AuthSession.firstData(); curdat; curdat = curdat->next()) { uuid::uuid sdid; curdat->getDid(sdid); if (strcmp(cdid, "admin") == 0 || if ((strcmp(cdid, "admin") == 0 && sdid.empty()) || (!did.empty() && did == sdid)) { uuid::uuid sid; curdat->getSid(sid); seen_sids.insert(std::string(sid.c_str())); json_object *jsess = json_object_new_object(); json_object_object_add(jsess, "sid", json_object_new_string(sid.c_str())); json_object_object_add(jsess, "did", json_object_new_string(sdid.c_str())); Loading @@ -1095,6 +1101,29 @@ namespace authdb { json_object_array_add(jarr, jsess); } } // Cluster sessions from all nodes if (g_Cluster && g_Cluster->isRunning()) { std::vector<Cluster::SessionInfo> csessions; g_Cluster->listAllSessions(csessions); for (const auto &cs : csessions) { std::string sidstr = cs.sid.c_str(); if (seen_sids.find(sidstr) != seen_sids.end()) continue; if ((strcmp(cdid, "admin") == 0 && cs.did.empty()) || (!did.empty() && did == cs.did)) { seen_sids.insert(sidstr); json_object *jsess = json_object_new_object(); json_object_object_add(jsess, "sid", json_object_new_string(cs.sid.c_str())); json_object_object_add(jsess, "did", json_object_new_string(cs.did.c_str())); json_object_object_add(jsess, "username", json_object_new_string(cs.username.c_str())); json_object_array_add(jarr, jsess); } } } json_object_object_add(jobj, "sessions", jarr); sendJson(curreq, jobj); json_object_put(jobj); Loading
src/cluster.cpp +51 −0 Changes for src/cluster.cpp: 51 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ #include <cstring> #include <iostream> #include <algorithm> #include <set> #ifdef _WIN32 #include <winsock2.h> Loading Loading @@ -683,6 +684,56 @@ namespace authdb { } } void Cluster::listAllSessions(std::vector<SessionInfo> &out) { out.clear(); std::set<std::string> seen_sids; auto tryDeserialize = [&](const std::vector<uint8_t> &data) { SessionInfo info; if (SessionBlock::deserialize(data, info.sid, info.uid, info.did, info.members, info.username, info.gpo_results)) { std::string key = info.sid.c_str(); if (!info.sid.empty() && seen_sids.find(key) == seen_sids.end()) { seen_sids.insert(key); out.push_back(std::move(info)); } } }; // Enumerate local store auto groups = store_->list_groups(); for (uint64_t gid : groups) { std::vector<uint8_t> data; if (store_->fetch(gid, 0, data)) { tryDeserialize(data); } } // Enumerate each peer node if (pclient_) { for (size_t ni = 0; ni < cfg_.peers.size(); ni++) { try { std::vector<uint64_t> pgroups; { std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(5)); if (!lock.owns_lock()) continue; if (!pclient_->list_groups_on_node(ni, pgroups)) continue; } for (uint64_t gid : pgroups) { std::vector<uint8_t> data; std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(5)); if (!lock.owns_lock()) break; if (pclient_->fetch_from_peers(gid, 0, data) && !data.empty()) { tryDeserialize(data); } } } catch (...) { continue; } } } } };
src/cluster.h +10 −0 Changes for src/cluster.h: 10 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -156,6 +156,16 @@ namespace authdb { const uuid::uuid &uid, int dataType, const AuthData *records = nullptr); // List all sessions from local store and peer nodes. // Returns deserialized sessions (deduplicated by SID). struct SessionInfo { uuid::uuid sid, uid, did; std::vector<uuid::uuid> members; std::string username; std::vector<std::pair<uuid::uuid, bool>> gpo_results; }; void listAllSessions(std::vector<SessionInfo> &out); private: ClusterConfig cfg_; std::atomic<bool> running_{false}; Loading