Commit fd9a0ab2 authored by jan.koester's avatar jan.koester
Browse files

test

parent 3a10e1ff
Loading
Loading
Loading
Loading
Loading
+200 −303
Original line number Diff line number Diff line
@@ -145,32 +145,22 @@ namespace authdb {
        void apiListUsers(libhttppp::HttpRequest &curreq, const char *cdid) {
            AuthBackend *backend = getDomain(cdid);
            if (!backend) throw AuthBackendError("listUsers: could not resolve domain!");
            AuthBackend::Guard guard(*backend);

            json_object *jobj = json_object_new_object();
            json_object *jarr = json_object_new_array();

            User user;
            size_t rd = sizeof(authdb::AuthHeader), end = backend->end();
            std::shared_ptr<authdb::AuthData::Record> cur = std::make_shared<authdb::AuthData::Record>();

            while (rd < end) {
                cur->type = EmptyData;
                if (rd + sizeof(AuthData::Record) > end) break;
                backend->setPos(rd);
                backend->read((unsigned char*)cur.get(), sizeof(AuthData::Record));
                size_t next = backend->getPos() + cur->datasize;
                if (next < backend->getPos() || next > end) break;
                rd = next;

                if (cur->type == UserData && strcmp(cur->fieldname, "username") == 0) {
                    class UserData udat(cur->ruid);
            std::vector<uuid::uuid> uuids;
            user.list(*backend, uuids);

            for (const auto &uid : uuids) {
                class UserData udat(uid);
                try {
                    size_t upos = sizeof(authdb::AuthHeader);
                    user.info(*backend, udat, upos);

                    json_object *juser = json_object_new_object();
                        json_object_object_add(juser, "uid", json_object_new_string(uuid::uuid(cur->ruid).c_str()));
                    json_object_object_add(juser, "uid", json_object_new_string(uid.c_str()));
                    json_object_object_add(juser, "username", json_object_new_string(udat.getUsername().c_str()));
                    try { json_object_object_add(juser, "firstname", json_object_new_string(udat.getFirstname().c_str())); } catch (...) {}
                    try { json_object_object_add(juser, "lastname", json_object_new_string(udat.getLastname().c_str())); } catch (...) {}
@@ -180,7 +170,6 @@ namespace authdb {
                    std::cerr << e.what() << std::endl;
                }
            }
            }
            json_object_object_add(jobj, "users", jarr);
            sendJson(curreq, jobj);
            json_object_put(jobj);
@@ -198,26 +187,22 @@ namespace authdb {
            json_object *jobj = json_object_new_object();
            json_object *jfields = json_object_new_array();

            size_t rd = sizeof(authdb::AuthHeader), end = backend->end();
            while (rd + sizeof(AuthData::Record) <= end) {
                std::shared_ptr<authdb::AuthData::Record> cur = std::make_shared<authdb::AuthData::Record>();
                backend->setPos(rd);
                backend->read((unsigned char*)cur.get(), sizeof(AuthData::Record));
                size_t next = backend->getPos() + cur->datasize;
                if (next < backend->getPos() || next > end) break;
                rd = next;

                if (uid == cur->ruid && cur->type == UserData && cur->storage == TextStorage) {
                    cur->data = new char[cur->datasize + 1];
                    backend->read((unsigned char*)cur->data, cur->datasize);
                    cur->data[cur->datasize] = '\0';
            User user;
            class UserData udat(uid);
            size_t upos = sizeof(authdb::AuthHeader);
            user.info(*backend, udat, upos);

            auto addField = [&](const char *name, const std::string &val) {
                json_object *jfield = json_object_new_object();
                    json_object_object_add(jfield, "name", json_object_new_string(cur->fieldname));
                    json_object_object_add(jfield, "value", json_object_new_string(cur->data));
                json_object_object_add(jfield, "name", json_object_new_string(name));
                json_object_object_add(jfield, "value", json_object_new_string(val.c_str()));
                json_object_array_add(jfields, jfield);
                    delete[] cur->data;
                }
            }
            };
            try { addField("username", udat.getUsername()); } catch (...) {}
            try { addField("firstname", udat.getFirstname()); } catch (...) {}
            try { addField("lastname", udat.getLastname()); } catch (...) {}
            try { addField("mail", udat.getMail()); } catch (...) {}

            json_object_object_add(jobj, "fields", jfields);
            sendJson(curreq, jobj);
            json_object_put(jobj);
@@ -506,37 +491,27 @@ namespace authdb {
        bool isSuperAdmin(const SessionData *sdat) {
            if (!sdat) return false;

            // Refresh admin backend data from cluster (RAII: lock + unlock)
            AuthBackend::Guard guard(_AdminBackend);

            // Get the user ID from the session
            uuid::uuid uid;
            sdat->getUid(uid);

            // Find "SuperAdmin" group in admin backend and check membership directly
            // Find "SuperAdmin" group in admin backend and check membership
            Group group;
            size_t rd = sizeof(authdb::AuthHeader), end = _AdminBackend.end();
            while (rd < end) {
                std::shared_ptr<authdb::AuthData::Record> cur = std::make_shared<authdb::AuthData::Record>();
                cur->type = EmptyData;
                _AdminBackend.setPos(rd);
                _AdminBackend.read((unsigned char*)cur.get(), sizeof(AuthData::Record));
                rd = _AdminBackend.getPos() + cur->datasize;

                if (cur->type == GroupData && strcmp(cur->fieldname, "groupname") == 0) {
                    class GroupData gdat(cur->ruid);
            std::vector<uuid::uuid> gids;
            group.list(_AdminBackend, gids);

            for (const auto &gid : gids) {
                class GroupData gdat(gid);
                try {
                    size_t gpos = sizeof(authdb::AuthHeader);
                    group.info(_AdminBackend, gdat, gpos);
                    if (gdat.getName() == "SuperAdmin") {
                            // Check membership from backend data, not session cache
                        return gdat.isMember(uid);
                    }
                } catch (AuthBackendError &e) {
                    std::cerr << e.what() << std::endl;
                }
            }
            }
            return false;
        }

@@ -686,28 +661,21 @@ namespace authdb {

        /* ---- JSON API: List Domains ---- */
        void apiListDomains(libhttppp::HttpRequest &curreq) {
            AuthBackend::Guard guard(_AdminBackend);
            json_object *jobj = json_object_new_object();
            json_object *jarr = json_object_new_array();

            Domain domain;
            size_t rd = sizeof(authdb::AuthHeader), end = _AdminBackend.end();

            while (rd < end) {
                std::shared_ptr<authdb::AuthData::Record> cur = std::make_shared<authdb::AuthData::Record>();
                cur->type = EmptyData;
                _AdminBackend.setPos(rd);
                _AdminBackend.read((unsigned char*)cur.get(), sizeof(AuthData::Record));
                rd = _AdminBackend.getPos() + cur->datasize;
            std::vector<uuid::uuid> dids;
            domain.list(_AdminBackend, dids);

                if (cur->type == DataType::DomainData && strcmp(cur->fieldname, "domainname") == 0) {
                    class DomainData ddat(cur->ruid);
            for (const auto &did : dids) {
                class DomainData ddat(did);
                try {
                    size_t dpos = sizeof(authdb::AuthHeader);
                    domain.info(_AdminBackend, ddat, dpos);

                    json_object *jdom = json_object_new_object();
                        json_object_object_add(jdom, "id", json_object_new_string(uuid::uuid(cur->ruid).c_str()));
                    json_object_object_add(jdom, "id", json_object_new_string(did.c_str()));
                    json_object_object_add(jdom, "name", json_object_new_string(ddat.getDomainName().c_str()));
                    json_object_object_add(jdom, "storagetype", json_object_new_int(ddat.getStorageType()));
                    json_object_object_add(jdom, "storageoptions", json_object_new_string(ddat.getStorageOptions().c_str()));
@@ -716,7 +684,6 @@ namespace authdb {
                    std::cerr << e.what() << std::endl;
                }
            }
            }
            json_object_object_add(jobj, "domains", jarr);
            sendJson(curreq, jobj);
            json_object_put(jobj);
@@ -884,37 +851,28 @@ namespace authdb {
        void apiListGroups(libhttppp::HttpRequest &curreq, const char *cdid) {
            AuthBackend *backend = getDomain(cdid);
            if (!backend) throw AuthBackendError("listGroups: could not resolve domain!");
            AuthBackend::Guard guard(*backend);

            json_object *jobj = json_object_new_object();
            json_object *jarr = json_object_new_array();

            Group group;
            size_t rd = sizeof(authdb::AuthHeader), end = backend->end();

            while (rd + sizeof(AuthData::Record) <= end) {
                std::shared_ptr<authdb::AuthData::Record> cur = std::make_shared<authdb::AuthData::Record>();
                backend->setPos(rd);
                backend->read((unsigned char*)cur.get(), sizeof(AuthData::Record));
                size_t next = backend->getPos() + cur->datasize;
                if (next < backend->getPos() || next > end) break;
                rd = next;

                if (cur->type == GroupData && strcmp(cur->fieldname, "groupname") == 0) {
                    class GroupData gdat(cur->ruid);
            std::vector<uuid::uuid> gids;
            group.list(*backend, gids);

            for (const auto &gid : gids) {
                class GroupData gdat(gid);
                try {
                    size_t upos = sizeof(authdb::AuthHeader);
                    group.info(*backend, gdat, upos);

                    json_object *jgrp = json_object_new_object();
                        json_object_object_add(jgrp, "gid", json_object_new_string(uuid::uuid(cur->ruid).c_str()));
                    json_object_object_add(jgrp, "gid", json_object_new_string(gid.c_str()));
                    json_object_object_add(jgrp, "name", json_object_new_string(gdat.getName().c_str()));
                    json_object_array_add(jarr, jgrp);
                } catch (AuthBackendError &e) {
                    std::cerr << e.what() << std::endl;
                }
            }
            }
            json_object_object_add(jobj, "groups", jarr);
            sendJson(curreq, jobj);
            json_object_put(jobj);
@@ -948,24 +906,19 @@ namespace authdb {

            // All users (for selection)
            json_object *jallusers = json_object_new_array();
            size_t rd = sizeof(authdb::AuthHeader), end = backend->end();
            while (rd + sizeof(AuthData::Record) <= end) {
                std::shared_ptr<authdb::AuthData::Record> cur = std::make_shared<authdb::AuthData::Record>();
                backend->setPos(rd);
                backend->read((unsigned char*)cur.get(), sizeof(AuthData::Record));
                size_t next = backend->getPos() + cur->datasize;
                if (next < backend->getPos() || next > end) break;
                rd = next;
                if (cur->type == UserData && cur->storage == TextStorage && strcmp(cur->fieldname, "username") == 0) {
                    cur->data = new char[cur->datasize + 1];
                    backend->read((unsigned char*)cur->data, cur->datasize);
                    cur->data[cur->datasize] = '\0';
            User usr;
            std::vector<uuid::uuid> uids;
            usr.list(*backend, uids);
            for (const auto &uid : uids) {
                class UserData udat(uid);
                try {
                    size_t upos = sizeof(authdb::AuthHeader);
                    usr.info(*backend, udat, upos);
                    json_object *ju = json_object_new_object();
                    json_object_object_add(ju, "uid", json_object_new_string(uuid::uuid(cur->ruid).c_str()));
                    json_object_object_add(ju, "username", json_object_new_string(cur->data));
                    json_object_object_add(ju, "uid", json_object_new_string(uid.c_str()));
                    json_object_object_add(ju, "username", json_object_new_string(udat.getUsername().c_str()));
                    json_object_array_add(jallusers, ju);
                    delete[] cur->data;
                }
                } catch (...) {}
            }
            json_object_object_add(jobj, "allusers", jallusers);

@@ -1133,31 +1086,22 @@ namespace authdb {
        void apiListGpos(libhttppp::HttpRequest &curreq, const char *cdid) {
            AuthBackend *backend = getDomain(cdid);
            if (!backend) throw AuthBackendError("listGpos: could not resolve domain!");
            AuthBackend::Guard guard(*backend);

            json_object *jobj = json_object_new_object();
            json_object *jarr = json_object_new_array();

            Gpo gpo;
            size_t rd = sizeof(authdb::AuthHeader), end = backend->end();

            while (rd + sizeof(AuthData::Record) <= end) {
                std::shared_ptr<authdb::AuthData::Record> cur = std::make_shared<authdb::AuthData::Record>();
                cur->type = EmptyData;
                backend->setPos(rd);
                backend->read((unsigned char*)cur.get(), sizeof(AuthData::Record));
                size_t next = backend->getPos() + cur->datasize;
                if (next < backend->getPos() || next > end) break;
                rd = next;

                if (cur->type == PolicyData && strcmp(cur->fieldname, "gponame") == 0) {
                    class GpoData gdat(cur->ruid);
            std::vector<uuid::uuid> gpids;
            gpo.list(*backend, gpids);

            for (const auto &gpid : gpids) {
                class GpoData gdat(gpid);
                try {
                    size_t upos = sizeof(authdb::AuthHeader);
                    gpo.info(*backend, gdat, upos);

                    json_object *jgpo = json_object_new_object();
                        json_object_object_add(jgpo, "id", json_object_new_string(uuid::uuid(cur->ruid).c_str()));
                    json_object_object_add(jgpo, "id", json_object_new_string(gpid.c_str()));
                    json_object_object_add(jgpo, "name", json_object_new_string(gdat.getName()));
                    try {
                        json_object_object_add(jgpo, "desc", json_object_new_string(gdat.getDesc()));
@@ -1170,7 +1114,6 @@ namespace authdb {
                    std::cerr << e.what() << std::endl;
                }
            }
            }
            json_object_object_add(jobj, "gpos", jarr);
            sendJson(curreq, jobj);
            json_object_put(jobj);
@@ -1215,23 +1158,19 @@ namespace authdb {

            // All groups
            json_object *jallgroups = json_object_new_array();
            size_t rd = sizeof(AuthHeader), end = backend->end();
            while (rd + sizeof(AuthData::Record) <= end) {
                AuthData::Record cur;
                backend->setPos(rd);
                backend->read((unsigned char*)&cur, sizeof(AuthData::Record));
                size_t next = backend->getPos() + cur.datasize;
                if (next < backend->getPos() || next > end) break;
                rd = next;
                if (cur.type == GroupData && strcmp(cur.fieldname, "groupname") == 0) {
                    cur.data = new char[cur.datasize];
                    backend->read((unsigned char*)cur.data, cur.datasize);
            Group grplst;
            std::vector<uuid::uuid> grpids;
            grplst.list(*backend, grpids);
            for (const auto &gid : grpids) {
                class GroupData grpdat(gid);
                try {
                    size_t gpos = sizeof(authdb::AuthHeader);
                    grplst.info(*backend, grpdat, gpos);
                    json_object *jg = json_object_new_object();
                    json_object_object_add(jg, "gid", json_object_new_string(uuid::uuid(cur.ruid).c_str()));
                    json_object_object_add(jg, "name", json_object_new_string(cur.data));
                    json_object_object_add(jg, "gid", json_object_new_string(gid.c_str()));
                    json_object_object_add(jg, "name", json_object_new_string(grpdat.getName().c_str()));
                    json_object_array_add(jallgroups, jg);
                    delete[] cur.data;
                }
                } catch (...) {}
            }
            json_object_object_add(jobj, "allgroups", jallgroups);

@@ -1359,31 +1298,22 @@ namespace authdb {
        void apiListServices(libhttppp::HttpRequest &curreq, const char *cdid) {
            AuthBackend *backend = getDomain(cdid);
            if (!backend) throw AuthBackendError("listServices: could not resolve domain!");
            AuthBackend::Guard guard(*backend);

            json_object *jobj = json_object_new_object();
            json_object *jarr = json_object_new_array();

            ServiceManager svcmgr;
            size_t rd = sizeof(authdb::AuthHeader), end = backend->end();

            while (rd + sizeof(authdb::AuthData::Record) <= end) {
                std::shared_ptr<authdb::AuthData::Record> cur = std::make_shared<authdb::AuthData::Record>();
                cur->type = EmptyData;
                backend->setPos(rd);
                backend->read((unsigned char*)cur.get(), sizeof(authdb::AuthData::Record));
                size_t next = backend->getPos() + cur->datasize;
                if (next < backend->getPos() || next > end) break;
                rd = next;

                if (cur->type == ServiceData && std::string(cur->fieldname) == "servicename") {
            std::vector<uuid::uuid> sids;
            svcmgr.list(*backend, sids);

            for (const auto &sid : sids) {
                try {
                        class ServiceData sdat(cur->ruid);
                    class ServiceData sdat(sid);
                    size_t spos = sizeof(authdb::AuthHeader);
                    svcmgr.info(*backend, sdat, spos);

                    json_object *jsvc = json_object_new_object();
                        json_object_object_add(jsvc, "id", json_object_new_string(uuid::uuid(cur->ruid).c_str()));
                    json_object_object_add(jsvc, "id", json_object_new_string(sid.c_str()));
                    json_object_object_add(jsvc, "servicename", json_object_new_string(sdat.getServiceName()));
                    try {
                        json_object_object_add(jsvc, "hostname", json_object_new_string(sdat.getHostName()));
@@ -1400,7 +1330,6 @@ namespace authdb {
                    std::cerr << "AuthBackendError: " << e.what() << std::endl;
                }
            }
            }
            json_object_object_add(jobj, "services", jarr);
            sendJson(curreq, jobj);
            json_object_put(jobj);
@@ -1621,38 +1550,28 @@ namespace authdb {
        void apiListClients(libhttppp::HttpRequest &curreq, const char *cdid) {
            AuthBackend *backend = getDomain(cdid);
            if (!backend) throw AuthBackendError("listClients: could not resolve domain!");
            AuthBackend::Guard guard(*backend);

            json_object *jobj = json_object_new_object();
            json_object *jarr = json_object_new_array();

            Client clt;
            size_t rd = sizeof(authdb::AuthHeader), end = backend->end();

            while (rd + sizeof(authdb::AuthData::Record) <= end) {
                std::shared_ptr<authdb::AuthData::Record> cur = std::make_shared<authdb::AuthData::Record>();
                cur->type = EmptyData;
                backend->setPos(rd);
                backend->read((unsigned char*)cur.get(), sizeof(authdb::AuthData::Record));
                size_t next = backend->getPos() + cur->datasize;
                if (next < backend->getPos() || next > end) break;
                rd = next;

                if (cur->type == ClientData && std::string(cur->fieldname) == "clientname") {
            std::vector<uuid::uuid> clids;
            clt.list(*backend, clids);

            for (const auto &clid : clids) {
                try {
                        class ClientData cdat(cur->ruid);
                    class ClientData cdat(clid);
                    size_t ccpos = sizeof(authdb::AuthHeader);
                    clt.info(*backend, cdat, ccpos);

                    json_object *jclient = json_object_new_object();
                        json_object_object_add(jclient, "id", json_object_new_string(uuid::uuid(cur->ruid).c_str()));
                    json_object_object_add(jclient, "id", json_object_new_string(clid.c_str()));
                    json_object_object_add(jclient, "name", json_object_new_string(cdat.getName()));
                    json_object_array_add(jarr, jclient);
                } catch (const AuthBackendError &e) {
                    std::cerr << "AuthBackendError: " << e.what() << std::endl;
                }
            }
            }
            json_object_object_add(jobj, "clients", jarr);
            sendJson(curreq, jobj);
            json_object_put(jobj);
@@ -1841,11 +1760,9 @@ namespace authdb {
        void apiVacuum(libhttppp::HttpRequest &curreq, const char *cdid) {
            AuthBackend *backend = getDomain(cdid);
            if (!backend) throw AuthBackendError("vacuum: could not resolve domain!");
            AuthBackend::Guard guard(*backend);

            size_t sizeBefore = backend->end();
            backend->vacuum();
            size_t sizeAfter = backend->end();
            size_t sizeBefore = 0, sizeAfter = 0;
            backend->vacuum(sizeBefore, sizeAfter);

            json_object *jobj = json_object_new_object();
            json_object_object_add(jobj, "status", json_object_new_string("ok"));
@@ -1916,24 +1833,12 @@ namespace authdb {
                throw AuthBackendError("login: could not parse uuid!");
            }

            // Lock backend to fetch latest data from cluster before reading
            AuthBackend::Guard guard(*backend);

            User user;
            size_t rd = sizeof(authdb::AuthHeader), end = backend->end();
            std::cerr << "[LOGIN] scanning backend: rd=" << rd << " end=" << end << std::endl;

            while (rd + sizeof(AuthData::Record) <= end) {
                std::shared_ptr<authdb::AuthData::Record> cur = std::make_shared<authdb::AuthData::Record>();
                cur->type = EmptyData;
                backend->setPos(rd);
                backend->read((unsigned char*)cur.get(), sizeof(AuthData::Record));
                size_t next = backend->getPos() + cur->datasize;
                if (next < backend->getPos() || next > end) break;
                rd = next;

                if (cur->type == UserData && strcmp(cur->fieldname, "username") == 0) {
                    class UserData udat(cur->ruid);
            std::vector<uuid::uuid> uids;
            user.list(*backend, uids);

            for (const auto &uid : uids) {
                class UserData udat(uid);
                size_t upos = sizeof(authdb::AuthHeader);
                user.info(*backend, udat, upos);

@@ -1963,7 +1868,6 @@ namespace authdb {
                    return;
                }
            }
            }
            throw AuthBackendError("login: Wrong Password or Username!");
        }

@@ -2062,21 +1966,15 @@ namespace authdb {

                    AuthBackend::Guard domguard(_AdminBackend);
                    Domain domain;
                    size_t rd = sizeof(authdb::AuthHeader), end = _AdminBackend.end();
                    std::vector<uuid::uuid> dids;
                    domain.list(_AdminBackend, dids);

                    while (rd < end) {
                        std::shared_ptr<authdb::AuthData::Record> cur = std::make_shared<authdb::AuthData::Record>();
                        cur->type = EmptyData;
                        _AdminBackend.setPos(rd);
                        _AdminBackend.read((unsigned char*)cur.get(), sizeof(AuthData::Record));
                        rd = _AdminBackend.getPos() + cur->datasize;

                        if (cur->type == DataType::DomainData && strcmp(cur->fieldname, "domainname") == 0) {
                            class DomainData ddat(cur->ruid);
                    for (const auto &did : dids) {
                        class DomainData ddat(did);
                        try {
                            size_t dpos = sizeof(authdb::AuthHeader);
                            domain.info(_AdminBackend, ddat, dpos);
                                *dform << "<option value=\"" << uuid::uuid(cur->ruid).c_str() << "\" >"
                            *dform << "<option value=\"" << did.c_str() << "\" >"
                                << ddat.getDomainName().c_str()
                                << "</option>";
                            domel->appendChild(dform->parse());
@@ -2085,7 +1983,6 @@ namespace authdb {
                            std::cerr << e.what() << std::endl;
                        }
                    }
                    }

                    if (loginel && el.what()) {
                        libhtmlpp::HtmlString errmsg;
+22 −34

File changed.

Preview size limit exceeded, changes collapsed.

+59 −16

File changed.

Preview size limit exceeded, changes collapsed.

+57 −15

File changed.

Preview size limit exceeded, changes collapsed.

+19 −0

File changed.

Preview size limit exceeded, changes collapsed.

Loading