Phone number verification

GitOrigin-RevId: f20d2a822de49eaa558fcf0cd8ecfbfb8b3f75b8
This commit is contained in:
Arseny Smirnov 2018-04-09 17:20:12 +03:00
parent 17ffd30722
commit ed4a90a717
5 changed files with 159 additions and 61 deletions

View File

@ -88,6 +88,27 @@ Result<telegram_api::account_sendChangePhoneCode> SendCodeHelper::send_change_ph
return telegram_api::account_sendChangePhoneCode(flags, false /*ignored*/, phone_number_, is_current_phone_number);
}
Result<telegram_api::account_sendVerifyPhoneCode> SendCodeHelper::send_verify_phone_code(Slice phone_number,
bool allow_flash_call,
bool is_current_phone_number) {
phone_number_ = phone_number.str();
int32 flags = 0;
if (allow_flash_call) {
flags |= AUTH_SEND_CODE_FLAG_ALLOW_FLASH_CALL;
}
return telegram_api::account_sendVerifyPhoneCode(flags, false /*ignored*/, phone_number_, is_current_phone_number);
}
Result<telegram_api::account_sendConfirmPhoneCode> SendCodeHelper::send_confirm_phone_code(
Slice phone_number, bool allow_flash_call, bool is_current_phone_number) {
phone_number_ = phone_number.str();
int32 flags = 0;
if (allow_flash_call) {
flags |= AUTH_SEND_CODE_FLAG_ALLOW_FLASH_CALL;
}
return telegram_api::account_sendConfirmPhoneCode(flags, false /*ignored*/, phone_number_, is_current_phone_number);
}
SendCodeHelper::AuthenticationCodeInfo SendCodeHelper::get_authentication_code_info(
tl_object_ptr<telegram_api::auth_CodeType> &&code_type_ptr) {
if (code_type_ptr == nullptr) {
@ -152,8 +173,8 @@ tl_object_ptr<td_api::AuthenticationCodeType> SendCodeHelper::get_authentication
}
}
// ChangePhoneNumberManager
void ChangePhoneNumberManager::get_state(uint64 query_id) {
// PhoneNumberManager
void PhoneNumberManager::get_state(uint64 query_id) {
tl_object_ptr<td_api::Object> obj;
switch (state_) {
case State::Ok:
@ -167,24 +188,40 @@ void ChangePhoneNumberManager::get_state(uint64 query_id) {
send_closure(G()->td(), &Td::send_result, query_id, std::move(obj));
}
ChangePhoneNumberManager::ChangePhoneNumberManager(ActorShared<> parent) : parent_(std::move(parent)) {
PhoneNumberManager::PhoneNumberManager(PhoneNumberManager::Type type, ActorShared<> parent)
: type_(type), parent_(std::move(parent)) {
}
void ChangePhoneNumberManager::change_phone_number(uint64 query_id, string phone_number, bool allow_flash_call,
bool is_current_phone_number) {
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"));
}
auto r_send_code = send_code_helper_.send_change_phone_code(phone_number, allow_flash_call, is_current_phone_number);
if (r_send_code.is_error()) {
return on_query_error(query_id, r_send_code.move_as_error());
}
auto with_send_code = [&](auto c) {
switch (this->type_) {
case Type::ChangePhone:
return c(send_code_helper_.send_change_phone_code(phone_number, allow_flash_call, is_current_phone_number));
case Type::VerifyPhone:
return c(send_code_helper_.send_verify_phone_code(phone_number, allow_flash_call, is_current_phone_number));
case Type::ConfirmPhone:
return c(send_code_helper_.send_confirm_phone_code(phone_number, allow_flash_call, is_current_phone_number));
}
};
on_new_query(query_id);
auto process_send_code = [&](auto r_send_code) {
if (r_send_code.is_error()) {
return on_query_error(query_id, r_send_code.move_as_error());
}
start_net_query(NetQueryType::SendCode, G()->net_query_creator().create(create_storer(r_send_code.move_as_ok())));
on_new_query(query_id);
start_net_query(NetQueryType::SendCode, G()->net_query_creator().create(create_storer(r_send_code.move_as_ok())));
};
with_send_code(process_send_code);
}
void ChangePhoneNumberManager::resend_authentication_code(uint64 query_id) {
void PhoneNumberManager::resend_authentication_code(uint64 query_id) {
if (state_ != State::WaitCode) {
return on_query_error(query_id, Status::Error(8, "resendAuthenticationCode unexpected"));
}
@ -201,18 +238,33 @@ void ChangePhoneNumberManager::resend_authentication_code(uint64 query_id) {
NetQuery::Type::Common, NetQuery::AuthFlag::Off));
}
void ChangePhoneNumberManager::check_code(uint64 query_id, string code) {
void PhoneNumberManager::check_code(uint64 query_id, string code) {
if (state_ != State::WaitCode) {
return on_query_error(query_id, Status::Error(8, "checkAuthenticationCode unexpected"));
}
auto with_api_object = [&](auto c) {
switch (type_) {
case Type::ChangePhone:
return c(telegram_api::account_changePhone(send_code_helper_.phone_number().str(),
send_code_helper_.phone_code_hash().str(), code));
case Type::ConfirmPhone:
return c(telegram_api::account_confirmPhone(send_code_helper_.phone_code_hash().str(), code));
case Type::VerifyPhone:
return c(telegram_api::account_verifyPhone(send_code_helper_.phone_number().str(),
send_code_helper_.phone_code_hash().str(), code));
}
};
on_new_query(query_id);
start_net_query(NetQueryType::ChangePhone,
G()->net_query_creator().create(create_storer(telegram_api::account_changePhone(
send_code_helper_.phone_number().str(), send_code_helper_.phone_code_hash().str(), code))));
auto send_new_query = [&](auto q) {
start_net_query(NetQueryType::CheckCode, G()->net_query_creator().create(create_storer(q)));
};
with_api_object(send_new_query);
}
void ChangePhoneNumberManager::on_new_query(uint64 query_id) {
void PhoneNumberManager::on_new_query(uint64 query_id) {
if (query_id_ != 0) {
on_query_error(Status::Error(9, "Another authorization query has started"));
}
@ -222,7 +274,7 @@ void ChangePhoneNumberManager::on_new_query(uint64 query_id) {
// TODO: cancel older net_query
}
void ChangePhoneNumberManager::on_query_error(Status status) {
void PhoneNumberManager::on_query_error(Status status) {
CHECK(query_id_ != 0);
auto id = query_id_;
query_id_ = 0;
@ -231,11 +283,11 @@ void ChangePhoneNumberManager::on_query_error(Status status) {
on_query_error(id, std::move(status));
}
void ChangePhoneNumberManager::on_query_error(uint64 id, Status status) {
void PhoneNumberManager::on_query_error(uint64 id, Status status) {
send_closure(G()->td(), &Td::send_error, id, std::move(status));
}
void ChangePhoneNumberManager::on_query_ok() {
void PhoneNumberManager::on_query_ok() {
CHECK(query_id_ != 0);
auto id = query_id_;
net_query_id_ = 0;
@ -244,24 +296,47 @@ void ChangePhoneNumberManager::on_query_ok() {
get_state(id);
}
void ChangePhoneNumberManager::start_net_query(NetQueryType net_query_type, NetQueryPtr net_query) {
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));
}
void ChangePhoneNumberManager::on_change_phone_result(NetQueryPtr &result) {
auto r_change_phone = fetch_result<telegram_api::account_changePhone>(result->ok());
if (r_change_phone.is_error()) {
return on_query_error(r_change_phone.move_as_error());
}
state_ = State::Ok;
on_query_ok();
void PhoneNumberManager::on_check_code_result(NetQueryPtr &result) {
auto with_result = [&](auto c) {
switch (type_) {
case Type::ChangePhone:
return c(fetch_result<telegram_api::account_changePhone>(result->ok()));
case Type::VerifyPhone:
return c(fetch_result<telegram_api::account_verifyPhone>(result->ok()));
case Type::ConfirmPhone:
return c(fetch_result<telegram_api::account_confirmPhone>(result->ok()));
}
};
auto process_result = [&](auto result) {
if (result.is_error()) {
return on_query_error(result.move_as_error());
}
state_ = State::Ok;
on_query_ok();
};
with_result(process_result);
}
void ChangePhoneNumberManager::on_send_code_result(NetQueryPtr &result) {
auto r_sent_code = fetch_result<telegram_api::account_sendChangePhoneCode>(result->ok());
void PhoneNumberManager::on_send_code_result(NetQueryPtr &result) {
auto r_sent_code = [&] {
switch (type_) {
case Type::ChangePhone:
return fetch_result<telegram_api::account_sendChangePhoneCode>(result->ok());
case Type::VerifyPhone:
return fetch_result<telegram_api::account_sendVerifyPhoneCode>(result->ok());
case Type::ConfirmPhone:
return fetch_result<telegram_api::account_sendConfirmPhoneCode>(result->ok());
}
}();
if (r_sent_code.is_error()) {
return on_query_error(r_sent_code.move_as_error());
}
@ -275,7 +350,7 @@ void ChangePhoneNumberManager::on_send_code_result(NetQueryPtr &result) {
on_query_ok();
}
void ChangePhoneNumberManager::on_result(NetQueryPtr result) {
void PhoneNumberManager::on_result(NetQueryPtr result) {
SCOPE_EXIT {
result->clear();
};
@ -298,13 +373,13 @@ void ChangePhoneNumberManager::on_result(NetQueryPtr result) {
case NetQueryType::SendCode:
on_send_code_result(result);
break;
case NetQueryType::ChangePhone:
on_change_phone_result(result);
case NetQueryType::CheckCode:
on_check_code_result(result);
break;
}
}
void ChangePhoneNumberManager::tear_down() {
void PhoneNumberManager::tear_down() {
parent_.reset();
}

View File

@ -24,11 +24,19 @@ class SendCodeHelper {
td_api::object_ptr<td_api::authorizationStateWaitCode> get_authorization_state_wait_code() const;
td_api::object_ptr<td_api::authenticationCodeInfo> get_authentication_code_info_object() const;
Result<telegram_api::auth_resendCode> resend_code();
Result<telegram_api::auth_sendCode> send_code(Slice phone_number, bool allow_flash_call, bool is_current_phone_number,
int32 api_id, const string &api_hash);
Result<telegram_api::account_sendChangePhoneCode> send_change_phone_code(Slice phone_number, bool allow_flash_call,
bool is_current_phone_number);
Result<telegram_api::account_sendVerifyPhoneCode> send_verify_phone_code(Slice phone_number, bool allow_flash_call,
bool is_current_phone_number);
Result<telegram_api::account_sendConfirmPhoneCode> send_confirm_phone_code(Slice phone_number, bool allow_flash_call,
bool is_current_phone_number);
Slice phone_number() const {
return phone_number_;
}
@ -85,18 +93,22 @@ class SendCodeHelper {
const AuthenticationCodeInfo &authentication_code_info);
};
class ChangePhoneNumberManager : public NetActor {
class PhoneNumberManager : public NetActor {
public:
explicit ChangePhoneNumberManager(ActorShared<> parent);
enum class Type { ChangePhone, VerifyPhone, ConfirmPhone };
explicit PhoneNumberManager(Type type, ActorShared<> parent);
void get_state(uint64 query_id);
void change_phone_number(uint64 query_id, string phone_number, bool allow_flash_call, bool is_current_phone_number);
void set_phone_number(uint64 query_id, 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 { Ok, WaitCode } state_ = State::Ok;
enum class NetQueryType { None, SendCode, ChangePhone };
enum class NetQueryType { None, SendCode, CheckCode };
ActorShared<> parent_;
uint64 query_id_ = 0;
@ -111,7 +123,7 @@ class ChangePhoneNumberManager : public NetActor {
void on_query_ok();
void start_net_query(NetQueryType net_query_type, NetQueryPtr net_query);
void on_change_phone_result(NetQueryPtr &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;

View File

@ -4174,8 +4174,6 @@ void Td::dec_actor_refcnt() {
LOG(DEBUG) << "AudiosManager was cleared " << timer;
auth_manager_.reset();
LOG(DEBUG) << "AuthManager was cleared " << timer;
change_phone_number_manager_.reset();
LOG(DEBUG) << "ChangePhoneNumberManager was cleared " << timer;
contacts_manager_.reset();
LOG(DEBUG) << "ContactsManager was cleared " << timer;
documents_manager_.reset();
@ -4294,6 +4292,10 @@ void Td::clear() {
LOG(DEBUG) << "Requests was answered " << timer;
// close all pure actors
change_phone_number_manager_.reset();
LOG(DEBUG) << "ChangePhoneNumberManager was cleared " << timer;
verify_phone_number_manager_.reset();
LOG(DEBUG) << "ChangePhoneNumberManager was cleared " << timer;
call_manager_.reset();
LOG(DEBUG) << "CallManager was cleared " << timer;
config_manager_.reset();
@ -4325,8 +4327,6 @@ void Td::clear() {
LOG(DEBUG) << "AnimationsManager actor was cleared " << timer;
auth_manager_actor_.reset();
LOG(DEBUG) << "AuthManager actor was cleared " << timer;
change_phone_number_manager_actor_.reset();
LOG(DEBUG) << "ChangePhoneNumberManager actor was cleared " << timer;
contacts_manager_actor_.reset();
LOG(DEBUG) << "ContactsManager actor was cleared " << timer;
file_manager_actor_.reset();
@ -4530,8 +4530,6 @@ Status Td::init(DbKey key) {
animations_manager_ = std::make_unique<AnimationsManager>(this, create_reference());
animations_manager_actor_ = register_actor("AnimationsManager", animations_manager_.get());
G()->set_animations_manager(animations_manager_actor_.get());
change_phone_number_manager_ = std::make_unique<ChangePhoneNumberManager>(create_reference());
change_phone_number_manager_actor_ = register_actor("ChangePhoneNumberManager", change_phone_number_manager_.get());
contacts_manager_ = std::make_unique<ContactsManager>(this, create_reference());
contacts_manager_actor_ = register_actor("ContactsManager", contacts_manager_.get());
G()->set_contacts_manager(contacts_manager_actor_.get());
@ -4550,6 +4548,10 @@ Status Td::init(DbKey key) {
web_pages_manager_actor_ = register_actor("WebPagesManager", web_pages_manager_.get());
G()->set_web_pages_manager(web_pages_manager_actor_.get());
change_phone_number_manager_ = create_actor<PhoneNumberManager>(
"ChangePhoneNumberManager", PhoneNumberManager::Type::ChangePhone, create_reference());
verify_phone_number_manager_ = create_actor<PhoneNumberManager>(
"VerifyPhoneNumberManager", PhoneNumberManager::Type::VerifyPhone, create_reference());
call_manager_ = create_actor<CallManager>("CallManager", create_reference());
G()->set_call_manager(call_manager_.get());
device_token_manager_ = create_actor<DeviceTokenManager>("DeviceTokenManager", create_reference());
@ -5083,21 +5085,21 @@ void Td::on_request(uint64 id, td_api::changePhoneNumber &request) {
CHECK_AUTH();
CHECK_IS_USER();
CLEAN_INPUT_STRING(request.phone_number_);
change_phone_number_manager_->change_phone_number(id, std::move(request.phone_number_), request.allow_flash_call_,
request.is_current_phone_number_);
send_closure(change_phone_number_manager_, &PhoneNumberManager::set_phone_number, id,
std::move(request.phone_number_), request.allow_flash_call_, request.is_current_phone_number_);
}
void Td::on_request(uint64 id, td_api::checkChangePhoneNumberCode &request) {
CHECK_AUTH();
CHECK_IS_USER();
CLEAN_INPUT_STRING(request.code_);
change_phone_number_manager_->check_code(id, std::move(request.code_));
send_closure(change_phone_number_manager_, &PhoneNumberManager::check_code, id, std::move(request.code_));
}
void Td::on_request(uint64 id, td_api::resendChangePhoneNumberCode &request) {
CHECK_AUTH();
CHECK_IS_USER();
change_phone_number_manager_->resend_authentication_code(id);
send_closure(change_phone_number_manager_, &PhoneNumberManager::resend_authentication_code, id);
}
void Td::on_request(uint64 id, const td_api::getActiveSessions &request) {
@ -6868,20 +6870,21 @@ void Td::on_request(uint64 id, td_api::sendPhoneNumberVerificationCode &request)
CHECK_AUTH();
CHECK_IS_USER();
CLEAN_INPUT_STRING(request.phone_number_);
LOG(FATAL) << "TODO";
send_closure(verify_phone_number_manager_, &PhoneNumberManager::set_phone_number, id,
std::move(request.phone_number_), request.allow_flash_call_, request.is_current_phone_number_);
}
void Td::on_request(uint64 id, const td_api::resendPhoneNumberVerificationCode &request) {
CHECK_AUTH();
CHECK_IS_USER();
LOG(FATAL) << "TODO";
send_closure(verify_phone_number_manager_, &PhoneNumberManager::resend_authentication_code, id);
}
void Td::on_request(uint64 id, td_api::checkPhoneNumberVerificationCode &request) {
CHECK_AUTH();
CHECK_IS_USER();
CLEAN_INPUT_STRING(request.code_);
LOG(FATAL) << "TODO";
send_closure(verify_phone_number_manager_, &PhoneNumberManager::check_code, id, std::move(request.code_));
}
void Td::on_request(uint64 id, td_api::sendEmailAddressVerificationCode &request) {

View File

@ -35,7 +35,7 @@ class AudiosManager;
class AuthManager;
class CallManager;
class CallbackQueriesManager;
class ChangePhoneNumberManager;
class PhoneNumberManager;
class ConfigManager;
class ContactsManager;
class DeviceTokenManager;
@ -126,8 +126,6 @@ class Td final : public NetQueryCallback {
ActorOwn<AnimationsManager> animations_manager_actor_;
std::unique_ptr<AuthManager> auth_manager_;
ActorOwn<AuthManager> auth_manager_actor_;
std::unique_ptr<ChangePhoneNumberManager> change_phone_number_manager_;
ActorOwn<ChangePhoneNumberManager> change_phone_number_manager_actor_;
std::unique_ptr<ContactsManager> contacts_manager_;
ActorOwn<ContactsManager> contacts_manager_actor_;
std::unique_ptr<FileManager> file_manager_;
@ -143,6 +141,8 @@ class Td final : public NetQueryCallback {
std::unique_ptr<WebPagesManager> web_pages_manager_;
ActorOwn<WebPagesManager> web_pages_manager_actor_;
ActorOwn<PhoneNumberManager> change_phone_number_manager_;
ActorOwn<PhoneNumberManager> verify_phone_number_manager_;
ActorOwn<CallManager> call_manager_;
ActorOwn<ConfigManager> config_manager_;
ActorOwn<DeviceTokenManager> device_token_manager_;
@ -248,10 +248,10 @@ class Td final : public NetQueryCallback {
void on_alarm_timeout(int64 alarm_id);
template <class T>
friend class RequestActor; // uses send_result/send_error
friend class TestQuery; // uses send_result/send_error
friend class AuthManager; // uses send_result/send_error
friend class ChangePhoneNumberManager; // uses send_result/send_error
friend class RequestActor; // uses send_result/send_error
friend class TestQuery; // uses send_result/send_error
friend class AuthManager; // uses send_result/send_error
friend class PhoneNumberManager; // uses send_result/send_error
void add_handler(uint64 id, std::shared_ptr<ResultHandler> handler);
std::shared_ptr<ResultHandler> extract_handler(uint64 id);

View File

@ -968,9 +968,11 @@ class CliClient final : public Actor {
if (passport_data_type == "address" || passport_data_type == "a") {
data = "cucumber lives here";
} else if (passport_data_type == "email" || passport_data_type == "e") {
data = "{todo}";
data = file;
files.clear();
} else if (passport_data_type == "phone" || passport_data_type == "p") {
data = "{todo}";
data = file;
files.clear();
} else if (passport_data_type == "pd") {
data = "{todo}";
} else {
@ -1108,6 +1110,12 @@ class CliClient final : public Actor {
std::tie(id, types) = split(args);
send_request(make_tl_object<td_api::sendPassportAuthorizationForm>(to_integer<int32>(id),
as_passport_data_types(types), password));
} else if (op == "spnvc" || op == "SendPhoneNumberVerificationCode") {
send_request(make_tl_object<td_api::sendPhoneNumberVerificationCode>(args, false, false));
} else if (op == "cpnvc" || op == "CheckPhoneNumberVerificationCode") {
send_request(make_tl_object<td_api::checkPhoneNumberVerificationCode>(args));
} else if (op == "rpnvc" || op == "ResendPhoneNumverVerificationCode") {
send_request(make_tl_object<td_api::resendPhoneNumberVerificationCode>());
} else if (op == "srea" || op == "SetRecoveryEmailAddress") {
string password;
string recovery_email_address;