Allow sending paid messages.

This commit is contained in:
John Preston
2025-02-13 19:03:11 +04:00
parent 45c7829cd8
commit bbc14ba74f
25 changed files with 497 additions and 143 deletions
+101 -71
View File
@@ -86,7 +86,7 @@ enum { // Local Storage Keys
lskSavedGifsOld = 0x0e, // no data
lskSavedGifs = 0x0f, // no data
lskStickersKeys = 0x10, // no data
lskTrustedBots = 0x11, // no data
lskTrustedPeers = 0x11, // no data
lskFavedStickers = 0x12, // no data
lskExportSettings = 0x13, // no data
lskBackgroundOld = 0x14, // no data
@@ -220,7 +220,7 @@ base::flat_set<QString> Account::collectGoodNames() const {
_legacyBackgroundKeyDay,
_recentHashtagsAndBotsKey,
_exportSettingsKey,
_trustedBotsKey,
_trustedPeersKey,
_installedMasksKey,
_recentMasksKey,
_archivedMasksKey,
@@ -308,7 +308,7 @@ Account::ReadMapResult Account::readMapWith(
base::flat_map<PeerId, FileKey> draftsMap;
base::flat_map<PeerId, FileKey> draftCursorsMap;
base::flat_map<PeerId, bool> draftsNotReadMap;
quint64 locationsKey = 0, reportSpamStatusesKey = 0, trustedBotsKey = 0;
quint64 locationsKey = 0, reportSpamStatusesKey = 0, trustedPeersKey = 0;
quint64 recentStickersKeyOld = 0;
quint64 installedStickersKey = 0, featuredStickersKey = 0, recentStickersKey = 0, favedStickersKey = 0, archivedStickersKey = 0;
quint64 installedMasksKey = 0, recentMasksKey = 0, archivedMasksKey = 0;
@@ -371,8 +371,8 @@ Account::ReadMapResult Account::readMapWith(
map.stream >> reportSpamStatusesKey;
ClearKey(reportSpamStatusesKey, _basePath);
} break;
case lskTrustedBots: {
map.stream >> trustedBotsKey;
case lskTrustedPeers: {
map.stream >> trustedPeersKey;
} break;
case lskRecentStickersOld: {
map.stream >> recentStickersKeyOld;
@@ -459,7 +459,7 @@ Account::ReadMapResult Account::readMapWith(
_draftsNotReadMap = draftsNotReadMap;
_locationsKey = locationsKey;
_trustedBotsKey = trustedBotsKey;
_trustedPeersKey = trustedPeersKey;
_recentStickersKeyOld = recentStickersKeyOld;
_installedStickersKey = installedStickersKey;
_featuredStickersKey = featuredStickersKey;
@@ -573,7 +573,7 @@ void Account::writeMap() {
if (!_draftsMap.empty()) mapSize += sizeof(quint32) * 2 + _draftsMap.size() * sizeof(quint64) * 2;
if (!_draftCursorsMap.empty()) mapSize += sizeof(quint32) * 2 + _draftCursorsMap.size() * sizeof(quint64) * 2;
if (_locationsKey) mapSize += sizeof(quint32) + sizeof(quint64);
if (_trustedBotsKey) mapSize += sizeof(quint32) + sizeof(quint64);
if (_trustedPeersKey) mapSize += sizeof(quint32) + sizeof(quint64);
if (_recentStickersKeyOld) mapSize += sizeof(quint32) + sizeof(quint64);
if (_installedStickersKey || _featuredStickersKey || _recentStickersKey || _archivedStickersKey) {
mapSize += sizeof(quint32) + 4 * sizeof(quint64);
@@ -619,8 +619,8 @@ void Account::writeMap() {
if (_locationsKey) {
mapData.stream << quint32(lskLocations) << quint64(_locationsKey);
}
if (_trustedBotsKey) {
mapData.stream << quint32(lskTrustedBots) << quint64(_trustedBotsKey);
if (_trustedPeersKey) {
mapData.stream << quint32(lskTrustedPeers) << quint64(_trustedPeersKey);
}
if (_recentStickersKeyOld) {
mapData.stream << quint32(lskRecentStickersOld) << quint64(_recentStickersKeyOld);
@@ -693,7 +693,7 @@ void Account::reset() {
_draftsMap.clear();
_draftCursorsMap.clear();
_draftsNotReadMap.clear();
_locationsKey = _trustedBotsKey = 0;
_locationsKey = _trustedPeersKey = 0;
_recentStickersKeyOld = 0;
_installedStickersKey = 0;
_featuredStickersKey = 0;
@@ -3147,47 +3147,47 @@ void Account::readSelf(
}
}
void Account::writeTrustedBots() {
if (_trustedBots.empty()) {
if (_trustedBotsKey) {
ClearKey(_trustedBotsKey, _basePath);
_trustedBotsKey = 0;
void Account::writeTrustedPeers() {
if (_trustedPeers.empty()) {
if (_trustedPeersKey) {
ClearKey(_trustedPeersKey, _basePath);
_trustedPeersKey = 0;
writeMapDelayed();
}
return;
}
if (!_trustedBotsKey) {
_trustedBotsKey = GenerateKey(_basePath);
if (!_trustedPeersKey) {
_trustedPeersKey = GenerateKey(_basePath);
writeMapQueued();
}
quint32 size = sizeof(qint32) + _trustedBots.size() * sizeof(quint64);
quint32 size = sizeof(qint32) + _trustedPeers.size() * sizeof(quint64);
EncryptedDescriptor data(size);
data.stream << qint32(_trustedBots.size());
for (const auto &[peerId, mask] : _trustedBots) {
// value: 8 bit mask, 56 bit bot peer_id.
data.stream << qint32(_trustedPeers.size());
for (const auto &[peerId, mask] : _trustedPeers) {
// value: 8 bit mask, 56 bit peer_id.
auto value = SerializePeerId(peerId);
Assert((value >> 56) == 0);
value |= (quint64(mask) << 56);
data.stream << value;
}
FileWriteDescriptor file(_trustedBotsKey, _basePath);
FileWriteDescriptor file(_trustedPeersKey, _basePath);
file.writeEncrypted(data, _localKey);
}
void Account::readTrustedBots() {
if (_trustedBotsRead) {
void Account::readTrustedPeers() {
if (_trustedPeersRead) {
return;
}
_trustedBotsRead = true;
if (!_trustedBotsKey) {
_trustedPeersRead = true;
if (!_trustedPeersKey) {
return;
}
FileReadDescriptor trusted;
if (!ReadEncryptedFile(trusted, _trustedBotsKey, _basePath, _localKey)) {
ClearKey(_trustedBotsKey, _basePath);
_trustedBotsKey = 0;
if (!ReadEncryptedFile(trusted, _trustedPeersKey, _basePath, _localKey)) {
ClearKey(_trustedPeersKey, _basePath);
_trustedPeersKey = 0;
writeMapDelayed();
return;
}
@@ -3197,76 +3197,106 @@ void Account::readTrustedBots() {
for (int i = 0; i < size; ++i) {
auto value = quint64();
trusted.stream >> value;
const auto mask = base::flags<BotTrustFlag>::from_raw(
const auto mask = base::flags<PeerTrustFlag>::from_raw(
uchar(value >> 56));
const auto peerIdSerialized = value & ~(0xFFULL << 56);
const auto peerId = DeserializePeerId(peerIdSerialized);
_trustedBots.emplace(peerId, mask);
_trustedPeers.emplace(peerId, mask);
}
}
void Account::markBotTrustedOpenGame(PeerId botId) {
if (isBotTrustedOpenGame(botId)) {
void Account::markPeerTrustedOpenGame(PeerId peerId) {
if (isPeerTrustedOpenGame(peerId)) {
return;
}
const auto i = _trustedBots.find(botId);
if (i == end(_trustedBots)) {
_trustedBots.emplace(botId, BotTrustFlag());
const auto i = _trustedPeers.find(peerId);
if (i == end(_trustedPeers)) {
_trustedPeers.emplace(peerId, PeerTrustFlag());
} else {
i->second &= ~BotTrustFlag::NoOpenGame;
i->second &= ~PeerTrustFlag::NoOpenGame;
}
writeTrustedBots();
writeTrustedPeers();
}
bool Account::isBotTrustedOpenGame(PeerId botId) {
readTrustedBots();
const auto i = _trustedBots.find(botId);
return (i != end(_trustedBots))
&& ((i->second & BotTrustFlag::NoOpenGame) == 0);
bool Account::isPeerTrustedOpenGame(PeerId peerId) {
readTrustedPeers();
const auto i = _trustedPeers.find(peerId);
return (i != end(_trustedPeers))
&& ((i->second & PeerTrustFlag::NoOpenGame) == 0);
}
void Account::markBotTrustedPayment(PeerId botId) {
if (isBotTrustedPayment(botId)) {
void Account::markPeerTrustedPayment(PeerId peerId) {
if (isPeerTrustedPayment(peerId)) {
return;
}
const auto i = _trustedBots.find(botId);
if (i == end(_trustedBots)) {
_trustedBots.emplace(
botId,
BotTrustFlag::NoOpenGame | BotTrustFlag::Payment);
const auto i = _trustedPeers.find(peerId);
if (i == end(_trustedPeers)) {
_trustedPeers.emplace(
peerId,
PeerTrustFlag::NoOpenGame | PeerTrustFlag::Payment);
} else {
i->second |= BotTrustFlag::Payment;
i->second |= PeerTrustFlag::Payment;
}
writeTrustedBots();
writeTrustedPeers();
}
bool Account::isBotTrustedPayment(PeerId botId) {
readTrustedBots();
const auto i = _trustedBots.find(botId);
return (i != end(_trustedBots))
&& ((i->second & BotTrustFlag::Payment) != 0);
bool Account::isPeerTrustedPayment(PeerId peerId) {
readTrustedPeers();
const auto i = _trustedPeers.find(peerId);
return (i != end(_trustedPeers))
&& ((i->second & PeerTrustFlag::Payment) != 0);
}
void Account::markBotTrustedOpenWebView(PeerId botId) {
if (isBotTrustedOpenWebView(botId)) {
void Account::markPeerTrustedOpenWebView(PeerId peerId) {
if (isPeerTrustedOpenWebView(peerId)) {
return;
}
const auto i = _trustedBots.find(botId);
if (i == end(_trustedBots)) {
_trustedBots.emplace(
botId,
BotTrustFlag::NoOpenGame | BotTrustFlag::OpenWebView);
const auto i = _trustedPeers.find(peerId);
if (i == end(_trustedPeers)) {
_trustedPeers.emplace(
peerId,
PeerTrustFlag::NoOpenGame | PeerTrustFlag::OpenWebView);
} else {
i->second |= BotTrustFlag::OpenWebView;
i->second |= PeerTrustFlag::OpenWebView;
}
writeTrustedBots();
writeTrustedPeers();
}
bool Account::isBotTrustedOpenWebView(PeerId botId) {
readTrustedBots();
const auto i = _trustedBots.find(botId);
return (i != end(_trustedBots))
&& ((i->second & BotTrustFlag::OpenWebView) != 0);
bool Account::isPeerTrustedOpenWebView(PeerId peerId) {
readTrustedPeers();
const auto i = _trustedPeers.find(peerId);
return (i != end(_trustedPeers))
&& ((i->second & PeerTrustFlag::OpenWebView) != 0);
}
void Account::markPeerTrustedPayForMessage(PeerId peerId) {
if (isPeerTrustedPayForMessage(peerId)) {
return;
}
const auto i = _trustedPeers.find(peerId);
if (i == end(_trustedPeers)) {
_trustedPeers.emplace(
peerId,
PeerTrustFlag::NoOpenGame | PeerTrustFlag::PayForMessage);
} else {
i->second |= PeerTrustFlag::PayForMessage;
}
writeTrustedPeers();
}
bool Account::isPeerTrustedPayForMessage(PeerId peerId) {
readTrustedPeers();
const auto i = _trustedPeers.find(peerId);
return (i != end(_trustedPeers))
&& ((i->second & PeerTrustFlag::PayForMessage) != 0);
}
void Account::clearPeerTrusted(PeerId peerId) {
const auto i = _trustedPeers.find(peerId);
if (i != end(_trustedPeers)) {
_trustedPeers.erase(i);
writeTrustedPeers();
}
}
void Account::enforceModernStorageIdBots() {
+17 -13
View File
@@ -167,12 +167,15 @@ public:
const QByteArray& serialized,
int32 streamVersion);
void markBotTrustedOpenGame(PeerId botId);
[[nodiscard]] bool isBotTrustedOpenGame(PeerId botId);
void markBotTrustedPayment(PeerId botId);
[[nodiscard]] bool isBotTrustedPayment(PeerId botId);
void markBotTrustedOpenWebView(PeerId botId);
[[nodiscard]] bool isBotTrustedOpenWebView(PeerId botId);
void markPeerTrustedOpenGame(PeerId peerId);
[[nodiscard]] bool isPeerTrustedOpenGame(PeerId peerId);
void markPeerTrustedPayment(PeerId peerId);
[[nodiscard]] bool isPeerTrustedPayment(PeerId peerId);
void markPeerTrustedOpenWebView(PeerId peerId);
[[nodiscard]] bool isPeerTrustedOpenWebView(PeerId peerId);
void markPeerTrustedPayForMessage(PeerId peerId);
[[nodiscard]] bool isPeerTrustedPayForMessage(PeerId peerId);
void clearPeerTrusted(PeerId peerId);
void enforceModernStorageIdBots();
[[nodiscard]] Webview::StorageId resolveStorageIdBots();
@@ -203,12 +206,13 @@ private:
IncorrectPasscode,
Failed,
};
enum class BotTrustFlag : uchar {
enum class PeerTrustFlag : uchar {
NoOpenGame = (1 << 0),
Payment = (1 << 1),
OpenWebView = (1 << 2),
PayForMessage = (1 << 3),
};
friend inline constexpr bool is_flag_type(BotTrustFlag) { return true; };
friend inline constexpr bool is_flag_type(PeerTrustFlag) { return true; };
[[nodiscard]] base::flat_set<QString> collectGoodNames() const;
[[nodiscard]] auto prepareReadSettingsContext() const
@@ -261,8 +265,8 @@ private:
Data::StickersSetFlags readingFlags = 0);
void importOldRecentStickers();
void readTrustedBots();
void writeTrustedBots();
void readTrustedPeers();
void writeTrustedPeers();
void readMediaLastPlaybackPositions();
void writeMediaLastPlaybackPositions();
@@ -295,7 +299,7 @@ private:
Fn<std::optional<QByteArray>()> _downloadsSerialize;
FileKey _locationsKey = 0;
FileKey _trustedBotsKey = 0;
FileKey _trustedPeersKey = 0;
FileKey _installedStickersKey = 0;
FileKey _featuredStickersKey = 0;
FileKey _recentStickersKey = 0;
@@ -324,8 +328,8 @@ private:
qint32 _cacheTotalTimeLimit = 0;
qint32 _cacheBigFileTotalTimeLimit = 0;
base::flat_map<PeerId, base::flags<BotTrustFlag>> _trustedBots;
bool _trustedBotsRead = false;
base::flat_map<PeerId, base::flags<PeerTrustFlag>> _trustedPeers;
bool _trustedPeersRead = false;
bool _readingUserSettings = false;
bool _recentHashtagsAndBotsWereRead = false;
bool _searchSuggestionsRead = false;