Add web authorizations export.

This commit is contained in:
John Preston 2018-06-21 22:15:27 +01:00
parent b5a65a4519
commit 856356ce75
8 changed files with 175 additions and 25 deletions

View File

@ -963,33 +963,66 @@ bool AppendTopPeers(ContactsList &to, const MTPcontacts_TopPeers &data) {
} }
Session ParseSession(const MTPAuthorization &data) { Session ParseSession(const MTPAuthorization &data) {
Expects(data.type() == mtpc_authorization); return data.match([&](const MTPDauthorization &data) {
auto result = Session();
const auto &fields = data.c_authorization(); result.platform = ParseString(data.vplatform);
auto result = Session(); result.deviceModel = ParseString(data.vdevice_model);
result.platform = ParseString(fields.vplatform); result.systemVersion = ParseString(data.vsystem_version);
result.deviceModel = ParseString(fields.vdevice_model); result.applicationName = ParseString(data.vapp_name);
result.systemVersion = ParseString(fields.vsystem_version); result.applicationVersion = ParseString(data.vapp_version);
result.applicationName = ParseString(fields.vapp_name); result.created = data.vdate_created.v;
result.applicationVersion = ParseString(fields.vapp_version); result.lastActive = data.vdate_active.v;
result.created = fields.vdate_created.v; result.ip = ParseString(data.vip);
result.lastActive = fields.vdate_active.v; result.country = ParseString(data.vcountry);
result.ip = ParseString(fields.vip); result.region = ParseString(data.vregion);
result.country = ParseString(fields.vcountry); return result;
result.region = ParseString(fields.vregion); });
return result;
} }
SessionsList ParseSessionsList(const MTPaccount_Authorizations &data) { SessionsList ParseSessionsList(const MTPaccount_Authorizations &data) {
Expects(data.type() == mtpc_account_authorizations); return data.match([](const MTPDaccount_authorizations &data) {
auto result = SessionsList();
const auto &list = data.vauthorizations.v;
result.list.reserve(list.size());
for (const auto &session : list) {
result.list.push_back(ParseSession(session));
}
return result;
});
}
auto result = SessionsList(); WebSession ParseWebSession(
const auto &list = data.c_account_authorizations().vauthorizations.v; const MTPWebAuthorization &data,
result.list.reserve(list.size()); const std::map<int32, User> &users) {
for (const auto &session : list) { return data.match([&](const MTPDwebAuthorization &data) {
result.list.push_back(ParseSession(session)); auto result = WebSession();
} const auto i = users.find(data.vbot_id.v);
return result; if (i != users.end() && i->second.isBot) {
result.botUsername = i->second.username;
}
result.domain = ParseString(data.vdomain);
result.platform = ParseString(data.vplatform);
result.browser = ParseString(data.vbrowser);
result.created = data.vdate_created.v;
result.lastActive = data.vdate_active.v;
result.ip = ParseString(data.vip);
result.region = ParseString(data.vregion);
return result;
});
}
SessionsList ParseWebSessionsList(
const MTPaccount_WebAuthorizations &data) {
return data.match([&](const MTPDaccount_webAuthorizations &data) {
auto result = SessionsList();
const auto users = ParseUsersList(data.vusers);
const auto &list = data.vauthorizations.v;
result.webList.reserve(list.size());
for (const auto &session : list) {
result.webList.push_back(ParseWebSession(session, users));
}
return result;
});
} }
DialogInfo::Type DialogTypeFromChat(const Chat &chat) { DialogInfo::Type DialogTypeFromChat(const Chat &chat) {

View File

@ -237,11 +237,24 @@ struct Session {
Utf8String region; Utf8String region;
}; };
struct WebSession {
Utf8String botUsername;
Utf8String domain;
Utf8String browser;
Utf8String platform;
TimeId created = 0;
TimeId lastActive = 0;
Utf8String ip;
Utf8String region;
};
struct SessionsList { struct SessionsList {
std::vector<Session> list; std::vector<Session> list;
std::vector<WebSession> webList;
}; };
SessionsList ParseSessionsList(const MTPaccount_Authorizations &data); SessionsList ParseSessionsList(const MTPaccount_Authorizations &data);
SessionsList ParseWebSessionsList(const MTPaccount_WebAuthorizations &data);
struct UnsupportedMedia { struct UnsupportedMedia {
}; };

View File

@ -729,7 +729,13 @@ void ApiWrap::requestSessions(FnMut<void(Data::SessionsList&&)> done) {
mainRequest(MTPaccount_GetAuthorizations( mainRequest(MTPaccount_GetAuthorizations(
)).done([=, done = std::move(done)]( )).done([=, done = std::move(done)](
const MTPaccount_Authorizations &result) mutable { const MTPaccount_Authorizations &result) mutable {
done(Data::ParseSessionsList(result)); auto list = Data::ParseSessionsList(result);
mainRequest(MTPaccount_GetWebAuthorizations(
)).done([=, done = std::move(done), list = std::move(list)](
const MTPaccount_WebAuthorizations &result) mutable {
list.webList = Data::ParseWebSessionsList(result).webList;
done(std::move(list));
}).send();
}).send(); }).send();
} }

View File

@ -14,7 +14,11 @@ namespace Export {
namespace Output { namespace Output {
std::unique_ptr<AbstractWriter> CreateWriter(Format format) { std::unique_ptr<AbstractWriter> CreateWriter(Format format) {
return std::make_unique<JsonWriter>(); switch (format) {
case Format::Text: return std::make_unique<TextWriter>();
case Format::Json: return std::make_unique<JsonWriter>();
}
Unexpected("Format in Export::Output::CreateWriter.");
} }
} // namespace Output } // namespace Output

View File

@ -688,6 +688,17 @@ Result JsonWriter::writeFrequentContacts(const Data::ContactsList &data) {
Result JsonWriter::writeSessionsList(const Data::SessionsList &data) { Result JsonWriter::writeSessionsList(const Data::SessionsList &data) {
Expects(_output != nullptr); Expects(_output != nullptr);
if (const auto result = writeSessions(data); !result) {
return result;
} else if (const auto result = writeWebSessions(data); !result) {
return result;
}
return Result::Success();
}
Result JsonWriter::writeSessions(const Data::SessionsList &data) {
Expects(_output != nullptr);
auto block = prepareObjectItemStart("sessions"); auto block = prepareObjectItemStart("sessions");
block.append(pushNesting(Context::kArray)); block.append(pushNesting(Context::kArray));
for (const auto &session : data.list) { for (const auto &session : data.list) {
@ -714,6 +725,27 @@ Result JsonWriter::writeSessionsList(const Data::SessionsList &data) {
return _output->writeBlock(block + popNesting()); return _output->writeBlock(block + popNesting());
} }
Result JsonWriter::writeWebSessions(const Data::SessionsList &data) {
Expects(_output != nullptr);
auto block = prepareObjectItemStart("web_sessions");
block.append(pushNesting(Context::kArray));
for (const auto &session : data.webList) {
block.append(prepareArrayItemStart());
block.append(SerializeObject(_context, {
{ "last_active", SerializeDate(session.lastActive) },
{ "last_ip", SerializeString(session.ip) },
{ "last_region", SerializeString(session.region) },
{ "bot_username", StringAllowNull(session.botUsername) },
{ "domain_name", StringAllowNull(session.domain) },
{ "browser", SerializeString(session.browser) },
{ "platform", SerializeString(session.platform) },
{ "created", SerializeDate(session.created) },
}));
}
return _output->writeBlock(block + popNesting());
}
Result JsonWriter::writeDialogsStart(const Data::DialogsInfo &data) { Result JsonWriter::writeDialogsStart(const Data::DialogsInfo &data) {
return writeChatsStart(data, "chats"); return writeChatsStart(data, "chats");
} }

View File

@ -72,6 +72,9 @@ private:
Result writeSavedContacts(const Data::ContactsList &data); Result writeSavedContacts(const Data::ContactsList &data);
Result writeFrequentContacts(const Data::ContactsList &data); Result writeFrequentContacts(const Data::ContactsList &data);
Result writeSessions(const Data::SessionsList &data);
Result writeWebSessions(const Data::SessionsList &data);
Result writeChatsStart( Result writeChatsStart(
const Data::DialogsInfo &data, const Data::DialogsInfo &data,
const QByteArray &listName); const QByteArray &listName);

View File

@ -621,6 +621,17 @@ Result TextWriter::writeFrequentContacts(const Data::ContactsList &data) {
Result TextWriter::writeSessionsList(const Data::SessionsList &data) { Result TextWriter::writeSessionsList(const Data::SessionsList &data) {
Expects(_summary != nullptr); Expects(_summary != nullptr);
if (const auto result = writeSessions(data); !result) {
return result;
} else if (const auto result = writeWebSessions(data); !result) {
return result;
}
return Result::Success();
}
Result TextWriter::writeSessions(const Data::SessionsList &data) {
Expects(_summary != nullptr);
if (data.list.empty()) { if (data.list.empty()) {
return Result::Success(); return Result::Success();
} }
@ -659,6 +670,51 @@ Result TextWriter::writeSessionsList(const Data::SessionsList &data) {
return _summary->writeBlock(header); return _summary->writeBlock(header);
} }
Result TextWriter::writeWebSessions(const Data::SessionsList &data) {
Expects(_summary != nullptr);
if (data.webList.empty()) {
return Result::Success();
}
const auto file = fileWithRelativePath("web_sessions.txt");
auto list = std::vector<QByteArray>();
list.reserve(data.webList.size());
for (const auto &session : data.webList) {
list.push_back(SerializeKeyValue({
{ "Last active", Data::FormatDateTime(session.lastActive) },
{ "Last IP address", session.ip },
{ "Last region", session.region },
{
"Bot username",
(session.botUsername.isEmpty()
? Data::Utf8String("(unknown)")
: session.botUsername)
},
{
"Domain name",
(session.domain.isEmpty()
? Data::Utf8String("(unknown)")
: session.domain)
},
{ "Browser", session.browser },
{ "Platform", session.platform },
{ "Created", Data::FormatDateTime(session.created) },
}));
}
const auto full = JoinList(kLineBreak, list);
if (const auto result = file->writeBlock(full); !result) {
return result;
}
const auto header = "Web sessions "
"(" + Data::NumberToString(data.webList.size()) + ")"
" - web_sessions.txt"
+ kLineBreak
+ kLineBreak;
return _summary->writeBlock(header);
}
Result TextWriter::writeDialogsStart(const Data::DialogsInfo &data) { Result TextWriter::writeDialogsStart(const Data::DialogsInfo &data) {
return writeChatsStart(data, "Chats", "chats.txt"); return writeChatsStart(data, "Chats", "chats.txt");
} }

View File

@ -53,6 +53,9 @@ private:
Result writeSavedContacts(const Data::ContactsList &data); Result writeSavedContacts(const Data::ContactsList &data);
Result writeFrequentContacts(const Data::ContactsList &data); Result writeFrequentContacts(const Data::ContactsList &data);
Result writeSessions(const Data::SessionsList &data);
Result writeWebSessions(const Data::SessionsList &data);
Result writeChatsStart( Result writeChatsStart(
const Data::DialogsInfo &data, const Data::DialogsInfo &data,
const QByteArray &listName, const QByteArray &listName,