diff options
| author | 2023-04-09 20:34:05 +0200 | |
|---|---|---|
| committer | 2023-04-09 20:34:05 +0200 | |
| commit | 4ced03bac14b57504cf6d3ca4d4770efc25dbfad (patch) | |
| tree | ae55996e94cc4734a7a2146ae8930c7f87364997 /mastoapi.c | |
| parent | More mastoapi work. (diff) | |
| download | snac2-4ced03bac14b57504cf6d3ca4d4770efc25dbfad.tar.gz snac2-4ced03bac14b57504cf6d3ca4d4770efc25dbfad.tar.xz snac2-4ced03bac14b57504cf6d3ca4d4770efc25dbfad.zip | |
OAuth login now works.
Diffstat (limited to 'mastoapi.c')
| -rw-r--r-- | mastoapi.c | 109 |
1 files changed, 98 insertions, 11 deletions
| @@ -73,12 +73,14 @@ xs_dict *app_get(const char *id) | |||
| 73 | 73 | ||
| 74 | const char *login_page = "" | 74 | const char *login_page = "" |
| 75 | "<!DOCTYPE html>\n" | 75 | "<!DOCTYPE html>\n" |
| 76 | "<body><h1>%s identify</h1>\n" | 76 | "<body><h1>%s OAuth identify</h1>\n" |
| 77 | "<div style=\"background-color: red; color: white\">%s</div>\n" | ||
| 77 | "<form method=\"post\" action=\"https:/" "/%s/oauth/x-snac-login\">\n" | 78 | "<form method=\"post\" action=\"https:/" "/%s/oauth/x-snac-login\">\n" |
| 78 | "<p>Login: <input type=\"text\" name=\"login\"></p>\n" | 79 | "<p>Login: <input type=\"text\" name=\"login\"></p>\n" |
| 79 | "<p>Password: <input type=\"password\" name=\"passwd\"></p>\n" | 80 | "<p>Password: <input type=\"password\" name=\"passwd\"></p>\n" |
| 80 | "<input type=\"hidden\" name=\"redir\" value=\"%s\">\n" | 81 | "<input type=\"hidden\" name=\"redir\" value=\"%s\">\n" |
| 81 | "<input type=\"hidden\" name=\"cid\" value=\"%s\">\n" | 82 | "<input type=\"hidden\" name=\"cid\" value=\"%s\">\n" |
| 83 | "<input type=\"submit\" value=\"OK\">\n" | ||
| 82 | "</form><p>%s</p></body>\n" | 84 | "</form><p>%s</p></body>\n" |
| 83 | ""; | 85 | ""; |
| 84 | 86 | ||
| @@ -90,13 +92,15 @@ int oauth_get_handler(const xs_dict *req, const char *q_path, | |||
| 90 | 92 | ||
| 91 | { | 93 | { |
| 92 | xs *j = xs_json_dumps_pp(req, 4); | 94 | xs *j = xs_json_dumps_pp(req, 4); |
| 93 | printf("oauth:\n%s\n", j); | 95 | printf("oauth get:\n%s\n", j); |
| 94 | } | 96 | } |
| 95 | 97 | ||
| 96 | int status = 404; | 98 | int status = 404; |
| 97 | xs_dict *msg = xs_dict_get(req, "q_vars"); | 99 | xs_dict *msg = xs_dict_get(req, "q_vars"); |
| 98 | xs *cmd = xs_replace(q_path, "/oauth", ""); | 100 | xs *cmd = xs_replace(q_path, "/oauth", ""); |
| 99 | 101 | ||
| 102 | srv_debug(0, xs_fmt("oauth_get_handler %s", q_path)); | ||
| 103 | |||
| 100 | if (strcmp(cmd, "/authorize") == 0) { | 104 | if (strcmp(cmd, "/authorize") == 0) { |
| 101 | const char *cid = xs_dict_get(msg, "client_id"); | 105 | const char *cid = xs_dict_get(msg, "client_id"); |
| 102 | const char *ruri = xs_dict_get(msg, "redirect_uri"); | 106 | const char *ruri = xs_dict_get(msg, "redirect_uri"); |
| @@ -110,11 +114,17 @@ int oauth_get_handler(const xs_dict *req, const char *q_path, | |||
| 110 | if (app != NULL) { | 114 | if (app != NULL) { |
| 111 | const char *host = xs_dict_get(srv_config, "host"); | 115 | const char *host = xs_dict_get(srv_config, "host"); |
| 112 | 116 | ||
| 113 | *body = xs_fmt(login_page, host, host, ruri, cid, USER_AGENT); | 117 | *body = xs_fmt(login_page, host, "", host, ruri, cid, USER_AGENT); |
| 114 | *ctype = "text/html"; | 118 | *ctype = "text/html"; |
| 115 | status = 200; | 119 | status = 200; |
| 120 | |||
| 121 | srv_debug(0, xs_fmt("oauth authorize: generating login page")); | ||
| 116 | } | 122 | } |
| 123 | else | ||
| 124 | srv_debug(0, xs_fmt("oauth authorize: bad client_id %s", cid)); | ||
| 117 | } | 125 | } |
| 126 | else | ||
| 127 | srv_debug(0, xs_fmt("oauth authorize: invalid or unset arguments")); | ||
| 118 | } | 128 | } |
| 119 | 129 | ||
| 120 | return status; | 130 | return status; |
| @@ -122,25 +132,70 @@ int oauth_get_handler(const xs_dict *req, const char *q_path, | |||
| 122 | 132 | ||
| 123 | 133 | ||
| 124 | int oauth_post_handler(const xs_dict *req, const char *q_path, | 134 | int oauth_post_handler(const xs_dict *req, const char *q_path, |
| 125 | const char *payload, int p_size, | 135 | const char *payload, int p_size, |
| 126 | char **body, int *b_size, char **ctype) | 136 | char **body, int *b_size, char **ctype) |
| 127 | { | 137 | { |
| 128 | if (!xs_startswith(q_path, "/oauth/")) | 138 | if (!xs_startswith(q_path, "/oauth/")) |
| 129 | return 0; | 139 | return 0; |
| 130 | 140 | ||
| 141 | { | ||
| 142 | xs *j = xs_json_dumps_pp(req, 4); | ||
| 143 | printf("oauth post:\n%s\n", j); | ||
| 144 | } | ||
| 145 | |||
| 131 | int status = 404; | 146 | int status = 404; |
| 132 | xs_dict *msg = xs_dict_get(req, "p_vars"); | 147 | xs_dict *msg = xs_dict_get(req, "p_vars"); |
| 133 | xs *cmd = xs_replace(q_path, "/oauth", ""); | 148 | xs *cmd = xs_replace(q_path, "/oauth", ""); |
| 134 | 149 | ||
| 135 | printf("oauth: %s\n", q_path); | 150 | srv_debug(0, xs_fmt("oauth_post_handler %s", q_path)); |
| 151 | |||
| 152 | if (strcmp(cmd, "/x-snac-login") == 0) { | ||
| 153 | const char *login = xs_dict_get(msg, "login"); | ||
| 154 | const char *passwd = xs_dict_get(msg, "passwd"); | ||
| 155 | const char *redir = xs_dict_get(msg, "redir"); | ||
| 156 | const char *cid = xs_dict_get(msg, "cid"); | ||
| 157 | |||
| 158 | const char *host = xs_dict_get(srv_config, "host"); | ||
| 159 | |||
| 160 | /* by default, generate another login form with an error */ | ||
| 161 | *body = xs_fmt(login_page, host, "LOGIN INCORRECT", host, redir, cid, USER_AGENT); | ||
| 162 | *ctype = "text/html"; | ||
| 163 | status = 200; | ||
| 164 | |||
| 165 | if (login && passwd && redir && cid) { | ||
| 166 | snac snac; | ||
| 136 | 167 | ||
| 168 | if (user_open(&snac, login)) { | ||
| 169 | /* check the login + password */ | ||
| 170 | if (check_password(login, passwd, | ||
| 171 | xs_dict_get(snac.config, "passwd"))) { | ||
| 172 | /* success! redirect to the desired uri */ | ||
| 173 | xs *code = random_str(); | ||
| 174 | |||
| 175 | xs_free(*body); | ||
| 176 | *body = xs_fmt("%s?code=%s", redir, code); | ||
| 177 | status = 303; | ||
| 178 | |||
| 179 | srv_debug(0, xs_fmt("oauth x-snac-login: redirect to %s", *body)); | ||
| 180 | } | ||
| 181 | else | ||
| 182 | srv_debug(0, xs_fmt("oauth x-snac-login: login '%s' incorrect", login)); | ||
| 183 | |||
| 184 | user_free(&snac); | ||
| 185 | } | ||
| 186 | else | ||
| 187 | srv_debug(0, xs_fmt("oauth x-snac-login: bad user '%s'", login)); | ||
| 188 | } | ||
| 189 | else | ||
| 190 | srv_debug(0, xs_fmt("oauth x-snac-login: invalid or unset arguments")); | ||
| 191 | } | ||
| 192 | else | ||
| 137 | if (strcmp(cmd, "/token") == 0) { | 193 | if (strcmp(cmd, "/token") == 0) { |
| 138 | const char *gtype = xs_dict_get(msg, "grant_type"); | 194 | const char *gtype = xs_dict_get(msg, "grant_type"); |
| 139 | const char *code = xs_dict_get(msg, "code"); | 195 | const char *code = xs_dict_get(msg, "code"); |
| 140 | const char *cid = xs_dict_get(msg, "client_id"); | 196 | const char *cid = xs_dict_get(msg, "client_id"); |
| 141 | const char *csec = xs_dict_get(msg, "client_secret"); | 197 | const char *csec = xs_dict_get(msg, "client_secret"); |
| 142 | const char *ruri = xs_dict_get(msg, "redirect_uri"); | 198 | const char *ruri = xs_dict_get(msg, "redirect_uri"); |
| 143 | const char *scope = xs_dict_get(msg, "scope"); | ||
| 144 | 199 | ||
| 145 | if (gtype && code && cid && csec && ruri) { | 200 | if (gtype && code && cid && csec && ruri) { |
| 146 | xs *rsp = xs_dict_new(); | 201 | xs *rsp = xs_dict_new(); |
| @@ -149,15 +204,18 @@ int oauth_post_handler(const xs_dict *req, const char *q_path, | |||
| 149 | 204 | ||
| 150 | rsp = xs_dict_append(rsp, "access_token", token); | 205 | rsp = xs_dict_append(rsp, "access_token", token); |
| 151 | rsp = xs_dict_append(rsp, "token_type", "Bearer"); | 206 | rsp = xs_dict_append(rsp, "token_type", "Bearer"); |
| 152 | rsp = xs_dict_append(rsp, "scope", scope); | ||
| 153 | rsp = xs_dict_append(rsp, "created_at", cat); | 207 | rsp = xs_dict_append(rsp, "created_at", cat); |
| 154 | 208 | ||
| 155 | *body = xs_json_dumps_pp(rsp, 4); | 209 | *body = xs_json_dumps_pp(rsp, 4); |
| 156 | *ctype = "application/json"; | 210 | *ctype = "application/json"; |
| 157 | status = 200; | 211 | status = 200; |
| 212 | |||
| 213 | srv_debug(0, xs_fmt("oauth token: successful login, token %s", token)); | ||
| 158 | } | 214 | } |
| 159 | else | 215 | else { |
| 216 | srv_debug(0, xs_fmt("oauth token: invalid or unset arguments")); | ||
| 160 | status = 400; | 217 | status = 400; |
| 218 | } | ||
| 161 | } | 219 | } |
| 162 | else | 220 | else |
| 163 | if (strcmp(cmd, "/revoke") == 0) { | 221 | if (strcmp(cmd, "/revoke") == 0) { |
| @@ -178,13 +236,42 @@ int oauth_post_handler(const xs_dict *req, const char *q_path, | |||
| 178 | } | 236 | } |
| 179 | 237 | ||
| 180 | 238 | ||
| 239 | int mastoapi_get_handler(const xs_dict *req, const char *q_path, | ||
| 240 | char **body, int *b_size, char **ctype) | ||
| 241 | { | ||
| 242 | if (!xs_startswith(q_path, "/api/v1/")) | ||
| 243 | return 0; | ||
| 244 | |||
| 245 | { | ||
| 246 | xs *j = xs_json_dumps_pp(req, 4); | ||
| 247 | printf("mastoapi get:\n%s\n", j); | ||
| 248 | } | ||
| 249 | |||
| 250 | int status = 404; | ||
| 251 | xs_dict *msg = xs_dict_get(req, "q_vars"); | ||
| 252 | xs *cmd = xs_replace(q_path, "/api/v1", ""); | ||
| 253 | |||
| 254 | srv_debug(0, xs_fmt("mastoapi_get_handler %s", q_path)); | ||
| 255 | |||
| 256 | if (strcmp(cmd, "/accounts/verify_credentials") == 0) { | ||
| 257 | } | ||
| 258 | |||
| 259 | return status; | ||
| 260 | } | ||
| 261 | |||
| 262 | |||
| 181 | int mastoapi_post_handler(const xs_dict *req, const char *q_path, | 263 | int mastoapi_post_handler(const xs_dict *req, const char *q_path, |
| 182 | const char *payload, int p_size, | 264 | const char *payload, int p_size, |
| 183 | char **body, int *b_size, char **ctype) | 265 | char **body, int *b_size, char **ctype) |
| 184 | { | 266 | { |
| 185 | if (!xs_startswith(q_path, "/api/v1/")) | 267 | if (!xs_startswith(q_path, "/api/v1/")) |
| 186 | return 0; | 268 | return 0; |
| 187 | 269 | ||
| 270 | { | ||
| 271 | xs *j = xs_json_dumps_pp(req, 4); | ||
| 272 | printf("mastoapi post:\n%s\n", j); | ||
| 273 | } | ||
| 274 | |||
| 188 | int status = 404; | 275 | int status = 404; |
| 189 | xs *msg = NULL; | 276 | xs *msg = NULL; |
| 190 | char *i_ctype = xs_dict_get(req, "content-type"); | 277 | char *i_ctype = xs_dict_get(req, "content-type"); |