summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data.c38
-rw-r--r--httpd.c2
-rw-r--r--mastoapi.c110
-rw-r--r--snac.h6
4 files changed, 141 insertions, 15 deletions
diff --git a/data.c b/data.c
index 46d95b4..ed65d32 100644
--- a/data.c
+++ b/data.c
@@ -1732,6 +1732,7 @@ xs_list *tag_search(char *tag, int skip, int show)
/** lists **/
xs_val *list_maint(snac *user, const char *list, int op)
+/* list maintenance */
{
xs_val *l = NULL;
@@ -1810,15 +1811,48 @@ xs_val *list_maint(snac *user, const char *list, int op)
fn = xs_replace_i(fn, ".id", ".lst");
unlink(fn);
- fn = xs_replace_i(fn, ".list", ".idx");
+ fn = xs_replace_i(fn, ".lst", ".idx");
unlink(fn);
}
}
break;
+ }
+
+ return l;
+}
+
+
+xs_val *list_content(snac *user, const char *list, const char *actor_md5, int op)
+/* list content management */
+{
+ xs_val *l = NULL;
+
+ if (!xs_is_hex(list))
+ return NULL;
+
+ if (actor_md5 != NULL && !xs_is_hex(actor_md5))
+ return NULL;
+
+ xs *fn = xs_fmt("%s/list/%s.lst", user->basedir, list);
+
+ switch (op) {
+ case 0: /** list content **/
+ l = index_list(fn, XS_ALL);
- case 3: /** list content (list is the id) **/
break;
+
+ case 1: /** append actor to list **/
+ if (actor_md5 != NULL) {
+ if (!index_in(fn, actor_md5))
+ index_add_md5(fn, actor_md5);
+ }
+
+ break;
+
+ case 2: /** delete actor from list **/
+ if (actor_md5 != NULL)
+ index_del_md5(fn, actor_md5);
}
return l;
diff --git a/httpd.c b/httpd.c
index e402e61..bda8159 100644
--- a/httpd.c
+++ b/httpd.c
@@ -360,7 +360,7 @@ void httpd_connection(FILE *f)
#ifndef NO_MASTODON_API
if (status == 0)
status = mastoapi_delete_handler(req, q_path,
- &body, &b_size, &ctype);
+ payload, p_size, &body, &b_size, &ctype);
#endif
}
diff --git a/mastoapi.c b/mastoapi.c
index 54d2777..8c41efb 100644
--- a/mastoapi.c
+++ b/mastoapi.c
@@ -1765,7 +1765,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
status = 200;
}
else
- if (strcmp(cmd, "/v1/lists") == 0) { /** **/
+ if (strcmp(cmd, "/v1/lists") == 0) { /** list of lists **/
if (logged_in) {
xs *lol = list_maint(&snac1, NULL, 0);
xs *l = xs_list_new();
@@ -1789,6 +1789,36 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
}
}
else
+ if (xs_startswith(cmd, "/v1/lists/")) { /** list information **/
+ if (logged_in) {
+ xs *l = xs_split(cmd, "/");
+ char *op = xs_list_get(l, -1);
+ char *id = xs_list_get(l, -2);
+
+ if (op && id && xs_is_hex(id)) {
+ if (strcmp(op, "accounts") == 0) {
+ xs *actors = list_content(&snac1, id, NULL, 0);
+ xs *out = xs_list_new();
+ int c = 0;
+ char *v;
+
+ while (xs_list_next(actors, &v, &c)) {
+ xs *actor = NULL;
+
+ if (valid_status(object_get_by_md5(v, &actor))) {
+ xs *acct = mastoapi_account(actor);
+ out = xs_list_append(out, acct);
+ }
+ }
+
+ *body = xs_json_dumps(out, 4);
+ *ctype = "application/json";
+ status = 200;
+ }
+ }
+ }
+ }
+ else
if (strcmp(cmd, "/v1/scheduled_statuses") == 0) { /** **/
/* snac does not schedule notes */
*body = xs_dup("[]");
@@ -2676,6 +2706,29 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
status = 422;
}
}
+ if (xs_startswith(cmd, "/v1/lists/")) { /** list maintenance **/
+ if (logged_in) {
+ xs *l = xs_split(cmd, "/");
+ char *op = xs_list_get(l, -1);
+ char *id = xs_list_get(l, -2);
+
+ if (op && id && xs_is_hex(id)) {
+ if (strcmp(op, "accounts") == 0) {
+ xs_list *accts = xs_dict_get(args, "account_ids[]");
+ int c = 0;
+ char *v;
+
+ while (xs_list_next(accts, &v, &c)) {
+ list_content(&snac, id, v, 1);
+ }
+
+ status = 200;
+ }
+ }
+ }
+ else
+ status = 422;
+ }
/* user cleanup */
if (logged_in)
@@ -2688,18 +2741,39 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
int mastoapi_delete_handler(const xs_dict *req, const char *q_path,
- char **body, int *b_size, char **ctype) {
-
- (void)req;
+ const char *payload, int p_size,
+ char **body, int *b_size, char **ctype)
+{
+ (void)p_size;
(void)body;
(void)b_size;
(void)ctype;
- int status = 404;
-
if (!xs_startswith(q_path, "/api/v1/") && !xs_startswith(q_path, "/api/v2/"))
return 0;
+ int status = 404;
+ xs *args = NULL;
+ char *i_ctype = xs_dict_get(req, "content-type");
+
+ if (i_ctype && xs_startswith(i_ctype, "application/json")) {
+ if (!xs_is_null(payload))
+ args = xs_json_loads(payload);
+ }
+ else if (i_ctype && xs_startswith(i_ctype, "application/x-www-form-urlencoded"))
+ {
+ // Some apps send form data instead of json so we should cater for those
+ if (!xs_is_null(payload)) {
+ xs *upl = xs_url_dec(payload);
+ args = xs_url_vars(upl);
+ }
+ }
+ else
+ args = xs_dup(xs_dict_get(req, "p_vars"));
+
+ if (args == NULL)
+ return 400;
+
snac snac = {0};
int logged_in = process_auth_token(&snac, req);
@@ -2713,10 +2787,26 @@ int mastoapi_delete_handler(const xs_dict *req, const char *q_path,
if (xs_startswith(cmd, "/v1/lists/")) {
if (logged_in) {
xs *l = xs_split(cmd, "/");
- char *id = xs_list_get(l, -1);
-
- if (xs_is_hex(id)) {
- list_maint(&snac, id, 2);
+ char *p = xs_list_get(l, -1);
+
+ if (p) {
+ if (strcmp(p, "accounts") == 0) {
+ /* delete account from list */
+ p = xs_list_get(l, -2);
+ xs_list *accts = xs_dict_get(args, "account_ids[]");
+ int c = 0;
+ char *v;
+
+ while (xs_list_next(accts, &v, &c)) {
+ list_content(&snac, p, v, 2);
+ }
+ }
+ else {
+ /* delete list */
+ if (xs_is_hex(p)) {
+ list_maint(&snac, p, 2);
+ }
+ }
}
status = 200;
diff --git a/snac.h b/snac.h
index f76f8e0..da8b6f9 100644
--- a/snac.h
+++ b/snac.h
@@ -175,6 +175,7 @@ void tag_index(const char *id, const xs_dict *obj);
xs_list *tag_search(char *tag, int skip, int show);
xs_val *list_maint(snac *user, const char *list, int op);
+xs_val *list_content(snac *user, const char *list_id, const char *actor_md5, int op);
int actor_add(const char *actor, xs_dict *msg);
int actor_get(const char *actor, xs_dict **data);
@@ -339,11 +340,12 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
char **body, int *b_size, char **ctype);
int mastoapi_get_handler(const xs_dict *req, const char *q_path,
char **body, int *b_size, char **ctype);
-int mastoapi_delete_handler(const xs_dict *req, const char *q_path,
- char **body, int *b_size, char **ctype);
int mastoapi_post_handler(const xs_dict *req, const char *q_path,
const char *payload, int p_size,
char **body, int *b_size, char **ctype);
+int mastoapi_delete_handler(const xs_dict *req, const char *q_path,
+ const char *payload, int p_size,
+ char **body, int *b_size, char **ctype);
int mastoapi_put_handler(const xs_dict *req, const char *q_path,
const char *payload, int p_size,
char **body, int *b_size, char **ctype);