Using new permissions system consequently
This commit is contained in:
parent
d42ec40a58
commit
23a9385afe
@ -70,6 +70,14 @@ namespace ts {
|
||||
return BasicChannel::permission_granted(data,granted_value, require_granted_value);
|
||||
}
|
||||
|
||||
ts_always_inline bool talk_power_granted(const permission::v2::PermissionFlaggedValue& granted_value) {
|
||||
return this->permission_granted(permission::i_client_needed_talk_power, granted_value, false);
|
||||
}
|
||||
|
||||
ts_always_inline std::shared_ptr<permission::v2::PermissionManager> permissions(){ return this->_permissions; }
|
||||
virtual void setPermissionManager(const std::shared_ptr<permission::v2::PermissionManager>&);
|
||||
virtual void setProperties(const std::shared_ptr<Properties>&);
|
||||
private:
|
||||
ts_always_inline
|
||||
static bool permission_granted(const permission::v2::PermissionFlaggedValue& channel_permission_value, const permission::v2::PermissionFlaggedValue& granted_value, bool require_granted_value) {
|
||||
if(!channel_permission_value.has_value || channel_permission_value.value == 0) {
|
||||
@ -81,14 +89,6 @@ namespace ts {
|
||||
return granted_value.value >= channel_permission_value.value;
|
||||
}
|
||||
|
||||
ts_always_inline bool talk_power_granted(const permission::v2::PermissionFlaggedValue& granted_value) {
|
||||
return this->permission_granted(permission::i_client_needed_talk_power, granted_value, false);
|
||||
}
|
||||
|
||||
ts_always_inline std::shared_ptr<permission::v2::PermissionManager> permissions(){ return this->_permissions; }
|
||||
virtual void setPermissionManager(const std::shared_ptr<permission::v2::PermissionManager>&);
|
||||
virtual void setProperties(const std::shared_ptr<Properties>&);
|
||||
protected:
|
||||
public:
|
||||
ChannelId channelId() const override;
|
||||
ChannelId previousChannelId() const override;
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "./misc/spin_lock.h"
|
||||
#include "Definitions.h"
|
||||
#include "Variable.h"
|
||||
#include "spdlog/fmt/ostr.h" // must be included
|
||||
|
||||
#define permNotGranted (-2)
|
||||
#define PERM_ID_GRANT ((ts::permission::PermissionType) (1 << 15))
|
||||
@ -809,9 +810,33 @@ namespace ts {
|
||||
struct PermissionFlaggedValue {
|
||||
PermissionValue value = permNotGranted;
|
||||
bool has_value = false;
|
||||
|
||||
constexpr bool has_power() const { return this->has_value && (this->value > 0 || this->value == -1); }
|
||||
constexpr bool has_infinite_power() const { return this->has_value && this->value == -1; }
|
||||
|
||||
inline bool operator==(const PermissionFlaggedValue& other) const { return other.value == this->value && other.has_value == this->has_value; }
|
||||
inline bool operator!=(const PermissionFlaggedValue& other) const { return !(*this == other); }
|
||||
};
|
||||
static constexpr PermissionFlaggedValue empty_permission_flagged_value{0, false};
|
||||
|
||||
|
||||
static constexpr bool permission_granted(const PermissionFlaggedValue& required, const PermissionFlaggedValue& given, bool requires_given = true) {
|
||||
if(!required.has_value) {
|
||||
return !requires_given || given.has_power();
|
||||
} else if(!given.has_power()) {
|
||||
return false;
|
||||
} else if(given.has_infinite_power()) {
|
||||
return true;
|
||||
} else if(required.has_infinite_power()) {
|
||||
return false;
|
||||
} else {
|
||||
return given.value >= required.value;
|
||||
}
|
||||
}
|
||||
static constexpr bool permission_granted(const PermissionValue& required, const PermissionFlaggedValue& given, bool requires_given = true) {
|
||||
return permission_granted({required, true}, given, requires_given);
|
||||
}
|
||||
|
||||
class PermissionManager {
|
||||
public:
|
||||
static constexpr size_t PERMISSIONS_BULK_BITS = 4; /* 16 permissions per block */
|
||||
@ -909,6 +934,13 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const ts::permission::v2::PermissionFlaggedValue& c) {
|
||||
if(c.has_value)
|
||||
return os << c.value;
|
||||
else
|
||||
return os << "unset";
|
||||
}
|
||||
|
||||
DEFINE_VARIABLE_TRANSFORM(ts::permission::PermissionType, VARTYPE_INT, std::to_string((int16_t) in), static_cast<ts::permission::PermissionType>(in.as<int16_t>()));
|
||||
DEFINE_VARIABLE_TRANSFORM(ts::permission::PermissionGroup, VARTYPE_INT, std::to_string((uint16_t) in), static_cast<ts::permission::PermissionGroup>(in.as<uint16_t>()));
|
||||
DEFINE_VARIABLE_TRANSFORM(ts::permission::PermissionSqlType, VARTYPE_INT, std::to_string((int8_t) in), static_cast<ts::permission::PermissionSqlType>(in.as<int8_t>()));
|
@ -3,6 +3,7 @@
|
||||
#include <string>
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
|
||||
#include "escape.h"
|
||||
#include "converters/converter.h"
|
||||
@ -10,6 +11,36 @@
|
||||
|
||||
namespace ts {
|
||||
namespace impl {
|
||||
inline bool value_raw_impl(const std::string_view& data, const std::string_view& key, size_t& begin, size_t* end) {
|
||||
size_t index{0}, findex, max{data.size()}, key_size{key.size()};
|
||||
do {
|
||||
findex = data.find(key, index);
|
||||
if(findex > max) return false;
|
||||
|
||||
/* not starting with a space so not a match */
|
||||
if(findex != 0 && data[findex - 1] != ' ') {
|
||||
index = findex + key_size;
|
||||
continue;
|
||||
}
|
||||
|
||||
findex += key_size;
|
||||
if(findex < max) {
|
||||
if(findex < max && data[findex] != '=') {
|
||||
index = findex + key_size;
|
||||
continue;
|
||||
}
|
||||
|
||||
begin = findex + 1;
|
||||
if(end) *end = data.find(' ', findex + 1);
|
||||
return true;
|
||||
} else {
|
||||
begin = max;
|
||||
if(end) *end = max;
|
||||
return true;
|
||||
}
|
||||
} while(true);
|
||||
}
|
||||
|
||||
class command_string_parser {
|
||||
public:
|
||||
[[nodiscard]] inline bool is_empty() const noexcept { return this->data.empty(); }
|
||||
@ -22,33 +53,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
[[nodiscard]] inline std::string_view value_raw(const std::string_view& key, bool& has_been_found) const noexcept {
|
||||
has_been_found = false;
|
||||
size_t begin, end;
|
||||
has_been_found = value_raw_impl(this->data, key, begin, &end);
|
||||
if(!has_been_found) return {};
|
||||
|
||||
size_t index{0}, findex, max{this->data.size()}, key_size{key.size()};
|
||||
do {
|
||||
findex = this->data.find(key, index);
|
||||
if(findex > max) return std::string_view{};
|
||||
|
||||
/* not starting with a space so not a match */
|
||||
if(findex != 0 && this->data[findex - 1] != ' ') {
|
||||
index = findex + key_size;
|
||||
continue;
|
||||
}
|
||||
|
||||
findex += key_size;
|
||||
if(findex < max) {
|
||||
if(findex < max && this->data[findex] != '=') {
|
||||
index = findex + key_size;
|
||||
continue;
|
||||
}
|
||||
|
||||
has_been_found = true;
|
||||
return this->data.substr(findex + 1, this->data.find(' ', findex + 1) - findex - 1);
|
||||
} else {
|
||||
has_been_found = true;
|
||||
return std::string_view{};
|
||||
}
|
||||
} while(true);
|
||||
return this->data.substr(begin, end - begin);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline std::string value(const std::string_view& key) const {
|
||||
@ -121,4 +130,101 @@ namespace ts {
|
||||
std::vector<command_bulk> _bulks{};
|
||||
std::vector<std::string_view> flags{};
|
||||
};
|
||||
|
||||
template <typename vector_t = std::vector<std::string>>
|
||||
class command_builder_impl {
|
||||
public:
|
||||
explicit command_builder_impl(std::string command, size_t expected_bulk_size = 128, size_t expected_bulks = 1) : _identifier{std::move(command)}, expected_bulk_size{expected_bulk_size} {
|
||||
for(size_t index = 0; index < expected_bulks; index++)
|
||||
this->bulks.emplace_back(" ").reserve(expected_bulk_size);
|
||||
}
|
||||
|
||||
inline command_builder_impl<std::vector<std::string>> as_normalized() {
|
||||
return command_builder_impl<std::vector<std::string>>{this->expected_bulk_size, this->_identifier, this->bulks.begin(), this->bulks.end()};
|
||||
}
|
||||
|
||||
inline std::string build() const {
|
||||
if(this->builded.has_value())
|
||||
return this->builded.value();
|
||||
|
||||
std::string result{};
|
||||
size_t required_size{this->_identifier.size()};
|
||||
for(auto& entry : this->bulks)
|
||||
required_size += entry.size() + 1;
|
||||
|
||||
result.append(this->_identifier);
|
||||
for(auto it = this->bulks.begin(); it != this->bulks.end(); it++) {
|
||||
result.append(*it);
|
||||
if(it + 1 != this->bulks.end())
|
||||
result.append("|");
|
||||
}
|
||||
|
||||
this->builded = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void reserve_bulks(size_t count) { this->bulks.reserve(count); }
|
||||
|
||||
inline void put(size_t index, const std::string_view& key, const std::string_view& value) {
|
||||
while(this->bulks.size() <= index)
|
||||
this->bulks.emplace_back(" ").reserve(expected_bulk_size);
|
||||
|
||||
auto& data = this->bulks[index];
|
||||
size_t begin, end;
|
||||
if(impl::value_raw_impl(data, key, begin, &end)) {
|
||||
std::string result{};
|
||||
result.reserve(data.size());
|
||||
|
||||
result.append(data, 0, begin - key.size() - 1); /* key incl = */
|
||||
result.append(data, end + 1); /* get rid of the space */
|
||||
data = result;
|
||||
}
|
||||
this->impl_put_unchecked(data, index, key, value);
|
||||
}
|
||||
|
||||
template <typename T, std::enable_if_t<!(std::is_same<T, std::string_view>::value || std::is_same<T, std::string>::value), int> = 1>
|
||||
inline void put(size_t index, const std::string_view& key, const T& value) {
|
||||
static_assert(converter<T>::supported, "Target type isn't supported!");
|
||||
static_assert(!converter<T>::supported || converter<T>::to_string, "Target type dosn't support building");
|
||||
auto data = converter<T>::to_string(value);
|
||||
this->put(index, key, std::string_view{data});
|
||||
}
|
||||
|
||||
/* directly puts data without checking for duplicates */
|
||||
inline void put_unchecked(size_t index, const std::string_view& key, const std::string_view& value) {
|
||||
while(this->bulks.size() <= index)
|
||||
this->bulks.emplace_back(" ").reserve(expected_bulk_size);
|
||||
|
||||
this->impl_put_unchecked(this->bulks[index], index, key, value);
|
||||
}
|
||||
|
||||
template <typename T, std::enable_if_t<!(std::is_same<T, std::string_view>::value || std::is_same<T, std::string>::value), int> = 1>
|
||||
inline void put_unchecked(size_t index, const std::string_view& key, const T& value) {
|
||||
static_assert(converter<T>::supported, "Target type isn't supported!");
|
||||
static_assert(!converter<T>::supported || converter<T>::to_string, "Target type dosn't support building");
|
||||
auto data = converter<T>::to_string(value);
|
||||
this->put_unchecked(index, key, std::string_view{data});
|
||||
}
|
||||
private:
|
||||
command_builder_impl(size_t expected, size_t identifier, vector_t::iterator begin, vector_t::iterator end) : expected_bulk_size{expected}, _identifier{identifier}, bulks{begin, end} {}
|
||||
|
||||
void impl_put_unchecked(std::string& data, size_t index, const std::string_view& key, const std::string_view& value) {
|
||||
auto escaped_value = ts::query::escape(std::string{value});
|
||||
|
||||
data.reserve(data.length() + key.size() + escaped_value.size() + 2);
|
||||
data.append(key);
|
||||
data.append("=");
|
||||
data.append(escaped_value);
|
||||
data.append(" ");
|
||||
|
||||
this->builded.reset();
|
||||
}
|
||||
|
||||
const size_t expected_bulk_size;
|
||||
const std::string _identifier;
|
||||
mutable std::optional<std::string> builded{};
|
||||
vector_t bulks{};
|
||||
};
|
||||
|
||||
using command_builder = command_builder_impl<>;
|
||||
}
|
@ -7,6 +7,7 @@ namespace ts {
|
||||
namespace cconstants {
|
||||
|
||||
typedef command_handler::field<tl("return_code"), std::string> return_code;
|
||||
typedef command_handler::field<tl("reasonmsg"), std::string> reasonmsg;
|
||||
|
||||
typedef command_handler::field<tl("sid"), ServerId> server_id;
|
||||
|
||||
@ -17,7 +18,7 @@ namespace ts {
|
||||
typedef command_handler::field<tl("cpid"), ChannelId> channel_parent_id;
|
||||
|
||||
typedef command_handler::field<tl("cgid"), GroupId> channel_group_id;
|
||||
typedef command_handler::field<tl("cgid"), GroupId> server_group_id;
|
||||
typedef command_handler::field<tl("sgid"), GroupId> server_group_id;
|
||||
|
||||
//FIXME
|
||||
/* typedef descriptor::field<tl("permid"), permission::PermissionType> permission_id;
|
||||
|
@ -157,6 +157,14 @@ int main() {
|
||||
|
||||
cmd_handler->invoke(cmd);
|
||||
|
||||
{
|
||||
ts::command_builder builder{"hello_world"};
|
||||
builder.put(0, "hello", "this is hello world");
|
||||
builder.put(1, "hello", "this is hello world1");
|
||||
builder.put(1, "hello", "this is hello world2");
|
||||
builder.put_unchecked(6, "hello", 22);
|
||||
std::cout << "Result: " << builder.build() << "\n";
|
||||
}
|
||||
//auto v = ts::descriptor::entry::bulked::val;
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user