sendAuthorizationForm (with bugs)
GitOrigin-RevId: e68b57a2f6ff2e117913c40779cc9473153828ab
This commit is contained in:
parent
c240d107f6
commit
0eee63b723
@ -2910,10 +2910,10 @@ 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 @password Password of the current user
|
//@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 password:string = PassportAuthorizationForm;
|
getPassportAuthorizationForm bot_id:int32 scope:string public_key:string payload: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 types:vector<PassportDataType> = Ok;
|
sendPassportAuthorizationForm autorization_form_id:int32 types:vector<PassportDataType> password:string = 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.
@ -644,10 +644,10 @@ class MessagePassportDataSent : public MessageContent {
|
|||||||
class MessagePassportDataReceived : public MessageContent {
|
class MessagePassportDataReceived : public MessageContent {
|
||||||
public:
|
public:
|
||||||
vector<EncryptedSecureValue> values;
|
vector<EncryptedSecureValue> values;
|
||||||
SecureCredentials credentials;
|
EncryptedSecureCredentials credentials;
|
||||||
|
|
||||||
MessagePassportDataReceived() = default;
|
MessagePassportDataReceived() = default;
|
||||||
MessagePassportDataReceived(vector<EncryptedSecureValue> &&values, SecureCredentials &&credentials)
|
MessagePassportDataReceived(vector<EncryptedSecureValue> &&values, EncryptedSecureCredentials &&credentials)
|
||||||
: values(std::move(values)), credentials(std::move(credentials)) {
|
: values(std::move(values)), credentials(std::move(credentials)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
GetSecureValue::GetSecureValue(ActorShared<> parent, std::string password, SecureValueType type,
|
GetSecureValue::GetSecureValue(ActorShared<> parent, std::string password, SecureValueType type,
|
||||||
Promise<TdApiSecureValue> promise)
|
Promise<SecureValueWithCredentials> promise)
|
||||||
: parent_(std::move(parent)), password_(std::move(password)), type_(type), promise_(std::move(promise)) {
|
: parent_(std::move(parent)), password_(std::move(password)), type_(type), promise_(std::move(promise)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ void GetSecureValue::loop() {
|
|||||||
if (r_secure_value.is_error()) {
|
if (r_secure_value.is_error()) {
|
||||||
return on_error(r_secure_value.move_as_error());
|
return on_error(r_secure_value.move_as_error());
|
||||||
}
|
}
|
||||||
promise_.set_result(get_passport_data_object(file_manager, r_secure_value.move_as_ok()));
|
promise_.set_result(r_secure_value.move_as_ok());
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ void GetSecureValue::on_result(NetQueryPtr query) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SetSecureValue::SetSecureValue(ActorShared<> parent, string password, SecureValue secure_value,
|
SetSecureValue::SetSecureValue(ActorShared<> parent, string password, SecureValue secure_value,
|
||||||
Promise<TdApiSecureValue> promise)
|
Promise<SecureValueWithCredentials> promise)
|
||||||
: parent_(std::move(parent))
|
: parent_(std::move(parent))
|
||||||
, password_(std::move(password))
|
, password_(std::move(password))
|
||||||
, secure_value_(std::move(secure_value))
|
, secure_value_(std::move(secure_value))
|
||||||
@ -230,7 +230,7 @@ void SetSecureValue::on_result(NetQueryPtr query) {
|
|||||||
if (r_secure_value.is_error()) {
|
if (r_secure_value.is_error()) {
|
||||||
return on_error(r_secure_value.move_as_error());
|
return on_error(r_secure_value.move_as_error());
|
||||||
}
|
}
|
||||||
promise_.set_result(get_passport_data_object(file_manager, r_secure_value.move_as_ok()));
|
promise_.set_result(r_secure_value.move_as_ok());
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,7 +330,7 @@ class GetPassportAuthorizationForm : public NetQueryCallback {
|
|||||||
auto r_secure_value =
|
auto r_secure_value =
|
||||||
decrypt_encrypted_secure_value(file_manager, *secret_, std::move(*encrypted_secure_value));
|
decrypt_encrypted_secure_value(file_manager, *secret_, std::move(*encrypted_secure_value));
|
||||||
if (r_secure_value.is_ok()) {
|
if (r_secure_value.is_ok()) {
|
||||||
secure_value = r_secure_value.move_as_ok();
|
secure_value = r_secure_value.move_as_ok().value;
|
||||||
} else {
|
} else {
|
||||||
LOG(ERROR) << "Failed to decrypt secure value: " << r_secure_value.error();
|
LOG(ERROR) << "Failed to decrypt secure value: " << r_secure_value.error();
|
||||||
}
|
}
|
||||||
@ -348,6 +348,19 @@ SecureManager::SecureManager(ActorShared<> parent) : parent_(std::move(parent))
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SecureManager::get_secure_value(std::string password, SecureValueType type, Promise<TdApiSecureValue> promise) {
|
void SecureManager::get_secure_value(std::string password, SecureValueType type, Promise<TdApiSecureValue> promise) {
|
||||||
|
auto new_promise =
|
||||||
|
PromiseCreator::lambda([promise = std::move(promise)](Result<SecureValueWithCredentials> r_secure_value) mutable {
|
||||||
|
if (r_secure_value.is_error()) {
|
||||||
|
return promise.set_error(r_secure_value.move_as_error());
|
||||||
|
}
|
||||||
|
auto *file_manager = G()->file_manager().get_actor_unsafe();
|
||||||
|
promise.set_value(get_passport_data_object(file_manager, r_secure_value.move_as_ok().value));
|
||||||
|
});
|
||||||
|
do_get_secure_value(std::move(password), type, std::move(new_promise));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SecureManager::do_get_secure_value(std::string password, SecureValueType type,
|
||||||
|
Promise<SecureValueWithCredentials> promise) {
|
||||||
refcnt_++;
|
refcnt_++;
|
||||||
create_actor<GetSecureValue>("GetSecureValue", actor_shared(), std::move(password), type, std::move(promise))
|
create_actor<GetSecureValue>("GetSecureValue", actor_shared(), std::move(password), type, std::move(promise))
|
||||||
.release();
|
.release();
|
||||||
@ -356,15 +369,23 @@ void SecureManager::get_secure_value(std::string password, SecureValueType type,
|
|||||||
void SecureManager::set_secure_value(string password, SecureValue secure_value, Promise<TdApiSecureValue> promise) {
|
void SecureManager::set_secure_value(string password, SecureValue secure_value, Promise<TdApiSecureValue> promise) {
|
||||||
refcnt_++;
|
refcnt_++;
|
||||||
auto type = secure_value.type;
|
auto type = secure_value.type;
|
||||||
|
auto new_promise =
|
||||||
|
PromiseCreator::lambda([promise = std::move(promise)](Result<SecureValueWithCredentials> r_secure_value) mutable {
|
||||||
|
if (r_secure_value.is_error()) {
|
||||||
|
return promise.set_error(r_secure_value.move_as_error());
|
||||||
|
}
|
||||||
|
auto *file_manager = G()->file_manager().get_actor_unsafe();
|
||||||
|
promise.set_value(get_passport_data_object(file_manager, r_secure_value.move_as_ok().value));
|
||||||
|
});
|
||||||
set_secure_value_queries_[type] = create_actor<SetSecureValue>("SetSecureValue", actor_shared(), std::move(password),
|
set_secure_value_queries_[type] = create_actor<SetSecureValue>("SetSecureValue", actor_shared(), std::move(password),
|
||||||
std::move(secure_value), std::move(promise));
|
std::move(secure_value), std::move(new_promise));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SecureManager::get_passport_authorization_form(string password, int32 bot_id, string scope, string public_key,
|
void SecureManager::get_passport_authorization_form(string password, int32 bot_id, string scope, string public_key,
|
||||||
Promise<TdApiAuthorizationForm> promise) {
|
string payload, Promise<TdApiAuthorizationForm> promise) {
|
||||||
refcnt_++;
|
refcnt_++;
|
||||||
auto authorization_form_id = ++authorization_form_id_;
|
auto authorization_form_id = ++authorization_form_id_;
|
||||||
authorization_forms_[authorization_form_id] = AuthorizationForm{bot_id, public_key};
|
authorization_forms_[authorization_form_id] = AuthorizationForm{bot_id, scope, public_key, payload};
|
||||||
create_actor<GetPassportAuthorizationForm>("GetPassportAuthorizationForm", actor_shared(), std::move(password),
|
create_actor<GetPassportAuthorizationForm>("GetPassportAuthorizationForm", actor_shared(), std::move(password),
|
||||||
authorization_form_id, bot_id, std::move(scope), std::move(public_key),
|
authorization_form_id, bot_id, std::move(scope), std::move(public_key),
|
||||||
std::move(promise))
|
std::move(promise))
|
||||||
@ -377,7 +398,91 @@ void SecureManager::send_passport_authorization_form(string password, int32 auth
|
|||||||
if (it == authorization_forms_.end()) {
|
if (it == authorization_forms_.end()) {
|
||||||
return promise.set_error(Status::Error(400, "Unknown authorization_form_id"));
|
return promise.set_error(Status::Error(400, "Unknown authorization_form_id"));
|
||||||
}
|
}
|
||||||
|
if (types.empty()) {
|
||||||
|
return promise.set_error(Status::Error(400, "Empty types"));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct JoinPromise {
|
||||||
|
std::mutex mutex_;
|
||||||
|
Promise<std::vector<SecureValueCredentials>> promise_;
|
||||||
|
std::vector<SecureValueCredentials> credentials_;
|
||||||
|
int wait_cnt_{0};
|
||||||
|
};
|
||||||
|
|
||||||
|
auto join = std::make_shared<JoinPromise>();
|
||||||
|
std::lock_guard<std::mutex> guard(join->mutex_);
|
||||||
|
for (auto type : types) {
|
||||||
|
join->wait_cnt_++;
|
||||||
|
do_get_secure_value(password, type,
|
||||||
|
PromiseCreator::lambda([join](Result<SecureValueWithCredentials> r_secure_value) {
|
||||||
|
std::lock_guard<std::mutex> guard(join->mutex_);
|
||||||
|
if (!join->promise_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (r_secure_value.is_error()) {
|
||||||
|
return join->promise_.set_error(r_secure_value.move_as_error());
|
||||||
|
}
|
||||||
|
join->credentials_.push_back(r_secure_value.move_as_ok().credentials);
|
||||||
|
join->wait_cnt_--;
|
||||||
|
LOG(ERROR) << tag("wait_cnt", join->wait_cnt_);
|
||||||
|
if (join->wait_cnt_ == 0) {
|
||||||
|
LOG(ERROR) << "set promise";
|
||||||
|
join->promise_.set_value(std::move(join->credentials_));
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
join->promise_ =
|
||||||
|
PromiseCreator::lambda([promise = std::move(promise), actor_id = actor_id(this),
|
||||||
|
authorization_form_id](Result<vector<SecureValueCredentials>> r_credentials) mutable {
|
||||||
|
LOG(ERROR) << "on promise";
|
||||||
|
if (r_credentials.is_error()) {
|
||||||
|
return promise.set_error(r_credentials.move_as_error());
|
||||||
|
}
|
||||||
|
send_closure(actor_id, &SecureManager::do_send_passport_authorization_form, authorization_form_id,
|
||||||
|
r_credentials.move_as_ok(), std::move(promise));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SecureManager::do_send_passport_authorization_form(int32 authorization_form_id,
|
||||||
|
vector<SecureValueCredentials> credentials, Promise<> promise) {
|
||||||
|
LOG(ERROR) << "do_send_passport_authorization_form";
|
||||||
|
auto it = authorization_forms_.find(authorization_form_id);
|
||||||
|
if (it == authorization_forms_.end()) {
|
||||||
|
return promise.set_error(Status::Error(400, "Unknown authorization_form_id"));
|
||||||
|
}
|
||||||
|
if (credentials.empty()) {
|
||||||
|
return promise.set_error(Status::Error(400, "Empty types"));
|
||||||
|
}
|
||||||
|
std::vector<telegram_api::object_ptr<telegram_api::secureValueHash>> hashes;
|
||||||
|
for (auto &c : credentials) {
|
||||||
|
hashes.push_back(telegram_api::make_object<telegram_api::secureValueHash>(
|
||||||
|
get_secure_value_type_telegram_object(c.type), BufferSlice(c.hash)));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto r_encrypted_credentials = 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto td_query = telegram_api::account_acceptAuthorization(
|
||||||
|
it->second.bot_id, it->second.scope, it->second.public_key, std::move(hashes),
|
||||||
|
get_secure_credentials_encrypted_object(r_encrypted_credentials.move_as_ok()));
|
||||||
|
LOG(ERROR) << to_string(td_query);
|
||||||
|
auto query = G()->net_query_creator().create(create_storer(td_query));
|
||||||
|
auto new_promise =
|
||||||
|
PromiseCreator::lambda([promise = std::move(promise)](Result<NetQueryPtr> r_net_query_ptr) mutable {
|
||||||
|
if (r_net_query_ptr.is_error()) {
|
||||||
|
return promise.set_error(r_net_query_ptr.move_as_error());
|
||||||
|
}
|
||||||
|
auto r_result = fetch_result<telegram_api::account_acceptAuthorization>(r_net_query_ptr.move_as_ok());
|
||||||
|
if (r_result.is_error()) {
|
||||||
|
return promise.set_error(r_result.move_as_error());
|
||||||
|
}
|
||||||
|
promise.set_value(Unit());
|
||||||
|
});
|
||||||
|
send_with_promise(std::move(query), std::move(new_promise));
|
||||||
|
}
|
||||||
|
|
||||||
void SecureManager::hangup() {
|
void SecureManager::hangup() {
|
||||||
dec_refcnt();
|
dec_refcnt();
|
||||||
}
|
}
|
||||||
@ -391,4 +496,13 @@ void SecureManager::dec_refcnt() {
|
|||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void SecureManager::on_result(NetQueryPtr query) {
|
||||||
|
auto token = get_link_token();
|
||||||
|
container_.extract(token).set_value(std::move(query));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SecureManager::send_with_promise(NetQueryPtr query, Promise<NetQueryPtr> promise) {
|
||||||
|
auto id = container_.create(std::move(promise));
|
||||||
|
G()->net_query_dispatcher().dispatch_with_callback(std::move(query), actor_shared(this, id));
|
||||||
|
}
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -20,13 +20,14 @@ using TdApiSecureValue = td_api::object_ptr<td_api::passportData>;
|
|||||||
using TdApiAuthorizationForm = td_api::object_ptr<td_api::passportAuthorizationForm>;
|
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<SecureValueWithCredentials> promise);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ActorShared<> parent_;
|
ActorShared<> parent_;
|
||||||
string password_;
|
string password_;
|
||||||
SecureValueType type_;
|
SecureValueType type_;
|
||||||
Promise<TdApiSecureValue> promise_;
|
Promise<SecureValueWithCredentials> promise_;
|
||||||
optional<EncryptedSecureValue> encrypted_secure_value_;
|
optional<EncryptedSecureValue> encrypted_secure_value_;
|
||||||
optional<secure_storage::Secret> secret_;
|
optional<secure_storage::Secret> secret_;
|
||||||
|
|
||||||
@ -40,13 +41,14 @@ class GetSecureValue : public NetQueryCallback {
|
|||||||
|
|
||||||
class SetSecureValue : public NetQueryCallback {
|
class SetSecureValue : public NetQueryCallback {
|
||||||
public:
|
public:
|
||||||
SetSecureValue(ActorShared<> parent, string password, SecureValue secure_value, Promise<TdApiSecureValue> promise);
|
SetSecureValue(ActorShared<> parent, string password, SecureValue secure_value,
|
||||||
|
Promise<SecureValueWithCredentials> promise);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ActorShared<> parent_;
|
ActorShared<> parent_;
|
||||||
string password_;
|
string password_;
|
||||||
SecureValue secure_value_;
|
SecureValue secure_value_;
|
||||||
Promise<TdApiSecureValue> promise_;
|
Promise<SecureValueWithCredentials> promise_;
|
||||||
optional<secure_storage::Secret> secret_;
|
optional<secure_storage::Secret> secret_;
|
||||||
|
|
||||||
size_t files_left_to_upload_ = 0;
|
size_t files_left_to_upload_ = 0;
|
||||||
@ -87,14 +89,14 @@ class SetSecureValue : public NetQueryCallback {
|
|||||||
void merge(FileManager *file_manager, FileId file_id, EncryptedSecureFile &encrypted_file);
|
void merge(FileManager *file_manager, FileId file_id, EncryptedSecureFile &encrypted_file);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SecureManager : public Actor {
|
class SecureManager : public NetQueryCallback {
|
||||||
public:
|
public:
|
||||||
SecureManager(ActorShared<> parent);
|
SecureManager(ActorShared<> parent);
|
||||||
|
|
||||||
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,
|
void get_passport_authorization_form(string password, int32 bot_id, string scope, string public_key, string payload,
|
||||||
Promise<TdApiAuthorizationForm> promise);
|
Promise<TdApiAuthorizationForm> promise);
|
||||||
void send_passport_authorization_form(string password, int32 authorization_form_id,
|
void send_passport_authorization_form(string password, int32 authorization_form_id,
|
||||||
std::vector<SecureValueType> types, Promise<> promise);
|
std::vector<SecureValueType> types, Promise<> promise);
|
||||||
@ -106,7 +108,9 @@ class SecureManager : public Actor {
|
|||||||
|
|
||||||
struct AuthorizationForm {
|
struct AuthorizationForm {
|
||||||
int32 bot_id;
|
int32 bot_id;
|
||||||
|
string scope;
|
||||||
string public_key;
|
string public_key;
|
||||||
|
string payload;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::map<int32, AuthorizationForm> authorization_forms_;
|
std::map<int32, AuthorizationForm> authorization_forms_;
|
||||||
@ -115,5 +119,12 @@ class SecureManager : public Actor {
|
|||||||
void hangup() override;
|
void hangup() override;
|
||||||
void hangup_shared() override;
|
void hangup_shared() override;
|
||||||
void dec_refcnt();
|
void dec_refcnt();
|
||||||
|
void do_get_secure_value(std::string password, SecureValueType type, Promise<SecureValueWithCredentials> promise);
|
||||||
|
void do_send_passport_authorization_form(int32 authorization_form_id, vector<SecureValueCredentials> credentials,
|
||||||
|
Promise<> promise);
|
||||||
|
|
||||||
|
void on_result(NetQueryPtr query) override;
|
||||||
|
Container<Promise<NetQueryPtr>> container_;
|
||||||
|
void send_with_promise(NetQueryPtr query, Promise<NetQueryPtr> promise);
|
||||||
};
|
};
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
#include "td/utils/misc.h"
|
#include "td/utils/misc.h"
|
||||||
#include "td/utils/overloaded.h"
|
#include "td/utils/overloaded.h"
|
||||||
|
#include "td/utils/JsonBuilder.h"
|
||||||
|
#include "td/utils/base64.h"
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
@ -79,6 +81,11 @@ vector<SecureValueType> get_secure_value_types(
|
|||||||
return transform(std::move(secure_value_types), get_secure_value_type);
|
return transform(std::move(secure_value_types), get_secure_value_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<SecureValueType> get_secure_value_types_td_api(
|
||||||
|
vector<tl_object_ptr<td_api::PassportDataType>> &&secure_value_types) {
|
||||||
|
return transform(std::move(secure_value_types), get_secure_value_type_td_api);
|
||||||
|
}
|
||||||
|
|
||||||
td_api::object_ptr<td_api::PassportDataType> get_passport_data_type_object(SecureValueType type) {
|
td_api::object_ptr<td_api::PassportDataType> get_passport_data_type_object(SecureValueType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SecureValueType::PersonalDetails:
|
case SecureValueType::PersonalDetails:
|
||||||
@ -291,6 +298,7 @@ EncryptedSecureValue get_encrypted_secure_value(FileManager *file_manager,
|
|||||||
if (secure_value->selfie_ != nullptr) {
|
if (secure_value->selfie_ != nullptr) {
|
||||||
result.selfie = get_secure_file(file_manager, std::move(secure_value->selfie_));
|
result.selfie = get_secure_file(file_manager, std::move(secure_value->selfie_));
|
||||||
}
|
}
|
||||||
|
result.hash = secure_value->hash_.as_slice().str();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,17 +355,24 @@ vector<td_api::object_ptr<td_api::encryptedPassportData>> get_encrypted_passport
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const SecureCredentials &lhs, const SecureCredentials &rhs) {
|
bool operator==(const EncryptedSecureCredentials &lhs, const EncryptedSecureCredentials &rhs) {
|
||||||
return lhs.data == rhs.data && lhs.hash == rhs.hash && lhs.encrypted_secret == rhs.encrypted_secret;
|
return lhs.data == rhs.data && lhs.hash == rhs.hash && lhs.encrypted_secret == rhs.encrypted_secret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const SecureCredentials &lhs, const SecureCredentials &rhs) {
|
bool operator!=(const EncryptedSecureCredentials &lhs, const EncryptedSecureCredentials &rhs) {
|
||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
SecureCredentials get_secure_credentials(tl_object_ptr<telegram_api::secureCredentialsEncrypted> &&credentials) {
|
telegram_api::object_ptr<telegram_api::secureCredentialsEncrypted> get_secure_credentials_encrypted_object(
|
||||||
|
const EncryptedSecureCredentials &credentials) {
|
||||||
|
return telegram_api::make_object<telegram_api::secureCredentialsEncrypted>(
|
||||||
|
BufferSlice(credentials.data), BufferSlice(credentials.hash), BufferSlice(credentials.encrypted_secret));
|
||||||
|
}
|
||||||
|
|
||||||
|
EncryptedSecureCredentials get_secure_credentials(
|
||||||
|
tl_object_ptr<telegram_api::secureCredentialsEncrypted> &&credentials) {
|
||||||
CHECK(credentials != nullptr);
|
CHECK(credentials != nullptr);
|
||||||
SecureCredentials result;
|
EncryptedSecureCredentials result;
|
||||||
result.data = credentials->data_.as_slice().str();
|
result.data = credentials->data_.as_slice().str();
|
||||||
result.hash = credentials->hash_.as_slice().str();
|
result.hash = credentials->hash_.as_slice().str();
|
||||||
result.encrypted_secret = credentials->secret_.as_slice().str();
|
result.encrypted_secret = credentials->secret_.as_slice().str();
|
||||||
@ -365,7 +380,7 @@ SecureCredentials get_secure_credentials(tl_object_ptr<telegram_api::secureCrede
|
|||||||
}
|
}
|
||||||
|
|
||||||
td_api::object_ptr<td_api::encryptedCredentials> get_encrypted_credentials_object(
|
td_api::object_ptr<td_api::encryptedCredentials> get_encrypted_credentials_object(
|
||||||
const SecureCredentials &credentials) {
|
const EncryptedSecureCredentials &credentials) {
|
||||||
return td_api::make_object<td_api::encryptedCredentials>(credentials.data, credentials.hash,
|
return td_api::make_object<td_api::encryptedCredentials>(credentials.data, credentials.hash,
|
||||||
credentials.encrypted_secret);
|
credentials.encrypted_secret);
|
||||||
}
|
}
|
||||||
@ -404,10 +419,11 @@ td_api::object_ptr<td_api::passportData> get_passport_data_object(FileManager *f
|
|||||||
std::move(files), std::move(selfie));
|
std::move(files), std::move(selfie));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<FileId> decrypt_secure_file(FileManager *file_manager, const secure_storage::Secret &master_secret,
|
Result<std::pair<FileId, SecureFileCredentials>> decrypt_secure_file(FileManager *file_manager,
|
||||||
const EncryptedSecureFile &secure_file) {
|
const secure_storage::Secret &master_secret,
|
||||||
|
const EncryptedSecureFile &secure_file) {
|
||||||
if (!secure_file.file_id.is_valid()) {
|
if (!secure_file.file_id.is_valid()) {
|
||||||
return secure_file.file_id;
|
return std::make_pair(secure_file.file_id, 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));
|
||||||
@ -415,33 +431,39 @@ Result<FileId> decrypt_secure_file(FileManager *file_manager, const secure_stora
|
|||||||
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_id, std::move(key));
|
||||||
return secure_file.file_id;
|
return std::make_pair(secure_file.file_id, SecureFileCredentials{secret.as_slice().str(), hash.as_slice().str()});
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<vector<FileId>> decrypt_secure_files(FileManager *file_manager, const secure_storage::Secret &secret,
|
Result<std::pair<vector<FileId>, vector<SecureFileCredentials>>> decrypt_secure_files(
|
||||||
const vector<EncryptedSecureFile> &secure_files) {
|
FileManager *file_manager, const secure_storage::Secret &secret, const vector<EncryptedSecureFile> &secure_files) {
|
||||||
vector<FileId> res;
|
vector<FileId> res;
|
||||||
|
vector<SecureFileCredentials> credentials;
|
||||||
res.reserve(secure_files.size());
|
res.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);
|
res.push_back(decrypted_file.first);
|
||||||
|
credentials.push_back(decrypted_file.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::move(res);
|
return std::make_pair(std::move(res), std::move(credentials));
|
||||||
}
|
}
|
||||||
Result<string> decrypt_secure_data(const secure_storage::Secret &master_secret,
|
Result<std::pair<string, SecureDataCredentials>> decrypt_secure_data(const secure_storage::Secret &master_secret,
|
||||||
const EncryptedSecureData &secure_data) {
|
const EncryptedSecureData &secure_data) {
|
||||||
TRY_RESULT(hash, secure_storage::ValueHash::create(secure_data.hash));
|
TRY_RESULT(hash, secure_storage::ValueHash::create(secure_data.hash));
|
||||||
TRY_RESULT(encrypted_secret, secure_storage::EncryptedSecret::create(secure_data.encrypted_secret));
|
TRY_RESULT(encrypted_secret, secure_storage::EncryptedSecret::create(secure_data.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()));
|
||||||
TRY_RESULT(value, secure_storage::decrypt_value(secret, hash, secure_data.data));
|
TRY_RESULT(value, secure_storage::decrypt_value(secret, hash, secure_data.data));
|
||||||
return value.as_slice().str();
|
return std::make_pair(value.as_slice().str(), SecureDataCredentials{secret.as_slice().str(), hash.as_slice().str()});
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<SecureValue> decrypt_encrypted_secure_value(FileManager *file_manager, const secure_storage::Secret &secret,
|
Result<SecureValueWithCredentials> decrypt_encrypted_secure_value(FileManager *file_manager,
|
||||||
const EncryptedSecureValue &encrypted_secure_value) {
|
const secure_storage::Secret &secret,
|
||||||
|
const EncryptedSecureValue &encrypted_secure_value) {
|
||||||
SecureValue res;
|
SecureValue res;
|
||||||
|
SecureValueCredentials res_credentials;
|
||||||
res.type = encrypted_secure_value.type;
|
res.type = encrypted_secure_value.type;
|
||||||
|
res_credentials.type = res.type;
|
||||||
|
res_credentials.hash = encrypted_secure_value.hash;
|
||||||
switch (encrypted_secure_value.type) {
|
switch (encrypted_secure_value.type) {
|
||||||
case SecureValueType::EmailAddress:
|
case SecureValueType::EmailAddress:
|
||||||
case SecureValueType::PhoneNumber:
|
case SecureValueType::PhoneNumber:
|
||||||
@ -449,15 +471,22 @@ Result<SecureValue> decrypt_encrypted_secure_value(FileManager *file_manager, co
|
|||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
TRY_RESULT(data, decrypt_secure_data(secret, encrypted_secure_value.data));
|
TRY_RESULT(data, decrypt_secure_data(secret, encrypted_secure_value.data));
|
||||||
res.data = std::move(data);
|
res.data = std::move(data.first);
|
||||||
|
if (!res.data.empty()) {
|
||||||
|
res_credentials.data = std::move(data.second);
|
||||||
|
}
|
||||||
TRY_RESULT(files, decrypt_secure_files(file_manager, secret, encrypted_secure_value.files));
|
TRY_RESULT(files, decrypt_secure_files(file_manager, secret, encrypted_secure_value.files));
|
||||||
res.files = std::move(files);
|
res.files = std::move(files.first);
|
||||||
|
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);
|
res.selfie = std::move(selfie.first);
|
||||||
|
if (res.selfie.is_valid()) {
|
||||||
|
res_credentials.selfie = std::move(selfie.second);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return std::move(res);
|
return SecureValueWithCredentials{std::move(res), std::move(res_credentials)};
|
||||||
}
|
}
|
||||||
|
|
||||||
EncryptedSecureFile encrypt_secure_file(FileManager *file_manager, const secure_storage::Secret &master_secret,
|
EncryptedSecureFile encrypt_secure_file(FileManager *file_manager, const secure_storage::Secret &master_secret,
|
||||||
@ -528,4 +557,117 @@ EncryptedSecureValue encrypt_secure_value(FileManager *file_manager, const secur
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class AsJsonable : public Jsonable {
|
||||||
|
public:
|
||||||
|
AsJsonable(const T &value) : value_(value) {
|
||||||
|
}
|
||||||
|
void store(JsonValueScope *scope) const {
|
||||||
|
*scope + value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const T &value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
auto as_jsonable(const T &value) {
|
||||||
|
return AsJsonable<T>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonScope &operator+(JsonValueScope &scope, const SecureDataCredentials &credentials) {
|
||||||
|
auto object = scope.enter_object();
|
||||||
|
object << ctie("data_hash", base64_encode(credentials.hash));
|
||||||
|
object << ctie("secret", base64_encode(credentials.secret));
|
||||||
|
return scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonScope &operator+(JsonValueScope &scope, const SecureFileCredentials &credentials) {
|
||||||
|
auto object = scope.enter_object();
|
||||||
|
object << ctie("file_hash", base64_encode(credentials.hash));
|
||||||
|
object << ctie("secret", base64_encode(credentials.secret));
|
||||||
|
return scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonScope &operator+(JsonValueScope &scope, const vector<SecureFileCredentials> &files) {
|
||||||
|
auto arr = scope.enter_array();
|
||||||
|
for (auto &file : files) {
|
||||||
|
arr << as_jsonable(file);
|
||||||
|
}
|
||||||
|
return scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonScope &operator+(JsonValueScope &scope, const SecureValueCredentials &credentials) {
|
||||||
|
auto object = scope.enter_object();
|
||||||
|
if (credentials.data) {
|
||||||
|
object << ctie("data", as_jsonable(credentials.data.value()));
|
||||||
|
}
|
||||||
|
if (!credentials.files.empty()) {
|
||||||
|
object << ctie("files", as_jsonable(credentials.files));
|
||||||
|
}
|
||||||
|
if (credentials.selfie) {
|
||||||
|
object << ctie("selfie", as_jsonable(credentials.selfie.value()));
|
||||||
|
}
|
||||||
|
return scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
Slice secure_value_type_as_slice(SecureValueType type) {
|
||||||
|
switch (type) {
|
||||||
|
case SecureValueType::PersonalDetails:
|
||||||
|
return "personal_details";
|
||||||
|
case SecureValueType::Passport:
|
||||||
|
return "passport";
|
||||||
|
case SecureValueType::DriverLicense:
|
||||||
|
return "driver_license";
|
||||||
|
case SecureValueType::IdentityCard:
|
||||||
|
return "identity_card";
|
||||||
|
case SecureValueType::Address:
|
||||||
|
return "address";
|
||||||
|
case SecureValueType::UtilityBill:
|
||||||
|
return "utility_bill";
|
||||||
|
case SecureValueType::BankStatement:
|
||||||
|
return "bank_statement";
|
||||||
|
case SecureValueType::RentalAgreement:
|
||||||
|
return "rental_agreement";
|
||||||
|
case SecureValueType::PhoneNumber:
|
||||||
|
return "phone_number";
|
||||||
|
case SecureValueType::EmailAddress:
|
||||||
|
return "email_address";
|
||||||
|
default:
|
||||||
|
case SecureValueType::None:
|
||||||
|
UNREACHABLE();
|
||||||
|
return "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonScope &operator+(JsonValueScope &scope, const std::vector<SecureValueCredentials> &credentials) {
|
||||||
|
auto object = scope.enter_object();
|
||||||
|
for (auto &c : credentials) {
|
||||||
|
object << ctie(secure_value_type_as_slice(c.type), as_jsonable(c));
|
||||||
|
}
|
||||||
|
return scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonScope &operator+(JsonValueScope &scope,
|
||||||
|
const std::pair<const std::vector<SecureValueCredentials> &, const Slice &> &credentials) {
|
||||||
|
auto object = scope.enter_object();
|
||||||
|
object << ctie("secure_data", as_jsonable(credentials.first));
|
||||||
|
object << ctie("payload", credentials.second);
|
||||||
|
return scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<EncryptedSecureCredentials> encrypted_credentials(std::vector<SecureValueCredentials> &credentials,
|
||||||
|
Slice payload, Slice public_key) {
|
||||||
|
auto encoded_credentials = json_encode<std::string>(as_jsonable(ctie(credentials, payload)));
|
||||||
|
LOG(ERROR) << encoded_credentials;
|
||||||
|
|
||||||
|
auto secret = secure_storage::Secret::create_new();
|
||||||
|
auto encrypted_value = secure_storage::encrypt_value(secret, encoded_credentials).move_as_ok();
|
||||||
|
EncryptedSecureCredentials res;
|
||||||
|
res.data = encrypted_value.data.as_slice().str();
|
||||||
|
res.hash = encrypted_value.data.as_slice().str();
|
||||||
|
TRY_RESULT(encrypted_secret, rsa_encrypt_pkcs1_oaep(public_key, secret.as_slice()));
|
||||||
|
res.encrypted_secret = encrypted_secret.as_slice().str();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "td/telegram/SecureStorage.h"
|
#include "td/telegram/SecureStorage.h"
|
||||||
|
|
||||||
#include "td/utils/common.h"
|
#include "td/utils/common.h"
|
||||||
|
#include "td/utils/JsonBuilder.h"
|
||||||
#include "td/utils/optional.h"
|
#include "td/utils/optional.h"
|
||||||
#include "td/utils/Status.h"
|
#include "td/utils/Status.h"
|
||||||
|
|
||||||
@ -39,6 +40,8 @@ SecureValueType get_secure_value_type_td_api(tl_object_ptr<td_api::PassportDataT
|
|||||||
|
|
||||||
vector<SecureValueType> get_secure_value_types(
|
vector<SecureValueType> get_secure_value_types(
|
||||||
vector<tl_object_ptr<telegram_api::SecureValueType>> &&secure_value_types);
|
vector<tl_object_ptr<telegram_api::SecureValueType>> &&secure_value_types);
|
||||||
|
vector<SecureValueType> get_secure_value_types_td_api(
|
||||||
|
vector<tl_object_ptr<td_api::PassportDataType>> &&secure_value_types);
|
||||||
|
|
||||||
td_api::object_ptr<td_api::PassportDataType> get_passport_data_type_object(SecureValueType type);
|
td_api::object_ptr<td_api::PassportDataType> get_passport_data_type_object(SecureValueType type);
|
||||||
td_api::object_ptr<telegram_api::SecureValueType> get_secure_value_type_telegram_object(SecureValueType type);
|
td_api::object_ptr<telegram_api::SecureValueType> get_secure_value_type_telegram_object(SecureValueType type);
|
||||||
@ -116,18 +119,42 @@ telegram_api::object_ptr<telegram_api::inputSecureValue> get_input_secure_value_
|
|||||||
vector<td_api::object_ptr<td_api::encryptedPassportData>> get_encrypted_passport_data_object(
|
vector<td_api::object_ptr<td_api::encryptedPassportData>> get_encrypted_passport_data_object(
|
||||||
FileManager *file_manager, const vector<EncryptedSecureValue> &values);
|
FileManager *file_manager, const vector<EncryptedSecureValue> &values);
|
||||||
|
|
||||||
struct SecureCredentials {
|
struct EncryptedSecureCredentials {
|
||||||
string data;
|
string data;
|
||||||
string hash;
|
string hash;
|
||||||
string encrypted_secret;
|
string encrypted_secret;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool operator==(const SecureCredentials &lhs, const SecureCredentials &rhs);
|
bool operator==(const EncryptedSecureCredentials &lhs, const EncryptedSecureCredentials &rhs);
|
||||||
bool operator!=(const SecureCredentials &lhs, const SecureCredentials &rhs);
|
bool operator!=(const EncryptedSecureCredentials &lhs, const EncryptedSecureCredentials &rhs);
|
||||||
|
|
||||||
SecureCredentials get_secure_credentials(tl_object_ptr<telegram_api::secureCredentialsEncrypted> &&credentials);
|
EncryptedSecureCredentials get_secure_credentials(
|
||||||
|
tl_object_ptr<telegram_api::secureCredentialsEncrypted> &&credentials);
|
||||||
|
|
||||||
td_api::object_ptr<td_api::encryptedCredentials> get_encrypted_credentials_object(const SecureCredentials &credentials);
|
telegram_api::object_ptr<telegram_api::secureCredentialsEncrypted> get_secure_credentials_encrypted_object(
|
||||||
|
const EncryptedSecureCredentials &credentials);
|
||||||
|
td_api::object_ptr<td_api::encryptedCredentials> get_encrypted_credentials_object(
|
||||||
|
const EncryptedSecureCredentials &credentials);
|
||||||
|
|
||||||
|
struct SecureDataCredentials {
|
||||||
|
string hash;
|
||||||
|
string secret;
|
||||||
|
};
|
||||||
|
struct SecureFileCredentials {
|
||||||
|
string hash;
|
||||||
|
string secret;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SecureValueCredentials {
|
||||||
|
SecureValueType type;
|
||||||
|
string hash;
|
||||||
|
optional<SecureDataCredentials> data;
|
||||||
|
std::vector<SecureFileCredentials> files;
|
||||||
|
optional<SecureFileCredentials> selfie;
|
||||||
|
};
|
||||||
|
|
||||||
|
Result<EncryptedSecureCredentials> encrypted_credentials(std::vector<SecureValueCredentials> &credentials,
|
||||||
|
Slice payload, Slice public_key);
|
||||||
|
|
||||||
class SecureValue {
|
class SecureValue {
|
||||||
public:
|
public:
|
||||||
@ -137,18 +164,26 @@ class SecureValue {
|
|||||||
FileId selfie;
|
FileId selfie;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SecureValueWithCredentials {
|
||||||
|
SecureValue value;
|
||||||
|
SecureValueCredentials credentials;
|
||||||
|
};
|
||||||
|
|
||||||
Result<SecureValue> get_secure_value(FileManager *file_manager,
|
Result<SecureValue> get_secure_value(FileManager *file_manager,
|
||||||
td_api::object_ptr<td_api::inputPassportData> &&input_passport_data);
|
td_api::object_ptr<td_api::inputPassportData> &&input_passport_data);
|
||||||
|
|
||||||
td_api::object_ptr<td_api::passportData> get_passport_data_object(FileManager *file_manager, const SecureValue &value);
|
td_api::object_ptr<td_api::passportData> get_passport_data_object(FileManager *file_manager, const SecureValue &value);
|
||||||
|
|
||||||
Result<FileId> decrypt_secure_file(FileManager *file_manager, const secure_storage::Secret &secret,
|
Result<std::pair<FileId, SecureFileCredentials>> decrypt_secure_file(FileManager *file_manager,
|
||||||
const EncryptedSecureFile &secure_file);
|
const secure_storage::Secret &secret,
|
||||||
Result<vector<FileId>> decrypt_secure_files(FileManager *file_manager, const secure_storage::Secret &secret,
|
const EncryptedSecureFile &secure_file);
|
||||||
const vector<EncryptedSecureFile> &secure_file);
|
Result<std::pair<vector<FileId>, vector<SecureFileCredentials>>> decrypt_secure_files(
|
||||||
Result<string> decrypt_secure_data(const secure_storage::Secret &secret, const EncryptedSecureData &secure_data);
|
FileManager *file_manager, const secure_storage::Secret &secret, const vector<EncryptedSecureFile> &secure_file);
|
||||||
Result<SecureValue> decrypt_encrypted_secure_value(FileManager *file_manager, const secure_storage::Secret &secret,
|
Result<std::pair<string, SecureDataCredentials>> decrypt_secure_data(const secure_storage::Secret &secret,
|
||||||
const EncryptedSecureValue &encrypted_secure_value);
|
const EncryptedSecureData &secure_data);
|
||||||
|
Result<SecureValueWithCredentials> decrypt_encrypted_secure_value(FileManager *file_manager,
|
||||||
|
const secure_storage::Secret &secret,
|
||||||
|
const EncryptedSecureValue &encrypted_secure_value);
|
||||||
|
|
||||||
EncryptedSecureFile encrypt_secure_file(FileManager *file_manager, const secure_storage::Secret &master_secret,
|
EncryptedSecureFile encrypt_secure_file(FileManager *file_manager, const secure_storage::Secret &master_secret,
|
||||||
FileId file, string &to_hash);
|
FileId file, string &to_hash);
|
||||||
|
@ -43,14 +43,14 @@ void parse(EncryptedSecureData &data, ParserT &parser) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class StorerT>
|
template <class StorerT>
|
||||||
void store(const SecureCredentials &credentials, StorerT &storer) {
|
void store(const EncryptedSecureCredentials &credentials, StorerT &storer) {
|
||||||
store(credentials.data, storer);
|
store(credentials.data, storer);
|
||||||
store(credentials.hash, storer);
|
store(credentials.hash, storer);
|
||||||
store(credentials.encrypted_secret, storer);
|
store(credentials.encrypted_secret, storer);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ParserT>
|
template <class ParserT>
|
||||||
void parse(SecureCredentials &credentials, ParserT &parser) {
|
void parse(EncryptedSecureCredentials &credentials, ParserT &parser) {
|
||||||
parse(credentials.data, parser);
|
parse(credentials.data, parser);
|
||||||
parse(credentials.hash, parser);
|
parse(credentials.hash, parser);
|
||||||
parse(credentials.encrypted_secret, parser);
|
parse(credentials.encrypted_secret, parser);
|
||||||
|
@ -6902,15 +6902,27 @@ void Td::on_request(uint64 id, td_api::getPassportAuthorizationForm &request) {
|
|||||||
CLEAN_INPUT_STRING(request.password_);
|
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_);
|
||||||
|
CLEAN_INPUT_STRING(request.payload_);
|
||||||
CREATE_REQUEST_PROMISE(promise);
|
CREATE_REQUEST_PROMISE(promise);
|
||||||
send_closure(secure_manager_, &SecureManager::get_passport_authorization_form, request.password_, request.bot_id_,
|
send_closure(secure_manager_, &SecureManager::get_passport_authorization_form, request.password_, request.bot_id_,
|
||||||
request.scope_, request.public_key_, std::move(promise));
|
request.scope_, request.public_key_, request.payload_, std::move(promise));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Td::on_request(uint64 id, const td_api::sendPassportAuthorizationForm &request) {
|
void Td::on_request(uint64 id, td_api::sendPassportAuthorizationForm &request) {
|
||||||
CHECK_AUTH();
|
CHECK_AUTH();
|
||||||
CHECK_IS_USER();
|
CHECK_IS_USER();
|
||||||
LOG(FATAL) << "TODO";
|
CLEAN_INPUT_STRING(request.password_);
|
||||||
|
CREATE_REQUEST_PROMISE(promise);
|
||||||
|
auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result<> result) mutable {
|
||||||
|
if (result.is_error()) {
|
||||||
|
promise.set_error(result.move_as_error());
|
||||||
|
} else {
|
||||||
|
promise.set_value(make_tl_object<td_api::ok>());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
send_closure(secure_manager_, &SecureManager::send_passport_authorization_form, request.password_,
|
||||||
|
request.autorization_form_id_, get_secure_value_types_td_api(std::move(request.types_)),
|
||||||
|
std::move(query_promise));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Td::on_request(uint64 id, const td_api::getSupportUser &request) {
|
void Td::on_request(uint64 id, const td_api::getSupportUser &request) {
|
||||||
|
@ -769,7 +769,7 @@ class Td final : public NetQueryCallback {
|
|||||||
|
|
||||||
void on_request(uint64 id, td_api::getPassportAuthorizationForm &request);
|
void on_request(uint64 id, td_api::getPassportAuthorizationForm &request);
|
||||||
|
|
||||||
void on_request(uint64 id, const td_api::sendPassportAuthorizationForm &request);
|
void on_request(uint64 id, td_api::sendPassportAuthorizationForm &request);
|
||||||
|
|
||||||
void on_request(uint64 id, const td_api::getSupportUser &request);
|
void on_request(uint64 id, const td_api::getSupportUser &request);
|
||||||
|
|
||||||
|
@ -936,7 +936,7 @@ class CliClient final : public Actor {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static tl_object_ptr<td_api::PassportDataType> as_passport_data_type(string passport_data_type) {
|
static tl_object_ptr<td_api::PassportDataType> as_passport_data_type(Slice passport_data_type) {
|
||||||
if (passport_data_type == "address" || passport_data_type == "a") {
|
if (passport_data_type == "address" || passport_data_type == "a") {
|
||||||
return make_tl_object<td_api::passportDataTypeAddress>();
|
return make_tl_object<td_api::passportDataTypeAddress>();
|
||||||
}
|
}
|
||||||
@ -952,6 +952,10 @@ class CliClient final : public Actor {
|
|||||||
return make_tl_object<td_api::passportDataTypePassport>();
|
return make_tl_object<td_api::passportDataTypePassport>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static auto as_passport_data_types(Slice types, char delimiter = ',') {
|
||||||
|
return transform(full_split(types, delimiter), [](Slice str) { return as_passport_data_type(str); });
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
@ -1091,9 +1095,18 @@ class CliClient final : public Actor {
|
|||||||
string bot_id = query.arg("bot_id").str();
|
string bot_id = query.arg("bot_id").str();
|
||||||
string scope = query.arg("scope").str();
|
string scope = query.arg("scope").str();
|
||||||
string public_key = query.arg("public_key").str();
|
string public_key = query.arg("public_key").str();
|
||||||
send_request(
|
string payload = query.arg("payload").str();
|
||||||
make_tl_object<td_api::getPassportAuthorizationForm>(to_integer<int32>(bot_id), scope, public_key, password));
|
LOG(ERROR) << query.arg("callback_url");
|
||||||
|
send_request(make_tl_object<td_api::getPassportAuthorizationForm>(to_integer<int32>(bot_id), scope, public_key,
|
||||||
|
payload, password));
|
||||||
} else if (op == "spaf") {
|
} else if (op == "spaf") {
|
||||||
|
string password;
|
||||||
|
string id;
|
||||||
|
string types;
|
||||||
|
std::tie(password, args) = split(args);
|
||||||
|
std::tie(id, types) = split(args);
|
||||||
|
send_request(make_tl_object<td_api::sendPassportAuthorizationForm>(to_integer<int32>(id),
|
||||||
|
as_passport_data_types(types), password));
|
||||||
} else if (op == "srea" || op == "SetRecoveryEmailAddress") {
|
} else if (op == "srea" || op == "SetRecoveryEmailAddress") {
|
||||||
string password;
|
string password;
|
||||||
string recovery_email_address;
|
string recovery_email_address;
|
||||||
|
@ -401,6 +401,10 @@ class Result {
|
|||||||
CHECK(status_.is_ok()) << status_;
|
CHECK(status_.is_ok()) << status_;
|
||||||
return value_;
|
return value_;
|
||||||
}
|
}
|
||||||
|
const T &ok_ref() const {
|
||||||
|
CHECK(status_.is_ok()) << status_;
|
||||||
|
return value_;
|
||||||
|
}
|
||||||
T move_as_ok() {
|
T move_as_ok() {
|
||||||
CHECK(status_.is_ok()) << status_;
|
CHECK(status_.is_ok()) << status_;
|
||||||
return std::move(value_);
|
return std::move(value_);
|
||||||
|
@ -19,12 +19,15 @@ class optional {
|
|||||||
template <class T1>
|
template <class T1>
|
||||||
optional(T1 &&t) : impl_(std::forward<T1>(t)) {
|
optional(T1 &&t) : impl_(std::forward<T1>(t)) {
|
||||||
}
|
}
|
||||||
explicit operator bool() {
|
explicit operator bool() const {
|
||||||
return impl_.is_ok();
|
return impl_.is_ok();
|
||||||
}
|
}
|
||||||
T &value() {
|
T &value() {
|
||||||
return impl_.ok_ref();
|
return impl_.ok_ref();
|
||||||
}
|
}
|
||||||
|
const T &value() const {
|
||||||
|
return impl_.ok_ref();
|
||||||
|
}
|
||||||
T &operator*() {
|
T &operator*() {
|
||||||
return value();
|
return value();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user