diff options
| -rw-r--r-- | main.c | 5 | ||||
| -rw-r--r-- | snac.h | 2 | ||||
| -rw-r--r-- | utils.c | 106 |
3 files changed, 113 insertions, 0 deletions
| @@ -247,6 +247,11 @@ int main(int argc, char *argv[]) | |||
| 247 | return 0; | 247 | return 0; |
| 248 | } | 248 | } |
| 249 | 249 | ||
| 250 | if (strcmp(cmd, "verify_links") == 0) { /** **/ | ||
| 251 | verify_links(&snac); | ||
| 252 | return 0; | ||
| 253 | } | ||
| 254 | |||
| 250 | if (strcmp(cmd, "timeline") == 0) { /** **/ | 255 | if (strcmp(cmd, "timeline") == 0) { /** **/ |
| 251 | #if 0 | 256 | #if 0 |
| 252 | xs *list = local_list(&snac, XS_ALL); | 257 | xs *list = local_list(&snac, XS_ALL); |
| @@ -330,3 +330,5 @@ int mastoapi_put_handler(const xs_dict *req, const char *q_path, | |||
| 330 | const char *payload, int p_size, | 330 | const char *payload, int p_size, |
| 331 | char **body, int *b_size, char **ctype); | 331 | char **body, int *b_size, char **ctype); |
| 332 | void mastoapi_purge(void); | 332 | void mastoapi_purge(void); |
| 333 | |||
| 334 | void verify_links(snac *user); | ||
| @@ -8,6 +8,8 @@ | |||
| 8 | #include "xs_openssl.h" | 8 | #include "xs_openssl.h" |
| 9 | #include "xs_random.h" | 9 | #include "xs_random.h" |
| 10 | #include "xs_glob.h" | 10 | #include "xs_glob.h" |
| 11 | #include "xs_curl.h" | ||
| 12 | #include "xs_regex.h" | ||
| 11 | 13 | ||
| 12 | #include "snac.h" | 14 | #include "snac.h" |
| 13 | 15 | ||
| @@ -407,3 +409,107 @@ int deluser(snac *user) | |||
| 407 | 409 | ||
| 408 | return ret; | 410 | return ret; |
| 409 | } | 411 | } |
| 412 | |||
| 413 | |||
| 414 | void verify_links(snac *user) | ||
| 415 | /* verifies a user's links */ | ||
| 416 | { | ||
| 417 | xs_dict *p = xs_dict_get(user->config, "metadata"); | ||
| 418 | char *k, *v; | ||
| 419 | int changed = 0; | ||
| 420 | |||
| 421 | while (p && xs_dict_iter(&p, &k, &v)) { | ||
| 422 | /* not an https link? skip */ | ||
| 423 | if (!xs_startswith(v, "https:/" "/")) | ||
| 424 | continue; | ||
| 425 | |||
| 426 | int status; | ||
| 427 | xs *req = NULL; | ||
| 428 | xs *payload = NULL; | ||
| 429 | int p_size = 0; | ||
| 430 | |||
| 431 | req = xs_http_request("GET", v, NULL, NULL, 0, &status, | ||
| 432 | &payload, &p_size, 0); | ||
| 433 | |||
| 434 | if (!valid_status(status)) | ||
| 435 | continue; | ||
| 436 | |||
| 437 | /* extract the links */ | ||
| 438 | xs *ls = xs_regex_select(payload, "< *(a|link) +[^>]+>"); | ||
| 439 | |||
| 440 | xs_list *lp = ls; | ||
| 441 | char *ll; | ||
| 442 | |||
| 443 | while (xs_list_iter(&lp, &ll)) { | ||
| 444 | /* extract href and rel */ | ||
| 445 | xs *r = xs_regex_select(ll, "(href|rel) *= *(\"[^\"]*\"|'[^']*')"); | ||
| 446 | |||
| 447 | /* must have both attributes */ | ||
| 448 | if (xs_list_len(r) != 2) | ||
| 449 | continue; | ||
| 450 | |||
| 451 | xs *href = NULL; | ||
| 452 | int is_rel_me = 0; | ||
| 453 | xs_list *pr = r; | ||
| 454 | char *ar; | ||
| 455 | |||
| 456 | while (xs_list_iter(&pr, &ar)) { | ||
| 457 | xs *nq = xs_dup(ar); | ||
| 458 | |||
| 459 | nq = xs_replace_i(nq, "\"", ""); | ||
| 460 | nq = xs_replace_i(nq, "'", ""); | ||
| 461 | |||
| 462 | xs *r2 = xs_split_n(nq, "=", 1); | ||
| 463 | if (xs_list_len(r2) != 2) | ||
| 464 | continue; | ||
| 465 | |||
| 466 | xs *ak = xs_strip_i(xs_dup(xs_list_get(r2, 0))); | ||
| 467 | xs *av = xs_strip_i(xs_dup(xs_list_get(r2, 1))); | ||
| 468 | |||
| 469 | if (strcmp(ak, "href") == 0) | ||
| 470 | href = xs_dup(av); | ||
| 471 | else | ||
| 472 | if (strcmp(ak, "rel") == 0) { | ||
| 473 | /* split the value by spaces */ | ||
| 474 | xs *vbs = xs_split(av, " "); | ||
| 475 | |||
| 476 | /* is any of it "me"? */ | ||
| 477 | if (xs_list_in(vbs, "me") != -1) | ||
| 478 | is_rel_me = 1; | ||
| 479 | } | ||
| 480 | } | ||
| 481 | |||
| 482 | /* after all this acrobatics, do we have an href and a rel="me"? */ | ||
| 483 | if (href != NULL && is_rel_me) { | ||
| 484 | /* is it the same as the actor? */ | ||
| 485 | if (strcmp(href, user->actor) == 0) { | ||
| 486 | /* got it! */ | ||
| 487 | xs *verified_at = xs_str_utctime(0, ISO_DATE_SPEC); | ||
| 488 | |||
| 489 | user->links = xs_dict_set(user->links, v, verified_at); | ||
| 490 | |||
| 491 | changed++; | ||
| 492 | |||
| 493 | snac_log(user, xs_fmt("verify_links: %s at %s", v, verified_at)); | ||
| 494 | } | ||
| 495 | } | ||
| 496 | } | ||
| 497 | } | ||
| 498 | |||
| 499 | if (changed) { | ||
| 500 | FILE *f; | ||
| 501 | |||
| 502 | /* update the links.json file */ | ||
| 503 | xs *fn = xs_fmt("%s/links.json", user->basedir); | ||
| 504 | xs *bfn = xs_fmt("%s.bak", fn); | ||
| 505 | |||
| 506 | rename(fn, bfn); | ||
| 507 | |||
| 508 | if ((f = fopen(fn, "w")) != NULL) { | ||
| 509 | xs_json_dump(user->links, 4, f); | ||
| 510 | fclose(f); | ||
| 511 | } | ||
| 512 | else | ||
| 513 | rename(bfn, fn); | ||
| 514 | } | ||
| 515 | } | ||