Created
April 5, 2024 12:07
-
-
Save alekxeyuk/943e313cf142eaa6929ce1b1b096e02b to your computer and use it in GitHub Desktop.
bizzarechat
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <unordered_set> | |
typedef std::unordered_set<int> int_set; | |
enum AccessLevel : int | |
{ | |
ADMIN, // Может регистрировать новых пользователей, давать роль админа или модератора другим пользователям, а также полностью останавливать чат | |
MODERATOR, // Может банить пользователей, создавать других модераторов, а также полностью редактировать все сообщения | |
BANNED, // Не может ничего, предполагается, что ни ADMIN, ни MODERATOR не станут BANNED | |
USER // Может писать сообщения, а также редактировать сообщения, но только свои | |
}; | |
struct ResposeData { | |
bool Success; | |
std::string Response; | |
}; | |
static bool set_has_id(const int& id, const int_set& set) { | |
const auto search_set = set.find(id); | |
return search_set != set.end(); | |
} | |
class AccessControl { | |
int_set db_[4] = { int_set{}, int_set{}, int_set{}, int_set{} }; | |
public: | |
bool HasRole(const int id, const AccessLevel roleName) | |
{ | |
return set_has_id(id, db_[roleName]); | |
} | |
bool GrantRole(const int id, const AccessLevel roleName) | |
{ | |
if (set_has_id(id, db_[roleName])) { | |
return false; | |
} | |
db_[roleName].insert(id); | |
return true; | |
} | |
bool RemoveRole(const int id, const AccessLevel roleName) | |
{ | |
if (set_has_id(id, db_[roleName])) | |
{ | |
const auto search_set = db_[roleName].find(id); | |
db_[roleName].erase(search_set); | |
return true; | |
} | |
return false; | |
} | |
ResposeData BanUser(int sender, int user) { | |
if (HasRole(sender, MODERATOR) && HasRole(user, USER)) { | |
return ResposeData{ GrantRole(user, BANNED), "BANNED user" }; | |
} | |
return ResposeData{ false, "Cant BAN user" }; | |
} | |
ResposeData UnBanUser(int sender, int user) { | |
if (HasRole(sender, MODERATOR) && HasRole(user, BANNED)) { | |
return ResposeData{ RemoveRole(user, BANNED), "UNBANNED user" }; | |
} | |
return ResposeData{ false, "Cant UNBAN user" }; | |
} | |
ResposeData RegisterNewUser(int sender, int newUser) { | |
if (HasRole(sender, ADMIN) && !HasRole(newUser, USER)) { | |
return ResposeData{ GrantRole(newUser, USER), "Registered new USER" }; | |
} | |
return ResposeData{ false, "Cant register new USER" }; | |
} | |
ResposeData GrantModeratorRole(int sender, int user) { | |
if ((HasRole(sender, ADMIN) || HasRole(sender, MODERATOR)) && !HasRole(user, MODERATOR) && !HasRole(user, BANNED)) { | |
return ResposeData{ GrantRole(user, MODERATOR), "Granted MODERATOR role" }; | |
} | |
return ResposeData{ false, "Cant grant MODERATOR role" }; | |
} | |
ResposeData GrantAdminRole(int sender, int user) { | |
if (HasRole(sender, ADMIN) && !HasRole(user, ADMIN) && !HasRole(user, BANNED)) { | |
return ResposeData{ GrantRole(user, ADMIN), "Granted ADMIN role" }; | |
} | |
return ResposeData{ false, "Cant grant ADMIN role" }; | |
} | |
}; | |
enum ServerState { | |
Stopped, | |
Running | |
}; | |
class Pausable | |
{ | |
bool status = Running; // false = paused | |
using HasRoleFunctionType = bool(AccessControl::*)(int, AccessLevel); | |
HasRoleFunctionType hasRolePtr = nullptr; | |
AccessControl* accessControlRef = nullptr; | |
public: | |
Pausable(AccessControl& a, HasRoleFunctionType f) : accessControlRef(&a), hasRolePtr(f) {} | |
ResposeData StopChat(int sender) { | |
if (status == Running && (accessControlRef->*hasRolePtr)(sender, ADMIN)) { | |
status = false; | |
return ResposeData{ true , "chat stopped" }; | |
} | |
return ResposeData{ false, "only admin can stop chat" }; | |
} | |
ResposeData ResumeChat(int sender) { | |
if (status == Stopped && (accessControlRef->*hasRolePtr)(sender, ADMIN)) { | |
status = true; | |
return ResposeData{ true, "chat resumed" }; | |
} | |
return ResposeData{ false , "only admin can start chat" }; | |
} | |
}; | |
class SystemBase : public AccessControl, public Pausable { | |
public: | |
SystemBase(int admin) : Pausable(*this, &AccessControl::HasRole) { | |
AccessControl::GrantRole(admin, ADMIN); | |
} | |
}; | |
static void PrintResponse(const ResposeData& response) { | |
std::cout << "result: " << response.Success << "\nresponse: " << response.Response << "\n"; | |
} | |
int main() { | |
const int USER1 = 1; | |
const int USER2 = 2; | |
const int USER3 = 3; | |
SystemBase chat(1); | |
auto responseStart3FromAdmin = chat.ResumeChat(USER1); | |
PrintResponse(responseStart3FromAdmin); | |
auto responseRegisterFromAdmin1 = chat.RegisterNewUser(USER1, USER2); | |
PrintResponse(responseRegisterFromAdmin1); | |
auto responseRegisterFromAdmin2 = chat.RegisterNewUser(USER1, USER2); | |
PrintResponse(responseRegisterFromAdmin2); | |
auto responseGrantFromAdmin = chat.GrantModeratorRole(USER1, USER2); | |
PrintResponse(responseGrantFromAdmin); | |
auto responseRegisterFromModerator = chat.RegisterNewUser(USER2, USER3); | |
PrintResponse(responseRegisterFromModerator); | |
auto responseRegisterFromAdmin3 = chat.RegisterNewUser(USER1, USER3); | |
PrintResponse(responseRegisterFromAdmin3); | |
auto responseBanFromModer = chat.BanUser(USER2, USER3); | |
PrintResponse(responseBanFromModer); | |
auto responseStopFromModer = chat.StopChat(USER2); | |
PrintResponse(responseStopFromModer); | |
auto responseStopFromAdmin = chat.StopChat(USER1); | |
PrintResponse(responseStopFromAdmin); | |
auto responseStop2FromAdmin = chat.StopChat(USER1); | |
PrintResponse(responseStop2FromAdmin); | |
auto responseStartFromAdmin = chat.ResumeChat(USER1); | |
PrintResponse(responseStartFromAdmin); | |
auto responseStart2FromAdmin = chat.ResumeChat(USER1); | |
PrintResponse(responseStart2FromAdmin); | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment