Commit 2b8d931b authored by jan.koester's avatar jan.koester
Browse files

test

parent 8b8f1a1b
Loading
Loading
Loading
Loading
Loading
+23 −11
Changes for src/api.cpp: 23 added lines, 11 removed lines.
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@
#include "authdb.h"
#include "backend.h"
#include "api.h"
#include "index.h"
#include "user.h"
#include "client.h"
#include "gpo.h"
@@ -279,19 +280,24 @@ public:
                _SessionData = nullptr;

                class User user;
                std::vector<uuid::uuid> uids;
                user.list(_Backend, uids);

                for (const auto &uid : uids) {
                // O(1) indexed lookup by username instead of O(n) scan
                {
                    AuthBackend::Guard guard(_Backend, AuthBackend::Shared);
                    RecordIndex &idx = _Backend.getIndex();
                    if (!idx.valid() || idx.revision() != _Backend.getRevesion())
                        idx.build(_Backend);

                    uuid::uuid found_uid;
                    if (idx.findByName(DataType::UserData, "username", name, found_uid)) {
                        std::shared_ptr<class UserData> udat =
                        std::make_shared<class UserData>(uid);
                            std::make_shared<class UserData>(found_uid);
                        size_t upos = sizeof(AuthHeader);
                        user.info(_Backend, *udat, upos);

                    if (name == udat->getUsername()) {
                        if (constant_time_eq(pwsalt, udat->getPwHash())) {
                            const SessionData* sdat =
                                AuthSession->addSession(_Backend, _Did.value, uid.value);
                                AuthSession->addSession(_Backend, _Did.value, found_uid.value);

                            json_object* respid = json_object_new_object();
                            ::uuid::uuid sessid;
@@ -329,14 +335,19 @@ public:
                sha512 sha;
                sha.hash(pw, pwsalt);

                std::vector<uuid::uuid> clids;
                AuthClient.list(_Backend, clids);
                for (auto &clid : clids) {
                    class ClientData cdat(clid);
                // O(1) indexed lookup by clientname instead of O(n) scan
                {
                    AuthBackend::Guard guard(_Backend, AuthBackend::Shared);
                    RecordIndex &idx = _Backend.getIndex();
                    if (!idx.valid() || idx.revision() != _Backend.getRevesion())
                        idx.build(_Backend);

                    uuid::uuid found_clid;
                    if (idx.findByName(DataType::ClientData, "clientname", name, found_clid)) {
                        class ClientData cdat(found_clid);
                        size_t upos = sizeof(AuthHeader);
                        AuthClient.info(_Backend, cdat, upos);

                    if (name == cdat.getName()) {
                        if (constant_time_eq(pwsalt, cdat.getKey())) {
                            ClientConnections* cid = AuthClient.addConnection(_Backend, cdat);
                            json_object* respid = json_object_new_object();
@@ -351,6 +362,7 @@ public:
                }
                }
            }
        }
        return nullptr;
    }

+5 −21
Changes for src/backend.cpp: 5 added lines, 21 removed lines.
Original line number Diff line number Diff line
@@ -71,42 +71,26 @@ void authdb::AuthBackend::write(const unsigned char* dest, size_t destsize){
}

void authdb::AuthBackend::lock(){
    auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(5);
    for(;;){
        int expected = 0;
        if(_Lock.compare_exchange_weak(expected, -1))
            break;
        if(std::chrono::steady_clock::now() >= deadline)
            throw AuthBackendError("backend lock timeout");
        std::this_thread::yield();
    }
    _Lock.lock();
    try {
        _Api->lock();
    } catch (...) {
        _Lock.store(0);
        _Lock.unlock();
        throw;
    }
}

void authdb::AuthBackend::unlock(){
    _Api->unlock();
    _Lock.store(0);
    _Lock.unlock();
}

void authdb::AuthBackend::lock_shared(){
    auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(5);
    for(;;){
        int cur = _Lock.load();
        if(cur >= 0 && _Lock.compare_exchange_weak(cur, cur + 1))
            break;
        if(std::chrono::steady_clock::now() >= deadline)
            throw AuthBackendError("backend shared lock timeout");
        std::this_thread::yield();
    }
    _Lock.lock_shared();
}

void authdb::AuthBackend::unlock_shared(){
    _Lock.fetch_sub(1);
    _Lock.unlock_shared();
}

void authdb::AuthBackend::setPos(size_t pos){
+2 −1
Changes for src/backend.h: 2 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@

#include <stdexcept>
#include <mutex>
#include <shared_mutex>
#include <atomic>

#pragma once
@@ -143,6 +144,6 @@ namespace authdb{
        AuthBackendApi                *_Api;
        const std::string              _Options;
        const std::string              _Domain;
        std::atomic<int>               _Lock{0}; // 0=unlocked, -1=exclusive, >0=shared count
        std::shared_mutex              _Lock;
    };
};
+11 −12
Changes for src/client.cpp: 11 added lines, 12 removed lines.
Original line number Diff line number Diff line
@@ -218,18 +218,23 @@ authdb::ClientConnections *authdb::Client::addConnection(AuthBackend &backend,co

    ncid.generate();

    ClientConnections *conn;
    if(_firstConnection){
        _lastConnection->_next=new ClientConnections(ncid,backend,data);
        _lastConnection=_lastConnection->_next;
        conn = _lastConnection;
    }else{
        _firstConnection=new ClientConnections(ncid,backend,data);
        _lastConnection=_firstConnection;
        conn = _firstConnection;
    }
    return _lastConnection;
    _connectionIndex[ncid] = conn;
    return conn;
}

void authdb::Client::delConnection(const uuid::uuid &conid){
    std::lock_guard<std::mutex> guard(_lockConnection);
    _connectionIndex.erase(conid);
    ClientConnections *prev=nullptr;
    for(ClientConnections *curdat=_firstConnection; curdat; ){
        if(curdat->_sessionId==conid){
@@ -261,6 +266,7 @@ void authdb::Client::cleanupExpiredConnections(){
        auto age=std::chrono::duration_cast<std::chrono::hours>(now - curdat->_created).count();
        if(age >= 24){
            ClientConnections *next=curdat->_next;
            _connectionIndex.erase(curdat->_sessionId);
            if(prev){
                prev->_next=next;
            }else{
@@ -281,21 +287,14 @@ void authdb::Client::cleanupExpiredConnections(){

bool authdb::Client::checkConnection(const uuid::uuid &conid) const{
    std::lock_guard<std::mutex> guard(_lockConnection);
    for(ClientConnections *curdat=_firstConnection; curdat; curdat=curdat->_next){
        if(curdat->_sessionId==conid){
            return true;
        }
    }
    return false;
    return _connectionIndex.count(conid) > 0;
}

authdb::ClientConnections *authdb::Client::findConnection(const uuid::uuid &conid){
    std::lock_guard<std::mutex> guard(_lockConnection);
    for(ClientConnections *curdat=_firstConnection; curdat; curdat=curdat->_next){
        if(curdat->_sessionId==conid){
            return curdat;
        }
    }
    auto it = _connectionIndex.find(conid);
    if (it != _connectionIndex.end())
        return it->second;
    return nullptr;
}

+2 −0
Changes for src/client.h: 2 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@

#include <chrono>
#include <vector>
#include <unordered_map>
#include <uuidp.h>

#include "authdb.h"
@@ -108,5 +109,6 @@ namespace authdb {
    private:
        ClientConnections *_firstConnection;
        ClientConnections *_lastConnection;
        std::unordered_map<uuid::uuid, ClientConnections*> _connectionIndex;
    };
};
Loading