aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md13
-rw-r--r--conf/clog.conf7
-rw-r--r--src/clog.c115
-rw-r--r--src/queries.h7
4 files changed, 126 insertions, 16 deletions
diff --git a/README.md b/README.md
index 3965f47..6e6e3bb 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@ An attempt to reimplement flog, using the [kore.io](https://kore.io) framework.
## Running
-```
+```sh
make fetch-dependencies
docker compose up
```
@@ -14,7 +14,7 @@ docker compose up
To run locally modify `conf/clog.conf`, comment out `root /var/chroot/` and uncomment
the `skip chroot` section:
-```
+```conf
privsep worker {
runas clog
@@ -26,7 +26,7 @@ privsep worker {
Maybe disable `seccomp_tracing` in `conf/clog.conf` if running into problems:
-```
+```conf
seccomp_tracing no
# seccomp_tracing yes
```
@@ -35,8 +35,9 @@ seccomp_tracing no
`psql` and load `db/db.sql`, `db/data.sql` for `db/data.sql`.
-
## TODO
-* Have `tests.py` load and drop database.
-* only do HTTP stuff at the edge.
+1. Have `tests.py` load and drop database.
+1. ~Only do HTTP stuff at the edge.~
+1. `PUT`/`PATCH`? posts.
+1. pagination
diff --git a/conf/clog.conf b/conf/clog.conf
index 9000d65..f26429b 100644
--- a/conf/clog.conf
+++ b/conf/clog.conf
@@ -43,7 +43,12 @@ domain * {
}
route ^/posts/[a-z0-9\-]+$ {
- handler delete_posts_resource
+ handler put_posts
+ methods put
+ }
+
+ route ^/posts/[a-z0-9\-]+$ {
+ handler delete_posts
methods delete
}
diff --git a/src/clog.c b/src/clog.c
index 2e2be5a..e3a96b0 100644
--- a/src/clog.c
+++ b/src/clog.c
@@ -71,15 +71,13 @@ int redirect(struct http_request *req);
int get_posts(struct http_request *req);
int get_posts_resource(struct http_request *req);
int post_posts(struct http_request *req);
-int delete_posts_resource(struct http_request *req);
+int put_posts(struct http_request *req);
+int delete_posts(struct http_request *req);
int sql_select_posts(struct post_query *pq);
+int sql_update_posts(const char *id, const char *title, const char *body);
int sql_delete_posts(const char *id);
-int sql_insert_posts(
- const char *id,
- const char *title,
- const char *body
-);
+int sql_insert_posts(const char *id, const char *title, const char *body);
int sql_render_posts(struct kore_pgsql *sql, struct post_query *pq);
static void process_md_output(const MD_CHAR *, MD_SIZE size, void *);
@@ -92,7 +90,6 @@ void post_query_init(struct post_query *pq, enum content_type type, const char *
pq->id = NULL;
pq->type = type;
-
pq->status = QUERY_STATUS_OK;
pq->result = kore_buf_alloc(0);
}
@@ -346,6 +343,75 @@ out: ;
return KORE_RESULT_OK;
}
+int put_posts(struct http_request *req) {
+ int err = 0;
+
+ int status = HTTP_STATUS_OK;
+
+ enum content_type type = get_content_type(req);
+
+ const char *id = NULL;
+ const char *title = NULL;
+ const char *body = NULL;
+
+ struct kore_json_item *item = NULL;
+ struct kore_json json;
+
+ kore_json_init(&json, req->http_body->data, req->http_body->length);
+
+ id = req->path + strlen("/posts/");
+
+ // Check for valid resource UUID
+ kore_log(LOG_DEBUG, "Resource id /posts/%s.", id);
+ err = validate_uuid(id);
+ if (err == KORE_RESULT_ERROR) {
+ kore_log(LOG_ERR, "Invalid post id %s.", id);
+ http_err_resp(req, type, HTTP_STATUS_NOT_FOUND);
+ goto out;
+ }
+
+ if (!kore_json_parse(&json)) {
+ status = HTTP_STATUS_BAD_REQUEST;
+ kore_log(LOG_ERR, "error parsing json: %s\n", kore_json_strerror());
+ goto out;
+ }
+
+ item = kore_json_find_string(json.root, "title");
+ if (item != NULL) {
+ title = item->data.string;
+ kore_log(LOG_INFO, "title = '%s'\n", title);
+ } else {
+ status = HTTP_STATUS_BAD_REQUEST;
+ kore_log(LOG_ERR, "Error parsing title: %s\n", kore_json_strerror());
+ goto out;
+ }
+
+ item = kore_json_find_string(json.root, "body");
+ if (item != NULL) {
+ body = item->data.string;
+ kore_log(LOG_INFO, "body = '%s'\n", body);
+ } else {
+ status = HTTP_STATUS_BAD_REQUEST;
+ kore_log(LOG_ERR, "Error parsing body: %s\n", kore_json_strerror());
+ goto out;
+ }
+
+ err = sql_update_posts(id, title, body);
+
+ if (err == KORE_RESULT_ERROR) {
+ status = HTTP_STATUS_INTERNAL_ERROR;
+ goto out;
+ }
+
+out: ;
+
+ http_err_resp(req, type, status);
+
+ kore_json_cleanup(&json);
+
+ return KORE_RESULT_OK;
+}
+
int sql_select_posts(struct post_query *pq) {
int err = KORE_RESULT_OK;
@@ -408,7 +474,7 @@ out: ;
return err;
}
-int delete_posts_resource(struct http_request *req) {
+int delete_posts(struct http_request *req) {
int err = 0;
enum content_type type = get_content_type(req);
@@ -545,6 +611,39 @@ out: ;
return err;
}
+int sql_update_posts(const char *id, const char *title, const char *body) {
+ int err = KORE_RESULT_OK;
+
+ struct kore_pgsql sql;
+ kore_pgsql_init(&sql);
+
+ err = kore_pgsql_setup(&sql, database, KORE_PGSQL_SYNC);
+ if (err == KORE_RESULT_ERROR) {
+ kore_pgsql_logerror(&sql);
+ goto out;
+ }
+
+ err = kore_pgsql_query_params(
+ &sql,
+ q_update_posts,
+ 0,
+ 3,
+ KORE_PGSQL_PARAM_TEXT(title),
+ KORE_PGSQL_PARAM_TEXT(body),
+ KORE_PGSQL_PARAM_TEXT(id)
+ );
+ if (err == KORE_RESULT_ERROR) {
+ kore_pgsql_logerror(&sql);
+ goto out;
+ }
+
+out: ;
+
+ kore_pgsql_cleanup(&sql);
+
+ return err;
+}
+
int sql_delete_posts(const char *id) {
int err = KORE_RESULT_OK;
diff --git a/src/queries.h b/src/queries.h
index 809d259..6230f41 100644
--- a/src/queries.h
+++ b/src/queries.h
@@ -36,9 +36,14 @@ const char *q_insert_posts_with_id = \
"($1, $2, $3) "
"RETURNING id;";
+const char *q_update_posts = \
+"UPDATE posts "
+"SET title = $1, body = $2, updated_at = NOW() "
+"WHERE id = $3 "
+"RETURNING id;";
+
const char *q_delete_posts = \
"DELETE "
"FROM posts "
"WHERE id = $1 "
"RETURNING id;";
-