diff options
author | nirav <nirav@teisuu.com> | 2019-03-09 11:03:43 +0530 |
---|---|---|
committer | Dandelion <nirav@teisuu.com> | 2019-03-09 11:03:43 +0530 |
commit | c14d6af39dbf2353134ba8c99ce95a52207a2b45 (patch) | |
tree | 93da586386fccd29a8dcf49df0b5f4ebfd915a5d | |
parent | 77a9d0050c16ffd6c4d3a2b17533954d560bb019 (diff) | |
download | ap_client-c14d6af39dbf2353134ba8c99ce95a52207a2b45.tar.gz ap_client-c14d6af39dbf2353134ba8c99ce95a52207a2b45.zip |
Add login
-rw-r--r-- | src/auth.c | 268 | ||||
-rw-r--r-- | src/auth.h | 10 | ||||
-rw-r--r-- | src/http.c | 19 | ||||
-rw-r--r-- | src/main.c | 41 | ||||
-rw-r--r-- | src/status.c | 2 |
5 files changed, 283 insertions, 57 deletions
@@ -1,6 +1,8 @@ #define _POSIX_C_SOURCE 200809L #include <err.h> #include <string.h> +#include <pthread.h> +#include <stdbool.h> #include <jansson.h> #include "string-util.h" #include "auth.h" @@ -8,64 +10,111 @@ #define CLIENT_NAME "ap_client" -char *instance_domain; -char *auth_token; -char *req_data; -char *client_id; -char *client_secret; +char *instance_domain = NULL; +char *client_id = NULL; +char *client_secret = NULL; +char *access_token = NULL; +char *scope = NULL; static char *protocol = "https://"; static char *app_register_url = "/api/v1/apps"; +static char *login_url = "/oauth/token"; -static void register_callback(char *data) +struct register_call_arg { + char *url; + char *domain; + char *post_data; + void (*callback)(bool); +}; + +static void *register_call(void *req_arg) { - if (req_data) - free(req_data); - if (!data) { - fprintf(stderr, "register_callback(): null data\n"); - return; + struct register_call_arg *arg = NULL; + char *resp = NULL; + json_t *root = NULL; + + arg = (struct register_call_arg *)req_arg; + if (!arg || !(arg->url)) { + fprintf(stderr, "register_call(): invalid arguments\n"); + goto error; } - json_t *root; - root = json_loads(data, 0, NULL); - free(data); + resp = post_request(arg->url, arg->post_data); + if (!resp) { + fprintf(stderr, "register_call(): failed to send http request\n"); + goto error; + } + + if (!resp) { + fprintf(stderr, "register_call(): null response\n"); + goto error; + } + + root = json_loads(resp, 0, NULL); if (!root) { - fprintf(stderr, "register_callback(): failed to parse json\n"); - return; + fprintf(stderr, "register_call(): failed to parse json\n"); + goto error; } if (!json_is_object(root)) { - fprintf(stderr, "register_callback(): json root is not object\n"); - json_decref(root); - return; + fprintf(stderr, "register_call(): json root is not object\n"); + goto error; } json_t *cid = json_object_get(root, "client_id"); json_t *csec = json_object_get(root, "client_secret"); if (!json_is_string(cid) || !json_is_string(csec)) { fprintf(stderr, - "register_callback(): invalid client_id or client_secret\n"); - json_decref(root); - return; + "register_call(): invalid client_id or client_secret\n"); + goto error; } client_id = strdup(json_string_value(cid)); client_secret = strdup(json_string_value(csec)); - json_decref(root); + instance_domain = arg->domain; if (strlen(client_id) < 1 || strlen(client_secret) < 1) { fprintf(stderr, - "register_callback(): invalid client_id or client_secret\n"); - return; + "register_call(): invalid client_id or client_secret\n"); + goto error; } - printf("cid: %s\ncsec: %s\n", client_id, client_secret); + free(arg->url); + if (arg->post_data) + free(arg->post_data); + free(arg); + free(resp); + json_decref(root); + (*(arg->callback))(true); + return NULL; + +error: + if (arg) { + if (arg->url) + free(arg->url); + if (arg->post_data) + free(arg->post_data); + free(arg); + } + if (resp) + free(resp); + if (root) + json_decref(root); + (*(arg->callback))(false); + return NULL; } -int register_app(char *instance) +int register_app(const char *instance, void (*callback)(bool success)) { + if (!instance || strlen(instance) < 1 || !callback) { + fprintf(stderr, "register_app(): invalid argument\n"); + return -1; + } + json_t *root; json_error_t error; - char *url; + pthread_t t; + char *url, *req_data; + struct register_call_arg *arg; root = json_pack_ex(&error, 1, "{s:s, s:s, s:s}", "client_name", CLIENT_NAME, "redirect_uris", "urn:ietf:wg:oauth:2.0:oob", "scopes", @@ -88,16 +137,165 @@ int register_app(char *instance) strlen(protocol) + strlen(instance) + strlen(app_register_url) + 1; url = malloc(s); if (!url) { - err(1, "register_app(): "); + err(1, "register_app(): malloc failed"); + return -1; } sprintf(url, "%s%s%s", protocol, instance, app_register_url); - if (http_post_async(url, req_data, ®ister_callback)) { - fprintf(stderr, "register_app(): failed to send http request\n"); - free(req_data); + + arg = calloc(1, sizeof(struct register_call_arg)); + if (!arg) { + err(1, "register_app(): calloc failed"); + return -1; + } + arg->url = url; + arg->domain = strdup(instance); + arg->post_data = req_data; + arg->callback = callback; + + return pthread_create(&t, NULL, ®ister_call, arg); +} + +struct login_call_arg { + char *url; + char *post_data; + void (*callback)(bool); +}; + +static void *login_call(void *req_arg) +{ + struct login_call_arg *arg = NULL; + char *resp = NULL; + json_t *root = NULL; + + arg = (struct login_call_arg *)req_arg; + if (!arg || !(arg->url)) { + fprintf(stderr, "login_call(): invalid arguments\n"); + goto error; + } + + resp = post_request(arg->url, arg->post_data); + if (!resp) { + fprintf(stderr, "login_call(): failed to send http request\n"); + goto error; + } + + if (!resp) { + fprintf(stderr, "login_call(): null response\n"); + goto error; + } + + root = json_loads(resp, 0, NULL); + if (!root) { + fprintf(stderr, "login_call(): failed to parse json\n"); + goto error; + } + + if (!json_is_object(root)) { + fprintf(stderr, "login_call(): json root is not object\n"); + goto error; + } + + json_t *access_token_j = json_object_get(root, "access_token"); + json_t *scope_j = json_object_get(root, "scope"); + if (!json_is_string(access_token_j) || !json_is_string(scope_j) || + strlen(json_string_value(access_token_j)) < 1 || + strlen(json_string_value(scope_j)) < 1) { + fprintf(stderr, "login_call(): invalid access_token or scope\n"); + goto error; + } + + access_token = strdup(json_string_value(access_token_j)); + scope = strdup(json_string_value(scope_j)); + + free(arg->url); + if (arg->post_data) + free(arg->post_data); + free(arg); + free(resp); + json_decref(root); + (*(arg->callback))(true); + + printf("access_token: %s\n", access_token); + return NULL; + +error: + if (arg) { + if (arg->url) + free(arg->url); + if (arg->post_data) + free(arg->post_data); + free(arg); + } + if (resp) + free(resp); + if (root) + json_decref(root); + (*(arg->callback))(false); + return NULL; +} + +int login( + const char *email, const char *password, void (*callback)(bool success)) +{ + if (!email || strlen(email) < 1 || !password || strlen(password) < 1) { + fprintf(stderr, "login(): invalid argument\n"); + return -1; + } + + if (!client_id || strlen(client_id) < 1 || !client_secret || + strlen(client_secret) < 1 || !instance_domain || + strlen(instance_domain) < 1) { + fprintf(stderr, "login(): invalid client_id or client_secret\n"); + printf("cid: %s\n", client_id); + printf("csec: %s\n", client_secret); + printf("in: %s\n", instance_domain); + return -1; + } + + json_t *root; + json_error_t error; + pthread_t t; + char *url, *req_data; + struct login_call_arg *arg; + + root = json_pack_ex(&error, 1, "{s:s, s:s, s:s, s:s, s:s}", "client_id", client_id, + "client_secret", client_secret, "grant_type", "password", + "username", email, "password", password); + + if (!root) { + fprintf(stderr, "login(): json pack error: line %d: %s\n", error.line, + error.text); + return -1; + } + + req_data = json_dumps(root, 0); + json_decref(root); + if (!req_data) { + fprintf(stderr, "login(): failed to dump json\n"); + return -1; + } + + size_t s = strlen(protocol) + strlen(instance_domain) + + strlen(login_url) + 1; + url = malloc(s); + if (!url) { + err(1, "login(): malloc failed"); + return -1; + } + + sprintf(url, "%s%s%s", protocol, instance_domain, login_url); + + arg = calloc(1, sizeof(struct login_call_arg)); + if (!arg) { + err(1, "login(): calloc failed"); return -1; } + arg->url = url; + arg->post_data = req_data; + arg->callback = callback; + return pthread_create(&t, NULL, &login_call, arg); return 0; } @@ -105,10 +303,8 @@ void auth_cleanup() { if (instance_domain) free(instance_domain); - if (auth_token) - free(auth_token); - if (req_data) - free(req_data); + if (access_token) + free(access_token); if (client_id) free(client_id); if (client_secret) @@ -1,10 +1,16 @@ #ifndef __AUTH_H #define __AUTH_H +#include <stdbool.h> + extern char *instance_domain; -extern char *auth_token; +extern char *client_id; +extern char *client_secret; +extern char *access_token; +extern char *scope; -int register_app(char *instance); +int register_app(const char *instance, void (*callback) (bool success)); +int login(const char *email, const char *password, void (*callback) (bool success)); void auth_cleanup(); #endif @@ -60,12 +60,12 @@ char *get_request(const char *url) struct write_result write_result = {.data = data, .pos = 0}; - if (auth_token) { + if (access_token) { char *auth_header_val = - malloc(strlen(AUTH_HEADER_STR_PREFIX) + strlen(auth_token) + 1); + malloc(strlen(AUTH_HEADER_STR_PREFIX) + strlen(access_token) + 1); strlcpy(auth_header_val, AUTH_HEADER_STR_PREFIX, sizeof(auth_header_val)); - strlcat(auth_header_val, auth_token, sizeof(auth_header_val)); + strlcat(auth_header_val, access_token, sizeof(auth_header_val)); headers = curl_slist_append(headers, auth_header_val); } @@ -121,12 +121,12 @@ char *post_request(const char *url, char *post_data) struct write_result write_result = {.data = data, .pos = 0}; - if (auth_token) { + if (access_token) { char *auth_header_val = - malloc(strlen(AUTH_HEADER_STR_PREFIX) + strlen(auth_token) + 1); + malloc(strlen(AUTH_HEADER_STR_PREFIX) + strlen(access_token) + 1); strlcpy(auth_header_val, AUTH_HEADER_STR_PREFIX, sizeof(auth_header_val)); - strlcat(auth_header_val, auth_token, sizeof(auth_header_val)); + strlcat(auth_header_val, access_token, sizeof(auth_header_val)); headers = curl_slist_append(headers, auth_header_val); } if (post_data) { @@ -195,12 +195,12 @@ void *post_one_url(void *arg) struct write_result write_result = {.data = data, .pos = 0}; - if (auth_token) { + if (access_token) { char *auth_header_val = - malloc(strlen(AUTH_HEADER_STR_PREFIX) + strlen(auth_token) + 1); + malloc(strlen(AUTH_HEADER_STR_PREFIX) + strlen(access_token) + 1); strlcpy(auth_header_val, AUTH_HEADER_STR_PREFIX, sizeof(auth_header_val)); - strlcat(auth_header_val, auth_token, sizeof(auth_header_val)); + strlcat(auth_header_val, access_token, sizeof(auth_header_val)); headers = curl_slist_append(headers, auth_header_val); } if (req_args->post_data) { @@ -221,6 +221,7 @@ void *post_one_url(void *arg) goto error; } + fprintf(stderr, "http method: POST, url: %s, res: %s\n", req_args->url, data); curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code); if (code != 200) { fprintf(stderr, "post_request(): server responded with code %ld\n", code); @@ -2,6 +2,7 @@ #include <err.h> #include <stdio.h> #include <stdlib.h> +#include <stdbool.h> #include <gtk-3.0/gtk/gtk.h> #include "auth.h" #include "http.h" @@ -13,18 +14,40 @@ static GtkWidget *box; static GtkWidget *instance_name_box, *email_box, *password_box; static GtkWidget *submit_button; -static void submit_login_form() +static void login_callback(bool success) { - const char *instance_name, *email, *password; - instance_name = gtk_entry_get_text(GTK_ENTRY(instance_name_box)); + if (!success) { + fprintf(stderr, "login_callback(): login failed\n"); + return; + } + + printf("login success\n"); +} + +static void register_callback(bool success) +{ + if (!success) { + fprintf(stderr, "register_callback(): register failed\n"); + return; + } + printf("register success\n"); + + const char *email, *password; email = gtk_entry_get_text(GTK_ENTRY(email_box)); password = gtk_entry_get_text(GTK_ENTRY(password_box)); - g_print("\n%s\n%s\n%s\n", instance_name, email, password); - char *in = strdup(instance_name); - int ok; - ok = register_app(in); - fprintf(stderr, "submit_login_form(): return val %d\n", ok); - free(in); + + if(login(email, password, &login_callback)) { + return; + } +} + +static void submit_login_form() +{ + const char *instance_name; + instance_name = gtk_entry_get_text(GTK_ENTRY(instance_name_box)); + if(register_app(instance_name, ®ister_callback)) { + return; + } } static void submit_button_clicked(GtkButton *button, gpointer user_data) diff --git a/src/status.c b/src/status.c index f96267f..36cd865 100644 --- a/src/status.c +++ b/src/status.c @@ -103,7 +103,7 @@ void status_free(struct status *s) free(s->uri); if (s->url) free(s->url); - if (s->in_reply_to_id != NULL) + if (s->in_reply_to_id) free(s->in_reply_to_id); if (s->in_reply_to_account_id) free(s->in_reply_to_account_id); |