Fixed the permfind command

This commit is contained in:
WolverinDEV 2020-04-02 14:10:33 +02:00
parent 924e553664
commit 1865a3b20d
3 changed files with 104 additions and 44 deletions

@ -1 +1 @@
Subproject commit 3b5787d4d98dab2bfa732c906710f149a7f93395
Subproject commit 59e57218969572d50fd9f014ab5df59046b7a196

View File

@ -1329,7 +1329,9 @@ command_result ConnectedClient::handleCommandPermFind(Command &cmd) {
CMD_CHK_AND_INC_FLOOD_POINTS(5);
ACTION_REQUIRES_GLOBAL_PERMISSION(permission::b_virtualserver_permission_find, 1);
deque<pair<pair<string, permission::PermissionType>, bool>> permissions;
std::vector<std::tuple<std::string, permission::PermissionType, bool>> requested_permissions{};
requested_permissions.reserve(cmd.bulkCount());
std::shared_ptr<permission::PermissionTypeEntry> permission;
for(size_t index = 0; index < cmd.bulkCount(); index++) {
bool granted = false;
@ -1349,22 +1351,21 @@ command_result ConnectedClient::handleCommandPermFind(Command &cmd) {
continue;
}
permissions.emplace_back(pair<pair<string, permission::PermissionType>, bool>{{permission->name, permission->type}, granted});
requested_permissions.emplace_back(permission->name, permission->type, granted);
}
if(permissions.empty())
if(requested_permissions.empty())
return command_result{error::database_empty_result};
map<string, uint8_t> flags;
map<string, permission::PermissionType> quick_mapping;
string query_string;
for(const auto& entry : permissions) {
if(flags[entry.first.first] == 0) {
quick_mapping[entry.first.first] = entry.first.second;
query_string += string(query_string.empty() ? "" : " OR ") + "`permId` = '" + entry.first.first + "'";
std::map<std::string, std::tuple<permission::PermissionType, uint8_t>> db_lookup_mapping{};
std::string query_string{};
for(const auto& [name, id, as_granted] : requested_permissions) {
auto& mapping = db_lookup_mapping[name];
if(std::get<0>(mapping) == 0) {
std::get<0>(mapping) = id;
query_string += std::string{query_string.empty() ? "" : " OR "} + "`permId` = '" + name + "'";
}
flags[entry.first.first] |= entry.second ? 2 : 1;
std::get<1>(mapping) |= (1U << as_granted);
}
deque<unique_ptr<PermissionEntry>> entries;
@ -1373,13 +1374,14 @@ command_result ConnectedClient::handleCommandPermFind(Command &cmd) {
variable{":sid", this->server->getServerId()},
variable{":playlist", permission::SQL_PERM_PLAYLIST}
).query([&](int length, string* values, string* columns) {
permission::PermissionSqlType type = permission::SQL_PERM_GROUP;
uint64_t id = 0;
ChannelId channel_id = 0;
permission::PermissionValue value = 0,
granted_value = 0;
string permission_name;
permission::PermissionSqlType type{permission::SQL_PERM_GROUP};
uint64_t id{0};
ChannelId channel_id{0};
permission::PermissionValue value{0}, granted_value{0};
string permission_name{};
bool negate = false, skip = false;
#if 0
for (int index = 0; index < length; index++) {
try {
if(columns[index] == "type")
@ -1403,35 +1405,48 @@ command_result ConnectedClient::handleCommandPermFind(Command &cmd) {
return 0;
}
}
#else
assert(length == 8);
try {
type = static_cast<permission::PermissionSqlType>(stoll(values[1]));
permission_name = values[0];
id = static_cast<uint64_t>(stoll(values[2]));
channel_id = static_cast<ChannelId>(stoll(values[3]));
value = static_cast<permission::PermissionValue>(stoll(values[4]));
granted_value = static_cast<permission::PermissionValue>(stoll(values[5]));
negate = values[7] == "1";
skip = values[6] == "1";
} catch(std::exception& ex) {
return 0;
}
#endif
auto request = db_lookup_mapping.find(permission_name);
if(request == db_lookup_mapping.end()) return 0; /* shall not happen */
auto flags = std::get<1>(request->second);
/* value */
if((flags[permission_name] & 0x1) > 0 && value > 0) {
if((flags & 0x1U) > 0 && value > 0) {
auto result = make_unique<PermissionEntry>();
result->permission_type = quick_mapping[permission_name];
result->permission_type = std::get<0>(request->second);
result->permission_value = value;
result->type = type;
result->channel_id = channel_id;
result->negate = negate;
result->skip = skip;
if (type == permission::SQL_PERM_GROUP) {
auto gr = this->server->groups->findGroup(id);
if (!gr) return 0;
result->group_id = id;
if(gr->target() == GROUPTARGET_CHANNEL)
result->channel_id = 1;
} else if(type == permission::SQL_PERM_USER) {
result->client_id = id;
}
if(result)
entries.push_back(std::move(result));
}
/* granted */
if((flags[permission_name] & 0x2) > 0 && granted_value > 0) {
if((flags & 0x2U) > 0 && granted_value > 0) {
auto result = make_unique<PermissionEntry>();
result->permission_type = (permission::PermissionType) (quick_mapping[permission_name] | PERM_ID_GRANT);
result->permission_type = (permission::PermissionType) (std::get<0>(request->second) | PERM_ID_GRANT);
result->permission_value = granted_value;
result->type = type;
result->channel_id = channel_id;
@ -1439,21 +1454,17 @@ command_result ConnectedClient::handleCommandPermFind(Command &cmd) {
result->skip = skip;
if (type == permission::SQL_PERM_GROUP) {
auto gr = this->server->groups->findGroup(id);
if (!gr) return 0;
result->group_id = id;
if(gr->target() == GROUPTARGET_CHANNEL)
result->channel_id = 1;
} else if(type == permission::SQL_PERM_USER) {
result->client_id = id;
}
if(result)
entries.push_back(std::move(result));
}
return 0;
});
if(entries.empty())
return command_result{error::database_empty_result};
struct CommandPerm {
permission::PermissionType p;
@ -1465,13 +1476,13 @@ command_result ConnectedClient::handleCommandPermFind(Command &cmd) {
std::vector<CommandPerm> perms;
perms.resize(entries.size());
size_t index = 0;
size_t index{0};
auto all_groups = this->server->groups->availableGroups(true);
for(const auto& entry : entries) {
auto& perm = perms[index++];
perm.p = entry->permission_type;
perm.v = entry->permission_value;
#if 0 /* TS3 switched the oder and YatQa as well, to keep compatibility we do it as well */
if(entry->type == permission::SQL_PERM_USER) {
if(entry->channel_id > 0) {
perm.id1 = entry->client_id;
@ -1497,7 +1508,42 @@ command_result ConnectedClient::handleCommandPermFind(Command &cmd) {
perm.t = 0; /* server group */
}
}
#else
if(entry->type == permission::SQL_PERM_USER) {
if(entry->channel_id > 0) {
perm.id1 = entry->channel_id;
perm.id2 = entry->client_id;
perm.t = 4; /* client channel */
} else {
perm.id1 = entry->client_id;
perm.id2 = 0;
perm.t = 1; /* client server */
}
} else if(entry->type == permission::SQL_PERM_CHANNEL) {
perm.id1 = entry->channel_id;
perm.id2 = 0;
perm.t = 2; /* channel permission */
} else if(entry->type == permission::SQL_PERM_GROUP) {
auto group = std::find_if(all_groups.begin(), all_groups.end(), [&](const auto& group) { return group->groupId() == entry->group_id; });
if(group == all_groups.end()) {
index--; /* unknown group */
continue;
}
if((*group)->target() == GroupTarget::GROUPTARGET_CHANNEL) {
perm.id1 = 0;
perm.id2 = entry->group_id;
perm.t = 3; /* channel group */
} else {
perm.id1 = entry->group_id;
perm.id2 = 0;
perm.t = 0; /* server group */
}
}
#endif
perm.p = entry->permission_type;
perm.v = entry->permission_value;
}
perms.erase(perms.begin() + index, perms.end());
sort(perms.begin(), perms.end(), [](const CommandPerm& a, const CommandPerm& b) {
@ -1516,6 +1562,7 @@ command_result ConnectedClient::handleCommandPermFind(Command &cmd) {
return &a > &b;
});
#if 0
Command result(this->notify_response_command("notifypermfind"));
index = 0;
@ -1528,9 +1575,22 @@ command_result ConnectedClient::handleCommandPermFind(Command &cmd) {
result[index]["t"] = e.t;
index++;
}
if(index == 0) return command_result{error::database_empty_result};
this->sendCommand(result);
#else
command_builder result{this->notify_response_command("notifypermfind"), 64, perms.size()};
index = 0;
for(const auto& e : perms) {
auto bulk = result.bulk(index++);
bulk.put("t", e.t);
bulk.put("p", (uint16_t) e.p);
bulk.put("v", e.v);
bulk.put("id1", e.id1);
bulk.put("id2", e.id2);
}
this->sendCommand(result);
#endif
return command_result{error::ok};
}

2
shared

@ -1 +1 @@
Subproject commit 889477c6461164cb1dd687b270bd629763db1ef6
Subproject commit c879f3b7764e2b6a226ca80d3013bdff838a9972