Replace master branch with local files
This commit is contained in:
commit
875a53f499
60 changed files with 21637 additions and 0 deletions
181
backend/src/controllers/AdminController.cpp
Normal file
181
backend/src/controllers/AdminController.cpp
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
#include "AdminController.h"
|
||||
#include "../services/OmeClient.h"
|
||||
#include "../services/RedisHelper.h"
|
||||
|
||||
using namespace drogon::orm;
|
||||
|
||||
namespace {
|
||||
HttpResponsePtr jsonResp(const Json::Value& j, HttpStatusCode c = k200OK) {
|
||||
auto r = HttpResponse::newHttpJsonResponse(j);
|
||||
r->setStatusCode(c);
|
||||
return r;
|
||||
}
|
||||
|
||||
HttpResponsePtr jsonError(const std::string& error, HttpStatusCode code = k400BadRequest) {
|
||||
Json::Value j;
|
||||
j["success"] = false;
|
||||
j["error"] = error;
|
||||
return jsonResp(j, code);
|
||||
}
|
||||
}
|
||||
|
||||
UserInfo AdminController::getUserFromRequest(const HttpRequestPtr &req) {
|
||||
UserInfo user;
|
||||
std::string auth = req->getHeader("Authorization");
|
||||
|
||||
if (auth.empty() || auth.substr(0, 7) != "Bearer ") {
|
||||
return user;
|
||||
}
|
||||
|
||||
std::string token = auth.substr(7);
|
||||
AuthService::getInstance().validateToken(token, user);
|
||||
return user;
|
||||
}
|
||||
|
||||
void AdminController::getUsers(const HttpRequestPtr &req,
|
||||
std::function<void(const HttpResponsePtr &)> &&callback) {
|
||||
UserInfo user = getUserFromRequest(req);
|
||||
if (user.id == 0 || !user.isAdmin) {
|
||||
callback(jsonError("Unauthorized", k403Forbidden));
|
||||
return;
|
||||
}
|
||||
|
||||
auto dbClient = app().getDbClient();
|
||||
*dbClient << "SELECT u.id, u.username, u.is_admin, u.is_streamer, u.created_at, "
|
||||
"(SELECT COUNT(*) FROM realms WHERE user_id = u.id) as realm_count "
|
||||
"FROM users u ORDER BY u.created_at DESC"
|
||||
>> [callback](const Result& r) {
|
||||
Json::Value resp;
|
||||
resp["success"] = true;
|
||||
Json::Value users(Json::arrayValue);
|
||||
|
||||
for (const auto& row : r) {
|
||||
Json::Value user;
|
||||
user["id"] = static_cast<Json::Int64>(row["id"].as<int64_t>());
|
||||
user["username"] = row["username"].as<std::string>();
|
||||
user["isAdmin"] = row["is_admin"].as<bool>();
|
||||
user["isStreamer"] = row["is_streamer"].as<bool>();
|
||||
user["createdAt"] = row["created_at"].as<std::string>();
|
||||
user["realmCount"] = static_cast<Json::Int64>(row["realm_count"].as<int64_t>());
|
||||
users.append(user);
|
||||
}
|
||||
|
||||
resp["users"] = users;
|
||||
callback(jsonResp(resp));
|
||||
}
|
||||
>> [callback](const DrogonDbException& e) {
|
||||
LOG_ERROR << "Failed to get users: " << e.base().what();
|
||||
callback(jsonError("Failed to get users"));
|
||||
};
|
||||
}
|
||||
|
||||
void AdminController::getActiveStreams(const HttpRequestPtr &req,
|
||||
std::function<void(const HttpResponsePtr &)> &&callback) {
|
||||
UserInfo user = getUserFromRequest(req);
|
||||
if (user.id == 0 || !user.isAdmin) {
|
||||
callback(jsonError("Unauthorized", k403Forbidden));
|
||||
return;
|
||||
}
|
||||
|
||||
// Get live realms from database
|
||||
auto dbClient = app().getDbClient();
|
||||
*dbClient << "SELECT r.id, r.name, r.stream_key, r.viewer_count, "
|
||||
"u.username FROM realms r "
|
||||
"JOIN users u ON r.user_id = u.id "
|
||||
"WHERE r.is_live = true"
|
||||
>> [callback](const Result& r) {
|
||||
Json::Value resp;
|
||||
resp["success"] = true;
|
||||
Json::Value streams(Json::arrayValue);
|
||||
|
||||
for (const auto& row : r) {
|
||||
Json::Value stream;
|
||||
stream["id"] = static_cast<Json::Int64>(row["id"].as<int64_t>());
|
||||
stream["name"] = row["name"].as<std::string>();
|
||||
stream["streamKey"] = row["stream_key"].as<std::string>();
|
||||
stream["viewerCount"] = static_cast<Json::Int64>(row["viewer_count"].as<int64_t>());
|
||||
stream["username"] = row["username"].as<std::string>();
|
||||
streams.append(stream);
|
||||
}
|
||||
|
||||
resp["streams"] = streams;
|
||||
callback(jsonResp(resp));
|
||||
}
|
||||
>> [callback](const DrogonDbException& e) {
|
||||
LOG_ERROR << "Failed to get active streams: " << e.base().what();
|
||||
callback(jsonError("Failed to get active streams"));
|
||||
};
|
||||
}
|
||||
|
||||
void AdminController::disconnectStream(const HttpRequestPtr &req,
|
||||
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||
const std::string &streamKey) {
|
||||
UserInfo user = getUserFromRequest(req);
|
||||
if (user.id == 0 || !user.isAdmin) {
|
||||
callback(jsonError("Unauthorized", k403Forbidden));
|
||||
return;
|
||||
}
|
||||
|
||||
// Add to Redis set for OpenResty to disconnect
|
||||
RedisHelper::addToSet("streams_to_disconnect", streamKey);
|
||||
|
||||
// Also try direct disconnect
|
||||
OmeClient::getInstance().disconnectStream(streamKey, [callback](bool) {
|
||||
Json::Value resp;
|
||||
resp["success"] = true;
|
||||
resp["message"] = "Stream disconnect initiated";
|
||||
callback(jsonResp(resp));
|
||||
});
|
||||
}
|
||||
|
||||
void AdminController::promoteToStreamer(const HttpRequestPtr &req,
|
||||
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||
const std::string &userId) {
|
||||
UserInfo user = getUserFromRequest(req);
|
||||
if (user.id == 0 || !user.isAdmin) {
|
||||
callback(jsonError("Unauthorized", k403Forbidden));
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t targetUserId = std::stoll(userId);
|
||||
|
||||
auto dbClient = app().getDbClient();
|
||||
*dbClient << "UPDATE users SET is_streamer = true WHERE id = $1"
|
||||
<< targetUserId
|
||||
>> [callback](const Result&) {
|
||||
Json::Value resp;
|
||||
resp["success"] = true;
|
||||
resp["message"] = "User promoted to streamer";
|
||||
callback(jsonResp(resp));
|
||||
}
|
||||
>> [callback](const DrogonDbException& e) {
|
||||
LOG_ERROR << "Failed to promote user: " << e.base().what();
|
||||
callback(jsonError("Failed to promote user"));
|
||||
};
|
||||
}
|
||||
|
||||
void AdminController::demoteFromStreamer(const HttpRequestPtr &req,
|
||||
std::function<void(const HttpResponsePtr &)> &&callback,
|
||||
const std::string &userId) {
|
||||
UserInfo user = getUserFromRequest(req);
|
||||
if (user.id == 0 || !user.isAdmin) {
|
||||
callback(jsonError("Unauthorized", k403Forbidden));
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t targetUserId = std::stoll(userId);
|
||||
|
||||
auto dbClient = app().getDbClient();
|
||||
*dbClient << "UPDATE users SET is_streamer = false WHERE id = $1"
|
||||
<< targetUserId
|
||||
>> [callback](const Result&) {
|
||||
Json::Value resp;
|
||||
resp["success"] = true;
|
||||
resp["message"] = "User demoted from streamer";
|
||||
callback(jsonResp(resp));
|
||||
}
|
||||
>> [callback](const DrogonDbException& e) {
|
||||
LOG_ERROR << "Failed to demote user: " << e.base().what();
|
||||
callback(jsonError("Failed to demote user"));
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue