0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-18 07:50:57 +01:00
construct/modules/federation/query.cc
2019-02-21 11:53:25 -08:00

155 lines
2.8 KiB
C++

// Matrix Construct
//
// Copyright (C) Matrix Construct Developers, Authors & Contributors
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice is present in all copies. The
// full license for this software is available in the LICENSE file.
using namespace ircd;
mapi::header
IRCD_MODULE
{
"Federation :Query"
};
const string_view
query_description
{R"(
Performs a single query request on the receiving homeserver.
The Query Type part of the path specifies the kind of query
being made, and its query arguments have a meaning specific to
that kind of query. The response is a JSON-encoded object whose
meaning also depends on the kind of query.
)"};
resource
query_resource
{
"/_matrix/federation/v1/query/",
{
query_description,
resource::DIRECTORY
}
};
static resource::response
get__query_profile(client &client,
const resource::request &request);
static resource::response
get__query_directory(client &client,
const resource::request &request);
resource::response
get__query(client &client,
const resource::request &request)
{
const auto type
{
request.parv[0]
};
if(type == "profile")
return get__query_profile(client, request);
if(type == "directory")
return get__query_directory(client, request);
throw m::NOT_FOUND
{
"Query type not found."
};
}
resource::method
method_get
{
query_resource, "GET", get__query,
{
method_get.VERIFY_ORIGIN
}
};
resource::response
get__query_profile(client &client,
const resource::request &request)
{
m::user::id::buf user_id
{
url::decode(user_id, request.query.at("user_id"))
};
const string_view field
{
//TODO: XXX full profile aggregation w/ user:: linkage
request.query.at("field")
};
const m::user user
{
user_id
};
const m::user::profile profile
{
user
};
profile.get(field, [&client]
(const string_view &field, const string_view &value)
{
resource::response
{
client, json::members
{
{ field, value }
}
};
});
return {}; // responded from closure
}
resource::response
get__query_directory(client &client,
const resource::request &request)
{
m::room::alias::buf room_alias
{
url::decode(room_alias, request.query.at("room_alias"))
};
const auto room_id
{
m::room_id(room_alias)
};
//TODO: servers
const std::array<json::value, 2> server
{
{ room_alias.host(), my_host() }
};
const size_t server_count
{
server.size() - bool(room_alias.host() == my_host())
};
const json::value servers
{
server.data(), server_count
};
return resource::response
{
client, json::members
{
{ "room_id", room_id },
{ "servers", servers },
}
};
}