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:
mjentsch 2015-11-15 14:04:00 +01:00
parent 6fce2cf8fa
commit f89f3fd71a
6 changed files with 157 additions and 262 deletions

View file

@ -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.
*/

View file

@ -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

View file

@ -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)

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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);