Loading src/admin.cpp +239 −0 Changes for src/admin.cpp: 239 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -144,6 +144,35 @@ namespace fenrirds { /* ---- JSON API: List Users ---- */ void apiListUsers(libhttppp::HttpRequest &curreq, const char *cdid) { /* the admin console (admin.local) has no directory — its own * accounts (SuperAdmins) are native; list them from the backend */ if (strcmp(cdid, "admin") == 0) { json_object *jobj = json_object_new_object(); json_object *jarr = json_object_new_array(); User user; std::vector<uuid::uuid> uuids; user.list(_AdminBackend, uuids); for (const auto &uid : uuids) { class UserData udat(uid); try { size_t upos = sizeof(fenrirds::AuthHeader); user.info(_AdminBackend, udat, upos); json_object *juser = json_object_new_object(); 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 (...) {} try { json_object_object_add(juser, "mail", json_object_new_string(udat.getMail().c_str())); } catch (...) {} json_object_object_add(juser, "windowslogin", json_object_new_boolean(false)); json_object_array_add(jarr, juser); } catch (AuthBackendError &e) { std::cerr << e.what() << std::endl; } } json_object_object_add(jobj, "users", jarr); sendJson(curreq, jobj); json_object_put(jobj); return; } std::string domain = domainNameFor(cdid); if (domain.empty() || !g_AdPlugin) throw AuthBackendError("listUsers: no directory for domain!"); Loading Loading @@ -174,6 +203,32 @@ namespace fenrirds { /* ---- JSON API: Get User (for edit form) ---- */ void apiGetUser(libhttppp::HttpRequest &curreq, const char *cdid, const char *cuid) { if (strcmp(cdid, "admin") == 0) { /* admin console: native SuperAdmin account */ uuid::uuid uid; uid.parse(cuid); User user; class UserData udat(uid); size_t upos = sizeof(AuthHeader); user.info(_AdminBackend, udat, upos); json_object *jobj = json_object_new_object(); json_object *jfields = json_object_new_array(); auto af = [&](const char *name, const std::string &val) { json_object *jf = json_object_new_object(); json_object_object_add(jf, "name", json_object_new_string(name)); json_object_object_add(jf, "value", json_object_new_string(val.c_str())); json_object_array_add(jfields, jf); }; try { af("username", udat.getUsername()); } catch (...) {} try { af("firstname", udat.getFirstname()); } catch (...) {} try { af("lastname", udat.getLastname()); } catch (...) {} try { af("mail", udat.getMail()); } catch (...) {} json_object_object_add(jobj, "fields", jfields); json_object_object_add(jobj, "windowslogin", json_object_new_boolean(false)); sendJson(curreq, jobj); json_object_put(jobj); return; } std::string domain = domainNameFor(cdid); if (domain.empty() || !g_AdPlugin) throw AuthBackendError("getUser: no directory for domain!"); Loading Loading @@ -210,6 +265,46 @@ namespace fenrirds { /* ---- JSON API: Create User (directory object) ---- */ void apiCreateUser(libhttppp::HttpRequest &curreq, const char *cdid) { if (strcmp(cdid, "admin") == 0) { /* admin console: create a native SuperAdmin account */ libhttppp::HttpForm curform; curform.parse(curreq); uuid::uuid uid; uid.generate(); class UserData udat(uid); std::string uname, pw; for (const auto &fd : curform.multipartData()) { if (fd.value.empty()) continue; std::string name; for (const auto &d : fd.dispositions) { std::string k = d.key; std::transform(k.begin(), k.end(), k.begin(), [](unsigned char c){ return std::tolower(c); }); if (k == "name") name = d.value; } std::string val(fd.value.begin(), fd.value.end()); if (name == "username") { uname = val; udat.setUserName(val); } else if (name == "firstname") udat.setFirstName(val); else if (name == "lastname") udat.setLastName(val); else if (name == "mail") udat.setMail(val); else if (name == "pwhash") pw = val; } if (uname.empty()) throw AuthBackendError("username not set!"); if (!pw.empty()) { Hash h; std::string hh; h.hash(pw, hh); udat.setPwHash(hh); } User user; user.create(_AdminBackend, &udat); /* add to the native SuperAdmin group so it has admin rights */ Group group; std::vector<uuid::uuid> gids; group.list(_AdminBackend, gids); for (const auto &gid : gids) { class GroupData gd(gid); size_t gp = sizeof(AuthHeader); try { group.info(_AdminBackend, gd, gp); } catch (...) { continue; } if (gd.getName() == "SuperAdmin") { gd.addMember(uid); gp = sizeof(AuthHeader); group.edit(_AdminBackend, gd, gp); break; } } json_object *jobj = json_object_new_object(); json_object_object_add(jobj, "status", json_object_new_string("ok")); json_object_object_add(jobj, "uid", json_object_new_string(uid.c_str())); sendJson(curreq, jobj); json_object_put(jobj); return; } std::string domain = domainNameFor(cdid); if (domain.empty() || !g_AdPlugin) throw AuthBackendError("createUser: no directory for domain!"); Loading Loading @@ -282,6 +377,16 @@ namespace fenrirds { /* ---- JSON API: Remove User ---- */ void apiRemoveUser(libhttppp::HttpRequest &curreq, const char *cdid, const char *cuid) { if (strcmp(cdid, "admin") == 0) { uuid::uuid uid; uid.parse(cuid); User user; user.remove(_AdminBackend, uid); json_object *jok = json_object_new_object(); json_object_object_add(jok, "status", json_object_new_string("ok")); sendJson(curreq, jok); json_object_put(jok); return; } std::string domain = domainNameFor(cdid); if (domain.empty() || !g_AdPlugin) throw AuthBackendError("removeUser: no directory for domain!"); Loading @@ -300,6 +405,35 @@ namespace fenrirds { /* ---- JSON API: Edit User (directory object) ---- */ void apiEditUser(libhttppp::HttpRequest &curreq, const char *cdid, const char *cuid) { if (strcmp(cdid, "admin") == 0) { /* admin console: edit a native SuperAdmin account */ uuid::uuid uid; uid.parse(cuid); libhttppp::HttpForm curform; curform.parse(curreq); User user; class UserData udat(uid); size_t upos = sizeof(AuthHeader); user.info(_AdminBackend, udat, upos); for (const auto &fd : curform.multipartData()) { if (fd.value.empty()) continue; std::string name; for (const auto &d : fd.dispositions) { std::string k = d.key; std::transform(k.begin(), k.end(), k.begin(), [](unsigned char c){ return std::tolower(c); }); if (k == "name") name = d.value; } std::string val(fd.value.begin(), fd.value.end()); if (name == "firstname") udat.setFirstName(val); else if (name == "lastname") udat.setLastName(val); else if (name == "mail") udat.setMail(val); else if (name == "pwhash" && !val.empty()) { Hash h; std::string hh; h.hash(val, hh); udat.setPwHash(hh); } } upos = sizeof(AuthHeader); user.edit(_AdminBackend, udat, upos); json_object *jok = json_object_new_object(); json_object_object_add(jok, "status", json_object_new_string("ok")); sendJson(curreq, jok); json_object_put(jok); return; } std::string domain = domainNameFor(cdid); if (domain.empty() || !g_AdPlugin) throw AuthBackendError("editUser: no directory for domain!"); Loading Loading @@ -912,6 +1046,31 @@ namespace fenrirds { /* ---- JSON API: List Groups ---- */ void apiListGroups(libhttppp::HttpRequest &curreq, const char *cdid) { if (strcmp(cdid, "admin") == 0) { /* admin console: native groups (e.g. SuperAdmin) */ json_object *jobj = json_object_new_object(); json_object *jarr = json_object_new_array(); Group group; std::vector<uuid::uuid> gids; group.list(_AdminBackend, gids); for (const auto &gid : gids) { class GroupData gdat(gid); try { size_t gpos = sizeof(fenrirds::AuthHeader); group.info(_AdminBackend, gdat, gpos); json_object *jgrp = json_object_new_object(); 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_object_add(jgrp, "windowslogin", json_object_new_boolean(false)); 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); return; } std::string domain = domainNameFor(cdid); if (domain.empty() || !g_AdPlugin) throw AuthBackendError("listGroups: no directory for domain!"); Loading @@ -937,6 +1096,34 @@ namespace fenrirds { /* ---- JSON API: Get Group (for edit) ---- */ void apiGetGroup(libhttppp::HttpRequest &curreq, const char *cdid, const char *cgid) { if (strcmp(cdid, "admin") == 0) { /* admin console: native group + native member picker */ uuid::uuid gid(cgid); class GroupData gdat(gid); Group grp; size_t pos = sizeof(AuthHeader); grp.info(_AdminBackend, gdat, pos); json_object *jobj = json_object_new_object(); json_object_object_add(jobj, "groupname", json_object_new_string(gdat.getName().c_str())); std::vector<uuid::uuid> mrecs; gdat.getMembers(mrecs); json_object *jmembers = json_object_new_array(); for (const auto &m : mrecs) json_object_array_add(jmembers, json_object_new_string(m.c_str())); json_object_object_add(jobj, "members", jmembers); json_object *jall = json_object_new_array(); User usr; std::vector<uuid::uuid> uids; usr.list(_AdminBackend, uids); for (const auto &uid : uids) { class UserData udat(uid); try { size_t up = sizeof(AuthHeader); usr.info(_AdminBackend, udat, up); json_object *ju = json_object_new_object(); 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(jall, ju); } catch (...) {} } json_object_object_add(jobj, "allusers", jall); sendJson(curreq, jobj); json_object_put(jobj); return; } std::string domain = domainNameFor(cdid); if (domain.empty() || !g_AdPlugin) throw AuthBackendError("getGroup: no directory for domain!"); Loading Loading @@ -984,6 +1171,27 @@ namespace fenrirds { /* ---- JSON API: Create Group (directory object) ---- */ void apiCreateGroup(libhttppp::HttpRequest &curreq, const char *cdid) { if (strcmp(cdid, "admin") == 0) { std::string reqbody = getRequestBody(curreq); json_object *jreq = json_tokener_parse(reqbody.c_str()); if (!jreq) throw AuthBackendError("createGroup: invalid JSON!"); json_object *jname = json_object_object_get(jreq, "groupname"); json_object *jmembers = json_object_object_get(jreq, "groupmembers"); uuid::uuid gid; gid.generate(); class GroupData gd(gid); if (jname) gd.setName(json_object_get_string(jname)); if (jmembers && json_object_get_type(jmembers) == json_type_array) for (int i = 0; i < json_object_array_length(jmembers); i++) gd.addMember(uuid::uuid(json_object_get_string(json_object_array_get_idx(jmembers, i)))); Group grp; grp.create(_AdminBackend, &gd); json_object_put(jreq); json_object *jobj = json_object_new_object(); json_object_object_add(jobj, "status", json_object_new_string("ok")); json_object_object_add(jobj, "gid", json_object_new_string(gid.c_str())); sendJson(curreq, jobj); json_object_put(jobj); return; } std::string domain = domainNameFor(cdid); if (domain.empty() || !g_AdPlugin) throw AuthBackendError("createGroup: no directory for domain!"); Loading Loading @@ -1029,6 +1237,16 @@ namespace fenrirds { /* ---- JSON API: Remove Group ---- */ void apiRemoveGroup(libhttppp::HttpRequest &curreq, const char *cdid, const char *cgid) { if (strcmp(cdid, "admin") == 0) { uuid::uuid gid; gid.parse(cgid); Group group; group.remove(_AdminBackend, gid); json_object *jok = json_object_new_object(); json_object_object_add(jok, "status", json_object_new_string("ok")); sendJson(curreq, jok); json_object_put(jok); return; } std::string domain = domainNameFor(cdid); if (domain.empty() || !g_AdPlugin) throw AuthBackendError("removeGroup: no directory for domain!"); Loading @@ -1047,6 +1265,27 @@ namespace fenrirds { /* ---- JSON API: Edit Group (reconcile membership) ---- */ void apiEditGroup(libhttppp::HttpRequest &curreq, const char *cdid, const char *cgid) { if (strcmp(cdid, "admin") == 0) { uuid::uuid gid(cgid); std::string reqbody = getRequestBody(curreq); json_object *jreq = json_tokener_parse(reqbody.c_str()); if (!jreq) throw AuthBackendError("editGroup: invalid JSON!"); json_object *jname = json_object_object_get(jreq, "groupname"); json_object *jmem = json_object_object_get(jreq, "groupmembers"); class GroupData editrec(gid); if (jname) editrec.setName(json_object_get_string(jname)); if (jmem && json_object_get_type(jmem) == json_type_array) for (int i = 0; i < json_object_array_length(jmem); i++) editrec.addMember(uuid::uuid(json_object_get_string(json_object_array_get_idx(jmem, i)))); Group grp; size_t pos = sizeof(AuthHeader); grp.edit(_AdminBackend, editrec, pos); json_object_put(jreq); json_object *jok = json_object_new_object(); json_object_object_add(jok, "status", json_object_new_string("ok")); sendJson(curreq, jok); json_object_put(jok); return; } std::string domain = domainNameFor(cdid); if (domain.empty() || !g_AdPlugin) throw AuthBackendError("editGroup: no directory for domain!"); Loading Loading
src/admin.cpp +239 −0 Changes for src/admin.cpp: 239 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -144,6 +144,35 @@ namespace fenrirds { /* ---- JSON API: List Users ---- */ void apiListUsers(libhttppp::HttpRequest &curreq, const char *cdid) { /* the admin console (admin.local) has no directory — its own * accounts (SuperAdmins) are native; list them from the backend */ if (strcmp(cdid, "admin") == 0) { json_object *jobj = json_object_new_object(); json_object *jarr = json_object_new_array(); User user; std::vector<uuid::uuid> uuids; user.list(_AdminBackend, uuids); for (const auto &uid : uuids) { class UserData udat(uid); try { size_t upos = sizeof(fenrirds::AuthHeader); user.info(_AdminBackend, udat, upos); json_object *juser = json_object_new_object(); 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 (...) {} try { json_object_object_add(juser, "mail", json_object_new_string(udat.getMail().c_str())); } catch (...) {} json_object_object_add(juser, "windowslogin", json_object_new_boolean(false)); json_object_array_add(jarr, juser); } catch (AuthBackendError &e) { std::cerr << e.what() << std::endl; } } json_object_object_add(jobj, "users", jarr); sendJson(curreq, jobj); json_object_put(jobj); return; } std::string domain = domainNameFor(cdid); if (domain.empty() || !g_AdPlugin) throw AuthBackendError("listUsers: no directory for domain!"); Loading Loading @@ -174,6 +203,32 @@ namespace fenrirds { /* ---- JSON API: Get User (for edit form) ---- */ void apiGetUser(libhttppp::HttpRequest &curreq, const char *cdid, const char *cuid) { if (strcmp(cdid, "admin") == 0) { /* admin console: native SuperAdmin account */ uuid::uuid uid; uid.parse(cuid); User user; class UserData udat(uid); size_t upos = sizeof(AuthHeader); user.info(_AdminBackend, udat, upos); json_object *jobj = json_object_new_object(); json_object *jfields = json_object_new_array(); auto af = [&](const char *name, const std::string &val) { json_object *jf = json_object_new_object(); json_object_object_add(jf, "name", json_object_new_string(name)); json_object_object_add(jf, "value", json_object_new_string(val.c_str())); json_object_array_add(jfields, jf); }; try { af("username", udat.getUsername()); } catch (...) {} try { af("firstname", udat.getFirstname()); } catch (...) {} try { af("lastname", udat.getLastname()); } catch (...) {} try { af("mail", udat.getMail()); } catch (...) {} json_object_object_add(jobj, "fields", jfields); json_object_object_add(jobj, "windowslogin", json_object_new_boolean(false)); sendJson(curreq, jobj); json_object_put(jobj); return; } std::string domain = domainNameFor(cdid); if (domain.empty() || !g_AdPlugin) throw AuthBackendError("getUser: no directory for domain!"); Loading Loading @@ -210,6 +265,46 @@ namespace fenrirds { /* ---- JSON API: Create User (directory object) ---- */ void apiCreateUser(libhttppp::HttpRequest &curreq, const char *cdid) { if (strcmp(cdid, "admin") == 0) { /* admin console: create a native SuperAdmin account */ libhttppp::HttpForm curform; curform.parse(curreq); uuid::uuid uid; uid.generate(); class UserData udat(uid); std::string uname, pw; for (const auto &fd : curform.multipartData()) { if (fd.value.empty()) continue; std::string name; for (const auto &d : fd.dispositions) { std::string k = d.key; std::transform(k.begin(), k.end(), k.begin(), [](unsigned char c){ return std::tolower(c); }); if (k == "name") name = d.value; } std::string val(fd.value.begin(), fd.value.end()); if (name == "username") { uname = val; udat.setUserName(val); } else if (name == "firstname") udat.setFirstName(val); else if (name == "lastname") udat.setLastName(val); else if (name == "mail") udat.setMail(val); else if (name == "pwhash") pw = val; } if (uname.empty()) throw AuthBackendError("username not set!"); if (!pw.empty()) { Hash h; std::string hh; h.hash(pw, hh); udat.setPwHash(hh); } User user; user.create(_AdminBackend, &udat); /* add to the native SuperAdmin group so it has admin rights */ Group group; std::vector<uuid::uuid> gids; group.list(_AdminBackend, gids); for (const auto &gid : gids) { class GroupData gd(gid); size_t gp = sizeof(AuthHeader); try { group.info(_AdminBackend, gd, gp); } catch (...) { continue; } if (gd.getName() == "SuperAdmin") { gd.addMember(uid); gp = sizeof(AuthHeader); group.edit(_AdminBackend, gd, gp); break; } } json_object *jobj = json_object_new_object(); json_object_object_add(jobj, "status", json_object_new_string("ok")); json_object_object_add(jobj, "uid", json_object_new_string(uid.c_str())); sendJson(curreq, jobj); json_object_put(jobj); return; } std::string domain = domainNameFor(cdid); if (domain.empty() || !g_AdPlugin) throw AuthBackendError("createUser: no directory for domain!"); Loading Loading @@ -282,6 +377,16 @@ namespace fenrirds { /* ---- JSON API: Remove User ---- */ void apiRemoveUser(libhttppp::HttpRequest &curreq, const char *cdid, const char *cuid) { if (strcmp(cdid, "admin") == 0) { uuid::uuid uid; uid.parse(cuid); User user; user.remove(_AdminBackend, uid); json_object *jok = json_object_new_object(); json_object_object_add(jok, "status", json_object_new_string("ok")); sendJson(curreq, jok); json_object_put(jok); return; } std::string domain = domainNameFor(cdid); if (domain.empty() || !g_AdPlugin) throw AuthBackendError("removeUser: no directory for domain!"); Loading @@ -300,6 +405,35 @@ namespace fenrirds { /* ---- JSON API: Edit User (directory object) ---- */ void apiEditUser(libhttppp::HttpRequest &curreq, const char *cdid, const char *cuid) { if (strcmp(cdid, "admin") == 0) { /* admin console: edit a native SuperAdmin account */ uuid::uuid uid; uid.parse(cuid); libhttppp::HttpForm curform; curform.parse(curreq); User user; class UserData udat(uid); size_t upos = sizeof(AuthHeader); user.info(_AdminBackend, udat, upos); for (const auto &fd : curform.multipartData()) { if (fd.value.empty()) continue; std::string name; for (const auto &d : fd.dispositions) { std::string k = d.key; std::transform(k.begin(), k.end(), k.begin(), [](unsigned char c){ return std::tolower(c); }); if (k == "name") name = d.value; } std::string val(fd.value.begin(), fd.value.end()); if (name == "firstname") udat.setFirstName(val); else if (name == "lastname") udat.setLastName(val); else if (name == "mail") udat.setMail(val); else if (name == "pwhash" && !val.empty()) { Hash h; std::string hh; h.hash(val, hh); udat.setPwHash(hh); } } upos = sizeof(AuthHeader); user.edit(_AdminBackend, udat, upos); json_object *jok = json_object_new_object(); json_object_object_add(jok, "status", json_object_new_string("ok")); sendJson(curreq, jok); json_object_put(jok); return; } std::string domain = domainNameFor(cdid); if (domain.empty() || !g_AdPlugin) throw AuthBackendError("editUser: no directory for domain!"); Loading Loading @@ -912,6 +1046,31 @@ namespace fenrirds { /* ---- JSON API: List Groups ---- */ void apiListGroups(libhttppp::HttpRequest &curreq, const char *cdid) { if (strcmp(cdid, "admin") == 0) { /* admin console: native groups (e.g. SuperAdmin) */ json_object *jobj = json_object_new_object(); json_object *jarr = json_object_new_array(); Group group; std::vector<uuid::uuid> gids; group.list(_AdminBackend, gids); for (const auto &gid : gids) { class GroupData gdat(gid); try { size_t gpos = sizeof(fenrirds::AuthHeader); group.info(_AdminBackend, gdat, gpos); json_object *jgrp = json_object_new_object(); 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_object_add(jgrp, "windowslogin", json_object_new_boolean(false)); 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); return; } std::string domain = domainNameFor(cdid); if (domain.empty() || !g_AdPlugin) throw AuthBackendError("listGroups: no directory for domain!"); Loading @@ -937,6 +1096,34 @@ namespace fenrirds { /* ---- JSON API: Get Group (for edit) ---- */ void apiGetGroup(libhttppp::HttpRequest &curreq, const char *cdid, const char *cgid) { if (strcmp(cdid, "admin") == 0) { /* admin console: native group + native member picker */ uuid::uuid gid(cgid); class GroupData gdat(gid); Group grp; size_t pos = sizeof(AuthHeader); grp.info(_AdminBackend, gdat, pos); json_object *jobj = json_object_new_object(); json_object_object_add(jobj, "groupname", json_object_new_string(gdat.getName().c_str())); std::vector<uuid::uuid> mrecs; gdat.getMembers(mrecs); json_object *jmembers = json_object_new_array(); for (const auto &m : mrecs) json_object_array_add(jmembers, json_object_new_string(m.c_str())); json_object_object_add(jobj, "members", jmembers); json_object *jall = json_object_new_array(); User usr; std::vector<uuid::uuid> uids; usr.list(_AdminBackend, uids); for (const auto &uid : uids) { class UserData udat(uid); try { size_t up = sizeof(AuthHeader); usr.info(_AdminBackend, udat, up); json_object *ju = json_object_new_object(); 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(jall, ju); } catch (...) {} } json_object_object_add(jobj, "allusers", jall); sendJson(curreq, jobj); json_object_put(jobj); return; } std::string domain = domainNameFor(cdid); if (domain.empty() || !g_AdPlugin) throw AuthBackendError("getGroup: no directory for domain!"); Loading Loading @@ -984,6 +1171,27 @@ namespace fenrirds { /* ---- JSON API: Create Group (directory object) ---- */ void apiCreateGroup(libhttppp::HttpRequest &curreq, const char *cdid) { if (strcmp(cdid, "admin") == 0) { std::string reqbody = getRequestBody(curreq); json_object *jreq = json_tokener_parse(reqbody.c_str()); if (!jreq) throw AuthBackendError("createGroup: invalid JSON!"); json_object *jname = json_object_object_get(jreq, "groupname"); json_object *jmembers = json_object_object_get(jreq, "groupmembers"); uuid::uuid gid; gid.generate(); class GroupData gd(gid); if (jname) gd.setName(json_object_get_string(jname)); if (jmembers && json_object_get_type(jmembers) == json_type_array) for (int i = 0; i < json_object_array_length(jmembers); i++) gd.addMember(uuid::uuid(json_object_get_string(json_object_array_get_idx(jmembers, i)))); Group grp; grp.create(_AdminBackend, &gd); json_object_put(jreq); json_object *jobj = json_object_new_object(); json_object_object_add(jobj, "status", json_object_new_string("ok")); json_object_object_add(jobj, "gid", json_object_new_string(gid.c_str())); sendJson(curreq, jobj); json_object_put(jobj); return; } std::string domain = domainNameFor(cdid); if (domain.empty() || !g_AdPlugin) throw AuthBackendError("createGroup: no directory for domain!"); Loading Loading @@ -1029,6 +1237,16 @@ namespace fenrirds { /* ---- JSON API: Remove Group ---- */ void apiRemoveGroup(libhttppp::HttpRequest &curreq, const char *cdid, const char *cgid) { if (strcmp(cdid, "admin") == 0) { uuid::uuid gid; gid.parse(cgid); Group group; group.remove(_AdminBackend, gid); json_object *jok = json_object_new_object(); json_object_object_add(jok, "status", json_object_new_string("ok")); sendJson(curreq, jok); json_object_put(jok); return; } std::string domain = domainNameFor(cdid); if (domain.empty() || !g_AdPlugin) throw AuthBackendError("removeGroup: no directory for domain!"); Loading @@ -1047,6 +1265,27 @@ namespace fenrirds { /* ---- JSON API: Edit Group (reconcile membership) ---- */ void apiEditGroup(libhttppp::HttpRequest &curreq, const char *cdid, const char *cgid) { if (strcmp(cdid, "admin") == 0) { uuid::uuid gid(cgid); std::string reqbody = getRequestBody(curreq); json_object *jreq = json_tokener_parse(reqbody.c_str()); if (!jreq) throw AuthBackendError("editGroup: invalid JSON!"); json_object *jname = json_object_object_get(jreq, "groupname"); json_object *jmem = json_object_object_get(jreq, "groupmembers"); class GroupData editrec(gid); if (jname) editrec.setName(json_object_get_string(jname)); if (jmem && json_object_get_type(jmem) == json_type_array) for (int i = 0; i < json_object_array_length(jmem); i++) editrec.addMember(uuid::uuid(json_object_get_string(json_object_array_get_idx(jmem, i)))); Group grp; size_t pos = sizeof(AuthHeader); grp.edit(_AdminBackend, editrec, pos); json_object_put(jreq); json_object *jok = json_object_new_object(); json_object_object_add(jok, "status", json_object_new_string("ok")); sendJson(curreq, jok); json_object_put(jok); return; } std::string domain = domainNameFor(cdid); if (domain.empty() || !g_AdPlugin) throw AuthBackendError("editGroup: no directory for domain!"); Loading