mirror of
https://github.com/matrix-construct/construct
synced 2024-11-29 10:12:39 +01:00
ircd: Various matrix library / modules / database development.
This commit is contained in:
parent
10472684f2
commit
0149610bb2
16 changed files with 483 additions and 295 deletions
|
@ -25,6 +25,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#define HAVE_IRCD_M_H
|
#define HAVE_IRCD_M_H
|
||||||
|
|
||||||
|
#include "json/parse.h"
|
||||||
|
|
||||||
namespace ircd {
|
namespace ircd {
|
||||||
namespace m {
|
namespace m {
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,8 @@ struct error
|
||||||
{
|
{
|
||||||
template<class... args> error(const http::code &, const string_view &errcode, const char *const &fmt, args&&...);
|
template<class... args> error(const http::code &, const string_view &errcode, const char *const &fmt, args&&...);
|
||||||
template<class... args> error(const string_view &errcode, const char *const &fmt, args&&...);
|
template<class... args> error(const string_view &errcode, const char *const &fmt, args&&...);
|
||||||
error(const http::code &, const json::doc &doc = {});
|
error(const http::code &, const json::object &object = {});
|
||||||
error(const http::code &, const json::obj &obj);
|
error(const http::code &, const json::index &idx);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace m
|
} // namespace m
|
||||||
|
@ -42,14 +42,14 @@ struct error
|
||||||
|
|
||||||
inline
|
inline
|
||||||
ircd::m::error::error(const http::code &c,
|
ircd::m::error::error(const http::code &c,
|
||||||
const json::obj &obj)
|
const json::index &index)
|
||||||
:http::error{c, std::string{obj}}
|
:http::error{c, std::string{index}}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
ircd::m::error::error(const http::code &c,
|
ircd::m::error::error(const http::code &c,
|
||||||
const json::doc &doc)
|
const json::object &object)
|
||||||
:http::error{c, std::string{doc}}
|
:http::error{c, std::string{object}}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template<class... args>
|
template<class... args>
|
||||||
|
@ -75,7 +75,7 @@ ircd::m::error::error(const http::code &status,
|
||||||
fmt::snprintf{estr, sizeof(estr), fmt, std::forward<args>(a)...}
|
fmt::snprintf{estr, sizeof(estr), fmt, std::forward<args>(a)...}
|
||||||
};
|
};
|
||||||
|
|
||||||
return json::obj
|
return json::index
|
||||||
{
|
{
|
||||||
{ "errcode", errcode },
|
{ "errcode", errcode },
|
||||||
{ "error", string_view(estr, estr_len) }
|
{ "error", string_view(estr, estr_len) }
|
||||||
|
|
|
@ -22,16 +22,32 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ircd/json/object.h>
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#define HAVE_IRCD_M_EVENT_H
|
#define HAVE_IRCD_M_EVENT_H
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Protocol notes
|
||||||
|
//
|
||||||
|
// 10.4
|
||||||
|
// The total size of any event MUST NOT exceed 65 KB.
|
||||||
|
//
|
||||||
|
// There are additional restrictions on sizes per key:
|
||||||
|
// sender MUST NOT exceed 255 bytes (including domain).
|
||||||
|
// room_id MUST NOT exceed 255 bytes.
|
||||||
|
// state_key MUST NOT exceed 255 bytes.
|
||||||
|
// type MUST NOT exceed 255 bytes.
|
||||||
|
// event_id MUST NOT exceed 255 bytes.
|
||||||
|
//
|
||||||
|
// Some event types have additional size restrictions which are specified in
|
||||||
|
// the description of the event. Additional keys have no limit other than that
|
||||||
|
// implied by the total 65 KB limit on events.
|
||||||
|
//
|
||||||
|
|
||||||
namespace ircd {
|
namespace ircd {
|
||||||
namespace m {
|
namespace m {
|
||||||
|
|
||||||
struct event
|
struct event
|
||||||
:json::object
|
:json::parse
|
||||||
<
|
<
|
||||||
string_view,
|
string_view,
|
||||||
time_t,
|
time_t,
|
||||||
|
@ -53,35 +69,7 @@ struct event
|
||||||
|
|
||||||
template<class... A>
|
template<class... A>
|
||||||
event(A&&... a)
|
event(A&&... a)
|
||||||
:object{std::make_tuple(std::forward<A>(a)...)}
|
:parse{*this, std::forward<A>(a)...}
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sync
|
|
||||||
:json::object
|
|
||||||
<
|
|
||||||
string_view,
|
|
||||||
string_view,
|
|
||||||
string_view,
|
|
||||||
string_view
|
|
||||||
>
|
|
||||||
{
|
|
||||||
IRCD_MEMBERS
|
|
||||||
(
|
|
||||||
"account_data",
|
|
||||||
"next_batch",
|
|
||||||
"rooms",
|
|
||||||
"presence",
|
|
||||||
)
|
|
||||||
|
|
||||||
sync(const json::doc &doc)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class... A>
|
|
||||||
sync(A&&... a)
|
|
||||||
:object{std::make_tuple(std::forward<A>(a)...)}
|
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace ircd {
|
||||||
namespace m {
|
namespace m {
|
||||||
|
|
||||||
struct request
|
struct request
|
||||||
:json::obj
|
:json::index
|
||||||
{
|
{
|
||||||
string_view method;
|
string_view method;
|
||||||
string_view path;
|
string_view path;
|
||||||
|
@ -39,12 +39,12 @@ struct request
|
||||||
request(const string_view &method,
|
request(const string_view &method,
|
||||||
const string_view &path,
|
const string_view &path,
|
||||||
const string_view &query = {},
|
const string_view &query = {},
|
||||||
std::initializer_list<json::obj::member> body = {});
|
std::initializer_list<json::index::member> body = {});
|
||||||
|
|
||||||
request(const string_view &method,
|
request(const string_view &method,
|
||||||
const string_view &path,
|
const string_view &path,
|
||||||
const string_view &query,
|
const string_view &query,
|
||||||
const json::doc &content);
|
const json::object &content);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace m
|
} // namespace m
|
||||||
|
@ -54,8 +54,8 @@ inline
|
||||||
ircd::m::request::request(const string_view &method,
|
ircd::m::request::request(const string_view &method,
|
||||||
const string_view &path,
|
const string_view &path,
|
||||||
const string_view &query,
|
const string_view &query,
|
||||||
std::initializer_list<json::obj::member> body)
|
std::initializer_list<json::index::member> body)
|
||||||
:json::obj{std::move(body)}
|
:json::index{std::move(body)}
|
||||||
,method{method}
|
,method{method}
|
||||||
,path{path}
|
,path{path}
|
||||||
,query{query}
|
,query{query}
|
||||||
|
@ -66,8 +66,8 @@ inline
|
||||||
ircd::m::request::request(const string_view &method,
|
ircd::m::request::request(const string_view &method,
|
||||||
const string_view &path,
|
const string_view &path,
|
||||||
const string_view &query,
|
const string_view &query,
|
||||||
const json::doc &content)
|
const json::object &content)
|
||||||
:json::obj{content}
|
:json::index{content}
|
||||||
,method{method}
|
,method{method}
|
||||||
,path{path}
|
,path{path}
|
||||||
,query{query}
|
,query{query}
|
||||||
|
|
|
@ -35,7 +35,7 @@ struct session
|
||||||
std::deque<std::string> tape;
|
std::deque<std::string> tape;
|
||||||
std::multimap<string_view, string_view> resource;
|
std::multimap<string_view, string_view> resource;
|
||||||
|
|
||||||
json::doc operator()(parse::buffer &pb, request &);
|
json::object operator()(parse::buffer &pb, request &);
|
||||||
|
|
||||||
session(const host_port &);
|
session(const host_port &);
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,7 +26,7 @@ ircd::m::session::session(const host_port &host_port)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ircd::json::doc
|
ircd::json::object
|
||||||
ircd::m::session::operator()(parse::buffer &pb,
|
ircd::m::session::operator()(parse::buffer &pb,
|
||||||
request &r)
|
request &r)
|
||||||
{
|
{
|
||||||
|
@ -49,20 +49,20 @@ ircd::m::session::operator()(parse::buffer &pb,
|
||||||
};
|
};
|
||||||
|
|
||||||
http::code status;
|
http::code status;
|
||||||
json::doc doc;
|
json::object object;
|
||||||
http::response
|
http::response
|
||||||
{
|
{
|
||||||
pc,
|
pc,
|
||||||
nullptr,
|
nullptr,
|
||||||
[&pc, &status, &doc](const http::response::head &head)
|
[&pc, &status, &object](const http::response::head &head)
|
||||||
{
|
{
|
||||||
status = http::status(head.status);
|
status = http::status(head.status);
|
||||||
doc = http::response::content{pc, head};
|
object = http::response::content{pc, head};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if(status < 200 || status >= 300)
|
if(status < 200 || status >= 300)
|
||||||
throw m::error(status, doc);
|
throw m::error(status, object);
|
||||||
|
|
||||||
return doc;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
225
modules/client/events.cc
Normal file
225
modules/client/events.cc
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Charybdis Development Team
|
||||||
|
* Copyright (C) 2017 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.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using namespace ircd;
|
||||||
|
|
||||||
|
const database::descriptor events_type_descriptor
|
||||||
|
{
|
||||||
|
// name
|
||||||
|
"type",
|
||||||
|
|
||||||
|
// explanation
|
||||||
|
R"(### protocol note:
|
||||||
|
|
||||||
|
10.1
|
||||||
|
The type of event. This SHOULD be namespaced similar to Java package naming conventions
|
||||||
|
e.g. 'com.example.subdomain.event.type'.
|
||||||
|
|
||||||
|
10.4
|
||||||
|
MUST NOT exceed 255 bytes.
|
||||||
|
|
||||||
|
### developer note:
|
||||||
|
key is event_id
|
||||||
|
)",
|
||||||
|
|
||||||
|
// typing (key, value)
|
||||||
|
{
|
||||||
|
typeid(string_view), typeid(string_view)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const database::descriptor events_content_descriptor
|
||||||
|
{
|
||||||
|
// name
|
||||||
|
"content",
|
||||||
|
|
||||||
|
// explanation
|
||||||
|
R"(### protocol note:
|
||||||
|
|
||||||
|
10.1
|
||||||
|
The fields in this object will vary depending on the type of event. When interacting
|
||||||
|
with the REST API, this is the HTTP body.
|
||||||
|
|
||||||
|
### developer note:
|
||||||
|
Since events must not exceed 65 KB the maximum size for the content is the remaining
|
||||||
|
space after all the other fields for the event are rendered.
|
||||||
|
|
||||||
|
key is event_id
|
||||||
|
)",
|
||||||
|
|
||||||
|
// typing (key, value)
|
||||||
|
{
|
||||||
|
typeid(string_view), typeid(string_view)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const database::descriptor events_room_id_descriptor
|
||||||
|
{
|
||||||
|
// name
|
||||||
|
"room_id",
|
||||||
|
|
||||||
|
// explanation
|
||||||
|
R"(### protocol note:
|
||||||
|
|
||||||
|
10.2 (apropos room events)
|
||||||
|
Required. The ID of the room associated with this event.
|
||||||
|
|
||||||
|
10.4
|
||||||
|
MUST NOT exceed 255 bytes.
|
||||||
|
|
||||||
|
### developer note:
|
||||||
|
key is event_id
|
||||||
|
)",
|
||||||
|
|
||||||
|
// typing (key, value)
|
||||||
|
{
|
||||||
|
typeid(string_view), typeid(string_view)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const database::descriptor events_sender_descriptor
|
||||||
|
{
|
||||||
|
// name
|
||||||
|
"sender",
|
||||||
|
|
||||||
|
// explanation
|
||||||
|
R"(### protocol note:
|
||||||
|
|
||||||
|
10.2 (apropos room events)
|
||||||
|
Required. Contains the fully-qualified ID of the user who sent this event.
|
||||||
|
|
||||||
|
10.4
|
||||||
|
MUST NOT exceed 255 bytes.
|
||||||
|
|
||||||
|
### developer note:
|
||||||
|
key is event_id
|
||||||
|
)",
|
||||||
|
|
||||||
|
// typing (key, value)
|
||||||
|
{
|
||||||
|
typeid(string_view), typeid(string_view)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const database::descriptor events_state_key_descriptor
|
||||||
|
{
|
||||||
|
// name
|
||||||
|
"state_key",
|
||||||
|
|
||||||
|
// explanation
|
||||||
|
R"(### protocol note:
|
||||||
|
|
||||||
|
10.3 (apropos room state events)
|
||||||
|
A unique key which defines the overwriting semantics for this piece of room state.
|
||||||
|
This value is often a zero-length string. The presence of this key makes this event a
|
||||||
|
State Event. The key MUST NOT start with '_'.
|
||||||
|
|
||||||
|
10.4
|
||||||
|
MUST NOT exceed 255 bytes.
|
||||||
|
|
||||||
|
### developer note:
|
||||||
|
key is event_id
|
||||||
|
)",
|
||||||
|
|
||||||
|
// typing (key, value)
|
||||||
|
{
|
||||||
|
typeid(string_view), typeid(string_view)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const database::descriptor events_origin_descriptor
|
||||||
|
{
|
||||||
|
// name
|
||||||
|
"origin",
|
||||||
|
|
||||||
|
// explanation
|
||||||
|
R"(### protocol note:
|
||||||
|
|
||||||
|
FEDERATION 4.1
|
||||||
|
DNS name of homeserver that created this PDU
|
||||||
|
|
||||||
|
### developer note:
|
||||||
|
key is event_id
|
||||||
|
)",
|
||||||
|
|
||||||
|
// typing (key, value)
|
||||||
|
{
|
||||||
|
typeid(string_view), typeid(string_view)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const database::descriptor events_origin_server_ts_descriptor
|
||||||
|
{
|
||||||
|
// name
|
||||||
|
"origin_server_ts",
|
||||||
|
|
||||||
|
// explanation
|
||||||
|
R"(### protocol note:
|
||||||
|
|
||||||
|
FEDERATION 4.1
|
||||||
|
Timestamp in milliseconds on origin homeserver when this PDU was created.
|
||||||
|
|
||||||
|
### developer note:
|
||||||
|
key is event_id
|
||||||
|
value is a machine integer (binary)
|
||||||
|
|
||||||
|
TODO: consider unsigned rather than time_t because of millisecond precision
|
||||||
|
|
||||||
|
)",
|
||||||
|
|
||||||
|
// typing (key, value)
|
||||||
|
{
|
||||||
|
typeid(string_view), typeid(time_t)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const database::description events_description
|
||||||
|
{
|
||||||
|
{ "default" },
|
||||||
|
events_type_descriptor,
|
||||||
|
events_content_descriptor,
|
||||||
|
events_room_id_descriptor,
|
||||||
|
events_sender_descriptor,
|
||||||
|
events_state_key_descriptor,
|
||||||
|
events_origin_descriptor,
|
||||||
|
events_origin_server_ts_descriptor,
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<database> events_database
|
||||||
|
{
|
||||||
|
std::make_shared<database>("events"s, ""s, events_description)
|
||||||
|
};
|
||||||
|
|
||||||
|
extern database *const events
|
||||||
|
{
|
||||||
|
events_database.get()
|
||||||
|
};
|
||||||
|
|
||||||
|
resource events_resource
|
||||||
|
{
|
||||||
|
"_matrix/client/r0/events",
|
||||||
|
"Events (6.2.3) (10.x)"
|
||||||
|
};
|
||||||
|
|
||||||
|
mapi::header IRCD_MODULE
|
||||||
|
{
|
||||||
|
"registers the resource 'client/events' and hosts the events database"
|
||||||
|
};
|
30
modules/client/events.h
Normal file
30
modules/client/events.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Charybdis Development Team
|
||||||
|
* Copyright (C) 2017 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.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ircd::import_shared<ircd::database> events_database
|
||||||
|
{
|
||||||
|
"client_events", "events_database"
|
||||||
|
};
|
||||||
|
|
||||||
|
extern ircd::database *const events
|
||||||
|
{
|
||||||
|
events_database.get()
|
||||||
|
};
|
|
@ -40,7 +40,7 @@ using object = db::object<account>;
|
||||||
template<class T = string_view> using value = db::value<T, account>;
|
template<class T = string_view> using value = db::value<T, account>;
|
||||||
|
|
||||||
resource::response
|
resource::response
|
||||||
login_password(client &client, const resource::request &request)
|
post_login_password(client &client, const resource::request &request)
|
||||||
{
|
{
|
||||||
const auto user
|
const auto user
|
||||||
{
|
{
|
||||||
|
@ -98,7 +98,7 @@ login_password(client &client, const resource::request &request)
|
||||||
}
|
}
|
||||||
|
|
||||||
resource::response
|
resource::response
|
||||||
login_token(client &client, const resource::request &request)
|
post_login_token(client &client, const resource::request &request)
|
||||||
{
|
{
|
||||||
const auto token
|
const auto token
|
||||||
{
|
{
|
||||||
|
@ -128,7 +128,7 @@ login_token(client &client, const resource::request &request)
|
||||||
}
|
}
|
||||||
|
|
||||||
resource::response
|
resource::response
|
||||||
login(client &client, const resource::request &request)
|
post_login(client &client, const resource::request &request)
|
||||||
{
|
{
|
||||||
const auto type
|
const auto type
|
||||||
{
|
{
|
||||||
|
@ -137,9 +137,9 @@ login(client &client, const resource::request &request)
|
||||||
};
|
};
|
||||||
|
|
||||||
if(type == "m.login.password")
|
if(type == "m.login.password")
|
||||||
return login_password(client, request);
|
return post_login_password(client, request);
|
||||||
else if(type == "m.login.token")
|
else if(type == "m.login.token")
|
||||||
return login_token(client, request);
|
return post_login_token(client, request);
|
||||||
else
|
else
|
||||||
throw m::error
|
throw m::error
|
||||||
{
|
{
|
||||||
|
@ -147,9 +147,28 @@ login(client &client, const resource::request &request)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
resource::method post
|
resource::method method_post
|
||||||
{
|
{
|
||||||
login_resource, "POST", login
|
login_resource, "POST", post_login
|
||||||
|
};
|
||||||
|
|
||||||
|
resource::response
|
||||||
|
get_login(client &client, const resource::request &request)
|
||||||
|
{
|
||||||
|
static const json::object flows
|
||||||
|
{
|
||||||
|
R"({"flows":[{"type":"m.login.password"}]})"
|
||||||
|
};
|
||||||
|
|
||||||
|
return resource::response
|
||||||
|
{
|
||||||
|
client, flows
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
resource::method method_get
|
||||||
|
{
|
||||||
|
login_resource, "GET", get_login
|
||||||
};
|
};
|
||||||
|
|
||||||
mapi::header IRCD_MODULE
|
mapi::header IRCD_MODULE
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "room.h"
|
#include "rooms.h"
|
||||||
|
|
||||||
using namespace ircd;
|
using namespace ircd;
|
||||||
|
|
||||||
|
@ -33,49 +33,6 @@ resource publicrooms_resource
|
||||||
resource::response
|
resource::response
|
||||||
get_publicrooms(client &client, const resource::request &request)
|
get_publicrooms(client &client, const resource::request &request)
|
||||||
{
|
{
|
||||||
json::doc test
|
|
||||||
{
|
|
||||||
R"({"content":"hello","origin_server_ts":12345,"sender":"me"})"
|
|
||||||
};
|
|
||||||
|
|
||||||
m::event ev
|
|
||||||
{
|
|
||||||
"some content", 0, "some sender", "some type", "some unsigned", "statie"
|
|
||||||
};
|
|
||||||
|
|
||||||
json::for_each(ev, []
|
|
||||||
(const auto &key, const auto &val)
|
|
||||||
{
|
|
||||||
std::cout << key << " => " << val << std::endl;
|
|
||||||
});
|
|
||||||
|
|
||||||
std::cout << std::endl;
|
|
||||||
json::rfor_each(ev, []
|
|
||||||
(const string_view &key, const auto &val)
|
|
||||||
{
|
|
||||||
std::cout << key << " => " << val << std::endl;
|
|
||||||
});
|
|
||||||
|
|
||||||
std::cout << std::endl;
|
|
||||||
json::until(ev, []
|
|
||||||
(const string_view &key, const auto &val)
|
|
||||||
{
|
|
||||||
std::cout << key << " => " << val << std::endl;
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
std::cout << std::endl;
|
|
||||||
json::runtil(ev, []
|
|
||||||
(const string_view &key, const auto &val)
|
|
||||||
{
|
|
||||||
std::cout << key << " => " << val << std::endl;
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
std::cout << std::endl;
|
|
||||||
std::cout << index(ev, "origin_server_ts") << std::endl;
|
|
||||||
std::cout << std::endl;
|
|
||||||
|
|
||||||
return resource::response
|
return resource::response
|
||||||
{
|
{
|
||||||
client, json::index
|
client, json::index
|
||||||
|
|
|
@ -89,10 +89,10 @@ handle_post(client &client,
|
||||||
"M_INVALID_USERNAME", "The desired user ID is not a valid user name."
|
"M_INVALID_USERNAME", "The desired user ID is not a valid user name."
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto pass
|
const auto password
|
||||||
{
|
{
|
||||||
// "Required. The desired password for the account."
|
// "Required. The desired password for the account."
|
||||||
request.at("pass")
|
request.at("password")
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto bind_email
|
const auto bind_email
|
||||||
|
@ -139,7 +139,7 @@ handle_post(client &client,
|
||||||
// Batch transaction to database
|
// Batch transaction to database
|
||||||
db::write
|
db::write
|
||||||
({
|
({
|
||||||
{ db::SET, password_text, pass },
|
{ db::SET, password_text, password },
|
||||||
{ db::SET, access_token_text, access_token },
|
{ db::SET, access_token_text, access_token },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,173 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2017 Charybdis Development Team
|
|
||||||
* Copyright (C) 2017 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.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
|
||||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
|
||||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using namespace ircd;
|
|
||||||
|
|
||||||
const database::descriptor room_created_descriptor
|
|
||||||
{
|
|
||||||
"created",
|
|
||||||
|
|
||||||
R"(### developer note:
|
|
||||||
A UNIX epoch timestamp sampled when the room was created.
|
|
||||||
)",
|
|
||||||
{
|
|
||||||
// readable key // binary value
|
|
||||||
typeid(string_view), typeid(time_t)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const database::descriptor room_creator_descriptor
|
|
||||||
{
|
|
||||||
"creator",
|
|
||||||
|
|
||||||
R"(### protocol note:
|
|
||||||
The user_id of the room creator. This is set by the homeserver.
|
|
||||||
)"
|
|
||||||
};
|
|
||||||
|
|
||||||
const database::descriptor room_topic_descriptor
|
|
||||||
{
|
|
||||||
"topic",
|
|
||||||
|
|
||||||
R"(### protocol note:
|
|
||||||
If this is included, an m.room.topic event will be sent into the room to indicate the
|
|
||||||
topic for the room. See Room Events for more information on m.room.topic.
|
|
||||||
)"
|
|
||||||
};
|
|
||||||
|
|
||||||
const database::descriptor room_visibility_descriptor
|
|
||||||
{
|
|
||||||
"visibility",
|
|
||||||
|
|
||||||
R"(### protocol note:
|
|
||||||
Rooms default to private visibility if this key is not included.
|
|
||||||
|
|
||||||
* "public" visibility indicates that the room will be shown in the published room list.
|
|
||||||
|
|
||||||
* "private" visibility will hide the room from the published room list.
|
|
||||||
|
|
||||||
One of: ["public", "private"]
|
|
||||||
)"
|
|
||||||
};
|
|
||||||
|
|
||||||
const database::descriptor room_join_rules_descriptor
|
|
||||||
{
|
|
||||||
"join_rules",
|
|
||||||
|
|
||||||
R"(### protocol note:
|
|
||||||
A room may be public meaning anyone can join the room without any prior action.
|
|
||||||
Alternatively, it can be invite meaning that a user who wishes to join the room must first
|
|
||||||
receive an invite to the room from someone already inside of the room. Currently, knock and private
|
|
||||||
are reserved keywords which are not implemented.
|
|
||||||
|
|
||||||
The type of rules used for users wishing to join this room.
|
|
||||||
One of: ["public", "knock", "invite", "private"]
|
|
||||||
)"
|
|
||||||
};
|
|
||||||
|
|
||||||
const database::descriptor room_history_visibility_descriptor
|
|
||||||
{
|
|
||||||
"history_visibility",
|
|
||||||
|
|
||||||
R"(### protocol note:
|
|
||||||
|
|
||||||
* "world_readable" All events while this is the m.room.history_visibility value may be shared
|
|
||||||
by any participating homeserver with anyone, regardless of whether they have ever joined the room.
|
|
||||||
|
|
||||||
* "shared" Previous events are always accessible to newly joined members. All events in the room
|
|
||||||
are accessible, even those sent when the member was not a part of the room.
|
|
||||||
|
|
||||||
* "invited" Events are accessible to newly joined members from the point they were invited onwards.
|
|
||||||
Events stop being accessible when the member's state changes to something other than invite or join.
|
|
||||||
|
|
||||||
* "joined" Events are accessible to newly joined members from the point they joined the room onwards.
|
|
||||||
Events stop being accessible when the member's state changes to something other than join.
|
|
||||||
)"
|
|
||||||
};
|
|
||||||
|
|
||||||
const database::descriptor room_alias_descriptor
|
|
||||||
{
|
|
||||||
"alias",
|
|
||||||
|
|
||||||
R"(### protocol note:
|
|
||||||
The desired room alias local part. If this is included, a room alias will be created and mapped to
|
|
||||||
the newly created room. The alias will belong on the same homeserver which created the room.
|
|
||||||
For example, if this was set to "foo" and sent to the homeserver "example.com" the complete
|
|
||||||
room alias would be #foo:example.com.
|
|
||||||
|
|
||||||
### developer note:
|
|
||||||
The alias column on the room's primary row has a comma separated list of aliases.
|
|
||||||
For each of those aliases this column has a key indexed for it; the value for that key is
|
|
||||||
the primary room's name. This is a cross-reference that must be kept in sync.
|
|
||||||
)"
|
|
||||||
};
|
|
||||||
|
|
||||||
const database::descriptor room_federate_descriptor
|
|
||||||
{
|
|
||||||
"federate",
|
|
||||||
|
|
||||||
R"(### protocol note:
|
|
||||||
Whether users on other servers can join this room. Defaults to true if key does not exist.
|
|
||||||
)",
|
|
||||||
{
|
|
||||||
// readable key // binary value
|
|
||||||
typeid(string_view), typeid(bool)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const database::description room_description
|
|
||||||
{
|
|
||||||
{ "default" },
|
|
||||||
room_created_descriptor,
|
|
||||||
room_creator_descriptor,
|
|
||||||
room_topic_descriptor,
|
|
||||||
room_visibility_descriptor,
|
|
||||||
room_join_rules_descriptor,
|
|
||||||
room_history_visibility_descriptor,
|
|
||||||
room_alias_descriptor,
|
|
||||||
room_federate_descriptor,
|
|
||||||
};
|
|
||||||
|
|
||||||
std::shared_ptr<database> room_database
|
|
||||||
{
|
|
||||||
std::make_shared<database>("room"s, ""s, room_description)
|
|
||||||
};
|
|
||||||
|
|
||||||
extern database *const room
|
|
||||||
{
|
|
||||||
room_database.get()
|
|
||||||
};
|
|
||||||
|
|
||||||
struct room
|
|
||||||
:resource
|
|
||||||
{
|
|
||||||
using resource::resource;
|
|
||||||
}
|
|
||||||
room_resource
|
|
||||||
{
|
|
||||||
"_matrix/client/r0/room",
|
|
||||||
"Rooms (7.0)"
|
|
||||||
};
|
|
||||||
|
|
||||||
mapi::header IRCD_MODULE
|
|
||||||
{
|
|
||||||
"registers the resource 'client/room' to manage Matrix rooms"
|
|
||||||
};
|
|
76
modules/client/rooms.cc
Normal file
76
modules/client/rooms.cc
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Charybdis Development Team
|
||||||
|
* Copyright (C) 2017 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.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using namespace ircd;
|
||||||
|
|
||||||
|
const database::descriptor rooms_head_descriptor
|
||||||
|
{
|
||||||
|
// name
|
||||||
|
"head",
|
||||||
|
|
||||||
|
// notes
|
||||||
|
R"(
|
||||||
|
### developer note:
|
||||||
|
|
||||||
|
The latest event for a room.
|
||||||
|
|
||||||
|
key is room_id
|
||||||
|
value is event_id
|
||||||
|
|
||||||
|
)",
|
||||||
|
|
||||||
|
// typing for key and value
|
||||||
|
{
|
||||||
|
typeid(string_view), typeid(string_view)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const database::description rooms_description
|
||||||
|
{
|
||||||
|
{ "default" },
|
||||||
|
rooms_head_descriptor,
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<database> rooms_database
|
||||||
|
{
|
||||||
|
std::make_shared<database>("room"s, ""s, rooms_description)
|
||||||
|
};
|
||||||
|
|
||||||
|
extern database *const room
|
||||||
|
{
|
||||||
|
rooms_database.get()
|
||||||
|
};
|
||||||
|
|
||||||
|
struct room
|
||||||
|
:resource
|
||||||
|
{
|
||||||
|
using resource::resource;
|
||||||
|
}
|
||||||
|
rooms_resource
|
||||||
|
{
|
||||||
|
"_matrix/client/r0/rooms/",
|
||||||
|
"Rooms (7.0)"
|
||||||
|
};
|
||||||
|
|
||||||
|
mapi::header IRCD_MODULE
|
||||||
|
{
|
||||||
|
"registers the resource 'client/rooms' and hosts the rooms database"
|
||||||
|
};
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2017 Charybdis Development Team
|
* Copyright (C) 2017 Charybdis Development Team
|
||||||
* Copyright (C) 2017 Jason Volk <jason@zemos.net>
|
* Copyright (C) 2017 Jason Volk <jason@zemos.net>
|
||||||
*
|
*
|
||||||
|
@ -19,12 +19,12 @@
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ircd::import_shared<ircd::database> room_database
|
ircd::import_shared<ircd::database> rooms_database
|
||||||
{
|
{
|
||||||
"client_room", "room_database"
|
"client_rooms", "rooms_database"
|
||||||
};
|
};
|
||||||
|
|
||||||
extern ircd::database *const room
|
extern ircd::database *const rooms
|
||||||
{
|
{
|
||||||
room_database.get()
|
rooms_database.get()
|
||||||
};
|
};
|
|
@ -19,8 +19,6 @@
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ircd/listen.h>
|
|
||||||
|
|
||||||
using namespace ircd;
|
using namespace ircd;
|
||||||
|
|
||||||
mapi::header IRCD_MODULE
|
mapi::header IRCD_MODULE
|
||||||
|
@ -30,6 +28,8 @@ mapi::header IRCD_MODULE
|
||||||
|
|
||||||
std::map<std::string, module> modules;
|
std::map<std::string, module> modules;
|
||||||
|
|
||||||
|
void test();
|
||||||
|
|
||||||
//TODO: XXX very temporary stuff around here
|
//TODO: XXX very temporary stuff around here
|
||||||
// The path root (serves static assets for web etc); this pointer
|
// The path root (serves static assets for web etc); this pointer
|
||||||
// exists for now to easily find and reload that specifically.
|
// exists for now to easily find and reload that specifically.
|
||||||
|
@ -37,34 +37,97 @@ module *root_module;
|
||||||
const auto _init_([]
|
const auto _init_([]
|
||||||
{
|
{
|
||||||
// These modules host databases and have to be loaded first.
|
// These modules host databases and have to be loaded first.
|
||||||
|
modules.emplace("client_events.so"s, "client_events.so"s);
|
||||||
modules.emplace("client_account.so"s, "client_account.so"s);
|
modules.emplace("client_account.so"s, "client_account.so"s);
|
||||||
modules.emplace("client_room.so"s, "client_room.so"s);
|
modules.emplace("client_rooms.so"s, "client_rooms.so"s);
|
||||||
|
|
||||||
for(const auto &name : mods::available())
|
for(const auto &name : mods::available())
|
||||||
if(name != "matrix.so")
|
if(name != "matrix.so")
|
||||||
modules.emplace(name, name);
|
modules.emplace(name, name);
|
||||||
|
|
||||||
root_module = &modules.at("root.so"s);
|
root_module = &modules.at("root.so"s);
|
||||||
|
|
||||||
|
test();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}());
|
}());
|
||||||
|
|
||||||
listener matrices
|
listener matrices
|
||||||
{
|
{
|
||||||
std::string { json::obj
|
std::string { json::index
|
||||||
{
|
{
|
||||||
{ "name", "Chat Matrix" },
|
{ "name", "Chat Matrix" },
|
||||||
{ "host", "0.0.0.0" },
|
{ "host", "0.0.0.0" },
|
||||||
{
|
{
|
||||||
"ssl_certificate_chain_file", "/home/jason/.synapse/zemos.net.crt"
|
"ssl_certificate_file", "/home/jason/newcert.pem"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ssl_tmp_dh_file", "/home/jason/.synapse/cdc.z.tls.dh"
|
"ssl_certificate_chain_file", "/home/jason/newcert.pem"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ssl_private_key_file_pem", "/home/jason/.synapse/cdc.z.tls.key"
|
"ssl_tmp_dh_file", "/home/jason/dh1024.pem"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"port", 6667
|
"ssl_private_key_file_pem", "/home/jason/privkey.pem"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"port", 8448
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void test()
|
||||||
|
{
|
||||||
|
json::object test
|
||||||
|
{
|
||||||
|
R"({"content":"hello","origin_server_ts":12345,"sender":"@foo:bar.com"})"
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
const m::event ev0
|
||||||
|
{
|
||||||
|
"some content", 0, "some sender", "some type", "some unsigned", "statie"
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
const m::event ev
|
||||||
|
{
|
||||||
|
test
|
||||||
|
};
|
||||||
|
|
||||||
|
std::cout << "size: " << sizeof(ev) << std::endl;
|
||||||
|
|
||||||
|
json::for_each(ev, []
|
||||||
|
(auto&& key, auto&& val)
|
||||||
|
{
|
||||||
|
std::cout << key << " => " << val << std::endl;
|
||||||
|
});
|
||||||
|
|
||||||
|
std::cout << "----" << std::endl;
|
||||||
|
|
||||||
|
json::rfor_each(ev, []
|
||||||
|
(const string_view &key, auto&& val)
|
||||||
|
{
|
||||||
|
std::cout << key << " => " << val << std::endl;
|
||||||
|
});
|
||||||
|
|
||||||
|
std::cout << "----" << std::endl;
|
||||||
|
|
||||||
|
json::until(ev, []
|
||||||
|
(const string_view &key, auto&& val)
|
||||||
|
{
|
||||||
|
std::cout << key << " => " << val << std::endl;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
std::cout << "----" << std::endl;
|
||||||
|
|
||||||
|
json::runtil(ev, []
|
||||||
|
(const string_view &key, auto&& val)
|
||||||
|
{
|
||||||
|
std::cout << key << " => " << val << std::endl;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << json::indexof(ev, "origin_server_ts") << std::endl;
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
|
|
@ -37,9 +37,10 @@ __attribute__((constructor))
|
||||||
void
|
void
|
||||||
init_0()
|
init_0()
|
||||||
{
|
{
|
||||||
for(const auto &file : fs::ls("/home/jason/charybdis/charybdis/modules/static"))
|
// TODO: XXX
|
||||||
|
for(const auto &file : fs::ls_recursive("/home/jason/charybdis/charybdis/modules/static"))
|
||||||
{
|
{
|
||||||
const auto name(token_last(file, "/"));
|
const auto name(tokens_after(file, "/", 5));
|
||||||
files.emplace(std::string(name), file);
|
files.emplace(std::string(name), file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue