Skip to content
authdb.cpp 54.7 KiB
Newer Older
jan.koester's avatar
jan.koester committed
/*******************************************************************************
jan.koester's avatar
jan.koester committed
 * Copyright (c) 2025, Jan Koester jan.koester@gmx.net
jan.koester's avatar
jan.koester committed
 * 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 <algorithm>
jan.koester's avatar
jan.koester committed
#include <iostream>
jan.koester's avatar
jan.koester committed
#include <cstring>
jan.koester's avatar
jan.koester committed
#include <sstream>
jan.koester's avatar
jan.koester committed
#include <map>
jan.koester's avatar
jan.koester committed
#include <fstream>
jan.koester's avatar
jan.koester committed

jan.koester's avatar
jan.koester committed
#include <uuid/uuid.h>
jan.koester's avatar
jan.koester committed
#include <cmdplus/cmdplus.h>
#include <confplus/conf.h>
jan.koester's avatar
jan.koester committed

jan.koester's avatar
jan.koester committed
#include <httppp/httpd.h>
jan.koester's avatar
jan.koester committed
#include <htmlpp/html.h>
jan.koester's avatar
jan.koester committed

jan.koester's avatar
jan.koester committed
#include "backend.h"
jan.koester's avatar
jan.koester committed
#include "authdb.h"
jan.koester's avatar
jan.koester committed
#include "user.h"
jan.koester's avatar
jan.koester committed
#include "domain.h"
jan.koester's avatar
jan.koester committed
#include "group.h"
jan.koester's avatar
jan.koester committed
#include "types.h"
jan.koester's avatar
jan.koester committed
#include "hash.h"
jan.koester's avatar
jan.koester committed

jan.koester's avatar
jan.koester committed
namespace authdb {
jan.koester's avatar
jan.koester committed

    bool initalized=true;

jan.koester's avatar
jan.koester committed
    class DomainBackend {
    public:
        DomainBackend(authdb::AuthBackend &adminbck) : _adminbck(adminbck) {
            _domainbck=nullptr;
        }

        authdb::AuthBackend *data(uuid_t did){
            size_t rd=sizeof(authdb::AuthHeader),end=_adminbck.end();

            while(rd<end){
                authdb::AuthData::Record cur;

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

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

                if(uuid_compare(cur.uuid,did) == 0 && cur.type == DataType::DomainData &&
                    strcmp(cur.fieldname,"domainName")==0){

                    class DomainData ddat(cur.uuid);

                    size_t dpos=sizeof(authdb::AuthHeader);

                    Domain domain;
                    domain.info(_adminbck,ddat,dpos);

                    _domainbck = new AuthBackend(ddat.getStorageType(),ddat.getStorageOptions(),ddat.getDomainName());
                }
            }
            return _domainbck;
        }

        ~DomainBackend(){
            delete _domainbck;
        }

    private:
        authdb::AuthBackend &_adminbck;
        authdb::AuthBackend *_domainbck;
    };

jan.koester's avatar
jan.koester committed
    class AuthDB : public libhttppp::HttpEvent{
    public:
jan.koester's avatar
jan.koester committed
        AuthDB(authdb::AuthBackend &backend,netplus::socket *ssock) : HttpEvent(ssock), _AdminBackend(backend){
jan.koester's avatar
jan.koester committed
            _Indexpage.loadFile(_IndexElement,"../data/index.html");
jan.koester's avatar
jan.koester committed

            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);

jan.koester's avatar
jan.koester committed
        void listUsers(libhttppp::HttpRequest *curreq, const int tid, ULONG_PTR args,const char *url){
jan.koester's avatar
jan.koester committed
            libhtmlpp::HtmlString userlist,out,ddat;
jan.koester's avatar
jan.koester committed

jan.koester's avatar
jan.koester committed
            libhtmlpp::HtmlElement root=_IndexElement;
jan.koester's avatar
jan.koester committed

jan.koester's avatar
jan.koester committed
            libhtmlpp::HtmlElement *content=root.getElementbyID("content"),*domel=nullptr;
jan.koester's avatar
jan.koester committed

jan.koester's avatar
jan.koester committed
            User user;
jan.koester's avatar
jan.koester committed

jan.koester's avatar
jan.koester committed
            domel=DomainChangeForm(curreq,url,_AdminBackend,ddat);
jan.koester's avatar
jan.koester committed

jan.koester's avatar
jan.koester committed
            if(!domel){
                throw AuthBackendError("listUsers: cannot load doamin's!");
            }

            char cdid[255];
            uuid_t did;

            if(sscanf(curreq->getRequestURL(),"/settings/%[^/]",cdid)<0){
                throw AuthBackendError("listUsers: wrong url!");
            }

            DomainBackend dbackend(_AdminBackend);

            AuthBackend *backend=nullptr;

            if(strcmp(cdid,"admin") == 0 ){
                backend=&_AdminBackend;
            }else if(uuid_parse(cdid,did) == 0 ){
                backend=dbackend.data(did);
            }else{
                throw AuthBackendError("listUsers: could not parse uuid!");
            }

            size_t rd=sizeof(authdb::AuthHeader),end=backend->end();
jan.koester's avatar
jan.koester committed

            content->appendChild(domel);

jan.koester's avatar
jan.koester committed
            userlist <<"<div><p>UserList:</p><table class=\"userlist\">";
jan.koester's avatar
jan.koester committed

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

jan.koester's avatar
jan.koester committed
                backend->setPos(rd);
                backend->read((unsigned char*)&cur,sizeof(AuthData::Record));
jan.koester's avatar
jan.koester committed
                rd=backend->getPos()+cur.datasize;
                if(cur.type == UserData && strcmp(cur.fieldname,"username")==0){
                    class UserData udat(cur.uuid);
jan.koester's avatar
jan.koester committed
                    try {
                        size_t upos=sizeof(authdb::AuthHeader);
jan.koester's avatar
jan.koester committed
                        user.info(*backend,udat,upos);

                        char cruid[20];
                        uuid_unparse(cur.uuid,cruid);
jan.koester's avatar
jan.koester committed
                        userlist << "<tr><td class=\"list_username\">"
                        << udat.getUsername()
                        << "</td></tr>"
jan.koester's avatar
jan.koester committed
                        << "<tr><td><img class=\"list_picture\" style=\"height:100px;\" src=\"" <<"/getavatar/" << cdid << "/" << cruid << ".jpg\" alt=\"avatar\">"
jan.koester's avatar
jan.koester committed
                        << "</td><td><ul><li>"
                        << "uid: " << cruid
jan.koester's avatar
jan.koester committed
                        << "</li>"
                        << "<li><span>Firstname:</span><span>" << udat.getFirstname() << "</span></li>"
jan.koester's avatar
jan.koester committed
                        << "<li><span>Lastname:</span><span>" << udat.getLastname() << "</span></li>"
jan.koester's avatar
jan.koester committed
                        << "<li><span>Email:</span><span>" << udat.getMail() << "</span></li>"
                        << "</ul></td><td><ul class=\"usertoolbar\" >"
jan.koester's avatar
jan.koester committed
                        << "<li><a class=\"button\" href=\"/settings/"<< cdid << "/edituser/" << cruid << "\">EditUser</a></li>"
                        << "<li><a class=\"button\" href=\"/settings/" << cdid << "/removeuser/" << cruid << "\">RemoveUser</a></li>"
jan.koester's avatar
jan.koester committed
                        << "</ul></td></tr>";
                    }catch(AuthBackendError &e){
                        std::cerr << e.what() << std::endl;
jan.koester's avatar
jan.koester committed
                    }
                }
jan.koester's avatar
jan.koester committed
            }
jan.koester's avatar
jan.koester committed

jan.koester's avatar
jan.koester committed
            userlist << "</table></div><div><ul class=\"usertoolbar\" ><li><a class=\"button\" href=\"/settings/"<< cdid << "/createuser\">CreateUser</a></li></ul></div>";
jan.koester's avatar
jan.koester committed

jan.koester's avatar
jan.koester committed
            content->appendChild(userlist.parse());
jan.koester's avatar
jan.koester committed

            libhtmlpp::print(&root,out,true);

jan.koester's avatar
jan.koester committed
            libhttppp::HttpResponse rep;
jan.koester's avatar
jan.koester committed
            rep.setContentType("text/html");
            rep.send(curreq,out.c_str(),out.size());
jan.koester's avatar
jan.koester committed
        }

jan.koester's avatar
jan.koester committed
        void createUser(libhttppp::HttpRequest *curreq, const int tid, ULONG_PTR args,const char *baseurl){
jan.koester's avatar
jan.koester committed
            libhttppp::HttpResponse rep;
Loading
Loading full blame...