Support passportDataError.

GitOrigin-RevId: 4a331274c4f53c5deab3ada92cf6b2cca7a3618e
This commit is contained in:
levlam 2018-04-18 17:28:48 +03:00
parent 89c54af478
commit 0c785aa361
9 changed files with 186 additions and 17 deletions

View File

@ -95,8 +95,8 @@ authorizationStateClosing = AuthorizationState;
authorizationStateClosed = AuthorizationState;
//@description Represents the current state of 2-step verification @has_password True if a 2-step verification password has been set up @password_hint Hint for the password; can be empty @has_recovery_email_address True if a recovery email has been set up @unconfirmed_recovery_email_address_pattern Pattern of the email address to which a confirmation email was sent
passwordState has_password:Bool password_hint:string has_recovery_email_address:Bool unconfirmed_recovery_email_address_pattern:string = PasswordState;
//@description Represents the current state of 2-step verification @has_password True if a 2-step verification password has been set up @password_hint Hint for the password; can be empty @has_recovery_email_address True if a recovery email has been set up @has_passport_data True if some Telegram Passport data has been saved @unconfirmed_recovery_email_address_pattern Pattern of the email address to which a confirmation email was sent
passwordState has_password:Bool password_hint:string has_recovery_email_address:Bool has_passport_data:Bool unconfirmed_recovery_email_address_pattern:string = PasswordState;
//@description Contains information about the current recovery email address @recovery_email_address Recovery email address
recoveryEmailAddress recovery_email_address:string = RecoveryEmailAddress;
@ -916,10 +916,29 @@ inputPassportDataEmailAddress email_address:string = InputPassportData;
allPassportData data:vector<PassportData> = AllPassportData;
//@class PassportDataErrorSource @description Contains description of an error in a Telegram Passport data; for bots only
//@description A field of data contains an error. The error is considered resolved when the field's value changes @field_name Field name
passportDataErrorSourceDataField field_name:string = PassportDataErrorSource;
//@description A file contains an error. The error is considered resolved when the file changes
passportDataErrorSourceFile = PassportDataErrorSource;
//@description A list of attached files contains an error. The error is considered resolved when the file list changes
passportDataErrorSourceFiles = PassportDataErrorSource;
//@description A selfie contains an error. The error is considered resolved when the file with the selfie changes
passportDataErrorSourceSelfie = PassportDataErrorSource;
//@description Contains description of an error in a Telegram Passport data @type Telegram Passport data type with the error @message Error message @source Error source
passportDataError type:PassportDataType message:string source:PassportDataErrorSource = PassportDataError;
//@description Contains information about requested Telegram Passport authorization form @id Authorization form unique identifier
//@required_types Types required to complete the form. If there are more than one identity document or address proof, then any of them can be chosen
//@data Already available data @is_selfie_required True, if selfie is required with an identity document @privacy_policy_url URL with the service privacy policy; can be empty
passportAuthorizationForm id:int32 required_types:vector<PassportDataType> data:vector<PassportData> is_selfie_required:Bool privacy_policy_url:string = PassportAuthorizationForm;
//@data Already available data @errors Errors in already available data @is_selfie_required True, if selfie is required with an identity document @privacy_policy_url URL with the service privacy policy; can be empty
passportAuthorizationForm id:int32 required_types:vector<PassportDataType> data:vector<PassportData> errors:vector<passportDataError> is_selfie_required:Bool privacy_policy_url:string = PassportAuthorizationForm;
//@description Contains an encrypted Telegram Passport data credentials @data The encrypted credentials @hash The decrypted data hash @secret Encrypted by service public key secret for data decryption
@ -938,7 +957,7 @@ inputPassportDataErrorSourceDataField field_name:string data_hash:bytes = InputP
//@description A file contains an error. The error is considered resolved when the file changes @file_hash Hash of the file with an error
inputPassportDataErrorSourceFile file_hash:bytes = InputPassportDataErrorSource;
//@description A list of attached files contains an error. The error is considered resolved when the file list changes @type Telegram Passport data type @file_hashes Hashes of all files
//@description A list of attached files contains an error. The error is considered resolved when the file list changes @file_hashes Hashes of all files
inputPassportDataErrorSourceFiles file_hashes:vector<bytes> = InputPassportDataErrorSource;
//@description A selfie contains an error. The error is considered resolved when the file with the selfie changes @file_hash Current file with the selfie hash

Binary file not shown.

View File

@ -463,7 +463,7 @@ authorization#7bf2e6f6 hash:long flags:int device_model:string platform:string s
account.authorizations#1250abde authorizations:Vector<Authorization> = account.Authorizations;
account.noPassword#5ea182f6 new_salt:bytes new_secure_salt:bytes secure_random:bytes email_unconfirmed_pattern:string = account.Password;
account.password#d06c5fc3 current_salt:bytes new_salt:bytes new_secure_salt:bytes secure_random:bytes hint:string has_recovery:Bool email_unconfirmed_pattern:string = account.Password;
account.password#ca39b447 flags:# has_recovery:flags.0?true has_secure_values:flags.1?true current_salt:bytes new_salt:bytes new_secure_salt:bytes secure_random:bytes hint:string email_unconfirmed_pattern:string = account.Password;
account.passwordSettings#7bd9c3f1 email:string secure_salt:bytes secure_secret:bytes secure_secret_id:long = account.PasswordSettings;
@ -883,7 +883,6 @@ initConnection#c7481da6 {X:Type} api_id:int device_model:string system_version:s
invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X;
invokeWithoutUpdates#bf9459b7 {X:Type} query:!X = X;
auth.checkPhone#6fe51dfb phone_number:string = auth.CheckedPhone;
auth.sendCode#86aef0ec flags:# allow_flashcall:flags.0?true phone_number:string current_number:flags.0?Bool api_id:int api_hash:string = auth.SentCode;
auth.signUp#1b067634 phone_number:string phone_code_hash:string phone_code:string first_name:string last_name:string = auth.Authorization;
auth.signIn#bcd51581 phone_number:string phone_code_hash:string phone_code:string = auth.Authorization;
@ -935,7 +934,6 @@ account.getAllSecureValues#b288bc7d = Vector<SecureValue>;
account.getSecureValue#73665bc2 types:Vector<SecureValueType> = Vector<SecureValue>;
account.saveSecureValue#899fe31d value:InputSecureValue secure_secret_id:long = SecureValue;
account.deleteSecureValue#b880bc4b types:Vector<SecureValueType> = Bool;
account.setSecureValueErrors#d0093ce4 user_id:InputUser errors:Vector<SecureValueError> = Bool;
account.getAuthorizationForm#b86ba8e1 bot_id:int scope:string public_key:string = account.AuthorizationForm;
account.acceptAuthorization#e7027c94 bot_id:int scope:string public_key:string value_hashes:Vector<SecureValueHash> credentials:SecureCredentialsEncrypted = Bool;
account.sendVerifyPhoneCode#823380b4 flags:# allow_flashcall:flags.0?true phone_number:string current_number:flags.0?Bool = auth.SentCode;
@ -945,6 +943,7 @@ account.verifyEmail#ecba39db email:string code:string = Bool;
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
users.getFullUser#ca30a5b1 id:InputUser = UserFull;
users.setSecureValueErrors#90c894b5 id:InputUser errors:Vector<SecureValueError> = Bool;
contacts.getStatuses#c4a353ee = Vector<ContactStatus>;
contacts.getContacts#c023849f hash:int = contacts.Contacts;

Binary file not shown.

View File

@ -447,6 +447,7 @@ void PasswordManager::do_get_state(Promise<PasswordState> promise) {
state.new_secure_salt = no_password->new_secure_salt_.as_slice().str();
secure_random = no_password->secure_random_.as_slice().str();
state.has_recovery_email_address = false;
state.has_secure_values = false;
state.unconfirmed_recovery_email_address_pattern = no_password->email_unconfirmed_pattern_;
} else if (result->get_id() == telegram_api::account_password::ID) {
auto password = move_tl_object_as<telegram_api::account_password>(result);
@ -456,7 +457,11 @@ void PasswordManager::do_get_state(Promise<PasswordState> promise) {
state.new_salt = password->new_salt_.as_slice().str();
state.new_secure_salt = password->new_secure_salt_.as_slice().str();
secure_random = password->secure_random_.as_slice().str();
state.has_recovery_email_address = password->has_recovery_;
state.has_recovery_email_address =
(password->flags_ & telegram_api::account_password::HAS_RECOVERY_MASK) != 0;
state.has_secure_values =
(password->flags_ & telegram_api::account_password::HAS_SECURE_VALUES_MASK) != 0;
;
state.unconfirmed_recovery_email_address_pattern = password->email_unconfirmed_pattern_;
} else {
UNREACHABLE();

View File

@ -84,6 +84,7 @@ class PasswordManager : public NetQueryCallback {
bool has_password = false;
string password_hint;
bool has_recovery_email_address = false;
bool has_secure_values = false;
string unconfirmed_recovery_email_address_pattern = "";
string current_salt;
@ -93,7 +94,7 @@ class PasswordManager : public NetQueryCallback {
State as_td_api() const {
return td_api::make_object<td_api::passwordState>(has_password, password_hint, has_recovery_email_address,
unconfirmed_recovery_email_address_pattern);
has_secure_values, unconfirmed_recovery_email_address_pattern);
}
};

View File

@ -33,11 +33,11 @@ class SetSecureValueErrorsQuery : public Td::ResultHandler {
void send(tl_object_ptr<telegram_api::InputUser> input_user,
vector<tl_object_ptr<telegram_api::SecureValueError>> input_errors) {
send_query(G()->net_query_creator().create(
create_storer(telegram_api::account_setSecureValueErrors(std::move(input_user), std::move(input_errors)))));
create_storer(telegram_api::users_setSecureValueErrors(std::move(input_user), std::move(input_errors)))));
}
void on_result(uint64 id, BufferSlice packet) override {
auto result_ptr = fetch_result<telegram_api::account_setSecureValueErrors>(packet);
auto result_ptr = fetch_result<telegram_api::users_setSecureValueErrors>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
}
@ -449,9 +449,60 @@ class GetPassportAuthorizationForm : public NetQueryCallback {
break;
}
}
vector<td_api::object_ptr<td_api::passportDataError>> errors;
for (auto &error_ptr : authorization_form_->errors_) {
CHECK(error_ptr != nullptr);
SecureValueType type = SecureValueType::None;
td_api::object_ptr<td_api::PassportDataErrorSource> source;
string message;
switch (error_ptr->get_id()) {
case telegram_api::secureValueErrorData::ID: {
auto error = move_tl_object_as<telegram_api::secureValueErrorData>(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<td_api::passportDataErrorSourceDataField>(std::move(field_name));
break;
}
case telegram_api::secureValueErrorFile::ID: {
auto error = move_tl_object_as<telegram_api::secureValueErrorFile>(error_ptr);
type = get_secure_value_type(error->type_);
message = std::move(error->text_);
source = td_api::make_object<td_api::passportDataErrorSourceFile>();
break;
}
case telegram_api::secureValueErrorFiles::ID: {
auto error = move_tl_object_as<telegram_api::secureValueErrorFiles>(error_ptr);
type = get_secure_value_type(error->type_);
message = std::move(error->text_);
source = td_api::make_object<td_api::passportDataErrorSourceFiles>();
break;
}
case telegram_api::secureValueErrorSelfie::ID: {
auto error = move_tl_object_as<telegram_api::secureValueErrorSelfie>(error_ptr);
type = get_secure_value_type(error->type_);
message = std::move(error->text_);
source = td_api::make_object<td_api::passportDataErrorSourceSelfie>();
break;
}
default:
UNREACHABLE();
}
if (source == nullptr) {
continue;
}
errors.push_back(td_api::make_object<td_api::passportDataError>(get_passport_data_type_object(type), message,
std::move(source)));
}
promise_.set_value(make_tl_object<td_api::passportAuthorizationForm>(
authorization_form_id_, get_passport_data_types_object(types), std::move(values), is_selfie_required,
authorization_form_->privacy_policy_url_));
authorization_form_id_, get_passport_data_types_object(types), std::move(values), std::move(errors),
is_selfie_required, authorization_form_->privacy_policy_url_));
stop();
}
};

View File

@ -25,6 +25,36 @@
namespace td {
StringBuilder &operator<<(StringBuilder &string_builder, const SecureValueType &type) {
switch (type) {
case SecureValueType::PersonalDetails:
return string_builder << "PersonalDetails";
case SecureValueType::Passport:
return string_builder << "Passport";
case SecureValueType::DriverLicense:
return string_builder << "DriverLicense";
case SecureValueType::IdentityCard:
return string_builder << "IdentityCard";
case SecureValueType::Address:
return string_builder << "Address";
case SecureValueType::UtilityBill:
return string_builder << "UtilityBill";
case SecureValueType::BankStatement:
return string_builder << "BankStatement";
case SecureValueType::RentalAgreement:
return string_builder << "RentalAgreement";
case SecureValueType::PhoneNumber:
return string_builder << "PhoneNumber";
case SecureValueType::EmailAddress:
return string_builder << "EmailAddress";
case SecureValueType::None:
return string_builder << "None";
default:
UNREACHABLE();
return string_builder;
}
}
SecureValueType get_secure_value_type(const tl_object_ptr<telegram_api::SecureValueType> &secure_value_type) {
CHECK(secure_value_type != nullptr);
switch (secure_value_type->get_id()) {
@ -83,14 +113,29 @@ SecureValueType get_secure_value_type_td_api(const tl_object_ptr<td_api::Passpor
}
}
static vector<SecureValueType> unique_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++) {
if (types[i] == types[j]) {
LOG(ERROR) << "Have duplicate Passport Data type " << types[i] << " at positions " << i << " and " << j;
types[i--] = types[--size];
break;
}
}
}
types.resize(size);
return types;
}
vector<SecureValueType> get_secure_value_types(
const vector<tl_object_ptr<telegram_api::SecureValueType>> &secure_value_types) {
return transform(secure_value_types, get_secure_value_type);
return unique_types(transform(secure_value_types, get_secure_value_type));
}
vector<SecureValueType> get_secure_value_types_td_api(
const vector<tl_object_ptr<td_api::PassportDataType>> &secure_value_types) {
return transform(secure_value_types, get_secure_value_type_td_api);
return unique_types(transform(secure_value_types, get_secure_value_type_td_api));
}
td_api::object_ptr<td_api::PassportDataType> get_passport_data_type_object(SecureValueType type) {
@ -156,6 +201,51 @@ vector<td_api::object_ptr<td_api::PassportDataType>> get_passport_data_types_obj
return transform(types, get_passport_data_type_object);
}
string get_secure_value_data_field_name(SecureValueType type, string field_name) {
switch (type) {
case SecureValueType::PersonalDetails:
if (field_name == "first_name" || field_name == "last_name" || field_name == "gender" ||
field_name == "country_code") {
return field_name;
}
if (field_name == "birth_date") {
return "birthdate";
}
break;
case SecureValueType::Passport:
case SecureValueType::DriverLicense:
case SecureValueType::IdentityCard:
if (field_name == "expiry_date") {
return field_name;
}
if (field_name == "document_no") {
return "number";
}
break;
case SecureValueType::Address:
if (field_name == "state" || field_name == "city" || field_name == "street_line1" ||
field_name == "street_line2" || field_name == "country_code") {
return field_name;
}
if (field_name == "post_code") {
return "postal_code";
}
break;
case SecureValueType::UtilityBill:
case SecureValueType::BankStatement:
case SecureValueType::RentalAgreement:
case SecureValueType::PhoneNumber:
case SecureValueType::EmailAddress:
break;
case SecureValueType::None:
default:
UNREACHABLE();
break;
}
LOG(ERROR) << "Receive error about unknown field \"" << field_name << "\" in type " << type;
return string();
}
bool operator==(const EncryptedSecureFile &lhs, const EncryptedSecureFile &rhs) {
return lhs.file_id == rhs.file_id && lhs.file_hash == rhs.file_hash && lhs.encrypted_secret == rhs.encrypted_secret;
}

View File

@ -23,7 +23,7 @@ namespace td {
class FileManager;
enum class SecureValueType {
enum class SecureValueType : int32 {
None,
PersonalDetails,
Passport,
@ -37,6 +37,8 @@ enum class SecureValueType {
EmailAddress
};
StringBuilder &operator<<(StringBuilder &string_builder, const SecureValueType &type);
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::PassportDataType> &passport_data_type);
@ -51,6 +53,8 @@ td_api::object_ptr<telegram_api::SecureValueType> get_secure_value_type_object(S
vector<td_api::object_ptr<td_api::PassportDataType>> get_passport_data_types_object(
const vector<SecureValueType> &types);
string get_secure_value_data_field_name(SecureValueType type, string field_name);
struct EncryptedSecureFile {
FileId file_id;
string file_hash;