aboutsummaryrefslogtreecommitdiffstats
path: root/src/login.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/login.c')
-rw-r--r--src/login.c162
1 files changed, 103 insertions, 59 deletions
diff --git a/src/login.c b/src/login.c
index 9829d75..67b6b22 100644
--- a/src/login.c
+++ b/src/login.c
@@ -25,50 +25,25 @@
#include "asprintf.h"
#include "util.h"
-void
-store_config(const char *instance,
- const char *client_id,
- const char *client_secret,
- const char *access_token)
-{
- FILE *fp = fopen(".demiurgerc", "w+");
-
- fprintf(fp, "%s=%s\n", "instance", instance);
- fprintf(fp, "%s=%s\n", "client_id", client_id);
- fprintf(fp, "%s=%s\n", "client_secret", client_secret);
- fprintf(fp, "%s=%s\n", "access_token", access_token);
- fclose(fp);
-}
-
/* I am confident to present you, without a doubt, the worst code i've
* ever written */
-int
-setup()
+static int
+get_client_id(struct config *config)
{
- char *instance = NULL;
- instance =
- readline("Enter your instance (e.g. https://social.fnord.tld) ");
-
char *api_url = "/api/v1/apps";
CURL *curl = curl_easy_init();
- struct json_object *parsed_json;
- struct json_object *json_client_id;
- struct json_object *json_client_secret;
- struct json_object *json_access_token;
-
if(curl == NULL) {
fprintf(stderr, "Error creating curl (what?)\n");
return -1;
}
-
- char *post_url = NULL;
struct memory chunk = {0};
- dm_asprintf(&post_url, "%s%s", instance, api_url);
+ char *post_url = NULL;
+ dm_asprintf(&post_url, "%s%s", config->instance, api_url);
curl_easy_setopt(curl, CURLOPT_URL, post_url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
@@ -78,53 +53,86 @@ setup()
* to do this */
curl_easy_setopt(curl,
- CURLOPT_POSTFIELDS,
- "client_name=demiurge&redirect_uris=urn:ietf:wg:oauth:2."
- "0:oob&scope=read+write+follow");
+ CURLOPT_POSTFIELDS,
+ "client_name=demiurge"
+ "&redirect_uris=urn:ietf:wg:oauth:2.0:oob"
+ "&scope=read+write+follow"
+ "&website=https://example.org");
curl_easy_perform(curl);
curl_easy_cleanup(curl);
+ free(post_url);
+
+ struct json_object *parsed_json;
+ struct json_object *json_client_id;
+ struct json_object *json_client_secret;
parsed_json = json_tokener_parse(chunk.response);
if(parsed_json == NULL) {
fprintf(stderr, "error\n");
+ free_response(&chunk);
return -1;
}
json_object_object_get_ex(parsed_json, "client_id", &json_client_id);
- json_object_object_get_ex(
- parsed_json, "client_secret", &json_client_secret);
+ json_object_object_get_ex(parsed_json, "client_secret", &json_client_secret);
+
const char *client_id = json_object_get_string(json_client_id);
const char *client_secret = json_object_get_string(json_client_secret);
+ int ret;
+
+ if(!client_id || !client_secret) {
+ eputs("Can't get client_id or client_secret");
+ ret = -1;
+ } else {
+ dm_strncpy(config->client_id, client_id, sizeof(config->client_id));
+ dm_strncpy(config->client_secret, client_secret, sizeof(config->client_secret));
+ ret = 0;
+ }
- char *fmt = "%s%sresonse_type=code&client_id=%s&redirect_uri=urn:ietf:wg:"
- "oauth:2.0:oob&force_login&scope=read+write+follow";
- api_url = "/oauth/authorize?";
-
- free(post_url);
-
- post_url = NULL;
+ free_response(&chunk);
+ return ret;
+}
- dm_asprintf(&post_url, fmt, instance, api_url, client_id);
- puts(post_url);
+static char *
+ask_for_token(struct config *config)
+{
+ const char *api_url = "/oauth/authorize?";
+ char *fmt = "%s%s"
+ "client_id=%s"
+ "&redirect_uri=urn:ietf:wg:oauth:2.0:oob"
+ "&response_type=code"
+ "&scope=read+write+follow\n";
- curl = curl_easy_init();
+ printf(fmt, config->instance, api_url, config->client_id);
- char *code = NULL;
- code = readline("Please log in in that url and paste the code here: ");
+ return readline("Please log in in that url and paste the code here: ");
+}
- char *access_token_fmt =
- "client_id=%s&client_secret=%s&redirect_uri=urn:ietf:wg:oauth:2.0:"
- "oob&grant_type=authorization_code&code=%s&scope=read+write+follow";
- api_url = "/oauth/token";
+static int
+get_token(struct config *config, const char *code)
+{
+ char *fmt =
+ "client_id=%s"
+ "&client_secret=%s"
+ "&redirect_uri=urn:ietf:wg:oauth:2.0:oob"
+ "&code=%s"
+ "&grant_type=authorization_code"
+ "&scope=read+write+follow";
+ const char *api_url = "/oauth/token";
- char *post_token_url = NULL;
+ CURL *curl = curl_easy_init();
+ if(curl == NULL) {
+ fprintf(stderr, "Error creating curl (what?)\n");
+ return -1;
+ }
- dm_asprintf(
- &post_token_url, access_token_fmt, client_id, client_secret, code);
+ struct memory chunk = {0};
- post_url = NULL;
+ char *post_token_url;
+ char *post_url;
- dm_asprintf(&post_url, "%s%s", instance, api_url);
+ dm_asprintf(&post_token_url, fmt, config->client_id, config->client_secret, code);
+ dm_asprintf(&post_url, "%s%s", config->instance, api_url);
curl_easy_setopt(curl, CURLOPT_URL, post_url);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_token_url);
@@ -132,15 +140,51 @@ setup()
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
curl_easy_perform(curl);
+ curl_easy_cleanup(curl);
+ free(post_token_url);
+ free(post_url);
+ struct json_object *parsed_json;
+ struct json_object *json_access_token;
+
parsed_json = json_tokener_parse(chunk.response);
json_object_object_get_ex(parsed_json, "access_token", &json_access_token);
const char *access_token = json_object_get_string(json_access_token);
- store_config(instance, client_id, client_secret, access_token);
+ int ret;
+ if(!access_token) {
+ eputs("Can't get access_token");
+ ret = -1;
+ } else {
+ dm_strncpy(config->access_token, access_token, sizeof(config->access_token));
+ ret = 0;
+ }
+
+ free_response(&chunk);
+
+ return ret;
+}
+
+int
+setup()
+{
+ struct config config;
+
+ dm_strncpy(config.instance, readline("Enter your instance (e.g. https://social.fnord.tld) "),
+ sizeof(config.instance));
+
+ if(get_client_id(&config) < 0)
+ return -1;
+
+ char *code = ask_for_token(&config);
+
+ if(get_token(&config, code) < 0)
+ {
+ free(code);
+ return -1;
+ }
+
+ store_config(&config);
free(code);
- free(post_url);
- free(post_token_url);
- free(chunk.response);
return 0;
}