Commit 6831b69b authored by jan.koester's avatar jan.koester
Browse files

test

parent cb09dedd
Loading
Loading
Loading
Loading
Loading
+25 −114
Changes for src/session.cpp: 25 added lines, 114 removed lines.
Original line number Diff line number Diff line
@@ -419,15 +419,13 @@ authdb::ClusterSession::ClusterSession() : LocalSession() {}
authdb::ClusterSession::~ClusterSession() {}

const authdb::SessionData *authdb::ClusterSession::addSession(AuthBackend &backend,uuid::uuid domainid,uuid::uuid userid){
    // Reject if cluster is not available — session would not replicate
    if (!g_Cluster || !g_Cluster->isRunning()) {
    if (!g_Cluster || !g_Cluster->isRunning())
        throw AuthBackendError("cluster not ready — please try again later");
    } else if (g_Cluster->isCritical()) {
    if (g_Cluster->isCritical())
        throw AuthBackendError("cluster critical — too few nodes online, please try again later");
    }

    // Check cluster for existing session
    if (g_Cluster && g_Cluster->isRunning()) {
    // Check cluster for existing session (same user+domain)
    {
        uuid::uuid cluster_sid;
        std::vector<uuid::uuid> cluster_members;
        std::string cluster_username;
@@ -437,9 +435,7 @@ const authdb::SessionData *authdb::ClusterSession::addSession(AuthBackend &backe
            SessionData *imported = new SessionData(cluster_sid, userid, domainid, cluster_members);
            imported->_username = cluster_username;
            imported->setGPOResults(cluster_gpo);

            std::lock_guard<std::mutex> guard(_lock);
            // Replace any stale cache entry
            removeLocal(cluster_sid);
            appendLocal(imported);
            return imported;
@@ -454,86 +450,31 @@ const authdb::SessionData *authdb::ClusterSession::addSession(AuthBackend &backe
    std::cerr << "[SESSION] addSession: created sid=" << newSid.c_str()
              << " uid=" << userid.c_str() << " did=" << domainid.c_str() << std::endl;

    // Synchronous push to cluster with retry — re-push if verify fails
    if (g_Cluster && g_Cluster->isRunning()) {
        bool verified = false;
        int push_retries = 3;

        for (int retry = 0; retry < push_retries && !verified; ++retry) {
    // Push to cluster
    try {
        g_Cluster->pushSession(*newSession);
                std::cerr << "[SESSION] addSession: pushSession attempt " << (retry+1) << " OK" << std::endl;
        std::cerr << "[SESSION] addSession: pushSession OK" << std::endl;
    } catch (const std::exception &e) {
                std::cerr << "[SESSION] addSession: pushSession attempt " << (retry+1)
                          << " FAILED: " << e.what() << std::endl;
                std::this_thread::sleep_for(std::chrono::milliseconds(200));
                continue;
            }

            // Verify session is retrievable from cluster
            auto verify_deadline = std::chrono::steady_clock::now() + std::chrono::seconds(2);
            int checks = 0;
            while (std::chrono::steady_clock::now() < verify_deadline) {
                ++checks;
                uuid::uuid v_sid, v_uid, v_did;
                std::vector<uuid::uuid> v_members;
                std::string v_username;
                std::vector<std::pair<uuid::uuid, bool>> v_gpo;
                if (g_Cluster->fetchSessionBySid(newSid, v_sid, v_uid, v_did,
                                                  v_members, v_username, v_gpo)) {
                    std::cerr << "[SESSION] addSession: verified on attempt " << (retry+1)
                              << " after " << checks << " check(s)" << std::endl;
                    verified = true;
                    break;
                }
                std::this_thread::sleep_for(std::chrono::milliseconds(150));
            }

            if (!verified) {
                std::cerr << "[SESSION] addSession: verify FAILED on attempt " << (retry+1)
                          << " after " << checks << " checks — will retry push" << std::endl;
            }
        }

        if (!verified) {
            std::cerr << "[SESSION] addSession: ERROR — session not verifiable after "
                      << push_retries << " push attempts" << std::endl;
        std::cerr << "[SESSION] addSession: pushSession FAILED: " << e.what() << std::endl;
        delete newSession;
        throw AuthBackendError("session could not be stored in cluster — please try again");
    }
    }

    // Keep pointer alive for callers
    {
        std::lock_guard<std::mutex> guard(_lock);
        appendLocal(newSession);
    }

    return newSession;
}

const authdb::SessionData *authdb::ClusterSession::getSession(uuid::uuid sessionid){
    // Reject if cluster is not available
    if (!g_Cluster || !g_Cluster->isRunning()) {
        throw AuthBackendError("cluster not ready — please try again later");
    } else if (g_Cluster->isCritical()) {
        throw AuthBackendError("cluster critical — too few nodes online, please try again later");
    }

    // Check temp cache first (TTL 5 seconds)
    {
        std::lock_guard<std::mutex> guard(_lock);
        cleanupExpired();
        SessionData *cur = findLocal(sessionid);
        if (cur) {
            auto age = std::chrono::duration_cast<std::chrono::seconds>(
                std::chrono::steady_clock::now() - cur->_lastClusterSync).count();
            if (age < 5)
                return cur;
        }
    }
    if (!g_Cluster || !g_Cluster->isRunning())
        return nullptr;
    if (g_Cluster->isCritical())
        return nullptr;

    // Single cluster fetch — no long retry loop to avoid blocking the API response
    if (g_Cluster && g_Cluster->isRunning()) {
    // Fetch directly from cluster — single source of truth
    uuid::uuid sid, uid, did;
    std::vector<uuid::uuid> members;
    std::string username;
@@ -542,8 +483,6 @@ const authdb::SessionData *authdb::ClusterSession::getSession(uuid::uuid session
        SessionData *imported = new SessionData(sid, uid, did, members);
        imported->_username = username;
        imported->setGPOResults(gpo_results);
            imported->_lastClusterSync = std::chrono::steady_clock::now();

        std::lock_guard<std::mutex> guard(_lock);
        removeLocal(sessionid);
        appendLocal(imported);
@@ -552,78 +491,51 @@ const authdb::SessionData *authdb::ClusterSession::getSession(uuid::uuid session

    std::cerr << "[SESSION] getSession: sid=" << sessionid.c_str()
              << " not found in cluster" << std::endl;

        // Return stale cache if available — and lazily push it to the cluster
        // so other nodes can find it (heals sessions from before cluster code)
        std::lock_guard<std::mutex> guard(_lock);
        SessionData *stale = findLocal(sessionid);
        if (stale) {
            std::cerr << "[SESSION] getSession: found stale local session, pushing to cluster (lazy heal)" << std::endl;
            try {
                g_Cluster->pushSession(*stale);
            } catch (...) {
                std::cerr << "[SESSION] getSession: lazy heal push failed" << std::endl;
            }
            stale->_lastClusterSync = std::chrono::steady_clock::now();
            return stale;
        }
    }

    return nullptr;
}

void authdb::ClusterSession::remSession(uuid::uuid sessionid){
    // Remove from cluster
    if (g_Cluster && g_Cluster->isRunning()) {
        try {
            g_Cluster->removeSessionBySid(sessionid);
        } catch (...) {}
    }
    // Remove from temp cache
    std::lock_guard<std::mutex> guard(_lock);
    removeLocal(sessionid);
}

void authdb::ClusterSession::relSession(AuthBackend &backend,uuid::uuid sessionid){
    // Fetch current session from cluster
    SessionData *cursess = nullptr;
    if (!g_Cluster || !g_Cluster->isRunning())
        throw AuthBackendError("reload session: cluster not available");

    if (g_Cluster && g_Cluster->isRunning()) {
    // Fetch from cluster
    uuid::uuid sid, uid, did;
    std::vector<uuid::uuid> members;
    std::string c_username;
    std::vector<std::pair<uuid::uuid, bool>> gpo_results;
        if (g_Cluster->fetchSessionBySid(sessionid, sid, uid, did, members, c_username, gpo_results)) {
            cursess = new SessionData(sid, uid, did, members);
    if (!g_Cluster->fetchSessionBySid(sessionid, sid, uid, did, members, c_username, gpo_results))
        throw AuthBackendError("reload session: sessionid not found !");

    SessionData *cursess = new SessionData(sid, uid, did, members);
    cursess->_username = c_username;
    cursess->setGPOResults(gpo_results);
            std::lock_guard<std::mutex> guard(_lock);
            removeLocal(sessionid);
            appendLocal(cursess);
        }
    }

    if (!cursess)
        throw AuthBackendError("reload session: sessionid not found !");

    {
        std::lock_guard<std::mutex> guard(_lock);
    reloadSessionData(backend, cursess);
    }

    // Push updated data back to cluster
    if (g_Cluster && g_Cluster->isRunning()) {
    try {
        g_Cluster->pushSession(*cursess);
    } catch (...) {}
    }

    std::lock_guard<std::mutex> guard(_lock);
    removeLocal(sessionid);
    appendLocal(cursess);
}

void authdb::ClusterSession::listSessions(std::vector<SessionInfo> &out){
    out.clear();
    if (!g_Cluster || !g_Cluster->isRunning()) return;

    // Always from cluster — single source of truth
    if (g_Cluster && g_Cluster->isRunning()) {
    std::vector<Cluster::SessionInfo> csessions;
    g_Cluster->listAllSessions(csessions);
    for (const auto &cs : csessions) {
@@ -635,4 +547,3 @@ void authdb::ClusterSession::listSessions(std::vector<SessionInfo> &out){
        out.push_back(std::move(info));
    }
}
}