/******************************************************************************* * 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 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 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. *******************************************************************************/ #include "types.h" #include "user.h" namespace authdb { inline const char *getUserData(const AuthData *dat,AuthData::Record **varclass,const char *varname){ if(*varclass && (*varclass)->data ){ return (*varclass)->data; }else{ for(const AuthData *curdat=dat; curdat; curdat=curdat->next()){ if(curdat->Data && strcmp(curdat->Data->fieldname,varname)==0){ *varclass=curdat->Data; return curdat->Data->data; } } } std::string err; err=varname; err+=" data not found !"; throw(authdb::AuthBackendError(err.c_str())); } inline void setUserData(AuthData *dat,AuthData::Record **varclass,const char *varname,const char *value){ AuthData::Record *target=*varclass; AuthData *curec=dat; uuid_t gid; uuid_copy(gid,dat->Data->uuid); if(!target){ while(curec){ if(curec->Data->type == authdb::UserData && uuid_compare(curec->Data->uuid,dat->Data->uuid)==0 && strcmp(curec->Data->fieldname,varname)==0 ){ target=curec->Data; target->datasize=0; delete[] target->data; target->data=nullptr; break; } curec=curec->next(); } } if(!target){ target=new AuthData::Record; *varclass=dat->append(*target)->Data; target=*varclass; } target->start=0xFE; uuid_copy(target->uuid,gid); target->type=DataType::UserData; target->storage=StorageType::TextStorage; snprintf(target->fieldname,255,"%s",varname); target->datasize=strlen(value)+1; target->data= new char[target->datasize]; strcpy(target->data,value); } }; authdb::UserData::UserData(uuid_t id) : AuthData(id){ username=nullptr; firstname=nullptr; lastname=nullptr; mail=nullptr; pwhash=nullptr; avatar=nullptr; uuid_copy(uid,id); } authdb::UserData::~UserData(){ } void authdb::UserData::setFirstName(const char* src){ setUserData(this,&firstname,"firstname",src); } const char *authdb::UserData::getFirstname(){ return getUserData(this,&firstname,"firstname"); } void authdb::UserData::setLastName(const char* src){ setUserData(this,&lastname,"lastname",src); } const char * authdb::UserData::getLastname(){ return getUserData(this,&lastname,"lastname"); } void authdb::UserData::setMail(const char* src){ setUserData(this,&mail,"mail",src); } const char *authdb::UserData::getMail(){ return getUserData(this,&mail,"mail"); } void authdb::UserData::setPwHash(const char* src){ setUserData(this,&pwhash,"pwhash",src); } const char * authdb::UserData::getPwHash(){ return getUserData(this,&pwhash,"pwhash"); } void authdb::UserData::setUserName(const char* src){ setUserData(this,&username,"username",src); } const char * authdb::UserData::getUsername(){ return getUserData(this,&username,"username"); } void authdb::UserData::setAvatar(const std::vector& src){ AuthData::Record *target=avatar; AuthData *curec=this; uuid_t gid; uuid_copy(gid,Data->uuid); if(!target){ while(curec){ if(curec->Data->type == authdb::UserData && uuid_compare(curec->Data->uuid,uid)==0 && strcmp(curec->Data->fieldname,"avatar")==0 ){ target=curec->Data; target->datasize=0; delete[] target->data; target->data=nullptr; break; } curec=curec->next(); } } if(!target){ AuthData::Record newrec; target=append(newrec)->Data; } target->type=DataType::UserData; target->storage=StorageType::BinaryStorage; uuid_copy(target->uuid,gid); snprintf(target->fieldname,255,"%s","avatar"); target->datasize=src.size(); target->data= new char[target->datasize]; memcpy(target->data,src.data(),target->datasize); avatar=target; } void authdb::UserData::getAvatar(std::vector& dest){ if(avatar && avatar->data) std::copy(avatar->data,avatar->data+avatar->datasize, std::back_inserter(dest)); else throw(authdb::AuthBackendError("Avatar data nout found !")); } void authdb::User::create(AuthBackend &backend,class UserData* dat){ int exi=0; if(exits(backend,&dat->uid,dat->getUsername(),exi)){ switch(exi){ case 1: throw authdb::AuthBackendError("Create User: Username already Exists aborting!"); default: throw authdb::AuthBackendError("Create User: UUID already Exists aborting!"); } } size_t wd=backend.end(); for(AuthData *curec=dat; curec; curec=curec->next()){ curec->Data->type=UserData; backend.setPos(wd); backend.write((unsigned char*)curec->Data,sizeof(struct AuthData::Record)); backend.write((unsigned char*)curec->Data->data,curec->Data->datasize); wd=backend.end(); } } bool authdb::User::exits(AuthBackend& backend, uuid_t* uid, const char* name,int &ret){ authdb::AuthData::Record cur; size_t rd=sizeof(authdb::AuthHeader),end=backend.end(); while(rddatasize; if(cur->type == UserData && uuid_compare(dat.uid,cur->uuid) == 0){ if(!getRecord(backend,dat,DataType::UserData)) continue; if(strcmp(dat.Data->fieldname,"username")==0){ dat.username=dat.Data; }else if(strcmp(dat.Data->fieldname,"firstname")==0){ dat.firstname=dat.Data; }else if(strcmp(dat.Data->fieldname,"lastname")==0){ dat.lastname=dat.Data; }else if(strcmp(dat.Data->fieldname,"mail")==0){ dat.mail=dat.Data; }else if(strcmp(dat.Data->fieldname,"pwhash")==0){ dat.pwhash=dat.Data; }else if(strcmp(dat.Data->fieldname,"avatar")==0){ dat.avatar=dat.Data; } } delete cur; } }