Support new Passport authorization form.

GitOrigin-RevId: 5830754700dcd19f4e0bcb08ccb5d72c22db76f0
This commit is contained in:
levlam 2018-08-12 12:51:24 +03:00
parent af4c366fdd
commit 4f8d855527
6 changed files with 95 additions and 32 deletions

View File

@ -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<passportSuitableElement> = 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<PassportElementType> elements:vector<PassportElement> errors:vector<passportElementError> 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<passportRequiredElement> elements:vector<PassportElement> errors:vector<passportElementError> 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

Binary file not shown.

View File

@ -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<TdApiSecureValue> values;
vector<SecureValueType> types;
vector<vector<SuitableSecureValue>> required_types;
vector<SecureValueType> all_types;
for (auto &type_ptr : authorization_form_->required_types_) {
CHECK(type_ptr != nullptr);
vector<SuitableSecureValue> required_type;
switch (type_ptr->get_id()) {
case telegram_api::secureRequiredType::ID: {
auto type = move_tl_object_as<telegram_api::secureRequiredType>(type_ptr);
types.push_back(get_secure_value_type(type->type_));
auto value = get_suitable_secure_value(move_tl_object_as<telegram_api::secureRequiredType>(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<telegram_api::secureRequiredTypeOneOf>(type_ptr);
// TODO
// append(types, get_secure_value_types(type->types_));
auto type_one_of = move_tl_object_as<telegram_api::secureRequiredTypeOneOf>(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<telegram_api::secureRequiredType>(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<TdApiSecureValue> 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<td_api::passportAuthorizationForm>(
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());
}

View File

@ -136,7 +136,7 @@ SecureValueType get_secure_value_type_td_api(const tl_object_ptr<td_api::Passpor
}
}
static vector<SecureValueType> unique_types(vector<SecureValueType> types) {
vector<SecureValueType> unique_secure_value_types(vector<SecureValueType> 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<SecureValueType> unique_types(vector<SecureValueType> types) {
vector<SecureValueType> get_secure_value_types(
const vector<tl_object_ptr<telegram_api::SecureValueType>> &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<SecureValueType> get_secure_value_types_td_api(
const vector<tl_object_ptr<td_api::PassportElementType>> &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<td_api::PassportElementType> get_passport_element_type_object(SecureValueType type) {
@ -236,6 +236,35 @@ vector<td_api::object_ptr<td_api::PassportElementType>> get_passport_element_typ
return transform(types, get_passport_element_type_object);
}
SuitableSecureValue get_suitable_secure_value(
const tl_object_ptr<telegram_api::secureRequiredType> &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<td_api::passportSuitableElement> get_passport_suitable_element_object(
const SuitableSecureValue &element) {
return td_api::make_object<td_api::passportSuitableElement>(
get_passport_element_type_object(element.type), element.is_selfie_required, element.is_translation_required,
element.is_native_name_required);
}
td_api::object_ptr<td_api::passportRequiredElement> get_passport_required_element_object(
const vector<SuitableSecureValue> &required_element) {
return td_api::make_object<td_api::passportRequiredElement>(
transform(required_element, get_passport_suitable_element_object));
}
vector<td_api::object_ptr<td_api::passportRequiredElement>> get_passport_required_elements_object(
const vector<vector<SuitableSecureValue>> &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<SecureValueCredentials> &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<SecureValueCredentials> &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<SecureValueCredentials> &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<SecureValueCredentials> &c
}
Result<EncryptedSecureCredentials> get_encrypted_credentials(const std::vector<SecureValueCredentials> &credentials,
Slice payload, bool with_selfie, bool with_translations,
Slice public_key) {
auto encoded_credentials =
json_encode<std::string>(credentials_as_jsonable(credentials, payload, with_selfie, with_translations));
Slice payload, Slice public_key) {
auto encoded_credentials = json_encode<std::string>(credentials_as_jsonable(credentials, payload));
LOG(INFO) << "Created credentials " << encoded_credentials;
auto secret = secure_storage::Secret::create_new();

View File

@ -43,6 +43,8 @@ enum class SecureValueType : int32 {
StringBuilder &operator<<(StringBuilder &string_builder, const SecureValueType &type);
vector<SecureValueType> unique_secure_value_types(vector<SecureValueType> types);
SecureValueType get_secure_value_type(const tl_object_ptr<telegram_api::SecureValueType> &secure_value_type);
SecureValueType get_secure_value_type_td_api(const tl_object_ptr<td_api::PassportElementType> &passport_element_type);
@ -57,6 +59,25 @@ td_api::object_ptr<telegram_api::SecureValueType> get_input_secure_value_type(Se
vector<td_api::object_ptr<td_api::PassportElementType>> get_passport_element_types_object(
const vector<SecureValueType> &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<telegram_api::secureRequiredType> &secure_required_type);
td_api::object_ptr<td_api::passportSuitableElement> get_passport_suitable_element_object(
const SuitableSecureValue &required_element);
td_api::object_ptr<td_api::passportRequiredElement> get_passport_required_element_object(
const vector<SuitableSecureValue> &required_element);
vector<td_api::object_ptr<td_api::passportRequiredElement>> get_passport_required_elements_object(
const vector<vector<SuitableSecureValue>> &required_elements);
string get_secure_value_data_field_name(SecureValueType type, string field_name);
struct DatedFile {
@ -174,8 +195,7 @@ struct SecureValueCredentials {
};
Result<EncryptedSecureCredentials> get_encrypted_credentials(const std::vector<SecureValueCredentials> &credentials,
Slice payload, bool with_selfie, bool with_translations,
Slice public_key);
Slice payload, Slice public_key);
class SecureValue {
public:

View File

@ -841,7 +841,7 @@ Result<SocketFd> 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()) {