From 4f8d8555276a6ad3a2725698dae56f2d50d32154 Mon Sep 17 00:00:00 2001 From: levlam Date: Sun, 12 Aug 2018 12:51:24 +0300 Subject: [PATCH] Support new Passport authorization form. GitOrigin-RevId: 5830754700dcd19f4e0bcb08ccb5d72c22db76f0 --- td/generate/scheme/td_api.tl | 12 ++++-- td/generate/scheme/td_api.tlo | Bin 132104 -> 132484 bytes td/telegram/SecureManager.cpp | 35 +++++++++++------ td/telegram/SecureValue.cpp | 54 +++++++++++++++++++------- td/telegram/SecureValue.h | 24 +++++++++++- td/telegram/net/ConnectionCreator.cpp | 2 +- 6 files changed, 95 insertions(+), 32 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 6818dc38..d8505083 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -1008,11 +1008,17 @@ passportElementErrorSourceFiles = PassportElementErrorSource; passportElementError type:PassportElementType message:string source:PassportElementErrorSource = PassportElementError; +//@description Contains information about a Telegram Passport element that was requested by a service @type Type of the element @is_selfie_required True, if a selfie is required with the identity document +//@is_translation_required True, if a translation is required with the identity document @is_native_name_required True, if a native name is required with the personal details +passportSuitableElement type:PassportElementType is_selfie_required:Bool is_translation_required:Bool is_native_name_required:Bool = PassportSuitableElement; + +//@description Contains description of required Telegram Passport element that was requested by a service @suitable_elements List of Telegram Passport elements any of which is enough to provide +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_types Telegram Passport element types that need to be provided to complete the form. If the user has more than one identity document or proof of address document, any one of each can be chosen -//@elements Already available Telegram Passport elements @errors Errors in the elements that is already available @is_selfie_required True, if a selfie is required with the identity document -//@is_translation_required True, if a translation is required with the identity document @privacy_policy_url URL for the privacy policy of the service; can be empty -passportAuthorizationForm id:int32 required_types:vector elements:vector errors:vector is_selfie_required:Bool is_translation_required:Bool privacy_policy_url:string = PassportAuthorizationForm; +//@elements Already available Telegram Passport elements @errors Errors in the elements that is 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; //@description Contains encrypted Telegram Passport data credentials @data The encrypted credentials @hash The decrypted data hash @secret Secret for data decryption, encrypted with service's public key diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index 1576b0a0d8471f23cd90e11645d059494a29ec83..c3eb8eaea2d5940d1bb7213160e4de398c6f5ac2 100644 GIT binary patch delta 419 zcmeC^;ArXQ;C(b(---bWPHg1W7iO8EabxOc2VosXnX~LiI>iGLi;D~Li%No03rjPL zQd3-WQgc)DN+wQ_kdbNraRDwLT$)*un3R)>kl&mm62r@wu=%87`w2~usgeayvm8rH zGV+Tus}f5x^Yh&Di*gwlK=L<_3Hh*2Hq=oT6fA<;7M}{SZt}wA@~j~DFit-Es$%lO z*ZL55UU@x-*B0zfnAvFV1j&KSWd!L&Z%5lYjeG9V%&9@*qkS#2e8CR=Mc6l8$x!^SmcOKAxWvTIbiMgqh>tD-GRxsmW r0jb=a@^j4&u=}S!Si@*AeT567z~nc|0@G7AG3J29w_n-BXc7njGXte~ delta 141 zcmZqa=IH3);C(b(---bWj&0=C7iO9Bard*$4#GN&o3Dt(@G{12HdJaq!3GkQESO%n znNbR?V)BA+iRl}d83p+Hic$+pGmBDF;!7$EQj4eeKW5aM?D{%qvhT0x$s1l9Kn#5H cdJgaAH@_C_0CT5L*vz;G%-SBXh0!Ds0CBZHk^lez diff --git a/td/telegram/SecureManager.cpp b/td/telegram/SecureManager.cpp index f9f22031..b379803f 100644 --- a/td/telegram/SecureManager.cpp +++ b/td/telegram/SecureManager.cpp @@ -681,27 +681,39 @@ class GetPassportAuthorizationForm : public NetQueryCallback { 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(); - std::vector values; - vector types; + vector> required_types; + vector 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 type = move_tl_object_as(type_ptr); - types.push_back(get_secure_value_type(type->type_)); + auto value = get_suitable_secure_value(move_tl_object_as(type_ptr)); + all_types.push_back(value.type); + required_type.push_back(std::move(value)); break; } case telegram_api::secureRequiredTypeOneOf::ID: { - auto type = move_tl_object_as(type_ptr); - // TODO - // append(types, get_secure_value_types(type->types_)); + 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.push_back(value.type); + required_type.push_back(std::move(value)); + } else { + LOG(ERROR) << to_string(type); + } + } break; } default: UNREACHABLE(); } } - for (auto type : types) { + all_types = unique_secure_value_types(std::move(all_types)); + + std::vector values; + for (auto type : all_types) { for (auto &value : authorization_form_->values_) { if (value == nullptr) { continue; @@ -817,8 +829,8 @@ class GetPassportAuthorizationForm : public NetQueryCallback { } promise_.set_value(make_tl_object( - authorization_form_id_, get_passport_element_types_object(types), std::move(values), std::move(errors), true, - true, authorization_form_->privacy_policy_url_)); + authorization_form_id_, get_passport_required_elements_object(required_types), std::move(values), + std::move(errors), authorization_form_->privacy_policy_url_)); stop(); } }; @@ -1090,8 +1102,7 @@ void SecureManager::do_send_passport_authorization_form(int32 authorization_form BufferSlice(c.hash))); } - auto r_encrypted_credentials = - get_encrypted_credentials(credentials, it->second.payload, true, true, it->second.public_key); + auto r_encrypted_credentials = get_encrypted_credentials(credentials, it->second.payload, it->second.public_key); if (r_encrypted_credentials.is_error()) { return promise.set_error(r_encrypted_credentials.move_as_error()); } diff --git a/td/telegram/SecureValue.cpp b/td/telegram/SecureValue.cpp index 4681c706..3514b9f8 100644 --- a/td/telegram/SecureValue.cpp +++ b/td/telegram/SecureValue.cpp @@ -136,7 +136,7 @@ SecureValueType get_secure_value_type_td_api(const tl_object_ptr unique_types(vector types) { +vector unique_secure_value_types(vector types) { size_t size = types.size(); for (size_t i = 0; i < size; i++) { for (size_t j = 0; j < i; j++) { @@ -153,12 +153,12 @@ static vector unique_types(vector types) { vector get_secure_value_types( const vector> &secure_value_types) { - return unique_types(transform(secure_value_types, get_secure_value_type)); + return unique_secure_value_types(transform(secure_value_types, get_secure_value_type)); } vector get_secure_value_types_td_api( const vector> &secure_value_types) { - return unique_types(transform(secure_value_types, get_secure_value_type_td_api)); + return unique_secure_value_types(transform(secure_value_types, get_secure_value_type_td_api)); } td_api::object_ptr get_passport_element_type_object(SecureValueType type) { @@ -236,6 +236,35 @@ vector> get_passport_element_typ return transform(types, get_passport_element_type_object); } +SuitableSecureValue get_suitable_secure_value( + const tl_object_ptr &secure_required_type) { + SuitableSecureValue result; + result.type = get_secure_value_type(secure_required_type->type_); + auto flags = secure_required_type->flags_; + result.is_selfie_required = (flags & telegram_api::secureRequiredType::SELFIE_REQUIRED_MASK) != 0; + result.is_translation_required = (flags & telegram_api::secureRequiredType::TRANSLATION_REQUIRED_MASK) != 0; + result.is_native_name_required = (flags & telegram_api::secureRequiredType::NATIVE_NAMES_MASK) != 0; + return result; +} + +td_api::object_ptr get_passport_suitable_element_object( + const SuitableSecureValue &element) { + return td_api::make_object( + get_passport_element_type_object(element.type), element.is_selfie_required, element.is_translation_required, + element.is_native_name_required); +} + +td_api::object_ptr get_passport_required_element_object( + const vector &required_element) { + return td_api::make_object( + transform(required_element, get_passport_suitable_element_object)); +} + +vector> get_passport_required_elements_object( + const vector> &required_elements) { + return transform(required_elements, get_passport_required_element_object); +} + string get_secure_value_data_field_name(SecureValueType type, string field_name) { switch (type) { case SecureValueType::PersonalDetails: @@ -1380,16 +1409,15 @@ static Slice secure_value_type_as_slice(SecureValueType type) { } } -static auto credentials_as_jsonable(const std::vector &credentials, Slice payload, - bool with_selfie, bool with_translations) { - return json_object([&credentials, payload, with_selfie, with_translations](auto &o) { - o("secure_data", json_object([&credentials, with_selfie, with_translations](auto &o) { +static auto credentials_as_jsonable(const std::vector &credentials, Slice payload) { + return json_object([&credentials, payload](auto &o) { + o("secure_data", json_object([&credentials](auto &o) { for (auto &cred : credentials) { if (cred.type == SecureValueType::PhoneNumber || cred.type == SecureValueType::EmailAddress) { continue; } - o(secure_value_type_as_slice(cred.type), json_object([&cred, with_selfie, with_translations](auto &o) { + o(secure_value_type_as_slice(cred.type), json_object([&cred](auto &o) { if (cred.data) { o("data", as_jsonable(cred.data.value())); } @@ -1402,10 +1430,10 @@ static auto credentials_as_jsonable(const std::vector &c if (cred.reverse_side) { o("reverse_side", as_jsonable(cred.reverse_side.value())); } - if (cred.selfie && with_selfie) { + if (cred.selfie) { o("selfie", as_jsonable(cred.selfie.value())); } - if (!cred.translations.empty() && with_translations) { + if (!cred.translations.empty()) { o("translation", as_jsonable(cred.translations)); } })); @@ -1416,10 +1444,8 @@ static auto credentials_as_jsonable(const std::vector &c } Result get_encrypted_credentials(const std::vector &credentials, - Slice payload, bool with_selfie, bool with_translations, - Slice public_key) { - auto encoded_credentials = - json_encode(credentials_as_jsonable(credentials, payload, with_selfie, with_translations)); + Slice payload, Slice public_key) { + auto encoded_credentials = json_encode(credentials_as_jsonable(credentials, payload)); LOG(INFO) << "Created credentials " << encoded_credentials; auto secret = secure_storage::Secret::create_new(); diff --git a/td/telegram/SecureValue.h b/td/telegram/SecureValue.h index de7dc27d..ea705408 100644 --- a/td/telegram/SecureValue.h +++ b/td/telegram/SecureValue.h @@ -43,6 +43,8 @@ enum class SecureValueType : int32 { StringBuilder &operator<<(StringBuilder &string_builder, const SecureValueType &type); +vector unique_secure_value_types(vector types); + SecureValueType get_secure_value_type(const tl_object_ptr &secure_value_type); SecureValueType get_secure_value_type_td_api(const tl_object_ptr &passport_element_type); @@ -57,6 +59,25 @@ td_api::object_ptr get_input_secure_value_type(Se vector> get_passport_element_types_object( const vector &types); +struct SuitableSecureValue { + SecureValueType type; + bool is_selfie_required; + bool is_translation_required; + bool is_native_name_required; +}; + +SuitableSecureValue get_suitable_secure_value( + const tl_object_ptr &secure_required_type); + +td_api::object_ptr get_passport_suitable_element_object( + const SuitableSecureValue &required_element); + +td_api::object_ptr get_passport_required_element_object( + const vector &required_element); + +vector> get_passport_required_elements_object( + const vector> &required_elements); + string get_secure_value_data_field_name(SecureValueType type, string field_name); struct DatedFile { @@ -174,8 +195,7 @@ struct SecureValueCredentials { }; Result get_encrypted_credentials(const std::vector &credentials, - Slice payload, bool with_selfie, bool with_translations, - Slice public_key); + Slice payload, Slice public_key); class SecureValue { public: diff --git a/td/telegram/net/ConnectionCreator.cpp b/td/telegram/net/ConnectionCreator.cpp index eb2acab2..93dd60ab 100644 --- a/td/telegram/net/ConnectionCreator.cpp +++ b/td/telegram/net/ConnectionCreator.cpp @@ -841,7 +841,7 @@ Result ConnectionCreator::find_connection(const ProxyInfo &proxy, DcId TRY_RESULT(transport_type, get_transport_type(proxy, info)); extra.transport_type = std::move(transport_type); - extra.debug_str = PSTRING() << " to " << (info.option->is_media_only() ? " MEDIA" : "") << dc_id + extra.debug_str = PSTRING() << " to " << (info.option->is_media_only() ? "MEDIA " : "") << dc_id << (info.use_http ? " over HTTP" : ""); if (proxy.use_mtproto_proxy()) {