diff --git a/Schema/TokenRequest.json b/Schema/TokenRequest.json new file mode 100644 index 0000000..150b0fa --- /dev/null +++ b/Schema/TokenRequest.json @@ -0,0 +1,14 @@ +{ + "header": "Schema\/TokenRequest.h", + "types": { + "TokenRequest": { + "fields": { + "name": { "type": "string" }, + "max_uses": { "type": "integer" }, + "lifetime": { "type": "integer" } + }, + "type": "struct" + } + }, + "guard": "TELODENDRIA_TOKENREQUEST_H" +} diff --git a/src/Routes/RouteAdminTokens.c b/src/Routes/RouteAdminTokens.c index b40b3ad..986db9d 100644 --- a/src/Routes/RouteAdminTokens.c +++ b/src/Routes/RouteAdminTokens.c @@ -26,16 +26,22 @@ #include #include #include +#include +#include #include #include ROUTE_IMPL(RouteAdminTokens, path, argp) { RouteArgs *args = argp; + HashMap *request = NULL; HashMap *response = NULL; char *token; + char *username; + char *name; + char *msg; Db *db = args->matrixArgs->db; @@ -48,11 +54,16 @@ ROUTE_IMPL(RouteAdminTokens, path, argp) RegTokenInfo *info; + TokenRequest *req; + size_t i; - if (method != HTTP_GET) + Int64 maxuses; + Int64 lifetime; + + if (method != HTTP_GET && method != HTTP_POST) { - char *msg = "Route only supports GET for now."; + msg = "Route only supports GET and POST for now."; HttpResponseStatus(args->context, HTTP_BAD_REQUEST); return MatrixErrorCreate(M_UNRECOGNIZED, msg); } @@ -74,7 +85,7 @@ ROUTE_IMPL(RouteAdminTokens, path, argp) if (!(UserGetPrivileges(user) & USER_ISSUE_TOKENS)) { - char *msg = "User doesn't have the ISSUE_TOKENS privilege."; + msg = "User doesn't have the ISSUE_TOKENS privilege."; HttpResponseStatus(args->context, HTTP_FORBIDDEN); response = MatrixErrorCreate(M_FORBIDDEN, msg); goto finish; @@ -95,9 +106,10 @@ ROUTE_IMPL(RouteAdminTokens, path, argp) for (i = 0; i < ArraySize(tokens); i++) { char *tokenname = ArrayGet(tokens, i); + HashMap *jsoninfo; info = RegTokenGetInfo(db, tokenname); - HashMap *jsoninfo = RegTokenJSON(info); + jsoninfo = RegTokenJSON(info); RegTokenClose(info); @@ -117,8 +129,66 @@ ROUTE_IMPL(RouteAdminTokens, path, argp) RegTokenClose(info); RegTokenFree(info); break; + case HTTP_POST: + request = JsonDecode(HttpServerStream(args->context)); + if (!request) + { + HttpResponseStatus(args->context, HTTP_BAD_REQUEST); + response = MatrixErrorCreate(M_NOT_JSON, NULL); + goto finish; + } + req = Malloc(sizeof(TokenRequest)); + req->max_uses = Int64Neg(Int64Create(0, 1)); + req->lifetime = Int64Create(0, 0); + req->name = NULL; + + if (!TokenRequestFromJson(request, req, &msg)) + { + TokenRequestFree(req); + Free(req); + + HttpResponseStatus(args->context, HTTP_BAD_REQUEST); + response = MatrixErrorCreate(M_BAD_JSON, msg); + goto finish; + + } + + if (!req->name) + { + req->name = StrRandom(16); + } + + username = UserGetName(user); + name = req->name; + maxuses = req->max_uses; + lifetime = req->lifetime; + + info = RegTokenCreate(db, name, username, maxuses, lifetime, 0); + if (!info) + { + RegTokenClose(info); + RegTokenFree(info); + TokenRequestFree(req); + Free(req); + + HttpResponseStatus(args->context, HTTP_BAD_REQUEST); + msg = "Cannot create token"; + response = MatrixErrorCreate(M_INVALID_PARAM, msg); + goto finish; + } + response = RegTokenJSON(info); + + RegTokenClose(info); + RegTokenFree(info); + TokenRequestFree(req); + Free(req); + break; + default: + /* Fallthrough, as those are naturally kept out beforehand */ + break; } finish: UserUnlock(user); + JsonFree(request); return response; }