Support translation for Telegram Passport personal documents.

GitOrigin-RevId: b54a7193e584b631ca6d9aeb132be72e02e5f87f
This commit is contained in:
levlam 2018-08-14 16:17:47 +03:00
parent 55417e88fd
commit 712d6bea89
5 changed files with 93 additions and 57 deletions

View File

@ -883,10 +883,16 @@ personalDetails first_name:string middle_name:string last_name:string native_fir
//@reverse_side Reverse side of the document; only for driver license and identity card @selfie Selfie with the document; may be null @translation List of files with the document translation
identityDocument number:string expiry_date:date front_side:datedFile reverse_side:datedFile selfie:datedFile translation:vector<datedFile> = IdentityDocument;
//@description An identity document to be saved @number Document number; 1-24 characters @expiry_date Document expiry date, if available @front_side Front side of the document
//@description An identity document to be saved to Telegram Passport @number Document number; 1-24 characters @expiry_date Document expiry date, if available @front_side Front side of the document
//@reverse_side Reverse side of the document; only for driver license and identity card @selfie Selfie with the document, if available @translation List of files with the document translation
inputIdentityDocument number:string expiry_date:date front_side:InputFile reverse_side:InputFile selfie:InputFile translation:vector<InputFile> = InputIdentityDocument;
//@description A personal document, containing some information about a user @files List of files with the document @translation List of files with the document translation
personalDocument files:vector<datedFile> translation:vector<datedFile> = PersonalDocument;
//@description A personal document to be saved to Telegram Passport @files List of files with the document @translation List of files with the document translation
inputPersonalDocument files:vector<InputFile> translation:vector<InputFile> = InputPersonalDocument;
//@class PassportElement @description Contains information about a Telegram Passport element
@ -908,20 +914,20 @@ passportElementInternalPassport internal_passport:identityDocument = PassportEle
//@description A Telegram Passport element containing the user's address @address Address
passportElementAddress address:address = PassportElement;
//@description A Telegram Passport element containing the user's utility bill @files List of files with the utility bill
passportElementUtilityBill files:vector<datedFile> = PassportElement;
//@description A Telegram Passport element containing the user's utility bill @utility_bill Utility bill
passportElementUtilityBill utility_bill:personalDocument = PassportElement;
//@description A Telegram Passport element containing the user's bank statement @files List of files with the bank statement
passportElementBankStatement files:vector<datedFile> = PassportElement;
//@description A Telegram Passport element containing the user's bank statement @bank_statement Bank statement
passportElementBankStatement bank_statement:personalDocument = PassportElement;
//@description A Telegram Passport element containing the user's rental agreement @files List of files with the rental agreement
passportElementRentalAgreement files:vector<datedFile> = PassportElement;
//@description A Telegram Passport element containing the user's rental agreement @rental_agreement Rental agreement
passportElementRentalAgreement rental_agreement:personalDocument = PassportElement;
//@description A Telegram Passport element containing the user's passport registration pages @files List of files with the passport registration pages
passportElementPassportRegistration files:vector<datedFile> = PassportElement;
//@description A Telegram Passport element containing the user's passport registration pages @passport_registration Passport registration pages
passportElementPassportRegistration passport_registration:personalDocument = PassportElement;
//@description A Telegram Passport element containing the user's temporary registration @files List of files with the temporary registration
passportElementTemporaryRegistration files:vector<datedFile> = PassportElement;
//@description A Telegram Passport element containing the user's temporary registration @temporary_registration Temporary registration
passportElementTemporaryRegistration temporary_registration:personalDocument = PassportElement;
//@description A Telegram Passport element containing the user's phone number @phone_number Phone number
passportElementPhoneNumber phone_number:string = PassportElement;
@ -950,20 +956,20 @@ inputPassportElementInternalPassport internal_passport:inputIdentityDocument = I
//@description A Telegram Passport element to be saved containing the user's address @address The address to be saved
inputPassportElementAddress address:address = InputPassportElement;
//@description A Telegram Passport element to be saved containing the user's utility bill @files List of files with the utility bill
inputPassportElementUtilityBill files:vector<InputFile> = InputPassportElement;
//@description A Telegram Passport element to be saved containing the user's utility bill @utility_bill The utility bill to be saved
inputPassportElementUtilityBill utility_bill:inputPersonalDocument = InputPassportElement;
//@description A Telegram Passport element to be saved containing the user's bank statement @files List of files with the bank statement
inputPassportElementBankStatement files:vector<InputFile> = InputPassportElement;
//@description A Telegram Passport element to be saved containing the user's bank statement @bank_statement The bank statement to be saved
inputPassportElementBankStatement bank_statement:inputPersonalDocument = InputPassportElement;
//@description A Telegram Passport element to be saved containing the user's rental agreement @files List of files with the rental agreement
inputPassportElementRentalAgreement files:vector<InputFile> = InputPassportElement;
//@description A Telegram Passport element to be saved containing the user's rental agreement @rental_agreement The rental agreement to be saved
inputPassportElementRentalAgreement rental_agreement:inputPersonalDocument = InputPassportElement;
//@description A Telegram Passport element to be saved containing the user's passport registration @files List of files with the passport registration
inputPassportElementPassportRegistration files:vector<InputFile> = InputPassportElement;
//@description A Telegram Passport element to be saved containing the user's passport registration @passport_registration The passport registration pages to be saved
inputPassportElementPassportRegistration passport_registration:inputPersonalDocument = InputPassportElement;
//@description A Telegram Passport element to be saved containing the user's temporary registration @files List of files with the temporary registration
inputPassportElementTemporaryRegistration files:vector<InputFile> = InputPassportElement;
//@description A Telegram Passport element to be saved containing the user's temporary registration @temporary_registration The temporary registration to be saved
inputPassportElementTemporaryRegistration temporary_registration:inputPersonalDocument = InputPassportElement;
//@description A Telegram Passport element to be saved containing the user's phone number @phone_number The phone number to be saved
inputPassportElementPhoneNumber phone_number:string = InputPassportElement;
@ -1011,7 +1017,7 @@ passportElementError type:PassportElementType message:string source:PassportElem
//@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
//@is_translation_required True, if a translation is required with the 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
@ -1033,7 +1039,7 @@ encryptedPassportElement type:PassportElementType data:bytes front_side:datedFil
//@class InputPassportElementErrorSource @description Contains the description of an error in Telegram Passport element; for bots only
//@description The element contains an error in an unspecified place. The error will be considered resolved when anything changes @element_hash Current hash of the whole element
//@description The element contains an error in an unspecified place. The error will be considered resolved when new data is added @element_hash Current hash of the whole element
inputPassportElementErrorSourceUnspecified element_hash:bytes = InputPassportElementErrorSource;
//@description A data field contains an error. The error is considered resolved when the field's value changes @field_name Field name @data_hash Current data hash

Binary file not shown.

View File

@ -413,7 +413,6 @@ void SetSecureValue::start_up() {
}
}
CHECK(secure_value_.files.empty() || secure_value_.translations.empty());
if (!secure_value_.files.empty()) {
CHECK(!front_side_file_id.is_valid());
CHECK(!reverse_side_file_id.is_valid());
@ -444,6 +443,12 @@ void SetSecureValue::start_up() {
break;
}
}
for (auto &dated_file : secure_value_.files) {
if (file_id == file_manager->get_file_view(dated_file.file_id).file_id()) {
is_duplicate = true;
break;
}
}
if (is_duplicate) {
it = secure_value_.translations.erase(it);
} else {

View File

@ -409,6 +409,11 @@ static td_api::object_ptr<td_api::datedFile> get_dated_file_object(FileManager *
return td_api::make_object<td_api::datedFile>(file_manager->get_file_object(file.file_id), file.date);
}
static vector<td_api::object_ptr<td_api::datedFile>> get_dated_files_object(FileManager *file_manager,
const vector<DatedFile> &files) {
return transform(files, [file_manager](const DatedFile &file) { return get_dated_file_object(file_manager, file); });
}
static td_api::object_ptr<td_api::datedFile> get_dated_file_object(FileManager *file_manager,
const EncryptedSecureFile &file) {
DatedFile dated_file = file.file;
@ -502,8 +507,7 @@ static bool check_encrypted_secure_value(const EncryptedSecureValue &value) {
case SecureValueType::RentalAgreement:
case SecureValueType::PassportRegistration:
case SecureValueType::TemporaryRegistration:
return !has_encrypted_data && !has_plain_data && has_files && !has_front_side && !has_reverse_side &&
!has_selfie && !has_translations;
return !has_encrypted_data && !has_plain_data && has_files && !has_front_side && !has_reverse_side && !has_selfie;
case SecureValueType::PhoneNumber:
return has_plain_data && !has_files && !has_front_side && !has_reverse_side && !has_selfie && !has_translations;
case SecureValueType::EmailAddress:
@ -941,13 +945,39 @@ static Result<td_api::object_ptr<td_api::identityDocument>> get_identity_documen
TRY_STATUS(check_document_number(number));
TRY_RESULT(date, get_date_object(expiry_date));
auto translations = transform(
value.translations, [file_manager](const DatedFile &file) { return get_dated_file_object(file_manager, file); });
auto translations = get_dated_files_object(file_manager, value.translations);
return td_api::make_object<td_api::identityDocument>(std::move(number), std::move(date), std::move(front_side),
std::move(reverse_side), std::move(selfie),
std::move(translations));
}
static Result<SecureValue> get_personal_document(
SecureValueType type, FileManager *file_manager,
td_api::object_ptr<td_api::inputPersonalDocument> &&personal_document) {
if (personal_document == nullptr) {
return Status::Error(400, "Personal document must not be empty");
}
SecureValue res;
res.type = type;
if (personal_document->files_.empty()) {
return Status::Error(400, "Document's files are required");
}
TRY_RESULT(files, get_secure_files(file_manager, std::move(personal_document->files_)));
res.files = std::move(files);
if (!personal_document->translation_.empty()) {
TRY_RESULT(translations, get_secure_files(file_manager, std::move(personal_document->translation_)));
res.translations = std::move(translations);
}
return res;
}
static td_api::object_ptr<td_api::personalDocument> get_personal_document_object(FileManager *file_manager,
const SecureValue &value) {
return td_api::make_object<td_api::personalDocument>(get_dated_files_object(file_manager, value.files),
get_dated_files_object(file_manager, value.translations));
}
static Status check_phone_number(string &phone_number) {
if (!clean_input_string(phone_number)) {
return Status::Error(400, "Phone number must be encoded in UTF-8");
@ -1004,38 +1034,25 @@ Result<SecureValue> get_secure_value(FileManager *file_manager,
}
case td_api::inputPassportElementUtilityBill::ID: {
auto input = td_api::move_object_as<td_api::inputPassportElementUtilityBill>(input_passport_element);
res.type = SecureValueType::UtilityBill;
TRY_RESULT(files, get_secure_files(file_manager, std::move(input->files_)));
res.files = std::move(files);
break;
return get_personal_document(SecureValueType::UtilityBill, file_manager, std::move(input->utility_bill_));
}
case td_api::inputPassportElementBankStatement::ID: {
auto input = td_api::move_object_as<td_api::inputPassportElementBankStatement>(input_passport_element);
res.type = SecureValueType::BankStatement;
TRY_RESULT(files, get_secure_files(file_manager, std::move(input->files_)));
res.files = std::move(files);
break;
return get_personal_document(SecureValueType::BankStatement, file_manager, std::move(input->bank_statement_));
}
case td_api::inputPassportElementRentalAgreement::ID: {
auto input = td_api::move_object_as<td_api::inputPassportElementRentalAgreement>(input_passport_element);
res.type = SecureValueType::RentalAgreement;
TRY_RESULT(files, get_secure_files(file_manager, std::move(input->files_)));
res.files = std::move(files);
break;
return get_personal_document(SecureValueType::RentalAgreement, file_manager, std::move(input->rental_agreement_));
}
case td_api::inputPassportElementPassportRegistration::ID: {
auto input = td_api::move_object_as<td_api::inputPassportElementPassportRegistration>(input_passport_element);
res.type = SecureValueType::PassportRegistration;
TRY_RESULT(files, get_secure_files(file_manager, std::move(input->files_)));
res.files = std::move(files);
break;
return get_personal_document(SecureValueType::PassportRegistration, file_manager,
std::move(input->passport_registration_));
}
case td_api::inputPassportElementTemporaryRegistration::ID: {
auto input = td_api::move_object_as<td_api::inputPassportElementTemporaryRegistration>(input_passport_element);
res.type = SecureValueType::TemporaryRegistration;
TRY_RESULT(files, get_secure_files(file_manager, std::move(input->files_)));
res.files = std::move(files);
break;
return get_personal_document(SecureValueType::TemporaryRegistration, file_manager,
std::move(input->temporary_registration_));
}
case td_api::inputPassportElementPhoneNumber::ID: {
auto input = td_api::move_object_as<td_api::inputPassportElementPhoneNumber>(input_passport_element);
@ -1089,22 +1106,21 @@ Result<td_api::object_ptr<td_api::PassportElement>> get_passport_element_object(
case SecureValueType::RentalAgreement:
case SecureValueType::PassportRegistration:
case SecureValueType::TemporaryRegistration: {
auto files = transform(
value.files, [file_manager](const DatedFile &file) { return get_dated_file_object(file_manager, file); });
auto document = get_personal_document_object(file_manager, value);
if (value.type == SecureValueType::UtilityBill) {
return td_api::make_object<td_api::passportElementUtilityBill>(std::move(files));
return td_api::make_object<td_api::passportElementUtilityBill>(std::move(document));
}
if (value.type == SecureValueType::BankStatement) {
return td_api::make_object<td_api::passportElementBankStatement>(std::move(files));
return td_api::make_object<td_api::passportElementBankStatement>(std::move(document));
}
if (value.type == SecureValueType::RentalAgreement) {
return td_api::make_object<td_api::passportElementRentalAgreement>(std::move(files));
return td_api::make_object<td_api::passportElementRentalAgreement>(std::move(document));
}
if (value.type == SecureValueType::PassportRegistration) {
return td_api::make_object<td_api::passportElementPassportRegistration>(std::move(files));
return td_api::make_object<td_api::passportElementPassportRegistration>(std::move(document));
}
if (value.type == SecureValueType::TemporaryRegistration) {
return td_api::make_object<td_api::passportElementTemporaryRegistration>(std::move(files));
return td_api::make_object<td_api::passportElementTemporaryRegistration>(std::move(document));
}
UNREACHABLE();
break;
@ -1199,6 +1215,9 @@ Result<SecureValueWithCredentials> decrypt_secure_value(FileManager *file_manage
TRY_RESULT(files, decrypt_secure_files(file_manager, secret, encrypted_secure_value.files));
res.files = std::move(files.first);
res_credentials.files = std::move(files.second);
TRY_RESULT(translations, decrypt_secure_files(file_manager, secret, encrypted_secure_value.translations));
res.translations = std::move(translations.first);
res_credentials.translations = std::move(translations.second);
break;
}
default: {
@ -1330,6 +1349,7 @@ EncryptedSecureValue encrypt_secure_value(FileManager *file_manager, const secur
case SecureValueType::TemporaryRegistration: {
string to_hash;
res.files = encrypt_secure_files(file_manager, master_secret, secure_value.files, to_hash);
res.translations = encrypt_secure_files(file_manager, master_secret, secure_value.translations, to_hash);
res.hash = secure_storage::calc_value_hash(to_hash).as_slice().str();
break;
}

View File

@ -1123,8 +1123,13 @@ class CliClient final : public Actor {
make_tl_object<td_api::inputIdentityDocument>("1234567890", nullptr, std::move(front_side), nullptr,
std::move(selfie), std::move(input_files)));
}
} else if (passport_element_type == "rental_aggrement" || passport_element_type == "ra") {
return make_tl_object<td_api::inputPassportElementRentalAgreement>(std::move(input_files));
} else if (passport_element_type == "rental_agreement" || passport_element_type == "ra") {
vector<td_api::object_ptr<td_api::InputFile>> translation;
if (selfie != nullptr) {
translation.push_back(std::move(selfie));
}
return make_tl_object<td_api::inputPassportElementRentalAgreement>(
make_tl_object<td_api::inputPersonalDocument>(std::move(input_files), std::move(translation)));
}
LOG(ERROR) << "Unsupported passport element type " << passport_element_type;