webfinger.c 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /* snac - A simple, minimalistic ActivityPub instance */
  2. /* copyright (c) 2022 grunfink - MIT license */
  3. #include "xs.h"
  4. #include "xs_encdec.h"
  5. #include "xs_json.h"
  6. #include "snac.h"
  7. void webfinger_get_handler(d_char *req, char *q_path, int *status,
  8. char **body, int *b_size, char **ctype)
  9. /* serves webfinger queries */
  10. {
  11. if (strcmp(q_path, "/.well-known/webfinger") != 0)
  12. return;
  13. char *q_vars = xs_dict_get(req, "q_vars");
  14. char *resource = xs_dict_get(q_vars, "resource");
  15. if (resource == NULL) {
  16. *status = 400;
  17. return;
  18. }
  19. snac snac;
  20. int found = 0;
  21. if (xs_startswith(resource, "https:/" "/")) {
  22. /* actor search: find a user with this actor */
  23. xs *list = user_list();
  24. char *p, *uid;
  25. p = list;
  26. while (xs_list_iter(&p, &uid)) {
  27. if (user_open(&snac, uid)) {
  28. if (strcmp(snac.actor, resource) == 0) {
  29. found = 1;
  30. break;
  31. }
  32. user_free(&snac);
  33. }
  34. }
  35. }
  36. else
  37. if (xs_startswith(resource, "acct:")) {
  38. /* it's an account name */
  39. xs *an = xs_replace(resource, "acct:", "");
  40. xs *l = NULL;
  41. /* strip a possible leading @ */
  42. if (xs_startswith(an, "@"))
  43. an = xs_crop(an, 1, 0);
  44. l = xs_split_n(an, "@", 1);
  45. if (xs_list_len(l) == 2) {
  46. char *uid = xs_list_get(l, 0);
  47. char *host = xs_list_get(l, 1);
  48. if (strcmp(host, xs_dict_get(srv_config, "host")) == 0)
  49. found = user_open(&snac, uid);
  50. }
  51. }
  52. if (found) {
  53. /* build the object */
  54. xs *acct;
  55. xs *aaj = xs_dict_new();
  56. xs *links = xs_list_new();
  57. xs *obj = xs_dict_new();
  58. d_char *j;
  59. acct = xs_fmt("acct:%s@%s",
  60. xs_dict_get(snac.config, "uid"), xs_dict_get(srv_config, "host"));
  61. aaj = xs_dict_append(aaj, "rel", "self");
  62. aaj = xs_dict_append(aaj, "type", "application/activity+json");
  63. aaj = xs_dict_append(aaj, "href", snac.actor);
  64. links = xs_list_append(links, aaj);
  65. obj = xs_dict_append(obj, "subject", acct);
  66. obj = xs_dict_append(obj, "links", links);
  67. j = xs_json_dumps_pp(obj, 4);
  68. user_free(&snac);
  69. *status = 200;
  70. *body = j;
  71. *ctype = "application/json";
  72. }
  73. }