DatedFile support.

GitOrigin-RevId: d38c3711f66f07ab2beab1c96ac0b9896138f7ec
This commit is contained in:
levlam 2018-04-20 17:48:17 +03:00
parent c8c8de0260
commit 8fdb19e06e
6 changed files with 127 additions and 87 deletions

View File

@ -799,6 +799,10 @@ paymentResult success:Bool verification_url:string = PaymentResult;
paymentReceipt date:int32 payments_provider_user_id:int32 invoice:invoice order_info:orderInfo shipping_option:shippingOption credentials_title:string = PaymentReceipt; paymentReceipt date:int32 payments_provider_user_id:int32 invoice:invoice order_info:orderInfo shipping_option:shippingOption credentials_title:string = PaymentReceipt;
//@description File with the date it was uploaded @file The file @date Point in time (Unix timestamp) when the file was uploaded
datedFile file:file date:int32 = DatedFile;
//@class PassportDataType @description Contains type of a Telegram Passport data //@class PassportDataType @description Contains type of a Telegram Passport data
//@description The Telegram Passport data contains a user's personal details //@description The Telegram Passport data contains a user's personal details
@ -840,7 +844,7 @@ date day:int32 month:int32 year:int32 = Date;
personalDetails first_name:string last_name:string birthdate:date gender:string country_code:string = PersonalDetails; personalDetails first_name:string last_name:string birthdate:date gender:string country_code:string = PersonalDetails;
//@description An identity document @number Document's number; 1-24 characters @expiry_date Document's expiry date; may be null @files List of files with the document images @selfie Selfie with the document; may be null //@description An identity document @number Document's number; 1-24 characters @expiry_date Document's expiry date; may be null @files List of files with the document images @selfie Selfie with the document; may be null
identityDocument number:string expiry_date:date files:vector<file> selfie:file = IdentityDocument; identityDocument number:string expiry_date:date files:vector<datedFile> selfie:datedFile = IdentityDocument;
//@description An identity document to save @number Document's number @expiry_date Document's expiry date, if available @files List of files with the document images @selfie Selfie with the document, if available //@description An identity document to save @number Document's number @expiry_date Document's expiry date, if available @files List of files with the document images @selfie Selfie with the document, if available
inputIdentityDocument number:string expiry_date:date files:vector<InputFile> selfie:InputFile = InputIdentityDocument; inputIdentityDocument number:string expiry_date:date files:vector<InputFile> selfie:InputFile = InputIdentityDocument;
@ -864,13 +868,13 @@ passportDataIdentityCard identity_card:identityDocument = PassportData;
passportDataAddress address:address = PassportData; passportDataAddress address:address = PassportData;
//@description The Telegram Passport data contains a user's utility bill @files List of files with the utility bill //@description The Telegram Passport data contains a user's utility bill @files List of files with the utility bill
passportDataUtilityBill files:vector<file> = PassportData; passportDataUtilityBill files:vector<datedFile> = PassportData;
//@description The Telegram Passport data contains a user's bank statement @files List of files with the bank statement //@description The Telegram Passport data contains a user's bank statement @files List of files with the bank statement
passportDataBankStatement files:vector<file> = PassportData; passportDataBankStatement files:vector<datedFile> = PassportData;
//@description The Telegram Passport data contains a user's rental agreement @files List of files with the rental agreement //@description The Telegram Passport data contains a user's rental agreement @files List of files with the rental agreement
passportDataRentalAgreement files:vector<file> = PassportData; passportDataRentalAgreement files:vector<datedFile> = PassportData;
//@description The Telegram Passport data contains a user's phone number @phone_number The phone number //@description The Telegram Passport data contains a user's phone number @phone_number The phone number
passportDataPhoneNumber phone_number:string = PassportData; passportDataPhoneNumber phone_number:string = PassportData;
@ -946,7 +950,7 @@ encryptedCredentials data:bytes hash:bytes secret:bytes = EncryptedCredentials;
//@description Contains information about an encrypted Telegram Passport data @type Telegram Passport data type @data Encrypted JSON-encoded data about the user @files List of attached files @value Unencrypted data, phone number or email address @selfie Selfie with the document //@description Contains information about an encrypted Telegram Passport data @type Telegram Passport data type @data Encrypted JSON-encoded data about the user @files List of attached files @value Unencrypted data, phone number or email address @selfie Selfie with the document
encryptedPassportData type:PassportDataType data:bytes files:vector<file> value:string selfie:file = EncryptedPassportData; encryptedPassportData type:PassportDataType data:bytes files:vector<datedFile> value:string selfie:datedFile = EncryptedPassportData;
//@class InputPassportDataErrorSource @description Contains description of an error in a Telegram Passport data; for bots only //@class InputPassportDataErrorSource @description Contains description of an error in a Telegram Passport data; for bots only

Binary file not shown.

View File

@ -339,33 +339,34 @@ void SetSecureValue::start_up() {
})); }));
auto *file_manager = G()->td().get_actor_unsafe()->file_manager_.get(); auto *file_manager = G()->td().get_actor_unsafe()->file_manager_.get();
// Remove duplicated files // Remove duplicate files
FileId selfie_file_id;
if (secure_value_.selfie.file_id.is_valid()) {
selfie_file_id = file_manager->get_file_view(secure_value_.selfie.file_id).file_id();
}
for (auto it = secure_value_.files.begin(); it != secure_value_.files.end();) { for (auto it = secure_value_.files.begin(); it != secure_value_.files.end();) {
bool is_duplicate = false; auto file_id = file_manager->get_file_view(it->file_id).file_id();
bool is_duplicate = file_id == selfie_file_id;
for (auto pit = secure_value_.files.begin(); pit != it; pit++) { for (auto pit = secure_value_.files.begin(); pit != it; pit++) {
if (file_manager->get_file_view(*it).file_id() == file_manager->get_file_view(*pit).file_id()) { if (file_id == file_manager->get_file_view(pit->file_id).file_id()) {
is_duplicate = true; is_duplicate = true;
break; break;
} }
} }
if (secure_value_.selfie.is_valid() &&
file_manager->get_file_view(*it).file_id() == file_manager->get_file_view(secure_value_.selfie).file_id()) {
is_duplicate = true;
}
if (is_duplicate) { if (is_duplicate) {
it = secure_value_.files.erase(it); it = secure_value_.files.erase(it);
} else { } else {
it++; ++it;
} }
} }
to_upload_.resize(secure_value_.files.size()); to_upload_.resize(secure_value_.files.size());
upload_callback_ = std::make_shared<UploadCallback>(actor_id(this)); upload_callback_ = std::make_shared<UploadCallback>(actor_id(this));
for (size_t i = 0; i < to_upload_.size(); i++) { for (size_t i = 0; i < to_upload_.size(); i++) {
start_upload(file_manager, secure_value_.files[i], to_upload_[i]); start_upload(file_manager, secure_value_.files[i].file_id, to_upload_[i]);
} }
if (selfie_) { if (secure_value_.selfie.file_id.is_valid()) {
start_upload(file_manager, secure_value_.selfie, selfie_.value()); start_upload(file_manager, secure_value_.selfie.file_id, selfie_.value());
} }
} }
@ -414,10 +415,10 @@ void SetSecureValue::on_result(NetQueryPtr query) {
return on_error(Status::Error("Different files count")); return on_error(Status::Error("Different files count"));
} }
for (size_t i = 0; i < secure_value_.files.size(); i++) { for (size_t i = 0; i < secure_value_.files.size(); i++) {
merge(file_manager, secure_value_.files[i], encrypted_secure_value.files[i]); merge(file_manager, secure_value_.files[i].file_id, encrypted_secure_value.files[i]);
} }
if (secure_value_.selfie.is_valid()) { if (secure_value_.selfie.file_id.is_valid()) {
merge(file_manager, secure_value_.selfie, encrypted_secure_value.selfie); merge(file_manager, secure_value_.selfie.file_id, encrypted_secure_value.selfie);
} }
auto r_secure_value = decrypt_secure_value(file_manager, *secret_, encrypted_secure_value); auto r_secure_value = decrypt_secure_value(file_manager, *secret_, encrypted_secure_value);
if (r_secure_value.is_error()) { if (r_secure_value.is_error()) {
@ -435,7 +436,7 @@ void SetSecureValue::merge(FileManager *file_manager, FileId file_id, EncryptedS
LOG(ERROR) << "Hash mismatch"; LOG(ERROR) << "Hash mismatch";
return; return;
} }
auto status = file_manager->merge(encrypted_file.file_id, file_id); auto status = file_manager->merge(encrypted_file.file.file_id, file_id);
LOG_IF(ERROR, status.is_error()) << status.error(); LOG_IF(ERROR, status.is_error()) << status.error();
} }

View File

@ -8,6 +8,7 @@
#include "td/telegram/DialogId.h" #include "td/telegram/DialogId.h"
#include "td/telegram/files/FileManager.h" #include "td/telegram/files/FileManager.h"
#include "td/telegram/Global.h"
#include "td/telegram/misc.h" #include "td/telegram/misc.h"
#include "td/telegram/Payments.h" #include "td/telegram/Payments.h"
@ -246,9 +247,16 @@ string get_secure_value_data_field_name(SecureValueType type, string field_name)
return string(); return string();
} }
bool operator==(const DatedFile &lhs, const DatedFile &rhs) {
return lhs.file_id == rhs.file_id && lhs.date == rhs.date;
}
bool operator!=(const DatedFile &lhs, const DatedFile &rhs) {
return !(lhs == rhs);
}
bool operator==(const EncryptedSecureFile &lhs, const EncryptedSecureFile &rhs) { bool operator==(const EncryptedSecureFile &lhs, const EncryptedSecureFile &rhs) {
return lhs.file_id == rhs.file_id && lhs.date == rhs.date && lhs.file_hash == rhs.file_hash && return lhs.file == rhs.file && lhs.file_hash == rhs.file_hash && lhs.encrypted_secret == rhs.encrypted_secret;
lhs.encrypted_secret == rhs.encrypted_secret;
} }
bool operator!=(const EncryptedSecureFile &lhs, const EncryptedSecureFile &rhs) { bool operator!=(const EncryptedSecureFile &lhs, const EncryptedSecureFile &rhs) {
@ -269,13 +277,13 @@ EncryptedSecureFile get_encrypted_secure_file(FileManager *file_manager,
LOG(ERROR) << "Wrong dc_id = " << dc_id; LOG(ERROR) << "Wrong dc_id = " << dc_id;
break; break;
} }
result.file_id = file_manager->register_remote( result.file.file_id = file_manager->register_remote(
FullRemoteFileLocation(FileType::Secure, secure_file->id_, secure_file->access_hash_, DcId::internal(dc_id)), FullRemoteFileLocation(FileType::Secure, secure_file->id_, secure_file->access_hash_, DcId::internal(dc_id)),
FileLocationSource::FromServer, {}, 0, 0, ""); FileLocationSource::FromServer, {}, 0, 0, "");
result.date = secure_file->date_; result.file.date = secure_file->date_;
if (result.date < 0) { if (result.file.date < 0) {
LOG(ERROR) << "Receive wrong date " << result.date; LOG(ERROR) << "Receive wrong date " << result.file.date;
result.date = 0; result.file.date = 0;
} }
result.encrypted_secret = secure_file->secret_.as_slice().str(); result.encrypted_secret = secure_file->secret_.as_slice().str();
result.file_hash = secure_file->file_hash_.as_slice().str(); result.file_hash = secure_file->file_hash_.as_slice().str();
@ -293,7 +301,7 @@ vector<EncryptedSecureFile> get_encrypted_secure_files(FileManager *file_manager
results.reserve(secure_files.size()); results.reserve(secure_files.size());
for (auto &secure_file : secure_files) { for (auto &secure_file : secure_files) {
auto result = get_encrypted_secure_file(file_manager, std::move(secure_file)); auto result = get_encrypted_secure_file(file_manager, std::move(secure_file));
if (result.file_id.is_valid()) { if (result.file.file_id.is_valid()) {
results.push_back(std::move(result)); results.push_back(std::move(result));
} }
} }
@ -303,11 +311,11 @@ vector<EncryptedSecureFile> get_encrypted_secure_files(FileManager *file_manager
telegram_api::object_ptr<telegram_api::InputSecureFile> get_input_secure_file_object(FileManager *file_manager, telegram_api::object_ptr<telegram_api::InputSecureFile> get_input_secure_file_object(FileManager *file_manager,
const EncryptedSecureFile &file, const EncryptedSecureFile &file,
SecureInputFile &input_file) { SecureInputFile &input_file) {
CHECK(file_manager->get_file_view(file.file_id).file_id() == CHECK(file_manager->get_file_view(file.file.file_id).file_id() ==
file_manager->get_file_view(input_file.file_id).file_id()); file_manager->get_file_view(input_file.file_id).file_id());
auto res = std::move(input_file.input_file); auto res = std::move(input_file.input_file);
if (res == nullptr) { if (res == nullptr) {
return file_manager->get_file_view(file.file_id).remote_location().as_input_secure_file(); return file_manager->get_file_view(file.file.file_id).remote_location().as_input_secure_file();
} }
telegram_api::downcast_call(*res, overloaded( telegram_api::downcast_call(*res, overloaded(
[&](telegram_api::inputSecureFileUploaded &uploaded) { [&](telegram_api::inputSecureFileUploaded &uploaded) {
@ -318,20 +326,27 @@ telegram_api::object_ptr<telegram_api::InputSecureFile> get_input_secure_file_ob
return res; return res;
} }
td_api::object_ptr<td_api::file> get_encrypted_file_object(FileManager *file_manager, const EncryptedSecureFile &file) { static td_api::object_ptr<td_api::datedFile> get_dated_file_object(FileManager *file_manager, DatedFile file) {
CHECK(file.file_id.is_valid()); return td_api::make_object<td_api::datedFile>(file_manager->get_file_object(file.file_id), file.date);
auto file_view = file_manager->get_file_view(file.file_id); }
auto file_id = file_manager->register_remote(
static td_api::object_ptr<td_api::datedFile> get_dated_file_object(FileManager *file_manager,
const EncryptedSecureFile &file) {
DatedFile dated_file = file.file;
auto file_id = dated_file.file_id;
CHECK(file_id.is_valid());
auto file_view = file_manager->get_file_view(file_id);
dated_file.file_id = file_manager->register_remote(
FullRemoteFileLocation(FileType::SecureRaw, file_view.remote_location().get_id(), FullRemoteFileLocation(FileType::SecureRaw, file_view.remote_location().get_id(),
file_view.remote_location().get_access_hash(), file_view.remote_location().get_dc_id()), file_view.remote_location().get_access_hash(), file_view.remote_location().get_dc_id()),
FileLocationSource::FromServer, {}, 0, 0, ""); FileLocationSource::FromServer, {}, 0, 0, "");
return file_manager->get_file_object(file_id); return get_dated_file_object(file_manager, dated_file);
} }
vector<td_api::object_ptr<td_api::file>> get_encrypted_files_object(FileManager *file_manager, static vector<td_api::object_ptr<td_api::datedFile>> get_dated_files_object(FileManager *file_manager,
const vector<EncryptedSecureFile> &files) { const vector<EncryptedSecureFile> &files) {
return transform( return transform(
files, [file_manager](const EncryptedSecureFile &file) { return get_encrypted_file_object(file_manager, file); }); files, [file_manager](const EncryptedSecureFile &file) { return get_dated_file_object(file_manager, file); });
} }
vector<telegram_api::object_ptr<telegram_api::InputSecureFile>> get_input_secure_files_object( vector<telegram_api::object_ptr<telegram_api::InputSecureFile>> get_input_secure_files_object(
@ -417,15 +432,15 @@ td_api::object_ptr<td_api::encryptedPassportData> get_encrypted_passport_data_ob
bool is_plain = value.data.hash.empty(); bool is_plain = value.data.hash.empty();
return td_api::make_object<td_api::encryptedPassportData>( return td_api::make_object<td_api::encryptedPassportData>(
get_passport_data_type_object(value.type), is_plain ? string() : value.data.data, get_passport_data_type_object(value.type), is_plain ? string() : value.data.data,
get_encrypted_files_object(file_manager, value.files), is_plain ? value.data.data : string(), get_dated_files_object(file_manager, value.files), is_plain ? value.data.data : string(),
value.selfie.file_id.is_valid() ? get_encrypted_file_object(file_manager, value.selfie) : nullptr); value.selfie.file.file_id.is_valid() ? get_dated_file_object(file_manager, value.selfie) : nullptr);
} }
telegram_api::object_ptr<telegram_api::inputSecureValue> get_input_secure_value_object( telegram_api::object_ptr<telegram_api::inputSecureValue> get_input_secure_value_object(
FileManager *file_manager, const EncryptedSecureValue &value, std::vector<SecureInputFile> &input_files, FileManager *file_manager, const EncryptedSecureValue &value, std::vector<SecureInputFile> &input_files,
optional<SecureInputFile> &selfie) { optional<SecureInputFile> &selfie) {
bool is_plain = value.type == SecureValueType::PhoneNumber || value.type == SecureValueType::EmailAddress; bool is_plain = value.type == SecureValueType::PhoneNumber || value.type == SecureValueType::EmailAddress;
bool has_selfie = value.selfie.file_id.is_valid(); bool has_selfie = value.selfie.file.file_id.is_valid();
int32 flags = 0; int32 flags = 0;
tl_object_ptr<telegram_api::SecurePlainData> plain_data; tl_object_ptr<telegram_api::SecurePlainData> plain_data;
if (is_plain) { if (is_plain) {
@ -645,16 +660,21 @@ static Status check_document_number(string &number) {
return Status::OK(); return Status::OK();
} }
static Result<FileId> get_secure_file(FileManager *file_manager, td_api::object_ptr<td_api::InputFile> &&file) { static Result<DatedFile> get_secure_file(FileManager *file_manager, td_api::object_ptr<td_api::InputFile> &&file) {
return file_manager->get_input_file_id(FileType::Secure, std::move(file), DialogId(), false, false, false, true); TRY_RESULT(file_id,
file_manager->get_input_file_id(FileType::Secure, std::move(file), DialogId(), false, false, false, true));
DatedFile result;
result.file_id = file_id;
result.date = G()->unix_time();
return std::move(result);
} }
static Result<vector<FileId>> get_secure_files(FileManager *file_manager, static Result<vector<DatedFile>> get_secure_files(FileManager *file_manager,
vector<td_api::object_ptr<td_api::InputFile>> &&files) { vector<td_api::object_ptr<td_api::InputFile>> &&files) {
vector<FileId> result; vector<DatedFile> result;
for (auto &file : files) { for (auto &file : files) {
TRY_RESULT(file_id, get_secure_file(file_manager, std::move(file))); TRY_RESULT(dated_file, get_secure_file(file_manager, std::move(file)));
result.push_back(file_id); result.push_back(std::move(dated_file));
} }
return result; return result;
} }
@ -678,19 +698,21 @@ static Result<SecureValue> get_identity_document(
res.files = std::move(files); res.files = std::move(files);
if (identity_document->selfie_ != nullptr) { if (identity_document->selfie_ != nullptr) {
TRY_RESULT(file_id, get_secure_file(file_manager, std::move(identity_document->selfie_))); TRY_RESULT(file, get_secure_file(file_manager, std::move(identity_document->selfie_)));
res.selfie = file_id; res.selfie = file;
} }
return res; return res;
} }
static Result<td_api::object_ptr<td_api::identityDocument>> get_identity_document_object(FileManager *file_manager, static Result<td_api::object_ptr<td_api::identityDocument>> get_identity_document_object(FileManager *file_manager,
const SecureValue &value) { const SecureValue &value) {
auto files = transform(value.files, [file_manager](FileId id) { return file_manager->get_file_object(id); }); auto files = transform(value.files, [file_manager](const DatedFile &dated_file) {
return get_dated_file_object(file_manager, dated_file);
});
td_api::object_ptr<td_api::file> selfie; td_api::object_ptr<td_api::datedFile> selfie;
if (value.selfie.is_valid()) { if (value.selfie.file_id.is_valid()) {
selfie = file_manager->get_file_object(value.selfie); selfie = get_dated_file_object(file_manager, value.selfie);
} }
auto data_copy = value.data; auto data_copy = value.data;
@ -830,7 +852,8 @@ Result<td_api::object_ptr<td_api::PassportData>> get_passport_data_object(FileMa
case SecureValueType::UtilityBill: case SecureValueType::UtilityBill:
case SecureValueType::BankStatement: case SecureValueType::BankStatement:
case SecureValueType::RentalAgreement: { case SecureValueType::RentalAgreement: {
auto files = transform(value.files, [file_manager](FileId id) { return file_manager->get_file_object(id); }); auto files = transform(
value.files, [file_manager](const DatedFile &file) { return get_dated_file_object(file_manager, file); });
if (value.type == SecureValueType::UtilityBill) { if (value.type == SecureValueType::UtilityBill) {
return td_api::make_object<td_api::passportDataUtilityBill>(std::move(files)); return td_api::make_object<td_api::passportDataUtilityBill>(std::move(files));
} }
@ -871,33 +894,33 @@ td_api::object_ptr<td_api::allPassportData> get_all_passport_data_object(FileMan
return td_api::make_object<td_api::allPassportData>(std::move(result)); return td_api::make_object<td_api::allPassportData>(std::move(result));
} }
static Result<std::pair<FileId, SecureFileCredentials>> decrypt_secure_file(FileManager *file_manager, static Result<std::pair<DatedFile, SecureFileCredentials>> decrypt_secure_file(
const secure_storage::Secret &master_secret, FileManager *file_manager, const secure_storage::Secret &master_secret, const EncryptedSecureFile &secure_file) {
const EncryptedSecureFile &secure_file) { if (!secure_file.file.file_id.is_valid()) {
if (!secure_file.file_id.is_valid()) { return std::make_pair(DatedFile(), SecureFileCredentials());
return std::make_pair(FileId(), SecureFileCredentials());
} }
TRY_RESULT(hash, secure_storage::ValueHash::create(secure_file.file_hash)); TRY_RESULT(hash, secure_storage::ValueHash::create(secure_file.file_hash));
TRY_RESULT(encrypted_secret, secure_storage::EncryptedSecret::create(secure_file.encrypted_secret)); TRY_RESULT(encrypted_secret, secure_storage::EncryptedSecret::create(secure_file.encrypted_secret));
TRY_RESULT(secret, encrypted_secret.decrypt(PSLICE() << master_secret.as_slice() << hash.as_slice())); TRY_RESULT(secret, encrypted_secret.decrypt(PSLICE() << master_secret.as_slice() << hash.as_slice()));
FileEncryptionKey key{secret}; FileEncryptionKey key{secret};
key.set_value_hash(hash); key.set_value_hash(hash);
file_manager->set_encryption_key(secure_file.file_id, std::move(key)); file_manager->set_encryption_key(secure_file.file.file_id, std::move(key));
return std::make_pair(secure_file.file_id, SecureFileCredentials{secret.as_slice().str(), hash.as_slice().str()}); return std::make_pair(secure_file.file, SecureFileCredentials{secret.as_slice().str(), hash.as_slice().str()});
} }
static Result<std::pair<vector<FileId>, vector<SecureFileCredentials>>> decrypt_secure_files( static Result<std::pair<vector<DatedFile>, vector<SecureFileCredentials>>> decrypt_secure_files(
FileManager *file_manager, const secure_storage::Secret &secret, const vector<EncryptedSecureFile> &secure_files) { FileManager *file_manager, const secure_storage::Secret &secret, const vector<EncryptedSecureFile> &secure_files) {
vector<FileId> res; vector<DatedFile> result;
vector<SecureFileCredentials> credentials; vector<SecureFileCredentials> credentials;
res.reserve(secure_files.size()); result.reserve(secure_files.size());
credentials.reserve(secure_files.size());
for (auto &file : secure_files) { for (auto &file : secure_files) {
TRY_RESULT(decrypted_file, decrypt_secure_file(file_manager, secret, file)); TRY_RESULT(decrypted_file, decrypt_secure_file(file_manager, secret, file));
res.push_back(decrypted_file.first); result.push_back(std::move(decrypted_file.first));
credentials.push_back(decrypted_file.second); credentials.push_back(std::move(decrypted_file.second));
} }
return std::make_pair(std::move(res), std::move(credentials)); return std::make_pair(std::move(result), std::move(credentials));
} }
static Result<std::pair<string, SecureDataCredentials>> decrypt_secure_data(const secure_storage::Secret &master_secret, static Result<std::pair<string, SecureDataCredentials>> decrypt_secure_data(const secure_storage::Secret &master_secret,
@ -932,7 +955,7 @@ Result<SecureValueWithCredentials> decrypt_secure_value(FileManager *file_manage
res_credentials.files = std::move(files.second); res_credentials.files = std::move(files.second);
TRY_RESULT(selfie, decrypt_secure_file(file_manager, secret, encrypted_secure_value.selfie)); TRY_RESULT(selfie, decrypt_secure_file(file_manager, secret, encrypted_secure_value.selfie));
res.selfie = std::move(selfie.first); res.selfie = std::move(selfie.first);
if (res.selfie.is_valid()) { if (res.selfie.file_id.is_valid()) {
res_credentials.selfie = std::move(selfie.second); res_credentials.selfie = std::move(selfie.second);
} }
break; break;
@ -958,8 +981,8 @@ Result<vector<SecureValueWithCredentials>> decrypt_secure_values(
} }
static EncryptedSecureFile encrypt_secure_file(FileManager *file_manager, const secure_storage::Secret &master_secret, static EncryptedSecureFile encrypt_secure_file(FileManager *file_manager, const secure_storage::Secret &master_secret,
FileId file, string &to_hash) { DatedFile file, string &to_hash) {
auto file_view = file_manager->get_file_view(file); auto file_view = file_manager->get_file_view(file.file_id);
if (file_view.empty()) { if (file_view.empty()) {
return EncryptedSecureFile(); return EncryptedSecureFile();
} }
@ -974,7 +997,7 @@ static EncryptedSecureFile encrypt_secure_file(FileManager *file_manager, const
auto value_hash = file_view.encryption_key().value_hash(); auto value_hash = file_view.encryption_key().value_hash();
auto secret = file_view.encryption_key().secret(); auto secret = file_view.encryption_key().secret();
EncryptedSecureFile res; EncryptedSecureFile res;
res.file_id = file; res.file = file;
res.file_hash = value_hash.as_slice().str(); res.file_hash = value_hash.as_slice().str();
res.encrypted_secret = secret.encrypt(PSLICE() << master_secret.as_slice() << value_hash.as_slice()).as_slice().str(); res.encrypted_secret = secret.encrypt(PSLICE() << master_secret.as_slice() << value_hash.as_slice()).as_slice().str();
@ -985,9 +1008,9 @@ static EncryptedSecureFile encrypt_secure_file(FileManager *file_manager, const
static vector<EncryptedSecureFile> encrypt_secure_files(FileManager *file_manager, static vector<EncryptedSecureFile> encrypt_secure_files(FileManager *file_manager,
const secure_storage::Secret &master_secret, const secure_storage::Secret &master_secret,
vector<FileId> files, string &to_hash) { vector<DatedFile> files, string &to_hash) {
return transform(files, return transform(
[&](auto file_id) { return encrypt_secure_file(file_manager, master_secret, file_id, to_hash); }); files, [&](auto dated_file) { return encrypt_secure_file(file_manager, master_secret, dated_file, to_hash); });
} }
static EncryptedSecureData encrypt_secure_data(const secure_storage::Secret &master_secret, Slice data, static EncryptedSecureData encrypt_secure_data(const secure_storage::Secret &master_secret, Slice data,

View File

@ -55,9 +55,16 @@ vector<td_api::object_ptr<td_api::PassportDataType>> get_passport_data_types_obj
string get_secure_value_data_field_name(SecureValueType type, string field_name); string get_secure_value_data_field_name(SecureValueType type, string field_name);
struct EncryptedSecureFile { struct DatedFile {
FileId file_id; FileId file_id;
int32 date = 0; int32 date = 0;
};
bool operator==(const DatedFile &lhs, const DatedFile &rhs);
bool operator!=(const DatedFile &lhs, const DatedFile &rhs);
struct EncryptedSecureFile {
DatedFile file;
string file_hash; string file_hash;
string encrypted_secret; string encrypted_secret;
}; };
@ -79,11 +86,6 @@ telegram_api::object_ptr<telegram_api::InputSecureFile> get_input_secure_file_ob
const EncryptedSecureFile &file, const EncryptedSecureFile &file,
SecureInputFile &input_file); SecureInputFile &input_file);
td_api::object_ptr<td_api::file> get_encrypted_file_object(FileManager *file_manager, const EncryptedSecureFile &file);
vector<td_api::object_ptr<td_api::file>> get_encrypted_files_object(FileManager *file_manager,
const vector<EncryptedSecureFile> &files);
vector<telegram_api::object_ptr<telegram_api::InputSecureFile>> get_input_secure_files_object( vector<telegram_api::object_ptr<telegram_api::InputSecureFile>> get_input_secure_files_object(
FileManager *file_manager, const vector<EncryptedSecureFile> &file, vector<SecureInputFile> &input_files); FileManager *file_manager, const vector<EncryptedSecureFile> &file, vector<SecureInputFile> &input_files);
@ -167,8 +169,8 @@ class SecureValue {
public: public:
SecureValueType type = SecureValueType::None; SecureValueType type = SecureValueType::None;
string data; string data;
vector<FileId> files; vector<DatedFile> files;
FileId selfie; DatedFile selfie;
}; };
struct SecureValueWithCredentials { struct SecureValueWithCredentials {

View File

@ -15,17 +15,27 @@
namespace td { namespace td {
template <class StorerT> template <class StorerT>
void store(EncryptedSecureFile file, StorerT &storer) { void store(DatedFile file, StorerT &storer) {
store(file.file_id, storer); store(file.file_id, storer);
store(file.date, storer); store(file.date, storer);
}
template <class ParserT>
void parse(DatedFile &file, ParserT &parser) {
parse(file.file_id, parser);
parse(file.date, parser);
}
template <class StorerT>
void store(EncryptedSecureFile file, StorerT &storer) {
store(file.file, storer);
store(file.file_hash, storer); store(file.file_hash, storer);
store(file.encrypted_secret, storer); store(file.encrypted_secret, storer);
} }
template <class ParserT> template <class ParserT>
void parse(EncryptedSecureFile &file, ParserT &parser) { void parse(EncryptedSecureFile &file, ParserT &parser) {
parse(file.file_id, parser); parse(file.file, parser);
parse(file.date, parser);
parse(file.file_hash, parser); parse(file.file_hash, parser);
parse(file.encrypted_secret, parser); parse(file.encrypted_secret, parser);
} }
@ -62,7 +72,7 @@ template <class StorerT>
void store(const EncryptedSecureValue &value, StorerT &storer) { void store(const EncryptedSecureValue &value, StorerT &storer) {
bool has_data_hash = !value.data.hash.empty(); bool has_data_hash = !value.data.hash.empty();
bool has_files = !value.files.empty(); bool has_files = !value.files.empty();
bool has_selfie = value.selfie.file_id.is_valid(); bool has_selfie = value.selfie.file.file_id.is_valid();
BEGIN_STORE_FLAGS(); BEGIN_STORE_FLAGS();
STORE_FLAG(has_data_hash); STORE_FLAG(has_data_hash);
STORE_FLAG(has_files); STORE_FLAG(has_files);