Skip to content
session.cpp 6.75 KiB
Newer Older
/*******************************************************************************
 * Copyright (c) 2025, Jan Koester jan.koester@gmx.net
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 * Neither the name of the <organization> nor the
 *      names of its contributors may be used to endorse or promote products
 *      derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *******************************************************************************/

jan.koester's avatar
jan.koester committed
#include <cstring>

#include "session.h"
jan.koester's avatar
jan.koester committed
#include "backend.h"
#include "group.h"
#include "types.h"
jan.koester's avatar
jan.koester committed
#include "authdb.h"
jan.koester's avatar
jan.koester committed
#include "uuid.h"
jan.koester's avatar
jan.koester committed

jan.koester's avatar
jan.koester committed
authdb::SessionData::SessionData(uuid_t sessionid, uuid_t userid, uuid_t domainid,std::vector<uuid> &members){
jan.koester's avatar
jan.koester committed
    uuid_copy(_sid,sessionid);
    uuid_copy(_uid,userid);
    uuid_copy(_did,domainid);

jan.koester's avatar
jan.koester committed
    _members=members;;
jan.koester's avatar
jan.koester committed
    _next=nullptr;
}

authdb::SessionData::~SessionData(){
}

jan.koester's avatar
jan.koester committed
void authdb::SessionData::getUid(uuid_t& dest) const{
jan.koester's avatar
jan.koester committed
    uuid_copy(dest,_uid);
}

jan.koester's avatar
jan.koester committed
void authdb::SessionData::getSid(uuid_t& dest) const{
jan.koester's avatar
jan.koester committed
    uuid_copy(dest,_sid);
}

jan.koester's avatar
jan.koester committed
void authdb::SessionData::getDid(uuid_t& dest) const{
    uuid_copy(dest,_did);
}
jan.koester's avatar
jan.koester committed

jan.koester's avatar
jan.koester committed
const char * authdb::SessionData::getUsername() const{
    return _username.c_str();
}


jan.koester's avatar
jan.koester committed
bool authdb::SessionData::isMemberOf(const uuid_t& gid){
jan.koester's avatar
jan.koester committed
    for(auto member : _members){
        if(member==gid)
jan.koester's avatar
jan.koester committed
            return true;
    }
    return false;
}

jan.koester's avatar
jan.koester committed
const authdb::SessionData * authdb::SessionData::next() const{
jan.koester's avatar
jan.koester committed
    return _next.get();
jan.koester's avatar
jan.koester committed
}

jan.koester's avatar
jan.koester committed


authdb::Session::Session(){
    _firstData=nullptr;
    _lastData=nullptr;
}

authdb::Session::~Session(){
}

jan.koester's avatar
jan.koester committed
const authdb::SessionData * authdb::Session::addSession(AuthBackend &backend,uuid_t domainid,uuid_t userid){
jan.koester's avatar
jan.koester committed
    Group group;
jan.koester's avatar
jan.koester committed
    std::string username;

jan.koester's avatar
jan.koester committed
    size_t rd=sizeof(authdb::AuthHeader),end=backend.end();
    while(rd<end){
        authdb::AuthData::Record cur;

        cur.type=EmptyData;

        backend.setPos(rd);
        backend.read((unsigned char*)&cur,sizeof(AuthData::Record));

        rd=backend.getPos()+cur.datasize;

jan.koester's avatar
jan.koester committed
        if(cur.type == UserData && strcmp(cur.fieldname,"username")==0
            && uuid_compare(cur.uuid,userid)==0){

            char *tmp=new char[cur.datasize];
jan.koester's avatar
jan.koester committed
            backend.read((unsigned char*)tmp,cur.datasize);
jan.koester's avatar
jan.koester committed
            username=tmp;
            delete[] tmp;
        }
jan.koester's avatar
jan.koester committed
    }

    size_t count=0;

jan.koester's avatar
jan.koester committed
    std::vector<uuid> mbs;

    size_t mbs_pos=0;

jan.koester's avatar
jan.koester committed
    while(rd<end){
        authdb::AuthData::Record cur;

        cur.type=EmptyData;

        backend.setPos(rd);
        backend.read((unsigned char*)&cur,sizeof(AuthData::Record));

        rd=backend.getPos()+cur.datasize;

        if(cur.type == GroupData && strcmp(cur.fieldname,"groupname")==0){
            class GroupData grpi(cur.uuid);
            size_t upos=sizeof(authdb::AuthHeader);
            group.info(backend,grpi,upos);
jan.koester's avatar
jan.koester committed
            if(grpi.isMember(cur.uuid)){
                mbs.push_back(uuid(cur.uuid));
            }
jan.koester's avatar
jan.koester committed
    uuid_t sid;
    uuid_generate(sid);

jan.koester's avatar
jan.koester committed
    if(!_firstData){
jan.koester's avatar
jan.koester committed
        _firstData=std::shared_ptr<SessionData>(new SessionData(sid,userid,domainid,mbs));
jan.koester's avatar
jan.koester committed
        _lastData=_firstData;
    }else{
jan.koester's avatar
jan.koester committed
        _lastData->_next=std::shared_ptr<SessionData>(new SessionData(sid,userid,domainid,mbs));
jan.koester's avatar
jan.koester committed
        _lastData=_lastData->_next;
    }

jan.koester's avatar
jan.koester committed
    _lastData->_username=username;

jan.koester's avatar
jan.koester committed
    return _lastData.get();
jan.koester's avatar
jan.koester committed
}

jan.koester's avatar
jan.koester committed
const authdb::SessionData * authdb::Session::getSession(uuid_t sessionid) const{
    for(const SessionData *cur=firstData(); cur; cur=cur->next()){
        if(uuid_compare(cur->_sid,sessionid)==0)
jan.koester's avatar
jan.koester committed
            return cur;
    }
    return nullptr;
jan.koester's avatar
jan.koester committed
}
jan.koester's avatar
jan.koester committed

void authdb::Session::remSession(uuid_t sessionid){
jan.koester's avatar
jan.koester committed
    std::shared_ptr<SessionData> prev;
jan.koester's avatar
jan.koester committed

jan.koester's avatar
jan.koester committed
    for(std::shared_ptr<SessionData> cur=_firstData; cur; cur=cur->_next){
jan.koester's avatar
jan.koester committed
        if(uuid_compare(cur->_sid,sessionid)==0){
jan.koester's avatar
jan.koester committed
            if(prev)
                prev->_next=cur->_next;

            if(cur==_firstData)
                _firstData=cur->_next;

            if(cur==_lastData)
                _lastData=prev;

            cur->_next=nullptr;
jan.koester's avatar
jan.koester committed
            break;
jan.koester's avatar
jan.koester committed
        }
        prev=cur;
    }
}
jan.koester's avatar
jan.koester committed

jan.koester's avatar
jan.koester committed
void authdb::Session::relSession(AuthBackend &backend,uuid_t sessionid){
    Group group;

    std::string username;

jan.koester's avatar
jan.koester committed
    std::shared_ptr<SessionData> cursess=nullptr;
jan.koester's avatar
jan.koester committed

jan.koester's avatar
jan.koester committed
    for(std::shared_ptr<SessionData> cur=_firstData; cur; cur=cur->_next){
jan.koester's avatar
jan.koester committed
        if(uuid_compare(cur->_sid,sessionid)==0){
            cursess=cur;
            break;
        }
    }

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

jan.koester's avatar
jan.koester committed
    cursess->_members.clear();

jan.koester's avatar
jan.koester committed
    size_t rd=sizeof(authdb::AuthHeader),end=backend.end();
    while(rd<end){
        authdb::AuthData::Record cur;

        cur.type=EmptyData;

        backend.setPos(rd);
        backend.read((unsigned char*)&cur,sizeof(AuthData::Record));

        rd=backend.getPos()+cur.datasize;

        if(cur.type == UserData && strcmp(cur.fieldname,"username")==0
            && uuid_compare(cur.uuid,cursess->_uid)==0){

            char *tmp=new char[cur.datasize];
jan.koester's avatar
jan.koester committed
            backend.read(reinterpret_cast<unsigned char*>(tmp),cur.datasize);
jan.koester's avatar
jan.koester committed
            username=tmp;
            delete[] tmp;
        }

        if(cur.type == GroupData && strcmp(cur.fieldname,"groupname")==0){
            class GroupData grpi(cur.uuid);
            size_t upos=sizeof(authdb::AuthHeader);
            group.info(backend,grpi,upos);

            if(grpi.isMember(cursess->_uid))
jan.koester's avatar
jan.koester committed
                cursess->_members.emplace_back(uuid(cursess->_uid));
jan.koester's avatar
jan.koester committed
const authdb::SessionData * authdb::Session::firstData() const{
jan.koester's avatar
jan.koester committed
    return _firstData.get();
jan.koester's avatar
jan.koester committed
}