Loading editor/html/js/editor.js +4 −4 Original line number Diff line number Diff line Loading @@ -345,10 +345,10 @@ nameSpan.textContent = '#' + rev.revision + ' — ' + rev.name; info.appendChild(nameSpan); var dateSpan = document.createElement('div'); dateSpan.className = 'doc-item-date'; dateSpan.textContent = rev.created || ''; info.appendChild(dateSpan); var metaSpan = document.createElement('div'); metaSpan.className = 'doc-item-date'; metaSpan.textContent = (rev.author || '') + (rev.author && rev.created ? ' · ' : '') + (rev.created || ''); info.appendChild(metaSpan); item.appendChild(info); Loading editor/src/webedit_api.cpp +6 −2 Original line number Diff line number Diff line Loading @@ -765,11 +765,15 @@ void webedit::Api::handleSaveDocument(libhttppp::HttpRequest &curreq, std::string xml = exportTreeXml(doc); std::string docId; // Get author from session std::string author; _session.getData(sessionid, "username", author); if (doc.currentDocId.empty()) { docId = _db.saveDocument(doc.currentDocName, xml); docId = _db.saveDocument(doc.currentDocName, xml, author); doc.currentDocId = docId; } else { docId = _db.updateDocument(doc.currentDocId, doc.currentDocName, xml); docId = _db.updateDocument(doc.currentDocId, doc.currentDocName, xml, author); } json_object *resp = json_object_new_object(); Loading editor/src/webedit_db.cpp +15 −7 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ void webedit::Database::initTables() { << "revision integer NOT NULL," << "name varchar(255) NOT NULL," << "xml text NOT NULL," << "author varchar(255) DEFAULT ''," << "created timestamp DEFAULT CURRENT_TIMESTAMP," << "PRIMARY KEY (id)," << "FOREIGN KEY (document_id) REFERENCES documents (id)" Loading @@ -94,7 +95,8 @@ void webedit::Database::initTables() { _db->exec(sql, res); } std::string webedit::Database::saveDocument(const std::string &name, const std::string &xml) { std::string webedit::Database::saveDocument(const std::string &name, const std::string &xml, const std::string &author) { uuid::uuid docId; docId.generate(); Loading @@ -116,12 +118,14 @@ std::string webedit::Database::saveDocument(const std::string &name, const std:: res.clear(); escapedName.clear(); escapedXml.clear(); std::vector<char> escapedAuthor; sql << "INSERT INTO document_revisions (id, document_id, revision, name, xml) VALUES ('" sql << "INSERT INTO document_revisions (id, document_id, revision, name, xml, author) VALUES ('" << revId.c_str() << "','" << docId.c_str() << "',1,'" << dbpp::SQL::escaped(escapedName, name.c_str()) << "','" << dbpp::SQL::escaped(escapedXml, xml.c_str()) << "');"; << dbpp::SQL::escaped(escapedXml, xml.c_str()) << "','" << dbpp::SQL::escaped(escapedAuthor, author.c_str()) << "');"; _db->exec(sql, res); Loading @@ -130,7 +134,8 @@ std::string webedit::Database::saveDocument(const std::string &name, const std:: std::string webedit::Database::updateDocument(const std::string &id, const std::string &name, const std::string &xml) { const std::string &xml, const std::string &author) { dbpp::SQL sql; dbpp::DBResult res; std::vector<char> escapedName, escapedXml, escapedId; Loading Loading @@ -165,13 +170,15 @@ std::string webedit::Database::updateDocument(const std::string &id, escapedName.clear(); escapedXml.clear(); escapedId.clear(); std::vector<char> escapedAuthor; sql << "INSERT INTO document_revisions (id, document_id, revision, name, xml) VALUES ('" sql << "INSERT INTO document_revisions (id, document_id, revision, name, xml, author) VALUES ('" << revId.c_str() << "','" << dbpp::SQL::escaped(escapedId, id.c_str()) << "'," << nextRev << ",'" << dbpp::SQL::escaped(escapedName, name.c_str()) << "','" << dbpp::SQL::escaped(escapedXml, xml.c_str()) << "');"; << dbpp::SQL::escaped(escapedXml, xml.c_str()) << "','" << dbpp::SQL::escaped(escapedAuthor, author.c_str()) << "');"; _db->exec(sql, res); Loading Loading @@ -246,7 +253,7 @@ std::string webedit::Database::listRevisions(const std::string &docId) { dbpp::DBResult res; std::vector<char> escapedId; sql << "SELECT id, revision, name, created FROM document_revisions WHERE document_id='" sql << "SELECT id, revision, name, created, author FROM document_revisions WHERE document_id='" << dbpp::SQL::escaped(escapedId, docId.c_str()) << "' ORDER BY revision DESC;"; Loading @@ -260,6 +267,7 @@ std::string webedit::Database::listRevisions(const std::string &docId) { json_object_object_add(obj, "revision", json_object_new_int(std::stoi(std::string(res[i][1])))); json_object_object_add(obj, "name", json_object_new_string(res[i][2])); json_object_object_add(obj, "created", json_object_new_string(res[i][3])); json_object_object_add(obj, "author", json_object_new_string(res[i][4])); json_object_array_add(arr, obj); } Loading editor/src/webedit_db.h +3 −2 Original line number Diff line number Diff line Loading @@ -41,9 +41,10 @@ namespace webedit { void initTables(); // Document CRUD std::string saveDocument(const std::string &name, const std::string &xml); std::string saveDocument(const std::string &name, const std::string &xml, const std::string &author = ""); std::string updateDocument(const std::string &id, const std::string &name, const std::string &xml); const std::string &xml, const std::string &author = ""); bool loadDocument(const std::string &id, std::string &name, std::string &xml); bool deleteDocument(const std::string &id); std::string listDocuments(); // Returns JSON array Loading editor/src/webedit_server.cpp +89 −45 Original line number Diff line number Diff line Loading @@ -48,6 +48,16 @@ webedit::Server::Server(std::vector<netplus::socket*> serversocket, _session(db.getDb()), _api(db, _session, plugins), _plugins(plugins) { // Create connection pools for each auth source for (size_t i = 0; i < _config.getAuthSourceCount(); ++i) { const auto &src = _config.getAuthSource(i); _authPools.push_back(std::make_unique<authdb::client::ConnectionPool>( src.url, src.clientName, src.clientSecret, 4)); } // Auto-create login GPO on all auth sources initGPO(); } webedit::Server::~Server() { Loading Loading @@ -219,26 +229,30 @@ void webedit::Server::sendJsonResponse(libhttppp::HttpRequest &curreq, } bool webedit::Server::isAuthenticated(const std::string &authid) { if (authid.empty() || _config.getAuthSourceCount() == 0) if (authid.empty() || _authPools.empty()) return false; uuid::uuid sid(authid.c_str()); for (size_t i = 0; i < _config.getAuthSourceCount(); ++i) { const auto &src = _config.getAuthSource(i); for (size_t i = 0; i < _authPools.size(); ++i) { try { authdb::client::ClientConnection authcon; authcon.setUrl(src.url); authcon.setClientName(src.clientName); authcon.setClientSecret(src.clientSecret); authcon.setSessionID(sid); auto pooled = _authPools[i]->acquire(); pooled.setSessionID(sid); authdb::client::Client clt(authcon); if (clt.ClientAuth() && clt.GPOcheck(uuid::uuid("e7d3b8b3-4825-11f0-ae2b-3cecefce9cb6"))) { try { if (pooled.client().ClientAuth() && pooled.client().GPOcheck(uuid::uuid("e7d3b8b3-4825-11f0-ae2b-3cecefce9cb6"))) { return true; } } catch (...) { // Reconnect and retry once pooled.connection().reConnect(); pooled.setSessionID(sid); if (pooled.client().ClientAuth() && pooled.client().GPOcheck(uuid::uuid("e7d3b8b3-4825-11f0-ae2b-3cecefce9cb6"))) { return true; } } } catch (...) { continue; } Loading @@ -248,7 +262,7 @@ bool webedit::Server::isAuthenticated(const std::string &authid) { void webedit::Server::handleLogin(libhttppp::HttpRequest &curreq, const std::string &sessionid) { if (_config.getAuthSourceCount() == 0) { if (_authPools.empty()) { sendJsonResponse(curreq, HTTP500, "{\"error\":\"No auth source configured\"}"); return; Loading Loading @@ -293,45 +307,56 @@ void webedit::Server::handleLogin(libhttppp::HttpRequest &curreq, return; } try { authdb::client::ClientConnection authcon; authcon.setUrl(src->url); authcon.setClientName(src->clientName); authcon.setClientSecret(src->clientSecret); // Find the pool index for this auth source size_t poolIdx = 0; for (size_t i = 0; i < _config.getAuthSourceCount(); ++i) { if (&_config.getAuthSource(i) == src) { poolIdx = i; break; } } authdb::client::Client clt(authcon); try { auto pooled = _authPools[poolIdx]->acquire(); if (!clt.ClientAuth()) { if (!pooled.client().ClientAuth()) { sendJsonResponse(curreq, HTTP500, "{\"error\":\"Client authentication failed\"}"); return; } authcon.setUsername(user); authcon.setUserPassword(password); pooled.connection().setUsername(user); pooled.connection().setUserPassword(password); if (!clt.UserAuth()) { if (!pooled.client().UserAuth()) { sendJsonResponse(curreq, HTTP401, "{\"error\":\"Invalid credentials\"}"); return; } // Check GPO "Allow Login" if (!clt.GPOcheck(uuid::uuid("e7d3b8b3-4825-11f0-ae2b-3cecefce9cb6"))) { clt.remSession(); if (!pooled.client().GPOcheck(uuid::uuid("e7d3b8b3-4825-11f0-ae2b-3cecefce9cb6"))) { pooled.client().remSession(); sendJsonResponse(curreq, HTTP403, "{\"error\":\"Login not permitted\"}"); return; } // Store authid in session std::string authid = authcon.getSessionID().c_str(); std::string authid = pooled.connection().getSessionID().c_str(); _session.addData(sessionid, "authid", authid); // Get user info // Get user info and store in session authdb::SessionData sdat; clt.SessionInfo(sdat); pooled.client().SessionInfo(sdat); std::string displayname = sdat.getUsername(); uuid::uuid uid; sdat.getUid(uid); std::string uidStr = uid.c_str(); _session.addData(sessionid, "uid", uidStr); _session.addData(sessionid, "username", displayname); // Set authid cookie and return success libhttppp::HttpResponse resp; Loading @@ -345,17 +370,18 @@ void webedit::Server::handleLogin(libhttppp::HttpRequest &curreq, json_object *result = json_object_new_object(); json_object_object_add(result, "status", json_object_new_string("ok")); json_object_object_add(result, "username", json_object_new_string(displayname.c_str())); json_object_object_add(result, "uid", json_object_new_string(uidStr.c_str())); const char *jsonStr = json_object_to_json_string_ext(result, JSON_C_TO_STRING_PLAIN); resp.send(curreq, jsonStr, strlen(jsonStr)); json_object_put(result); } catch (authdb::AuthBackendError &e) { sendJsonResponse(curreq, HTTP500, std::string("{\"error\":\"Auth error: ") + e.what() + "\"}"); } catch (std::exception &e) { sendJsonResponse(curreq, HTTP401, std::string("{\"error\":\"") + e.what() + "\"}"); json_object *errResp = json_object_new_object(); json_object_object_add(errResp, "error", json_object_new_string(e.what())); const char *errStr = json_object_to_json_string_ext(errResp, JSON_C_TO_STRING_PLAIN); sendJsonResponse(curreq, HTTP401, errStr); json_object_put(errResp); } } Loading @@ -366,24 +392,20 @@ void webedit::Server::handleLogout(libhttppp::HttpRequest &curreq, if (!authid.empty()) { // Remove authdb session uuid::uuid sid(authid.c_str()); for (size_t i = 0; i < _config.getAuthSourceCount(); ++i) { const auto &src = _config.getAuthSource(i); for (size_t i = 0; i < _authPools.size(); ++i) { try { authdb::client::ClientConnection authcon; authcon.setUrl(src.url); authcon.setClientName(src.clientName); authcon.setClientSecret(src.clientSecret); authcon.setSessionID(sid); authdb::client::Client clt(authcon); if (clt.ClientAuth()) { clt.remSession(); auto pooled = _authPools[i]->acquire(); pooled.setSessionID(sid); if (pooled.client().ClientAuth()) { pooled.client().remSession(); break; } } catch (...) {} } _session.delData(sessionid, "authid"); _session.delData(sessionid, "uid"); _session.delData(sessionid, "username"); } // Clear the authid cookie Loading Loading @@ -431,6 +453,28 @@ void webedit::Server::handleI18n(libhttppp::HttpRequest &curreq) { json_object_put(obj); } void webedit::Server::initGPO() { const uuid::uuid loginGpoId("e7d3b8b3-4825-11f0-ae2b-3cecefce9cb6"); for (size_t i = 0; i < _authPools.size(); ++i) { try { auto pooled = _authPools[i]->acquire(); if (!pooled.client().ClientAuth()) continue; if (!pooled.client().GPOexits(loginGpoId)) { std::vector<std::string> members; pooled.client().GPOadd(loginGpoId, "Blogi: Allow Login", "Allow Login to webinterface", true, members); std::cout << "Created GPO 'Blogi: Allow Login' on auth source: " << _config.getAuthSource(i).domain << std::endl; } } catch (std::exception &e) { std::cerr << "Warning: could not ensure login GPO on auth source '" << _config.getAuthSource(i).domain << "': " << e.what() << std::endl; } } } std::string webedit::Server::getMimeType(const std::string &path) { if (path.ends_with(".html") || path.ends_with(".htm")) return "text/html; charset=utf-8"; Loading Loading
editor/html/js/editor.js +4 −4 Original line number Diff line number Diff line Loading @@ -345,10 +345,10 @@ nameSpan.textContent = '#' + rev.revision + ' — ' + rev.name; info.appendChild(nameSpan); var dateSpan = document.createElement('div'); dateSpan.className = 'doc-item-date'; dateSpan.textContent = rev.created || ''; info.appendChild(dateSpan); var metaSpan = document.createElement('div'); metaSpan.className = 'doc-item-date'; metaSpan.textContent = (rev.author || '') + (rev.author && rev.created ? ' · ' : '') + (rev.created || ''); info.appendChild(metaSpan); item.appendChild(info); Loading
editor/src/webedit_api.cpp +6 −2 Original line number Diff line number Diff line Loading @@ -765,11 +765,15 @@ void webedit::Api::handleSaveDocument(libhttppp::HttpRequest &curreq, std::string xml = exportTreeXml(doc); std::string docId; // Get author from session std::string author; _session.getData(sessionid, "username", author); if (doc.currentDocId.empty()) { docId = _db.saveDocument(doc.currentDocName, xml); docId = _db.saveDocument(doc.currentDocName, xml, author); doc.currentDocId = docId; } else { docId = _db.updateDocument(doc.currentDocId, doc.currentDocName, xml); docId = _db.updateDocument(doc.currentDocId, doc.currentDocName, xml, author); } json_object *resp = json_object_new_object(); Loading
editor/src/webedit_db.cpp +15 −7 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ void webedit::Database::initTables() { << "revision integer NOT NULL," << "name varchar(255) NOT NULL," << "xml text NOT NULL," << "author varchar(255) DEFAULT ''," << "created timestamp DEFAULT CURRENT_TIMESTAMP," << "PRIMARY KEY (id)," << "FOREIGN KEY (document_id) REFERENCES documents (id)" Loading @@ -94,7 +95,8 @@ void webedit::Database::initTables() { _db->exec(sql, res); } std::string webedit::Database::saveDocument(const std::string &name, const std::string &xml) { std::string webedit::Database::saveDocument(const std::string &name, const std::string &xml, const std::string &author) { uuid::uuid docId; docId.generate(); Loading @@ -116,12 +118,14 @@ std::string webedit::Database::saveDocument(const std::string &name, const std:: res.clear(); escapedName.clear(); escapedXml.clear(); std::vector<char> escapedAuthor; sql << "INSERT INTO document_revisions (id, document_id, revision, name, xml) VALUES ('" sql << "INSERT INTO document_revisions (id, document_id, revision, name, xml, author) VALUES ('" << revId.c_str() << "','" << docId.c_str() << "',1,'" << dbpp::SQL::escaped(escapedName, name.c_str()) << "','" << dbpp::SQL::escaped(escapedXml, xml.c_str()) << "');"; << dbpp::SQL::escaped(escapedXml, xml.c_str()) << "','" << dbpp::SQL::escaped(escapedAuthor, author.c_str()) << "');"; _db->exec(sql, res); Loading @@ -130,7 +134,8 @@ std::string webedit::Database::saveDocument(const std::string &name, const std:: std::string webedit::Database::updateDocument(const std::string &id, const std::string &name, const std::string &xml) { const std::string &xml, const std::string &author) { dbpp::SQL sql; dbpp::DBResult res; std::vector<char> escapedName, escapedXml, escapedId; Loading Loading @@ -165,13 +170,15 @@ std::string webedit::Database::updateDocument(const std::string &id, escapedName.clear(); escapedXml.clear(); escapedId.clear(); std::vector<char> escapedAuthor; sql << "INSERT INTO document_revisions (id, document_id, revision, name, xml) VALUES ('" sql << "INSERT INTO document_revisions (id, document_id, revision, name, xml, author) VALUES ('" << revId.c_str() << "','" << dbpp::SQL::escaped(escapedId, id.c_str()) << "'," << nextRev << ",'" << dbpp::SQL::escaped(escapedName, name.c_str()) << "','" << dbpp::SQL::escaped(escapedXml, xml.c_str()) << "');"; << dbpp::SQL::escaped(escapedXml, xml.c_str()) << "','" << dbpp::SQL::escaped(escapedAuthor, author.c_str()) << "');"; _db->exec(sql, res); Loading Loading @@ -246,7 +253,7 @@ std::string webedit::Database::listRevisions(const std::string &docId) { dbpp::DBResult res; std::vector<char> escapedId; sql << "SELECT id, revision, name, created FROM document_revisions WHERE document_id='" sql << "SELECT id, revision, name, created, author FROM document_revisions WHERE document_id='" << dbpp::SQL::escaped(escapedId, docId.c_str()) << "' ORDER BY revision DESC;"; Loading @@ -260,6 +267,7 @@ std::string webedit::Database::listRevisions(const std::string &docId) { json_object_object_add(obj, "revision", json_object_new_int(std::stoi(std::string(res[i][1])))); json_object_object_add(obj, "name", json_object_new_string(res[i][2])); json_object_object_add(obj, "created", json_object_new_string(res[i][3])); json_object_object_add(obj, "author", json_object_new_string(res[i][4])); json_object_array_add(arr, obj); } Loading
editor/src/webedit_db.h +3 −2 Original line number Diff line number Diff line Loading @@ -41,9 +41,10 @@ namespace webedit { void initTables(); // Document CRUD std::string saveDocument(const std::string &name, const std::string &xml); std::string saveDocument(const std::string &name, const std::string &xml, const std::string &author = ""); std::string updateDocument(const std::string &id, const std::string &name, const std::string &xml); const std::string &xml, const std::string &author = ""); bool loadDocument(const std::string &id, std::string &name, std::string &xml); bool deleteDocument(const std::string &id); std::string listDocuments(); // Returns JSON array Loading
editor/src/webedit_server.cpp +89 −45 Original line number Diff line number Diff line Loading @@ -48,6 +48,16 @@ webedit::Server::Server(std::vector<netplus::socket*> serversocket, _session(db.getDb()), _api(db, _session, plugins), _plugins(plugins) { // Create connection pools for each auth source for (size_t i = 0; i < _config.getAuthSourceCount(); ++i) { const auto &src = _config.getAuthSource(i); _authPools.push_back(std::make_unique<authdb::client::ConnectionPool>( src.url, src.clientName, src.clientSecret, 4)); } // Auto-create login GPO on all auth sources initGPO(); } webedit::Server::~Server() { Loading Loading @@ -219,26 +229,30 @@ void webedit::Server::sendJsonResponse(libhttppp::HttpRequest &curreq, } bool webedit::Server::isAuthenticated(const std::string &authid) { if (authid.empty() || _config.getAuthSourceCount() == 0) if (authid.empty() || _authPools.empty()) return false; uuid::uuid sid(authid.c_str()); for (size_t i = 0; i < _config.getAuthSourceCount(); ++i) { const auto &src = _config.getAuthSource(i); for (size_t i = 0; i < _authPools.size(); ++i) { try { authdb::client::ClientConnection authcon; authcon.setUrl(src.url); authcon.setClientName(src.clientName); authcon.setClientSecret(src.clientSecret); authcon.setSessionID(sid); auto pooled = _authPools[i]->acquire(); pooled.setSessionID(sid); authdb::client::Client clt(authcon); if (clt.ClientAuth() && clt.GPOcheck(uuid::uuid("e7d3b8b3-4825-11f0-ae2b-3cecefce9cb6"))) { try { if (pooled.client().ClientAuth() && pooled.client().GPOcheck(uuid::uuid("e7d3b8b3-4825-11f0-ae2b-3cecefce9cb6"))) { return true; } } catch (...) { // Reconnect and retry once pooled.connection().reConnect(); pooled.setSessionID(sid); if (pooled.client().ClientAuth() && pooled.client().GPOcheck(uuid::uuid("e7d3b8b3-4825-11f0-ae2b-3cecefce9cb6"))) { return true; } } } catch (...) { continue; } Loading @@ -248,7 +262,7 @@ bool webedit::Server::isAuthenticated(const std::string &authid) { void webedit::Server::handleLogin(libhttppp::HttpRequest &curreq, const std::string &sessionid) { if (_config.getAuthSourceCount() == 0) { if (_authPools.empty()) { sendJsonResponse(curreq, HTTP500, "{\"error\":\"No auth source configured\"}"); return; Loading Loading @@ -293,45 +307,56 @@ void webedit::Server::handleLogin(libhttppp::HttpRequest &curreq, return; } try { authdb::client::ClientConnection authcon; authcon.setUrl(src->url); authcon.setClientName(src->clientName); authcon.setClientSecret(src->clientSecret); // Find the pool index for this auth source size_t poolIdx = 0; for (size_t i = 0; i < _config.getAuthSourceCount(); ++i) { if (&_config.getAuthSource(i) == src) { poolIdx = i; break; } } authdb::client::Client clt(authcon); try { auto pooled = _authPools[poolIdx]->acquire(); if (!clt.ClientAuth()) { if (!pooled.client().ClientAuth()) { sendJsonResponse(curreq, HTTP500, "{\"error\":\"Client authentication failed\"}"); return; } authcon.setUsername(user); authcon.setUserPassword(password); pooled.connection().setUsername(user); pooled.connection().setUserPassword(password); if (!clt.UserAuth()) { if (!pooled.client().UserAuth()) { sendJsonResponse(curreq, HTTP401, "{\"error\":\"Invalid credentials\"}"); return; } // Check GPO "Allow Login" if (!clt.GPOcheck(uuid::uuid("e7d3b8b3-4825-11f0-ae2b-3cecefce9cb6"))) { clt.remSession(); if (!pooled.client().GPOcheck(uuid::uuid("e7d3b8b3-4825-11f0-ae2b-3cecefce9cb6"))) { pooled.client().remSession(); sendJsonResponse(curreq, HTTP403, "{\"error\":\"Login not permitted\"}"); return; } // Store authid in session std::string authid = authcon.getSessionID().c_str(); std::string authid = pooled.connection().getSessionID().c_str(); _session.addData(sessionid, "authid", authid); // Get user info // Get user info and store in session authdb::SessionData sdat; clt.SessionInfo(sdat); pooled.client().SessionInfo(sdat); std::string displayname = sdat.getUsername(); uuid::uuid uid; sdat.getUid(uid); std::string uidStr = uid.c_str(); _session.addData(sessionid, "uid", uidStr); _session.addData(sessionid, "username", displayname); // Set authid cookie and return success libhttppp::HttpResponse resp; Loading @@ -345,17 +370,18 @@ void webedit::Server::handleLogin(libhttppp::HttpRequest &curreq, json_object *result = json_object_new_object(); json_object_object_add(result, "status", json_object_new_string("ok")); json_object_object_add(result, "username", json_object_new_string(displayname.c_str())); json_object_object_add(result, "uid", json_object_new_string(uidStr.c_str())); const char *jsonStr = json_object_to_json_string_ext(result, JSON_C_TO_STRING_PLAIN); resp.send(curreq, jsonStr, strlen(jsonStr)); json_object_put(result); } catch (authdb::AuthBackendError &e) { sendJsonResponse(curreq, HTTP500, std::string("{\"error\":\"Auth error: ") + e.what() + "\"}"); } catch (std::exception &e) { sendJsonResponse(curreq, HTTP401, std::string("{\"error\":\"") + e.what() + "\"}"); json_object *errResp = json_object_new_object(); json_object_object_add(errResp, "error", json_object_new_string(e.what())); const char *errStr = json_object_to_json_string_ext(errResp, JSON_C_TO_STRING_PLAIN); sendJsonResponse(curreq, HTTP401, errStr); json_object_put(errResp); } } Loading @@ -366,24 +392,20 @@ void webedit::Server::handleLogout(libhttppp::HttpRequest &curreq, if (!authid.empty()) { // Remove authdb session uuid::uuid sid(authid.c_str()); for (size_t i = 0; i < _config.getAuthSourceCount(); ++i) { const auto &src = _config.getAuthSource(i); for (size_t i = 0; i < _authPools.size(); ++i) { try { authdb::client::ClientConnection authcon; authcon.setUrl(src.url); authcon.setClientName(src.clientName); authcon.setClientSecret(src.clientSecret); authcon.setSessionID(sid); authdb::client::Client clt(authcon); if (clt.ClientAuth()) { clt.remSession(); auto pooled = _authPools[i]->acquire(); pooled.setSessionID(sid); if (pooled.client().ClientAuth()) { pooled.client().remSession(); break; } } catch (...) {} } _session.delData(sessionid, "authid"); _session.delData(sessionid, "uid"); _session.delData(sessionid, "username"); } // Clear the authid cookie Loading Loading @@ -431,6 +453,28 @@ void webedit::Server::handleI18n(libhttppp::HttpRequest &curreq) { json_object_put(obj); } void webedit::Server::initGPO() { const uuid::uuid loginGpoId("e7d3b8b3-4825-11f0-ae2b-3cecefce9cb6"); for (size_t i = 0; i < _authPools.size(); ++i) { try { auto pooled = _authPools[i]->acquire(); if (!pooled.client().ClientAuth()) continue; if (!pooled.client().GPOexits(loginGpoId)) { std::vector<std::string> members; pooled.client().GPOadd(loginGpoId, "Blogi: Allow Login", "Allow Login to webinterface", true, members); std::cout << "Created GPO 'Blogi: Allow Login' on auth source: " << _config.getAuthSource(i).domain << std::endl; } } catch (std::exception &e) { std::cerr << "Warning: could not ensure login GPO on auth source '" << _config.getAuthSource(i).domain << "': " << e.what() << std::endl; } } } std::string webedit::Server::getMimeType(const std::string &path) { if (path.ends_with(".html") || path.ends_with(".htm")) return "text/html; charset=utf-8"; Loading