From d9c56fe1c3b147aae1f0ea752645a9488cc9f87b Mon Sep 17 00:00:00 2001 From: "me@ow.nekobit.net" Date: Sat, 7 May 2022 22:35:49 +0000 Subject: [PATCH] Login oauth form FossilOrigin-Name: e7f0102304e89879e9f7c633ed8947b05fa66af849b46b89a54b2c83d22cba83 --- src/login.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++----- src/login.h | 1 + src/main.c | 3 +- src/query.c | 5 ++-- src/query.h | 2 ++ 5 files changed, 82 insertions(+), 11 deletions(-) diff --git a/src/login.c b/src/login.c index dfc0f6b..9e3ddb1 100644 --- a/src/login.c +++ b/src/login.c @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +#include #include #include #include @@ -30,6 +31,77 @@ // Files #include "../static/login.chtml" +void apply_access_token(char* token) +{ + printf("Set-Cookie: access_token=%s; Path=/; Max-Age=31536000\r\n", token); + printf("Set-Cookie: logged_in=t; Path=/; Max-Age=31536000\r\n"); + // if config_url_prefix is empty, make it root + redirect(REDIRECT_303, config_url_prefix && + config_url_prefix[0] != '\0' ? config_url_prefix : "/"); +} + +void content_login_oauth(struct session* ssn, mastodont_t* api, char** data) +{ + struct mstdnt_storage storage = { 0 }, oauth_storage = { 0 }; + struct mstdnt_app app; + struct mstdnt_oauth_token token; + char* orig_url = api->url; + char* redirect_url = getenv("SERVER_NAME"); + char* decode_url = NULL; + char* urlify_redirect_url = NULL; + + if (ssn->query.code) + { + apply_access_token(ssn->query.code); + } + else if (ssn->post.instance) + { + decode_url = curl_easy_unescape(api->curl, ssn->post.instance, 0, NULL); + easprintf(&urlify_redirect_url, "https://%s/login/oauth", redirect_url ); + api->url = decode_url; + + struct mstdnt_args args_app = { + .client_name = "Treebird", + .redirect_uris = urlify_redirect_url, + .scopes = "read+write+follow+push", + .website = ssn->post.instance + }; + + if (mastodont_register_app(api, &args_app, &storage, &app) == 0) + { + struct mstdnt_args args_token = { + .grant_type = "password", + .client_id = app.client_id, + .client_secret = app.client_secret, + .redirect_uri = NULL, + .scope = NULL, + .code = NULL, + .username = ssn->post.username, + .password = ssn->post.password + }; + + char* url; + char* encode_id = curl_easy_escape(api->curl, app.client_id, 0); + easprintf(&url, "%s/oauth/authorize?response_type=code&client_id=%s&redirect_uri=%s", + decode_url, encode_id, urlify_redirect_url); + + // Set cookie and redirect + printf("Set-Cookie: instance_url=%s; Path=/; Max-Age=3153600\r\n", decode_url); + + redirect(REDIRECT_303, url); + free(url); + curl_free(encode_id); + } + } + + api->url = orig_url; + + mastodont_storage_cleanup(&storage); + mastodont_storage_cleanup(&oauth_storage); + if (urlify_redirect_url) free(urlify_redirect_url); + if (decode_url) curl_free(decode_url); +} + void content_login(struct session* ssn, mastodont_t* api, char** data) { struct mstdnt_storage storage = { 0 }, oauth_store = { 0 }; @@ -42,7 +114,7 @@ void content_login(struct session* ssn, mastodont_t* api, char** data) { // Getting the client id/secret struct mstdnt_args args_app = { - .client_name = "treebird", + .client_name = "Treebird", .redirect_uris = "http://localhost/", .scopes = "read+write+follow+push", .website = NULL @@ -93,12 +165,8 @@ void content_login(struct session* ssn, mastodont_t* api, char** data) else // Clear printf("Set-Cookie: instance_url=; Path=/; Max-Age=-1\r\n"); - printf("Set-Cookie: access_token=%s; Path=/; Max-Age=31536000\r\n", token.access_token); - printf("Set-Cookie: logged_in=t; Path=/; Max-Age=31536000\r\n"); - // if config_url_prefix is empty, make it root - redirect(REDIRECT_303, config_url_prefix ? - (config_url_prefix[0] == '\0' ? - "/" : config_url_prefix) : "/"); + + apply_access_token(token.access_token); if (url_link) free(url_link); return; } diff --git a/src/login.h b/src/login.h index 6a04b4d..c7a8ffb 100644 --- a/src/login.h +++ b/src/login.h @@ -22,6 +22,7 @@ #include #include "session.h" +void content_login_oauth(struct session* ssn, mastodont_t* api, char** data); void content_login(struct session* ssn, mastodont_t* api, char** data); #endif // LOGIN_H diff --git a/src/main.c b/src/main.c index b3864af..dc9ba80 100644 --- a/src/main.c +++ b/src/main.c @@ -80,8 +80,9 @@ int main(void) struct path_info paths[] = { { "/config/general", content_config_general }, { "/config/appearance", content_config_appearance }, - { "/config", content_config }, /* { "/config/account", content_config_account }, */ + { "/config", content_config }, + { "/login/oauth", content_login_oauth }, { "/login", content_login }, { "/test", content_test }, { "/user/:/action/:", content_account_action }, diff --git a/src/query.c b/src/query.c index ab5d5df..d563f0d 100644 --- a/src/query.c +++ b/src/query.c @@ -34,6 +34,7 @@ char* read_query_data(struct get_values* query) struct key_value_refs refs[] = { { "offset", &(query->offset), key_string }, { "q", &(query->query), key_string }, + { "code", &(query->code), key_string }, }; // END Query references @@ -85,9 +86,6 @@ void key_files(char* val, struct form_props* form, void* arg) arr->content[arr->array_size-1].content_size = form->data_size; arr->content[arr->array_size-1].filename = form->filename; arr->content[arr->array_size-1].filetype = form->filetype; - - return; - } char* read_post_data(struct query_values* post) @@ -116,6 +114,7 @@ char* read_post_data(struct query_values* post) { "min_id", &(post->min_id), key_string }, { "max_id", &(post->max_id), key_string }, { "start_id", &(post->start_id), key_string }, + { "instance", &(post->instance), key_string }, { "visibility", &(post->visibility), key_string }, { "file", &(post->files), key_files } }; diff --git a/src/query.h b/src/query.h index b575e89..09d2865 100644 --- a/src/query.h +++ b/src/query.h @@ -58,6 +58,7 @@ struct query_values char* password; char* replyid; char* visibility; + char* instance; // Navigation char* min_id; @@ -71,6 +72,7 @@ struct get_values { char* offset; char* query; + char* code; }; void key_files(char* val, struct form_props* form, void* arg);