Remove code duplication in sign-in procedures
Use the new libtgl request_values callback to query inputs from the user instead of implementing the sign-in methods manually.
This commit is contained in:
parent
6fce2cf8fa
commit
f89f3fd71a
6 changed files with 157 additions and 262 deletions
100
telegram-base.c
100
telegram-base.c
|
@ -247,13 +247,11 @@ void read_dc (struct tgl_state *TLS, int auth_file_fd, int id, unsigned ver) {
|
|||
bl_do_dc_signed (TLS, id);
|
||||
}
|
||||
|
||||
int error_if_val_false (struct tgl_state *TLS, int val, const char *cause, const char *msg) {
|
||||
if (!val) {
|
||||
int tgp_error_if_false (struct tgl_state *TLS, int val, const char *cause, const char *msg) {
|
||||
if (! val) {
|
||||
connection_data *conn = TLS->ev_base;
|
||||
purple_connection_error_reason (conn->gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, msg);
|
||||
|
||||
purple_notify_message (_telegram_protocol, PURPLE_NOTIFY_MSG_ERROR,
|
||||
cause, msg, NULL, NULL, NULL);
|
||||
purple_notify_message (_telegram_protocol, PURPLE_NOTIFY_MSG_ERROR, cause, msg, NULL, NULL, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
return 0;
|
||||
|
@ -319,7 +317,6 @@ void read_auth_file (struct tgl_state *TLS) {
|
|||
close (auth_file_fd);
|
||||
}
|
||||
|
||||
|
||||
void write_secret_chat (tgl_peer_t *_P, void *extra) {
|
||||
struct tgl_secret_chat *P = (void *)_P;
|
||||
if (tgl_get_peer_type (P->id) != TGL_PEER_ENCR_CHAT) { return; }
|
||||
|
@ -472,33 +469,6 @@ gchar *get_download_dir (struct tgl_state *TLS) {
|
|||
return dir;
|
||||
}
|
||||
|
||||
gboolean assert_file_exists (PurpleConnection *gc, const char *filepath, const char *format) {
|
||||
if (!g_file_test (filepath, G_FILE_TEST_EXISTS)) {
|
||||
gchar *msg = g_strdup_printf (format, filepath);
|
||||
purple_connection_error_reason (gc, PURPLE_CONNECTION_ERROR_CERT_OTHER_ERROR, msg);
|
||||
g_free (msg);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void export_auth_callback (struct tgl_state *TLS, void *extra, int success) {
|
||||
if (!error_if_val_false (TLS, success, _("Login canceled"), _("Authentication export to remote data centers failed, login not possible."))) {
|
||||
telegram_export_authorization (TLS);
|
||||
}
|
||||
}
|
||||
|
||||
void telegram_export_authorization (struct tgl_state *TLS) {
|
||||
int i;
|
||||
for (i = 0; i <= TLS->max_dc_num; i++) if (TLS->DC_list[i] && !tgl_signed_dc (TLS, TLS->DC_list[i])) {
|
||||
debug ("tgl_do_export_auth(%d)", i);
|
||||
tgl_do_export_auth (TLS, i, export_auth_callback, (void*)(long)TLS->DC_list[i]);
|
||||
return;
|
||||
}
|
||||
write_auth_file (TLS);
|
||||
on_ready (TLS);
|
||||
}
|
||||
|
||||
void write_secret_chat_gw (struct tgl_state *TLS, void *extra, int success, struct tgl_secret_chat *_) {
|
||||
if (!success) {
|
||||
tgp_notify_on_error_gw (TLS, NULL, success);
|
||||
|
@ -535,70 +505,6 @@ void tgp_create_group_chat_by_usernames (struct tgl_state *TLS, const char *titl
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static void sign_in_callback (struct tgl_state *TLS, void *extra, int success, int registered, const char *mhash) {
|
||||
connection_data *conn = TLS->ev_base;
|
||||
if (! error_if_val_false (TLS, success, _("Invalid phone number"),
|
||||
_("Please enter only numbers in the international phone number format, "
|
||||
"a leading + following by the country prefix and the phone number.\n"
|
||||
"Do not use any other special chars."))) {
|
||||
conn->hash = strdup (mhash);
|
||||
if (registered) {
|
||||
request_code (TLS, telegram_export_authorization);
|
||||
} else {
|
||||
request_name_and_code (TLS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void telegram_send_sms (struct tgl_state *TLS) {
|
||||
if (tgl_signed_dc (TLS, TLS->DC_working)) {
|
||||
telegram_export_authorization (TLS);
|
||||
return;
|
||||
}
|
||||
connection_data *conn = TLS->ev_base;
|
||||
char const *username = purple_account_get_username(conn->pa);
|
||||
tgl_do_send_code (TLS, username, (int) strlen(username), sign_in_callback, NULL);
|
||||
}
|
||||
|
||||
static int all_authorized (struct tgl_state *TLS) {
|
||||
int i;
|
||||
for (i = 0; i <= TLS->max_dc_num; i++) {
|
||||
if (TLS->DC_list[i]) {
|
||||
tgl_dc_authorize (TLS, TLS->DC_list[i]);
|
||||
if (!tgl_signed_dc (TLS, TLS->DC_list[i]) && !tgl_authorized_dc (TLS, TLS->DC_list[i])) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int check_all_authorized (gpointer arg) {
|
||||
struct tgl_state *TLS = arg;
|
||||
|
||||
if (all_authorized (TLS)) {
|
||||
((connection_data *)TLS->ev_base)->login_timer = 0;
|
||||
telegram_send_sms (TLS);
|
||||
return FALSE;
|
||||
} else {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void telegram_login (struct tgl_state *TLS) {
|
||||
connection_data *conn = TLS->ev_base;
|
||||
|
||||
read_auth_file (TLS);
|
||||
read_state_file (TLS);
|
||||
read_secret_chat_file (TLS);
|
||||
if (all_authorized (TLS)) {
|
||||
telegram_send_sms (TLS);
|
||||
return;
|
||||
}
|
||||
conn->login_timer = purple_timeout_add (100, check_all_authorized, TLS);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function generates a png image to visualize the sha1 key from an encrypted chat.
|
||||
*/
|
||||
|
|
|
@ -39,18 +39,14 @@ void read_secret_chat_file (struct tgl_state *TLS);
|
|||
void write_secret_chat_file (struct tgl_state *TLS);
|
||||
void write_secret_chat_gw (struct tgl_state *TLS, void *extra, int success, struct tgl_secret_chat *E);
|
||||
|
||||
void telegram_login (struct tgl_state *TLS);
|
||||
void telegram_export_authorization (struct tgl_state *TLS);
|
||||
|
||||
gchar *get_config_dir (char const *username);
|
||||
gchar *get_user_pk_path ();
|
||||
gchar *get_download_dir (struct tgl_state *TLS);
|
||||
|
||||
gboolean assert_file_exists (PurpleConnection *gc, const char *filepath, const char *format);
|
||||
|
||||
int tgp_visualize_key (struct tgl_state *TLS, unsigned char* sha1_key);
|
||||
void tgp_create_group_chat_by_usernames (struct tgl_state *TLS, const char *title,
|
||||
const char *users[], int num_users, int print_names);
|
||||
|
||||
void tgp_notify_on_error_gw (struct tgl_state *TLS, void *extra, int success);
|
||||
int tgp_error_if_false (struct tgl_state *TLS, int val, const char *cause, const char *msg);
|
||||
#endif
|
||||
|
|
|
@ -65,9 +65,8 @@
|
|||
#include "tgp-msg.h"
|
||||
#include "tgp-request.h"
|
||||
#include "tgp-blist.h"
|
||||
#include "tgp-structs.h"
|
||||
|
||||
static void get_password (struct tgl_state *TLS, enum tgl_value_type type, const char *prompt, int num_values,
|
||||
void (*callback)(struct tgl_state *TLS, const char *string[], void *arg), void *arg);
|
||||
static void update_message_handler (struct tgl_state *TLS, struct tgl_message *M);
|
||||
static void update_user_handler (struct tgl_state *TLS, struct tgl_user *U, unsigned flags);
|
||||
static void update_user_status_handler (struct tgl_state *TLS, struct tgl_user *U);
|
||||
|
@ -75,6 +74,7 @@ static void update_chat_handler (struct tgl_state *TLS, struct tgl_chat *C, unsi
|
|||
static void update_secret_chat_handler (struct tgl_state *TLS, struct tgl_secret_chat *C, unsigned flags);
|
||||
static void update_user_typing (struct tgl_state *TLS, struct tgl_user *U, enum tgl_typing_status status);
|
||||
static void update_marked_read (struct tgl_state *TLS, int num, struct tgl_message *list[]);
|
||||
static void update_on_ready (struct tgl_state *TLS);
|
||||
static char *format_print_name (struct tgl_state *TLS, tgl_peer_id_t id, const char *a1, const char *a2, const char *a3, const char *a4);
|
||||
static void on_user_get_info (struct tgl_state *TLS, void *info_data, int success, struct tgl_user *U);
|
||||
|
||||
|
@ -84,7 +84,8 @@ const char *pk_path = "/etc/telegram-purple/server.tglpub";
|
|||
|
||||
struct tgl_update_callback tgp_callback = {
|
||||
.logprintf = debug,
|
||||
.get_values = get_password,
|
||||
.get_values = request_value,
|
||||
.started = update_on_ready,
|
||||
.new_msg = update_message_handler,
|
||||
.msg_receive = update_message_handler,
|
||||
.user_update = update_user_handler,
|
||||
|
@ -286,21 +287,6 @@ static char *format_print_name (struct tgl_state *TLS, tgl_peer_id_t id, const c
|
|||
return tgl_strdup (s);
|
||||
}
|
||||
|
||||
static void get_password (struct tgl_state *TLS, enum tgl_value_type type, const char *prompt, int num_values,
|
||||
void (*callback)(struct tgl_state *TLS, const char *string[], void *arg), void *arg) {
|
||||
if (type == tgl_cur_password) {
|
||||
connection_data *conn = TLS->ev_base;
|
||||
const char *P = purple_account_get_string (conn->pa, TGP_KEY_PASSWORD_TWO_FACTOR, NULL);
|
||||
|
||||
if (str_not_empty (P)) {
|
||||
if (conn->password_retries++ < 1) {
|
||||
callback (TLS, &P, arg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
request_password (TLS, callback, arg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
static void on_contact_added (struct tgl_state *TLS,void *callback_extra, int success, int size, struct tgl_user *users[]) {
|
||||
|
@ -405,20 +391,6 @@ void on_user_get_info (struct tgl_state *TLS, void *info_data, int success, stru
|
|||
}
|
||||
}
|
||||
|
||||
void on_ready (struct tgl_state *TLS) {
|
||||
debug ("on_ready().");
|
||||
connection_data *conn = TLS->ev_base;
|
||||
|
||||
purple_connection_set_state (conn->gc, PURPLE_CONNECTED);
|
||||
purple_connection_set_display_name (conn->gc, purple_account_get_username (conn->pa));
|
||||
purple_blist_add_account (conn->pa);
|
||||
|
||||
debug ("seq = %d, pts = %d, date = %d", TLS->seq, TLS->pts, TLS->date);
|
||||
tgl_do_get_difference (TLS, purple_account_get_bool (conn->pa, "history-sync-all", FALSE), tgp_notify_on_error_gw, NULL);
|
||||
tgl_do_get_dialog_list (TLS, 200, 0, on_get_dialog_list_done, NULL);
|
||||
tgl_do_update_contact_list (TLS, 0, 0);
|
||||
}
|
||||
|
||||
static const char *tgprpl_list_icon (PurpleAccount *acct, PurpleBuddy *buddy) {
|
||||
return "telegram";
|
||||
}
|
||||
|
@ -474,6 +446,8 @@ static void create_secret_chat_done (struct tgl_state *TLS, void *callback_extra
|
|||
return;
|
||||
}
|
||||
write_secret_chat_file (TLS);
|
||||
|
||||
// show the created secret chat to the user
|
||||
}
|
||||
|
||||
static void start_secret_chat (PurpleBlistNode *node, gpointer data) {
|
||||
|
@ -516,12 +490,6 @@ void export_chat_link_checked (struct tgl_state *TLS, const char *name) {
|
|||
tgl_do_export_chat_link (TLS, C->id, create_chat_link_done, C);
|
||||
}
|
||||
|
||||
void leave_and_delete_chat_gw (PurpleBlistNode *node, gpointer data) {
|
||||
PurpleChat *PC = (PurpleChat*)node;
|
||||
tgl_peer_t *P = tgl_peer_get (pbn_get_conn (node)->TLS, p2tgl_chat_get_id (PC));
|
||||
leave_and_delete_chat (pbn_get_conn (node)->TLS, P);
|
||||
}
|
||||
|
||||
void leave_and_delete_chat (struct tgl_state *TLS, tgl_peer_t *P) {
|
||||
g_return_if_fail (P);
|
||||
if (P && P->chat.users_num) {
|
||||
|
@ -579,6 +547,22 @@ static GList* tgprpl_blist_node_menu (PurpleBlistNode *node) {
|
|||
return menu;
|
||||
}
|
||||
|
||||
static void update_on_ready (struct tgl_state *TLS) {
|
||||
debug ("update_on_ready().");
|
||||
|
||||
write_auth_file (TLS);
|
||||
|
||||
purple_connection_set_state (tg_get_conn (TLS), PURPLE_CONNECTED);
|
||||
purple_connection_set_display_name (tg_get_conn (TLS), purple_account_get_username (tg_get_acc (TLS)));
|
||||
purple_blist_add_account (tg_get_acc (TLS));
|
||||
|
||||
debug ("seq = %d, pts = %d, date = %d", TLS->seq, TLS->pts, TLS->date);
|
||||
tgl_do_get_difference (TLS, purple_account_get_bool (tg_get_acc (TLS), "history-sync-all", FALSE),
|
||||
tgp_notify_on_error_gw, NULL);
|
||||
tgl_do_get_dialog_list (TLS, 200, 0, on_get_dialog_list_done, NULL);
|
||||
tgl_do_update_contact_list (TLS, 0, 0);
|
||||
}
|
||||
|
||||
static void tgprpl_login (PurpleAccount * acct) {
|
||||
debug ("tgprpl_login()");
|
||||
|
||||
|
@ -638,46 +622,50 @@ static void tgprpl_login (PurpleAccount * acct) {
|
|||
if (! tgp_startswith (purple_account_get_username (acct), "+")) {
|
||||
char *cause = g_strdup_printf (_("Unable to sign on as %s: phone number lacks country prefix."),
|
||||
purple_account_get_username (acct));
|
||||
purple_connection_error_reason (gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, cause);
|
||||
purple_notify_message (_telegram_protocol, PURPLE_NOTIFY_MSG_ERROR, cause,
|
||||
_("Numbers must start with the full international\n"
|
||||
"prefix code, e.g. +49 for Germany."), NULL, NULL, NULL);
|
||||
g_free (cause);
|
||||
return;
|
||||
purple_connection_error_reason (gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, cause);
|
||||
purple_notify_message (_telegram_protocol, PURPLE_NOTIFY_MSG_ERROR, cause,
|
||||
_("Numbers must start with the full international\n"
|
||||
"prefix code, e.g. +49 for Germany."), NULL, NULL, NULL);
|
||||
g_free (cause);
|
||||
return;
|
||||
}
|
||||
|
||||
read_auth_file (TLS);
|
||||
read_state_file (TLS);
|
||||
read_secret_chat_file (TLS);
|
||||
|
||||
purple_connection_set_state (conn->gc, PURPLE_CONNECTING);
|
||||
|
||||
telegram_login (TLS);
|
||||
|
||||
tgl_login (TLS);
|
||||
}
|
||||
|
||||
static void tgprpl_close (PurpleConnection *gc) {
|
||||
debug ("tgprpl_close()");
|
||||
connection_data *conn = purple_connection_get_protocol_data (gc);
|
||||
connection_data_free (conn);
|
||||
connection_data_free (purple_connection_get_protocol_data (gc));
|
||||
}
|
||||
|
||||
static int tgprpl_send_im (PurpleConnection *gc, const char *who, const char *message, PurpleMessageFlags flags) {
|
||||
debug ("tgprpl_send_im()");
|
||||
|
||||
// this is part of a workaround to support clients without
|
||||
// the request API (request.h), see telegram-base.c:request_code()
|
||||
if (gc_get_conn (gc)->in_fallback_chat) {
|
||||
|
||||
// workaround to support clients without the request API (request.h), see tgp-request.c:request_code()
|
||||
if (gc_get_conn (gc)->request_code_data) {
|
||||
|
||||
// OTR plugins may try to insert messages that don't contain the code
|
||||
if (tgp_startswith (message, "?OTR")) {
|
||||
info ("Fallback SMS auth, skipping OTR message: '%s'", message);
|
||||
return -1;
|
||||
info ("Fallback SMS auth, skipping OTR message: '%s'", message);
|
||||
return -1;
|
||||
}
|
||||
request_code_entered (gc_get_conn (gc)->TLS, message);
|
||||
gc_get_conn (gc)->in_fallback_chat = 0;
|
||||
struct request_values_data *data = gc_get_conn (gc)->request_code_data;
|
||||
data->callback (gc_get_conn(gc)->TLS, &message, data->arg);
|
||||
free (data);
|
||||
|
||||
gc_get_conn (gc)->request_code_data = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Make sure that we only send messages to an existing peer by
|
||||
searching it in the peer tree. This allows us to give immediate feedback
|
||||
by returning an error-code in case the peer doesn't exist
|
||||
Make sure that to only send messages to an existing peer by searching it in the peer tree, to give immediate
|
||||
feedback by returning an error-code in case the peer doesn't exist.
|
||||
*/
|
||||
tgl_peer_t *peer = tgp_blist_peer_find (gc_get_conn (gc)->TLS, who);
|
||||
if (peer) {
|
||||
|
@ -1002,4 +990,3 @@ static PurplePluginInfo plugin_info = {
|
|||
};
|
||||
|
||||
PURPLE_INIT_PLUGIN (telegram, tgprpl_init, plugin_info)
|
||||
|
||||
|
|
189
tgp-request.c
189
tgp-request.c
|
@ -31,97 +31,71 @@
|
|||
#include "telegram-base.h"
|
||||
#include "tgp-2prpl.h"
|
||||
#include "tgp-utils.h"
|
||||
#include "tgp-structs.h"
|
||||
|
||||
static void code_receive_result (struct tgl_state *TLS, void *extra, int success, struct tgl_user *U) {
|
||||
struct request_password_data *data = extra;
|
||||
if (success) {
|
||||
((void (*) (struct tgl_state *TLS)) data->callback) (TLS);
|
||||
} else {
|
||||
debug ("bad code, retrying...");
|
||||
request_code (TLS, data->callback);
|
||||
}
|
||||
free (data);
|
||||
}
|
||||
|
||||
void request_code_entered (gpointer extra, const gchar *code) {
|
||||
struct request_password_data *data = extra;
|
||||
connection_data *conn = data->TLS->ev_base;
|
||||
char const *username = purple_account_get_username (conn->pa);
|
||||
static void request_code_entered (struct request_values_data *data, const gchar *code) {
|
||||
char *stripped = g_strstrip (purple_markup_strip_html (code));
|
||||
debug ("sending code: '%s'\n", stripped);
|
||||
|
||||
tgl_do_send_code_result (data->TLS, username, (int)strlen (username), conn->hash, (int)strlen (conn->hash),
|
||||
stripped, (int)strlen (stripped), code_receive_result, data);
|
||||
data->callback (data->TLS, (const char **)&stripped, data->arg);
|
||||
g_free (stripped);
|
||||
}
|
||||
|
||||
static void request_code_canceled (gpointer extra) {
|
||||
struct request_password_data *data = extra;
|
||||
connection_data *conn = data->TLS->ev_base;
|
||||
|
||||
purple_connection_error_reason (conn->gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, "registration canceled");
|
||||
static void request_code_canceled (struct request_values_data *data) {
|
||||
purple_connection_error_reason (tg_get_conn (data->TLS), PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, "registration canceled");
|
||||
free (data);
|
||||
}
|
||||
|
||||
void request_code (struct tgl_state *TLS, void (*callback) (struct tgl_state *TLS)) {
|
||||
debug ("Client is not registered, registering...");
|
||||
connection_data *conn = TLS->ev_base;
|
||||
|
||||
struct request_password_data *data = malloc (sizeof(struct request_password_data));
|
||||
static void request_code (struct tgl_state *TLS, void (*callback) (struct tgl_state *TLS, const char *string[], void *arg),
|
||||
void *arg) {
|
||||
debug ("client is not registered, registering...");
|
||||
|
||||
struct request_values_data *data = malloc (sizeof(struct request_values_data));
|
||||
data->TLS = TLS;
|
||||
data->arg = conn;
|
||||
data->arg = arg;
|
||||
data->callback = callback;
|
||||
|
||||
if (purple_account_get_bool (tg_get_acc (TLS), "compat-verification", 0) ||
|
||||
! purple_request_input (conn->gc, _("Login code"), _("Enter login code"), _("Telegram wants to verify your "
|
||||
! purple_request_input (tg_get_conn (TLS), _("Login code"), _("Enter login code"), _("Telegram wants to verify your "
|
||||
"identity. Please enter the code that you have received via SMS."), NULL, 0, 0, _("the code"), _("OK"),
|
||||
G_CALLBACK(request_code_entered), _("Cancel"), G_CALLBACK(request_code_canceled), conn->pa, NULL, NULL, data)) {
|
||||
G_CALLBACK(request_code_entered), _("Cancel"), G_CALLBACK(request_code_canceled), tg_get_acc (TLS), NULL, NULL, data)) {
|
||||
|
||||
// purple request API is not available, so we create a new conversation (the Telegram system
|
||||
// account "7770000") to prompt the user for the code
|
||||
conn->in_fallback_chat = 1;
|
||||
purple_connection_set_state (conn->gc, PURPLE_CONNECTED);
|
||||
PurpleConversation *conv = purple_conversation_new (PURPLE_CONV_TYPE_IM, conn->pa, "777000");
|
||||
purple_conversation_write (conv, "777000", _("What is your SMS verification code?"),
|
||||
// the purple request API is not supported, create a new conversation (the Telegram system account "Telegram") to
|
||||
// prompt the user for the code.
|
||||
tg_get_data (TLS)->request_code_data = data;
|
||||
purple_connection_set_state (tg_get_conn (TLS), PURPLE_CONNECTED);
|
||||
PurpleConversation *conv = purple_conversation_new (PURPLE_CONV_TYPE_IM, tg_get_acc (TLS), "Telegram");
|
||||
purple_conversation_write (conv, "Telegram", _("What is your SMS verification code?"),
|
||||
PURPLE_MESSAGE_RECV | PURPLE_MESSAGE_SYSTEM, 0);
|
||||
free (data);
|
||||
}
|
||||
}
|
||||
|
||||
static void code_auth_receive_result (struct tgl_state *TLS, void *extra, int success, struct tgl_user *U) {
|
||||
if (! success) {
|
||||
debug ("Bad code...");
|
||||
request_name_and_code (TLS);
|
||||
static void request_name_and_code (struct tgl_state *TLS, void (*callback) (struct tgl_state *TLS, const char *string[], void *arg), void *arg);
|
||||
static void request_name_code_entered (struct request_values_data *data, PurpleRequestFields* fields) {
|
||||
char *names[] = {
|
||||
g_strstrip (g_strdup (purple_request_fields_get_string (fields, "first_name"))),
|
||||
g_strstrip (g_strdup (purple_request_fields_get_string (fields, "last_name"))),
|
||||
g_strstrip (g_strdup (purple_request_fields_get_string (fields, "code")))
|
||||
};
|
||||
|
||||
if (str_not_empty (names[0]) && str_not_empty (names[1]) && str_not_empty (names[2])) {
|
||||
data->callback (data->TLS, (const char **) names, data->arg);
|
||||
} else {
|
||||
telegram_export_authorization (TLS);
|
||||
request_name_and_code (data->TLS, data->callback, data->arg);
|
||||
}
|
||||
|
||||
int j;
|
||||
for (j = 0; j < 3; ++j) {
|
||||
g_free (names[j]);
|
||||
}
|
||||
free (data);
|
||||
}
|
||||
|
||||
void request_name_code_entered (PurpleConnection* gc, PurpleRequestFields* fields) {
|
||||
connection_data *conn = purple_connection_get_protocol_data (gc);
|
||||
struct tgl_state *TLS = conn->TLS;
|
||||
char const *username = purple_account_get_username (conn->pa);
|
||||
|
||||
char* first = g_strstrip (g_strdup (purple_request_fields_get_string (fields, "first_name")));
|
||||
char* last = g_strstrip (g_strdup (purple_request_fields_get_string (fields, "last_name")));
|
||||
char* code = g_strstrip (g_strdup (purple_request_fields_get_string (fields, "code")));
|
||||
if (!first || !last || !code) {
|
||||
request_name_and_code (TLS);
|
||||
return;
|
||||
}
|
||||
tgl_do_send_code_result_auth (TLS, username, (int)strlen(username), conn->hash,
|
||||
(int)strlen (conn->hash), code, (int)strlen (code), first,
|
||||
(int)strlen (first), last, (int)strlen (last),
|
||||
code_auth_receive_result, NULL);
|
||||
g_free (first);
|
||||
g_free (last);
|
||||
g_free (code);
|
||||
}
|
||||
static void request_name_and_code (struct tgl_state *TLS, void (*callback) (struct tgl_state *TLS, const char *string[], void *arg), void *arg) {
|
||||
debug ("phone is not registered, registering...");
|
||||
|
||||
void request_name_and_code (struct tgl_state *TLS) {
|
||||
debug ("Phone is not registered, registering...");
|
||||
|
||||
connection_data *conn = TLS->ev_base;
|
||||
struct request_values_data *data = talloc0 (sizeof (struct request_values_data));
|
||||
data->callback = callback;
|
||||
data->arg = arg;
|
||||
|
||||
PurpleRequestFields* fields = purple_request_fields_new ();
|
||||
PurpleRequestField* field = 0;
|
||||
|
@ -138,26 +112,25 @@ void request_name_and_code (struct tgl_state *TLS) {
|
|||
purple_request_field_group_add_field (group, field);
|
||||
purple_request_fields_add_group (fields, group);
|
||||
|
||||
if (!purple_request_fields (conn->gc, _("Register"), _("Please register your phone number."), NULL, fields, _("OK"),
|
||||
G_CALLBACK(request_name_code_entered), _("Cancel"), NULL, conn->pa, NULL, NULL, conn->gc)) {
|
||||
if (!purple_request_fields (tg_get_conn (TLS), _("Register"), _("Please register your phone number."), NULL, fields,
|
||||
_("OK"), G_CALLBACK(request_name_code_entered), _("Cancel"), NULL, tg_get_acc (TLS), NULL, NULL, data)) {
|
||||
// purple_request API not available
|
||||
const char *error = _("Phone number is not registered. Please register your phone on a different client.");
|
||||
purple_connection_error_reason (conn->gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, error);
|
||||
purple_connection_error_reason (tg_get_conn (data->TLS) , PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, error);
|
||||
purple_notify_error (_telegram_protocol, _("Not Registered"), _("Not Registered"), error);
|
||||
}
|
||||
}
|
||||
|
||||
static void request_password_entered (struct request_password_data *data, PurpleRequestFields* fields) {
|
||||
const char* pass = purple_request_fields_get_string (fields, "password");
|
||||
((void (*)(struct tgl_state *TLS, const char *string[], void *arg)) data->callback) (data->TLS, &pass, data->arg);
|
||||
static void request_password_entered (struct request_values_data *data, PurpleRequestFields* fields) {
|
||||
const char *pass = purple_request_fields_get_string (fields, "password");
|
||||
data->callback (data->TLS, &pass, data->arg);
|
||||
free (data);
|
||||
}
|
||||
|
||||
void request_password (struct tgl_state *TLS, void (*callback) (struct tgl_state *TLS, const char *string[], void *arg),
|
||||
void *arg) {
|
||||
void request_password (struct tgl_state *TLS, void (*callback) (struct tgl_state *TLS, const char *string[], void *arg), void *arg) {
|
||||
connection_data *conn = TLS->ev_base;
|
||||
|
||||
struct request_password_data *data = malloc (sizeof(struct request_password_data));
|
||||
struct request_values_data *data = malloc (sizeof(struct request_values_data));
|
||||
data->TLS = TLS;
|
||||
data->arg = arg;
|
||||
data->callback = callback;
|
||||
|
@ -180,11 +153,8 @@ void request_password (struct tgl_state *TLS, void (*callback) (struct tgl_state
|
|||
}
|
||||
}
|
||||
|
||||
static void accept_secret_chat_cb (gpointer _data, const gchar *code) {
|
||||
struct accept_secret_chat_data *data = _data;
|
||||
|
||||
static void accept_secret_chat_cb (struct accept_secret_chat_data *data, const gchar *code) {
|
||||
tgl_do_accept_encr_chat_request (data->TLS, data->U, write_secret_chat_gw, 0);
|
||||
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
|
@ -212,8 +182,7 @@ void request_accept_secret_chat (struct tgl_state *TLS, struct tgl_secret_chat *
|
|||
g_free (message);
|
||||
}
|
||||
|
||||
static void create_group_chat_cb (void *_data, PurpleRequestFields* fields) {
|
||||
struct accept_create_chat_data *data = _data;
|
||||
static void create_group_chat_cb (struct accept_create_chat_data *data, PurpleRequestFields* fields) {
|
||||
// FIXME: Oh god.
|
||||
const char *users[3] = {
|
||||
purple_request_fields_get_string (fields, "user1"),
|
||||
|
@ -233,9 +202,6 @@ static void cancel_group_chat_cb (gpointer data) {
|
|||
}
|
||||
|
||||
void request_choose_user (struct accept_create_chat_data *data) {
|
||||
struct tgl_state *TLS = data->TLS;
|
||||
connection_data *conn = TLS->ev_base;
|
||||
|
||||
// Telegram doesn't allow to create chats with only one user, so we need to force
|
||||
// the user to specify at least one other one.
|
||||
PurpleRequestFields* fields = purple_request_fields_new();
|
||||
|
@ -256,13 +222,11 @@ void request_choose_user (struct accept_create_chat_data *data) {
|
|||
purple_request_field_group_add_field (group, field);
|
||||
|
||||
purple_request_fields_add_group (fields, group);
|
||||
purple_request_fields (conn->gc, _("Create group chat"), _("Invite users"), NULL, fields, _("OK"),
|
||||
G_CALLBACK(create_group_chat_cb), _("Cancel"), G_CALLBACK(cancel_group_chat_cb), conn->pa, NULL, NULL, data);
|
||||
purple_request_fields (tg_get_conn (data->TLS), _("Create group chat"), _("Invite users"), NULL, fields, _("OK"),
|
||||
G_CALLBACK(create_group_chat_cb), _("Cancel"), G_CALLBACK(cancel_group_chat_cb), tg_get_acc (data->TLS), NULL, NULL, data);
|
||||
}
|
||||
|
||||
void request_create_chat (struct tgl_state *TLS, const char *subject) {
|
||||
connection_data *conn = TLS->ev_base;
|
||||
|
||||
struct accept_create_chat_data *data = malloc (sizeof (struct accept_create_chat_data));
|
||||
data->title = g_strdup (subject);
|
||||
data->TLS = TLS;
|
||||
|
@ -272,7 +236,52 @@ void request_create_chat (struct tgl_state *TLS, const char *subject) {
|
|||
// FIXME: This dialog is pointless. It only asks whether the user wants to create a new chat.
|
||||
// This should be merged with the next dialog.
|
||||
// TODO: This still displays "Cancel" and "Accept", no matter $LANG
|
||||
purple_request_accept_cancel (conn->gc, _("Create group chat"), title, secondary, 1, conn->pa, NULL,
|
||||
purple_request_accept_cancel (tg_get_conn (TLS), _("Create group chat"), title, secondary, 1, tg_get_acc (TLS), NULL,
|
||||
NULL, data, G_CALLBACK(request_choose_user), G_CALLBACK(cancel_group_chat_cb));
|
||||
g_free (secondary);
|
||||
}
|
||||
|
||||
void request_value (struct tgl_state *TLS, enum tgl_value_type type, const char *prompt, int num_values,
|
||||
void (*callback) (struct tgl_state *TLS, const char *string[], void *arg), void *arg) {
|
||||
|
||||
debug ("tgl requests user input, tgl_value_type: %d, prompt: %s, count: %d", type, prompt, num_values);
|
||||
switch (type) {
|
||||
case tgl_cur_password: {
|
||||
const char *P = purple_account_get_string (tg_get_acc (TLS), TGP_KEY_PASSWORD_TWO_FACTOR, NULL);
|
||||
if (str_not_empty (P)) {
|
||||
if (tg_get_data (TLS)->password_retries ++ < 1) {
|
||||
callback (TLS, &P, arg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
request_password (TLS, callback, arg);
|
||||
break;
|
||||
}
|
||||
|
||||
case tgl_register_info:
|
||||
request_name_and_code (TLS, callback, arg);
|
||||
break;
|
||||
|
||||
case tgl_code:
|
||||
request_code (TLS, callback, arg);
|
||||
break;
|
||||
|
||||
case tgl_phone_number: {
|
||||
// if we arrive here for the second time the specified phone number is not valid. We do not
|
||||
// ask for the phone number directly, cause in that case the account would still be created
|
||||
// named with the invalid phone number, even though the login will work
|
||||
tgp_error_if_false (TLS, tg_get_data(TLS)->login_retries++ < 1, _("Invalid phone number"),
|
||||
_("Please enter only numbers in the international phone number format, "
|
||||
"a leading + following by the country prefix and the phone number.\n"
|
||||
"Do not use any other special chars."));
|
||||
|
||||
const char *username = purple_account_get_username (tg_get_acc (TLS));
|
||||
callback (TLS, &username, arg);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assert (FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,10 +26,11 @@
|
|||
|
||||
#include "tgp-structs.h"
|
||||
|
||||
struct request_password_data {
|
||||
struct request_values_data {
|
||||
struct tgl_state *TLS;
|
||||
void *callback;
|
||||
void (*callback) (struct tgl_state *TLS, const char *string[], void *arg);
|
||||
void *arg;
|
||||
const char *string[];
|
||||
};
|
||||
|
||||
struct accept_create_chat_data {
|
||||
|
@ -42,11 +43,8 @@ struct accept_secret_chat_data {
|
|||
struct tgl_secret_chat *U;
|
||||
};
|
||||
|
||||
void request_code (struct tgl_state *TLS, void (*callback) (struct tgl_state *TLS));
|
||||
void request_code_entered (gpointer extra, const gchar *code);
|
||||
void request_name_code_entered (PurpleConnection* gc, PurpleRequestFields* fields);
|
||||
void request_name_and_code (struct tgl_state *TLS);
|
||||
void request_password (struct tgl_state *TLS, void (*callback)(struct tgl_state *TLS, const char *string[], void *arg), void *arg);
|
||||
void request_value (struct tgl_state *TLS, enum tgl_value_type type, const char *prompt, int num_values,
|
||||
void (*callback) (struct tgl_state *TLS, const char *string[], void *arg), void *arg);
|
||||
void request_accept_secret_chat (struct tgl_state *TLS, struct tgl_secret_chat *U);
|
||||
void request_choose_user (struct accept_create_chat_data *data);
|
||||
void request_create_chat (struct tgl_state *TLS, const char *subject);
|
||||
|
|
|
@ -39,8 +39,9 @@ typedef struct {
|
|||
guint write_timer;
|
||||
guint login_timer;
|
||||
guint out_timer;
|
||||
int in_fallback_chat;
|
||||
struct request_values_data *request_code_data;
|
||||
int password_retries;
|
||||
int login_retries;
|
||||
PurpleRoomlist *roomlist;
|
||||
GHashTable *pending_chat_info;
|
||||
GHashTable *id_to_purple_name;
|
||||
|
@ -78,8 +79,6 @@ struct tgp_msg_sending {
|
|||
|
||||
void pending_reads_send_all (struct tgl_state *TLS);
|
||||
void pending_reads_add (GQueue *queue, tgl_peer_id_t id);
|
||||
struct message_text *message_text_init (struct tgl_message *M, gchar *text);
|
||||
void message_text_free (gpointer data);
|
||||
void used_images_add (connection_data *data, gint imgid);
|
||||
void *connection_data_free (connection_data *conn);
|
||||
connection_data *connection_data_init (struct tgl_state *TLS, PurpleConnection *gc, PurpleAccount *pa);
|
||||
|
|
Loading…
Add table
Reference in a new issue