From 5d1f93c1c58d55a537cbc927fda52b56bd4f08b1 Mon Sep 17 00:00:00 2001 From: levlam Date: Sat, 16 Feb 2019 19:01:47 +0300 Subject: [PATCH] Add PhoneNumberManager.h. GitOrigin-RevId: 7823601e61375efd9e7166add8028d3f5ee6ad1f --- CMakeLists.txt | 2 + td/telegram/AuthManager.cpp | 233 -------------------------- td/telegram/AuthManager.h | 47 ------ td/telegram/AuthManager.hpp | 39 +---- td/telegram/PhoneNumberManager.cpp | 252 +++++++++++++++++++++++++++++ td/telegram/PhoneNumberManager.h | 68 ++++++++ td/telegram/Td.cpp | 1 + 7 files changed, 324 insertions(+), 318 deletions(-) create mode 100644 td/telegram/PhoneNumberManager.cpp create mode 100644 td/telegram/PhoneNumberManager.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2bd20cfbf..33d14566c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -414,6 +414,7 @@ set(TDLIB_SOURCE td/telegram/NotificationType.cpp td/telegram/Payments.cpp td/telegram/PasswordManager.cpp + td/telegram/PhoneNumberManager.cpp td/telegram/PrivacyManager.cpp td/telegram/Photo.cpp td/telegram/ReplyMarkup.cpp @@ -564,6 +565,7 @@ set(TDLIB_SOURCE td/telegram/NotificationType.h td/telegram/PasswordManager.h td/telegram/Payments.h + td/telegram/PhoneNumberManager.h td/telegram/Photo.h td/telegram/PrivacyManager.h td/telegram/PtsManager.h diff --git a/td/telegram/AuthManager.cpp b/td/telegram/AuthManager.cpp index 356e8baaf..adea085b2 100644 --- a/td/telegram/AuthManager.cpp +++ b/td/telegram/AuthManager.cpp @@ -33,239 +33,6 @@ namespace td { -void PhoneNumberManager::get_state(uint64 query_id) { - tl_object_ptr obj; - switch (state_) { - case State::Ok: - obj = make_tl_object(); - break; - case State::WaitCode: - obj = send_code_helper_.get_authentication_code_info_object(); - break; - } - CHECK(obj); - send_closure(G()->td(), &Td::send_result, query_id, std::move(obj)); -} - -PhoneNumberManager::PhoneNumberManager(PhoneNumberManager::Type type, ActorShared<> parent) - : type_(type), parent_(std::move(parent)) { -} - -template -void PhoneNumberManager::process_send_code_result(uint64 query_id, T r_send_code) { - if (r_send_code.is_error()) { - return on_query_error(query_id, r_send_code.move_as_error()); - } - - on_new_query(query_id); - - start_net_query(NetQueryType::SendCode, G()->net_query_creator().create(create_storer(r_send_code.move_as_ok()))); -} - -void PhoneNumberManager::set_phone_number(uint64 query_id, string phone_number, bool allow_flash_call, - bool is_current_phone_number) { - if (phone_number.empty()) { - return on_query_error(query_id, Status::Error(8, "Phone number can't be empty")); - } - - switch (type_) { - case Type::ChangePhone: - return process_send_code_result( - query_id, send_code_helper_.send_change_phone_code(phone_number, allow_flash_call, is_current_phone_number)); - case Type::VerifyPhone: - return process_send_code_result( - query_id, send_code_helper_.send_confirm_phone_code(phone_number, allow_flash_call, is_current_phone_number)); - case Type::ConfirmPhone: - default: - UNREACHABLE(); - } -} - -void PhoneNumberManager::set_phone_number_and_hash(uint64 query_id, string hash, string phone_number, - bool allow_flash_call, bool is_current_phone_number) { - if (phone_number.empty()) { - return on_query_error(query_id, Status::Error(8, "Phone number can't be empty")); - } - if (hash.empty()) { - return on_query_error(query_id, Status::Error(8, "Hash can't be empty")); - } - - switch (type_) { - case Type::ConfirmPhone: - return process_send_code_result(query_id, send_code_helper_.send_verify_phone_code( - hash, phone_number, allow_flash_call, is_current_phone_number)); - case Type::ChangePhone: - case Type::VerifyPhone: - default: - UNREACHABLE(); - } -} - -void PhoneNumberManager::resend_authentication_code(uint64 query_id) { - if (state_ != State::WaitCode) { - return on_query_error(query_id, Status::Error(8, "resendAuthenticationCode unexpected")); - } - - auto r_resend_code = send_code_helper_.resend_code(); - if (r_resend_code.is_error()) { - return on_query_error(query_id, r_resend_code.move_as_error()); - } - - on_new_query(query_id); - - start_net_query(NetQueryType::SendCode, - G()->net_query_creator().create(create_storer(r_resend_code.move_as_ok()), DcId::main(), - NetQuery::Type::Common, NetQuery::AuthFlag::Off)); -} - -template -void PhoneNumberManager::send_new_check_code_query(const T &query) { - start_net_query(NetQueryType::CheckCode, G()->net_query_creator().create(create_storer(query))); -} - -void PhoneNumberManager::check_code(uint64 query_id, string code) { - if (state_ != State::WaitCode) { - return on_query_error(query_id, Status::Error(8, "checkAuthenticationCode unexpected")); - } - - on_new_query(query_id); - - switch (type_) { - case Type::ChangePhone: - return send_new_check_code_query(telegram_api::account_changePhone( - send_code_helper_.phone_number().str(), send_code_helper_.phone_code_hash().str(), code)); - case Type::ConfirmPhone: - return send_new_check_code_query( - telegram_api::account_confirmPhone(send_code_helper_.phone_code_hash().str(), code)); - case Type::VerifyPhone: - return send_new_check_code_query(telegram_api::account_verifyPhone( - send_code_helper_.phone_number().str(), send_code_helper_.phone_code_hash().str(), code)); - default: - UNREACHABLE(); - } -} - -void PhoneNumberManager::on_new_query(uint64 query_id) { - if (query_id_ != 0) { - on_query_error(Status::Error(9, "Another authorization query has started")); - } - net_query_id_ = 0; - net_query_type_ = NetQueryType::None; - query_id_ = query_id; - // TODO: cancel older net_query -} - -void PhoneNumberManager::on_query_error(Status status) { - CHECK(query_id_ != 0); - auto id = query_id_; - query_id_ = 0; - net_query_id_ = 0; - net_query_type_ = NetQueryType::None; - on_query_error(id, std::move(status)); -} - -void PhoneNumberManager::on_query_error(uint64 id, Status status) { - send_closure(G()->td(), &Td::send_error, id, std::move(status)); -} - -void PhoneNumberManager::on_query_ok() { - CHECK(query_id_ != 0); - auto id = query_id_; - net_query_id_ = 0; - net_query_type_ = NetQueryType::None; - query_id_ = 0; - get_state(id); -} - -void PhoneNumberManager::start_net_query(NetQueryType net_query_type, NetQueryPtr net_query) { - // TODO: cancel old net_query? - net_query_type_ = net_query_type; - net_query_id_ = net_query->id(); - G()->net_query_dispatcher().dispatch_with_callback(std::move(net_query), actor_shared(this)); -} - -template -void PhoneNumberManager::process_check_code_result(T result) { - if (result.is_error()) { - return on_query_error(result.move_as_error()); - } - state_ = State::Ok; - on_query_ok(); -} - -void PhoneNumberManager::on_check_code_result(NetQueryPtr &result) { - switch (type_) { - case Type::ChangePhone: - return process_check_code_result(fetch_result(result->ok())); - case Type::VerifyPhone: - return process_check_code_result(fetch_result(result->ok())); - case Type::ConfirmPhone: - return process_check_code_result(fetch_result(result->ok())); - default: - UNREACHABLE(); - } -} - -void PhoneNumberManager::on_send_code_result(NetQueryPtr &result) { - auto r_sent_code = [&] { - switch (type_) { - case Type::ChangePhone: - return fetch_result(result->ok()); - case Type::VerifyPhone: - return fetch_result(result->ok()); - case Type::ConfirmPhone: - return fetch_result(result->ok()); - default: - UNREACHABLE(); - return fetch_result(result->ok()); - } - }(); - if (r_sent_code.is_error()) { - return on_query_error(r_sent_code.move_as_error()); - } - auto sent_code = r_sent_code.move_as_ok(); - - LOG(INFO) << "Receive " << to_string(sent_code); - - send_code_helper_.on_sent_code(std::move(sent_code)); - - state_ = State::WaitCode; - on_query_ok(); -} - -void PhoneNumberManager::on_result(NetQueryPtr result) { - SCOPE_EXIT { - result->clear(); - }; - NetQueryType type = NetQueryType::None; - if (result->id() == net_query_id_) { - net_query_id_ = 0; - type = net_query_type_; - net_query_type_ = NetQueryType::None; - if (result->is_error()) { - if (query_id_ != 0) { - on_query_error(std::move(result->error())); - } - return; - } - } - switch (type) { - case NetQueryType::None: - result->ignore(); - break; - case NetQueryType::SendCode: - on_send_code_result(result); - break; - case NetQueryType::CheckCode: - on_check_code_result(result); - break; - } -} - -void PhoneNumberManager::tear_down() { - parent_.reset(); -} - AuthManager::AuthManager(int32 api_id, const string &api_hash, ActorShared<> parent) : parent_(std::move(parent)), api_id_(api_id), api_hash_(api_hash) { string auth_str = G()->td_db()->get_binlog_pmc()->get("auth"); diff --git a/td/telegram/AuthManager.h b/td/telegram/AuthManager.h index 71a6fbb12..0b04b2097 100644 --- a/td/telegram/AuthManager.h +++ b/td/telegram/AuthManager.h @@ -22,53 +22,6 @@ namespace td { -class PhoneNumberManager : public NetActor { - public: - enum class Type : int32 { ChangePhone, VerifyPhone, ConfirmPhone }; - PhoneNumberManager(Type type, ActorShared<> parent); - void get_state(uint64 query_id); - - void set_phone_number(uint64 query_id, string phone_number, bool allow_flash_call, bool is_current_phone_number); - void set_phone_number_and_hash(uint64 query_id, string hash, string phone_number, bool allow_flash_call, - bool is_current_phone_number); - - void resend_authentication_code(uint64 query_id); - void check_code(uint64 query_id, string code); - - private: - Type type_; - - enum class State : int32 { Ok, WaitCode } state_ = State::Ok; - enum class NetQueryType : int32 { None, SendCode, CheckCode }; - - ActorShared<> parent_; - uint64 query_id_ = 0; - uint64 net_query_id_ = 0; - NetQueryType net_query_type_; - - SendCodeHelper send_code_helper_; - - void on_new_query(uint64 query_id); - void on_query_error(Status status); - void on_query_error(uint64 id, Status status); - void on_query_ok(); - void start_net_query(NetQueryType net_query_type, NetQueryPtr net_query); - - template - void process_send_code_result(uint64 query_id, T r_send_code); - - template - void send_new_check_code_query(const T &query); - - template - void process_check_code_result(T result); - - void on_check_code_result(NetQueryPtr &result); - void on_send_code_result(NetQueryPtr &result); - void on_result(NetQueryPtr result) override; - void tear_down() override; -}; - class AuthManager : public NetActor { public: AuthManager(int32 api_id, const string &api_hash, ActorShared<> parent); diff --git a/td/telegram/AuthManager.hpp b/td/telegram/AuthManager.hpp index 540a61ab8..09af4cbee 100644 --- a/td/telegram/AuthManager.hpp +++ b/td/telegram/AuthManager.hpp @@ -8,6 +8,7 @@ #include "td/telegram/AuthManager.h" +#include "td/telegram/SendCodeHelper.hpp" #include "td/telegram/Version.h" #include "td/utils/format.h" @@ -16,44 +17,6 @@ namespace td { -template -void SendCodeHelper::AuthenticationCodeInfo::store(T &storer) const { - using td::store; - store(type, storer); - store(length, storer); - store(pattern, storer); -} - -template -void SendCodeHelper::AuthenticationCodeInfo::parse(T &parser) { - using td::parse; - parse(type, parser); - parse(length, parser); - parse(pattern, parser); -} - -template -void SendCodeHelper::store(T &storer) const { - using td::store; - store(phone_number_, storer); - store(phone_registered_, storer); - store(phone_code_hash_, storer); - store(sent_code_info_, storer); - store(next_code_info_, storer); - store(next_code_timestamp_, storer); -} - -template -void SendCodeHelper::parse(T &parser) { - using td::parse; - parse(phone_number_, parser); - parse(phone_registered_, parser); - parse(phone_code_hash_, parser); - parse(sent_code_info_, parser); - parse(next_code_info_, parser); - parse(next_code_timestamp_, parser); -} - template void AuthManager::WaitPasswordState::store(T &storer) const { using td::store; diff --git a/td/telegram/PhoneNumberManager.cpp b/td/telegram/PhoneNumberManager.cpp new file mode 100644 index 000000000..1f429de76 --- /dev/null +++ b/td/telegram/PhoneNumberManager.cpp @@ -0,0 +1,252 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2019 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/PhoneNumberManager.h" + +#include "td/telegram/Global.h" +#include "td/telegram/net/DcId.h" +#include "td/telegram/net/NetQueryDispatcher.h" +#include "td/telegram/Td.h" + +#include "td/utils/logging.h" +#include "td/utils/ScopeGuard.h" + +namespace td { + +void PhoneNumberManager::get_state(uint64 query_id) { + tl_object_ptr obj; + switch (state_) { + case State::Ok: + obj = make_tl_object(); + break; + case State::WaitCode: + obj = send_code_helper_.get_authentication_code_info_object(); + break; + } + CHECK(obj); + send_closure(G()->td(), &Td::send_result, query_id, std::move(obj)); +} + +PhoneNumberManager::PhoneNumberManager(PhoneNumberManager::Type type, ActorShared<> parent) + : type_(type), parent_(std::move(parent)) { +} + +template +void PhoneNumberManager::process_send_code_result(uint64 query_id, T r_send_code) { + if (r_send_code.is_error()) { + return on_query_error(query_id, r_send_code.move_as_error()); + } + + on_new_query(query_id); + + start_net_query(NetQueryType::SendCode, G()->net_query_creator().create(create_storer(r_send_code.move_as_ok()))); +} + +void PhoneNumberManager::set_phone_number(uint64 query_id, string phone_number, bool allow_flash_call, + bool is_current_phone_number) { + if (phone_number.empty()) { + return on_query_error(query_id, Status::Error(8, "Phone number can't be empty")); + } + + switch (type_) { + case Type::ChangePhone: + return process_send_code_result( + query_id, send_code_helper_.send_change_phone_code(phone_number, allow_flash_call, is_current_phone_number)); + case Type::VerifyPhone: + return process_send_code_result( + query_id, send_code_helper_.send_confirm_phone_code(phone_number, allow_flash_call, is_current_phone_number)); + case Type::ConfirmPhone: + default: + UNREACHABLE(); + } +} + +void PhoneNumberManager::set_phone_number_and_hash(uint64 query_id, string hash, string phone_number, + bool allow_flash_call, bool is_current_phone_number) { + if (phone_number.empty()) { + return on_query_error(query_id, Status::Error(8, "Phone number can't be empty")); + } + if (hash.empty()) { + return on_query_error(query_id, Status::Error(8, "Hash can't be empty")); + } + + switch (type_) { + case Type::ConfirmPhone: + return process_send_code_result(query_id, send_code_helper_.send_verify_phone_code( + hash, phone_number, allow_flash_call, is_current_phone_number)); + case Type::ChangePhone: + case Type::VerifyPhone: + default: + UNREACHABLE(); + } +} + +void PhoneNumberManager::resend_authentication_code(uint64 query_id) { + if (state_ != State::WaitCode) { + return on_query_error(query_id, Status::Error(8, "resendAuthenticationCode unexpected")); + } + + auto r_resend_code = send_code_helper_.resend_code(); + if (r_resend_code.is_error()) { + return on_query_error(query_id, r_resend_code.move_as_error()); + } + + on_new_query(query_id); + + start_net_query(NetQueryType::SendCode, + G()->net_query_creator().create(create_storer(r_resend_code.move_as_ok()), DcId::main(), + NetQuery::Type::Common, NetQuery::AuthFlag::Off)); +} + +template +void PhoneNumberManager::send_new_check_code_query(const T &query) { + start_net_query(NetQueryType::CheckCode, G()->net_query_creator().create(create_storer(query))); +} + +void PhoneNumberManager::check_code(uint64 query_id, string code) { + if (state_ != State::WaitCode) { + return on_query_error(query_id, Status::Error(8, "checkAuthenticationCode unexpected")); + } + + on_new_query(query_id); + + switch (type_) { + case Type::ChangePhone: + return send_new_check_code_query(telegram_api::account_changePhone( + send_code_helper_.phone_number().str(), send_code_helper_.phone_code_hash().str(), code)); + case Type::ConfirmPhone: + return send_new_check_code_query( + telegram_api::account_confirmPhone(send_code_helper_.phone_code_hash().str(), code)); + case Type::VerifyPhone: + return send_new_check_code_query(telegram_api::account_verifyPhone( + send_code_helper_.phone_number().str(), send_code_helper_.phone_code_hash().str(), code)); + default: + UNREACHABLE(); + } +} + +void PhoneNumberManager::on_new_query(uint64 query_id) { + if (query_id_ != 0) { + on_query_error(Status::Error(9, "Another authorization query has started")); + } + net_query_id_ = 0; + net_query_type_ = NetQueryType::None; + query_id_ = query_id; + // TODO: cancel older net_query +} + +void PhoneNumberManager::on_query_error(Status status) { + CHECK(query_id_ != 0); + auto id = query_id_; + query_id_ = 0; + net_query_id_ = 0; + net_query_type_ = NetQueryType::None; + on_query_error(id, std::move(status)); +} + +void PhoneNumberManager::on_query_error(uint64 id, Status status) { + send_closure(G()->td(), &Td::send_error, id, std::move(status)); +} + +void PhoneNumberManager::on_query_ok() { + CHECK(query_id_ != 0); + auto id = query_id_; + net_query_id_ = 0; + net_query_type_ = NetQueryType::None; + query_id_ = 0; + get_state(id); +} + +void PhoneNumberManager::start_net_query(NetQueryType net_query_type, NetQueryPtr net_query) { + // TODO: cancel old net_query? + net_query_type_ = net_query_type; + net_query_id_ = net_query->id(); + G()->net_query_dispatcher().dispatch_with_callback(std::move(net_query), actor_shared(this)); +} + +template +void PhoneNumberManager::process_check_code_result(T result) { + if (result.is_error()) { + return on_query_error(result.move_as_error()); + } + state_ = State::Ok; + on_query_ok(); +} + +void PhoneNumberManager::on_check_code_result(NetQueryPtr &result) { + switch (type_) { + case Type::ChangePhone: + return process_check_code_result(fetch_result(result->ok())); + case Type::VerifyPhone: + return process_check_code_result(fetch_result(result->ok())); + case Type::ConfirmPhone: + return process_check_code_result(fetch_result(result->ok())); + default: + UNREACHABLE(); + } +} + +void PhoneNumberManager::on_send_code_result(NetQueryPtr &result) { + auto r_sent_code = [&] { + switch (type_) { + case Type::ChangePhone: + return fetch_result(result->ok()); + case Type::VerifyPhone: + return fetch_result(result->ok()); + case Type::ConfirmPhone: + return fetch_result(result->ok()); + default: + UNREACHABLE(); + return fetch_result(result->ok()); + } + }(); + if (r_sent_code.is_error()) { + return on_query_error(r_sent_code.move_as_error()); + } + auto sent_code = r_sent_code.move_as_ok(); + + LOG(INFO) << "Receive " << to_string(sent_code); + + send_code_helper_.on_sent_code(std::move(sent_code)); + + state_ = State::WaitCode; + on_query_ok(); +} + +void PhoneNumberManager::on_result(NetQueryPtr result) { + SCOPE_EXIT { + result->clear(); + }; + NetQueryType type = NetQueryType::None; + if (result->id() == net_query_id_) { + net_query_id_ = 0; + type = net_query_type_; + net_query_type_ = NetQueryType::None; + if (result->is_error()) { + if (query_id_ != 0) { + on_query_error(std::move(result->error())); + } + return; + } + } + switch (type) { + case NetQueryType::None: + result->ignore(); + break; + case NetQueryType::SendCode: + on_send_code_result(result); + break; + case NetQueryType::CheckCode: + on_check_code_result(result); + break; + } +} + +void PhoneNumberManager::tear_down() { + parent_.reset(); +} + +} // namespace td diff --git a/td/telegram/PhoneNumberManager.h b/td/telegram/PhoneNumberManager.h new file mode 100644 index 000000000..cd49445a1 --- /dev/null +++ b/td/telegram/PhoneNumberManager.h @@ -0,0 +1,68 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2019 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/net/NetActor.h" +#include "td/telegram/net/NetQuery.h" +#include "td/telegram/SendCodeHelper.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/actor/actor.h" + +#include "td/utils/common.h" + +namespace td { + +class PhoneNumberManager : public NetActor { + public: + enum class Type : int32 { ChangePhone, VerifyPhone, ConfirmPhone }; + PhoneNumberManager(Type type, ActorShared<> parent); + void get_state(uint64 query_id); + + void set_phone_number(uint64 query_id, string phone_number, bool allow_flash_call, bool is_current_phone_number); + void set_phone_number_and_hash(uint64 query_id, string hash, string phone_number, bool allow_flash_call, + bool is_current_phone_number); + + void resend_authentication_code(uint64 query_id); + void check_code(uint64 query_id, string code); + + private: + Type type_; + + enum class State : int32 { Ok, WaitCode } state_ = State::Ok; + enum class NetQueryType : int32 { None, SendCode, CheckCode }; + + ActorShared<> parent_; + uint64 query_id_ = 0; + uint64 net_query_id_ = 0; + NetQueryType net_query_type_; + + SendCodeHelper send_code_helper_; + + void on_new_query(uint64 query_id); + void on_query_error(Status status); + void on_query_error(uint64 id, Status status); + void on_query_ok(); + void start_net_query(NetQueryType net_query_type, NetQueryPtr net_query); + + template + void process_send_code_result(uint64 query_id, T r_send_code); + + template + void send_new_check_code_query(const T &query); + + template + void process_check_code_result(T result); + + void on_check_code_result(NetQueryPtr &result); + void on_send_code_result(NetQueryPtr &result); + void on_result(NetQueryPtr result) override; + void tear_down() override; +}; + +} // namespace td diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 7bd4356d2..221b869ea 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -53,6 +53,7 @@ #include "td/telegram/NotificationSettings.h" #include "td/telegram/PasswordManager.h" #include "td/telegram/Payments.h" +#include "td/telegram/PhoneNumberManager.h" #include "td/telegram/Photo.h" #include "td/telegram/PrivacyManager.h" #include "td/telegram/RequestActor.h"