From 7b5e6b93622f7ced6a84b9e6c774cb1e64b38656 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 25 Sep 2018 05:12:41 +0300 Subject: [PATCH] Split td_api::getPassportAuthorizationForm into two requests. GitOrigin-RevId: 77fc44704061109014b522d9396935ac47e4f6f9 --- td/generate/scheme/td_api.tl | 19 +- td/generate/scheme/td_api.tlo | Bin 134484 -> 134744 bytes td/telegram/SecureManager.cpp | 480 +++++++++++++++++----------------- td/telegram/SecureManager.h | 17 +- td/telegram/Td.cpp | 14 +- td/telegram/Td.h | 2 + td/telegram/cli.cpp | 18 +- 7 files changed, 294 insertions(+), 256 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 76e69cbb0..a95ad0059 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -1027,9 +1027,12 @@ passportSuitableElement type:PassportElementType is_selfie_required:Bool is_tran passportRequiredElement suitable_elements:vector = PassportRequiredElement; //@description Contains information about a Telegram Passport authorization form that was requested @id Unique identifier of the authorization form -//@required_elements Information about the Telegram Passport elements that need to be provided to complete the form @elements Already available Telegram Passport elements -//@errors Errors in the elements that are already available @privacy_policy_url URL for the privacy policy of the service; can be empty -passportAuthorizationForm id:int32 required_elements:vector elements:vector errors:vector privacy_policy_url:string = PassportAuthorizationForm; +//@required_elements Information about the Telegram Passport elements that need to be provided to complete the form +//@privacy_policy_url URL for the privacy policy of the service; can be empty +passportAuthorizationForm id:int32 required_elements:vector privacy_policy_url:string = PassportAuthorizationForm; + +//@description Contains information about a Telegram Passport elements and corresponding errors @elements Telegram Passport elements @errors Errors in the elements that are already available +passportElementsWithErrors elements:vector errors:vector = PassportElementsWithErrors; //@description Contains encrypted Telegram Passport data credentials @data The encrypted credentials @hash The decrypted data hash @secret Secret for data decryption, encrypted with the service's public key @@ -3278,10 +3281,14 @@ resendEmailAddressVerificationCode = EmailAddressAuthenticationCodeInfo; checkEmailAddressVerificationCode code:string = Ok; -//@description Returns a Telegram Passport authorization form for sharing data with a service @bot_user_id User identifier of the service's bot @scope Telegram Passport element types requested by the service @public_key Service's public_key @nonce Authorization form nonce provided by the service @password Password of the current user -getPassportAuthorizationForm bot_user_id:int32 scope:string public_key:string nonce:string password:string = PassportAuthorizationForm; +//@description Returns a Telegram Passport authorization form for sharing data with a service @bot_user_id User identifier of the service's bot @scope Telegram Passport element types requested by the service @public_key Service's public_key @nonce Authorization form nonce provided by the service +getPassportAuthorizationForm bot_user_id:int32 scope:string public_key:string nonce:string = PassportAuthorizationForm; -//@description Sends a Telegram Passport authorization form, effectively sharing data with the service @autorization_form_id Authorization form identifier @types Types of Telegram Passport elements chosen by user to complete the authorization form +//@description Returns already available Telegram Passport elements suitable for completing a Telegram Passport authorization form. Result can be received only once for each authorization form @autorization_form_id Authorization form identifier @password Password of the current user +getPassportAuthorizationFormAvailableElements autorization_form_id:int32 password:string = PassportElementsWithErrors; + +//@description Sends a Telegram Passport authorization form, effectively sharing data with the service. This method must be called after getPassportAuthorizationFormAvailableElements if some previously available elements need to be used +//@autorization_form_id Authorization form identifier @types Types of Telegram Passport elements chosen by user to complete the authorization form sendPassportAuthorizationForm autorization_form_id:int32 types:vector = Ok; diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index 154d5044589cfd4b3f14ade2a897c8b7a2f9ae46..2003be21bf79623650c2eb08bb05f9a112884d6b 100644 GIT binary patch delta 327 zcmcaIi{r)|4&Fzz^{p77;M_*u#lo!nF6kYRoZk70QF`+QVF5<@B~w`ZqyiF)iwp9L zN?dbNb5rw5io-KYGF*#_@{5Wm-)E8B{6NHmk1=htrgHg7Hn9GJ>0PfFrC31h=@W_= zH737#<1l%~TLZAj<}+{i@T!2#Ex>6m14w?d%r%qAA#WXcik#VWIBeSvf&@3${9aSd zXs}(goUz@BW1?u)3YqlO60nQ87(h1OJSODBGX3sO#_q`hIvgG#A($7h%5lX!x-v6e z7pMc~C&$u~jQpa^s>G7a{5-e(qFl$a#LS$;q?}ZkZyCUjnZDu`qs{c3U5pwmAZKi! Jv5Rp}5CEw3fqno0 delta 169 zcmcaHhvUjD4&Fzz^{p77;Os`;#lmbeG;U0l448cHjnw7~!UBw&B}6^=7*jVVDwm&R z0m)6i^G1df#JG7($cJ?@}K2(1OQy( BM2`Rf diff --git a/td/telegram/SecureManager.cpp b/td/telegram/SecureManager.cpp index f22deb267..3206a4c91 100644 --- a/td/telegram/SecureManager.cpp +++ b/td/telegram/SecureManager.cpp @@ -157,7 +157,7 @@ GetSecureValue::GetSecureValue(ActorShared parent, std::string pa } void GetSecureValue::on_error(Status error) { - if (error.code() != 0) { + if (error.code() > 0) { promise_.set_error(std::move(error)); } else { promise_.set_error(Status::Error(400, error.message())); @@ -233,7 +233,7 @@ GetAllSecureValues::GetAllSecureValues(ActorShared parent, std::s } void GetAllSecureValues::on_error(Status error) { - if (error.code() != 0) { + if (error.code() > 0) { promise_.set_error(std::move(error)); } else { promise_.set_error(Status::Error(400, error.message())); @@ -361,7 +361,7 @@ void SetSecureValue::on_upload_error(FileId file_id, Status error) { } void SetSecureValue::on_error(Status error) { - if (error.code() != 0) { + if (error.code() > 0) { promise_.set_error(std::move(error)); } else { promise_.set_error(Status::Error(400, error.message())); @@ -624,13 +624,9 @@ class DeleteSecureValue : public NetQueryCallback { class GetPassportAuthorizationForm : public NetQueryCallback { public: - GetPassportAuthorizationForm( - ActorShared parent, string password, int32 authorization_form_id, UserId bot_user_id, string scope, - string public_key, - Promise, TdApiAuthorizationForm>> promise) + GetPassportAuthorizationForm(ActorShared parent, UserId bot_user_id, string scope, string public_key, + Promise> promise) : parent_(std::move(parent)) - , password_(std::move(password)) - , authorization_form_id_(authorization_form_id) , bot_user_id_(bot_user_id) , scope_(std::move(scope)) , public_key_(std::move(public_key)) @@ -639,28 +635,13 @@ class GetPassportAuthorizationForm : public NetQueryCallback { private: ActorShared parent_; - string password_; - int32 authorization_form_id_; UserId bot_user_id_; string scope_; string public_key_; - Promise, TdApiAuthorizationForm>> promise_; - optional secret_; - telegram_api::object_ptr authorization_form_; - - void on_secret(Result r_secret, bool dummy) { - if (r_secret.is_error()) { - if (!G()->close_flag()) { - LOG(ERROR) << "Receive error instead of secret: " << r_secret.error(); - } - return on_error(r_secret.move_as_error()); - } - secret_ = r_secret.move_as_ok(); - loop(); - } + Promise> promise_; void on_error(Status error) { - if (error.code() != 0) { + if (error.code() > 0) { promise_.set_error(std::move(error)); } else { promise_.set_error(Status::Error(400, error.message())); @@ -673,11 +654,6 @@ class GetPassportAuthorizationForm : public NetQueryCallback { telegram_api::account_getAuthorizationForm(bot_user_id_.get(), std::move(scope_), std::move(public_key_)); auto query = G()->net_query_creator().create(create_storer(account_get_authorization_form)); G()->net_query_dispatcher().dispatch_with_callback(std::move(query), actor_shared(this)); - - send_closure(G()->password_manager(), &PasswordManager::get_secure_secret, password_, - PromiseCreator::lambda([actor_id = actor_id(this)](Result r_secret) { - send_closure(actor_id, &GetPassportAuthorizationForm::on_secret, std::move(r_secret), true); - })); } void on_result(NetQueryPtr query) override { @@ -685,197 +661,7 @@ class GetPassportAuthorizationForm : public NetQueryCallback { if (r_result.is_error()) { return on_error(r_result.move_as_error()); } - authorization_form_ = r_result.move_as_ok(); - LOG(INFO) << "Receive " << to_string(authorization_form_); - loop(); - } - - static int32 get_file_index(const vector &file_credentials, Slice file_hash) { - for (size_t i = 0; i < file_credentials.size(); i++) { - if (file_credentials[i].hash == file_hash) { - return narrow_cast(i); - } - } - return -1; - } - - void loop() override { - if (!secret_ || !authorization_form_) { - return; - } - - G()->td().get_actor_unsafe()->contacts_manager_->on_get_users(std::move(authorization_form_->users_)); - - auto *file_manager = G()->td().get_actor_unsafe()->file_manager_.get(); - vector> required_types; - std::map all_types; - for (auto &type_ptr : authorization_form_->required_types_) { - CHECK(type_ptr != nullptr); - vector required_type; - switch (type_ptr->get_id()) { - case telegram_api::secureRequiredType::ID: { - auto value = get_suitable_secure_value(move_tl_object_as(type_ptr)); - all_types.emplace(value.type, value); - required_type.push_back(std::move(value)); - break; - } - case telegram_api::secureRequiredTypeOneOf::ID: { - auto type_one_of = move_tl_object_as(type_ptr); - for (auto &type : type_one_of->types_) { - if (type->get_id() == telegram_api::secureRequiredType::ID) { - auto value = get_suitable_secure_value(move_tl_object_as(type)); - all_types.emplace(value.type, value); - required_type.push_back(std::move(value)); - } else { - LOG(ERROR) << to_string(type); - } - } - break; - } - default: - UNREACHABLE(); - } - if (!required_type.empty()) { - required_types.push_back(required_type); - } - } - - std::vector values; - std::map all_credentials; - for (auto suitable_type : all_types) { - auto type = suitable_type.first; - for (auto &value : authorization_form_->values_) { - if (value == nullptr) { - continue; - } - auto value_type = get_secure_value_type(value->type_); - if (value_type != type) { - continue; - } - - auto r_secure_value = - decrypt_secure_value(file_manager, *secret_, get_encrypted_secure_value(file_manager, std::move(value))); - value = nullptr; - if (r_secure_value.is_error()) { - LOG(ERROR) << "Failed to decrypt secure value: " << r_secure_value.error(); - break; - } - - send_closure(parent_, &SecureManager::on_get_secure_value, r_secure_value.ok()); - - auto secure_value = r_secure_value.move_as_ok(); - auto r_passport_element = get_passport_element_object(file_manager, std::move(secure_value.value)); - if (r_passport_element.is_error()) { - LOG(ERROR) << "Failed to get passport element object: " << r_passport_element.error(); - break; - } - values.push_back(r_passport_element.move_as_ok()); - all_credentials.emplace(type, std::move(secure_value.credentials)); - - break; - } - } - - vector> errors; - for (auto &error_ptr : authorization_form_->errors_) { - CHECK(error_ptr != nullptr); - SecureValueType type = SecureValueType::None; - td_api::object_ptr source; - string message; - switch (error_ptr->get_id()) { - case telegram_api::secureValueError::ID: { - auto error = move_tl_object_as(error_ptr); - type = get_secure_value_type(error->type_); - message = std::move(error->text_); - source = td_api::make_object(); - break; - } - case telegram_api::secureValueErrorData::ID: { - auto error = move_tl_object_as(error_ptr); - type = get_secure_value_type(error->type_); - message = std::move(error->text_); - string field_name = get_secure_value_data_field_name(type, error->field_); - if (field_name.empty()) { - break; - } - source = td_api::make_object(std::move(field_name)); - break; - } - case telegram_api::secureValueErrorFile::ID: { - auto error = move_tl_object_as(error_ptr); - type = get_secure_value_type(error->type_); - message = std::move(error->text_); - int32 file_index = get_file_index(all_credentials[type].files, error->file_hash_.as_slice()); - if (file_index == -1) { - LOG(ERROR) << "Can't find file with error"; - break; - } - source = td_api::make_object(file_index); - break; - } - case telegram_api::secureValueErrorFiles::ID: { - auto error = move_tl_object_as(error_ptr); - type = get_secure_value_type(error->type_); - message = std::move(error->text_); - source = td_api::make_object(); - break; - } - case telegram_api::secureValueErrorFrontSide::ID: { - auto error = move_tl_object_as(error_ptr); - type = get_secure_value_type(error->type_); - message = std::move(error->text_); - source = td_api::make_object(); - break; - } - case telegram_api::secureValueErrorReverseSide::ID: { - auto error = move_tl_object_as(error_ptr); - type = get_secure_value_type(error->type_); - message = std::move(error->text_); - source = td_api::make_object(); - break; - } - case telegram_api::secureValueErrorSelfie::ID: { - auto error = move_tl_object_as(error_ptr); - type = get_secure_value_type(error->type_); - message = std::move(error->text_); - source = td_api::make_object(); - break; - } - case telegram_api::secureValueErrorTranslationFile::ID: { - auto error = move_tl_object_as(error_ptr); - type = get_secure_value_type(error->type_); - message = std::move(error->text_); - int32 file_index = get_file_index(all_credentials[type].translations, error->file_hash_.as_slice()); - if (file_index == -1) { - LOG(ERROR) << "Can't find translation file with error"; - break; - } - source = td_api::make_object(file_index); - break; - } - case telegram_api::secureValueErrorTranslationFiles::ID: { - auto error = move_tl_object_as(error_ptr); - type = get_secure_value_type(error->type_); - message = std::move(error->text_); - source = td_api::make_object(); - break; - } - default: - UNREACHABLE(); - } - if (source == nullptr) { - continue; - } - - errors.push_back(td_api::make_object(get_passport_element_type_object(type), - message, std::move(source))); - } - - auto authorization_form = make_tl_object( - authorization_form_id_, get_passport_required_elements_object(required_types), std::move(values), - std::move(errors), authorization_form_->privacy_policy_url_); - - promise_.set_value({std::move(all_types), std::move(authorization_form)}); + promise_.set_value(r_result.move_as_ok()); stop(); } }; @@ -1106,8 +892,7 @@ void SecureManager::set_secure_value_errors(Td *td, tl_object_ptrsend(std::move(input_user), std::move(input_errors)); } -void SecureManager::get_passport_authorization_form(string password, UserId bot_user_id, string scope, - string public_key, string nonce, +void SecureManager::get_passport_authorization_form(UserId bot_user_id, string scope, string public_key, string nonce, Promise promise) { refcnt_++; auto authorization_form_id = ++max_authorization_form_id_; @@ -1116,23 +901,20 @@ void SecureManager::get_passport_authorization_form(string password, UserId bot_ form.scope = scope; form.public_key = public_key; form.nonce = nonce; - form.is_received = false; auto new_promise = PromiseCreator::lambda( [actor_id = actor_id(this), authorization_form_id, promise = std::move(promise)]( - Result, TdApiAuthorizationForm>> - r_authorization_form) mutable { + Result> r_authorization_form) mutable { send_closure(actor_id, &SecureManager::on_get_passport_authorization_form, authorization_form_id, std::move(promise), std::move(r_authorization_form)); }); - create_actor("GetPassportAuthorizationForm", actor_shared(this), std::move(password), - authorization_form_id, bot_user_id, std::move(scope), - std::move(public_key), std::move(new_promise)) + create_actor("GetPassportAuthorizationForm", actor_shared(this), bot_user_id, + std::move(scope), std::move(public_key), std::move(new_promise)) .release(); } void SecureManager::on_get_passport_authorization_form( int32 authorization_form_id, Promise promise, - Result, TdApiAuthorizationForm>> r_authorization_form) { + Result> r_authorization_form) { auto it = authorization_forms_.find(authorization_form_id); CHECK(it != authorization_forms_.end()); CHECK(it->second.is_received == false); @@ -1142,10 +924,239 @@ void SecureManager::on_get_passport_authorization_form( } auto authorization_form = r_authorization_form.move_as_ok(); - it->second.options = std::move(authorization_form.first); + LOG(INFO) << "Receive " << to_string(authorization_form); + G()->td().get_actor_unsafe()->contacts_manager_->on_get_users(std::move(authorization_form->users_)); + + vector> required_types; + std::map all_types; + for (auto &type_ptr : authorization_form->required_types_) { + CHECK(type_ptr != nullptr); + vector required_type; + switch (type_ptr->get_id()) { + case telegram_api::secureRequiredType::ID: { + auto value = get_suitable_secure_value(move_tl_object_as(type_ptr)); + all_types.emplace(value.type, value); + required_type.push_back(std::move(value)); + break; + } + case telegram_api::secureRequiredTypeOneOf::ID: { + auto type_one_of = move_tl_object_as(type_ptr); + for (auto &type : type_one_of->types_) { + if (type->get_id() == telegram_api::secureRequiredType::ID) { + auto value = get_suitable_secure_value(move_tl_object_as(type)); + all_types.emplace(value.type, value); + required_type.push_back(std::move(value)); + } else { + LOG(ERROR) << to_string(type); + } + } + break; + } + default: + UNREACHABLE(); + } + if (!required_type.empty()) { + required_types.push_back(required_type); + } + } + + it->second.options = std::move(all_types); + it->second.values = std::move(authorization_form->values_); + it->second.errors = std::move(authorization_form->errors_); it->second.is_received = true; - CHECK(authorization_form.second != nullptr); - promise.set_value(std::move(authorization_form.second)); + + promise.set_value(td_api::make_object( + authorization_form_id, get_passport_required_elements_object(required_types), + authorization_form->privacy_policy_url_)); +} + +void SecureManager::get_passport_authorization_form_available_elements(int32 authorization_form_id, string password, + Promise promise) { + auto it = authorization_forms_.find(authorization_form_id); + if (it == authorization_forms_.end()) { + return promise.set_error(Status::Error(400, "Unknown authorization_form_id")); + } + if (!it->second.is_received) { + return promise.set_error(Status::Error(400, "Authorization form isn't received yet")); + } + + refcnt_++; + send_closure(G()->password_manager(), &PasswordManager::get_secure_secret, password, + PromiseCreator::lambda([actor_id = actor_shared(this), authorization_form_id, + promise = std::move(promise)](Result r_secret) mutable { + send_closure(actor_id, &SecureManager::on_get_passport_authorization_form_secret, + authorization_form_id, std::move(promise), std::move(r_secret)); + })); +} + +void SecureManager::on_get_passport_authorization_form_secret(int32 authorization_form_id, + Promise promise, + Result r_secret) { + auto it = authorization_forms_.find(authorization_form_id); + if (it == authorization_forms_.end()) { + return promise.set_error(Status::Error(400, "Authorization form has already been sent")); + } + CHECK(it->second.is_received); + if (it->second.is_decrypted) { + return promise.set_error(Status::Error(400, "Authorization form has already been decrypted")); + } + + if (r_secret.is_error()) { + auto error = r_secret.move_as_error(); + if (!G()->close_flag()) { + LOG(ERROR) << "Receive error instead of secret: " << error; + } + if (error.code() <= 0) { + error = Status::Error(400, error.message()); // TODO error.set_code(400) ? + } + return promise.set_error(std::move(error)); + } + auto secret = r_secret.move_as_ok(); + + it->second.is_decrypted = true; + + auto *file_manager = G()->td().get_actor_unsafe()->file_manager_.get(); + std::vector values; + std::map all_credentials; + for (auto suitable_type : it->second.options) { + auto type = suitable_type.first; + for (auto &value : it->second.values) { + if (value == nullptr) { + continue; + } + auto value_type = get_secure_value_type(value->type_); + if (value_type != type) { + continue; + } + + auto r_secure_value = + decrypt_secure_value(file_manager, secret, get_encrypted_secure_value(file_manager, std::move(value))); + value = nullptr; + if (r_secure_value.is_error()) { + LOG(ERROR) << "Failed to decrypt secure value: " << r_secure_value.error(); + break; + } + + on_get_secure_value(r_secure_value.ok()); + + auto secure_value = r_secure_value.move_as_ok(); + auto r_passport_element = get_passport_element_object(file_manager, std::move(secure_value.value)); + if (r_passport_element.is_error()) { + LOG(ERROR) << "Failed to get passport element object: " << r_passport_element.error(); + break; + } + values.push_back(r_passport_element.move_as_ok()); + all_credentials.emplace(type, std::move(secure_value.credentials)); + + break; + } + } + + auto get_file_index = [](const vector &file_credentials, Slice file_hash) -> int32 { + for (size_t i = 0; i < file_credentials.size(); i++) { + if (file_credentials[i].hash == file_hash) { + return narrow_cast(i); + } + } + return -1; + }; + + vector> errors; + for (auto &error_ptr : it->second.errors) { + CHECK(error_ptr != nullptr); + SecureValueType type = SecureValueType::None; + td_api::object_ptr source; + string message; + switch (error_ptr->get_id()) { + case telegram_api::secureValueError::ID: { + auto error = move_tl_object_as(error_ptr); + type = get_secure_value_type(error->type_); + message = std::move(error->text_); + source = td_api::make_object(); + break; + } + case telegram_api::secureValueErrorData::ID: { + auto error = move_tl_object_as(error_ptr); + type = get_secure_value_type(error->type_); + message = std::move(error->text_); + string field_name = get_secure_value_data_field_name(type, error->field_); + if (field_name.empty()) { + break; + } + source = td_api::make_object(std::move(field_name)); + break; + } + case telegram_api::secureValueErrorFile::ID: { + auto error = move_tl_object_as(error_ptr); + type = get_secure_value_type(error->type_); + message = std::move(error->text_); + int32 file_index = get_file_index(all_credentials[type].files, error->file_hash_.as_slice()); + if (file_index == -1) { + LOG(ERROR) << "Can't find file with error"; + break; + } + source = td_api::make_object(file_index); + break; + } + case telegram_api::secureValueErrorFiles::ID: { + auto error = move_tl_object_as(error_ptr); + type = get_secure_value_type(error->type_); + message = std::move(error->text_); + source = td_api::make_object(); + break; + } + case telegram_api::secureValueErrorFrontSide::ID: { + auto error = move_tl_object_as(error_ptr); + type = get_secure_value_type(error->type_); + message = std::move(error->text_); + source = td_api::make_object(); + break; + } + case telegram_api::secureValueErrorReverseSide::ID: { + auto error = move_tl_object_as(error_ptr); + type = get_secure_value_type(error->type_); + message = std::move(error->text_); + source = td_api::make_object(); + break; + } + case telegram_api::secureValueErrorSelfie::ID: { + auto error = move_tl_object_as(error_ptr); + type = get_secure_value_type(error->type_); + message = std::move(error->text_); + source = td_api::make_object(); + break; + } + case telegram_api::secureValueErrorTranslationFile::ID: { + auto error = move_tl_object_as(error_ptr); + type = get_secure_value_type(error->type_); + message = std::move(error->text_); + int32 file_index = get_file_index(all_credentials[type].translations, error->file_hash_.as_slice()); + if (file_index == -1) { + LOG(ERROR) << "Can't find translation file with error"; + break; + } + source = td_api::make_object(file_index); + break; + } + case telegram_api::secureValueErrorTranslationFiles::ID: { + auto error = move_tl_object_as(error_ptr); + type = get_secure_value_type(error->type_); + message = std::move(error->text_); + source = td_api::make_object(); + break; + } + default: + UNREACHABLE(); + } + if (source == nullptr) { + continue; + } + + errors.push_back(td_api::make_object(get_passport_element_type_object(type), message, + std::move(source))); + } + + promise.set_value(td_api::make_object(std::move(values), std::move(errors))); } void SecureManager::send_passport_authorization_form(int32 authorization_form_id, std::vector types, @@ -1157,6 +1168,7 @@ void SecureManager::send_passport_authorization_form(int32 authorization_form_id if (!it->second.is_received) { return promise.set_error(Status::Error(400, "Authorization form isn't received yet")); } + // there is no need to check for is_decrypted if (types.empty()) { return promise.set_error(Status::Error(400, "Types must be non-empty")); } diff --git a/td/telegram/SecureManager.h b/td/telegram/SecureManager.h index b7f007626..4e4b36966 100644 --- a/td/telegram/SecureManager.h +++ b/td/telegram/SecureManager.h @@ -30,6 +30,7 @@ class Td; using TdApiSecureValue = td_api::object_ptr; using TdApiSecureValues = td_api::object_ptr; +using TdApiSecureValuesWithErrors = td_api::object_ptr; using TdApiAuthorizationForm = td_api::object_ptr; class SecureManager : public NetQueryCallback { @@ -45,8 +46,10 @@ class SecureManager : public NetQueryCallback { void on_get_secure_value(SecureValueWithCredentials value); - void get_passport_authorization_form(string password, UserId bot_user_id, string scope, string public_key, - string nonce, Promise promise); + void get_passport_authorization_form(UserId bot_user_id, string scope, string public_key, string nonce, + Promise promise); + void get_passport_authorization_form_available_elements(int32 authorization_form_id, string password, + Promise promise); void send_passport_authorization_form(int32 authorization_form_id, std::vector types, Promise<> promise); @@ -63,8 +66,11 @@ class SecureManager : public NetQueryCallback { string scope; string public_key; string nonce; - bool is_received; + bool is_received = false; + bool is_decrypted = false; std::map options; + vector> values; + vector> errors; }; std::unordered_map authorization_forms_; @@ -76,7 +82,10 @@ class SecureManager : public NetQueryCallback { void on_delete_secure_value(SecureValueType type, Promise promise, Result result); void on_get_passport_authorization_form( int32 authorization_form_id, Promise promise, - Result, TdApiAuthorizationForm>> r_authorization_form); + Result> r_authorization_form); + void on_get_passport_authorization_form_secret(int32 authorization_form_id, + Promise promise, + Result r_secret); void on_result(NetQueryPtr query) override; Container> container_; diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 82026cfdb..0a34cce2a 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -6597,7 +6597,6 @@ void Td::on_request(uint64 id, td_api::checkEmailAddressVerificationCode &reques void Td::on_request(uint64 id, td_api::getPassportAuthorizationForm &request) { CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.password_); CLEAN_INPUT_STRING(request.public_key_); CLEAN_INPUT_STRING(request.scope_); CLEAN_INPUT_STRING(request.nonce_); @@ -6609,9 +6608,16 @@ void Td::on_request(uint64 id, td_api::getPassportAuthorizationForm &request) { return send_error_raw(id, 400, "Nonce must be non-empty"); } CREATE_REQUEST_PROMISE(); - send_closure(secure_manager_, &SecureManager::get_passport_authorization_form, std::move(request.password_), - bot_user_id, std::move(request.scope_), std::move(request.public_key_), std::move(request.nonce_), - std::move(promise)); + send_closure(secure_manager_, &SecureManager::get_passport_authorization_form, bot_user_id, std::move(request.scope_), + std::move(request.public_key_), std::move(request.nonce_), std::move(promise)); +} + +void Td::on_request(uint64 id, td_api::getPassportAuthorizationFormAvailableElements &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.password_); + CREATE_REQUEST_PROMISE(); + send_closure(secure_manager_, &SecureManager::get_passport_authorization_form_available_elements, + request.autorization_form_id_, std::move(request.password_), std::move(promise)); } void Td::on_request(uint64 id, td_api::sendPassportAuthorizationForm &request) { diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 368b341d5..cad3a1b6d 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -839,6 +839,8 @@ class Td final : public NetQueryCallback { void on_request(uint64 id, td_api::getPassportAuthorizationForm &request); + void on_request(uint64 id, td_api::getPassportAuthorizationFormAvailableElements &request); + void on_request(uint64 id, td_api::sendPassportAuthorizationForm &request); void on_request(uint64 id, td_api::sendPhoneNumberConfirmationCode &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 5e4d22fb6..17a11b4a9 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -1236,8 +1236,6 @@ class CliClient final : public Actor { } send_request(make_tl_object(password, new_password, new_hint, true, recovery_email_address)); } else if (op == "gpafhttp") { - string password; - std::tie(password, args) = split(args); ChainBufferWriter writer; writer.append(PSLICE() << "GET " << args << " HTTP/1.1\r\n\r\n\r\n"); ChainBufferReader reader = writer.extract_reader(); @@ -1254,10 +1252,9 @@ class CliClient final : public Actor { string public_key = query.get_arg("public_key").str(); string payload = query.get_arg("payload").str(); LOG(INFO) << "Callback URL:" << query.get_arg("callback_url"); - send_request(make_tl_object(to_integer(bot_id), scope, public_key, - payload, password)); + send_request( + make_tl_object(to_integer(bot_id), scope, public_key, payload)); } else if (op == "gpaf") { - string password; string bot_id; string scope; string public_key = @@ -1277,11 +1274,16 @@ class CliClient final : public Actor { "-----END PUBLIC KEY-----"; string payload; - std::tie(password, args) = split(args); std::tie(bot_id, args) = split(args); std::tie(scope, payload) = split(args); - send_request(make_tl_object(to_integer(bot_id), scope, public_key, - payload, password)); + send_request( + make_tl_object(to_integer(bot_id), scope, public_key, payload)); + } else if (op == "gpafae") { + string id; + string password; + std::tie(id, password) = split(args); + send_request( + make_tl_object(to_integer(id), password)); } else if (op == "spaf") { string id; string types;