#include <set>
#include <map>
#include <string>
using namespace std;
struct ResposeData {
bool Success;
string Response;
};
class AccessControl {
set<string> Roles;
map<int, set<string>> mp;
public:
bool HasRole(int id, const string &roleName) const {
return mp.find(id) != mp.end() && mp.find(id)->second.find(roleName) != mp.find(id)->second.end();
}
bool GrantRole(int id, const string &roleName) {
if (Roles.find(roleName) == Roles.end() || HasRole(id, roleName)) {
return false;
}
mp[id].insert(roleName);
return true;
}
bool RemoveRole(int id, const string &roleName) {
if (Roles.find(roleName) == Roles.end() || !HasRole(id, roleName)) {
return false;
}
mp[id].erase(roleName);
return true;
}
void RegisterRole(const string &roleName) {
Roles.insert(roleName);
}
};
class Pausable {
protected:
bool isPaused = false;
public:
void PauseChat() {
isPaused = true;
}
void ResumeChat() {
isPaused = false;
}
};
class SystemBase : public AccessControl, public Pausable {
const string Admin = "ADMIN";
const string Moderator = "Moderator";
const string Banned = "Banned";
const string User = "User";
public:
SystemBase(int admin) {
RegisterRole(Admin);
RegisterRole(Moderator);
RegisterRole(Banned);
RegisterRole(User);
GrantRole(admin, User);
GrantRole(admin, Admin);
}
ResposeData BanUser(int sender, int user) {
if (!HasRole(sender, Moderator)) {
cerr << "not Moderator" << endl;
return ResposeData{false, "not Moderator"};
}
if (!HasRole(user, User)) {
cerr << "User not exist" << endl;
return ResposeData{false, "User not exist"};
}
if (HasRole(user, Banned)) {
cerr << "already banned" << endl;
return ResposeData{false, "already banned"};
}
GrantRole(user, Banned);
return ResposeData{true, "Ban success"};
}
ResposeData UnBanUser(int sender, int user) {
if (!HasRole(sender, Moderator)) {
cerr << "not Moderator" << endl;
return ResposeData{false, "not Moderator"};
}
if (!HasRole(user, Banned)) {
cerr << "not banned" << endl;
return ResposeData{false, "not banned"};
}
RemoveRole(user, Banned);
return ResposeData{true, "Unban success"};
}
ResposeData RegisterNewUser(int sender, int newUser) {
if (HasRole(newUser, User) || !HasRole(sender, Admin)) {
cerr << "error registration" << endl;
return ResposeData{false, "error registration"};
}
GrantRole(newUser, User);
return ResposeData{true, "Registration success"};
}
ResposeData GrantModeratorRole(int sender, int user) {
if (!HasRole(sender, Admin)) {
cerr << "not admin" << endl;
return ResposeData{false, "not admin"};
}
GrantRole(user, Moderator);
return ResposeData{true, "Moderator role granted"};
}
ResposeData GrantAdminRole(int sender, int user) {
if (!HasRole(sender, Admin)) {
cerr << "not admin" << endl;
return ResposeData{false, "not admin"};
}
GrantRole(user, Admin);
return ResposeData{true, "Admin role granted"};
}
ResposeData StopChat(int sender) {
if (!HasRole(sender, Admin)) {
cerr << "not admin" << endl;
return ResposeData{false, "not admin"};
}
PauseChat();
return ResposeData{true, "Chat stopped"};
}
ResposeData ResumeChat(int sender) {
if (!HasRole(sender, Admin)) {
cerr << "not admin" << endl;
return ResposeData{false, "not admin"};
}
Pausable::ResumeChat();
return ResposeData{true, "Chat resumed"};
}
};
void PrintResponse(const ResposeData &response) {
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 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);
return 0;
}```