Commit d9c2aca0 authored by jan.koester's avatar jan.koester
Browse files

test

parent 1d337d9e
Loading
Loading
Loading
Loading
Loading
+75 −5
Changes for src/cluster.cpp: 75 added lines, 5 removed lines.
Original line number Diff line number Diff line
@@ -164,6 +164,22 @@ namespace authdb {
        return id;
    }

    uint64_t sidGroupId(const uuid::uuid &sid) {
        // SHA-256(0xFF || sid) → take first 8 bytes
        // 0xFF prefix avoids collision with sessionGroupId(uid||did)
        std::vector<uint8_t> input(17);
        input[0] = 0xFF;
        std::memcpy(input.data() + 1, sid.value, 16);

        auto hash = netplus::sha256_hash(input);

        uint64_t id = 0;
        for (int i = 0; i < 8; i++) {
            id = (id << 8) | hash[i];
        }
        return id;
    }

    // --- Cluster ---

    Cluster::Cluster() {}
@@ -264,19 +280,23 @@ namespace authdb {

        auto data = SessionBlock::serialize(sess);

        uuid::uuid uid, did;
        uuid::uuid sid, uid, did;
        sess.getSid(sid);
        sess.getUid(uid);
        sess.getDid(did);

        uint64_t sgid = sessionGroupId(uid, did);
        uint64_t sid_gid = sidGroupId(sid);

        // Store locally for peers to fetch
        // Store under both uid+did key and SID key
        store_->store(sgid, 0, data.data(), data.size());
        store_->store(sid_gid, 0, data.data(), data.size());

        // Replicate raw data to all peer nodes
        // Replicate raw data to all peer nodes under both keys
        try {
            std::lock_guard<std::mutex> lock(client_mutex_);
            pclient_->replicate_to_peers(sgid, 0, data.data(), data.size());
            pclient_->replicate_to_peers(sid_gid, 0, data.data(), data.size());
        } catch (const netplus::NetException &e) {
            std::cerr << "Cluster push session failed: " << e.what() << std::endl;
        } catch (const std::exception &e) {
@@ -321,10 +341,27 @@ namespace authdb {
    void Cluster::removeSession(const uuid::uuid &uid, const uuid::uuid &did) {
        uint64_t sgid = sessionGroupId(uid, did);

        // Remove from local store
        // Also remove the SID-keyed entry: fetch data first to get the SID
        std::vector<uint8_t> data;
        if (store_->fetch(sgid, 0, data)) {
            uuid::uuid sid, d_uid, d_did;
            std::vector<uuid::uuid> members;
            std::string username;
            if (SessionBlock::deserialize(data, sid, d_uid, d_did, members, username)) {
                uint64_t sid_gid = sidGroupId(sid);
                store_->remove_group(sid_gid);
                if (pclient_) {
                    try {
                        std::lock_guard<std::mutex> lock(client_mutex_);
                        pclient_->remove(sid_gid);
                    } catch (...) {}
                }
            }
        }

        // Remove uid+did keyed entry
        store_->remove_group(sgid);

        // Remove from all peer nodes
        if (pclient_) {
            try {
                std::lock_guard<std::mutex> lock(client_mutex_);
@@ -352,6 +389,39 @@ namespace authdb {
        return false;
    }

    bool Cluster::fetchSessionBySid(const uuid::uuid &session_id,
                                     uuid::uuid &sid, uuid::uuid &uid, uuid::uuid &did,
                                     std::vector<uuid::uuid> &members,
                                     std::string &username) {
        uint64_t sid_gid = sidGroupId(session_id);

        // Check local store first
        std::vector<uint8_t> data;
        if (store_->fetch(sid_gid, 0, data)) {
            if (SessionBlock::deserialize(data, sid, uid, did, members, username)) {
                return true;
            }
        }

        // Try to fetch from peer nodes
        if (pclient_) {
            try {
                std::lock_guard<std::mutex> lock(client_mutex_);
                if (pclient_->fetch_from_peers(sid_gid, 0, data) && !data.empty()) {
                    if (SessionBlock::deserialize(data, sid, uid, did, members, username)) {
                        // Cache locally
                        store_->store(sid_gid, 0, data.data(), data.size());
                        return true;
                    }
                }
            } catch (...) {
                return false;
            }
        }

        return false;
    }

    // --- DataOpBlock serialization ---

    std::vector<uint8_t> DataOpBlock::serialize(OpType op, const std::string &domain,
+7 −0
Changes for src/cluster.h: 7 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ namespace authdb {
    };

    uint64_t sessionGroupId(const uuid::uuid &uid, const uuid::uuid &did);
    uint64_t sidGroupId(const uuid::uuid &sid);

    // --- Data operation replication ---

@@ -137,6 +138,12 @@ namespace authdb {
        // Check if a session already exists in the cluster for uid+did
        bool hasSession(const uuid::uuid &uid, const uuid::uuid &did);

        // Fetch a session from the cluster by session ID (SID)
        bool fetchSessionBySid(const uuid::uuid &session_id,
                               uuid::uuid &sid, uuid::uuid &uid, uuid::uuid &did,
                               std::vector<uuid::uuid> &members,
                               std::string &username);

        // Replicate a data operation (create/edit/delete) to peers
        void replicateOp(OpType op, const std::string &domain,
                         const uuid::uuid &uid, int dataType,
+23 −3
Changes for src/session.cpp: 23 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -363,16 +363,36 @@ const authdb::SessionData *authdb::Session::addSession(AuthBackend &backend,uuid
}

const authdb::SessionData *authdb::Session::getSession(uuid::uuid sessionid){
    {
        std::lock_guard<std::mutex> guard(_SessionLock);
        cleanupExpired();
        for(SessionData *cur=_firstData; cur; cur=cur->_next){
            if(cur->_sid==sessionid)
                return cur;
        }
    }

    // Not found locally — fetch from cluster peers by SID
    if (g_Cluster && g_Cluster->isRunning()) {
        uuid::uuid sid, uid, did;
        std::vector<uuid::uuid> members;
        std::string username;
        if (g_Cluster->fetchSessionBySid(sessionid, sid, uid, did, members, username)) {
            SessionData *imported = new SessionData(sid, uid, did, members);
            imported->_username = username;

            std::lock_guard<std::mutex> guard(_SessionLock);
            if (!_firstData) {
                _firstData = imported;
                _lastData = _firstData;
            } else {
                _lastData->_next = imported;
                _lastData = _lastData->_next;
            }
            return imported;
        }
    }

    // Not found locally — check cluster peers
    // We can't query by session ID directly since cluster stores by uid+did,
    // so if not found locally, the session must be resolved through login flow
    return nullptr;
}