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

test

parent d8e30907
Loading
Loading
Loading
Loading
Loading
+79 −0
Changes for client/client.cpp: 79 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -1118,6 +1118,85 @@ std::vector<Client::GroupInfo> Client::listGroups() {
    return groups;
}

std::string Client::addGroup(const uuid::uuid& gid, const std::string& name) {
    ensure_http_client(_Con);

    json_object* jresponse = json_object_new_object();
    json_object* cmd = json_object_new_array();
    json_object* obj = json_object_new_object();
    json_object* groupadd = json_object_new_object();

    json_object_object_add(obj, "clientsession",
                           json_object_new_string(_Con.getClientId().c_str()));

    json_object_object_add(groupadd, "gid", json_object_new_string(gid.c_str()));
    json_object_object_add(groupadd, "name", json_object_new_string(name.c_str()));

    json_object_object_add(obj, "groupadd", groupadd);

    json_object_array_add(cmd, obj);
    json_object_object_add(jresponse, "commands", cmd);

    size_t outsize = 0;
    const char* tmp = json_object_to_json_string_length(jresponse, 0, &outsize);
    std::vector<char> out;
    out.reserve(outsize);
    std::copy(tmp, tmp + outsize, std::back_inserter(out));

    libhttppp::HttpRequest nreq;
    nreq.setHeaderData("accept")->push_back("application/json");
    nreq.setHeaderData("content-type")->push_back("application/json");
    nreq.setRequestURL(_Con._RequestPath.c_str());
    std::vector<char> resp(safe_post(_Con, nreq, out, _Con._MaxTries));
    resp.push_back('\0');

    json_object_put(jresponse);

    json_tokener* jtok = json_tokener_new();
    json_object* jrequest = json_tokener_parse_ex(jtok, resp.data(), resp.size() - 1);

    if (!jrequest) {
        const char* err = json_tokener_error_desc(json_tokener_get_error(jtok));
        json_tokener_free(jtok);
        throw authdb::AuthBackendError(err);
    }

    if (json_object_get_type(jrequest) != json_type_array) {
        json_object_put(jrequest);
        json_tokener_free(jtok);
        throw(authdb::AuthBackendError("Invalid Api Commands"));
    }

    std::string result;
    int fcount = json_object_array_length(jrequest);
    for (int i = 0; i < fcount; ++i) {
        json_object_object_foreach(json_object_array_get_idx(jrequest, i), key, val) {
            if (strcmp(key, "error") == 0) {
                std::string msg = json_object_get_string(val);
                json_object_put(jrequest);
                json_tokener_free(jtok);
                throw authdb::AuthBackendError(msg);
            }
            if (strcmp(key, "groupadd") == 0) {
                json_object_object_foreach(val, gkey, gval) {
                    if (json_object_get_boolean(gval)) {
                        result = gkey;
                    }
                }
            }
        }
    }

    json_object_put(jrequest);
    json_tokener_free(jtok);

    if (result.empty()) {
        throw authdb::AuthBackendError("addGroup failed: no group id returned");
    }

    return result;
}

// -------- PooledConnection --------

PooledConnection::PooledConnection(ConnectionPool* pool,
+1 −0
Changes for client/client.h: 1 added line, 0 removed lines.
Original line number Diff line number Diff line
@@ -145,6 +145,7 @@ namespace authdb {
            };

            std::vector<GroupInfo> listGroups();
            std::string addGroup(const uuid::uuid &gid, const std::string &name);

            // GPO result cache TTL in seconds (default 300 = 5 min)
            static void setGpoCacheTTL(int seconds);
+65 −0
Changes for src/api.cpp: 65 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -215,9 +215,11 @@ public:
                    } catch (const std::exception &e) {
                        std::cerr << "[api] GPOadd error for '" << name << "': " << e.what() << std::endl;
                        json_object_object_add(value, id.c_str(), json_object_new_boolean(false));
                        json_object_object_add(respid, "error", json_object_new_string(e.what()));
                    } catch (...) {
                        std::cerr << "[api] GPOadd unknown error for '" << name << "'" << std::endl;
                        json_object_object_add(value, id.c_str(), json_object_new_boolean(false));
                        json_object_object_add(respid, "error", json_object_new_string("unknown error"));
                    }

                    json_object_object_add(respid, "gpoadd", value);
@@ -227,6 +229,68 @@ public:
        }
    }

    void addGroup(json_object *request, json_object *response) {
        json_object* cmd = get_commands_array_or_throw(request);

        int fcount = json_object_array_length(cmd);
        for (int i = 0; i < fcount; ++i) {
            json_object_object_foreach(json_object_array_get_idx(cmd, i), key, val) {
                if (strcmp(key, "groupadd") == 0) {
                    std::string name, gid;

                    json_object_object_foreach(val, okey, oval) {
                        if (strcmp(okey, "gid") == 0) {
                            gid = json_object_get_string(oval);
                        } else if (strcmp(okey, "name") == 0) {
                            name = json_object_get_string(oval);
                        }
                    }

                    json_object* respid = json_object_new_object();
                    json_object* value  = json_object_new_object();

                    if (name.empty() || gid.empty()) {
                        json_object_object_add(value, gid.empty() ? "" : gid.c_str(),
                                               json_object_new_boolean(false));
                        json_object_object_add(respid, "groupadd", value);
                        json_object_array_add(response, respid);
                        continue;
                    }

                    ::uuid::uuid id(gid.c_str());

                    try {
                        class Group group;
                        int ret = -1;

                        // Idempotent: if group already exists (by id), just return success
                        if (group.exits(_Backend, id, "", ret)) {
                            json_object_object_add(value, id.c_str(), json_object_new_boolean(true));
                        } else {
                            class GroupData gdat(id);
                            gdat.setName(name.c_str());

                            group.create(_Backend, &gdat);

                            json_object_object_add(value, id.c_str(), json_object_new_boolean(true));
                        }
                    } catch (const std::exception &e) {
                        std::cerr << "[api] addGroup error for '" << name << "': " << e.what() << std::endl;
                        json_object_object_add(value, id.c_str(), json_object_new_boolean(false));
                        json_object_object_add(respid, "error", json_object_new_string(e.what()));
                    } catch (...) {
                        std::cerr << "[api] addGroup unknown error for '" << name << "'" << std::endl;
                        json_object_object_add(value, id.c_str(), json_object_new_boolean(false));
                        json_object_object_add(respid, "error", json_object_new_string("unknown error"));
                    }

                    json_object_object_add(respid, "groupadd", value);
                    json_object_array_add(response, respid);
                }
            }
        }
    }

    const SessionData* checkUser(json_object *request, json_object *response) {
        json_object* cmd = get_commands_array_or_throw(request);

@@ -780,6 +844,7 @@ public:
            if (curcon) {
                existsGPO(jrequest, jresponse);
                addGPO(jrequest, jresponse);
                addGroup(jrequest, jresponse);
                listGroups(jrequest, jresponse);
            }