From 5c171d6789a6cde696f779891f5a2aed047566b1 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Wed, 14 Feb 2018 14:04:26 -0800 Subject: [PATCH] modules/client/profile: 8.2 Profiles :with the user's user room. --- modules/client/profile.cc | 183 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 175 insertions(+), 8 deletions(-) diff --git a/modules/client/profile.cc b/modules/client/profile.cc index e055043c3..d15d7553a 100644 --- a/modules/client/profile.cc +++ b/modules/client/profile.cc @@ -10,33 +10,200 @@ using namespace ircd; -mapi::header IRCD_MODULE +mapi::header +IRCD_MODULE { - "registers the resource 'client/profile'" + "Client-Server 8.2 Profiles" }; -ircd::resource profile_resource +ircd::resource +profile_resource { - "/_matrix/client/r0/profile/", resource::opts + "/_matrix/client/r0/profile/", { - "profile", + "(8.2) Profiles", resource::DIRECTORY, } }; +static resource::response +get__profile_full(client &client, + const resource::request &request, + const m::room user_room) +{ + const m::room::state state + { + user_room + }; + + std::vector members; + state.for_each("ircd.profile", [&members] + (const m::event &event) + { + const auto &key + { + at<"state_key"_>(event) + }; + + const auto &value + { + at<"content"_>(event).at("text") + }; + + members.emplace_back(key, value); + }); + + const json::strung response + { + data(members), data(members) + size(members) + }; + + return resource::response + { + client, json::object + { + response + } + }; +} + resource::response -put_profile(client &client, +get__profile(client &client, const resource::request &request) { + if(request.parv.size() < 1) + throw m::error + { + http::MULTIPLE_CHOICES, "M_MISSING_PARAMS", + "user_id path parameter required" + }; + + m::user::id::buf user_id + { + url::decode(request.parv[0], user_id) + }; + + const m::user user + { + user_id + }; + + const m::room::id::buf user_room_id + { + user.room_id() + }; + + const m::room user_room + { + user_room_id + }; + + if(request.parv.size() < 2) + return get__profile_full(client, request, user_room); + + const string_view ¶m + { + request.parv[1] + }; + + user_room.get("ircd.profile", param, [&client, ¶m] + (const m::event &event) + { + const string_view &value + { + at<"content"_>(event).at("text") + }; + + resource::response + { + client, json::members + { + { param, value } + } + }; + }); + + return {}; // responded from closure +} + +resource::method +method_get +{ + profile_resource, "GET", get__profile +}; + +resource::response +put__profile(client &client, + const resource::request &request) +{ + if(request.parv.size() < 1) + throw m::error + { + http::MULTIPLE_CHOICES, "M_MISSING_PARAMS", + "user_id path parameter required" + }; + + if(request.parv.size() < 2) + throw m::error + { + http::MULTIPLE_CHOICES, "M_MISSING_PARAMS", + "profile property path parameter required" + }; + + m::user::id::buf user_id + { + url::decode(request.parv[0], user_id) + }; + + if(user_id != request.user_id) + throw m::FORBIDDEN + { + "Trying to set profile for '%s' but you are '%s'", + user_id, + request.user_id + }; + + const m::user user + { + user_id + }; + + const m::room::id::buf user_room_id + { + user.room_id() + }; + + const m::room user_room + { + user_room_id + }; + + const string_view ¶m + { + request.parv[1] + }; + + const json::object &body{request.content}; + const string_view &value + { + body.at(param) + }; + + send(user_room, request.user_id, "ircd.profile", param, + { + { "text", value } + }); + return resource::response { client, http::OK }; } -resource::method method_put +resource::method +method_put { - profile_resource, "PUT", put_profile, + profile_resource, "PUT", put__profile, { method_put.REQUIRES_AUTH }