// The Construct // // Copyright (C) The Construct Developers, Authors & Contributors // Copyright (C) 2016-2020 Jason Volk // // 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. decltype(ircd::m::bridge::log) ircd::m::bridge::log { "m.bridge" }; bool ircd::m::bridge::exists(const string_view &id) { return config::idx(std::nothrow, id); } // // query // namespace ircd::m::bridge { thread_local char urlencbuf[512]; } decltype(ircd::m::bridge::query::timeout) ircd::m::bridge::query::timeout { { "name", "ircd.m.bridge.query.timeout" }, { "default", 5L }, }; ircd::m::bridge::query::query(const config &config, const m::room::alias &alias) :base_url { at<"url"_>(config) } ,buf { 8_KiB } ,uri { fmt::sprintf { buf, "%s/_matrix/app/v1/rooms/%s?access_token=%s", base_url.path, url::encode(urlencbuf, alias), at<"hs_token"_>(config), } } ,wb { buf + size(uri) } ,hypertext { wb, base_url.remote, "GET", uri, } ,request { net::hostport { base_url.remote }, server::out { wb.completed(), {} }, server::in { wb.remains(), wb.remains() }, } ,code { request.get(seconds(timeout)) } { } ircd::m::bridge::query::query(const config &config, const m::user::id &user_id) :base_url { at<"url"_>(config) } ,buf { 8_KiB } ,uri { fmt::sprintf { buf, "%s/_matrix/app/v1/users/%s?access_token=%s", base_url.path, url::encode(urlencbuf, user_id), at<"hs_token"_>(config), } } ,wb { buf + size(uri) } ,hypertext { wb, base_url.remote, "GET", uri, } ,request { net::hostport { base_url.remote }, server::out { wb.completed(), {} }, server::in { wb.remains(), wb.remains() }, } ,code { request.get(seconds(timeout)) } { } // // config // bool ircd::m::bridge::config::for_each(const closure_bool &closure) { const m::room::id::buf bridge_room_id { "bridge", my_host() }; const m::room::state state { bridge_room_id }; return state.for_each("ircd.bridge", [&closure] (const string_view &type, const string_view &state_key, const event::idx &event_idx) { bool ret{true}; m::get(std::nothrow, event_idx, "content", [&event_idx, &closure, &ret] (const json::object &content) { ret = closure(event_idx, content); }); return ret; }); } void ircd::m::bridge::config::get(const string_view &id, const closure &closure) { if(!get(std::nothrow, id, closure)) throw m::NOT_FOUND { "Configuration for appservice '%s' not found.", id }; } bool ircd::m::bridge::config::get(std::nothrow_t, const string_view &id, const closure &closure) { const auto event_idx { idx(std::nothrow, id) }; return m::get(std::nothrow, event_idx, "content", [&event_idx, &closure] (const json::object &content) { closure(event_idx, content); }); } ircd::m::event::idx ircd::m::bridge::config::idx(const string_view &id) { const auto ret { idx(std::nothrow, id) }; if(!ret) throw m::NOT_FOUND { "Configuration for appservice '%s' not found.", id }; return ret; } ircd::m::event::idx ircd::m::bridge::config::idx(std::nothrow_t, const string_view &id) { const m::room::id::buf bridge_room_id { "bridge", my_host() }; const m::room::state state { bridge_room_id }; return state.get("ircd.bridge", id); }