From da7bf43385e900121aadbd90f6cb22d05c0cff5c Mon Sep 17 00:00:00 2001 From: default Date: Tue, 4 Oct 2022 09:40:16 +0200 Subject: [PATCH] New function adduser(). --- main.c | 14 +++++-- snac.h | 1 + utils.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 129 insertions(+), 4 deletions(-) diff --git a/main.c b/main.c index 64de82c..18c7c22 100644 --- a/main.c +++ b/main.c @@ -16,6 +16,7 @@ int usage(void) printf("Commands:\n"); printf("\n"); printf("init [{basedir}] Initializes the database\n"); + printf("adduser {basedir} [{uid}] Adds a new user\n"); printf("httpd {basedir} Starts the HTTPD daemon\n"); printf("webfinger {basedir} {user} Queries about a @user@host or actor\n"); printf("queue {basedir} {uid} Processes a user queue\n"); @@ -23,7 +24,6 @@ int usage(void) // printf("check {basedir} [{uid}] Checks the database\n"); // printf("purge {basedir} [{uid}] Purges old data\n"); -// printf("adduser {basedir} [{uid}] Adds a new user\n"); // printf("update {basedir} {uid} Sends a user update to followers\n"); // printf("passwd {basedir} {uid} Sets the password for {uid}\n"); @@ -71,9 +71,7 @@ int main(int argc, char *argv[]) /* ... */ basedir = GET_ARGV(); - initdb(basedir); - - return 0; + return initdb(basedir); } if ((basedir = GET_ARGV()) == NULL) @@ -84,6 +82,14 @@ int main(int argc, char *argv[]) return 1; } + if (strcmp(cmd, "adduser") == 0) { + user = GET_ARGV(); + + return adduser(user); + + return 0; + } + if (strcmp(cmd, "httpd") == 0) { httpd(); return 0; diff --git a/snac.h b/snac.h index d9b2e3b..9a387ad 100644 --- a/snac.h +++ b/snac.h @@ -134,3 +134,4 @@ int html_post_handler(d_char *req, char *q_path, d_char *payload, int p_size, char **body, int *b_size, char **ctype); int initdb(const char *_basedir); +int adduser(char *uid); diff --git a/utils.c b/utils.c index 028f863..422c907 100644 --- a/utils.c +++ b/utils.c @@ -5,10 +5,13 @@ #include "xs_io.h" #include "xs_encdec.h" #include "xs_json.h" +#include "xs_time.h" +#include "xs_openssl.h" #include "snac.h" #include +#include const char *default_srv_config = "{" "\"host\": \"\"," @@ -172,3 +175,118 @@ int initdb(const char *basedir) printf("Done.\n"); return 0; } + + +int adduser(char *uid) +/* creates a new user */ +{ + snac snac; + xs *config = xs_dict_new(); + xs *date = xs_str_utctime(0, "%Y-%m-%dT%H:%M:%SZ"); + int rndbuf[3]; + xs *pwd = NULL; + xs *pwd_f = NULL; + xs *key = NULL; + FILE *f; + + if (uid == NULL) { + printf("User id:\n"); + uid = xs_strip(xs_readline(stdin)); + } + + if (!validate_uid(uid)) { + printf("ERROR: only alphanumeric characters and _ are allowed in user ids.\n"); + return 1; + } + + if (user_open(&snac, uid)) { + printf("ERROR: user '%s' already exists\n", uid); + return 1; + } + + srandom(time(NULL) ^ getpid()); + rndbuf[0] = random() & 0xffffffff; + rndbuf[1] = random() & 0xffffffff; + rndbuf[2] = random() & 0xffffffff; + + pwd = xs_base64_enc((char *)rndbuf, sizeof(rndbuf)); + pwd_f = hash_password(uid, pwd, NULL); + + config = xs_dict_append(config, "uid", uid); + config = xs_dict_append(config, "name", uid); + config = xs_dict_append(config, "avatar", ""); + config = xs_dict_append(config, "bio", ""); + config = xs_dict_append(config, "published", date); + config = xs_dict_append(config, "password", pwd_f); + + xs *basedir = xs_fmt("%s/user/%s", srv_basedir, uid); + + if (mkdir(basedir, 0755) == -1) { + printf("ERROR: cannot create directory '%s'\n", basedir); + return 0; + } + + const char *dirs[] = { + "actors", "followers", "following", "local", "muted", + "queue", "static", "timeline", "history", NULL }; + int n; + + for (n = 0; dirs[n]; n++) { + xs *d = xs_fmt("%s/%s", basedir, dirs[n]); + mkdir(d, 0755); + } + + xs *scssfn = xs_fmt("%s/style.css", srv_basedir); + xs *ucssfn = xs_fmt("%s/static/style.css", basedir); + + if ((f = fopen(scssfn, "r")) != NULL) { + FILE *i; + + if ((i = fopen(ucssfn, "w")) == NULL) { + printf("ERROR: cannot create file '%s'\n", ucssfn); + return 1; + } + else { + xs *c = xs_readall(f); + fwrite(c, strlen(c), 1, i); + + fclose(i); + } + + fclose(f); + } + + xs *cfn = xs_fmt("%s/user.json", basedir); + + if ((f = fopen(cfn, "w")) == NULL) { + printf("ERROR: cannot create '%s'\n", cfn); + return 1; + } + else { + xs *j = xs_json_dumps_pp(config, 4); + fwrite(j, strlen(j), 1, f); + fclose(f); + } + + printf("\nCreating RSA key...\n"); + key = xs_rsa_genkey(4096); + printf("Done.\n"); + + xs *kfn = xs_fmt("%s/key.json", basedir); + + if ((f = fopen(kfn, "w")) == NULL) { + printf("ERROR: cannot create '%s'\n", kfn); + return 1; + } + else { + xs *j = xs_json_dumps_pp(key, 4); + fwrite(j, strlen(j), 1, f); + fclose(f); + } + + printf("\nUser password is %s\n", pwd); + + printf("\nGo to %s/%s and keep configuring your user.\n", srv_baseurl, uid); + + return 0; +}