summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornirav <nirav@teisuu.com>2019-03-09 11:03:43 +0530
committerDandelion <nirav@teisuu.com>2019-03-09 11:03:43 +0530
commitc14d6af39dbf2353134ba8c99ce95a52207a2b45 (patch)
tree93da586386fccd29a8dcf49df0b5f4ebfd915a5d
parent77a9d0050c16ffd6c4d3a2b17533954d560bb019 (diff)
downloadap_client-c14d6af39dbf2353134ba8c99ce95a52207a2b45.tar.gz
ap_client-c14d6af39dbf2353134ba8c99ce95a52207a2b45.zip
Add login
-rw-r--r--src/auth.c268
-rw-r--r--src/auth.h10
-rw-r--r--src/http.c19
-rw-r--r--src/main.c41
-rw-r--r--src/status.c2
5 files changed, 283 insertions, 57 deletions
diff --git a/src/auth.c b/src/auth.c
index 901a863..a2e8519 100644
--- a/src/auth.c
+++ b/src/auth.c
@@ -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, &register_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, &register_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)
diff --git a/src/auth.h b/src/auth.h
index e5e597c..e6691dd 100644
--- a/src/auth.h
+++ b/src/auth.h
@@ -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
diff --git a/src/http.c b/src/http.c
index a865f96..4c9f9dc 100644
--- a/src/http.c
+++ b/src/http.c
@@ -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);
diff --git a/src/main.c b/src/main.c
index 3db9eb6..abf6ba0 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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, &register_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);