diff --git a/Schema/UserDirectoryRequest.json b/Schema/UserDirectoryRequest.json new file mode 100644 index 0000000..7e27c03 --- /dev/null +++ b/Schema/UserDirectoryRequest.json @@ -0,0 +1,13 @@ +{ + "header": "Schema\/UserDirectoryRequest.h", + "types": { + "UserDirectoryRequest": { + "fields": { + "search_term": { "type": "string" }, + "limit": { "type": "integer" } + }, + "type": "struct" + } + }, + "guard": "TELODENDRIA_SCHEMA_USERDIRECTORYREQUEST_H" +} diff --git a/src/Routes/RouteUserDirectory.c b/src/Routes/RouteUserDirectory.c index 2c8c0e2..5cd6f71 100644 --- a/src/Routes/RouteUserDirectory.c +++ b/src/Routes/RouteUserDirectory.c @@ -4,7 +4,7 @@ * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, + * including without dirRequest.limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: @@ -30,6 +30,8 @@ #include #include +#include + #include ROUTE_IMPL(RouteUserDirectory, path, argp) @@ -47,19 +49,19 @@ ROUTE_IMPL(RouteUserDirectory, path, argp) User *user = NULL; - JsonValue *val = NULL; - char *token = NULL; - char *searchTerm = NULL; char *requesterName = NULL; char *msg = NULL; - size_t limit = 10; + UserDirectoryRequest dirRequest; size_t i, included; (void) path; + dirRequest.search_term = NULL; + dirRequest.limit = Int64Create(0, 10); + if (HttpRequestMethodGet(args->context) != HTTP_POST) { @@ -76,6 +78,20 @@ ROUTE_IMPL(RouteUserDirectory, path, argp) response = MatrixErrorCreate(M_NOT_JSON, NULL); goto finish; } + if (!UserDirectoryRequestFromJson(request, &dirRequest, &msg)) + { + HttpResponseStatus(args->context, HTTP_BAD_REQUEST); + response = MatrixErrorCreate(M_BAD_JSON, msg); + goto finish; + } + if (!dirRequest.search_term) + { + msg = "Field 'search_term' not set."; + HttpResponseStatus(args->context, HTTP_BAD_REQUEST); + response = MatrixErrorCreate(M_BAD_JSON, msg); + goto finish; + + } response = MatrixGetAccessToken(args->context, &token); if (response) @@ -93,25 +109,6 @@ ROUTE_IMPL(RouteUserDirectory, path, argp) } requesterName = UserGetName(user); - /* TODO: Use j2s instead of an hardcoded parser */ - if (!(val = JsonGet(request, 1, "search_term")) || - JsonValueType(val) != JSON_STRING) - { - /* The Spec requires search_term to be set to a string. */ - msg = "search_term must be set to a string"; - HttpResponseStatus(args->context, HTTP_BAD_REQUEST); - response = MatrixErrorCreate(M_BAD_JSON, msg); - goto finish; - } - searchTerm = StrLower(JsonValueAsString(val)); - - if ((val = JsonGet(request, 1, "limit")) && - JsonValueType(val) == JSON_INTEGER) - { - /* It is however far more leinent on limit, with 10 by default. */ - limit = JsonValueAsInteger(val); - } - response = HashMapCreate(); results = ArrayCreate(); @@ -131,7 +128,9 @@ ROUTE_IMPL(RouteUserDirectory, path, argp) goto finish; } - for (i = 0, included = 0; i < ArraySize(users) && included < limit; i++) +#define IncludedLtLimit (Int64Lt(Int64Create(0, included), dirRequest.limit)) + for (i = 0, included = 0; i < ArraySize(users) && IncludedLtLimit; i++) +#undef IncludedLtLimit { HashMap *obj; User *currentUser; @@ -154,8 +153,9 @@ ROUTE_IMPL(RouteUserDirectory, path, argp) avatarUrl = UserGetProfile(currentUser, "avatar_url"); /* Check for the user ID and display name. */ - if (strstr(name, searchTerm) || - (lowerDisplayName && strstr(lowerDisplayName, searchTerm))) + if (strstr(name, dirRequest.search_term) || + (lowerDisplayName && + strstr(lowerDisplayName, dirRequest.search_term))) { included++; @@ -170,9 +170,9 @@ ROUTE_IMPL(RouteUserDirectory, path, argp) } if (name) { - char *userID = StrConcat(4, "@", name, ":", config->serverName); - JsonSet(obj, JsonValueString(userID), 1, "user_id"); - Free(userID); + char *uID = StrConcat(4, "@", name, ":", config->serverName); + JsonSet(obj, JsonValueString(uID), 1, "user_id"); + Free(uID); } ArrayAdd(results, JsonValueObject(obj)); } @@ -186,28 +186,14 @@ ROUTE_IMPL(RouteUserDirectory, path, argp) } } JsonSet(response, JsonValueArray(results), 1, "results"); - JsonSet(response, JsonValueBoolean(included == limit), 1, "limited"); + JsonSet(response, JsonValueBoolean(Int64Eq(included, dirRequest.limit)), + 1, "limited"); finish: - if (user) - { - UserUnlock(user); - } - if (request) - { - JsonFree(request); - } - if (searchTerm) - { - Free(searchTerm); - } - if (users) - { - DbListFree(users); - } - if (config) - { - ConfigUnlock(config); - } + UserUnlock(user); + JsonFree(request); + DbListFree(users); + ConfigUnlock(config); + UserDirectoryRequestFree(&dirRequest); return response; }