getAuthorizationForm

GitOrigin-RevId: 3b432a32cb4af7a35dc7d000e8cfceed97400c1d
This commit is contained in:
Arseny Smirnov 2018-04-06 16:24:29 +03:00
parent 465c450d3f
commit 2f5ca11592
8 changed files with 172 additions and 7 deletions

View File

@ -838,7 +838,7 @@ inputPassportData type:PassportDataType data:string files:vector<InputFile> self
//@description Contains information about requested Telegram Passport authorization form @id Authorization form unique identifier @data Available data //@description Contains information about requested Telegram Passport authorization form @id Authorization form unique identifier @data Available data
passportAuthorizationForm id:int32 data:vector<passportData> = PassportAuthorizationForm; passportAuthorizationForm id:int32 data:vector<passportData> 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 //@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
@ -2909,11 +2909,11 @@ resendEmailAddressVerificationCode = EmailAddressAuthenticationCodeInfo;
checkEmailAddressVerificationCode code:string = Ok; checkEmailAddressVerificationCode code:string = Ok;
//@description Returns Telegram Passport authorization form for sharing data with a service @bot_id Service's bot identifier @scope Telegram Passport data types requested by the service @public_key Service's public_key //@description Returns Telegram Passport authorization form for sharing data with a service @bot_id Service's bot identifier @scope Telegram Passport data types requested by the service @public_key Service's public_key @password Password of the current user
getPassportAuthorizationForm bot_id:int32 scope:string public_key:string = PassportAuthorizationForm; getPassportAuthorizationForm bot_id:int32 scope:string public_key:string password:string = PassportAuthorizationForm;
//@description Sends Telegram Passport authorization form, effectively sharing data with the service @autorization_form_id Authorization form identifier //@description Sends Telegram Passport authorization form, effectively sharing data with the service @autorization_form_id Authorization form identifier
sendPassportAuthorizationForm autorization_form_id:int32 = Ok; sendPassportAuthorizationForm autorization_form_id:int32 types:vector<PassportDataType> = Ok;
//@description Informs the server about the number of pending bot updates if they haven't been processed for a long time; for bots only @pending_update_count The number of pending updates @error_message The last error message //@description Informs the server about the number of pending bot updates if they haven't been processed for a long time; for bots only @pending_update_count The number of pending updates @error_message The last error message

Binary file not shown.

View File

@ -84,7 +84,7 @@ SetSecureValue::UploadCallback::UploadCallback(ActorId<SetSecureValue> actor_id)
} }
void SetSecureValue::UploadCallback::on_upload_ok(FileId file_id, tl_object_ptr<telegram_api::InputFile> input_file) { void SetSecureValue::UploadCallback::on_upload_ok(FileId file_id, tl_object_ptr<telegram_api::InputFile> input_file) {
UNREACHABLE(); send_closure(actor_id_, &SetSecureValue::on_upload_ok, file_id, nullptr);
} }
void SetSecureValue::UploadCallback::on_upload_encrypted_ok( void SetSecureValue::UploadCallback::on_upload_encrypted_ok(
FileId file_id, tl_object_ptr<telegram_api::InputEncryptedFile> input_file) { FileId file_id, tl_object_ptr<telegram_api::InputEncryptedFile> input_file) {
@ -246,6 +246,104 @@ void SetSecureValue::merge(FileManager *file_manager, FileId file_id, SecureFile
LOG_IF(ERROR, status.is_error()) << status.error(); LOG_IF(ERROR, status.is_error()) << status.error();
} }
class GetPassportAuthorizationForm : public NetQueryCallback {
public:
GetPassportAuthorizationForm(ActorShared<> parent, string password, int32 authorization_form_id, int32 bot_id,
string scope, string public_key, Promise<TdApiAuthorizationForm> promise)
: parent_(std::move(parent))
, password_(std::move(password))
, authorization_form_id_(authorization_form_id)
, bot_id_(bot_id)
, scope_(std::move(scope))
, public_key_(std::move(public_key))
, promise_(std::move(promise)) {
}
private:
ActorShared<> parent_;
string password_;
int32 authorization_form_id_;
int32 bot_id_;
string scope_;
string public_key_;
Promise<TdApiAuthorizationForm> promise_;
optional<secure_storage::Secret> secret_;
telegram_api::object_ptr<telegram_api::account_authorizationForm> authorization_form_;
void on_secret(Result<secure_storage::Secret> r_secret, bool dummy) {
LOG_IF(ERROR, r_secret.is_error()) << r_secret.error();
LOG_IF(ERROR, r_secret.is_ok()) << r_secret.ok().get_hash();
if (r_secret.is_error()) {
return on_error(r_secret.move_as_error());
}
secret_ = r_secret.move_as_ok();
loop();
}
void on_error(Status status) {
promise_.set_error(std::move(status));
stop();
}
void start_up() override {
auto account_get_authorization_form =
telegram_api::account_getAuthorizationForm(bot_id_, std::move(scope_), std::move(public_key_));
auto query = G()->net_query_creator().create(create_storer(account_get_authorization_form));
G()->net_query_dispatcher().dispatch_with_callback(std::move(query), actor_shared(this));
send_closure(G()->password_manager(), &PasswordManager::get_secure_secret, password_, optional<int64>(),
PromiseCreator::lambda([actor_id = actor_id(this)](Result<secure_storage::Secret> r_secret) {
send_closure(actor_id, &GetPassportAuthorizationForm::on_secret, std::move(r_secret), true);
}));
}
void on_result(NetQueryPtr query) override {
auto r_result = fetch_result<telegram_api::account_getAuthorizationForm>(std::move(query));
if (r_result.is_error()) {
return on_error(r_result.move_as_error());
}
authorization_form_ = r_result.move_as_ok();
loop();
}
void loop() override {
if (!secret_ || !authorization_form_) {
return;
}
auto *file_manager = G()->file_manager().get_actor_unsafe();
std::vector<TdApiSecureValue> values;
auto types = get_secure_value_types(std::move(authorization_form_->required_types_));
for (auto type : types) {
optional<EncryptedSecureValue> encrypted_secure_value;
for (auto &value : authorization_form_->values_) {
auto value_type = get_secure_value_type(std::move(value->type_));
if (value_type != type) {
continue;
}
encrypted_secure_value = get_encrypted_secure_value(file_manager, std::move(value));
break;
}
SecureValue secure_value;
secure_value.type = type;
if (encrypted_secure_value) {
auto r_secure_value =
decrypt_encrypted_secure_value(file_manager, *secret_, std::move(*encrypted_secure_value));
if (r_secure_value.is_ok()) {
secure_value = r_secure_value.move_as_ok();
} else {
LOG(ERROR) << "Failed to decrypt secure value: " << r_secure_value.error();
}
}
values.push_back(get_passport_data_object(file_manager, std::move(secure_value)));
}
promise_.set_value(make_tl_object<td_api::passportAuthorizationForm>(authorization_form_id_, std::move(values),
authorization_form_->selfie_required_,
authorization_form_->privacy_policy_url_));
stop();
}
};
SecureManager::SecureManager(ActorShared<> parent) : parent_(std::move(parent)) { SecureManager::SecureManager(ActorShared<> parent) : parent_(std::move(parent)) {
} }
@ -262,6 +360,24 @@ void SecureManager::set_secure_value(string password, SecureValue secure_value,
std::move(secure_value), std::move(promise)); std::move(secure_value), std::move(promise));
} }
void SecureManager::get_passport_authorization_form(string password, int32 bot_id, string scope, string public_key,
Promise<TdApiAuthorizationForm> promise) {
refcnt_++;
auto authorization_form_id = ++authorization_form_id_;
authorization_forms_[authorization_form_id] = AuthorizationForm{bot_id, public_key};
create_actor<GetPassportAuthorizationForm>("GetPassportAuthorizationForm", actor_shared(), std::move(password),
authorization_form_id, bot_id, std::move(scope), std::move(public_key),
std::move(promise))
.release();
}
void SecureManager::send_passport_authorization_form(string password, int32 authorization_form_id,
std::vector<SecureValueType> types, Promise<> promise) {
auto it = authorization_forms_.find(authorization_form_id);
if (it == authorization_forms_.end()) {
return promise.set_error(Status::Error(400, "Unknown authorization_form_id"));
}
}
void SecureManager::hangup() { void SecureManager::hangup() {
dec_refcnt(); dec_refcnt();
} }

View File

@ -17,6 +17,7 @@
namespace td { namespace td {
using TdApiSecureValue = td_api::object_ptr<td_api::passportData>; using TdApiSecureValue = td_api::object_ptr<td_api::passportData>;
using TdApiAuthorizationForm = td_api::object_ptr<td_api::passportAuthorizationForm>;
class GetSecureValue : public NetQueryCallback { class GetSecureValue : public NetQueryCallback {
public: public:
GetSecureValue(ActorShared<> parent, std::string password, SecureValueType type, Promise<TdApiSecureValue> promise); GetSecureValue(ActorShared<> parent, std::string password, SecureValueType type, Promise<TdApiSecureValue> promise);
@ -93,11 +94,24 @@ class SecureManager : public Actor {
void get_secure_value(std::string password, SecureValueType type, Promise<TdApiSecureValue> promise); void get_secure_value(std::string password, SecureValueType type, Promise<TdApiSecureValue> promise);
void set_secure_value(string password, SecureValue secure_value, Promise<TdApiSecureValue> promise); void set_secure_value(string password, SecureValue secure_value, Promise<TdApiSecureValue> promise);
void get_passport_authorization_form(string password, int32 bot_id, string scope, string public_key,
Promise<TdApiAuthorizationForm> promise);
void send_passport_authorization_form(string password, int32 authorization_form_id,
std::vector<SecureValueType> types, Promise<> promise);
private: private:
ActorShared<> parent_; ActorShared<> parent_;
int32 refcnt_{1}; int32 refcnt_{1};
std::map<SecureValueType, ActorOwn<>> set_secure_value_queries_; std::map<SecureValueType, ActorOwn<>> set_secure_value_queries_;
struct AuthorizationForm {
int32 bot_id;
string public_key;
};
std::map<int32, AuthorizationForm> authorization_forms_;
int32 authorization_form_id_{0};
void hangup() override; void hangup() override;
void hangup_shared() override; void hangup_shared() override;
void dec_refcnt(); void dec_refcnt();

View File

@ -17,7 +17,8 @@ namespace secure_storage {
Result<ValueHash> ValueHash::create(Slice data) { Result<ValueHash> ValueHash::create(Slice data) {
UInt256 hash; UInt256 hash;
if (data.size() != ::td::as_slice(hash).size()) { if (data.size() != ::td::as_slice(hash).size()) {
return Status::Error("Wrong hash size"); LOG(FATAL);
return Status::Error(PSLICE() << "Wrong hash size " << data.size());
} }
::td::as_slice(hash).copy_from(data); ::td::as_slice(hash).copy_from(data);
return ValueHash{hash}; return ValueHash{hash};

View File

@ -405,6 +405,9 @@ td_api::object_ptr<td_api::passportData> get_passport_data_object(FileManager *f
Result<FileId> decrypt_secure_file(FileManager *file_manager, const secure_storage::Secret &master_secret, Result<FileId> decrypt_secure_file(FileManager *file_manager, const secure_storage::Secret &master_secret,
const SecureFile &secure_file) { const SecureFile &secure_file) {
if (!secure_file.file_id.is_valid()) {
return secure_file.file_id;
}
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()));

View File

@ -6899,9 +6899,12 @@ void Td::on_request(uint64 id, td_api::checkEmailAddressVerificationCode &reques
void Td::on_request(uint64 id, td_api::getPassportAuthorizationForm &request) { void Td::on_request(uint64 id, td_api::getPassportAuthorizationForm &request) {
CHECK_AUTH(); CHECK_AUTH();
CHECK_IS_USER(); CHECK_IS_USER();
CLEAN_INPUT_STRING(request.password_);
CLEAN_INPUT_STRING(request.public_key_); CLEAN_INPUT_STRING(request.public_key_);
CLEAN_INPUT_STRING(request.scope_); CLEAN_INPUT_STRING(request.scope_);
LOG(FATAL) << "TODO"; CREATE_REQUEST_PROMISE(promise);
send_closure(secure_manager_, &SecureManager::get_passport_authorization_form, request.password_, request.bot_id_,
request.scope_, request.public_key_, std::move(promise));
} }
void Td::on_request(uint64 id, const td_api::sendPassportAuthorizationForm &request) { void Td::on_request(uint64 id, const td_api::sendPassportAuthorizationForm &request) {

View File

@ -15,6 +15,8 @@
#include "memprof/memprof.h" #include "memprof/memprof.h"
#include "td/net/HttpReader.h"
#include "td/utils/buffer.h" #include "td/utils/buffer.h"
#include "td/utils/BufferedFd.h" #include "td/utils/BufferedFd.h"
#include "td/utils/FileLog.h" #include "td/utils/FileLog.h"
@ -944,8 +946,12 @@ class CliClient final : public Actor {
if (passport_data_type == "phone" || passport_data_type == "p") { if (passport_data_type == "phone" || passport_data_type == "p") {
return make_tl_object<td_api::passportDataTypePhoneNumber>(); return make_tl_object<td_api::passportDataTypePhoneNumber>();
} }
if (passport_data_type == "pd") {
return make_tl_object<td_api::passportDataTypePersonalDetails>();
}
return make_tl_object<td_api::passportDataTypePassport>(); return make_tl_object<td_api::passportDataTypePassport>();
} }
static tl_object_ptr<td_api::inputPassportData> as_input_passport_data(string passport_data_type, string file) { static tl_object_ptr<td_api::inputPassportData> as_input_passport_data(string passport_data_type, string file) {
vector<td_api::object_ptr<td_api::InputFile>> files; vector<td_api::object_ptr<td_api::InputFile>> files;
LOG(ERROR) << "FILE " << file; LOG(ERROR) << "FILE " << file;
@ -960,6 +966,8 @@ class CliClient final : public Actor {
data = "{todo}"; data = "{todo}";
} else if (passport_data_type == "phone" || passport_data_type == "p") { } else if (passport_data_type == "phone" || passport_data_type == "p") {
data = "{todo}"; data = "{todo}";
} else if (passport_data_type == "pd") {
data = "{todo}";
} else { } else {
data = "I am cucumber"; data = "I am cucumber";
} }
@ -1066,6 +1074,26 @@ class CliClient final : public Actor {
recovery_email_address = ""; recovery_email_address = "";
} }
send_request(make_tl_object<td_api::setPassword>(password, new_password, new_hint, true, recovery_email_address)); send_request(make_tl_object<td_api::setPassword>(password, new_password, new_hint, true, recovery_email_address));
} else if (op == "secureid") {
string password;
std::tie(password, args) = split(args);
ChainBufferWriter writer;
writer.append(PSLICE() << "GET " << args << " HTTP/1.1\r\n\r\n\r\n");
ChainBufferReader reader = writer.extract_reader();
HttpReader http_reader;
http_reader.init(&reader);
HttpQuery query;
auto status = http_reader.read_next(&query);
if (status.is_error()) {
LOG(ERROR) << status.error();
return;
}
string bot_id = query.arg("bot_id").str();
string scope = query.arg("scope").str();
string public_key = query.arg("public_key").str();
send_request(
make_tl_object<td_api::getPassportAuthorizationForm>(to_integer<int32>(bot_id), scope, public_key, password));
} else if (op == "spaf") {
} else if (op == "srea" || op == "SetRecoveryEmailAddress") { } else if (op == "srea" || op == "SetRecoveryEmailAddress") {
string password; string password;
string recovery_email_address; string recovery_email_address;