Newer
Older
/*******************************************************************************
* 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.
*******************************************************************************/
class AuthDB : public libhttppp::HttpEvent{
public:
AuthDB(authdb::AuthBackend &backend,netplus::socket *ssock) : HttpEvent(ssock), _AdminBackend(backend){
_Indexpage.loadFile(_IndexElement,"../data/index.html");
std::ifstream authfs("../data/authdb.js", std::ios::ate);
size_t asize = authfs.tellg();
_AuthJs.resize(asize);
authfs.seekg(0);
authfs.read(_AuthJs.data(),asize);
void listUsers(libhttppp::HttpRequest *curreq, const int tid, ULONG_PTR args,const char *baseurl){
size_t rd=sizeof(authdb::AuthHeader),end=_AdminBackend.end();
libhtmlpp::HtmlElement *content=root.getElementbyID("content"),*domel=nullptr;
domel=DomainChangeForm(curreq,baseurl,_AdminBackend,ddat);
if(!domel)
return;
content->appendChild(domel);
userlist <<"<div><p>UserList:</p><table class=\"userlist\">";
_AdminBackend.setPos(rd);
_AdminBackend.read((unsigned char*)&cur,sizeof(AuthData::Record));
if(cur.type == UserData && strcmp(cur.fieldname,"username")==0){
class UserData udat(cur.uuid);
char cruid[20];
uuid_unparse(cur.uuid,cruid);
userlist << "<tr><td class=\"list_username\">"
<< udat.getUsername()
<< "</td></tr>"
<< "<tr><td><img class=\"list_picture\" style=\"height:100px;\" src=\"/admin/getavatar/" << cruid << ".jpg\" alt=\"avatar\">"
<< "</li>"
<< "<li><span>Firstname:</span><span>" << udat.getFirstname() << "</span></li>"
<< "<li><span>Lastname:</span><span>" << udat.getLastname() << "</span></li>"
<< "<li><span>Email:</span><span>" << udat.getMail() << "</span></li>"
<< "</ul></td><td><ul class=\"usertoolbar\" >"
<< "<li><a class=\"button\" href=\"/admin/edituser/" << cruid << "\">EditUser</a></li>"
<< "<li><a class=\"button\" href=\"/admin/removeuser/" << cruid << "\">RemoveUser</a></li>"
<< "</ul></td></tr>";
}catch(AuthBackendError &e){
std::cerr << e.what() << std::endl;
userlist << "</table></div><div><ul class=\"usertoolbar\" ><li><a class=\"button\" href=\"/admin/createuser\">CreateUser</a></li></ul></div>";
rep.setContentType("text/html");
rep.send(curreq,out.c_str(),out.size());
void createUser(libhttppp::HttpRequest *curreq, const int tid, ULONG_PTR args,const char *baseurl){
libhttppp::HttpResponse rep;
libhttppp::HttpForm curform;
curform.parse(curreq);
char cdid[255];
if(sscanf(curreq->getRequestURL()+strlen(baseurl),"/%s[^/]",cdid)<0)
cdid[0]='\0';
if (curform.getBoundary()) {
uuid_t uid;
uuid_generate(uid);
for (libhttppp::HttpForm::MultipartForm::Data* curformdat = curform.MultipartFormData.getFormData();
curformdat; curformdat = curformdat->nextData()) {
if(curformdat->Value.empty())
continue;
std::string name;
int stortype=TextStorage;
for(libhttppp::HttpForm::MultipartForm::Data::ContentDisposition *curdispo=curformdat->getDisposition();
curdispo; curdispo=curdispo->nextContentDisposition()
){
std::string tmp=curdispo->getKey();
std::transform(tmp.begin(), tmp.end(), tmp.begin(),
[](unsigned char c){ return std::tolower(c); });
if(tmp=="name")
name=curdispo->getValue();
if(tmp=="filename"){
stortype=BinaryStorage;
}
if(name.empty() || stortype == EmptyStorage)
continue;
struct AuthData::Record cudat;
memset(&cudat,0,sizeof(AuthData::Record));
cudat.start=0xFE;
uuid_copy(cudat.uuid,uid);
cudat.type=UserData;
cudat.storage=stortype;
strcpy(cudat.fieldname,name.c_str());
if(cudat.storage==BinaryStorage){
cudat.datasize=curformdat->Value.size();
cudat.data=new char[cudat.datasize];
memcpy(cudat.data,curformdat->Value.data(),
cudat.datasize);
}else{
if(strcmp(cudat.fieldname,"pwhash")==0){
Hash hash;
std::string pwhash,inpw;
std::copy(curformdat->Value.begin(),curformdat->Value.end(),
std::back_inserter(inpw));
hash.hash(inpw,pwhash);
cudat.datasize=pwhash.length()+1;
cudat.data=new char[cudat.datasize];
memcpy(cudat.data,pwhash.c_str(),pwhash.length());
cudat.data[pwhash.length()]='\0';
}else{
cudat.datasize=curformdat->Value.size()+1;
cudat.data=new char[cudat.datasize];
memcpy(cudat.data,curformdat->Value.data(),
curformdat->Value.size());
cudat.data[curformdat->Value.size()]='\0';
}
}
udat.Data->append(cudat);
delete[] cudat.data;
}
libhtmlpp::HtmlString form,out;
form << "<form method=\"post\" enctype=\"multipart/form-data\">"
<< "<table>"
<< "<tr><td><label for=\"username\">username:</label></td>"
<< "<td><input type=\"text\" name=\"username\"></td></tr>"
<< "<tr><td><label for=\"firstname\">firstname:</label></td>"
<< "<td><input type=\"text\" name=\"firstname\"></td></tr>"
<< "<tr><td><label for=\"lastname\">lastname:</label></td>"
<< "<td><input type=\"text\" name=\"lastname\"></td></tr>"
<< "<tr><td><label for=\"mail\">mail:</label></td>"
<< "<td><input type=\"text\" name=\"mail\"></td></tr>"
<< "<tr><td><label for=\"pwhash\">password:</label></td>"
<< "<td><input type=\"text\" name=\"pwhash\"></td></tr>"
<< "<tr><td><label for=\"avatar\">ProfilBild:</label></td>"
<< "<td><input type=\"file\" name=\"avatar\"></td></tr>"
<< "<tr><td></td><td><input type=\"submit\"></td></tr>"
<< "</table>"
<< "</form";
libhtmlpp::HtmlElement *content=root.getElementbyID("content");
content->insertChild(form.parse());
libhtmlpp::print(&root,out,true);
rep.setContentType("text/html");
rep.setContentLength(out.size());
rep.send(curreq,out.c_str(),out.size());
}
void removeuser(libhttppp::HttpRequest *curreq, const int tid, ULONG_PTR args){
char uid[255];
sscanf(curreq->getRequestURL(),"/admin/removeuser/%s",uid);
User user;
uuid_t uuid;
uuid_parse(uid,uuid);
libhttppp::HttpResponse rep;
rep.setState(HTTP307);
rep.setVersion(HTTPVERSION(1.1));
rep.setHeaderData("Location")->push_back("/admin/listusers");
rep.setContentType("text/html");
rep.send(curreq,nullptr,0);
void getAvatar(libhttppp::HttpRequest *curreq, const int tid, ULONG_PTR args){
libhttppp::HttpResponse rep;
AuthBackend *backend;
char domain[255],cuid[255],ext[16];
if(sscanf(curreq->getRequestURL(),"/%[^/]/getavatar/%[^.].%s",domain,cuid,ext)<0)
return;
if( strcmp(domain,"admin")==0 ){
backend=&_AdminBackend;
}else{
return;
}
size_t rd=sizeof(authdb::AuthHeader),end=backend->end();
backend->setPos(rd);
backend->read((unsigned char*)&cur,sizeof(AuthData::Record));
rd=backend->getPos()+cur.datasize;
if(uuid_compare(cur.uuid,uid)==0 && strcmp(cur.fieldname,"avatar")==0){
cur.data = new char[cur.datasize];
backend->read((unsigned char*)cur.data,cur.datasize);
char ctype[255];
snprintf(ctype,255,"image/%s",ext);
rep.setContentType(ctype);
}
}
if(end!=0){
rep.setState(HTTP404);
rep.send(curreq,nullptr,0);
}
};
void editUser(libhttppp::HttpRequest *curreq, const int tid, ULONG_PTR args){
size_t rd=sizeof(authdb::AuthHeader),end=_AdminBackend.end();
char cuid[255];
sscanf(curreq->getRequestURL(),"/admin/edituser/%s",cuid);
uuid_t uid;
uuid_parse(cuid,uid);
AuthData editrec(uid);
bool data = false;
libhttppp::HttpForm curform;
curform.parse(curreq);
for (libhttppp::HttpForm::MultipartForm::Data* curformdat = curform.MultipartFormData.getFormData();
curformdat; curformdat = curformdat->nextData()) {
for(libhttppp::HttpForm::MultipartForm::Data::ContentDisposition *curdispo=curformdat->getDisposition();
curdispo; curdispo=curdispo->nextContentDisposition()
){
if(curformdat->Value.empty() || !curdispo->getValue())
continue;
data = true;
curec.Data->type=UserData;
curec.Data->storage=TextStorage;
for(libhttppp::HttpForm::MultipartForm::Data::ContentDisposition *curdispo=curformdat->getDisposition();
curdispo; curdispo=curdispo->nextContentDisposition()
){
std::string key;
if(curdispo->getKey())
key=curdispo->getKey();
std::transform(key.begin(), key.end(), key.begin(),
[](unsigned char c){ return std::tolower(c); });
if(key=="name"){
if(curec.Data->storage==TextStorage &&
strcmp(curec.Data->fieldname,"pwhash")==0){
Hash hash;
std::string pwhash,inpw;
std::copy(curformdat->Value.begin(),curformdat->Value.end(),
std::back_inserter(inpw));
hash.hash(inpw,pwhash);
curec.Data->datasize=pwhash.length()+1;
curec.Data->data=new char[curec.Data->datasize];
memcpy(curec.Data->data,pwhash.c_str(),pwhash.length());
curec.Data->data[pwhash.length()]='\0';
}else{
curec.Data->datasize=curformdat->Value.size()+1;
curec.Data->data=new char[curec.Data->datasize];
memcpy(curec.Data->data,curformdat->Value.data(),
curformdat->Value.size());
curec.Data->data[curformdat->Value.size()]='\0';
}
libhttppp::HttpResponse rep;
rep.setState(HTTP307);
rep.setVersion(HTTPVERSION(1.1));
rep.setHeaderData("Location")->push_back("/admin/listusers");
rep.setContentType("text/html");
rep.send(curreq,nullptr,0);
return;
}
libhtmlpp::HtmlPage page;
libhtmlpp::HtmlString form,out;
form << "<form method=\"post\" enctype=\"multipart/form-data\">"
<< "<table>";
while(rd<end){
_AdminBackend.setPos(rd);
_AdminBackend.read((unsigned char*)&cur,sizeof(AuthData::Record));
rd=_AdminBackend.getPos()+cur.datasize;
if(uuid_compare(cur.uuid,uid)==0 && cur.type==UserData && cur.storage==TextStorage){
cur.data = new char[cur.datasize];
_AdminBackend.read((unsigned char*)cur.data,cur.datasize);
form << "<tr><td><label for=\"username\">" << cur.fieldname << "</label></td>"
<< "<td><input type=\"text\" name=\"" << cur.fieldname << "\" value=\""
<< cur.data <<"\"></td></tr>";
}catch(AuthBackendError &e){
std::cerr << e.what() << std::endl;
}
}
}
form << "<tr><td><label for=\"avatar\">ProfilBild:</label></td>"
<< "<td><input type=\"file\" name=\"avatar\"></td></tr>"
<< "<tr><td></td><td><input type=\"submit\"></td></tr>"
<< "</table>"
<< "</form";
libhtmlpp::HtmlElement root=_IndexElement;
libhtmlpp::HtmlElement *content=root.getElementbyID("content");
content->insertChild(form.parse());
libhtmlpp::print(&root,out,true);
libhttppp::HttpResponse rep;
rep.setContentType("text/html");
rep.setContentLength(out.size());
rep.send(curreq,out.c_str(),out.size());
}
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
libhtmlpp::HtmlElement *DomainChangeForm(libhttppp::HttpRequest *curreq,const char *baseurl,
AuthBackend &backend,libhtmlpp::HtmlString &dest){
libhttppp::HttpForm form;
form.parse(curreq);
char cdid[255];
if(sscanf(curreq->getRequestURL()+strlen(baseurl),"/%s[^/]",cdid)<0)
cdid[0]='\0';
for (libhttppp::HttpForm::UrlcodedForm::Data* cururlform = form.UrlFormData.getFormData(); cururlform;
cururlform = cururlform->nextData()) {
if( strcmp(cururlform->getKey(),"domaindid")==0){
if(strcmp(cdid,cururlform->getValue())!=0){
char rurl[255];
snprintf(rurl,255,"%s/%s",baseurl,cururlform->getValue());
libhttppp::HttpResponse rep;
rep.setState(HTTP307);
rep.setVersion(HTTPVERSION(1.1));
rep.setHeaderData("Location")->push_back(rurl);
rep.setContentType("text/html");
rep.send(curreq,nullptr,0);
return nullptr;
}
}
}
size_t rd=sizeof(authdb::AuthHeader),end=backend.end();
Domain domain;
dest.clear();
dest << "<form method=\"post\" ><select name=\"domaindid\" onchange=\"this.form.submit()\">";
dest << "<option value=\"\" >admin.local</option>";
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 == DataType::DomainData && strcmp(cur.fieldname,"domainName")==0){
size_t dpos=sizeof(authdb::AuthHeader);
cur.data = new char[cur.datasize];
backend.read((unsigned char*)cur.data,cur.datasize);
char did[255];
uuid_unparse(cur.uuid,did);
dest << "<option value=\"" << did << "\" ";
if ( strcmp(cdid,did)==0 ){
dest << "selected";
}
dest << ">"
<< cur.data << "</option>";
delete [] cur.data;
}
}
dest << "</select></form>";
return (libhtmlpp::HtmlElement*)dest.parse();
}
void listDomains(libhttppp::HttpRequest *curreq, const int tid, ULONG_PTR args){
size_t rd=sizeof(authdb::AuthHeader),end=_AdminBackend.end();
libhtmlpp::HtmlString list,out;
libhtmlpp::HtmlElement root=_IndexElement;
libhtmlpp::HtmlElement *content=root.getElementbyID("content");
Domain domain;
list <<"<div><p>DomainList:</p><table class=\"domainlist\">";
while(rd<end){
authdb::AuthData::Record cur;
cur.type=EmptyData;
_AdminBackend.setPos(rd);
_AdminBackend.read((unsigned char*)&cur,sizeof(AuthData::Record));
if(cur.type == DataType::DomainData && strcmp(cur.fieldname,"domainName")==0){
class DomainData ddat(cur.uuid);
try {
size_t dpos=sizeof(authdb::AuthHeader);
char crdid[20];
uuid_unparse(cur.uuid,crdid);
list << "<tr><td>"
<< ddat.getDomainName()
<< "</td><td><ul><li>"
<< "Domainid: " << crdid
<< "</li>"
<< "<li><span>Storagetype: </span><span>" << ddat.getStorageType() << "</span></li>"
<< "<li><span>Storageoptions: </span><span>" << ddat.getStorageOptions() << "</span></li>"
<< "</ul></td><td><ul class=\"usertoolbar\" >"
<< "<li><a class=\"button\" href=\"/admin/removedomain/" << crdid << "\">RemoveDomain</a></li>"
<< "</ul></td></tr>";
}catch(AuthBackendError &e){
std::cerr << e.what() << std::endl;
}
}
}
<< "<li><a class=\"button\" href=\"/admin/createdomain\">CreateDomain</a>"
<< "</li></ul></div>";
libhtmlpp::print(&root,out,true);
libhttppp::HttpResponse rep;
rep.setContentType("text/html");
rep.setContentLength(out.size());
rep.send(curreq,out.c_str(),out.size());
}
void createDomain(libhttppp::HttpRequest *curreq, const int tid, ULONG_PTR args){
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
libhttppp::HttpForm curform;
curform.parse(curreq);
if (curform.getBoundary()) {
uuid_t uid;
uuid_generate(uid);
class DomainData ddat(uid);
for (libhttppp::HttpForm::MultipartForm::Data* curformdat = curform.MultipartFormData.getFormData();
curformdat; curformdat = curformdat->nextData()) {
if(curformdat->Value.empty())
continue;
std::string name;
int stortype=TextStorage;
for(libhttppp::HttpForm::MultipartForm::Data::ContentDisposition *curdispo=curformdat->getDisposition();
curdispo; curdispo=curdispo->nextContentDisposition()
){
std::string tmp=curdispo->getKey();
std::transform(tmp.begin(), tmp.end(), tmp.begin(),
[](unsigned char c){ return std::tolower(c); });
if(tmp=="name")
name=curdispo->getValue();
if(tmp=="filename"){
stortype=BinaryStorage;
for(auto t=curformdat->Value.begin(); t!=curformdat->Value.end();
++t){
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
if(!std::isdigit(*t)){
numeric=false;
break;
}
}
if(numeric){
stortype=StorageType::IntStorage;
}
}
if(name.empty() || stortype == EmptyStorage)
continue;
struct AuthData::Record dodat;
memset(&dodat,0,sizeof(AuthData::Record));
dodat.start=0xFE;
uuid_copy(dodat.uuid,uid);
dodat.type=UserData;
dodat.storage=stortype;
strcpy(dodat.fieldname,name.c_str());
if(dodat.storage==TextStorage){
dodat.datasize=curformdat->Value.size()+1;
dodat.data=new char[dodat.datasize];
memcpy(dodat.data,curformdat->Value.data(),
curformdat->Value.size());
dodat.data[curformdat->Value.size()]='\0';
}else if(dodat.storage==IntStorage){
dodat.datasize=sizeof(int);
dodat.data=(char*)new int;
int val=0;
std::copy(curformdat->Value.begin(),curformdat->Value.end(),&val);
}else {
dodat.datasize=curformdat->Value.size();
dodat.data=new char[dodat.datasize];
memcpy(dodat.data,curformdat->Value.data(),
dodat.datasize);
libhtmlpp::HtmlString form,out;
libhtmlpp::HtmlElement root=_IndexElement;
libhtmlpp::HtmlElement *content=root.getElementbyID("content");
form << "<form method=\"post\" enctype=\"multipart/form-data\">"
<< "<table>"
<< "<tr><td><label for=\"domainName\">Domain Name:</label></td>"
<< "<td><input class=\"domaintext\" type=\"text\" name=\"domainName\" value=\"tuxist.de\"></td></tr>"
<< "<tr><td><label for=\"domainStorage\">Domain Storage:</label></td>"
<< "<td><select name=\"domainStorage\">"
<< "<tr><td><label for=\"domainOptions\">Domain Options:</label></td>"
<< "<td><input class=\"domaintext\" type=\"text\" name=\"domainOptions\" value=\"/var/lib/authdb/tuxist.de.db\"></td></tr>"
<< "<tr><td></td><td><input type=\"submit\" value=\"save\" ></td></tr>"
<< "</table>";
content->insertChild(form.parse());
libhtmlpp::print(&root,out,true);
libhttppp::HttpResponse rep;
rep.setContentType("text/html");
rep.setContentLength(out.size());
rep.send(curreq,out.c_str(),out.size());
}
void removeDomain(libhttppp::HttpRequest *curreq, const int tid, ULONG_PTR args){
char uid[255];
sscanf(curreq->getRequestURL(),"/admin/removedomain/%s",uid);
Domain domain;
uuid_t uuid;
uuid_parse(uid,uuid);
libhttppp::HttpResponse rep;
rep.setState(HTTP307);
rep.setVersion(HTTPVERSION(1.1));
rep.setHeaderData("Location")->push_back("/admin/listdomains");
rep.setContentType("text/html");
rep.send(curreq,nullptr,0);
}
void AdminController(libhttppp::HttpRequest *curreq, const int tid, ULONG_PTR args){
_AdminBackend.lock();
char domain[255],url[255];
if(sscanf(curreq->getRequestURL(),"/%[^/]/%s",domain,url)<0)
throw AuthBackendError("wrong url!");
if(strncmp(url,"listusers",9)==0){
listUsers(curreq,tid,args,"/admin/listusers");
}else if(strncmp(url,"createuser",9)==0){
createUser(curreq,tid,args,"/admin/createuser");
}else if(strncmp(url,"removeuser",9)==0){
libhttppp::HttpResponse rep;
rep.setContentType("text/javascript");
rep.send(curreq,_AuthJs.data(),_AuthJs.size());
}else{
libhtmlpp::HtmlElement root=_IndexElement;
libhtmlpp::HtmlString out;
libhtmlpp::print(&root,out,true);
libhttppp::HttpResponse rep;
rep.setContentType("text/html");
rep.setContentLength(out.size());
rep.send(curreq,out.c_str(),out.size());
}
}catch(AuthBackendError &e){
libhttppp::HttpResponse rep;
rep.setState(HTTP500);
rep.setContentType("text/html");
rep.send(curreq,e.what(),strlen(e.what()));
}
void RequestEvent(libhttppp::HttpRequest *curreq, const int tid, ULONG_PTR args){
if(strncmp(curreq->getRequestURL(),"/admin",6)==0){
AdminController(curreq,tid,args);
}else if(strncmp(curreq->getRequestURL(),"/api",4)==0){
}else{
libhttppp::HttpResponse rep;
rep.setState(HTTP307);
rep.setVersion(HTTPVERSION(1.1));
rep.setHeaderData("Location")->push_back("/admin/index");
libhtmlpp::HtmlElement _IndexElement;
libhtmlpp::HtmlPage _Indexpage;
};
int searchValue(authdb::AuthBackend &backend,const char*fieldname,const char *value){
int rd=sizeof(authdb::AuthHeader),brd=rd;
while(rd>backend.end()){
backend.setPos(rd);
backend.read((unsigned char*)user,sizeof(AuthData::Record));
user->data = new char[user->datasize];
backend.read((unsigned char*)user->data,user->datasize);
Data->storage=EmptyStorage;
uuid_copy(Data->uuid,id);
AuthData::AuthData(const AuthData &src){
Data = new AuthData::Record;
AuthData *dest=this;
for(const AuthData *cursrc=&src; cursrc; cursrc=cursrc->next()){
memcpy(dest->Data,cursrc->Data,sizeof(AuthData::Record));
Data->data=new char[cursrc->Data->datasize];
memcpy(dest->Data->data,cursrc->Data->data,cursrc->Data->datasize);
if(cursrc->next()){
dest->_next=new AuthData(this->Data->uuid);
dest=dest->_next;
}
}
AuthData *AuthData::append(const AuthData &src){
AuthData *curec=this;
curec=curec->_next;
break;
}
curec=curec->_next;
for(const AuthData *cuxrcrec=&src; cuxrcrec; cuxrcrec=cuxrcrec->next()){
memcpy(curec->Data,cuxrcrec->Data,sizeof(AuthData::Record));
curec->Data->data=new char[curec->Data->datasize];
memcpy(curec->Data->data,cuxrcrec->Data->data,curec->Data->datasize);
curec->_next=nullptr;
if(cuxrcrec->next()){
curec->_next=new AuthData(src.Data->uuid);
}
return curec;
}
AuthData *AuthData::append(const AuthData::Record &src){
AuthData *curec=this;
curec=curec->_next;
break;
}
curec=curec->_next;
memcpy(curec->Data,&src,sizeof(AuthData::Record));
curec->Data->data=new char[curec->Data->datasize];
memcpy(curec->Data->data,src.data,curec->Data->datasize);
bool getRecord(authdb::AuthBackend &backend,AuthData &rec,int type){
bool found=false;
int rd=sizeof(authdb::AuthHeader),end=backend.end();
AuthData::Record cur;
memset(&cur,0,sizeof(AuthData::Record));
backend.setPos(rd);
backend.read((unsigned char*)&cur,sizeof(AuthData::Record));
rd=backend.getPos()+cur.datasize;
if(uuid_compare(cur.uuid,rec.Data->uuid) == 0 && cur.type == type){
cur.data=new char[cur.datasize];
backend.read((unsigned char*)cur.data,cur.datasize);
rec.append(cur);
delete[] cur.data;
bool editRecord(AuthBackend &backend,AuthData &rec,int type){
AuthData old(rec.Data->uuid);
std::vector<AuthData::Record*> changemap; //use fieldname;
std::vector<AuthData::Record*> newmap;
for(const AuthData *curdat=&rec; curdat; curdat=curdat->_next){
for(const AuthData *olddat=&old; olddat; olddat=olddat->_next){
if(uuid_compare(olddat->Data->uuid,curdat->Data->uuid)==0
&& strcmp(olddat->Data->fieldname,curdat->Data->fieldname)==0
){
size_t end = olddat->Data->datasize;
if(end!=curdat->Data->datasize){
changemap.push_back(curdat->Data);
}else{
for(size_t i=0; i<end; ++i){
if(olddat->Data->data[i]!=curdat->Data->data[i]){
changemap.push_back(curdat->Data);
break;
}
}
}
newentry=false;
}
}
if(newentry){
newmap.push_back(curdat->Data);
}
}
for(auto newel : newmap){
backend.setPos(backend.end());
backend.write((unsigned char*)newel,sizeof(AuthData::Record));;
backend.write((unsigned char*)newel->data,newel->datasize);
}
const unsigned char zero = 0;
for(auto chel : changemap){
size_t rd=sizeof(authdb::AuthHeader),end=backend.end();
while(rd<end){
authdb::AuthData::Record *rdrec=new AuthData::Record;
backend.setPos(rd);
backend.read((unsigned char*)rdrec,sizeof(AuthData::Record));
if(uuid_compare(rdrec->uuid,rec.Data->uuid)==0 && strcmp(rdrec->fieldname,chel->fieldname)==0){
backend.setPos(backend.end());
backend.write((const unsigned char*)chel,sizeof(AuthData::Record));
backend.write((const unsigned char*)chel->data,chel->datasize);
size_t dsize=rdrec->datasize;
backend.setPos(rd);
backend.write((const unsigned char*)rdrec,sizeof(AuthData::Record));
for(size_t i =0; i<rdrec->datasize; ++i){
backend.write(&zero,1);
}
rd=backend.getPos();
}else{
rd=backend.getPos()+rdrec->datasize;