[ADD/WIP] User unfriendly init wizard

I'll need to make it better, alongside a PL system that doesn't make
terrible decisions, like unPLing itself, or revoking someone's PL-1.
This commit is contained in:
LDA 2024-07-09 17:35:11 +02:00
commit 1035603b9f
2 changed files with 183 additions and 8 deletions

View file

@ -2,10 +2,114 @@
#include <Cytoplasm/Memory.h>
#include <Cytoplasm/Json.h>
#include <Cytoplasm/Util.h>
#include <Cytoplasm/Str.h>
#include <Cytoplasm/Log.h>
#include <stdlib.h>
#include <string.h>
static ParseeConfig *config = NULL;
static char *
GetLine(void)
{
Stream *input = StreamStdin();
char *out = NULL;
size_t length;
UtilGetLine(&out, &length, input);
if (out)
{
char *line = strchr(out, '\n');
if (line)
{
*line = '\0';
}
}
return out;
}
#include <stdarg.h>
static char *
PromptString(const char *expression, const char *def, ...)
{
Stream *output = StreamStdout();
char *out = NULL;
va_list ap;
while (!out)
{
va_start(ap, def);
StreamVprintf(output, expression, ap);
if (def)
{
StreamPrintf(output, " [%s]", def);
}
StreamPrintf(output, ": ");
StreamFlush(output);
va_end(ap);
out = GetLine();
if (!*out)
{
Free(out);
out = NULL;
if (def)
{
return StrDuplicate(def);
}
}
Log(LOG_INFO, "R=%s", out);
}
return out;
}
static int
PromptInteger(const char *expression, int def, ...)
{
Stream *output = StreamStdout();
char *out;
long l;
va_list ap;
va_start(ap, def);
StreamVprintf(output, expression, ap);
if (def >= 0)
{
StreamPrintf(output, " [%d]", def);
}
StreamPrintf(output, ": ");
StreamFlush(output);
va_end(ap);
while (true)
{
char *inval;
out = GetLine();
l = strtol(out, &inval, 10);
Free(out);
/* Not a use-after-free, as we reference only the addresses. */
if (l != 0 || inval != out)
{
break;
}
if (def >= 0)
{
return def;
}
}
return l;
}
/* TODO: Memleaks, galore! */
void
ParseeConfigInit(void)
{
@ -15,17 +119,72 @@ ParseeConfigInit(void)
{
return;
}
/* TODO: Give the user an achievement at the end, just because they're
* cool. */
Log(LOG_NOTICE, "It seems like it is the first time you have configured ");
Log(LOG_NOTICE, "Parsee.");
Log(LOG_NOTICE, "As such, I need to ask you a couple of questions before ");
Log(LOG_NOTICE, "being able to use it.");
Log(LOG_NOTICE, "(don't worry; it won't take too long.)");
Log(LOG_NOTICE, "");
Log(LOG_NOTICE, "");
config = Malloc(sizeof(*config));
config->as_token = StrRandom(32);
config->hs_token = StrRandom(32);
config->sender_localpart = StrDuplicate("_parsee_bridge");
config->namespace_base = StrDuplicate("_parsee_j");
config->listen_as = StrDuplicate("localhost");
config->port = 7642; /* proposed by Saint */
config->component_port = 0;
config->component_host = NULL;
config->shared_comp_secret = NULL;
/* TODO: This is NOT user friendly, and I know it! */
config->sender_localpart = PromptString(
"Name of the bridge bot, used for commands and bridged rooms",
"_parsee_bridge"
);
config->namespace_base = PromptString(
"Base namespace for Parsee (so foo@bar.com => @[NS]_foo=40bar.com)",
"_jabber"
);
config->listen_as = StrDuplicate("localhost");
config->port = PromptInteger(
"Matrix port for the AS service to use",
7642 /* proposed by Saint */
);
config->component_host = PromptString(
"XMPP component to be used for the configuration",
NULL
);
config->component_port = PromptInteger(
"XMPP port for to use for '%s'",
5347, config->component_host
);
config->shared_comp_secret = PromptString(
"%s's shared secret",
NULL, config->component_host
);
config->homeserver_host = PromptString(
"Delegated homeserver to be used for the configuration",
NULL
);
config->homeserver_port = PromptInteger(
"HTTP port for to use for '%s'",
443, config->homeserver_host
);
config->db_path = PromptString(
"Base directory for Parsee data",
NULL
);
config->media_base = PromptString(
"Base media URL for bridged media",
NULL
);
Log(LOG_NOTICE, "Done! Please look over to the parsee.yaml file, ");
Log(LOG_NOTICE, "and follow the instructions listed in it. Then, ");
Log(LOG_NOTICE, "restart Parsee. ");
Log(LOG_NOTICE, "------------------------------------------------");
stream = StreamOpen("parsee.json", "w");
json = HashMapCreate();
@ -37,8 +196,16 @@ ParseeConfigInit(void)
HashMapSet(json, "listen_as", JsonValueString(config->listen_as));
HashMapSet(json, "port", JsonValueInteger(config->port));
HashMapSet(json, "hs_host", JsonValueString(config->homeserver_host));
HashMapSet(json, "hs_port", JsonValueInteger(config->homeserver_port));
HashMapSet(json, "component_host", JsonValueString(config->component_host));
HashMapSet(json, "component_port", JsonValueInteger(config->component_port));
HashMapSet(json, "shared_comp_secret", JsonValueString(config->shared_comp_secret));
HashMapSet(json, "db", JsonValueString(config->db_path));
JsonEncode(json, stream, JSON_PRETTY);
HashMapFree(json);
JsonFree(json);
StreamClose(stream);
}
void
@ -51,6 +218,10 @@ ParseeConfigLoad(char *conf)
return;
}
stream = StreamOpen("parsee.json", "r");
if (!stream)
{
return;
}
json = JsonDecode(stream);
config = Malloc(sizeof(*config));

View file

@ -1150,6 +1150,8 @@ PresenceStanza(ParseeData *args, XMLElement *stanza)
}
else if (StrEquals(affiliation, "member"))
{
/* TODO: Reconsider setting the PL if a member, as there's no
* clear reason to do this in some cases. */
power_level = 0;
}
else if (StrEquals(affiliation, "outcast"))
@ -1157,7 +1159,9 @@ PresenceStanza(ParseeData *args, XMLElement *stanza)
power_level = -1;
}
/* Set the user's PL */
/* Set the user's PL
* TODO: Do NOT change the PL of *real* people nilly-willy.
* In some scenarios, this is really bad behaviour. */
if (room)
{
HashMap *powers = ASGetPL(args->config, room);