diff --git a/libdc/CMakeLists.txt b/libdc/CMakeLists.txt index 180e1f5..33514d0 100644 --- a/libdc/CMakeLists.txt +++ b/libdc/CMakeLists.txt @@ -11,12 +11,14 @@ SET(SOURCES "include/dc/account.h" "include/dc/api.h" "include/dc/apisync.h" + "include/dc/guild.h" "include/dc/loop.h" "include/dc/refable.h" "include/dc/util.h" "src/account.c" "src/api.c" "src/apisync.c" + "src/guild.c" "src/loop.c" "src/refable.c" "src/util.c" diff --git a/libdc/include/dc/account.h b/libdc/include/dc/account.h index adddef7..adbaa65 100644 --- a/libdc/include/dc/account.h +++ b/libdc/include/dc/account.h @@ -25,6 +25,8 @@ char const *dc_account_username(dc_account_t a); void dc_account_set_discriminator(dc_account_t a, char const *id); char const *dc_account_discriminator(dc_account_t a); +char const *dc_account_full_username(dc_account_t a); + void dc_account_set_token(dc_account_t a, char const *token); char const *dc_account_token(dc_account_t a); bool dc_account_has_token(dc_account_t a); diff --git a/libdc/include/dc/api.h b/libdc/include/dc/api.h index adc215f..6419cae 100644 --- a/libdc/include/dc/api.h +++ b/libdc/include/dc/api.h @@ -25,13 +25,30 @@ void dc_api_signal(dc_api_t api, CURL *easy, int code); /* internal curl stuff */ dc_api_sync_t dc_api_call(dc_api_t api, char const *token, - char const *method, json_t *j); + char const *verb, char const *method, + json_t *j); json_t *dc_api_call_sync(dc_api_t api, char const *token, - char const *method, json_t *j); + char const *verb, char const *method, + json_t *j); +/** + * Authenticate a given user account. The user account should have + * email, and password set. If the auth succeeds the account will have + * a login token, and will from now on be the "login account". You + * will have to pass that account to various other functions for + * authentication. + */ bool dc_api_authenticate(dc_api_t api, dc_account_t account); -bool dc_api_userinfo(dc_api_t api, dc_account_t logion, - dc_account_t user); +/** + * Retrieve basic user information for the given account. The first + * parameter is the user account holding login info, while the second + * is the account you wish to retrieve information about. + */ +bool dc_api_get_userinfo(dc_api_t api, dc_account_t login, + dc_account_t user); + +bool dc_api_get_userguilds(dc_api_t api, dc_account_t login, + GPtrArray *guilds); #endif diff --git a/libdc/include/dc/guild.h b/libdc/include/dc/guild.h new file mode 100644 index 0000000..97cdb04 --- /dev/null +++ b/libdc/include/dc/guild.h @@ -0,0 +1,17 @@ +#ifndef DC_GUILD_H +#define DC_GUILD_H + +/* Discords version of groups or chat servers + */ +struct dc_guild_; +typedef struct dc_guild_ *dc_guild_t; + +dc_guild_t dc_guild_new(void); + +char const *dc_guild_name(dc_guild_t d); +void dc_guild_set_name(dc_guild_t d, char const *val); + +char const *dc_guild_id(dc_guild_t d); +void dc_guild_set_id(dc_guild_t d, char const *val); + +#endif diff --git a/libdc/src/account.c b/libdc/src/account.c index 2402654..0aa9ece 100644 --- a/libdc/src/account.c +++ b/libdc/src/account.c @@ -38,6 +38,11 @@ static void dc_account_free(dc_account_t ptr) free(ptr->email); free(ptr->password); + free(ptr->id); + free(ptr->username); + free(ptr->discriminator); + free(ptr->full); + free(ptr->token); free(ptr); } diff --git a/libdc/src/api.c b/libdc/src/api.c index ea3def8..f0ae4f7 100644 --- a/libdc/src/api.c +++ b/libdc/src/api.c @@ -100,33 +100,15 @@ static int debug_callback(CURL *handle, curl_infotype type, } #endif -static int header_callback(char *data, size_t sz, size_t num, dc_api_t api) -{ - char *ptr = NULL; - - if ((ptr = strstr(data, "set-cookie")) != NULL) { - free(api->cookie); - api->cookie = NULL; - - if ((ptr = strstr(data, ":")) != NULL) { - api->cookie = strdup(ptr+1); - if ((ptr = strstr(api->cookie, ";")) != NULL) { - *ptr = '\0'; - } - } - } - - return sz * num; -} - -static dc_api_sync_t dc_api_post(dc_api_t api, - char const *url, - char const *token, - char const *data, int64_t len) +static dc_api_sync_t +dc_api_do(dc_api_t api, char const *verb, + char const *url, char const *token, + char const *data, int64_t len) { return_if_true(api == NULL, NULL); return_if_true(api->curl == NULL, NULL); return_if_true(url == NULL, NULL); + return_if_true(verb == NULL, NULL); CURL *c = NULL; bool ret = false; @@ -144,8 +126,6 @@ static dc_api_sync_t dc_api_post(dc_api_t api, curl_easy_setopt(c, CURLOPT_URL, url); curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, fwrite); curl_easy_setopt(c, CURLOPT_WRITEDATA, dc_api_sync_stream(sync)); - curl_easy_setopt(c, CURLOPT_HEADERFUNCTION, header_callback); - curl_easy_setopt(c, CURLOPT_HEADERDATA, api); if (api->cookie != NULL) { curl_easy_setopt(c, CURLOPT_COOKIE, api->cookie); @@ -177,15 +157,23 @@ static dc_api_sync_t dc_api_post(dc_api_t api, curl_easy_setopt(c, CURLOPT_DEBUGFUNCTION, debug_callback); #endif - if (data != NULL) { + if (strcmp(verb, "POST") == 0) { curl_easy_setopt(c, CURLOPT_POST, 1UL); curl_easy_setopt(c, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL); + } + + if (data != NULL) { curl_easy_setopt(c, CURLOPT_COPYPOSTFIELDS, data); if (len >= 0) { curl_easy_setopt(c, CURLOPT_POSTFIELDSIZE_LARGE, len); } } + if (strcmp(verb, "PUT") == 0 || + strcmp(verb, "DELETE") == 0) { + curl_easy_setopt(c, CURLOPT_CUSTOMREQUEST, verb); + } + if (curl_multi_add_handle(api->curl, c) != CURLM_OK) { goto cleanup; } @@ -206,7 +194,8 @@ cleanup: } dc_api_sync_t dc_api_call(dc_api_t api, char const *token, - char const *method, json_t *j) + char const *verb, char const *method, + json_t *j) { char *data = NULL; char *url = NULL; @@ -220,7 +209,7 @@ dc_api_sync_t dc_api_call(dc_api_t api, char const *token, goto_if_true(data == NULL, cleanup); } - s = dc_api_post(api, url, token, data, -1); + s = dc_api_do(api, verb, url, token, data, -1); goto_if_true(s == NULL, cleanup); cleanup: @@ -235,12 +224,13 @@ cleanup: } json_t *dc_api_call_sync(dc_api_t api, char const *token, - char const *method, json_t *j) + char const *verb, char const *method, + json_t *j) { dc_api_sync_t s = NULL; json_t *reply = NULL; - s = dc_api_call(api, token, method, j); + s = dc_api_call(api, verb, token, method, j); goto_if_true(s == NULL, cleanup); if (!dc_api_sync_wait(s)) { @@ -302,7 +292,7 @@ bool dc_api_authenticate(dc_api_t api, dc_account_t account) json_string(dc_account_password(account)) ); - reply = dc_api_call_sync(api, NULL, DISCORD_API_AUTH, j); + reply = dc_api_call_sync(api, "POST", NULL, DISCORD_API_AUTH, j); goto_if_true(reply == NULL, cleanup); if (dc_api_error(j, NULL, NULL)) { @@ -332,8 +322,8 @@ cleanup: return ret; } -bool dc_api_userinfo(dc_api_t api, dc_account_t login, - dc_account_t user) +bool dc_api_get_userinfo(dc_api_t api, dc_account_t login, + dc_account_t user) { char *url = NULL; json_t *reply = NULL, *val = NULL; @@ -345,7 +335,7 @@ bool dc_api_userinfo(dc_api_t api, dc_account_t login, asprintf(&url, "users/%s", dc_account_id(user)); - reply = dc_api_call_sync(api, dc_account_token(login), url, NULL); + reply = dc_api_call_sync(api, "GET", dc_account_token(login), url, NULL); goto_if_true(reply == NULL, cleanup); val = json_object_get(reply, "username"); @@ -371,3 +361,25 @@ cleanup: return ret; } + +bool dc_api_get_userguilds(dc_api_t api, dc_account_t login, + +{ + char *url = NULL; + json_t *reply = NULL, *val = NULL; + bool ret = false; + + return_if_true(api == NULL, false); + return_if_true(login == NULL, false); + return_if_true(user == NULL, false); + + asprintf(&url, "users/%s/guilds", dc_account_id(user)); + + reply = dc_api_call_sync(api, "GET", dc_account_token(login), url, NULL); + goto_if_true(reply == NULL, cleanup); + +cleanup: + + json_decref(reply); + return ret; +} diff --git a/libdc/src/guild.c b/libdc/src/guild.c new file mode 100644 index 0000000..16ca0a7 --- /dev/null +++ b/libdc/src/guild.c @@ -0,0 +1,56 @@ +#include +#include + +#include "internal.h" + +struct dc_guild_ +{ + dc_refable_t ref; + + char *name; + char *id; +}; + +static void dc_guild_free(dc_guild_t ptr) +{ + free(ptr->name); + free(ptr->id); + + free(ptr); +} + +dc_guild_t dc_guild_new(void) +{ + dc_guild_t p = calloc(1, sizeof(struct dc_guild_)); + return_if_true(p == NULL, NULL); + + p->ref.cleanup = (dc_cleanup_t)dc_guild_free; + + return p; +} + +char const *dc_guild_name(dc_guild_t d) +{ + return_if_true(d == NULL, NULL); + return d->name; +} + +void dc_guild_set_name(dc_guild_t d, char const *val) +{ + return_if_true(d == NULL || val == NULL,); + free(d->name); + d->name = strdup(val); +} + +char const *dc_guild_id(dc_guild_t d) +{ + return_if_true(d == NULL, NULL); + return d->id; +} + +void dc_guild_set_id(dc_guild_t d, char const *val) +{ + return_if_true(d == NULL || val == NULL,); + free(d->id); + d->id = strdup(val); +} diff --git a/libdc/src/internal.h b/libdc/src/internal.h index 4229468..3959aa9 100644 --- a/libdc/src/internal.h +++ b/libdc/src/internal.h @@ -23,7 +23,7 @@ #include -//#define DEBUG +#define DEBUG #define return_if_true(v,r) do { if (v) return r; } while(0) #define goto_if_true(v,l) do { if (v) goto l; } while(0)